1
0
mirror of https://github.com/Kitware/CMake.git synced 2025-10-21 23:00:50 +08:00

<LANG>_LINKER_LAUNCHER: Allow generator expressions

This commit is contained in:
Kyle Edwards
2023-02-02 11:40:01 -05:00
parent 84ada0b0c9
commit 33e27f6ca6
15 changed files with 47 additions and 15 deletions

View File

@@ -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 This property is initialized by the value of the
:variable:`CMAKE_<LANG>_LINKER_LAUNCHER` variable if it is set when a target is :variable:`CMAKE_<LANG>_LINKER_LAUNCHER` variable if it is set when a target is
created. created.
.. versionadded:: 3.27
The property value may use
:manual:`generator expressions <cmake-generator-expressions(7)>`.

View File

@@ -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)>`.

View File

@@ -7,6 +7,8 @@
#include <utility> #include <utility>
#include "cmComputeLinkInformation.h" #include "cmComputeLinkInformation.h"
#include "cmGeneratorExpression.h"
#include "cmGeneratorExpressionDAGChecker.h"
#include "cmGeneratorTarget.h" #include "cmGeneratorTarget.h"
#include "cmGlobalCommonGenerator.h" #include "cmGlobalCommonGenerator.h"
#include "cmGlobalGenerator.h" #include "cmGlobalGenerator.h"
@@ -283,11 +285,17 @@ std::string cmCommonTargetGenerator::GetLinkerLauncher(
const std::string& config) const std::string& config)
{ {
std::string lang = this->GeneratorTarget->GetLinkerLanguage(config); std::string lang = this->GeneratorTarget->GetLinkerLanguage(config);
cmValue launcherProp = std::string propName = lang + "_LINKER_LAUNCHER";
this->GeneratorTarget->GetProperty(lang + "_LINKER_LAUNCHER"); cmValue launcherProp = this->GeneratorTarget->GetProperty(propName);
if (cmNonempty(launcherProp)) { 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 // 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()) { if (!args.empty()) {
args[0] = this->LocalCommonGenerator->ConvertToOutputFormat( args[0] = this->LocalCommonGenerator->ConvertToOutputFormat(
args[0], cmOutputConverter::SHELL); args[0], cmOutputConverter::SHELL);

View File

@@ -177,6 +177,15 @@ bool cmGeneratorExpressionDAGChecker::EvaluatingLinkOptionsExpression() const
return property == "LINK_OPTIONS"_s; 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( bool cmGeneratorExpressionDAGChecker::EvaluatingLinkLibraries(
cmGeneratorTarget const* tgt, ForGenex genex) const cmGeneratorTarget const* tgt, ForGenex genex) const
{ {

View File

@@ -70,6 +70,7 @@ struct cmGeneratorExpressionDAGChecker
bool EvaluatingCompileExpression() const; bool EvaluatingCompileExpression() const;
bool EvaluatingLinkExpression() const; bool EvaluatingLinkExpression() const;
bool EvaluatingLinkOptionsExpression() const; bool EvaluatingLinkOptionsExpression() const;
bool EvaluatingLinkerLauncher() const;
enum class ForGenex enum class ForGenex
{ {

View File

@@ -1548,7 +1548,8 @@ static const struct LinkLanguageNode : public cmGeneratorExpressionNode
{ {
if (!context->HeadTarget || !dagChecker || if (!context->HeadTarget || !dagChecker ||
!(dagChecker->EvaluatingLinkExpression() || !(dagChecker->EvaluatingLinkExpression() ||
dagChecker->EvaluatingLinkLibraries())) { dagChecker->EvaluatingLinkLibraries() ||
dagChecker->EvaluatingLinkerLauncher())) {
reportError(context, content->GetOriginalExpression(), reportError(context, content->GetOriginalExpression(),
"$<LINK_LANGUAGE:...> may only be used with binary targets " "$<LINK_LANGUAGE:...> may only be used with binary targets "
"to specify link libraries, link directories, link options " "to specify link libraries, link directories, link options "
@@ -1641,7 +1642,8 @@ static const struct LinkLanguageAndIdNode : public cmGeneratorExpressionNode
{ {
if (!context->HeadTarget || !dagChecker || if (!context->HeadTarget || !dagChecker ||
!(dagChecker->EvaluatingLinkExpression() || !(dagChecker->EvaluatingLinkExpression() ||
dagChecker->EvaluatingLinkLibraries())) { dagChecker->EvaluatingLinkLibraries() ||
dagChecker->EvaluatingLinkerLauncher())) {
reportError( reportError(
context, content->GetOriginalExpression(), context, content->GetOriginalExpression(),
"$<LINK_LANG_AND_ID:lang,id> may only be used with binary targets " "$<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) {
if (dagCheckerParent->EvaluatingGenexExpression() || if (dagCheckerParent->EvaluatingGenexExpression() ||
dagCheckerParent->EvaluatingPICExpression()) { dagCheckerParent->EvaluatingPICExpression() ||
dagCheckerParent->EvaluatingLinkerLauncher()) {
// No check required. // No check required.
} else if (dagCheckerParent->EvaluatingLinkLibraries()) { } else if (dagCheckerParent->EvaluatingLinkLibraries()) {
evaluatingLinkLibraries = true; evaluatingLinkLibraries = true;

View File

@@ -1 +1 @@
.*-E env USED_LAUNCHER=1.* .*-E env USED_LAUNCHER=1 TARGET_NAME=main LANGUAGE=C.*

View File

@@ -1 +1 @@
.*-E env USED_LAUNCHER=1.* .*-E env USED_LAUNCHER=1 TARGET_NAME=main LANGUAGE=C.*

View File

@@ -1 +1 @@
.*-E env USED_LAUNCHER=1.* .*-E env USED_LAUNCHER=1 TARGET_NAME=main LANGUAGE=CXX.*

View File

@@ -1 +1 @@
.*-E env USED_LAUNCHER=1.* .*-E env USED_LAUNCHER=1 TARGET_NAME=main LANGUAGE=CXX.*

View File

@@ -1 +1 @@
.*-E env USED_LAUNCHER=1.* .*-E env USED_LAUNCHER=1 TARGET_NAME=main LANGUAGE=OBJC.*

View File

@@ -1 +1 @@
.*-E env USED_LAUNCHER=1.* .*-E env USED_LAUNCHER=1 TARGET_NAME=main LANGUAGE=OBJC.*

View File

@@ -1 +1 @@
.*-E env USED_LAUNCHER=1.* .*-E env USED_LAUNCHER=1 TARGET_NAME=main LANGUAGE=OBJCXX.*

View File

@@ -1 +1 @@
.*-E env USED_LAUNCHER=1.* .*-E env USED_LAUNCHER=1 TARGET_NAME=main LANGUAGE=OBJCXX.*

View File

@@ -17,7 +17,8 @@ endfunction()
function(run_linker_launcher_env lang) function(run_linker_launcher_env lang)
string(REGEX REPLACE "-.*" "" core_lang "${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}) run_linker_launcher(${lang})
unset(ENV{CMAKE_${core_lang}_LINKER_LAUNCHER}) unset(ENV{CMAKE_${core_lang}_LINKER_LAUNCHER})
endfunction() endfunction()