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

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 "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);

View File

@ -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
{

View File

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

View File

@ -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;

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)
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()