Merge topic 'LWYU-externalization'

14e57e9637 LINK_WHAT_YOU_USE feature: externalize configuration
9c5132a586 PGI: Fix "LINKER:" prefix generated separator
8a93de080c cmGeneratorTarget: Add method for LINKER: prefix translation

Acked-by: Kitware Robot <kwrobot@kitware.com>
Merge-request: !6306
This commit is contained in:
Brad King 2021-07-12 12:43:25 +00:00 committed by Kitware Robot
commit c9cd039e5f
24 changed files with 206 additions and 53 deletions

View File

@ -428,6 +428,7 @@ Variables that Control the Build
/variable/CMAKE_LANG_LINKER_LAUNCHER /variable/CMAKE_LANG_LINKER_LAUNCHER
/variable/CMAKE_LANG_LINK_LIBRARY_FILE_FLAG /variable/CMAKE_LANG_LINK_LIBRARY_FILE_FLAG
/variable/CMAKE_LANG_LINK_LIBRARY_FLAG /variable/CMAKE_LANG_LINK_LIBRARY_FLAG
/variable/CMAKE_LANG_LINK_WHAT_YOU_USE_FLAG
/variable/CMAKE_LANG_VISIBILITY_PRESET /variable/CMAKE_LANG_VISIBILITY_PRESET
/variable/CMAKE_LIBRARY_OUTPUT_DIRECTORY /variable/CMAKE_LIBRARY_OUTPUT_DIRECTORY
/variable/CMAKE_LIBRARY_OUTPUT_DIRECTORY_CONFIG /variable/CMAKE_LIBRARY_OUTPUT_DIRECTORY_CONFIG
@ -438,6 +439,7 @@ Variables that Control the Build
/variable/CMAKE_LINK_LIBRARY_FILE_FLAG /variable/CMAKE_LINK_LIBRARY_FILE_FLAG
/variable/CMAKE_LINK_LIBRARY_FLAG /variable/CMAKE_LINK_LIBRARY_FLAG
/variable/CMAKE_LINK_WHAT_YOU_USE /variable/CMAKE_LINK_WHAT_YOU_USE
/variable/CMAKE_LINK_WHAT_YOU_USE_CHECK
/variable/CMAKE_MACOSX_BUNDLE /variable/CMAKE_MACOSX_BUNDLE
/variable/CMAKE_MACOSX_RPATH /variable/CMAKE_MACOSX_RPATH
/variable/CMAKE_MAP_IMPORTED_CONFIG_CONFIG /variable/CMAKE_MAP_IMPORTED_CONFIG_CONFIG

View File

@ -1,16 +1,22 @@
LINK_WHAT_YOU_USE LINK_WHAT_YOU_USE
--------------------------- -----------------
.. versionadded:: 3.7 .. versionadded:: 3.7
This is a boolean option that when set to ``TRUE`` will automatically run 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 contents of variable :variable:`CMAKE_LINK_WHAT_YOU_USE_CHECK` on the target
``-Wl,--no-as-needed`` will be passed to the target with the link command so after it is linked. In addition, the linker flag specified by variable
that all libraries specified on the command line will be linked into the :variable:`CMAKE_<LANG>_LINK_WHAT_YOU_USE_FLAG` will be passed to the target
target. This will result in the link producing a list of libraries that with the link command so that all libraries specified on the command line will
provide no symbols used by this target but are being linked to it. be linked into the target. This will result in the link producing a list of
This is only applicable to executable and shared library targets and libraries that provide no symbols used by this target but are being linked to
will only work when ld and ldd accept the flags used. 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 This property is initialized by the value of
the :variable:`CMAKE_LINK_WHAT_YOU_USE` variable if it is set the :variable:`CMAKE_LINK_WHAT_YOU_USE` variable if it is set

View File

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

View File

@ -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`.

View File

@ -1,5 +1,5 @@
CMAKE_LINK_WHAT_YOU_USE CMAKE_LINK_WHAT_YOU_USE
--------------------------------- -----------------------
.. versionadded:: 3.7 .. versionadded:: 3.7

View File

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

View File

@ -91,6 +91,14 @@ if(CMAKE_USER_MAKE_RULES_OVERRIDE_C)
set(CMAKE_USER_MAKE_RULES_OVERRIDE_C "${_override}") set(CMAKE_USER_MAKE_RULES_OVERRIDE_C "${_override}")
endif() 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 # for most systems a module is the same as a shared library
# so unless the variable CMAKE_MODULE_EXISTS is set just # so unless the variable CMAKE_MODULE_EXISTS is set just
@ -196,5 +204,3 @@ if(NOT CMAKE_EXECUTABLE_RPATH_LINK_C_FLAG)
endif() endif()
set(CMAKE_C_INFORMATION_LOADED 1) set(CMAKE_C_INFORMATION_LOADED 1)

View File

@ -100,6 +100,15 @@ if(NOT CMAKE_MODULE_EXISTS)
set(CMAKE_SHARED_MODULE_CREATE_CUDA_FLAGS ${CMAKE_SHARED_LIBRARY_CREATE_CUDA_FLAGS}) set(CMAKE_SHARED_MODULE_CREATE_CUDA_FLAGS ${CMAKE_SHARED_LIBRARY_CREATE_CUDA_FLAGS})
endif() 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 # add the flags to the cache based
# on the initial values computed in the platform/*.cmake files # on the initial values computed in the platform/*.cmake files
# use _INIT variables so that this only happens the first time # use _INIT variables so that this only happens the first time

View File

@ -193,6 +193,15 @@ foreach(type SHARED_LIBRARY SHARED_MODULE EXE)
endif() endif()
endforeach() 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 # add the flags to the cache based
# on the initial values computed in the platform/*.cmake files # on the initial values computed in the platform/*.cmake files
# use _INIT variables so that this only happens the first time # use _INIT variables so that this only happens the first time

View File

@ -157,6 +157,15 @@ if(NOT CMAKE_INCLUDE_FLAG_Fortran)
set(CMAKE_INCLUDE_FLAG_Fortran ${CMAKE_INCLUDE_FLAG_C}) set(CMAKE_INCLUDE_FLAG_Fortran ${CMAKE_INCLUDE_FLAG_C})
endif() 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_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}") set(CMAKE_Fortran_FLAGS_INIT "$ENV{FFLAGS} ${CMAKE_Fortran_FLAGS_INIT}")

View File

@ -68,6 +68,15 @@ if(NOT CMAKE_MODULE_EXISTS)
set(CMAKE_SHARED_MODULE_CREATE_HIP_FLAGS ${CMAKE_SHARED_LIBRARY_CREATE_HIP_FLAGS}) set(CMAKE_SHARED_MODULE_CREATE_HIP_FLAGS ${CMAKE_SHARED_LIBRARY_CREATE_HIP_FLAGS})
endif() 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 # add the flags to the cache based
# on the initial values computed in the platform/*.cmake files # on the initial values computed in the platform/*.cmake files
# use _INIT variables so that this only happens the first time # use _INIT variables so that this only happens the first time

View File

@ -91,6 +91,15 @@ if(CMAKE_USER_MAKE_RULES_OVERRIDE_OBJC)
set(CMAKE_USER_MAKE_RULES_OVERRIDE_OBJC "${_override}") set(CMAKE_USER_MAKE_RULES_OVERRIDE_OBJC "${_override}")
endif() 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 # for most systems a module is the same as a shared library
# so unless the variable CMAKE_MODULE_EXISTS is set just # so unless the variable CMAKE_MODULE_EXISTS is set just

View File

@ -189,6 +189,15 @@ foreach(type SHARED_LIBRARY SHARED_MODULE EXE)
endif() endif()
endforeach() 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 # add the flags to the cache based
# on the initial values computed in the platform/*.cmake files # on the initial values computed in the platform/*.cmake files
# use _INIT variables so that this only happens the first time # use _INIT variables so that this only happens the first time

View File

@ -70,6 +70,15 @@ set(CMAKE_Swift_FLAGS_RELEASE_INIT "-O")
set(CMAKE_Swift_FLAGS_RELWITHDEBINFO_INIT "-O -g") set(CMAKE_Swift_FLAGS_RELWITHDEBINFO_INIT "-O -g")
set(CMAKE_Swift_FLAGS_MINSIZEREL_INIT "-Osize") 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") 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 # NOTE(compnerd) we do not have an object compile rule since we build the objects as part of the link step

View File

@ -26,7 +26,7 @@ macro(__compiler_pgi lang)
endif() endif()
set(CMAKE_${lang}_LINKER_WRAPPER_FLAG "-Wl,") set(CMAKE_${lang}_LINKER_WRAPPER_FLAG "-Wl,")
set(CMAKE_${lang}_LINKER_WRAPPER_FLAG ",") set(CMAKE_${lang}_LINKER_WRAPPER_FLAG_SEP ",")
set(_CMAKE_${lang}_IPO_SUPPORTED_BY_CMAKE YES) set(_CMAKE_${lang}_IPO_SUPPORTED_BY_CMAKE YES)
if(NOT CMAKE_SYSTEM_PROCESSOR STREQUAL ppc64le AND (NOT CMAKE_HOST_WIN32 OR CMAKE_${lang}_COMPILER_VERSION VERSION_LESS 16.3)) if(NOT CMAKE_SYSTEM_PROCESSOR STREQUAL ppc64le AND (NOT CMAKE_HOST_WIN32 OR CMAKE_${lang}_COMPILER_VERSION VERSION_LESS 16.3))

View File

@ -40,6 +40,7 @@ protected:
cmLocalCommonGenerator* LocalCommonGenerator; cmLocalCommonGenerator* LocalCommonGenerator;
cmGlobalCommonGenerator* GlobalCommonGenerator; cmGlobalCommonGenerator* GlobalCommonGenerator;
std::vector<std::string> ConfigNames; std::vector<std::string> ConfigNames;
bool UseLWYU = false;
void AppendFortranFormatFlags(std::string& flags, void AppendFortranFormatFlags(std::string& flags,
cmSourceFile const& source); cmSourceFile const& source);

View File

@ -4461,6 +4461,13 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetLinkOptions(
// Last step: replace "LINKER:" prefixed elements by // Last step: replace "LINKER:" prefixed elements by
// actual linker wrapper // actual linker wrapper
return this->ResolveLinkerWrapper(result, language);
}
std::vector<BT<std::string>>& cmGeneratorTarget::ResolveLinkerWrapper(
std::vector<BT<std::string>>& result, const std::string& language) const
{
// replace "LINKER:" prefixed elements by actual linker wrapper
const std::string wrapper(this->Makefile->GetSafeDefinition( const std::string wrapper(this->Makefile->GetSafeDefinition(
"CMAKE_" + language + "CMAKE_" + language +
(this->IsDeviceLink() ? "_DEVICE_LINKER_WRAPPER_FLAG" (this->IsDeviceLink() ? "_DEVICE_LINKER_WRAPPER_FLAG"

View File

@ -498,6 +498,9 @@ public:
std::vector<BT<std::string>> GetLinkOptions( std::vector<BT<std::string>> GetLinkOptions(
std::string const& config, std::string const& language) const; std::string const& config, std::string const& language) const;
std::vector<BT<std::string>>& ResolveLinkerWrapper(
std::vector<BT<std::string>>& result, const std::string& language) const;
void GetStaticLibraryLinkOptions(std::vector<std::string>& result, void GetStaticLibraryLinkOptions(std::vector<std::string>& result,
const std::string& config, const std::string& config,
const std::string& language) const; const std::string& language) const;

View File

@ -3058,6 +3058,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, void cmLocalGenerator::AppendCompileOptions(std::string& options,
std::string const& options_list, std::string const& options_list,
const char* regex) const const char* regex) const

View File

@ -171,6 +171,8 @@ public:
cmGeneratorTarget* target, cmGeneratorTarget* target,
const std::string& config, const std::string& config,
const std::string& lang); const std::string& lang);
bool AppendLWYUFlags(std::string& flags, const cmGeneratorTarget* target,
const std::string& lang);
enum class IncludePathStyle enum class IncludePathStyle
{ {

View File

@ -397,9 +397,8 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
this->LocalGenerator->GetLinkLibsCMP0065( this->LocalGenerator->GetLinkLibsCMP0065(
linkLanguage, *this->GeneratorTarget)); linkLanguage, *this->GeneratorTarget));
if (this->GeneratorTarget->GetPropertyAsBool("LINK_WHAT_YOU_USE")) { this->UseLWYU = this->LocalGenerator->AppendLWYUFlags(
this->LocalGenerator->AppendFlags(linkFlags, " -Wl,--no-as-needed"); linkFlags, this->GeneratorTarget, linkLanguage);
}
// Add language feature flags. // Add language feature flags.
this->LocalGenerator->AddLanguageFlagsForLinking( this->LocalGenerator->AddLanguageFlagsForLinking(
@ -577,12 +576,18 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
vars.Launcher = linkerLauncher.c_str(); vars.Launcher = linkerLauncher.c_str();
} }
if (this->GeneratorTarget->GetPropertyAsBool("LINK_WHAT_YOU_USE")) { if (this->UseLWYU) {
std::string cmakeCommand = cmProp lwyuCheck =
cmStrCat(this->LocalGenerator->ConvertToOutputFormat( this->Makefile->GetDefinition("CMAKE_LINK_WHAT_YOU_USE_CHECK");
cmSystemTools::GetCMakeCommand(), cmLocalGenerator::SHELL), if (lwyuCheck) {
" -E __run_co_compile --lwyu=", targetOutPathReal); std::string cmakeCommand = cmStrCat(
real_link_commands.push_back(std::move(cmakeCommand)); 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; std::string launcher;

View File

@ -178,9 +178,9 @@ void cmMakefileLibraryTargetGenerator::WriteSharedLibraryRules(bool relink)
this->AddModuleDefinitionFlag(linkLineComputer.get(), extraFlags, this->AddModuleDefinitionFlag(linkLineComputer.get(), extraFlags,
this->GetConfigName()); this->GetConfigName());
if (this->GeneratorTarget->GetPropertyAsBool("LINK_WHAT_YOU_USE")) { this->UseLWYU = this->LocalGenerator->AppendLWYUFlags(
this->LocalGenerator->AppendFlags(extraFlags, " -Wl,--no-as-needed"); extraFlags, this->GeneratorTarget, linkLanguage);
}
this->WriteLibraryRules(linkRuleVar, extraFlags, relink); this->WriteLibraryRules(linkRuleVar, extraFlags, relink);
} }
@ -871,13 +871,18 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
// Get the set of commands. // Get the set of commands.
std::string linkRule = this->GetLinkRule(linkRuleVar); std::string linkRule = this->GetLinkRule(linkRuleVar);
cmExpandList(linkRule, real_link_commands); cmExpandList(linkRule, real_link_commands);
if (this->GeneratorTarget->GetPropertyAsBool("LINK_WHAT_YOU_USE") && if (this->UseLWYU) {
(this->GeneratorTarget->GetType() == cmStateEnums::SHARED_LIBRARY)) { cmProp lwyuCheck =
std::string cmakeCommand = cmStrCat( this->Makefile->GetDefinition("CMAKE_LINK_WHAT_YOU_USE_CHECK");
this->LocalGenerator->ConvertToOutputFormat( if (lwyuCheck) {
cmSystemTools::GetCMakeCommand(), cmLocalGenerator::SHELL), std::string cmakeCommand = cmStrCat(
" -E __run_co_compile --lwyu=", targetOutPathReal); this->LocalGenerator->ConvertToOutputFormat(
real_link_commands.push_back(std::move(cmakeCommand)); 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. // Expand placeholders.

View File

@ -581,17 +581,23 @@ std::vector<std::string> cmNinjaNormalTargetGenerator::ComputeLinkCmd(
} }
} }
cmExpandList(linkCmdStr, linkCmds); cmExpandList(linkCmdStr, linkCmds);
if (this->GetGeneratorTarget()->GetPropertyAsBool("LINK_WHAT_YOU_USE")) { if (this->UseLWYU) {
std::string cmakeCommand = cmStrCat( cmProp lwyuCheck = mf->GetDefinition("CMAKE_LINK_WHAT_YOU_USE_CHECK");
this->GetLocalGenerator()->ConvertToOutputFormat( if (lwyuCheck) {
cmSystemTools::GetCMakeCommand(), cmLocalGenerator::SHELL), std::string cmakeCommand = cmStrCat(
" -E __run_co_compile --lwyu="); this->GetLocalGenerator()->ConvertToOutputFormat(
cmGeneratorTarget& gt = *this->GetGeneratorTarget(); cmSystemTools::GetCMakeCommand(), cmLocalGenerator::SHELL),
std::string targetOutputReal = this->ConvertToNinjaPath( " -E __run_co_compile --lwyu=");
gt.GetFullPath(config, cmStateEnums::RuntimeBinaryArtifact, cmakeCommand +=
/*realname=*/true)); this->GetLocalGenerator()->EscapeForShell(*lwyuCheck);
cmakeCommand += targetOutputReal;
linkCmds.push_back(std::move(cmakeCommand)); 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; return linkCmds;
} }
@ -1156,9 +1162,11 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement(
this->AddModuleDefinitionFlag(linkLineComputer.get(), vars["LINK_FLAGS"], this->AddModuleDefinitionFlag(linkLineComputer.get(), vars["LINK_FLAGS"],
config); 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["LINK_FLAGS"] = globalGen->EncodeLiteral(vars["LINK_FLAGS"]);
vars["MANIFESTS"] = this->GetManifests(config); vars["MANIFESTS"] = this->GetManifests(config);

View File

@ -385,18 +385,15 @@ int HandleTidy(const std::string& runCmd, const std::string& sourceFile,
return ret; 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>&) const std::vector<std::string>&)
{ {
// Construct the ldd -r -u (link what you use lwyu) command line // Construct the ldd -r -u (link what you use lwyu) command line
// ldd -u -r lwuy target // ldd -u -r lwuy target
std::vector<std::string> lwyu_cmd; std::vector<std::string> lwyu_cmd = cmExpandedList(runCmd, true);
lwyu_cmd.emplace_back("ldd"); lwyu_cmd.push_back(sourceFile);
lwyu_cmd.emplace_back("-u");
lwyu_cmd.emplace_back("-r");
lwyu_cmd.push_back(runCmd);
// Run the ldd -u -r command line. // Run the lwyu check command line, currently ldd is expected.
// Capture its stdout and hide its stderr. // Capture its stdout and hide its stderr.
// Ignore its return code because the tool always returns non-zero // Ignore its return code because the tool always returns non-zero
// if there are any warnings, but we just want to warn. // if there are any warnings, but we just want to warn.