summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCristian Adam <cristian.adam@gmail.com>2019-09-17 17:21:09 (GMT)
committerCristian Adam <cristian.adam@gmail.com>2019-09-28 13:56:53 (GMT)
commitdd0f304613b1661754d9cccf5829087a8bb19a12 (patch)
tree852c778a4b92ca5b2a58564fc59a7314a3a6d654
parentb515af782bccf147e8bd62444c9f1808668f12ac (diff)
downloadCMake-dd0f304613b1661754d9cccf5829087a8bb19a12.zip
CMake-dd0f304613b1661754d9cccf5829087a8bb19a12.tar.gz
CMake-dd0f304613b1661754d9cccf5829087a8bb19a12.tar.bz2
Objective C/C++: Add compiler standard detection
-rw-r--r--Source/cmLocalGenerator.cxx10
-rw-r--r--Source/cmMakefile.cxx148
-rw-r--r--Source/cmMakefile.h14
-rw-r--r--Source/cmTarget.cxx8
4 files changed, 108 insertions, 72 deletions
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index 3583dc9..303a484 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -1941,10 +1941,20 @@ void cmLocalGenerator::AddCompilerRequirementFlag(
langStdMap["CXX"].emplace_back("11");
langStdMap["CXX"].emplace_back("98");
+ langStdMap["OBJCXX"].emplace_back("20");
+ langStdMap["OBJCXX"].emplace_back("17");
+ langStdMap["OBJCXX"].emplace_back("14");
+ langStdMap["OBJCXX"].emplace_back("11");
+ langStdMap["OBJCXX"].emplace_back("98");
+
langStdMap["C"].emplace_back("11");
langStdMap["C"].emplace_back("99");
langStdMap["C"].emplace_back("90");
+ langStdMap["OBJC"].emplace_back("11");
+ langStdMap["OBJC"].emplace_back("99");
+ langStdMap["OBJC"].emplace_back("90");
+
langStdMap["CUDA"].emplace_back("14");
langStdMap["CUDA"].emplace_back("11");
langStdMap["CUDA"].emplace_back("98");
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index 34081ed..85ba38c 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -38,6 +38,7 @@
#include "cmState.h"
#include "cmStateDirectory.h"
#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmTargetLinkLibraryType.h"
#include "cmTest.h"
@@ -4615,9 +4616,9 @@ bool cmMakefile::AddRequiredTargetFeature(cmTarget* target,
target->AppendProperty("COMPILE_FEATURES", feature.c_str());
- return lang == "C"
- ? this->AddRequiredTargetCFeature(target, feature, error)
- : this->AddRequiredTargetCxxFeature(target, feature, error);
+ return lang == "C" || lang == "OBJC"
+ ? this->AddRequiredTargetCFeature(target, feature, lang, error)
+ : this->AddRequiredTargetCxxFeature(target, feature, lang, error);
}
bool cmMakefile::CompileFeatureKnown(cmTarget const* target,
@@ -4709,30 +4710,33 @@ bool cmMakefile::HaveStandardAvailable(cmTarget const* target,
std::string const& lang,
const std::string& feature) const
{
- return lang == "C" ? this->HaveCStandardAvailable(target, feature)
- : this->HaveCxxStandardAvailable(target, feature);
+ return lang == "C" || lang == "OBJC"
+ ? this->HaveCStandardAvailable(target, feature, lang)
+ : this->HaveCxxStandardAvailable(target, feature, lang);
}
bool cmMakefile::HaveCStandardAvailable(cmTarget const* target,
- const std::string& feature) const
+ const std::string& feature,
+ std::string const& lang) const
{
const char* defaultCStandard =
- this->GetDefinition("CMAKE_C_STANDARD_DEFAULT");
+ this->GetDefinition(cmStrCat("CMAKE_", lang, "_STANDARD_DEFAULT"));
if (!defaultCStandard) {
this->IssueMessage(
MessageType::INTERNAL_ERROR,
- "CMAKE_C_STANDARD_DEFAULT is not set. COMPILE_FEATURES support "
- "not fully configured for this compiler.");
+ cmStrCat("CMAKE_", lang,
+ "_STANDARD_DEFAULT is not set. COMPILE_FEATURES support "
+ "not fully configured for this compiler."));
// Return true so the caller does not try to lookup the default standard.
return true;
}
if (std::find_if(cm::cbegin(C_STANDARDS), cm::cend(C_STANDARDS),
cmStrCmp(defaultCStandard)) == cm::cend(C_STANDARDS)) {
- std::ostringstream e;
- e << "The CMAKE_C_STANDARD_DEFAULT variable contains an "
- "invalid value: \""
- << defaultCStandard << "\".";
- this->IssueMessage(MessageType::INTERNAL_ERROR, e.str());
+ const std::string e = cmStrCat("The CMAKE_", lang,
+ "_STANDARD_DEFAULT variable contains an "
+ "invalid value: \"",
+ defaultCStandard, "\".");
+ this->IssueMessage(MessageType::INTERNAL_ERROR, e);
return false;
}
@@ -4740,19 +4744,20 @@ bool cmMakefile::HaveCStandardAvailable(cmTarget const* target,
bool needC99 = false;
bool needC11 = false;
- this->CheckNeededCLanguage(feature, needC90, needC99, needC11);
+ this->CheckNeededCLanguage(feature, lang, needC90, needC99, needC11);
- const char* existingCStandard = target->GetProperty("C_STANDARD");
+ const char* existingCStandard =
+ target->GetProperty(cmStrCat(lang, "_STANDARD"));
if (!existingCStandard) {
existingCStandard = defaultCStandard;
}
if (std::find_if(cm::cbegin(C_STANDARDS), cm::cend(C_STANDARDS),
cmStrCmp(existingCStandard)) == cm::cend(C_STANDARDS)) {
- std::ostringstream e;
- e << "The C_STANDARD property on target \"" << target->GetName()
- << "\" contained an invalid value: \"" << existingCStandard << "\".";
- this->IssueMessage(MessageType::FATAL_ERROR, e.str());
+ const std::string e = cmStrCat(
+ "The ", lang, "_STANDARD property on target \"", target->GetName(),
+ "\" contained an invalid value: \"", existingCStandard, "\".");
+ this->IssueMessage(MessageType::FATAL_ERROR, e);
return false;
}
@@ -4783,7 +4788,7 @@ bool cmMakefile::IsLaterStandard(std::string const& lang,
std::string const& lhs,
std::string const& rhs)
{
- if (lang == "C") {
+ if (lang == "C" || lang == "OBJC") {
const char* const* rhsIt = std::find_if(
cm::cbegin(C_STANDARDS), cm::cend(C_STANDARDS), cmStrCmp(rhs));
@@ -4798,25 +4803,26 @@ bool cmMakefile::IsLaterStandard(std::string const& lang,
}
bool cmMakefile::HaveCxxStandardAvailable(cmTarget const* target,
- const std::string& feature) const
+ const std::string& feature,
+ std::string const& lang) const
{
const char* defaultCxxStandard =
- this->GetDefinition("CMAKE_CXX_STANDARD_DEFAULT");
+ this->GetDefinition(cmStrCat("CMAKE_", lang, "_STANDARD_DEFAULT"));
if (!defaultCxxStandard) {
this->IssueMessage(
MessageType::INTERNAL_ERROR,
- "CMAKE_CXX_STANDARD_DEFAULT is not set. COMPILE_FEATURES support "
- "not fully configured for this compiler.");
+ cmStrCat("CMAKE_", lang,
+ "_STANDARD_DEFAULT is not set. COMPILE_FEATURES support "
+ "not fully configured for this compiler."));
// Return true so the caller does not try to lookup the default standard.
return true;
}
if (std::find_if(cm::cbegin(CXX_STANDARDS), cm::cend(CXX_STANDARDS),
cmStrCmp(defaultCxxStandard)) == cm::cend(CXX_STANDARDS)) {
- std::ostringstream e;
- e << "The CMAKE_CXX_STANDARD_DEFAULT variable contains an "
- "invalid value: \""
- << defaultCxxStandard << "\".";
- this->IssueMessage(MessageType::INTERNAL_ERROR, e.str());
+ const std::string e =
+ cmStrCat("The CMAKE_", lang, "_STANDARD_DEFAULT variable contains an ",
+ "invalid value: \"", defaultCxxStandard, "\".");
+ this->IssueMessage(MessageType::INTERNAL_ERROR, e);
return false;
}
@@ -4825,10 +4831,11 @@ bool cmMakefile::HaveCxxStandardAvailable(cmTarget const* target,
bool needCxx14 = false;
bool needCxx17 = false;
bool needCxx20 = false;
- this->CheckNeededCxxLanguage(feature, needCxx98, needCxx11, needCxx14,
+ this->CheckNeededCxxLanguage(feature, lang, needCxx98, needCxx11, needCxx14,
needCxx17, needCxx20);
- const char* existingCxxStandard = target->GetProperty("CXX_STANDARD");
+ const char* existingCxxStandard =
+ target->GetProperty(cmStrCat(lang, "_STANDARD"));
if (!existingCxxStandard) {
existingCxxStandard = defaultCxxStandard;
}
@@ -4837,10 +4844,10 @@ bool cmMakefile::HaveCxxStandardAvailable(cmTarget const* target,
std::find_if(cm::cbegin(CXX_STANDARDS), cm::cend(CXX_STANDARDS),
cmStrCmp(existingCxxStandard));
if (existingCxxLevel == cm::cend(CXX_STANDARDS)) {
- std::ostringstream e;
- e << "The CXX_STANDARD property on target \"" << target->GetName()
- << "\" contained an invalid value: \"" << existingCxxStandard << "\".";
- this->IssueMessage(MessageType::FATAL_ERROR, e.str());
+ const std::string e = cmStrCat(
+ "The ", lang, "_STANDARD property on target \"", target->GetName(),
+ "\" contained an invalid value: \"", existingCxxStandard, "\".");
+ this->IssueMessage(MessageType::FATAL_ERROR, e);
return false;
}
@@ -4858,32 +4865,33 @@ bool cmMakefile::HaveCxxStandardAvailable(cmTarget const* target,
}
void cmMakefile::CheckNeededCxxLanguage(const std::string& feature,
+ std::string const& lang,
bool& needCxx98, bool& needCxx11,
bool& needCxx14, bool& needCxx17,
bool& needCxx20) const
{
if (const char* propCxx98 =
- this->GetDefinition("CMAKE_CXX98_COMPILE_FEATURES")) {
+ this->GetDefinition(cmStrCat("CMAKE_", lang, "98_COMPILE_FEATURES"))) {
std::vector<std::string> props = cmExpandedList(propCxx98);
needCxx98 = cmContains(props, feature);
}
if (const char* propCxx11 =
- this->GetDefinition("CMAKE_CXX11_COMPILE_FEATURES")) {
+ this->GetDefinition(cmStrCat("CMAKE_", lang, "11_COMPILE_FEATURES"))) {
std::vector<std::string> props = cmExpandedList(propCxx11);
needCxx11 = cmContains(props, feature);
}
if (const char* propCxx14 =
- this->GetDefinition("CMAKE_CXX14_COMPILE_FEATURES")) {
+ this->GetDefinition(cmStrCat("CMAKE_", lang, "14_COMPILE_FEATURES"))) {
std::vector<std::string> props = cmExpandedList(propCxx14);
needCxx14 = cmContains(props, feature);
}
if (const char* propCxx17 =
- this->GetDefinition("CMAKE_CXX17_COMPILE_FEATURES")) {
+ this->GetDefinition(cmStrCat("CMAKE_", lang, "17_COMPILE_FEATURES"))) {
std::vector<std::string> props = cmExpandedList(propCxx17);
needCxx17 = cmContains(props, feature);
}
if (const char* propCxx20 =
- this->GetDefinition("CMAKE_CXX20_COMPILE_FEATURES")) {
+ this->GetDefinition(cmStrCat("CMAKE_", lang, "20_COMPILE_FEATURES"))) {
std::vector<std::string> props = cmExpandedList(propCxx20);
needCxx20 = cmContains(props, feature);
}
@@ -4891,6 +4899,7 @@ void cmMakefile::CheckNeededCxxLanguage(const std::string& feature,
bool cmMakefile::AddRequiredTargetCxxFeature(cmTarget* target,
const std::string& feature,
+ std::string const& lang,
std::string* error) const
{
bool needCxx98 = false;
@@ -4899,13 +4908,14 @@ bool cmMakefile::AddRequiredTargetCxxFeature(cmTarget* target,
bool needCxx17 = false;
bool needCxx20 = false;
- this->CheckNeededCxxLanguage(feature, needCxx98, needCxx11, needCxx14,
+ this->CheckNeededCxxLanguage(feature, lang, needCxx98, needCxx11, needCxx14,
needCxx17, needCxx20);
- const char* existingCxxStandard = target->GetProperty("CXX_STANDARD");
+ const char* existingCxxStandard =
+ target->GetProperty(cmStrCat(lang, "_STANDARD"));
if (existingCxxStandard == nullptr) {
const char* defaultCxxStandard =
- this->GetDefinition("CMAKE_CXX_STANDARD_DEFAULT");
+ this->GetDefinition(cmStrCat("CMAKE_", lang, "_STANDARD_DEFAULT"));
if (defaultCxxStandard && *defaultCxxStandard) {
existingCxxStandard = defaultCxxStandard;
}
@@ -4916,14 +4926,14 @@ bool cmMakefile::AddRequiredTargetCxxFeature(cmTarget* target,
std::find_if(cm::cbegin(CXX_STANDARDS), cm::cend(CXX_STANDARDS),
cmStrCmp(existingCxxStandard));
if (existingCxxLevel == cm::cend(CXX_STANDARDS)) {
- std::ostringstream e;
- e << "The CXX_STANDARD property on target \"" << target->GetName()
- << "\" contained an invalid value: \"" << existingCxxStandard << "\".";
+ const std::string e = cmStrCat(
+ "The ", lang, "_STANDARD property on target \"", target->GetName(),
+ "\" contained an invalid value: \"", existingCxxStandard, "\".");
if (error) {
- *error = e.str();
+ *error = e;
} else {
- this->GetCMakeInstance()->IssueMessage(MessageType::FATAL_ERROR,
- e.str(), this->Backtrace);
+ this->GetCMakeInstance()->IssueMessage(MessageType::FATAL_ERROR, e,
+ this->Backtrace);
}
return false;
}
@@ -4964,7 +4974,7 @@ bool cmMakefile::AddRequiredTargetCxxFeature(cmTarget* target,
// Ensure the C++ language level is high enough to support
// the needed C++ features.
if (!existingCxxLevel || existingCxxLevel < needCxxLevel) {
- target->SetProperty("CXX_STANDARD", *needCxxLevel);
+ target->SetProperty(cmStrCat(lang, "_STANDARD"), *needCxxLevel);
}
// Ensure the CUDA language level is high enough to support
@@ -4978,21 +4988,21 @@ bool cmMakefile::AddRequiredTargetCxxFeature(cmTarget* target,
}
void cmMakefile::CheckNeededCLanguage(const std::string& feature,
- bool& needC90, bool& needC99,
- bool& needC11) const
+ std::string const& lang, bool& needC90,
+ bool& needC99, bool& needC11) const
{
if (const char* propC90 =
- this->GetDefinition("CMAKE_C90_COMPILE_FEATURES")) {
+ this->GetDefinition(cmStrCat("CMAKE_", lang, "90_COMPILE_FEATURES"))) {
std::vector<std::string> props = cmExpandedList(propC90);
needC90 = cmContains(props, feature);
}
if (const char* propC99 =
- this->GetDefinition("CMAKE_C99_COMPILE_FEATURES")) {
+ this->GetDefinition(cmStrCat("CMAKE_", lang, "99_COMPILE_FEATURES"))) {
std::vector<std::string> props = cmExpandedList(propC99);
needC99 = cmContains(props, feature);
}
if (const char* propC11 =
- this->GetDefinition("CMAKE_C11_COMPILE_FEATURES")) {
+ this->GetDefinition(cmStrCat("CMAKE_", lang, "11_COMPILE_FEATURES"))) {
std::vector<std::string> props = cmExpandedList(propC11);
needC11 = cmContains(props, feature);
}
@@ -5000,18 +5010,20 @@ void cmMakefile::CheckNeededCLanguage(const std::string& feature,
bool cmMakefile::AddRequiredTargetCFeature(cmTarget* target,
const std::string& feature,
+ std::string const& lang,
std::string* error) const
{
bool needC90 = false;
bool needC99 = false;
bool needC11 = false;
- this->CheckNeededCLanguage(feature, needC90, needC99, needC11);
+ this->CheckNeededCLanguage(feature, lang, needC90, needC99, needC11);
- const char* existingCStandard = target->GetProperty("C_STANDARD");
+ const char* existingCStandard =
+ target->GetProperty(cmStrCat(lang, "_STANDARD"));
if (existingCStandard == nullptr) {
const char* defaultCStandard =
- this->GetDefinition("CMAKE_C_STANDARD_DEFAULT");
+ this->GetDefinition(cmStrCat("CMAKE_", lang, "_STANDARD_DEFAULT"));
if (defaultCStandard && *defaultCStandard) {
existingCStandard = defaultCStandard;
}
@@ -5019,14 +5031,14 @@ bool cmMakefile::AddRequiredTargetCFeature(cmTarget* target,
if (existingCStandard) {
if (std::find_if(cm::cbegin(C_STANDARDS), cm::cend(C_STANDARDS),
cmStrCmp(existingCStandard)) == cm::cend(C_STANDARDS)) {
- std::ostringstream e;
- e << "The C_STANDARD property on target \"" << target->GetName()
- << "\" contained an invalid value: \"" << existingCStandard << "\".";
+ const std::string e = cmStrCat(
+ "The ", lang, "_STANDARD property on target \"", target->GetName(),
+ "\" contained an invalid value: \"", existingCStandard, "\".");
if (error) {
- *error = e.str();
+ *error = e;
} else {
- this->GetCMakeInstance()->IssueMessage(MessageType::FATAL_ERROR,
- e.str(), this->Backtrace);
+ this->GetCMakeInstance()->IssueMessage(MessageType::FATAL_ERROR, e,
+ this->Backtrace);
}
return false;
}
@@ -5057,11 +5069,11 @@ bool cmMakefile::AddRequiredTargetCFeature(cmTarget* target,
}
if (setC11) {
- target->SetProperty("C_STANDARD", "11");
+ target->SetProperty(cmStrCat(lang, "_STANDARD"), "11");
} else if (setC99) {
- target->SetProperty("C_STANDARD", "99");
+ target->SetProperty(cmStrCat(lang, "_STANDARD"), "99");
} else if (setC90) {
- target->SetProperty("C_STANDARD", "90");
+ target->SetProperty(cmStrCat(lang, "_STANDARD"), "90");
}
return true;
}
diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h
index db37477..1dc83b4 100644
--- a/Source/cmMakefile.h
+++ b/Source/cmMakefile.h
@@ -1135,22 +1135,28 @@ private:
bool MightHaveCustomCommand(const std::string& name) const;
bool AddRequiredTargetCFeature(cmTarget* target, const std::string& feature,
+ std::string const& lang,
std::string* error = nullptr) const;
bool AddRequiredTargetCxxFeature(cmTarget* target,
const std::string& feature,
+ std::string const& lang,
std::string* error = nullptr) const;
- void CheckNeededCLanguage(const std::string& feature, bool& needC90,
+ void CheckNeededCLanguage(const std::string& feature,
+ std::string const& lang, bool& needC90,
bool& needC99, bool& needC11) const;
- void CheckNeededCxxLanguage(const std::string& feature, bool& needCxx98,
+ void CheckNeededCxxLanguage(const std::string& feature,
+ std::string const& lang, bool& needCxx98,
bool& needCxx11, bool& needCxx14,
bool& needCxx17, bool& needCxx20) const;
bool HaveCStandardAvailable(cmTarget const* target,
- const std::string& feature) const;
+ const std::string& feature,
+ std::string const& lang) const;
bool HaveCxxStandardAvailable(cmTarget const* target,
- const std::string& feature) const;
+ const std::string& feature,
+ std::string const& lang) const;
void CheckForUnusedVariables() const;
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 1b88db6..f65a018 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -332,6 +332,9 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
initProp("C_STANDARD");
initProp("C_STANDARD_REQUIRED");
initProp("C_EXTENSIONS");
+ initProp("OBJC_STANDARD");
+ initProp("OBJC_STANDARD_REQUIRED");
+ initProp("OBJC_EXTENSIONS");
initProp("CXX_CLANG_TIDY");
initProp("CXX_COMPILER_LAUNCHER");
initProp("CXX_CPPLINT");
@@ -340,6 +343,9 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
initProp("CXX_STANDARD");
initProp("CXX_STANDARD_REQUIRED");
initProp("CXX_EXTENSIONS");
+ initProp("OBJCXX_STANDARD");
+ initProp("OBJCXX_STANDARD_REQUIRED");
+ initProp("OBJCXX_EXTENSIONS");
initProp("CUDA_STANDARD");
initProp("CUDA_STANDARD_REQUIRED");
initProp("CUDA_EXTENSIONS");
@@ -452,6 +458,8 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
this->GetType() != cmStateEnums::UTILITY) {
initProp("C_VISIBILITY_PRESET");
initProp("CXX_VISIBILITY_PRESET");
+ initProp("OBJC_VISIBILITY_PRESET");
+ initProp("OBJCXX_VISIBILITY_PRESET");
initProp("CUDA_VISIBILITY_PRESET");
initProp("VISIBILITY_INLINES_HIDDEN");
}