diff options
author | Stephen Kelly <steveire@gmail.com> | 2014-05-15 09:32:30 (GMT) |
---|---|---|
committer | Stephen Kelly <steveire@gmail.com> | 2014-05-21 15:22:32 (GMT) |
commit | 0dfe395e3cb1a720c4853087db554a6827feaadb (patch) | |
tree | 83d9cbe0ee9843bc4aa0012d9a7064a3522ba018 /Source/cmGeneratorExpressionEvaluator.cxx | |
parent | aa8a6fcee8c67b0516efcd745fb1d7a66d249096 (diff) | |
download | CMake-0dfe395e3cb1a720c4853087db554a6827feaadb.zip CMake-0dfe395e3cb1a720c4853087db554a6827feaadb.tar.gz CMake-0dfe395e3cb1a720c4853087db554a6827feaadb.tar.bz2 |
Features: Add COMPILE_FEATURES generator expression.
Allow setting build properties based on the features available
for a target. The availability of features is determined at
generate-time by evaluating the link implementation.
Ensure that the <LANG>_STANDARD determined while evaluating
COMPILE_FEATURES in the link implementation is not lower than that
provided by the INTERFACE of the link implementation. This is
similar to handling of transitive properties such as
POSITION_INDEPENDENT_CODE.
Diffstat (limited to 'Source/cmGeneratorExpressionEvaluator.cxx')
-rw-r--r-- | Source/cmGeneratorExpressionEvaluator.cxx | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/Source/cmGeneratorExpressionEvaluator.cxx b/Source/cmGeneratorExpressionEvaluator.cxx index a513921..0b357f6 100644 --- a/Source/cmGeneratorExpressionEvaluator.cxx +++ b/Source/cmGeneratorExpressionEvaluator.cxx @@ -1314,6 +1314,94 @@ static const struct TargetObjectsNode : public cmGeneratorExpressionNode } targetObjectsNode; //---------------------------------------------------------------------------- +static const struct CompileFeaturesNode : public cmGeneratorExpressionNode +{ + CompileFeaturesNode() {} + + virtual int NumExpectedParameters() const { return OneOrMoreParameters; } + + std::string Evaluate(const std::vector<std::string> ¶meters, + cmGeneratorExpressionContext *context, + const GeneratorExpressionContent *content, + cmGeneratorExpressionDAGChecker *dagChecker) const + { + cmTarget const* target = context->HeadTarget; + if (!target) + { + reportError(context, content->GetOriginalExpression(), + "$<COMPILE_FEATURE> may only be used with binary targets. It may " + "not be used with add_custom_command or add_custom_target."); + return std::string(); + } + + typedef std::map<std::string, std::vector<std::string> > LangMap; + static LangMap availableFeatures; + + LangMap testedFeatures; + + for (std::vector<std::string>::const_iterator it = parameters.begin(); + it != parameters.end(); ++it) + { + std::string error; + std::string lang; + if (!context->Makefile->CompileFeatureKnown(context->HeadTarget, + *it, lang, &error)) + { + reportError(context, content->GetOriginalExpression(), error); + return std::string(); + } + testedFeatures[lang].push_back(*it); + + if (availableFeatures.find(lang) == availableFeatures.end()) + { + const char* featuresKnown + = context->Makefile->CompileFeaturesAvailable(lang, &error); + if (!featuresKnown) + { + reportError(context, content->GetOriginalExpression(), error); + return std::string(); + } + cmSystemTools::ExpandListArgument(featuresKnown, + availableFeatures[lang]); + } + } + + bool evalLL = dagChecker && dagChecker->EvaluatingLinkLibraries(); + + std::string result; + + for (LangMap::const_iterator lit = testedFeatures.begin(); + lit != testedFeatures.end(); ++lit) + { + for (std::vector<std::string>::const_iterator it = lit->second.begin(); + it != lit->second.end(); ++it) + { + if (!context->Makefile->HaveFeatureAvailable(target, + lit->first, *it)) + { + if (evalLL) + { + const char* l = target->GetProperty(lit->first + "_STANDARD"); + if (!l) + { + l = context->Makefile + ->GetDefinition("CMAKE_" + lit->first + "_STANDARD_DEFAULT"); + } + assert(l); + context->MaxLanguageStandard[target][lit->first] = l; + } + else + { + return "0"; + } + } + } + } + return "1"; + } +} compileFeaturesNode; + +//---------------------------------------------------------------------------- static const char* targetPolicyWhitelist[] = { 0 #define TARGET_POLICY_STRING(POLICY) \ @@ -1647,6 +1735,7 @@ cmGeneratorExpressionNode* GetNode(const std::string &identifier) nodeMap["C_COMPILER_VERSION"] = &cCompilerVersionNode; nodeMap["CXX_COMPILER_VERSION"] = &cxxCompilerVersionNode; nodeMap["PLATFORM_ID"] = &platformIdNode; + nodeMap["COMPILE_FEATURES"] = &compileFeaturesNode; nodeMap["CONFIGURATION"] = &configurationNode; nodeMap["CONFIG"] = &configurationTestNode; nodeMap["TARGET_FILE"] = &targetFileNode; |