Add support of "LINKER:" prefix for artifact creation flags

The following variables now support the LINKER: prefix:
    * CMAKE_SHARED_LIBRARY_CREATE_<LANG>_FLAGS
    * CMAKE_SHARED_MODULE_CREATE_<LANG>_FLAGS
    * CMAKE_<LANG>_LINK_FLAGS
This commit is contained in:
Marc Chevrier
2024-11-04 17:08:03 +01:00
parent 2bd4c06c26
commit 8bcf9c7a3e
29 changed files with 191 additions and 20 deletions
+12 -7
View File
@@ -2695,7 +2695,7 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt,
// in many ways as an application bundle, as far as
// link flags go
std::string createFlags = this->LookupFlags(
"CMAKE_SHARED_MODULE_CREATE_", llang, "_FLAGS", "-bundle");
"CMAKE_SHARED_MODULE_CREATE_", llang, "_FLAGS", gtgt, "-bundle");
if (!createFlags.empty()) {
extraLinkOptions += ' ';
extraLinkOptions += createFlags;
@@ -2721,7 +2721,7 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt,
this->CreateString("NO"));
// Add the flags to create an executable.
std::string createFlags =
this->LookupFlags("CMAKE_", llang, "_LINK_FLAGS", "");
this->LookupFlags("CMAKE_", llang, "_LINK_FLAGS", gtgt, "");
if (!createFlags.empty()) {
extraLinkOptions += ' ';
extraLinkOptions += createFlags;
@@ -2750,8 +2750,9 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt,
this->CreateString(plist));
} else {
// Add the flags to create a shared library.
std::string createFlags = this->LookupFlags(
"CMAKE_SHARED_LIBRARY_CREATE_", llang, "_FLAGS", "-dynamiclib");
std::string createFlags =
this->LookupFlags("CMAKE_SHARED_LIBRARY_CREATE_", llang, "_FLAGS",
gtgt, "-dynamiclib");
if (!createFlags.empty()) {
extraLinkOptions += ' ';
extraLinkOptions += createFlags;
@@ -2771,7 +2772,7 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt,
case cmStateEnums::EXECUTABLE: {
// Add the flags to create an executable.
std::string createFlags =
this->LookupFlags("CMAKE_", llang, "_LINK_FLAGS", "");
this->LookupFlags("CMAKE_", llang, "_LINK_FLAGS", gtgt, "");
if (!createFlags.empty()) {
extraLinkOptions += ' ';
extraLinkOptions += createFlags;
@@ -5209,13 +5210,17 @@ void cmGlobalXCodeGenerator::AppendDirectoryForConfig(
std::string cmGlobalXCodeGenerator::LookupFlags(
const std::string& varNamePrefix, const std::string& varNameLang,
const std::string& varNameSuffix, const std::string& default_flags)
const std::string& varNameSuffix, cmGeneratorTarget const* gt,
const std::string& default_flags)
{
if (!varNameLang.empty()) {
std::string varName = cmStrCat(varNamePrefix, varNameLang, varNameSuffix);
if (cmValue varValue = this->CurrentMakefile->GetDefinition(varName)) {
if (!varValue->empty()) {
return *varValue;
std::string flags;
this->CurrentLocalGenerator->AppendFlags(
flags, *varValue, varName, gt, cmBuildStep::Link, varNameLang);
return flags;
}
}
}
+1
View File
@@ -304,6 +304,7 @@ private:
std::string LookupFlags(const std::string& varNamePrefix,
const std::string& varNameLang,
const std::string& varNameSuffix,
cmGeneratorTarget const* gt,
const std::string& default_flags);
class Factory;
+50
View File
@@ -214,6 +214,56 @@ cmLocalGenerator::CreateRulePlaceholderExpander(cmBuildStep buildStep) const
buildStep, this->Compilers, this->VariableMappings, this->CompilerSysroot,
this->LinkerSysroot);
}
std::unique_ptr<cmRulePlaceholderExpander>
cmLocalGenerator::CreateRulePlaceholderExpander(
cmBuildStep buildStep, cmGeneratorTarget const* target,
std::string const& language)
{
auto targetType = target->GetType();
if (buildStep == cmBuildStep::Link &&
(targetType == cmStateEnums::EXECUTABLE ||
targetType == cmStateEnums::SHARED_LIBRARY ||
targetType == cmStateEnums::MODULE_LIBRARY)) {
auto mappings = this->VariableMappings;
auto updateMapping = [buildStep, target, &language, &mappings,
this](std::string const& variable) {
auto search = this->VariableMappings.find(variable);
if (search != this->VariableMappings.end()) {
std::string finalFlags;
this->AppendFlags(finalFlags, search->second, variable, target,
buildStep, language);
mappings[variable] = std::move(finalFlags);
}
};
switch (targetType) {
// FALLTHROUGH is used because, depending of the compiler and/or
// platform, the wrong variable is used. For example
// CMAKE_SHARED_LIBRARY_CREATE_<LANG>_FLAGS is used to generate a module,
// and the variable CMAKE_SHARED_MODULE_CREATE_<LANG>_FLAGS is ignored.
case cmStateEnums::MODULE_LIBRARY:
updateMapping(
cmStrCat("CMAKE_SHARED_MODULE_CREATE_", language, "_FLAGS"));
CM_FALLTHROUGH;
case cmStateEnums::SHARED_LIBRARY:
updateMapping(
cmStrCat("CMAKE_SHARED_LIBRARY_CREATE_", language, "_FLAGS"));
CM_FALLTHROUGH;
case cmStateEnums::EXECUTABLE:
updateMapping(cmStrCat("CMAKE_", language, "_LINK_FLAGS"));
break;
default:
// no action needed
;
}
return cm::make_unique<cmRulePlaceholderExpander>(
buildStep, this->Compilers, std::move(mappings), this->CompilerSysroot,
this->LinkerSysroot);
}
return this->CreateRulePlaceholderExpander(buildStep);
}
cmLocalGenerator::~cmLocalGenerator() = default;
+4
View File
@@ -120,6 +120,10 @@ public:
virtual std::unique_ptr<cmRulePlaceholderExpander>
CreateRulePlaceholderExpander(
cmBuildStep buildStep = cmBuildStep::Compile) const;
virtual std::unique_ptr<cmRulePlaceholderExpander>
CreateRulePlaceholderExpander(cmBuildStep buildStep,
cmGeneratorTarget const* target,
std::string const& language);
std::string GetLinkLibsCMP0065(std::string const& linkLanguage,
cmGeneratorTarget& tgt) const;
+10
View File
@@ -57,6 +57,16 @@ cmLocalNinjaGenerator::CreateRulePlaceholderExpander(
ret->SetTargetImpLib("$TARGET_IMPLIB");
return std::unique_ptr<cmRulePlaceholderExpander>(std::move(ret));
}
std::unique_ptr<cmRulePlaceholderExpander>
cmLocalNinjaGenerator::CreateRulePlaceholderExpander(
cmBuildStep buildStep, cmGeneratorTarget const* target,
std::string const& language)
{
auto ret = this->cmLocalGenerator::CreateRulePlaceholderExpander(
buildStep, target, language);
ret->SetTargetImpLib("$TARGET_IMPLIB");
return std::unique_ptr<cmRulePlaceholderExpander>(std::move(ret));
}
cmLocalNinjaGenerator::~cmLocalNinjaGenerator() = default;
+3
View File
@@ -45,6 +45,9 @@ public:
std::unique_ptr<cmRulePlaceholderExpander> CreateRulePlaceholderExpander(
cmBuildStep buildStep = cmBuildStep::Compile) const override;
std::unique_ptr<cmRulePlaceholderExpander> CreateRulePlaceholderExpander(
cmBuildStep buildStep, cmGeneratorTarget const* target,
std::string const& language) override;
std::string GetTargetDirectory(
cmGeneratorTarget const* target) const override;
@@ -234,7 +234,8 @@ void cmMakefileExecutableTargetGenerator::WriteNvidiaDeviceExecutableRule(
}
auto rulePlaceholderExpander =
this->LocalGenerator->CreateRulePlaceholderExpander(cmBuildStep::Link);
this->LocalGenerator->CreateRulePlaceholderExpander(
cmBuildStep::Link, this->GeneratorTarget, linkLanguage);
// Expand placeholders in the commands.
rulePlaceholderExpander->SetTargetImpLib(targetOutput);
@@ -604,7 +605,8 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
}
auto rulePlaceholderExpander =
this->LocalGenerator->CreateRulePlaceholderExpander(cmBuildStep::Link);
this->LocalGenerator->CreateRulePlaceholderExpander(
cmBuildStep::Link, this->GeneratorTarget, linkLanguage);
// Expand placeholders in the commands.
rulePlaceholderExpander->SetTargetImpLib(targetOutPathImport);
+4 -2
View File
@@ -386,7 +386,8 @@ void cmMakefileLibraryTargetGenerator::WriteNvidiaDeviceLibraryRules(
}
auto rulePlaceholderExpander =
this->LocalGenerator->CreateRulePlaceholderExpander(cmBuildStep::Link);
this->LocalGenerator->CreateRulePlaceholderExpander(
cmBuildStep::Link, this->GeneratorTarget, linkLanguage);
// Construct the main link rule and expand placeholders.
rulePlaceholderExpander->SetTargetImpLib(targetOutput);
@@ -711,7 +712,8 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
// Expand the rule variables.
auto rulePlaceholderExpander =
this->LocalGenerator->CreateRulePlaceholderExpander(cmBuildStep::Link);
this->LocalGenerator->CreateRulePlaceholderExpander(
cmBuildStep::Link, this->GeneratorTarget, linkLanguage);
bool useWatcomQuote =
this->Makefile->IsOn(linkRuleVar + "_USE_WATCOM_QUOTE");
cmList real_link_commands;
+2 -2
View File
@@ -1708,8 +1708,8 @@ void cmMakefileTargetGenerator::WriteDeviceLinkRule(
vars.Flags = flags.c_str();
std::string compileCmd = this->GetLinkRule("CMAKE_CUDA_DEVICE_LINK_COMPILE");
auto rulePlaceholderExpander =
localGen->CreateRulePlaceholderExpander(cmBuildStep::Link);
auto rulePlaceholderExpander = localGen->CreateRulePlaceholderExpander(
cmBuildStep::Link, this->GetGeneratorTarget(), "CUDA");
rulePlaceholderExpander->ExpandRuleVariables(localGen, compileCmd, vars);
commands.emplace_back(compileCmd);
+6 -3
View File
@@ -352,7 +352,8 @@ void cmNinjaNormalTargetGenerator::WriteNvidiaDeviceLinkRule(
auto rulePlaceholderExpander =
this->GetLocalGenerator()->CreateRulePlaceholderExpander(
cmBuildStep::Link);
cmBuildStep::Link, this->GetGeneratorTarget(),
this->TargetLinkLanguage(config));
// Rule for linking library/executable.
std::vector<std::string> linkCmds = this->ComputeDeviceLinkCmd();
@@ -416,7 +417,8 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkRules(
"CMAKE_CUDA_DEVICE_LINK_COMPILE");
auto rulePlaceholderExpander =
this->GetLocalGenerator()->CreateRulePlaceholderExpander(
cmBuildStep::Link);
cmBuildStep::Link, this->GetGeneratorTarget(),
this->TargetLinkLanguage(config));
rulePlaceholderExpander->ExpandRuleVariables(this->GetLocalGenerator(),
compileCmd, vars);
@@ -570,7 +572,8 @@ void cmNinjaNormalTargetGenerator::WriteLinkRule(bool useResponseFile,
auto rulePlaceholderExpander =
this->GetLocalGenerator()->CreateRulePlaceholderExpander(
cmBuildStep::Link);
cmBuildStep::Link, this->GetGeneratorTarget(),
this->TargetLinkLanguage(config));
// Rule for linking library/executable.
std::vector<std::string> linkCmds = this->ComputeLinkCmd(config);
+2 -1
View File
@@ -875,7 +875,8 @@ add_RunCMake_test(target_link_libraries-LINK_GROUP -DCMAKE_SYSTEM_NAME=${CMAKE_S
-DCMAKE_IMPORT_LIBRARY_PREFIX=${CMAKE_IMPORT_LIBRARY_PREFIX}
-DCMAKE_IMPORT_LIBRARY_SUFFIX=${CMAKE_IMPORT_LIBRARY_SUFFIX}
-DCMAKE_LINK_LIBRARY_FLAG=${CMAKE_LINK_LIBRARY_FLAG})
add_RunCMake_test(target_link_libraries-LINKER-prefix -DCMAKE_C_COMPILER_ID=${CMAKE_C_COMPILER_ID})
add_RunCMake_test(target_link_libraries-LINKER-prefix -DCMAKE_C_COMPILER_ID=${CMAKE_C_COMPILER_ID}
-DCMAKE_C_COMPILER_FRONTEND_VARIANT=${CMAKE_C_COMPILER_FRONTEND_VARIANT})
add_RunCMake_test(add_link_options -DCMAKE_C_COMPILER_ID=${CMAKE_C_COMPILER_ID})
add_RunCMake_test(target_link_options -DCMAKE_C_COMPILER_ID=${CMAKE_C_COMPILER_ID}
-DCMake_TEST_CUDA=${CMake_TEST_CUDA})
@@ -1,2 +1,2 @@
include ("${CMAKE_CURRENT_LIST_DIR}/LINKER_expansion2-CMP0181-OLD-validation.cmake")
include ("${CMAKE_CURRENT_LIST_DIR}/LINKER_expansion-CMP0181-OLD-validation.cmake")
@@ -1,2 +1,2 @@
include ("${CMAKE_CURRENT_LIST_DIR}/LINKER_expansion2-CMP0181-OLD-validation.cmake")
include ("${CMAKE_CURRENT_LIST_DIR}/LINKER_expansion-CMP0181-OLD-validation.cmake")
@@ -1,2 +1,2 @@
include ("${CMAKE_CURRENT_LIST_DIR}/LINKER_expansion2-CMP0181-OLD-validation.cmake")
include ("${CMAKE_CURRENT_LIST_DIR}/LINKER_expansion-CMP0181-OLD-validation.cmake")
@@ -0,0 +1,3 @@
set(reference_file "LINKER.txt")
include ("${CMAKE_CURRENT_LIST_DIR}/LINKER_expansion-validation.cmake")
@@ -0,0 +1,3 @@
set(reference_file "LINKER.txt")
include ("${CMAKE_CURRENT_LIST_DIR}/LINKER_expansion-validation.cmake")
@@ -0,0 +1,3 @@
set(reference_file "LINKER.txt")
include ("${CMAKE_CURRENT_LIST_DIR}/LINKER_expansion-validation.cmake")
@@ -0,0 +1,2 @@
include ("${CMAKE_CURRENT_LIST_DIR}/LINKER_expansion-CMP0181-OLD-validation.cmake")
@@ -0,0 +1,2 @@
include ("${CMAKE_CURRENT_LIST_DIR}/LINKER_expansion-CMP0181-OLD-validation.cmake")
@@ -0,0 +1,2 @@
include ("${CMAKE_CURRENT_LIST_DIR}/LINKER_expansion-CMP0181-OLD-validation.cmake")
@@ -0,0 +1,55 @@
enable_language(C)
cmake_policy(SET CMP0181 ${CMP0181})
# ensure command line is always displayed and do not use any response file
set(CMAKE_VERBOSE_MAKEFILE TRUE)
if (CMAKE_GENERATOR MATCHES "Borland|NMake")
string(REPLACE "${CMAKE_START_TEMP_FILE}" "" CMAKE_C_LINK_EXECUTABLE "${CMAKE_C_LINK_EXECUTABLE}")
string(REPLACE "${CMAKE_END_TEMP_FILE}" "" CMAKE_C_LINK_EXECUTABLE "${CMAKE_C_LINK_EXECUTABLE}")
string(REPLACE "${CMAKE_START_TEMP_FILE}" "" CMAKE_C_CREATE_SHARED_LIBRARY "${CMAKE_C_CREATE_SHARED_LIBRARY}")
string(REPLACE "${CMAKE_END_TEMP_FILE}" "" CMAKE_C_CREATE_SHARED_LIBRARY "${CMAKE_C_CREATE_SHARED_LIBRARY}")
string(REPLACE "${CMAKE_START_TEMP_FILE}" "" CMAKE_C_CREATE_SHARED_MODULE "${CMAKE_C_CREATE_SHARED_MODULE}")
string(REPLACE "${CMAKE_END_TEMP_FILE}" "" CMAKE_C_CREATE_SHARED_MODULE "${CMAKE_C_CREATE_SHARED_MODULE}")
endif()
set(CMAKE_C_LINK_FLAGS "${CMAKE_C_LINK_FLAGS} LINKER:-foo,bar")
add_executable(c_exe_create_link_flags main.c)
set(CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS "${CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS} LINKER:-foo,bar")
add_library(c_shared_create_link_flags SHARED LinkOptionsLib.c)
set(CMAKE_SHARED_MODULE_CREATE_C_FLAGS "${CMAKE_SHARED_MODULE_CREATE_C_FLAGS} LINKER:-foo,bar")
add_library(c_module_create_link_flags MODULE LinkOptionsLib.c)
# generate reference for LINKER flag
if (CMP0181 STREQUAL "NEW")
if (CMAKE_C_LINKER_WRAPPER_FLAG)
set(linker_flag ${CMAKE_C_LINKER_WRAPPER_FLAG})
list(GET linker_flag -1 linker_space)
if (linker_space STREQUAL " ")
list(REMOVE_AT linker_flag -1)
else()
set(linker_space)
endif()
list (JOIN linker_flag " " linker_flag)
if (CMAKE_C_LINKER_WRAPPER_FLAG_SEP)
set(linker_sep "${CMAKE_C_LINKER_WRAPPER_FLAG_SEP}")
string (APPEND linker_flag "${linker_space}" "-foo${linker_sep}bar")
else()
set(linker_prefix "${linker_flag}${linker_space}")
set (linker_flag "${linker_prefix}-foo ${linker_prefix}bar")
endif()
else()
set(linker_flag "-foo bar")
endif()
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/LINKER.txt" "${linker_flag}")
endif()
@@ -33,5 +33,19 @@ if (RunCMake_GENERATOR MATCHES "Makefiles|Ninja|Xcode|Visual Studio"
run_cmake_target(LINKER_expansion2-CMP0181-${policy} EXE_LINKER_FLAGS exe_linker_flags --verbose)
run_cmake_target(LINKER_expansion2-CMP0181-${policy} SHARED_LINKER_FLAGS shared_linker_flags --verbose)
run_cmake_target(LINKER_expansion2-CMP0181-${policy} MODULE_LINKER_FLAGS module_linker_flags --verbose)
if (NOT (RunCMake_GENERATOR MATCHES "Visual Studio" OR CMAKE_C_COMPILER_ID MATCHES "Borland|Embarcadero"))
# Visual Studio generator and Borland, Embarcadero compilers do not use these variables
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/LINKER_expansion3-CMP0181-${policy}-build)
run_cmake_with_options(LINKER_expansion3 -DCMP0181=${policy})
run_cmake_target(LINKER_expansion3-CMP0181-${policy} C_EXE_CREATE_LINK_FLAGS c_exe_create_link_flags --verbose)
if (NOT (CMAKE_C_COMPILER_ID STREQUAL "MSVC" OR CMAKE_C_COMPILER_FRONTEND_VARIANT STREQUAL "MSVC"))
# MSVC compiler does not use these variables
run_cmake_target(LINKER_expansion3-CMP0181-${policy} C_SHARED_CREATE_LINK_FLAGS c_shared_create_link_flags --verbose)
run_cmake_target(LINKER_expansion3-CMP0181-${policy} C_MODULE_CREATE_LINK_FLAGS c_module_create_link_flags --verbose)
endif()
endif()
endforeach()
endif()