summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarc Chevrier <marc.chevrier@gmail.com>2021-07-02 08:47:32 (GMT)
committerMarc Chevrier <marc.chevrier@gmail.com>2021-07-09 12:50:50 (GMT)
commit14e57e9637964594461711954c6c906bc22eb7c7 (patch)
tree7e6bbfb2303d1c4377470180a36a6103df1a55fb
parent9c5132a586562c00511fd8ff2bac0250c70dae95 (diff)
downloadCMake-14e57e9637964594461711954c6c906bc22eb7c7.zip
CMake-14e57e9637964594461711954c6c906bc22eb7c7.tar.gz
CMake-14e57e9637964594461711954c6c906bc22eb7c7.tar.bz2
LINK_WHAT_YOU_USE feature: externalize configuration
Currently, this feature is only supported on ELF platforms. So, the property LINK_WHAT_YOU_USE will be ignored for other plateforms. Moreover, flags and commands are now controled by CMake variables. Fixes: #20174
-rw-r--r--Help/manual/cmake-variables.7.rst2
-rw-r--r--Help/prop_tgt/LINK_WHAT_YOU_USE.rst24
-rw-r--r--Help/release/dev/LINK_WHAT_USE_USE-configuration.rst5
-rw-r--r--Help/variable/CMAKE_LANG_LINK_WHAT_YOU_USE_FLAG.rst9
-rw-r--r--Help/variable/CMAKE_LINK_WHAT_YOU_USE.rst2
-rw-r--r--Help/variable/CMAKE_LINK_WHAT_YOU_USE_CHECK.rst10
-rw-r--r--Modules/CMakeCInformation.cmake10
-rw-r--r--Modules/CMakeCUDAInformation.cmake9
-rw-r--r--Modules/CMakeCXXInformation.cmake9
-rw-r--r--Modules/CMakeFortranInformation.cmake9
-rw-r--r--Modules/CMakeHIPInformation.cmake9
-rw-r--r--Modules/CMakeOBJCInformation.cmake9
-rw-r--r--Modules/CMakeOBJCXXInformation.cmake9
-rw-r--r--Modules/CMakeSwiftInformation.cmake9
-rw-r--r--Source/cmCommonTargetGenerator.h1
-rw-r--r--Source/cmLocalGenerator.cxx24
-rw-r--r--Source/cmLocalGenerator.h2
-rw-r--r--Source/cmMakefileExecutableTargetGenerator.cxx23
-rw-r--r--Source/cmMakefileLibraryTargetGenerator.cxx25
-rw-r--r--Source/cmNinjaNormalTargetGenerator.cxx36
-rw-r--r--Source/cmcmd.cxx11
21 files changed, 195 insertions, 52 deletions
diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst
index 39fbbed..02d0beb 100644
--- a/Help/manual/cmake-variables.7.rst
+++ b/Help/manual/cmake-variables.7.rst
@@ -427,6 +427,7 @@ Variables that Control the Build
/variable/CMAKE_LANG_LINKER_LAUNCHER
/variable/CMAKE_LANG_LINK_LIBRARY_FILE_FLAG
/variable/CMAKE_LANG_LINK_LIBRARY_FLAG
+ /variable/CMAKE_LANG_LINK_WHAT_YOU_USE_FLAG
/variable/CMAKE_LANG_VISIBILITY_PRESET
/variable/CMAKE_LIBRARY_OUTPUT_DIRECTORY
/variable/CMAKE_LIBRARY_OUTPUT_DIRECTORY_CONFIG
@@ -437,6 +438,7 @@ Variables that Control the Build
/variable/CMAKE_LINK_LIBRARY_FILE_FLAG
/variable/CMAKE_LINK_LIBRARY_FLAG
/variable/CMAKE_LINK_WHAT_YOU_USE
+ /variable/CMAKE_LINK_WHAT_YOU_USE_CHECK
/variable/CMAKE_MACOSX_BUNDLE
/variable/CMAKE_MACOSX_RPATH
/variable/CMAKE_MAP_IMPORTED_CONFIG_CONFIG
diff --git a/Help/prop_tgt/LINK_WHAT_YOU_USE.rst b/Help/prop_tgt/LINK_WHAT_YOU_USE.rst
index 2ed93ad..d6de0d4 100644
--- a/Help/prop_tgt/LINK_WHAT_YOU_USE.rst
+++ b/Help/prop_tgt/LINK_WHAT_YOU_USE.rst
@@ -1,16 +1,22 @@
LINK_WHAT_YOU_USE
----------------------------
+-----------------
.. versionadded:: 3.7
-This is a boolean option that when set to ``TRUE`` will automatically run
-``ldd -r -u`` on the target after it is linked. In addition, the linker flag
-``-Wl,--no-as-needed`` will be passed to the target with the link command so
-that all libraries specified on the command line will be linked into the
-target. This will result in the link producing a list of libraries that
-provide no symbols used by this target but are being linked to it.
-This is only applicable to executable and shared library targets and
-will only work when ld and ldd accept the flags used.
+This is a boolean option that, when set to ``TRUE``, will automatically run
+contents of variable :variable:`CMAKE_LINK_WHAT_YOU_USE_CHECK` on the target
+after it is linked. In addition, the linker flag specified by variable
+:variable:`CMAKE_<LANG>_LINK_WHAT_YOU_USE_FLAG` will be passed to the target
+with the link command so that all libraries specified on the command line will
+be linked into the target. This will result in the link producing a list of
+libraries that provide no symbols used by this target but are being linked to
+it.
+
+.. note::
+
+ For now, it is only supported for ``ELF`` platforms and is only applicable to
+ executable and shared or module library targets. This property will be
+ ignored for any other targets and configurations.
This property is initialized by the value of
the :variable:`CMAKE_LINK_WHAT_YOU_USE` variable if it is set
diff --git a/Help/release/dev/LINK_WHAT_USE_USE-configuration.rst b/Help/release/dev/LINK_WHAT_USE_USE-configuration.rst
new file mode 100644
index 0000000..990ed36
--- /dev/null
+++ b/Help/release/dev/LINK_WHAT_USE_USE-configuration.rst
@@ -0,0 +1,5 @@
+LINK_WHAT_YOU_USE-configuration
+-------------------------------
+
+* Configuration for :prop_tgt:`LINK_WHAT_YOU_USE` feature is now controlled by
+ ``CMake`` variables and only active for ``ELF`` platforms.
diff --git a/Help/variable/CMAKE_LANG_LINK_WHAT_YOU_USE_FLAG.rst b/Help/variable/CMAKE_LANG_LINK_WHAT_YOU_USE_FLAG.rst
new file mode 100644
index 0000000..5004530
--- /dev/null
+++ b/Help/variable/CMAKE_LANG_LINK_WHAT_YOU_USE_FLAG.rst
@@ -0,0 +1,9 @@
+CMAKE_<LANG>_LINK_WHAT_YOU_USE_FLAG
+-----------------------------------
+
+.. versionadded:: 3.22
+
+Linker flag to be used to configure linker so that all specified libraries on
+the command line will be linked into the target.
+
+See also variable :variable:`CMAKE_LINK_WHAT_YOU_USE_CHECK`.
diff --git a/Help/variable/CMAKE_LINK_WHAT_YOU_USE.rst b/Help/variable/CMAKE_LINK_WHAT_YOU_USE.rst
index 06b3aa8..bca4519 100644
--- a/Help/variable/CMAKE_LINK_WHAT_YOU_USE.rst
+++ b/Help/variable/CMAKE_LINK_WHAT_YOU_USE.rst
@@ -1,5 +1,5 @@
CMAKE_LINK_WHAT_YOU_USE
----------------------------------
+-----------------------
.. versionadded:: 3.7
diff --git a/Help/variable/CMAKE_LINK_WHAT_YOU_USE_CHECK.rst b/Help/variable/CMAKE_LINK_WHAT_YOU_USE_CHECK.rst
new file mode 100644
index 0000000..e626641
--- /dev/null
+++ b/Help/variable/CMAKE_LINK_WHAT_YOU_USE_CHECK.rst
@@ -0,0 +1,10 @@
+CMAKE_LINK_WHAT_YOU_USE_CHECK
+-----------------------------
+
+.. versionadded:: 3.22
+
+Defines the command executed after the link step to check libraries usage.
+This check is currently only defined on ``ELF`` platforms with value
+``ldd -u -r``.
+
+See also :variable:`CMAKE_<LANG>_LINK_WHAT_YOU_USE_FLAG` variables.
diff --git a/Modules/CMakeCInformation.cmake b/Modules/CMakeCInformation.cmake
index 6be1865..665f309 100644
--- a/Modules/CMakeCInformation.cmake
+++ b/Modules/CMakeCInformation.cmake
@@ -91,6 +91,14 @@ if(CMAKE_USER_MAKE_RULES_OVERRIDE_C)
set(CMAKE_USER_MAKE_RULES_OVERRIDE_C "${_override}")
endif()
+if(CMAKE_EXECUTABLE_FORMAT STREQUAL "ELF")
+ if(NOT DEFINED CMAKE_C_LINK_WHAT_YOU_USE_FLAG)
+ set(CMAKE_C_LINK_WHAT_YOU_USE_FLAG "LINKER:--no-as-needed")
+ endif()
+ if(NOT DEFINED CMAKE_LINK_WHAT_YOU_USE_CHECK)
+ set(CMAKE_LINK_WHAT_YOU_USE_CHECK ldd -u -r)
+ endif()
+endif()
# for most systems a module is the same as a shared library
# so unless the variable CMAKE_MODULE_EXISTS is set just
@@ -196,5 +204,3 @@ if(NOT CMAKE_EXECUTABLE_RPATH_LINK_C_FLAG)
endif()
set(CMAKE_C_INFORMATION_LOADED 1)
-
-
diff --git a/Modules/CMakeCUDAInformation.cmake b/Modules/CMakeCUDAInformation.cmake
index a2946f4..e9cfed6 100644
--- a/Modules/CMakeCUDAInformation.cmake
+++ b/Modules/CMakeCUDAInformation.cmake
@@ -100,6 +100,15 @@ if(NOT CMAKE_MODULE_EXISTS)
set(CMAKE_SHARED_MODULE_CREATE_CUDA_FLAGS ${CMAKE_SHARED_LIBRARY_CREATE_CUDA_FLAGS})
endif()
+if(CMAKE_EXECUTABLE_FORMAT STREQUAL "ELF")
+ if(NOT DEFINED CMAKE_CUDA_LINK_WHAT_YOU_USE_FLAG)
+ set(CMAKE_CUDA_LINK_WHAT_YOU_USE_FLAG "LINKER:--no-as-needed")
+ endif()
+ if(NOT DEFINED CMAKE_LINK_WHAT_YOU_USE_CHECK)
+ set(CMAKE_LINK_WHAT_YOU_USE_CHECK ldd -u -r)
+ endif()
+endif()
+
# add the flags to the cache based
# on the initial values computed in the platform/*.cmake files
# use _INIT variables so that this only happens the first time
diff --git a/Modules/CMakeCXXInformation.cmake b/Modules/CMakeCXXInformation.cmake
index 944d236..53abf37 100644
--- a/Modules/CMakeCXXInformation.cmake
+++ b/Modules/CMakeCXXInformation.cmake
@@ -193,6 +193,15 @@ foreach(type SHARED_LIBRARY SHARED_MODULE EXE)
endif()
endforeach()
+if(CMAKE_EXECUTABLE_FORMAT STREQUAL "ELF")
+ if(NOT DEFINED CMAKE_CXX_LINK_WHAT_YOU_USE_FLAG)
+ set(CMAKE_CXX_LINK_WHAT_YOU_USE_FLAG "LINKER:--no-as-needed")
+ endif()
+ if(NOT DEFINED CMAKE_LINK_WHAT_YOU_USE_CHECK)
+ set(CMAKE_LINK_WHAT_YOU_USE_CHECK ldd -u -r)
+ endif()
+endif()
+
# add the flags to the cache based
# on the initial values computed in the platform/*.cmake files
# use _INIT variables so that this only happens the first time
diff --git a/Modules/CMakeFortranInformation.cmake b/Modules/CMakeFortranInformation.cmake
index 9a4ce63..0f71c6f 100644
--- a/Modules/CMakeFortranInformation.cmake
+++ b/Modules/CMakeFortranInformation.cmake
@@ -157,6 +157,15 @@ if(NOT CMAKE_INCLUDE_FLAG_Fortran)
set(CMAKE_INCLUDE_FLAG_Fortran ${CMAKE_INCLUDE_FLAG_C})
endif()
+if(CMAKE_EXECUTABLE_FORMAT STREQUAL "ELF")
+ if(NOT DEFINED CMAKE_Fortran_LINK_WHAT_YOU_USE_FLAG)
+ set(CMAKE_Fortran_LINK_WHAT_YOU_USE_FLAG "LINKER:--no-as-needed")
+ endif()
+ if(NOT DEFINED CMAKE_LINK_WHAT_YOU_USE_CHECK)
+ set(CMAKE_LINK_WHAT_YOU_USE_CHECK ldd -u -r)
+ endif()
+endif()
+
set(CMAKE_VERBOSE_MAKEFILE FALSE CACHE BOOL "If this value is on, makefiles will be generated without the .SILENT directive, and all commands will be echoed to the console during the make. This is useful for debugging only. With Visual Studio IDE projects all commands are done without /nologo.")
set(CMAKE_Fortran_FLAGS_INIT "$ENV{FFLAGS} ${CMAKE_Fortran_FLAGS_INIT}")
diff --git a/Modules/CMakeHIPInformation.cmake b/Modules/CMakeHIPInformation.cmake
index ec37e1c..9862f24 100644
--- a/Modules/CMakeHIPInformation.cmake
+++ b/Modules/CMakeHIPInformation.cmake
@@ -68,6 +68,15 @@ if(NOT CMAKE_MODULE_EXISTS)
set(CMAKE_SHARED_MODULE_CREATE_HIP_FLAGS ${CMAKE_SHARED_LIBRARY_CREATE_HIP_FLAGS})
endif()
+if(CMAKE_EXECUTABLE_FORMAT STREQUAL "ELF")
+ if(NOT DEFINED CMAKE_HIP_LINK_WHAT_YOU_USE_FLAG)
+ set(CMAKE_HIP_LINK_WHAT_YOU_USE_FLAG "LINKER:--no-as-needed")
+ endif()
+ if(NOT DEFINED CMAKE_LINK_WHAT_YOU_USE_CHECK)
+ set(CMAKE_LINK_WHAT_YOU_USE_CHECK ldd -u -r)
+ endif()
+endif()
+
# add the flags to the cache based
# on the initial values computed in the platform/*.cmake files
# use _INIT variables so that this only happens the first time
diff --git a/Modules/CMakeOBJCInformation.cmake b/Modules/CMakeOBJCInformation.cmake
index ac67d01..4c697da 100644
--- a/Modules/CMakeOBJCInformation.cmake
+++ b/Modules/CMakeOBJCInformation.cmake
@@ -91,6 +91,15 @@ if(CMAKE_USER_MAKE_RULES_OVERRIDE_OBJC)
set(CMAKE_USER_MAKE_RULES_OVERRIDE_OBJC "${_override}")
endif()
+if(CMAKE_EXECUTABLE_FORMAT STREQUAL "ELF")
+ if(NOT DEFINED CMAKE_OBJC_LINK_WHAT_YOU_USE_FLAG)
+ set(CMAKE_OBJC_LINK_WHAT_YOU_USE_FLAG "LINKER:--no-as-needed")
+ endif()
+ if(NOT DEFINED CMAKE_LINK_WHAT_YOU_USE_CHECK)
+ set(CMAKE_LINK_WHAT_YOU_USE_CHECK ldd -u -r)
+ endif()
+endif()
+
# for most systems a module is the same as a shared library
# so unless the variable CMAKE_MODULE_EXISTS is set just
diff --git a/Modules/CMakeOBJCXXInformation.cmake b/Modules/CMakeOBJCXXInformation.cmake
index 70e8579..a6d824f 100644
--- a/Modules/CMakeOBJCXXInformation.cmake
+++ b/Modules/CMakeOBJCXXInformation.cmake
@@ -189,6 +189,15 @@ foreach(type SHARED_LIBRARY SHARED_MODULE EXE)
endif()
endforeach()
+if(CMAKE_EXECUTABLE_FORMAT STREQUAL "ELF")
+ if(NOT DEFINED CMAKE_OBJCXX_LINK_WHAT_YOU_USE_FLAG)
+ set(CMAKE_OBJCXX_LINK_WHAT_YOU_USE_FLAG "LINKER:--no-as-needed")
+ endif()
+ if(NOT DEFINED CMAKE_LINK_WHAT_YOU_USE_CHECK)
+ set(CMAKE_LINK_WHAT_YOU_USE_CHECK ldd -u -r)
+ endif()
+endif()
+
# add the flags to the cache based
# on the initial values computed in the platform/*.cmake files
# use _INIT variables so that this only happens the first time
diff --git a/Modules/CMakeSwiftInformation.cmake b/Modules/CMakeSwiftInformation.cmake
index 8f0909c..ecad1d5 100644
--- a/Modules/CMakeSwiftInformation.cmake
+++ b/Modules/CMakeSwiftInformation.cmake
@@ -70,6 +70,15 @@ set(CMAKE_Swift_FLAGS_RELEASE_INIT "-O")
set(CMAKE_Swift_FLAGS_RELWITHDEBINFO_INIT "-O -g")
set(CMAKE_Swift_FLAGS_MINSIZEREL_INIT "-Osize")
+if(CMAKE_EXECUTABLE_FORMAT STREQUAL "ELF")
+ if(NOT DEFINED CMAKE_Swift_LINK_WHAT_YOU_USE_FLAG)
+ set(CMAKE_Swift_LINK_WHAT_YOU_USE_FLAG "LINKER:--no-as-needed")
+ endif()
+ if(NOT DEFINED CMAKE_LINK_WHAT_YOU_USE_CHECK)
+ set(CMAKE_LINK_WHAT_YOU_USE_CHECK ldd -u -r)
+ endif()
+endif()
+
cmake_initialize_per_config_variable(CMAKE_Swift_FLAGS "Swift Compiler Flags")
# NOTE(compnerd) we do not have an object compile rule since we build the objects as part of the link step
diff --git a/Source/cmCommonTargetGenerator.h b/Source/cmCommonTargetGenerator.h
index a156a41..e1a4f8b 100644
--- a/Source/cmCommonTargetGenerator.h
+++ b/Source/cmCommonTargetGenerator.h
@@ -40,6 +40,7 @@ protected:
cmLocalCommonGenerator* LocalCommonGenerator;
cmGlobalCommonGenerator* GlobalCommonGenerator;
std::vector<std::string> ConfigNames;
+ bool UseLWYU = false;
void AppendFortranFormatFlags(std::string& flags,
cmSourceFile const& source);
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index a14f085..6b88a03 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -3047,6 +3047,30 @@ void cmLocalGenerator::AppendPositionIndependentLinkerFlags(
}
}
+bool cmLocalGenerator::AppendLWYUFlags(std::string& flags,
+ const cmGeneratorTarget* target,
+ const std::string& lang)
+{
+ auto useLWYU = target->GetPropertyAsBool("LINK_WHAT_YOU_USE") &&
+ (target->GetType() == cmStateEnums::TargetType::EXECUTABLE ||
+ target->GetType() == cmStateEnums::TargetType::SHARED_LIBRARY ||
+ target->GetType() == cmStateEnums::TargetType::MODULE_LIBRARY);
+
+ if (useLWYU) {
+ const auto& lwyuFlag = this->GetMakefile()->GetSafeDefinition(
+ cmStrCat("CMAKE_", lang, "_LINK_WHAT_YOU_USE_FLAG"));
+ useLWYU = !lwyuFlag.empty();
+
+ if (useLWYU) {
+ std::vector<BT<std::string>> lwyuOpts;
+ lwyuOpts.emplace_back(lwyuFlag);
+ this->AppendFlags(flags, target->ResolveLinkerWrapper(lwyuOpts, lang));
+ }
+ }
+
+ return useLWYU;
+}
+
void cmLocalGenerator::AppendCompileOptions(std::string& options,
std::string const& options_list,
const char* regex) const
diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h
index 993280a..3c896f7 100644
--- a/Source/cmLocalGenerator.h
+++ b/Source/cmLocalGenerator.h
@@ -171,6 +171,8 @@ public:
cmGeneratorTarget* target,
const std::string& config,
const std::string& lang);
+ bool AppendLWYUFlags(std::string& flags, const cmGeneratorTarget* target,
+ const std::string& lang);
enum class IncludePathStyle
{
diff --git a/Source/cmMakefileExecutableTargetGenerator.cxx b/Source/cmMakefileExecutableTargetGenerator.cxx
index 3a2744e..306b38f 100644
--- a/Source/cmMakefileExecutableTargetGenerator.cxx
+++ b/Source/cmMakefileExecutableTargetGenerator.cxx
@@ -397,9 +397,8 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
this->LocalGenerator->GetLinkLibsCMP0065(
linkLanguage, *this->GeneratorTarget));
- if (this->GeneratorTarget->GetPropertyAsBool("LINK_WHAT_YOU_USE")) {
- this->LocalGenerator->AppendFlags(linkFlags, " -Wl,--no-as-needed");
- }
+ this->UseLWYU = this->LocalGenerator->AppendLWYUFlags(
+ linkFlags, this->GeneratorTarget, linkLanguage);
// Add language feature flags.
this->LocalGenerator->AddLanguageFlagsForLinking(
@@ -577,12 +576,18 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
vars.Launcher = linkerLauncher.c_str();
}
- if (this->GeneratorTarget->GetPropertyAsBool("LINK_WHAT_YOU_USE")) {
- std::string cmakeCommand =
- cmStrCat(this->LocalGenerator->ConvertToOutputFormat(
- cmSystemTools::GetCMakeCommand(), cmLocalGenerator::SHELL),
- " -E __run_co_compile --lwyu=", targetOutPathReal);
- real_link_commands.push_back(std::move(cmakeCommand));
+ if (this->UseLWYU) {
+ cmProp lwyuCheck =
+ this->Makefile->GetDefinition("CMAKE_LINK_WHAT_YOU_USE_CHECK");
+ if (lwyuCheck) {
+ std::string cmakeCommand = cmStrCat(
+ this->LocalGenerator->ConvertToOutputFormat(
+ cmSystemTools::GetCMakeCommand(), cmLocalGenerator::SHELL),
+ " -E __run_co_compile --lwyu=");
+ cmakeCommand += this->LocalGenerator->EscapeForShell(*lwyuCheck);
+ cmakeCommand += cmStrCat(" --source=", targetOutPathReal);
+ real_link_commands.push_back(std::move(cmakeCommand));
+ }
}
std::string launcher;
diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx
index d0e3837..64992f2 100644
--- a/Source/cmMakefileLibraryTargetGenerator.cxx
+++ b/Source/cmMakefileLibraryTargetGenerator.cxx
@@ -178,9 +178,9 @@ void cmMakefileLibraryTargetGenerator::WriteSharedLibraryRules(bool relink)
this->AddModuleDefinitionFlag(linkLineComputer.get(), extraFlags,
this->GetConfigName());
- if (this->GeneratorTarget->GetPropertyAsBool("LINK_WHAT_YOU_USE")) {
- this->LocalGenerator->AppendFlags(extraFlags, " -Wl,--no-as-needed");
- }
+ this->UseLWYU = this->LocalGenerator->AppendLWYUFlags(
+ extraFlags, this->GeneratorTarget, linkLanguage);
+
this->WriteLibraryRules(linkRuleVar, extraFlags, relink);
}
@@ -871,13 +871,18 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
// Get the set of commands.
std::string linkRule = this->GetLinkRule(linkRuleVar);
cmExpandList(linkRule, real_link_commands);
- if (this->GeneratorTarget->GetPropertyAsBool("LINK_WHAT_YOU_USE") &&
- (this->GeneratorTarget->GetType() == cmStateEnums::SHARED_LIBRARY)) {
- std::string cmakeCommand = cmStrCat(
- this->LocalGenerator->ConvertToOutputFormat(
- cmSystemTools::GetCMakeCommand(), cmLocalGenerator::SHELL),
- " -E __run_co_compile --lwyu=", targetOutPathReal);
- real_link_commands.push_back(std::move(cmakeCommand));
+ if (this->UseLWYU) {
+ cmProp lwyuCheck =
+ this->Makefile->GetDefinition("CMAKE_LINK_WHAT_YOU_USE_CHECK");
+ if (lwyuCheck) {
+ std::string cmakeCommand = cmStrCat(
+ this->LocalGenerator->ConvertToOutputFormat(
+ cmSystemTools::GetCMakeCommand(), cmLocalGenerator::SHELL),
+ " -E __run_co_compile --lwyu=");
+ cmakeCommand += this->LocalGenerator->EscapeForShell(*lwyuCheck);
+ cmakeCommand += cmStrCat(" --source=", targetOutPathReal);
+ real_link_commands.push_back(std::move(cmakeCommand));
+ }
}
// Expand placeholders.
diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx
index 5a4c652..93a54c2 100644
--- a/Source/cmNinjaNormalTargetGenerator.cxx
+++ b/Source/cmNinjaNormalTargetGenerator.cxx
@@ -581,17 +581,23 @@ std::vector<std::string> cmNinjaNormalTargetGenerator::ComputeLinkCmd(
}
}
cmExpandList(linkCmdStr, linkCmds);
- if (this->GetGeneratorTarget()->GetPropertyAsBool("LINK_WHAT_YOU_USE")) {
- std::string cmakeCommand = cmStrCat(
- this->GetLocalGenerator()->ConvertToOutputFormat(
- cmSystemTools::GetCMakeCommand(), cmLocalGenerator::SHELL),
- " -E __run_co_compile --lwyu=");
- cmGeneratorTarget& gt = *this->GetGeneratorTarget();
- std::string targetOutputReal = this->ConvertToNinjaPath(
- gt.GetFullPath(config, cmStateEnums::RuntimeBinaryArtifact,
- /*realname=*/true));
- cmakeCommand += targetOutputReal;
- linkCmds.push_back(std::move(cmakeCommand));
+ if (this->UseLWYU) {
+ cmProp lwyuCheck = mf->GetDefinition("CMAKE_LINK_WHAT_YOU_USE_CHECK");
+ if (lwyuCheck) {
+ std::string cmakeCommand = cmStrCat(
+ this->GetLocalGenerator()->ConvertToOutputFormat(
+ cmSystemTools::GetCMakeCommand(), cmLocalGenerator::SHELL),
+ " -E __run_co_compile --lwyu=");
+ cmakeCommand +=
+ this->GetLocalGenerator()->EscapeForShell(*lwyuCheck);
+
+ std::string targetOutputReal =
+ this->ConvertToNinjaPath(this->GetGeneratorTarget()->GetFullPath(
+ config, cmStateEnums::RuntimeBinaryArtifact,
+ /*realname=*/true));
+ cmakeCommand += cmStrCat(" --source=", targetOutputReal);
+ linkCmds.push_back(std::move(cmakeCommand));
+ }
}
return linkCmds;
}
@@ -1156,9 +1162,11 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement(
this->AddModuleDefinitionFlag(linkLineComputer.get(), vars["LINK_FLAGS"],
config);
- if (gt->GetPropertyAsBool("LINK_WHAT_YOU_USE")) {
- vars["LINK_FLAGS"] += " -Wl,--no-as-needed";
- }
+
+ this->UseLWYU = this->GetLocalGenerator()->AppendLWYUFlags(
+ vars["LINK_FLAGS"], this->GetGeneratorTarget(),
+ this->TargetLinkLanguage(config));
+
vars["LINK_FLAGS"] = globalGen->EncodeLiteral(vars["LINK_FLAGS"]);
vars["MANIFESTS"] = this->GetManifests(config);
diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx
index 1f4c0b8..1e0f497 100644
--- a/Source/cmcmd.cxx
+++ b/Source/cmcmd.cxx
@@ -385,18 +385,15 @@ int HandleTidy(const std::string& runCmd, const std::string& sourceFile,
return ret;
}
-int HandleLWYU(const std::string& runCmd, const std::string& /* sourceFile */,
+int HandleLWYU(const std::string& runCmd, const std::string& sourceFile,
const std::vector<std::string>&)
{
// Construct the ldd -r -u (link what you use lwyu) command line
// ldd -u -r lwuy target
- std::vector<std::string> lwyu_cmd;
- lwyu_cmd.emplace_back("ldd");
- lwyu_cmd.emplace_back("-u");
- lwyu_cmd.emplace_back("-r");
- lwyu_cmd.push_back(runCmd);
+ std::vector<std::string> lwyu_cmd = cmExpandedList(runCmd, true);
+ lwyu_cmd.push_back(sourceFile);
- // Run the ldd -u -r command line.
+ // Run the lwyu check command line, currently ldd is expected.
// Capture its stdout and hide its stderr.
// Ignore its return code because the tool always returns non-zero
// if there are any warnings, but we just want to warn.