summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Auxiliary/vim/syntax/cmake.vim4
-rw-r--r--Help/envvar/CMAKE_LANG_LINKER_LAUNCHER.rst13
-rw-r--r--Help/manual/cmake-env-variables.7.rst1
-rw-r--r--Help/manual/cmake-properties.7.rst1
-rw-r--r--Help/manual/cmake-variables.7.rst1
-rw-r--r--Help/prop_tgt/LANG_LINKER_LAUNCHER.rst16
-rw-r--r--Help/release/dev/linker-launcher.rst7
-rw-r--r--Help/variable/CMAKE_LANG_LINKER_LAUNCHER.rst11
-rw-r--r--Modules/CMakeCInformation.cmake5
-rw-r--r--Modules/CMakeCXXInformation.cmake5
-rw-r--r--Modules/CMakeOBJCInformation.cmake5
-rw-r--r--Modules/CMakeOBJCXXInformation.cmake5
-rw-r--r--Source/cmCommonTargetGenerator.cxx22
-rw-r--r--Source/cmCommonTargetGenerator.h2
-rw-r--r--Source/cmMakefileExecutableTargetGenerator.cxx6
-rw-r--r--Source/cmMakefileLibraryTargetGenerator.cxx6
-rw-r--r--Source/cmNinjaNormalTargetGenerator.cxx5
-rw-r--r--Source/cmRulePlaceholderExpander.cxx20
-rw-r--r--Source/cmRulePlaceholderExpander.h1
-rw-r--r--Source/cmTarget.cxx4
-rw-r--r--Tests/RunCMake/CMakeLists.txt2
-rw-r--r--Tests/RunCMake/LinkerLauncher/C-Build-stdout.txt1
-rw-r--r--Tests/RunCMake/LinkerLauncher/C-common.cmake3
-rw-r--r--Tests/RunCMake/LinkerLauncher/C-env-Build-stdout.txt1
-rw-r--r--Tests/RunCMake/LinkerLauncher/C-env.cmake1
-rw-r--r--Tests/RunCMake/LinkerLauncher/C-launch-Build-stdout.txt1
-rw-r--r--Tests/RunCMake/LinkerLauncher/C-launch-env-Build-stdout.txt1
-rw-r--r--Tests/RunCMake/LinkerLauncher/C-launch-env.cmake3
-rw-r--r--Tests/RunCMake/LinkerLauncher/C-launch.cmake3
-rw-r--r--Tests/RunCMake/LinkerLauncher/C.cmake2
-rw-r--r--Tests/RunCMake/LinkerLauncher/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/LinkerLauncher/CXX-Build-stdout.txt1
-rw-r--r--Tests/RunCMake/LinkerLauncher/CXX-common.cmake3
-rw-r--r--Tests/RunCMake/LinkerLauncher/CXX-env-Build-stdout.txt1
-rw-r--r--Tests/RunCMake/LinkerLauncher/CXX-env.cmake1
-rw-r--r--Tests/RunCMake/LinkerLauncher/CXX-launch-Build-stdout.txt1
-rw-r--r--Tests/RunCMake/LinkerLauncher/CXX-launch-env-Build-stdout.txt1
-rw-r--r--Tests/RunCMake/LinkerLauncher/CXX-launch-env.cmake3
-rw-r--r--Tests/RunCMake/LinkerLauncher/CXX-launch.cmake3
-rw-r--r--Tests/RunCMake/LinkerLauncher/CXX.cmake2
-rw-r--r--Tests/RunCMake/LinkerLauncher/OBJC-Build-stdout.txt1
-rw-r--r--Tests/RunCMake/LinkerLauncher/OBJC-common.cmake3
-rw-r--r--Tests/RunCMake/LinkerLauncher/OBJC-env-Build-stdout.txt1
-rw-r--r--Tests/RunCMake/LinkerLauncher/OBJC-env.cmake1
-rw-r--r--Tests/RunCMake/LinkerLauncher/OBJC-launch-Build-stdout.txt1
-rw-r--r--Tests/RunCMake/LinkerLauncher/OBJC-launch-env-Build-stdout.txt1
-rw-r--r--Tests/RunCMake/LinkerLauncher/OBJC-launch-env.cmake3
-rw-r--r--Tests/RunCMake/LinkerLauncher/OBJC-launch.cmake3
-rw-r--r--Tests/RunCMake/LinkerLauncher/OBJC.cmake2
-rw-r--r--Tests/RunCMake/LinkerLauncher/OBJCXX-Build-stdout.txt1
-rw-r--r--Tests/RunCMake/LinkerLauncher/OBJCXX-common.cmake3
-rw-r--r--Tests/RunCMake/LinkerLauncher/OBJCXX-env-Build-stdout.txt1
-rw-r--r--Tests/RunCMake/LinkerLauncher/OBJCXX-env.cmake1
-rw-r--r--Tests/RunCMake/LinkerLauncher/OBJCXX-launch-Build-stdout.txt1
-rw-r--r--Tests/RunCMake/LinkerLauncher/OBJCXX-launch-env-Build-stdout.txt1
-rw-r--r--Tests/RunCMake/LinkerLauncher/OBJCXX-launch-env.cmake3
-rw-r--r--Tests/RunCMake/LinkerLauncher/OBJCXX-launch.cmake3
-rw-r--r--Tests/RunCMake/LinkerLauncher/OBJCXX.cmake2
-rw-r--r--Tests/RunCMake/LinkerLauncher/RunCMakeTest.cmake37
-rw-r--r--Tests/RunCMake/LinkerLauncher/main.c4
-rw-r--r--Tests/RunCMake/LinkerLauncher/main.cxx4
-rw-r--r--Tests/RunCMake/LinkerLauncher/main.m4
-rw-r--r--Tests/RunCMake/LinkerLauncher/main.mm4
63 files changed, 261 insertions, 1 deletions
diff --git a/Auxiliary/vim/syntax/cmake.vim b/Auxiliary/vim/syntax/cmake.vim
index 611f72a..d2a04fe 100644
--- a/Auxiliary/vim/syntax/cmake.vim
+++ b/Auxiliary/vim/syntax/cmake.vim
@@ -905,6 +905,7 @@ syn keyword cmakeVariable contained
\ CMAKE_CXX_INCLUDE_WHAT_YOU_USE
\ CMAKE_CXX_INIT
\ CMAKE_CXX_LIBRARY_ARCHITECTURE
+ \ CMAKE_CXX_LINKER_LAUNCHER
\ CMAKE_CXX_LINKER_PREFERENCE
\ CMAKE_CXX_LINKER_PREFERENCE_PROPAGATES
\ CMAKE_CXX_LINKER_WRAPPER_FLAG
@@ -970,6 +971,7 @@ syn keyword cmakeVariable contained
\ CMAKE_C_INCLUDE_WHAT_YOU_USE
\ CMAKE_C_INIT
\ CMAKE_C_LIBRARY_ARCHITECTURE
+ \ CMAKE_C_LINKER_LAUNCHER
\ CMAKE_C_LINKER_PREFERENCE
\ CMAKE_C_LINKER_PREFERENCE_PROPAGATES
\ CMAKE_C_LINKER_WRAPPER_FLAG
@@ -1263,10 +1265,12 @@ syn keyword cmakeVariable contained
\ CMAKE_NO_SYSTEM_FROM_IMPORTED
\ CMAKE_OBJCXX_CLANG_TIDY
\ CMAKE_OBJCXX_EXTENSIONS
+ \ CMAKE_OBJCXX_LINKER_LAUNCHER
\ CMAKE_OBJCXX_STANDARD
\ CMAKE_OBJCXX_STANDARD_REQUIRED
\ CMAKE_OBJC_CLANG_TIDY
\ CMAKE_OBJC_EXTENSIONS
+ \ CMAKE_OBJC_LINKER_LAUNCHER
\ CMAKE_OBJC_STANDARD
\ CMAKE_OBJC_STANDARD_REQUIRED
\ CMAKE_OBJECT_PATH_MAX
diff --git a/Help/envvar/CMAKE_LANG_LINKER_LAUNCHER.rst b/Help/envvar/CMAKE_LANG_LINKER_LAUNCHER.rst
new file mode 100644
index 0000000..6251d9c
--- /dev/null
+++ b/Help/envvar/CMAKE_LANG_LINKER_LAUNCHER.rst
@@ -0,0 +1,13 @@
+CMAKE_<LANG>_LINKER_LAUNCHER
+----------------------------
+
+.. versionadded:: 3.21
+
+.. include:: ENV_VAR.txt
+
+Default launcher to use when linking a target of the specified language. Will
+only be used by CMake to initialize the variable on the first configuration.
+Afterwards, it is available through the cache setting of the variable of the
+same name. For any configuration run (including the first), the environment
+variable will be ignored if the :variable:`CMAKE_<LANG>_LINKER_LAUNCHER`
+variable is defined.
diff --git a/Help/manual/cmake-env-variables.7.rst b/Help/manual/cmake-env-variables.7.rst
index bc1fa1d..8932abf 100644
--- a/Help/manual/cmake-env-variables.7.rst
+++ b/Help/manual/cmake-env-variables.7.rst
@@ -37,6 +37,7 @@ Environment Variables that Control the Build
/envvar/CMAKE_GENERATOR_PLATFORM
/envvar/CMAKE_GENERATOR_TOOLSET
/envvar/CMAKE_LANG_COMPILER_LAUNCHER
+ /envvar/CMAKE_LANG_LINKER_LAUNCHER
/envvar/CMAKE_MSVCIDE_RUN_PATH
/envvar/CMAKE_NO_VERBOSE
/envvar/CMAKE_OSX_ARCHITECTURES
diff --git a/Help/manual/cmake-properties.7.rst b/Help/manual/cmake-properties.7.rst
index 4f2c1b0..0a3e36b 100644
--- a/Help/manual/cmake-properties.7.rst
+++ b/Help/manual/cmake-properties.7.rst
@@ -272,6 +272,7 @@ Properties on Targets
/prop_tgt/LANG_CPPCHECK
/prop_tgt/LANG_CPPLINT
/prop_tgt/LANG_INCLUDE_WHAT_YOU_USE
+ /prop_tgt/LANG_LINKER_LAUNCHER
/prop_tgt/LANG_VISIBILITY_PRESET
/prop_tgt/LIBRARY_OUTPUT_DIRECTORY
/prop_tgt/LIBRARY_OUTPUT_DIRECTORY_CONFIG
diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst
index 0720d49..873bd89 100644
--- a/Help/manual/cmake-variables.7.rst
+++ b/Help/manual/cmake-variables.7.rst
@@ -424,6 +424,7 @@ Variables that Control the Build
/variable/CMAKE_LANG_CPPCHECK
/variable/CMAKE_LANG_CPPLINT
/variable/CMAKE_LANG_INCLUDE_WHAT_YOU_USE
+ /variable/CMAKE_LANG_LINKER_LAUNCHER
/variable/CMAKE_LANG_LINK_LIBRARY_FILE_FLAG
/variable/CMAKE_LANG_LINK_LIBRARY_FLAG
/variable/CMAKE_LANG_VISIBILITY_PRESET
diff --git a/Help/prop_tgt/LANG_LINKER_LAUNCHER.rst b/Help/prop_tgt/LANG_LINKER_LAUNCHER.rst
new file mode 100644
index 0000000..f6ca5ad
--- /dev/null
+++ b/Help/prop_tgt/LANG_LINKER_LAUNCHER.rst
@@ -0,0 +1,16 @@
+<LANG>_LINKER_LAUNCHER
+----------------------
+
+.. versionadded:: 3.21
+
+This property is implemented only when ``<LANG>`` is ``C``, ``CXX``,
+``OBJC``, or ``OBJCXX``
+
+Specify a :ref:`semicolon-separated list <CMake Language Lists>` containing a
+command line for a linker launching tool. The :ref:`Makefile Generators` and the
+:generator:`Ninja` generator will run this tool and pass the linker and its
+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.
diff --git a/Help/release/dev/linker-launcher.rst b/Help/release/dev/linker-launcher.rst
new file mode 100644
index 0000000..6563347
--- /dev/null
+++ b/Help/release/dev/linker-launcher.rst
@@ -0,0 +1,7 @@
+linker-launcher
+---------------
+
+* The :ref:`Makefile Generators` and the :generator:`Ninja` generator learned to
+ add linker launcher tools along with the linker for ``C``, ``CXX``, ``OBJC``, and
+ ``OBJCXX`` languages. See the :variable:`CMAKE_<LANG>_LINKER_LAUNCHER` variable
+ and :prop_tgt:`<LANG>_LINKER_LAUNCHER` target property for details.
diff --git a/Help/variable/CMAKE_LANG_LINKER_LAUNCHER.rst b/Help/variable/CMAKE_LANG_LINKER_LAUNCHER.rst
new file mode 100644
index 0000000..b76b939
--- /dev/null
+++ b/Help/variable/CMAKE_LANG_LINKER_LAUNCHER.rst
@@ -0,0 +1,11 @@
+CMAKE_<LANG>_LINKER_LAUNCHER
+----------------------------
+
+.. versionadded:: 3.21
+
+Default value for :prop_tgt:`<LANG>_LINKER_LAUNCHER` target property. This
+variable is used to initialize the property on each target as it is created.
+This is done only when ``<LANG>`` is ``C``, ``CXX``, ``OBJC``, or ``OBJCXX``.
+
+This variable is initialized to the :envvar:`CMAKE_<LANG>_LINKER_LAUNCHER`
+environment variable if it is set.
diff --git a/Modules/CMakeCInformation.cmake b/Modules/CMakeCInformation.cmake
index f6d620f..6be1865 100644
--- a/Modules/CMakeCInformation.cmake
+++ b/Modules/CMakeCInformation.cmake
@@ -115,6 +115,11 @@ if(NOT CMAKE_C_COMPILER_LAUNCHER AND DEFINED ENV{CMAKE_C_COMPILER_LAUNCHER})
CACHE STRING "Compiler launcher for C.")
endif()
+if(NOT CMAKE_C_LINKER_LAUNCHER AND DEFINED ENV{CMAKE_C_LINKER_LAUNCHER})
+ set(CMAKE_C_LINKER_LAUNCHER "$ENV{CMAKE_C_LINKER_LAUNCHER}"
+ CACHE STRING "Linker launcher for C.")
+endif()
+
include(CMakeCommonLanguageInclude)
# now define the following rule variables
diff --git a/Modules/CMakeCXXInformation.cmake b/Modules/CMakeCXXInformation.cmake
index dbb4366..944d236 100644
--- a/Modules/CMakeCXXInformation.cmake
+++ b/Modules/CMakeCXXInformation.cmake
@@ -212,6 +212,11 @@ if(NOT CMAKE_CXX_COMPILER_LAUNCHER AND DEFINED ENV{CMAKE_CXX_COMPILER_LAUNCHER})
CACHE STRING "Compiler launcher for CXX.")
endif()
+if(NOT CMAKE_CXX_LINKER_LAUNCHER AND DEFINED ENV{CMAKE_CXX_LINKER_LAUNCHER})
+ set(CMAKE_CXX_LINKER_LAUNCHER "$ENV{CMAKE_CXX_LINKER_LAUNCHER}"
+ CACHE STRING "Linker launcher for CXX.")
+endif()
+
include(CMakeCommonLanguageInclude)
# now define the following rules:
diff --git a/Modules/CMakeOBJCInformation.cmake b/Modules/CMakeOBJCInformation.cmake
index d530191..ac67d01 100644
--- a/Modules/CMakeOBJCInformation.cmake
+++ b/Modules/CMakeOBJCInformation.cmake
@@ -115,6 +115,11 @@ if(NOT CMAKE_OBJC_COMPILER_LAUNCHER AND DEFINED ENV{CMAKE_OBJC_COMPILER_LAUNCHER
CACHE STRING "Compiler launcher for OBJC.")
endif()
+if(NOT CMAKE_OBJC_LINKER_LAUNCHER AND DEFINED ENV{CMAKE_OBJC_LINKER_LAUNCHER})
+ set(CMAKE_OBJC_LINKER_LAUNCHER "$ENV{CMAKE_OBJC_LINKER_LAUNCHER}"
+ CACHE STRING "Linker launcher for OBJC.")
+endif()
+
include(CMakeCommonLanguageInclude)
# now define the following rule variables
diff --git a/Modules/CMakeOBJCXXInformation.cmake b/Modules/CMakeOBJCXXInformation.cmake
index 7a3b9d7..70e8579 100644
--- a/Modules/CMakeOBJCXXInformation.cmake
+++ b/Modules/CMakeOBJCXXInformation.cmake
@@ -208,6 +208,11 @@ if(NOT CMAKE_OBJCXX_COMPILER_LAUNCHER AND DEFINED ENV{CMAKE_OBJCXX_COMPILER_LAUN
CACHE STRING "Compiler launcher for OBJCXX.")
endif()
+if(NOT CMAKE_OBJCXX_LINKER_LAUNCHER AND DEFINED ENV{CMAKE_OBJCXX_LINKER_LAUNCHER})
+ set(CMAKE_OBJCXX_LINKER_LAUNCHER "$ENV{CMAKE_OBJCXX_LINKER_LAUNCHER}"
+ CACHE STRING "Linker launcher for OBJCXX.")
+endif()
+
include(CMakeCommonLanguageInclude)
# now define the following rules:
diff --git a/Source/cmCommonTargetGenerator.cxx b/Source/cmCommonTargetGenerator.cxx
index 0c5a7df..7c2e20c 100644
--- a/Source/cmCommonTargetGenerator.cxx
+++ b/Source/cmCommonTargetGenerator.cxx
@@ -15,6 +15,7 @@
#include "cmMakefile.h"
#include "cmOutputConverter.h"
#include "cmProperty.h"
+#include "cmRange.h"
#include "cmSourceFile.h"
#include "cmStateTypes.h"
#include "cmStringAlgorithms.h"
@@ -291,3 +292,24 @@ void cmCommonTargetGenerator::AppendOSXVerFlag(std::string& flags,
this->LocalCommonGenerator->AppendFlags(flags, vflag.str());
}
}
+
+std::string cmCommonTargetGenerator::GetLinkerLauncher(
+ const std::string& config)
+{
+ std::string lang = this->GeneratorTarget->GetLinkerLanguage(config);
+ cmProp launcherProp =
+ this->GeneratorTarget->GetProperty(lang + "_LINKER_LAUNCHER");
+ if (cmNonempty(launcherProp)) {
+ // Convert ;-delimited list to single string
+ std::vector<std::string> args = cmExpandedList(*launcherProp, true);
+ if (!args.empty()) {
+ args[0] = this->LocalCommonGenerator->ConvertToOutputFormat(
+ args[0], cmOutputConverter::SHELL);
+ for (std::string& i : cmMakeRange(args.begin() + 1, args.end())) {
+ i = this->LocalCommonGenerator->EscapeForShell(i);
+ }
+ return cmJoin(args, " ");
+ }
+ }
+ return std::string();
+}
diff --git a/Source/cmCommonTargetGenerator.h b/Source/cmCommonTargetGenerator.h
index fba6b0a..a156a41 100644
--- a/Source/cmCommonTargetGenerator.h
+++ b/Source/cmCommonTargetGenerator.h
@@ -64,6 +64,8 @@ protected:
const std::string& config) const;
std::string ComputeTargetCompilePDB(const std::string& config) const;
+ std::string GetLinkerLauncher(const std::string& config);
+
private:
using ByLanguageMap = std::map<std::string, std::string>;
struct ByConfig
diff --git a/Source/cmMakefileExecutableTargetGenerator.cxx b/Source/cmMakefileExecutableTargetGenerator.cxx
index 2940b8b..3a2744e 100644
--- a/Source/cmMakefileExecutableTargetGenerator.cxx
+++ b/Source/cmMakefileExecutableTargetGenerator.cxx
@@ -571,6 +571,12 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
vars.LinkFlags = linkFlags.c_str();
vars.Manifests = manifests.c_str();
+ std::string linkerLauncher =
+ this->GetLinkerLauncher(this->GetConfigName());
+ if (cmNonempty(linkerLauncher)) {
+ vars.Launcher = linkerLauncher.c_str();
+ }
+
if (this->GeneratorTarget->GetPropertyAsBool("LINK_WHAT_YOU_USE")) {
std::string cmakeCommand =
cmStrCat(this->LocalGenerator->ConvertToOutputFormat(
diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx
index f96bcde..d0e3837 100644
--- a/Source/cmMakefileLibraryTargetGenerator.cxx
+++ b/Source/cmMakefileLibraryTargetGenerator.cxx
@@ -804,6 +804,12 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
vars.LanguageCompileFlags = langFlags.c_str();
+ std::string linkerLauncher =
+ this->GetLinkerLauncher(this->GetConfigName());
+ if (cmNonempty(linkerLauncher)) {
+ vars.Launcher = linkerLauncher.c_str();
+ }
+
std::string launcher;
cmProp val = this->LocalGenerator->GetRuleLauncher(this->GeneratorTarget,
"RULE_LAUNCH_LINK");
diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx
index 03fc0b4..9a48047 100644
--- a/Source/cmNinjaNormalTargetGenerator.cxx
+++ b/Source/cmNinjaNormalTargetGenerator.cxx
@@ -456,6 +456,11 @@ void cmNinjaNormalTargetGenerator::WriteLinkRule(bool useResponseFile,
vars.LanguageCompileFlags = langFlags.c_str();
}
+ std::string linkerLauncher = this->GetLinkerLauncher(config);
+ if (cmNonempty(linkerLauncher)) {
+ vars.Launcher = linkerLauncher.c_str();
+ }
+
std::string launcher;
cmProp val = this->GetLocalGenerator()->GetRuleLauncher(
this->GetGeneratorTarget(), "RULE_LAUNCH_LINK");
diff --git a/Source/cmRulePlaceholderExpander.cxx b/Source/cmRulePlaceholderExpander.cxx
index d00bbdf..7480aeb 100644
--- a/Source/cmRulePlaceholderExpander.cxx
+++ b/Source/cmRulePlaceholderExpander.cxx
@@ -6,6 +6,7 @@
#include <utility>
#include "cmOutputConverter.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
cmRulePlaceholderExpander::cmRulePlaceholderExpander(
@@ -280,6 +281,13 @@ std::string cmRulePlaceholderExpander::ExpandRuleVariable(
this->VariableMappings["CMAKE_" + compIt->second +
"_COMPILE_OPTIONS_SYSROOT"];
+ if (compIt->second == replaceValues.Language && replaceValues.Launcher) {
+ // Add launcher as part of expansion so that it always appears
+ // immediately before the command itself, regardless of whether the
+ // overall rule template contains other content at the front.
+ ret = cmStrCat(replaceValues.Launcher, " ", ret);
+ }
+
// if there are required arguments to the compiler add it
// to the compiler string
if (!compilerArg1.empty()) {
@@ -317,7 +325,17 @@ std::string cmRulePlaceholderExpander::ExpandRuleVariable(
auto mapIt = this->VariableMappings.find(variable);
if (mapIt != this->VariableMappings.end()) {
if (variable.find("_FLAG") == std::string::npos) {
- return outputConverter->ConvertToOutputForExisting(mapIt->second);
+ std::string ret =
+ outputConverter->ConvertToOutputForExisting(mapIt->second);
+
+ if (replaceValues.Launcher && variable == "CMAKE_LINKER") {
+ // Add launcher as part of expansion so that it always appears
+ // immediately before the command itself, regardless of whether the
+ // overall rule template contains other content at the front.
+ ret = cmStrCat(replaceValues.Launcher, " ", ret);
+ }
+
+ return ret;
}
return mapIt->second;
}
diff --git a/Source/cmRulePlaceholderExpander.h b/Source/cmRulePlaceholderExpander.h
index f8dc368..c22e0fa 100644
--- a/Source/cmRulePlaceholderExpander.h
+++ b/Source/cmRulePlaceholderExpander.h
@@ -67,6 +67,7 @@ public:
const char* ISPCHeader = nullptr;
const char* Fatbinary = nullptr;
const char* RegisterFile = nullptr;
+ const char* Launcher = nullptr;
};
// Expand rule variables in CMake of the type found in language rules
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 29e361c..6f2e447 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -354,11 +354,13 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
initProp("C_CPPLINT");
initProp("C_CPPCHECK");
initProp("C_INCLUDE_WHAT_YOU_USE");
+ initProp("C_LINKER_LAUNCHER");
initProp("LINK_WHAT_YOU_USE");
initProp("CXX_CLANG_TIDY");
initProp("CXX_CPPLINT");
initProp("CXX_CPPCHECK");
initProp("CXX_INCLUDE_WHAT_YOU_USE");
+ initProp("CXX_LINKER_LAUNCHER");
initProp("CUDA_SEPARABLE_COMPILATION");
initProp("CUDA_RESOLVE_DEVICE_SYMBOLS");
initProp("CUDA_RUNTIME_LIBRARY");
@@ -374,7 +376,9 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
initProp("LINK_SEARCH_START_STATIC");
initProp("LINK_SEARCH_END_STATIC");
initProp("OBJC_CLANG_TIDY");
+ initProp("OBJC_LINKER_LAUNCHER");
initProp("OBJCXX_CLANG_TIDY");
+ initProp("OBJCXX_LINKER_LAUNCHER");
initProp("Swift_LANGUAGE_VERSION");
initProp("Swift_MODULE_DIRECTORY");
initProp("VS_JUST_MY_CODE_DEBUGGING");
diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt
index 14a7fa3..d02d7a2 100644
--- a/Tests/RunCMake/CMakeLists.txt
+++ b/Tests/RunCMake/CMakeLists.txt
@@ -732,12 +732,14 @@ if("${CMAKE_GENERATOR}" MATCHES "Make|Ninja")
endif()
if (APPLE AND CMAKE_C_COMPILER_ID MATCHES "Clang|GNU")
list(APPEND CompilerLauncher_ARGS -DCMake_TEST_OBJC=1)
+ list(APPEND LinkerLauncher_ARGS -DCMake_TEST_OBJC=1)
endif()
add_RunCMake_test(CompilerLauncher)
set_property(TEST RunCMake.CompilerLauncher APPEND
PROPERTY LABELS "CUDA;ISPC")
add_RunCMake_test(ctest_labels_for_subprojects)
add_RunCMake_test(CompilerArgs)
+ add_RunCMake_test(LinkerLauncher)
endif()
set(cpack_tests
diff --git a/Tests/RunCMake/LinkerLauncher/C-Build-stdout.txt b/Tests/RunCMake/LinkerLauncher/C-Build-stdout.txt
new file mode 100644
index 0000000..3313e31
--- /dev/null
+++ b/Tests/RunCMake/LinkerLauncher/C-Build-stdout.txt
@@ -0,0 +1 @@
+.*-E env USED_LAUNCHER=1.*
diff --git a/Tests/RunCMake/LinkerLauncher/C-common.cmake b/Tests/RunCMake/LinkerLauncher/C-common.cmake
new file mode 100644
index 0000000..96b004b
--- /dev/null
+++ b/Tests/RunCMake/LinkerLauncher/C-common.cmake
@@ -0,0 +1,3 @@
+enable_language(C)
+set(CMAKE_VERBOSE_MAKEFILE TRUE)
+add_executable(main main.c)
diff --git a/Tests/RunCMake/LinkerLauncher/C-env-Build-stdout.txt b/Tests/RunCMake/LinkerLauncher/C-env-Build-stdout.txt
new file mode 100644
index 0000000..3313e31
--- /dev/null
+++ b/Tests/RunCMake/LinkerLauncher/C-env-Build-stdout.txt
@@ -0,0 +1 @@
+.*-E env USED_LAUNCHER=1.*
diff --git a/Tests/RunCMake/LinkerLauncher/C-env.cmake b/Tests/RunCMake/LinkerLauncher/C-env.cmake
new file mode 100644
index 0000000..09b5167
--- /dev/null
+++ b/Tests/RunCMake/LinkerLauncher/C-env.cmake
@@ -0,0 +1 @@
+include(C-common.cmake)
diff --git a/Tests/RunCMake/LinkerLauncher/C-launch-Build-stdout.txt b/Tests/RunCMake/LinkerLauncher/C-launch-Build-stdout.txt
new file mode 100644
index 0000000..3313e31
--- /dev/null
+++ b/Tests/RunCMake/LinkerLauncher/C-launch-Build-stdout.txt
@@ -0,0 +1 @@
+.*-E env USED_LAUNCHER=1.*
diff --git a/Tests/RunCMake/LinkerLauncher/C-launch-env-Build-stdout.txt b/Tests/RunCMake/LinkerLauncher/C-launch-env-Build-stdout.txt
new file mode 100644
index 0000000..3313e31
--- /dev/null
+++ b/Tests/RunCMake/LinkerLauncher/C-launch-env-Build-stdout.txt
@@ -0,0 +1 @@
+.*-E env USED_LAUNCHER=1.*
diff --git a/Tests/RunCMake/LinkerLauncher/C-launch-env.cmake b/Tests/RunCMake/LinkerLauncher/C-launch-env.cmake
new file mode 100644
index 0000000..68abcb5
--- /dev/null
+++ b/Tests/RunCMake/LinkerLauncher/C-launch-env.cmake
@@ -0,0 +1,3 @@
+set(CTEST_USE_LAUNCHERS 1)
+include(CTestUseLaunchers)
+include(C-env.cmake)
diff --git a/Tests/RunCMake/LinkerLauncher/C-launch.cmake b/Tests/RunCMake/LinkerLauncher/C-launch.cmake
new file mode 100644
index 0000000..e66ca20
--- /dev/null
+++ b/Tests/RunCMake/LinkerLauncher/C-launch.cmake
@@ -0,0 +1,3 @@
+set(CTEST_USE_LAUNCHERS 1)
+include(CTestUseLaunchers)
+include(C.cmake)
diff --git a/Tests/RunCMake/LinkerLauncher/C.cmake b/Tests/RunCMake/LinkerLauncher/C.cmake
new file mode 100644
index 0000000..b55ca8e
--- /dev/null
+++ b/Tests/RunCMake/LinkerLauncher/C.cmake
@@ -0,0 +1,2 @@
+set(CMAKE_C_LINKER_LAUNCHER "${CMAKE_COMMAND};-E;env;USED_LAUNCHER=1")
+include(C-common.cmake)
diff --git a/Tests/RunCMake/LinkerLauncher/CMakeLists.txt b/Tests/RunCMake/LinkerLauncher/CMakeLists.txt
new file mode 100644
index 0000000..7cabeb6
--- /dev/null
+++ b/Tests/RunCMake/LinkerLauncher/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.20)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/LinkerLauncher/CXX-Build-stdout.txt b/Tests/RunCMake/LinkerLauncher/CXX-Build-stdout.txt
new file mode 100644
index 0000000..3313e31
--- /dev/null
+++ b/Tests/RunCMake/LinkerLauncher/CXX-Build-stdout.txt
@@ -0,0 +1 @@
+.*-E env USED_LAUNCHER=1.*
diff --git a/Tests/RunCMake/LinkerLauncher/CXX-common.cmake b/Tests/RunCMake/LinkerLauncher/CXX-common.cmake
new file mode 100644
index 0000000..3d2ee00
--- /dev/null
+++ b/Tests/RunCMake/LinkerLauncher/CXX-common.cmake
@@ -0,0 +1,3 @@
+enable_language(CXX)
+set(CMAKE_VERBOSE_MAKEFILE TRUE)
+add_executable(main main.cxx)
diff --git a/Tests/RunCMake/LinkerLauncher/CXX-env-Build-stdout.txt b/Tests/RunCMake/LinkerLauncher/CXX-env-Build-stdout.txt
new file mode 100644
index 0000000..3313e31
--- /dev/null
+++ b/Tests/RunCMake/LinkerLauncher/CXX-env-Build-stdout.txt
@@ -0,0 +1 @@
+.*-E env USED_LAUNCHER=1.*
diff --git a/Tests/RunCMake/LinkerLauncher/CXX-env.cmake b/Tests/RunCMake/LinkerLauncher/CXX-env.cmake
new file mode 100644
index 0000000..db36956
--- /dev/null
+++ b/Tests/RunCMake/LinkerLauncher/CXX-env.cmake
@@ -0,0 +1 @@
+include(CXX-common.cmake)
diff --git a/Tests/RunCMake/LinkerLauncher/CXX-launch-Build-stdout.txt b/Tests/RunCMake/LinkerLauncher/CXX-launch-Build-stdout.txt
new file mode 100644
index 0000000..3313e31
--- /dev/null
+++ b/Tests/RunCMake/LinkerLauncher/CXX-launch-Build-stdout.txt
@@ -0,0 +1 @@
+.*-E env USED_LAUNCHER=1.*
diff --git a/Tests/RunCMake/LinkerLauncher/CXX-launch-env-Build-stdout.txt b/Tests/RunCMake/LinkerLauncher/CXX-launch-env-Build-stdout.txt
new file mode 100644
index 0000000..3313e31
--- /dev/null
+++ b/Tests/RunCMake/LinkerLauncher/CXX-launch-env-Build-stdout.txt
@@ -0,0 +1 @@
+.*-E env USED_LAUNCHER=1.*
diff --git a/Tests/RunCMake/LinkerLauncher/CXX-launch-env.cmake b/Tests/RunCMake/LinkerLauncher/CXX-launch-env.cmake
new file mode 100644
index 0000000..a65cc89
--- /dev/null
+++ b/Tests/RunCMake/LinkerLauncher/CXX-launch-env.cmake
@@ -0,0 +1,3 @@
+set(CTEST_USE_LAUNCHERS 1)
+include(CTestUseLaunchers)
+include(CXX-env.cmake)
diff --git a/Tests/RunCMake/LinkerLauncher/CXX-launch.cmake b/Tests/RunCMake/LinkerLauncher/CXX-launch.cmake
new file mode 100644
index 0000000..3002c9d
--- /dev/null
+++ b/Tests/RunCMake/LinkerLauncher/CXX-launch.cmake
@@ -0,0 +1,3 @@
+set(CTEST_USE_LAUNCHERS 1)
+include(CTestUseLaunchers)
+include(CXX.cmake)
diff --git a/Tests/RunCMake/LinkerLauncher/CXX.cmake b/Tests/RunCMake/LinkerLauncher/CXX.cmake
new file mode 100644
index 0000000..4326614
--- /dev/null
+++ b/Tests/RunCMake/LinkerLauncher/CXX.cmake
@@ -0,0 +1,2 @@
+set(CMAKE_CXX_LINKER_LAUNCHER "${CMAKE_COMMAND};-E;env;USED_LAUNCHER=1")
+include(CXX-common.cmake)
diff --git a/Tests/RunCMake/LinkerLauncher/OBJC-Build-stdout.txt b/Tests/RunCMake/LinkerLauncher/OBJC-Build-stdout.txt
new file mode 100644
index 0000000..3313e31
--- /dev/null
+++ b/Tests/RunCMake/LinkerLauncher/OBJC-Build-stdout.txt
@@ -0,0 +1 @@
+.*-E env USED_LAUNCHER=1.*
diff --git a/Tests/RunCMake/LinkerLauncher/OBJC-common.cmake b/Tests/RunCMake/LinkerLauncher/OBJC-common.cmake
new file mode 100644
index 0000000..7b565f4
--- /dev/null
+++ b/Tests/RunCMake/LinkerLauncher/OBJC-common.cmake
@@ -0,0 +1,3 @@
+enable_language(OBJC)
+set(CMAKE_VERBOSE_MAKEFILE TRUE)
+add_executable(main main.m)
diff --git a/Tests/RunCMake/LinkerLauncher/OBJC-env-Build-stdout.txt b/Tests/RunCMake/LinkerLauncher/OBJC-env-Build-stdout.txt
new file mode 100644
index 0000000..3313e31
--- /dev/null
+++ b/Tests/RunCMake/LinkerLauncher/OBJC-env-Build-stdout.txt
@@ -0,0 +1 @@
+.*-E env USED_LAUNCHER=1.*
diff --git a/Tests/RunCMake/LinkerLauncher/OBJC-env.cmake b/Tests/RunCMake/LinkerLauncher/OBJC-env.cmake
new file mode 100644
index 0000000..949e88d
--- /dev/null
+++ b/Tests/RunCMake/LinkerLauncher/OBJC-env.cmake
@@ -0,0 +1 @@
+include(OBJC-common.cmake)
diff --git a/Tests/RunCMake/LinkerLauncher/OBJC-launch-Build-stdout.txt b/Tests/RunCMake/LinkerLauncher/OBJC-launch-Build-stdout.txt
new file mode 100644
index 0000000..3313e31
--- /dev/null
+++ b/Tests/RunCMake/LinkerLauncher/OBJC-launch-Build-stdout.txt
@@ -0,0 +1 @@
+.*-E env USED_LAUNCHER=1.*
diff --git a/Tests/RunCMake/LinkerLauncher/OBJC-launch-env-Build-stdout.txt b/Tests/RunCMake/LinkerLauncher/OBJC-launch-env-Build-stdout.txt
new file mode 100644
index 0000000..3313e31
--- /dev/null
+++ b/Tests/RunCMake/LinkerLauncher/OBJC-launch-env-Build-stdout.txt
@@ -0,0 +1 @@
+.*-E env USED_LAUNCHER=1.*
diff --git a/Tests/RunCMake/LinkerLauncher/OBJC-launch-env.cmake b/Tests/RunCMake/LinkerLauncher/OBJC-launch-env.cmake
new file mode 100644
index 0000000..1cf13d3
--- /dev/null
+++ b/Tests/RunCMake/LinkerLauncher/OBJC-launch-env.cmake
@@ -0,0 +1,3 @@
+set(CTEST_USE_LAUNCHERS 1)
+include(CTestUseLaunchers)
+include(OBJC-env.cmake)
diff --git a/Tests/RunCMake/LinkerLauncher/OBJC-launch.cmake b/Tests/RunCMake/LinkerLauncher/OBJC-launch.cmake
new file mode 100644
index 0000000..43e8521
--- /dev/null
+++ b/Tests/RunCMake/LinkerLauncher/OBJC-launch.cmake
@@ -0,0 +1,3 @@
+set(CTEST_USE_LAUNCHERS 1)
+include(CTestUseLaunchers)
+include(OBJC.cmake)
diff --git a/Tests/RunCMake/LinkerLauncher/OBJC.cmake b/Tests/RunCMake/LinkerLauncher/OBJC.cmake
new file mode 100644
index 0000000..e0360b3
--- /dev/null
+++ b/Tests/RunCMake/LinkerLauncher/OBJC.cmake
@@ -0,0 +1,2 @@
+set(CMAKE_OBJC_LINKER_LAUNCHER "${CMAKE_COMMAND};-E;env;USED_LAUNCHER=1")
+include(OBJC-common.cmake)
diff --git a/Tests/RunCMake/LinkerLauncher/OBJCXX-Build-stdout.txt b/Tests/RunCMake/LinkerLauncher/OBJCXX-Build-stdout.txt
new file mode 100644
index 0000000..3313e31
--- /dev/null
+++ b/Tests/RunCMake/LinkerLauncher/OBJCXX-Build-stdout.txt
@@ -0,0 +1 @@
+.*-E env USED_LAUNCHER=1.*
diff --git a/Tests/RunCMake/LinkerLauncher/OBJCXX-common.cmake b/Tests/RunCMake/LinkerLauncher/OBJCXX-common.cmake
new file mode 100644
index 0000000..e2ee4eb
--- /dev/null
+++ b/Tests/RunCMake/LinkerLauncher/OBJCXX-common.cmake
@@ -0,0 +1,3 @@
+enable_language(OBJCXX)
+set(CMAKE_VERBOSE_MAKEFILE TRUE)
+add_executable(main main.mm)
diff --git a/Tests/RunCMake/LinkerLauncher/OBJCXX-env-Build-stdout.txt b/Tests/RunCMake/LinkerLauncher/OBJCXX-env-Build-stdout.txt
new file mode 100644
index 0000000..3313e31
--- /dev/null
+++ b/Tests/RunCMake/LinkerLauncher/OBJCXX-env-Build-stdout.txt
@@ -0,0 +1 @@
+.*-E env USED_LAUNCHER=1.*
diff --git a/Tests/RunCMake/LinkerLauncher/OBJCXX-env.cmake b/Tests/RunCMake/LinkerLauncher/OBJCXX-env.cmake
new file mode 100644
index 0000000..3ed966d
--- /dev/null
+++ b/Tests/RunCMake/LinkerLauncher/OBJCXX-env.cmake
@@ -0,0 +1 @@
+include(OBJCXX-common.cmake)
diff --git a/Tests/RunCMake/LinkerLauncher/OBJCXX-launch-Build-stdout.txt b/Tests/RunCMake/LinkerLauncher/OBJCXX-launch-Build-stdout.txt
new file mode 100644
index 0000000..3313e31
--- /dev/null
+++ b/Tests/RunCMake/LinkerLauncher/OBJCXX-launch-Build-stdout.txt
@@ -0,0 +1 @@
+.*-E env USED_LAUNCHER=1.*
diff --git a/Tests/RunCMake/LinkerLauncher/OBJCXX-launch-env-Build-stdout.txt b/Tests/RunCMake/LinkerLauncher/OBJCXX-launch-env-Build-stdout.txt
new file mode 100644
index 0000000..3313e31
--- /dev/null
+++ b/Tests/RunCMake/LinkerLauncher/OBJCXX-launch-env-Build-stdout.txt
@@ -0,0 +1 @@
+.*-E env USED_LAUNCHER=1.*
diff --git a/Tests/RunCMake/LinkerLauncher/OBJCXX-launch-env.cmake b/Tests/RunCMake/LinkerLauncher/OBJCXX-launch-env.cmake
new file mode 100644
index 0000000..04c916a
--- /dev/null
+++ b/Tests/RunCMake/LinkerLauncher/OBJCXX-launch-env.cmake
@@ -0,0 +1,3 @@
+set(CTEST_USE_LAUNCHERS 1)
+include(CTestUseLaunchers)
+include(OBJCXX-env.cmake)
diff --git a/Tests/RunCMake/LinkerLauncher/OBJCXX-launch.cmake b/Tests/RunCMake/LinkerLauncher/OBJCXX-launch.cmake
new file mode 100644
index 0000000..5a54bff
--- /dev/null
+++ b/Tests/RunCMake/LinkerLauncher/OBJCXX-launch.cmake
@@ -0,0 +1,3 @@
+set(CTEST_USE_LAUNCHERS 1)
+include(CTestUseLaunchers)
+include(OBJCXX.cmake)
diff --git a/Tests/RunCMake/LinkerLauncher/OBJCXX.cmake b/Tests/RunCMake/LinkerLauncher/OBJCXX.cmake
new file mode 100644
index 0000000..3667745
--- /dev/null
+++ b/Tests/RunCMake/LinkerLauncher/OBJCXX.cmake
@@ -0,0 +1,2 @@
+set(CMAKE_OBJCXX_LINKER_LAUNCHER "${CMAKE_COMMAND};-E;env;USED_LAUNCHER=1")
+include(OBJCXX-common.cmake)
diff --git a/Tests/RunCMake/LinkerLauncher/RunCMakeTest.cmake b/Tests/RunCMake/LinkerLauncher/RunCMakeTest.cmake
new file mode 100644
index 0000000..8f2bf63
--- /dev/null
+++ b/Tests/RunCMake/LinkerLauncher/RunCMakeTest.cmake
@@ -0,0 +1,37 @@
+include(RunCMake)
+
+function(run_linker_launcher lang)
+ # Preserve build tree so we can reuse it for the ${lang}-Build subtest below
+ set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${lang}-build)
+ set(RunCMake_TEST_NO_CLEAN 1)
+ file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+ file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+ run_cmake(${lang})
+
+ set(RunCMake_TEST_OUTPUT_MERGE 1)
+ if("${RunCMake_GENERATOR}" MATCHES "Ninja")
+ set(verbose_args -- -v)
+ endif()
+ run_cmake_command(${lang}-Build ${CMAKE_COMMAND} --build . ${verbose_args})
+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")
+ run_linker_launcher(${lang})
+ unset(ENV{CMAKE_${core_lang}_LINKER_LAUNCHER})
+endfunction()
+
+set(langs C CXX)
+if(CMake_TEST_OBJC)
+ list(APPEND langs OBJC OBJCXX)
+endif()
+
+foreach(lang ${langs})
+ run_linker_launcher(${lang})
+ run_linker_launcher_env(${lang}-env)
+ if(NOT RunCMake_GENERATOR STREQUAL "Watcom WMake")
+ run_linker_launcher(${lang}-launch)
+ run_linker_launcher_env(${lang}-launch-env)
+ endif()
+endforeach()
diff --git a/Tests/RunCMake/LinkerLauncher/main.c b/Tests/RunCMake/LinkerLauncher/main.c
new file mode 100644
index 0000000..8488f4e
--- /dev/null
+++ b/Tests/RunCMake/LinkerLauncher/main.c
@@ -0,0 +1,4 @@
+int main(void)
+{
+ return 0;
+}
diff --git a/Tests/RunCMake/LinkerLauncher/main.cxx b/Tests/RunCMake/LinkerLauncher/main.cxx
new file mode 100644
index 0000000..f8b643a
--- /dev/null
+++ b/Tests/RunCMake/LinkerLauncher/main.cxx
@@ -0,0 +1,4 @@
+int main()
+{
+ return 0;
+}
diff --git a/Tests/RunCMake/LinkerLauncher/main.m b/Tests/RunCMake/LinkerLauncher/main.m
new file mode 100644
index 0000000..8488f4e
--- /dev/null
+++ b/Tests/RunCMake/LinkerLauncher/main.m
@@ -0,0 +1,4 @@
+int main(void)
+{
+ return 0;
+}
diff --git a/Tests/RunCMake/LinkerLauncher/main.mm b/Tests/RunCMake/LinkerLauncher/main.mm
new file mode 100644
index 0000000..f8b643a
--- /dev/null
+++ b/Tests/RunCMake/LinkerLauncher/main.mm
@@ -0,0 +1,4 @@
+int main()
+{
+ return 0;
+}