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/cmMakefile.cxx | |
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/cmMakefile.cxx')
-rw-r--r-- | Source/cmMakefile.cxx | 116 |
1 files changed, 114 insertions, 2 deletions
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; +} |