diff options
author | Brad King <brad.king@kitware.com> | 2019-05-02 13:42:59 (GMT) |
---|---|---|
committer | Kitware Robot <kwrobot@kitware.com> | 2019-05-02 13:43:09 (GMT) |
commit | e08efc36eb17992f4bb8697b4173ede913aafab4 (patch) | |
tree | 6ee74eeb2a0b5b33d13fe48192815ec1b2587ad2 /Source/cmGeneratorExpressionNode.cxx | |
parent | 3b4315dc23bdedb3163a0c84b9fdbae2324470c6 (diff) | |
parent | 3d856eba16fae90f66dd142f91c21d4121b760d0 (diff) | |
download | CMake-e08efc36eb17992f4bb8697b4173ede913aafab4.zip CMake-e08efc36eb17992f4bb8697b4173ede913aafab4.tar.gz CMake-e08efc36eb17992f4bb8697b4173ede913aafab4.tar.bz2 |
Merge topic 'genex-code-cleanup'
3d856eba16 cmGeneratorExpressionNode: refactor TargetPropertyNode
9e1df5df54 cmGeneratorExpressionNode: use ctor arguments instead of macro
36f36d6a49 cmGeneratorExpressionNode: add VersionNode
3f57787dff cmGeneratorExpressionNode: remove structs CompilerId*, CompilerVersion*
20d7c5631e cmGeneratorExpressionNode: add CharacterNode
abd62201bd cmGeneratorExpressionNode: simplify code in EqualNode
f2c8ff8259 cmGeneratorExpressionNode: Simplify static string constant
Acked-by: Kitware Robot <kwrobot@kitware.com>
Merge-request: !3234
Diffstat (limited to 'Source/cmGeneratorExpressionNode.cxx')
-rw-r--r-- | Source/cmGeneratorExpressionNode.cxx | 591 |
1 files changed, 175 insertions, 416 deletions
diff --git a/Source/cmGeneratorExpressionNode.cxx b/Source/cmGeneratorExpressionNode.cxx index 8803830..06e02aa 100644 --- a/Source/cmGeneratorExpressionNode.cxx +++ b/Source/cmGeneratorExpressionNode.cxx @@ -21,10 +21,13 @@ #include "cmStateTypes.h" #include "cmSystemTools.h" #include "cmTarget.h" +#include "cm_static_string_view.hxx" +#include "cm_string_view.hxx" #include "cmake.h" #include "cmsys/RegularExpression.hxx" #include "cmsys/String.h" + #include <algorithm> #include <assert.h> #include <errno.h> @@ -96,36 +99,42 @@ static const struct OneNode buildInterfaceNode; static const struct ZeroNode installInterfaceNode; -#define BOOLEAN_OP_NODE(OPNAME, OP, SUCCESS_VALUE, FAILURE_VALUE) \ - static const struct OP##Node : public cmGeneratorExpressionNode \ - { \ - OP##Node() {} /* NOLINT(modernize-use-equals-default) */ \ - virtual int NumExpectedParameters() const { return OneOrMoreParameters; } \ - \ - std::string Evaluate(const std::vector<std::string>& parameters, \ - cmGeneratorExpressionContext* context, \ - const GeneratorExpressionContent* content, \ - cmGeneratorExpressionDAGChecker*) const \ - { \ - for (std::string const& param : parameters) { \ - if (param == #FAILURE_VALUE) { \ - return #FAILURE_VALUE; \ - } \ - if (param != #SUCCESS_VALUE) { \ - reportError(context, content->GetOriginalExpression(), \ - "Parameters to $<" #OP \ - "> must resolve to either '0' or '1'."); \ - return std::string(); \ - } \ - } \ - return #SUCCESS_VALUE; \ - } \ - } OPNAME; - -BOOLEAN_OP_NODE(andNode, AND, 1, 0) -BOOLEAN_OP_NODE(orNode, OR, 0, 1) - -#undef BOOLEAN_OP_NODE +struct BooleanOpNode : public cmGeneratorExpressionNode +{ + BooleanOpNode(const char* op_, const char* successVal_, + const char* failureVal_) + : op(op_) + , successVal(successVal_) + , failureVal(failureVal_) + { + } + + int NumExpectedParameters() const override { return OneOrMoreParameters; } + + std::string Evaluate(const std::vector<std::string>& parameters, + cmGeneratorExpressionContext* context, + const GeneratorExpressionContent* content, + cmGeneratorExpressionDAGChecker*) const override + { + for (std::string const& param : parameters) { + if (param == this->failureVal) { + return this->failureVal; + } + if (param != this->successVal) { + std::ostringstream e; + e << "Parameters to $<" << this->op; + e << "> must resolve to either '0' or '1'."; + reportError(context, content->GetOriginalExpression(), e.str()); + return std::string(); + } + } + return this->successVal; + } + + const char *const op, *const successVal, *const failureVal; +}; + +static const BooleanOpNode andNode("AND", "1", "0"), orNode("OR", "0", "1"); static const struct NotNode : public cmGeneratorExpressionNode { @@ -212,69 +221,44 @@ static const struct EqualNode : public cmGeneratorExpressionNode const GeneratorExpressionContent* content, cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override { - char* pEnd; - - int base = 0; - bool flipSign = false; - - const char* lhs = parameters[0].c_str(); - if (cmHasLiteralPrefix(lhs, "0b") || cmHasLiteralPrefix(lhs, "0B")) { - base = 2; - lhs += 2; - } - if (cmHasLiteralPrefix(lhs, "-0b") || cmHasLiteralPrefix(lhs, "-0B")) { - base = 2; - lhs += 3; - flipSign = true; - } - if (cmHasLiteralPrefix(lhs, "+0b") || cmHasLiteralPrefix(lhs, "+0B")) { - base = 2; - lhs += 3; - } - - long lnum = strtol(lhs, &pEnd, base); - if (pEnd == lhs || *pEnd != '\0' || errno == ERANGE) { - reportError(context, content->GetOriginalExpression(), - "$<EQUAL> parameter " + parameters[0] + - " is not a valid integer."); - return std::string(); - } - - if (flipSign) { - lnum = -lnum; + long numbers[2]; + for (int i = 0; i < 2; ++i) { + if (!ParameterToLong(parameters[i].c_str(), &numbers[i])) { + reportError(context, content->GetOriginalExpression(), + "$<EQUAL> parameter " + parameters[i] + + " is not a valid integer."); + return {}; + } } + return numbers[0] == numbers[1] ? "1" : "0"; + } - base = 0; - flipSign = false; + static bool ParameterToLong(const char* param, long* outResult) + { + const char isNegative = param[0] == '-'; - const char* rhs = parameters[1].c_str(); - if (cmHasLiteralPrefix(rhs, "0b") || cmHasLiteralPrefix(rhs, "0B")) { - base = 2; - rhs += 2; - } - if (cmHasLiteralPrefix(rhs, "-0b") || cmHasLiteralPrefix(rhs, "-0B")) { + int base = 0; + if (cmHasLiteralPrefix(param, "0b") || cmHasLiteralPrefix(param, "0B")) { base = 2; - rhs += 3; - flipSign = true; - } - if (cmHasLiteralPrefix(rhs, "+0b") || cmHasLiteralPrefix(rhs, "+0B")) { + param += 2; + } else if (cmHasLiteralPrefix(param, "-0b") || + cmHasLiteralPrefix(param, "-0B") || + cmHasLiteralPrefix(param, "+0b") || + cmHasLiteralPrefix(param, "+0B")) { base = 2; - rhs += 3; + param += 3; } - long rnum = strtol(rhs, &pEnd, base); - if (pEnd == rhs || *pEnd != '\0' || errno == ERANGE) { - reportError(context, content->GetOriginalExpression(), - "$<EQUAL> parameter " + parameters[1] + - " is not a valid integer."); - return std::string(); + char* pEnd; + long result = strtol(param, &pEnd, base); + if (pEnd == param || *pEnd != '\0' || errno == ERANGE) { + return false; } - - if (flipSign) { - rnum = -rnum; + if (isNegative && result > 0) { + result *= -1; } - - return lnum == rnum ? "1" : "0"; + *outResult = result; + return true; } } equalNode; @@ -621,9 +605,10 @@ static const struct MakeCIdentifierNode : public cmGeneratorExpressionNode } } makeCIdentifierNode; -static const struct Angle_RNode : public cmGeneratorExpressionNode +template <char C> +struct CharacterNode : public cmGeneratorExpressionNode { - Angle_RNode() {} // NOLINT(modernize-use-equals-default) + CharacterNode() {} // NOLINT(modernize-use-equals-default) int NumExpectedParameters() const override { return 0; } @@ -633,47 +618,39 @@ static const struct Angle_RNode : public cmGeneratorExpressionNode const GeneratorExpressionContent* /*content*/, cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override { - return ">"; + return { C }; } -} angle_rNode; +}; +static const CharacterNode<'>'> angle_rNode; +static const CharacterNode<','> commaNode; +static const CharacterNode<';'> semicolonNode; -static const struct CommaNode : public cmGeneratorExpressionNode +struct CompilerIdNode : public cmGeneratorExpressionNode { - CommaNode() {} // NOLINT(modernize-use-equals-default) - - int NumExpectedParameters() const override { return 0; } - - std::string Evaluate( - const std::vector<std::string>& /*parameters*/, - cmGeneratorExpressionContext* /*context*/, - const GeneratorExpressionContent* /*content*/, - cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override + CompilerIdNode(const char* compilerLang) + : CompilerLanguage(compilerLang) { - return ","; } -} commaNode; -static const struct SemicolonNode : public cmGeneratorExpressionNode -{ - SemicolonNode() {} // NOLINT(modernize-use-equals-default) - - int NumExpectedParameters() const override { return 0; } + int NumExpectedParameters() const override { return OneOrZeroParameters; } std::string Evaluate( - const std::vector<std::string>& /*parameters*/, - cmGeneratorExpressionContext* /*context*/, - const GeneratorExpressionContent* /*content*/, - cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override + const std::vector<std::string>& parameters, + cmGeneratorExpressionContext* context, + const GeneratorExpressionContent* content, + cmGeneratorExpressionDAGChecker* dagChecker) const override { - return ";"; + if (!context->HeadTarget) { + std::ostringstream e; + e << "$<" << this->CompilerLanguage + << "_COMPILER_ID> may only be used with binary targets. It may " + "not be used with add_custom_command or add_custom_target."; + reportError(context, content->GetOriginalExpression(), e.str()); + return {}; + } + return this->EvaluateWithLanguage(parameters, context, content, dagChecker, + this->CompilerLanguage); } -} semicolonNode; - -struct CompilerIdNode : public cmGeneratorExpressionNode -{ - CompilerIdNode() {} // NOLINT(modernize-use-equals-default) - - int NumExpectedParameters() const override { return OneOrZeroParameters; } std::string EvaluateWithLanguage(const std::vector<std::string>& parameters, cmGeneratorExpressionContext* context, @@ -721,77 +698,21 @@ struct CompilerIdNode : public cmGeneratorExpressionNode } return "0"; } -}; - -static const struct CCompilerIdNode : public CompilerIdNode -{ - CCompilerIdNode() {} // NOLINT(modernize-use-equals-default) - std::string Evaluate( - const std::vector<std::string>& parameters, - cmGeneratorExpressionContext* context, - const GeneratorExpressionContent* content, - cmGeneratorExpressionDAGChecker* dagChecker) const override - { - if (!context->HeadTarget) { - reportError( - context, content->GetOriginalExpression(), - "$<C_COMPILER_ID> may only be used with binary targets. It may " - "not be used with add_custom_command or add_custom_target."); - return std::string(); - } - return this->EvaluateWithLanguage(parameters, context, content, dagChecker, - "C"); - } -} cCompilerIdNode; + const char* const CompilerLanguage; +}; -static const struct CXXCompilerIdNode : public CompilerIdNode -{ - CXXCompilerIdNode() {} // NOLINT(modernize-use-equals-default) +static const CompilerIdNode cCompilerIdNode("C"), cxxCompilerIdNode("CXX"), + cudaCompilerIdNode("CUDA"), fortranCompilerIdNode("Fortran"); - std::string Evaluate( - const std::vector<std::string>& parameters, - cmGeneratorExpressionContext* context, - const GeneratorExpressionContent* content, - cmGeneratorExpressionDAGChecker* dagChecker) const override - { - if (!context->HeadTarget) { - reportError( - context, content->GetOriginalExpression(), - "$<CXX_COMPILER_ID> may only be used with binary targets. It may " - "not be used with add_custom_command or add_custom_target."); - return std::string(); - } - return this->EvaluateWithLanguage(parameters, context, content, dagChecker, - "CXX"); - } -} cxxCompilerIdNode; - -static const struct CUDACompilerIdNode : public CompilerIdNode +struct CompilerVersionNode : public cmGeneratorExpressionNode { - CUDACompilerIdNode() {} // NOLINT(modernize-use-equals-default) - - std::string Evaluate( - const std::vector<std::string>& parameters, - cmGeneratorExpressionContext* context, - const GeneratorExpressionContent* content, - cmGeneratorExpressionDAGChecker* dagChecker) const override + CompilerVersionNode(const char* compilerLang) + : CompilerLanguage(compilerLang) { - if (!context->HeadTarget) { - reportError( - context, content->GetOriginalExpression(), - "$<CUDA_COMPILER_ID> may only be used with binary targets. It may " - "not be used with add_custom_command or add_custom_target."); - return std::string(); - } - return this->EvaluateWithLanguage(parameters, context, content, dagChecker, - "CUDA"); } -} cudaCompilerIdNode; -static const struct FortranCompilerIdNode : public CompilerIdNode -{ - FortranCompilerIdNode() {} // NOLINT(modernize-use-equals-default) + int NumExpectedParameters() const override { return OneOrZeroParameters; } std::string Evaluate( const std::vector<std::string>& parameters, @@ -800,22 +721,16 @@ static const struct FortranCompilerIdNode : public CompilerIdNode cmGeneratorExpressionDAGChecker* dagChecker) const override { if (!context->HeadTarget) { - reportError( - context, content->GetOriginalExpression(), - "$<Fortran_COMPILER_ID> may only be used with binary targets. It may " - "not be used with add_custom_command or add_custom_target."); - return std::string(); + std::ostringstream e; + e << "$<" << this->CompilerLanguage + << "_COMPILER_VERSION> may only be used with binary targets. It " + "may not be used with add_custom_command or add_custom_target."; + reportError(context, content->GetOriginalExpression(), e.str()); + return {}; } return this->EvaluateWithLanguage(parameters, context, content, dagChecker, - "Fortran"); + this->CompilerLanguage); } -} fortranCompilerIdNode; - -struct CompilerVersionNode : public cmGeneratorExpressionNode -{ - CompilerVersionNode() {} // NOLINT(modernize-use-equals-default) - - int NumExpectedParameters() const override { return OneOrZeroParameters; } std::string EvaluateWithLanguage(const std::vector<std::string>& parameters, cmGeneratorExpressionContext* context, @@ -834,7 +749,7 @@ struct CompilerVersionNode : public cmGeneratorExpressionNode if (!compilerIdValidator.find(parameters.front())) { reportError(context, content->GetOriginalExpression(), "Expression syntax not recognized."); - return std::string(); + return {}; } if (compilerVersion.empty()) { return parameters.front().empty() ? "1" : "0"; @@ -846,95 +761,13 @@ struct CompilerVersionNode : public cmGeneratorExpressionNode ? "1" : "0"; } -}; - -static const struct CCompilerVersionNode : public CompilerVersionNode -{ - CCompilerVersionNode() {} // NOLINT(modernize-use-equals-default) - - std::string Evaluate( - const std::vector<std::string>& parameters, - cmGeneratorExpressionContext* context, - const GeneratorExpressionContent* content, - cmGeneratorExpressionDAGChecker* dagChecker) const override - { - if (!context->HeadTarget) { - reportError( - context, content->GetOriginalExpression(), - "$<C_COMPILER_VERSION> may only be used with binary targets. It " - "may not be used with add_custom_command or add_custom_target."); - return std::string(); - } - return this->EvaluateWithLanguage(parameters, context, content, dagChecker, - "C"); - } -} cCompilerVersionNode; -static const struct CXXCompilerVersionNode : public CompilerVersionNode -{ - CXXCompilerVersionNode() {} // NOLINT(modernize-use-equals-default) - - std::string Evaluate( - const std::vector<std::string>& parameters, - cmGeneratorExpressionContext* context, - const GeneratorExpressionContent* content, - cmGeneratorExpressionDAGChecker* dagChecker) const override - { - if (!context->HeadTarget) { - reportError( - context, content->GetOriginalExpression(), - "$<CXX_COMPILER_VERSION> may only be used with binary targets. It " - "may not be used with add_custom_command or add_custom_target."); - return std::string(); - } - return this->EvaluateWithLanguage(parameters, context, content, dagChecker, - "CXX"); - } -} cxxCompilerVersionNode; - -static const struct CUDACompilerVersionNode : public CompilerVersionNode -{ - CUDACompilerVersionNode() {} // NOLINT(modernize-use-equals-default) - - std::string Evaluate( - const std::vector<std::string>& parameters, - cmGeneratorExpressionContext* context, - const GeneratorExpressionContent* content, - cmGeneratorExpressionDAGChecker* dagChecker) const override - { - if (!context->HeadTarget) { - reportError( - context, content->GetOriginalExpression(), - "$<CUDA_COMPILER_VERSION> may only be used with binary targets. It " - "may not be used with add_custom_command or add_custom_target."); - return std::string(); - } - return this->EvaluateWithLanguage(parameters, context, content, dagChecker, - "CUDA"); - } -} cudaCompilerVersionNode; - -static const struct FortranCompilerVersionNode : public CompilerVersionNode -{ - FortranCompilerVersionNode() {} // NOLINT(modernize-use-equals-default) + const char* const CompilerLanguage; +}; - std::string Evaluate( - const std::vector<std::string>& parameters, - cmGeneratorExpressionContext* context, - const GeneratorExpressionContent* content, - cmGeneratorExpressionDAGChecker* dagChecker) const override - { - if (!context->HeadTarget) { - reportError( - context, content->GetOriginalExpression(), - "$<Fortran_COMPILER_VERSION> may only be used with binary targets. " - "It may not be used with add_custom_command or add_custom_target."); - return std::string(); - } - return this->EvaluateWithLanguage(parameters, context, content, dagChecker, - "Fortran"); - } -} fortranCompilerVersionNode; +static const CompilerVersionNode cCompilerVersionNode("C"), + cxxCompilerVersionNode("CXX"), cudaCompilerVersionNode("CUDA"), + fortranCompilerVersionNode("Fortran"); struct PlatformIdNode : public cmGeneratorExpressionNode { @@ -965,69 +798,10 @@ struct PlatformIdNode : public cmGeneratorExpressionNode } } platformIdNode; -static const struct VersionGreaterNode : public cmGeneratorExpressionNode -{ - VersionGreaterNode() {} // NOLINT(modernize-use-equals-default) - - int NumExpectedParameters() const override { return 2; } - - std::string Evaluate( - const std::vector<std::string>& parameters, - cmGeneratorExpressionContext* /*context*/, - const GeneratorExpressionContent* /*content*/, - cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override - { - return cmSystemTools::VersionCompare(cmSystemTools::OP_GREATER, - parameters.front().c_str(), - parameters[1].c_str()) - ? "1" - : "0"; - } -} versionGreaterNode; - -static const struct VersionGreaterEqNode : public cmGeneratorExpressionNode -{ - VersionGreaterEqNode() {} // NOLINT(modernize-use-equals-default) - - int NumExpectedParameters() const override { return 2; } - - std::string Evaluate( - const std::vector<std::string>& parameters, - cmGeneratorExpressionContext* /*context*/, - const GeneratorExpressionContent* /*content*/, - cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override - { - return cmSystemTools::VersionCompare(cmSystemTools::OP_GREATER_EQUAL, - parameters.front().c_str(), - parameters[1].c_str()) - ? "1" - : "0"; - } -} versionGreaterEqNode; - -static const struct VersionLessNode : public cmGeneratorExpressionNode -{ - VersionLessNode() {} // NOLINT(modernize-use-equals-default) - - int NumExpectedParameters() const override { return 2; } - - std::string Evaluate( - const std::vector<std::string>& parameters, - cmGeneratorExpressionContext* /*context*/, - const GeneratorExpressionContent* /*content*/, - cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override - { - return cmSystemTools::VersionCompare(cmSystemTools::OP_LESS, - parameters.front().c_str(), - parameters[1].c_str()) - ? "1" - : "0"; - } -} versionLessNode; - -static const struct VersionLessEqNode : public cmGeneratorExpressionNode +template <cmSystemTools::CompareOp Op> +struct VersionNode : public cmGeneratorExpressionNode { - VersionLessEqNode() {} // NOLINT(modernize-use-equals-default) + VersionNode() {} // NOLINT(modernize-use-equals-default) int NumExpectedParameters() const override { return 2; } @@ -1037,33 +811,18 @@ static const struct VersionLessEqNode : public cmGeneratorExpressionNode const GeneratorExpressionContent* /*content*/, cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override { - return cmSystemTools::VersionCompare(cmSystemTools::OP_LESS_EQUAL, - parameters.front().c_str(), + return cmSystemTools::VersionCompare(Op, parameters.front().c_str(), parameters[1].c_str()) ? "1" : "0"; } -} versionLessEqNode; +}; -static const struct VersionEqualNode : public cmGeneratorExpressionNode -{ - VersionEqualNode() {} // NOLINT(modernize-use-equals-default) - - int NumExpectedParameters() const override { return 2; } - - std::string Evaluate( - const std::vector<std::string>& parameters, - cmGeneratorExpressionContext* /*context*/, - const GeneratorExpressionContent* /*content*/, - cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override - { - return cmSystemTools::VersionCompare(cmSystemTools::OP_EQUAL, - parameters.front().c_str(), - parameters[1].c_str()) - ? "1" - : "0"; - } -} versionEqualNode; +static const VersionNode<cmSystemTools::OP_GREATER> versionGreaterNode; +static const VersionNode<cmSystemTools::OP_GREATER_EQUAL> versionGreaterEqNode; +static const VersionNode<cmSystemTools::OP_LESS> versionLessNode; +static const VersionNode<cmSystemTools::OP_LESS_EQUAL> versionLessEqNode; +static const VersionNode<cmSystemTools::OP_EQUAL> versionEqualNode; static const struct LinkOnlyNode : public cmGeneratorExpressionNode { @@ -1270,73 +1029,54 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode // This node handles errors on parameter count itself. int NumExpectedParameters() const override { return OneOrMoreParameters; } + static const char* GetErrorText(std::string const& targetName, + std::string const& propertyName) + { + static cmsys::RegularExpression propertyNameValidator("^[A-Za-z0-9_]+$"); + if (targetName.empty() && propertyName.empty()) { + return "$<TARGET_PROPERTY:tgt,prop> expression requires a non-empty " + "target name and property name."; + } + if (targetName.empty()) { + return "$<TARGET_PROPERTY:tgt,prop> expression requires a non-empty " + "target name."; + } + if (!cmGeneratorExpression::IsValidTargetName(targetName)) { + if (!propertyNameValidator.find(propertyName)) { + return "Target name and property name not supported."; + } + return "Target name not supported."; + } + return nullptr; + } + std::string Evaluate( const std::vector<std::string>& parameters, cmGeneratorExpressionContext* context, const GeneratorExpressionContent* content, cmGeneratorExpressionDAGChecker* dagCheckerParent) const override { - if (parameters.size() != 1 && parameters.size() != 2) { - reportError( - context, content->GetOriginalExpression(), - "$<TARGET_PROPERTY:...> expression requires one or two parameters"); - return std::string(); - } static cmsys::RegularExpression propertyNameValidator("^[A-Za-z0-9_]+$"); - cmGeneratorTarget const* target = context->HeadTarget; - std::string propertyName = parameters.front(); - - if (parameters.size() == 1) { - context->HadHeadSensitiveCondition = true; - } - if (!target && parameters.size() == 1) { - reportError( - context, content->GetOriginalExpression(), - "$<TARGET_PROPERTY:prop> may only be used with binary targets. " - "It may not be used with add_custom_command or add_custom_target. " - "Specify the target to read a property from using the " - "$<TARGET_PROPERTY:tgt,prop> signature instead."); - return std::string(); - } + cmGeneratorTarget const* target = nullptr; + std::string targetName, propertyName; if (parameters.size() == 2) { - if (parameters.front().empty() && parameters[1].empty()) { - reportError( - context, content->GetOriginalExpression(), - "$<TARGET_PROPERTY:tgt,prop> expression requires a non-empty " - "target name and property name."); - return std::string(); - } - if (parameters.front().empty()) { - reportError( - context, content->GetOriginalExpression(), - "$<TARGET_PROPERTY:tgt,prop> expression requires a non-empty " - "target name."); - return std::string(); - } - - std::string targetName = parameters.front(); + targetName = parameters[0]; propertyName = parameters[1]; - if (!cmGeneratorExpression::IsValidTargetName(targetName)) { - if (!propertyNameValidator.find(propertyName)) { - ::reportError(context, content->GetOriginalExpression(), - "Target name and property name not supported."); - return std::string(); - } - ::reportError(context, content->GetOriginalExpression(), - "Target name not supported."); + + if (const char* e = GetErrorText(targetName, propertyName)) { + reportError(context, content->GetOriginalExpression(), e); return std::string(); } - static const std::string propALIASED_TARGET = "ALIASED_TARGET"; - if (propertyName == propALIASED_TARGET) { + if (propertyName == "ALIASED_TARGET"_s) { if (context->LG->GetMakefile()->IsAlias(targetName)) { if (cmGeneratorTarget* tgt = context->LG->FindGeneratorTargetToUse(targetName)) { return tgt->GetName(); } } - return ""; + return std::string(); } target = context->LG->FindGeneratorTargetToUse(targetName); @@ -1347,15 +1087,34 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode return std::string(); } context->AllTargets.insert(target); - } - if (target == context->HeadTarget) { + } else if (parameters.size() == 1) { + target = context->HeadTarget; + propertyName = parameters[0]; + // Keep track of the properties seen while processing. // The evaluation of the LINK_LIBRARIES generator expressions // will check this to ensure that properties have one consistent // value for all evaluations. context->SeenTargetProperties.insert(propertyName); + + context->HadHeadSensitiveCondition = true; + if (!target) { + reportError( + context, content->GetOriginalExpression(), + "$<TARGET_PROPERTY:prop> may only be used with binary targets. " + "It may not be used with add_custom_command or add_custom_target. " + "Specify the target to read a property from using the " + "$<TARGET_PROPERTY:tgt,prop> signature instead."); + return std::string(); + } + } else { + reportError( + context, content->GetOriginalExpression(), + "$<TARGET_PROPERTY:...> expression requires one or two parameters"); + return std::string(); } + if (propertyName == "SOURCES") { context->SourceSensitiveTargets.insert(target); } |