From ae108418ae45aff7740605bb7add3843b050d226 Mon Sep 17 00:00:00 2001 From: Bobby D Reynolds Date: Tue, 18 May 2021 08:57:02 -0700 Subject: Launchers: Support setting linker launchers Fixes: #18316 --- Auxiliary/vim/syntax/cmake.vim | 4 +++ Help/envvar/CMAKE_LANG_LINKER_LAUNCHER.rst | 13 ++++++++ Help/manual/cmake-env-variables.7.rst | 1 + Help/manual/cmake-properties.7.rst | 1 + Help/manual/cmake-variables.7.rst | 1 + Help/prop_tgt/LANG_LINKER_LAUNCHER.rst | 16 ++++++++++ Help/release/dev/linker-launcher.rst | 7 ++++ Help/variable/CMAKE_LANG_LINKER_LAUNCHER.rst | 11 +++++++ Modules/CMakeCInformation.cmake | 5 +++ Modules/CMakeCXXInformation.cmake | 5 +++ Modules/CMakeOBJCInformation.cmake | 5 +++ Modules/CMakeOBJCXXInformation.cmake | 5 +++ Source/cmCommonTargetGenerator.cxx | 22 +++++++++++++ Source/cmCommonTargetGenerator.h | 2 ++ Source/cmMakefileExecutableTargetGenerator.cxx | 6 ++++ Source/cmMakefileLibraryTargetGenerator.cxx | 6 ++++ Source/cmNinjaNormalTargetGenerator.cxx | 5 +++ Source/cmRulePlaceholderExpander.cxx | 20 +++++++++++- Source/cmRulePlaceholderExpander.h | 1 + Source/cmTarget.cxx | 4 +++ Tests/RunCMake/CMakeLists.txt | 2 ++ Tests/RunCMake/LinkerLauncher/C-Build-stdout.txt | 1 + Tests/RunCMake/LinkerLauncher/C-common.cmake | 3 ++ .../RunCMake/LinkerLauncher/C-env-Build-stdout.txt | 1 + Tests/RunCMake/LinkerLauncher/C-env.cmake | 1 + .../LinkerLauncher/C-launch-Build-stdout.txt | 1 + .../LinkerLauncher/C-launch-env-Build-stdout.txt | 1 + Tests/RunCMake/LinkerLauncher/C-launch-env.cmake | 3 ++ Tests/RunCMake/LinkerLauncher/C-launch.cmake | 3 ++ Tests/RunCMake/LinkerLauncher/C.cmake | 2 ++ Tests/RunCMake/LinkerLauncher/CMakeLists.txt | 3 ++ Tests/RunCMake/LinkerLauncher/CXX-Build-stdout.txt | 1 + Tests/RunCMake/LinkerLauncher/CXX-common.cmake | 3 ++ .../LinkerLauncher/CXX-env-Build-stdout.txt | 1 + Tests/RunCMake/LinkerLauncher/CXX-env.cmake | 1 + .../LinkerLauncher/CXX-launch-Build-stdout.txt | 1 + .../LinkerLauncher/CXX-launch-env-Build-stdout.txt | 1 + Tests/RunCMake/LinkerLauncher/CXX-launch-env.cmake | 3 ++ Tests/RunCMake/LinkerLauncher/CXX-launch.cmake | 3 ++ Tests/RunCMake/LinkerLauncher/CXX.cmake | 2 ++ .../RunCMake/LinkerLauncher/OBJC-Build-stdout.txt | 1 + Tests/RunCMake/LinkerLauncher/OBJC-common.cmake | 3 ++ .../LinkerLauncher/OBJC-env-Build-stdout.txt | 1 + Tests/RunCMake/LinkerLauncher/OBJC-env.cmake | 1 + .../LinkerLauncher/OBJC-launch-Build-stdout.txt | 1 + .../OBJC-launch-env-Build-stdout.txt | 1 + .../RunCMake/LinkerLauncher/OBJC-launch-env.cmake | 3 ++ Tests/RunCMake/LinkerLauncher/OBJC-launch.cmake | 3 ++ Tests/RunCMake/LinkerLauncher/OBJC.cmake | 2 ++ .../LinkerLauncher/OBJCXX-Build-stdout.txt | 1 + Tests/RunCMake/LinkerLauncher/OBJCXX-common.cmake | 3 ++ .../LinkerLauncher/OBJCXX-env-Build-stdout.txt | 1 + Tests/RunCMake/LinkerLauncher/OBJCXX-env.cmake | 1 + .../LinkerLauncher/OBJCXX-launch-Build-stdout.txt | 1 + .../OBJCXX-launch-env-Build-stdout.txt | 1 + .../LinkerLauncher/OBJCXX-launch-env.cmake | 3 ++ Tests/RunCMake/LinkerLauncher/OBJCXX-launch.cmake | 3 ++ Tests/RunCMake/LinkerLauncher/OBJCXX.cmake | 2 ++ Tests/RunCMake/LinkerLauncher/RunCMakeTest.cmake | 37 ++++++++++++++++++++++ Tests/RunCMake/LinkerLauncher/main.c | 4 +++ Tests/RunCMake/LinkerLauncher/main.cxx | 4 +++ Tests/RunCMake/LinkerLauncher/main.m | 4 +++ Tests/RunCMake/LinkerLauncher/main.mm | 4 +++ 63 files changed, 261 insertions(+), 1 deletion(-) create mode 100644 Help/envvar/CMAKE_LANG_LINKER_LAUNCHER.rst create mode 100644 Help/prop_tgt/LANG_LINKER_LAUNCHER.rst create mode 100644 Help/release/dev/linker-launcher.rst create mode 100644 Help/variable/CMAKE_LANG_LINKER_LAUNCHER.rst create mode 100644 Tests/RunCMake/LinkerLauncher/C-Build-stdout.txt create mode 100644 Tests/RunCMake/LinkerLauncher/C-common.cmake create mode 100644 Tests/RunCMake/LinkerLauncher/C-env-Build-stdout.txt create mode 100644 Tests/RunCMake/LinkerLauncher/C-env.cmake create mode 100644 Tests/RunCMake/LinkerLauncher/C-launch-Build-stdout.txt create mode 100644 Tests/RunCMake/LinkerLauncher/C-launch-env-Build-stdout.txt create mode 100644 Tests/RunCMake/LinkerLauncher/C-launch-env.cmake create mode 100644 Tests/RunCMake/LinkerLauncher/C-launch.cmake create mode 100644 Tests/RunCMake/LinkerLauncher/C.cmake create mode 100644 Tests/RunCMake/LinkerLauncher/CMakeLists.txt create mode 100644 Tests/RunCMake/LinkerLauncher/CXX-Build-stdout.txt create mode 100644 Tests/RunCMake/LinkerLauncher/CXX-common.cmake create mode 100644 Tests/RunCMake/LinkerLauncher/CXX-env-Build-stdout.txt create mode 100644 Tests/RunCMake/LinkerLauncher/CXX-env.cmake create mode 100644 Tests/RunCMake/LinkerLauncher/CXX-launch-Build-stdout.txt create mode 100644 Tests/RunCMake/LinkerLauncher/CXX-launch-env-Build-stdout.txt create mode 100644 Tests/RunCMake/LinkerLauncher/CXX-launch-env.cmake create mode 100644 Tests/RunCMake/LinkerLauncher/CXX-launch.cmake create mode 100644 Tests/RunCMake/LinkerLauncher/CXX.cmake create mode 100644 Tests/RunCMake/LinkerLauncher/OBJC-Build-stdout.txt create mode 100644 Tests/RunCMake/LinkerLauncher/OBJC-common.cmake create mode 100644 Tests/RunCMake/LinkerLauncher/OBJC-env-Build-stdout.txt create mode 100644 Tests/RunCMake/LinkerLauncher/OBJC-env.cmake create mode 100644 Tests/RunCMake/LinkerLauncher/OBJC-launch-Build-stdout.txt create mode 100644 Tests/RunCMake/LinkerLauncher/OBJC-launch-env-Build-stdout.txt create mode 100644 Tests/RunCMake/LinkerLauncher/OBJC-launch-env.cmake create mode 100644 Tests/RunCMake/LinkerLauncher/OBJC-launch.cmake create mode 100644 Tests/RunCMake/LinkerLauncher/OBJC.cmake create mode 100644 Tests/RunCMake/LinkerLauncher/OBJCXX-Build-stdout.txt create mode 100644 Tests/RunCMake/LinkerLauncher/OBJCXX-common.cmake create mode 100644 Tests/RunCMake/LinkerLauncher/OBJCXX-env-Build-stdout.txt create mode 100644 Tests/RunCMake/LinkerLauncher/OBJCXX-env.cmake create mode 100644 Tests/RunCMake/LinkerLauncher/OBJCXX-launch-Build-stdout.txt create mode 100644 Tests/RunCMake/LinkerLauncher/OBJCXX-launch-env-Build-stdout.txt create mode 100644 Tests/RunCMake/LinkerLauncher/OBJCXX-launch-env.cmake create mode 100644 Tests/RunCMake/LinkerLauncher/OBJCXX-launch.cmake create mode 100644 Tests/RunCMake/LinkerLauncher/OBJCXX.cmake create mode 100644 Tests/RunCMake/LinkerLauncher/RunCMakeTest.cmake create mode 100644 Tests/RunCMake/LinkerLauncher/main.c create mode 100644 Tests/RunCMake/LinkerLauncher/main.cxx create mode 100644 Tests/RunCMake/LinkerLauncher/main.m create mode 100644 Tests/RunCMake/LinkerLauncher/main.mm 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__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__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 @@ +_LINKER_LAUNCHER +---------------------- + +.. versionadded:: 3.21 + +This property is implemented only when ```` is ``C``, ``CXX``, +``OBJC``, or ``OBJCXX`` + +Specify a :ref:`semicolon-separated list ` 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__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__LINKER_LAUNCHER` variable + and :prop_tgt:`_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__LINKER_LAUNCHER +---------------------------- + +.. versionadded:: 3.21 + +Default value for :prop_tgt:`_LINKER_LAUNCHER` target property. This +variable is used to initialize the property on each target as it is created. +This is done only when ```` is ``C``, ``CXX``, ``OBJC``, or ``OBJCXX``. + +This variable is initialized to the :envvar:`CMAKE__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 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; 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 #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; +} -- cgit v0.12