diff options
15 files changed, 47 insertions, 15 deletions
diff --git a/Help/prop_tgt/LANG_LINKER_LAUNCHER.rst b/Help/prop_tgt/LANG_LINKER_LAUNCHER.rst index f6ca5ad..d39ec20 100644 --- a/Help/prop_tgt/LANG_LINKER_LAUNCHER.rst +++ b/Help/prop_tgt/LANG_LINKER_LAUNCHER.rst @@ -14,3 +14,8 @@ arguments to the tool. This is useful for tools such as static analyzers. This property is initialized by the value of the :variable:`CMAKE_<LANG>_LINKER_LAUNCHER` variable if it is set when a target is created. + +.. versionadded:: 3.27 + + The property value may use + :manual:`generator expressions <cmake-generator-expressions(7)>`. diff --git a/Help/release/dev/lang-linker-launcher-genex.rst b/Help/release/dev/lang-linker-launcher-genex.rst new file mode 100644 index 0000000..b6494eb --- /dev/null +++ b/Help/release/dev/lang-linker-launcher-genex.rst @@ -0,0 +1,5 @@ +lang-linker-launcher-genex +-------------------------- + +* The :prop_tgt:`<LANG>_LINKER_LAUNCHER` target property now supports + :manual:`generator expressions <cmake-generator-expressions(7)>`. diff --git a/Source/cmCommonTargetGenerator.cxx b/Source/cmCommonTargetGenerator.cxx index 5fe6756..8f74ceb 100644 --- a/Source/cmCommonTargetGenerator.cxx +++ b/Source/cmCommonTargetGenerator.cxx @@ -7,6 +7,8 @@ #include <utility> #include "cmComputeLinkInformation.h" +#include "cmGeneratorExpression.h" +#include "cmGeneratorExpressionDAGChecker.h" #include "cmGeneratorTarget.h" #include "cmGlobalCommonGenerator.h" #include "cmGlobalGenerator.h" @@ -283,11 +285,17 @@ std::string cmCommonTargetGenerator::GetLinkerLauncher( const std::string& config) { std::string lang = this->GeneratorTarget->GetLinkerLanguage(config); - cmValue launcherProp = - this->GeneratorTarget->GetProperty(lang + "_LINKER_LAUNCHER"); + std::string propName = lang + "_LINKER_LAUNCHER"; + cmValue launcherProp = this->GeneratorTarget->GetProperty(propName); if (cmNonempty(launcherProp)) { + cmGeneratorExpressionDAGChecker dagChecker(this->GeneratorTarget, propName, + nullptr, nullptr); + std::string evaluatedLinklauncher = cmGeneratorExpression::Evaluate( + *launcherProp, this->LocalCommonGenerator, config, this->GeneratorTarget, + &dagChecker, this->GeneratorTarget, lang); // Convert ;-delimited list to single string - std::vector<std::string> args = cmExpandedList(*launcherProp, true); + std::vector<std::string> args = + cmExpandedList(evaluatedLinklauncher, true); if (!args.empty()) { args[0] = this->LocalCommonGenerator->ConvertToOutputFormat( args[0], cmOutputConverter::SHELL); diff --git a/Source/cmGeneratorExpressionDAGChecker.cxx b/Source/cmGeneratorExpressionDAGChecker.cxx index 6be5153..82a6c57 100644 --- a/Source/cmGeneratorExpressionDAGChecker.cxx +++ b/Source/cmGeneratorExpressionDAGChecker.cxx @@ -177,6 +177,15 @@ bool cmGeneratorExpressionDAGChecker::EvaluatingLinkOptionsExpression() const return property == "LINK_OPTIONS"_s; } +bool cmGeneratorExpressionDAGChecker::EvaluatingLinkerLauncher() const +{ + cm::string_view property(this->Top()->Property); + + return property.length() > cmStrLen("_LINKER_LAUNCHER") && + property.substr(property.length() - cmStrLen("_LINKER_LAUNCHER")) == + "_LINKER_LAUNCHER"_s; +} + bool cmGeneratorExpressionDAGChecker::EvaluatingLinkLibraries( cmGeneratorTarget const* tgt, ForGenex genex) const { diff --git a/Source/cmGeneratorExpressionDAGChecker.h b/Source/cmGeneratorExpressionDAGChecker.h index 55d131f..df1e005 100644 --- a/Source/cmGeneratorExpressionDAGChecker.h +++ b/Source/cmGeneratorExpressionDAGChecker.h @@ -70,6 +70,7 @@ struct cmGeneratorExpressionDAGChecker bool EvaluatingCompileExpression() const; bool EvaluatingLinkExpression() const; bool EvaluatingLinkOptionsExpression() const; + bool EvaluatingLinkerLauncher() const; enum class ForGenex { diff --git a/Source/cmGeneratorExpressionNode.cxx b/Source/cmGeneratorExpressionNode.cxx index 6595323..4c6dda9 100644 --- a/Source/cmGeneratorExpressionNode.cxx +++ b/Source/cmGeneratorExpressionNode.cxx @@ -1548,7 +1548,8 @@ static const struct LinkLanguageNode : public cmGeneratorExpressionNode { if (!context->HeadTarget || !dagChecker || !(dagChecker->EvaluatingLinkExpression() || - dagChecker->EvaluatingLinkLibraries())) { + dagChecker->EvaluatingLinkLibraries() || + dagChecker->EvaluatingLinkerLauncher())) { reportError(context, content->GetOriginalExpression(), "$<LINK_LANGUAGE:...> may only be used with binary targets " "to specify link libraries, link directories, link options " @@ -1641,7 +1642,8 @@ static const struct LinkLanguageAndIdNode : public cmGeneratorExpressionNode { if (!context->HeadTarget || !dagChecker || !(dagChecker->EvaluatingLinkExpression() || - dagChecker->EvaluatingLinkLibraries())) { + dagChecker->EvaluatingLinkLibraries() || + dagChecker->EvaluatingLinkerLauncher())) { reportError( context, content->GetOriginalExpression(), "$<LINK_LANG_AND_ID:lang,id> may only be used with binary targets " @@ -2098,7 +2100,8 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode if (dagCheckerParent) { if (dagCheckerParent->EvaluatingGenexExpression() || - dagCheckerParent->EvaluatingPICExpression()) { + dagCheckerParent->EvaluatingPICExpression() || + dagCheckerParent->EvaluatingLinkerLauncher()) { // No check required. } else if (dagCheckerParent->EvaluatingLinkLibraries()) { evaluatingLinkLibraries = true; diff --git a/Tests/RunCMake/LinkerLauncher/C-env-Build-stdout.txt b/Tests/RunCMake/LinkerLauncher/C-env-Build-stdout.txt index 3313e31..544b65f 100644 --- a/Tests/RunCMake/LinkerLauncher/C-env-Build-stdout.txt +++ b/Tests/RunCMake/LinkerLauncher/C-env-Build-stdout.txt @@ -1 +1 @@ -.*-E env USED_LAUNCHER=1.* +.*-E env USED_LAUNCHER=1 TARGET_NAME=main LANGUAGE=C.* diff --git a/Tests/RunCMake/LinkerLauncher/C-launch-env-Build-stdout.txt b/Tests/RunCMake/LinkerLauncher/C-launch-env-Build-stdout.txt index 3313e31..544b65f 100644 --- a/Tests/RunCMake/LinkerLauncher/C-launch-env-Build-stdout.txt +++ b/Tests/RunCMake/LinkerLauncher/C-launch-env-Build-stdout.txt @@ -1 +1 @@ -.*-E env USED_LAUNCHER=1.* +.*-E env USED_LAUNCHER=1 TARGET_NAME=main LANGUAGE=C.* diff --git a/Tests/RunCMake/LinkerLauncher/CXX-env-Build-stdout.txt b/Tests/RunCMake/LinkerLauncher/CXX-env-Build-stdout.txt index 3313e31..082c7b5 100644 --- a/Tests/RunCMake/LinkerLauncher/CXX-env-Build-stdout.txt +++ b/Tests/RunCMake/LinkerLauncher/CXX-env-Build-stdout.txt @@ -1 +1 @@ -.*-E env USED_LAUNCHER=1.* +.*-E env USED_LAUNCHER=1 TARGET_NAME=main LANGUAGE=CXX.* diff --git a/Tests/RunCMake/LinkerLauncher/CXX-launch-env-Build-stdout.txt b/Tests/RunCMake/LinkerLauncher/CXX-launch-env-Build-stdout.txt index 3313e31..082c7b5 100644 --- a/Tests/RunCMake/LinkerLauncher/CXX-launch-env-Build-stdout.txt +++ b/Tests/RunCMake/LinkerLauncher/CXX-launch-env-Build-stdout.txt @@ -1 +1 @@ -.*-E env USED_LAUNCHER=1.* +.*-E env USED_LAUNCHER=1 TARGET_NAME=main LANGUAGE=CXX.* diff --git a/Tests/RunCMake/LinkerLauncher/OBJC-env-Build-stdout.txt b/Tests/RunCMake/LinkerLauncher/OBJC-env-Build-stdout.txt index 3313e31..d2efd3d 100644 --- a/Tests/RunCMake/LinkerLauncher/OBJC-env-Build-stdout.txt +++ b/Tests/RunCMake/LinkerLauncher/OBJC-env-Build-stdout.txt @@ -1 +1 @@ -.*-E env USED_LAUNCHER=1.* +.*-E env USED_LAUNCHER=1 TARGET_NAME=main LANGUAGE=OBJC.* diff --git a/Tests/RunCMake/LinkerLauncher/OBJC-launch-env-Build-stdout.txt b/Tests/RunCMake/LinkerLauncher/OBJC-launch-env-Build-stdout.txt index 3313e31..d2efd3d 100644 --- a/Tests/RunCMake/LinkerLauncher/OBJC-launch-env-Build-stdout.txt +++ b/Tests/RunCMake/LinkerLauncher/OBJC-launch-env-Build-stdout.txt @@ -1 +1 @@ -.*-E env USED_LAUNCHER=1.* +.*-E env USED_LAUNCHER=1 TARGET_NAME=main LANGUAGE=OBJC.* diff --git a/Tests/RunCMake/LinkerLauncher/OBJCXX-env-Build-stdout.txt b/Tests/RunCMake/LinkerLauncher/OBJCXX-env-Build-stdout.txt index 3313e31..0082ab2 100644 --- a/Tests/RunCMake/LinkerLauncher/OBJCXX-env-Build-stdout.txt +++ b/Tests/RunCMake/LinkerLauncher/OBJCXX-env-Build-stdout.txt @@ -1 +1 @@ -.*-E env USED_LAUNCHER=1.* +.*-E env USED_LAUNCHER=1 TARGET_NAME=main LANGUAGE=OBJCXX.* diff --git a/Tests/RunCMake/LinkerLauncher/OBJCXX-launch-env-Build-stdout.txt b/Tests/RunCMake/LinkerLauncher/OBJCXX-launch-env-Build-stdout.txt index 3313e31..0082ab2 100644 --- a/Tests/RunCMake/LinkerLauncher/OBJCXX-launch-env-Build-stdout.txt +++ b/Tests/RunCMake/LinkerLauncher/OBJCXX-launch-env-Build-stdout.txt @@ -1 +1 @@ -.*-E env USED_LAUNCHER=1.* +.*-E env USED_LAUNCHER=1 TARGET_NAME=main LANGUAGE=OBJCXX.* diff --git a/Tests/RunCMake/LinkerLauncher/RunCMakeTest.cmake b/Tests/RunCMake/LinkerLauncher/RunCMakeTest.cmake index 8f2bf63..025f367 100644 --- a/Tests/RunCMake/LinkerLauncher/RunCMakeTest.cmake +++ b/Tests/RunCMake/LinkerLauncher/RunCMakeTest.cmake @@ -17,7 +17,8 @@ endfunction() function(run_linker_launcher_env lang) string(REGEX REPLACE "-.*" "" core_lang "${lang}") - set(ENV{CMAKE_${core_lang}_LINKER_LAUNCHER} "${CMAKE_COMMAND};-E;env;USED_LAUNCHER=1") + # Use the noop genexp $<PATH:...> genexp to validate genexp support. + set(ENV{CMAKE_${core_lang}_LINKER_LAUNCHER} "$<PATH:CMAKE_PATH,${CMAKE_COMMAND}>;-E;env;USED_LAUNCHER=1;TARGET_NAME=$<TARGET_PROPERTY:NAME>;LANGUAGE=$<LINK_LANGUAGE>") run_linker_launcher(${lang}) unset(ENV{CMAKE_${core_lang}_LINKER_LAUNCHER}) endfunction() |