diff options
author | Stephen Kelly <steveire@gmail.com> | 2013-11-04 00:15:43 (GMT) |
---|---|---|
committer | Stephen Kelly <steveire@gmail.com> | 2014-05-14 22:15:18 (GMT) |
commit | e0890d03a48d12904ffe24aa94fb2847d8d5f4e7 (patch) | |
tree | 820631dcc5cd8c95111dbfa7d33e1a59d554f8a4 /Source | |
parent | 775458dede98d28fe81ac878541a6ead735443fc (diff) | |
download | CMake-e0890d03a48d12904ffe24aa94fb2847d8d5f4e7.zip CMake-e0890d03a48d12904ffe24aa94fb2847d8d5f4e7.tar.gz CMake-e0890d03a48d12904ffe24aa94fb2847d8d5f4e7.tar.bz2 |
Features: Extend concept to C language.
Add properties and variables corresponding to CXX equivalents.
Add features for c_function_prototypes (C90), c_restrict (C99),
c_variadic_macros (C99) and c_static_assert (C11). This feature
set can be extended later.
Add a <PREFIX>_RESTRICT symbol define to WriteCompilerDetectionHeader
to conditionally represent the c_restrict feature.
Diffstat (limited to 'Source')
-rw-r--r-- | Source/cmLocalGenerator.cxx | 4 | ||||
-rw-r--r-- | Source/cmMakefile.cxx | 116 | ||||
-rw-r--r-- | Source/cmMakefile.h | 6 | ||||
-rw-r--r-- | Source/cmTarget.cxx | 3 | ||||
-rw-r--r-- | Source/cmake.cxx | 8 | ||||
-rw-r--r-- | Source/cmake.h | 6 |
6 files changed, 139 insertions, 4 deletions
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index 7028da0..a6ad714 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -2201,6 +2201,10 @@ AddCompilerRequirementFlag(std::string &flags, cmTarget* target, // Maintain sorted order, most recent first. langStdMap["CXX"].push_back("11"); langStdMap["CXX"].push_back("98"); + + langStdMap["C"].push_back("11"); + langStdMap["C"].push_back("99"); + langStdMap["C"].push_back("90"); } std::string standard(standardProp); diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index 90a7b0b..42dedc9 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -4973,6 +4973,10 @@ void cmMakefile::RecordPolicies(cmPolicies::PolicyMap& pm) } #define FEATURE_STRING(F) , #F +static const char * const C_FEATURES[] = { + 0 + FOR_EACH_C_FEATURE(FEATURE_STRING) +}; static const char * const CXX_FEATURES[] = { 0 @@ -4980,6 +4984,11 @@ static const char * const CXX_FEATURES[] = { }; #undef FEATURE_STRING +static const char * const C_STANDARDS[] = { + "90" + , "99" + , "11" +}; static const char * const CXX_STANDARDS[] = { "98" , "11" @@ -4995,10 +5004,13 @@ AddRequiredTargetFeature(cmTarget *target, const std::string& feature, target->AppendProperty("COMPILE_FEATURES", feature.c_str()); return true; } + bool isCFeature = std::find_if(cmArrayBegin(C_FEATURES) + 1, + cmArrayEnd(C_FEATURES), cmStrCmp(feature)) + != cmArrayEnd(C_FEATURES); bool isCxxFeature = std::find_if(cmArrayBegin(CXX_FEATURES) + 1, cmArrayEnd(CXX_FEATURES), cmStrCmp(feature)) != cmArrayEnd(CXX_FEATURES); - if (!isCxxFeature) + if (!isCFeature && !isCxxFeature) { cmOStringStream e; if (error) @@ -5022,7 +5034,7 @@ AddRequiredTargetFeature(cmTarget *target, const std::string& feature, return false; } - std::string lang = "CXX"; + std::string lang = isCFeature ? "C" : "CXX"; const char* featuresKnown = this->GetDefinition("CMAKE_" + lang + "_COMPILE_FEATURES"); @@ -5071,6 +5083,16 @@ AddRequiredTargetFeature(cmTarget *target, const std::string& feature, target->AppendProperty("COMPILE_FEATURES", feature.c_str()); + return isCFeature + ? this->AddRequiredTargetCFeature(target, feature) + : this->AddRequiredTargetCxxFeature(target, feature); +} + +//---------------------------------------------------------------------------- +bool cmMakefile:: +AddRequiredTargetCxxFeature(cmTarget *target, + const std::string& feature) const +{ bool needCxx98 = false; bool needCxx11 = false; @@ -5136,3 +5158,93 @@ AddRequiredTargetFeature(cmTarget *target, const std::string& feature, } return true; } + +//---------------------------------------------------------------------------- +bool cmMakefile:: +AddRequiredTargetCFeature(cmTarget *target, const std::string& feature) const +{ + bool needC90 = false; + bool needC99 = false; + bool needC11 = false; + + if (const char *propC90 = + this->GetDefinition("CMAKE_C90_COMPILE_FEATURES")) + { + std::vector<std::string> props; + cmSystemTools::ExpandListArgument(propC90, props); + needC90 = std::find(props.begin(), props.end(), feature) != props.end(); + } + if (const char *propC99 = + this->GetDefinition("CMAKE_C99_COMPILE_FEATURES")) + { + std::vector<std::string> props; + cmSystemTools::ExpandListArgument(propC99, props); + needC99 = std::find(props.begin(), props.end(), feature) != props.end(); + } + if (const char *propC11 = + this->GetDefinition("CMAKE_C11_COMPILE_FEATURES")) + { + std::vector<std::string> props; + cmSystemTools::ExpandListArgument(propC11, props); + needC11 = std::find(props.begin(), props.end(), feature) != props.end(); + } + + const char *existingCStandard = target->GetProperty("C_STANDARD"); + if (existingCStandard) + { + if (std::find_if(cmArrayBegin(C_STANDARDS), cmArrayEnd(C_STANDARDS), + cmStrCmp(existingCStandard)) == cmArrayEnd(C_STANDARDS)) + { + cmOStringStream e; + e << "The C_STANDARD property on target \"" << target->GetName() + << "\" contained an invalid value: \"" << existingCStandard << "\"."; + this->IssueMessage(cmake::FATAL_ERROR, e.str().c_str()); + return false; + } + } + const char * const *existingCIt = existingCStandard + ? std::find_if(cmArrayBegin(C_STANDARDS), + cmArrayEnd(C_STANDARDS), + cmStrCmp(existingCStandard)) + : cmArrayEnd(C_STANDARDS); + + bool setC90 = needC90 && !existingCStandard; + bool setC99 = needC99 && !existingCStandard; + bool setC11 = needC11 && !existingCStandard; + + if (needC11 && existingCStandard && existingCIt < + std::find_if(cmArrayBegin(C_STANDARDS), + cmArrayEnd(C_STANDARDS), + cmStrCmp("11"))) + { + setC11 = true; + } + else if(needC99 && existingCStandard && existingCIt < + std::find_if(cmArrayBegin(C_STANDARDS), + cmArrayEnd(C_STANDARDS), + cmStrCmp("99"))) + { + setC99 = true; + } + else if(needC90 && existingCStandard && existingCIt < + std::find_if(cmArrayBegin(C_STANDARDS), + cmArrayEnd(C_STANDARDS), + cmStrCmp("90"))) + { + setC90 = true; + } + + if (setC11) + { + target->SetProperty("C_STANDARD", "11"); + } + else if (setC99) + { + target->SetProperty("C_STANDARD", "99"); + } + else if (setC90) + { + target->SetProperty("C_STANDARD", "90"); + } + return true; +} diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h index 2bfd19b..90e2e19 100644 --- a/Source/cmMakefile.h +++ b/Source/cmMakefile.h @@ -1098,6 +1098,12 @@ private: std::vector<cmSourceFile*> QtUiFilesWithOptions; unsigned int NumLastMatches; + + bool AddRequiredTargetCFeature(cmTarget *target, + const std::string& feature) const; + + bool AddRequiredTargetCxxFeature(cmTarget *target, + const std::string& feature) const; }; //---------------------------------------------------------------------------- diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 3f2ae9e..319b609 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -314,6 +314,9 @@ void cmTarget::SetMakefile(cmMakefile* mf) this->SetPropertyDefault("MACOSX_BUNDLE", 0); this->SetPropertyDefault("MACOSX_RPATH", 0); this->SetPropertyDefault("NO_SYSTEM_FROM_IMPORTED", 0); + this->SetPropertyDefault("C_STANDARD", 0); + this->SetPropertyDefault("C_STANDARD_REQUIRED", 0); + this->SetPropertyDefault("C_EXTENSIONS", 0); this->SetPropertyDefault("CXX_STANDARD", 0); this->SetPropertyDefault("CXX_STANDARD_REQUIRED", 0); this->SetPropertyDefault("CXX_EXTENSIONS", 0); diff --git a/Source/cmake.cxx b/Source/cmake.cxx index 3e78990..a83ebd5 100644 --- a/Source/cmake.cxx +++ b/Source/cmake.cxx @@ -2273,12 +2273,16 @@ const char *cmake::GetProperty(const std::string& prop, } this->SetProperty("ENABLED_LANGUAGES", lang.c_str()); } +#define STRING_LIST_ELEMENT(F) ";" #F + if (prop == "CMAKE_C_KNOWN_FEATURES") + { + return FOR_EACH_C_FEATURE(STRING_LIST_ELEMENT) + 1; + } if (prop == "CMAKE_CXX_KNOWN_FEATURES") { -#define STRING_LIST_ELEMENT(F) ";" #F return FOR_EACH_CXX_FEATURE(STRING_LIST_ELEMENT) + 1; -#undef STRING_LIST_ELEMENT } +#undef STRING_LIST_ELEMENT return this->Properties.GetPropertyValue(prop, scope, chain); } diff --git a/Source/cmake.h b/Source/cmake.h index 33b4f74..33a5d78 100644 --- a/Source/cmake.h +++ b/Source/cmake.h @@ -458,6 +458,12 @@ private: {"-Wno-dev", "Suppress developer warnings."},\ {"-Wdev", "Enable developer warnings."} +#define FOR_EACH_C_FEATURE(F) \ + F(c_function_prototypes) \ + F(c_restrict) \ + F(c_static_assert) \ + F(c_variadic_macros) + #define FOR_EACH_CXX_FEATURE(F) \ F(cxx_alias_templates) \ F(cxx_alignas) \ |