Merge topic 'link_what_you_use'
a0902efa
Help: Add notes for topic 'link_what_you_use'96242f80
Add options to run `ldd -u -r` as a "link-what-you-use" tool
This commit is contained in:
commit
e4cb7d7609
|
@ -218,6 +218,7 @@ Properties on Targets
|
||||||
/prop_tgt/LINK_LIBRARIES
|
/prop_tgt/LINK_LIBRARIES
|
||||||
/prop_tgt/LINK_SEARCH_END_STATIC
|
/prop_tgt/LINK_SEARCH_END_STATIC
|
||||||
/prop_tgt/LINK_SEARCH_START_STATIC
|
/prop_tgt/LINK_SEARCH_START_STATIC
|
||||||
|
/prop_tgt/LINK_WHAT_YOU_USE
|
||||||
/prop_tgt/LOCATION_CONFIG
|
/prop_tgt/LOCATION_CONFIG
|
||||||
/prop_tgt/LOCATION
|
/prop_tgt/LOCATION
|
||||||
/prop_tgt/MACOSX_BUNDLE_INFO_PLIST
|
/prop_tgt/MACOSX_BUNDLE_INFO_PLIST
|
||||||
|
|
|
@ -275,6 +275,7 @@ Variables that Control the Build
|
||||||
/variable/CMAKE_LINK_INTERFACE_LIBRARIES
|
/variable/CMAKE_LINK_INTERFACE_LIBRARIES
|
||||||
/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_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
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
LINK_WHAT_YOU_USE
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
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 property is initialized by the value of
|
||||||
|
the :variable:`CMAKE_LINK_WHAT_YOU_USE` variable if it is set
|
||||||
|
when a target is created.
|
|
@ -0,0 +1,7 @@
|
||||||
|
link_what_you_use
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
* A :prop_tgt:`LINK_WHAT_YOU_USE` target property and supporting
|
||||||
|
:variable:`CMAKE_LINK_WHAT_YOU_USE` variable were introduced
|
||||||
|
to detect (on UNIX) shared libraries that are linked but not
|
||||||
|
needed by running ``ldd -r -u``.
|
|
@ -0,0 +1,6 @@
|
||||||
|
CMAKE_LINK_WHAT_YOU_USE
|
||||||
|
---------------------------------
|
||||||
|
|
||||||
|
Default value for :prop_tgt:`LINK_WHAT_YOU_USE` target property.
|
||||||
|
This variable is used to initialize the property on each target as it is
|
||||||
|
created.
|
|
@ -187,6 +187,9 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
|
||||||
this->LocalGenerator->AppendFlags(
|
this->LocalGenerator->AppendFlags(
|
||||||
linkFlags, this->Makefile->GetDefinition(export_flag_var));
|
linkFlags, this->Makefile->GetDefinition(export_flag_var));
|
||||||
}
|
}
|
||||||
|
if (this->GeneratorTarget->GetProperty("LINK_WHAT_YOU_USE")) {
|
||||||
|
this->LocalGenerator->AppendFlags(linkFlags, " -Wl,--no-as-needed");
|
||||||
|
}
|
||||||
|
|
||||||
// Add language feature flags.
|
// Add language feature flags.
|
||||||
this->AddFeatureFlags(flags, linkLanguage);
|
this->AddFeatureFlags(flags, linkLanguage);
|
||||||
|
@ -356,6 +359,15 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
|
||||||
vars.LinkFlags = linkFlags.c_str();
|
vars.LinkFlags = linkFlags.c_str();
|
||||||
vars.Manifests = manifests.c_str();
|
vars.Manifests = manifests.c_str();
|
||||||
|
|
||||||
|
if (this->GeneratorTarget->GetProperty("LINK_WHAT_YOU_USE")) {
|
||||||
|
std::string cmakeCommand =
|
||||||
|
this->Convert(cmSystemTools::GetCMakeCommand(), cmLocalGenerator::NONE,
|
||||||
|
cmLocalGenerator::SHELL);
|
||||||
|
cmakeCommand += " -E __run_iwyu --lwyu=";
|
||||||
|
cmakeCommand += targetOutPathReal;
|
||||||
|
real_link_commands.push_back(cmakeCommand);
|
||||||
|
}
|
||||||
|
|
||||||
// Expand placeholders in the commands.
|
// Expand placeholders in the commands.
|
||||||
this->LocalGenerator->TargetImplib = targetOutPathImport;
|
this->LocalGenerator->TargetImplib = targetOutPathImport;
|
||||||
for (std::vector<std::string>::iterator i = real_link_commands.begin();
|
for (std::vector<std::string>::iterator i = real_link_commands.begin();
|
||||||
|
|
|
@ -163,6 +163,9 @@ void cmMakefileLibraryTargetGenerator::WriteSharedLibraryRules(bool relink)
|
||||||
extraFlags, "CMAKE_SHARED_LINKER_FLAGS", this->ConfigName);
|
extraFlags, "CMAKE_SHARED_LINKER_FLAGS", this->ConfigName);
|
||||||
this->AddModuleDefinitionFlag(extraFlags);
|
this->AddModuleDefinitionFlag(extraFlags);
|
||||||
|
|
||||||
|
if (this->GeneratorTarget->GetProperty("LINK_WHAT_YOU_USE")) {
|
||||||
|
this->LocalGenerator->AppendFlags(extraFlags, " -Wl,--no-as-needed");
|
||||||
|
}
|
||||||
this->WriteLibraryRules(linkRuleVar, extraFlags, relink);
|
this->WriteLibraryRules(linkRuleVar, extraFlags, relink);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -686,6 +689,15 @@ 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);
|
||||||
cmSystemTools::ExpandListArgument(linkRule, real_link_commands);
|
cmSystemTools::ExpandListArgument(linkRule, real_link_commands);
|
||||||
|
if (this->GeneratorTarget->GetProperty("LINK_WHAT_YOU_USE") &&
|
||||||
|
(this->GeneratorTarget->GetType() == cmState::SHARED_LIBRARY)) {
|
||||||
|
std::string cmakeCommand =
|
||||||
|
this->Convert(cmSystemTools::GetCMakeCommand(),
|
||||||
|
cmLocalGenerator::NONE, cmLocalGenerator::SHELL);
|
||||||
|
cmakeCommand += " -E __run_iwyu --lwyu=";
|
||||||
|
cmakeCommand += targetOutPathReal;
|
||||||
|
real_link_commands.push_back(cmakeCommand);
|
||||||
|
}
|
||||||
|
|
||||||
// Expand placeholders.
|
// Expand placeholders.
|
||||||
for (std::vector<std::string>::iterator i = real_link_commands.begin();
|
for (std::vector<std::string>::iterator i = real_link_commands.begin();
|
||||||
|
@ -732,6 +744,7 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
|
||||||
commands.insert(commands.end(), commands1.begin(), commands1.end());
|
commands.insert(commands.end(), commands1.begin(), commands1.end());
|
||||||
commands1.clear();
|
commands1.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the post-build rules when building but not when relinking.
|
// Add the post-build rules when building but not when relinking.
|
||||||
if (!relink) {
|
if (!relink) {
|
||||||
this->LocalGenerator->AppendCustomCommands(
|
this->LocalGenerator->AppendCustomCommands(
|
||||||
|
|
|
@ -313,6 +313,22 @@ std::vector<std::string> cmNinjaNormalTargetGenerator::ComputeLinkCmd()
|
||||||
const char* linkCmd = mf->GetDefinition(linkCmdVar);
|
const char* linkCmd = mf->GetDefinition(linkCmdVar);
|
||||||
if (linkCmd) {
|
if (linkCmd) {
|
||||||
cmSystemTools::ExpandListArgument(linkCmd, linkCmds);
|
cmSystemTools::ExpandListArgument(linkCmd, linkCmds);
|
||||||
|
if (this->GetGeneratorTarget()->GetProperty("LINK_WHAT_YOU_USE")) {
|
||||||
|
std::string cmakeCommand =
|
||||||
|
this->GetLocalGenerator()->ConvertToOutputFormat(
|
||||||
|
cmSystemTools::GetCMakeCommand(), cmLocalGenerator::SHELL);
|
||||||
|
cmakeCommand += " -E __run_iwyu --lwyu=";
|
||||||
|
cmGeneratorTarget& gt = *this->GetGeneratorTarget();
|
||||||
|
const std::string cfgName = this->GetConfigName();
|
||||||
|
std::string targetOutput = ConvertToNinjaPath(gt.GetFullPath(cfgName));
|
||||||
|
std::string targetOutputReal =
|
||||||
|
this->ConvertToNinjaPath(gt.GetFullPath(cfgName,
|
||||||
|
/*implib=*/false,
|
||||||
|
/*realpath=*/true));
|
||||||
|
cmakeCommand += targetOutputReal;
|
||||||
|
cmakeCommand += " || true";
|
||||||
|
linkCmds.push_back(cmakeCommand);
|
||||||
|
}
|
||||||
return linkCmds;
|
return linkCmds;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -485,6 +501,10 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
|
||||||
vars["MANIFESTS"] = this->GetManifests();
|
vars["MANIFESTS"] = this->GetManifests();
|
||||||
|
|
||||||
vars["LINK_PATH"] = frameworkPath + linkPath;
|
vars["LINK_PATH"] = frameworkPath + linkPath;
|
||||||
|
std::string lwyuFlags;
|
||||||
|
if (genTarget.GetProperty("LINK_WHAT_YOU_USE")) {
|
||||||
|
lwyuFlags = " -Wl,--no-as-needed";
|
||||||
|
}
|
||||||
|
|
||||||
// Compute architecture specific link flags. Yes, these go into a different
|
// Compute architecture specific link flags. Yes, these go into a different
|
||||||
// variable for executables, probably due to a mistake made when duplicating
|
// variable for executables, probably due to a mistake made when duplicating
|
||||||
|
@ -492,16 +512,17 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
|
||||||
if (targetType == cmState::EXECUTABLE) {
|
if (targetType == cmState::EXECUTABLE) {
|
||||||
std::string t = vars["FLAGS"];
|
std::string t = vars["FLAGS"];
|
||||||
localGen.AddArchitectureFlags(t, &genTarget, TargetLinkLanguage, cfgName);
|
localGen.AddArchitectureFlags(t, &genTarget, TargetLinkLanguage, cfgName);
|
||||||
|
t += lwyuFlags;
|
||||||
vars["FLAGS"] = t;
|
vars["FLAGS"] = t;
|
||||||
} else {
|
} else {
|
||||||
std::string t = vars["ARCH_FLAGS"];
|
std::string t = vars["ARCH_FLAGS"];
|
||||||
localGen.AddArchitectureFlags(t, &genTarget, TargetLinkLanguage, cfgName);
|
localGen.AddArchitectureFlags(t, &genTarget, TargetLinkLanguage, cfgName);
|
||||||
vars["ARCH_FLAGS"] = t;
|
vars["ARCH_FLAGS"] = t;
|
||||||
t = "";
|
t = "";
|
||||||
|
t += lwyuFlags;
|
||||||
localGen.AddLanguageFlags(t, TargetLinkLanguage, cfgName);
|
localGen.AddLanguageFlags(t, TargetLinkLanguage, cfgName);
|
||||||
vars["LANGUAGE_COMPILE_FLAGS"] = t;
|
vars["LANGUAGE_COMPILE_FLAGS"] = t;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->GetGeneratorTarget()->HasSOName(cfgName)) {
|
if (this->GetGeneratorTarget()->HasSOName(cfgName)) {
|
||||||
vars["SONAME_FLAG"] = mf->GetSONameFlag(this->TargetLinkLanguage);
|
vars["SONAME_FLAG"] = mf->GetSONameFlag(this->TargetLinkLanguage);
|
||||||
vars["SONAME"] = this->TargetNameSO;
|
vars["SONAME"] = this->TargetNameSO;
|
||||||
|
@ -625,7 +646,6 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
|
||||||
vars["POST_BUILD"] = ":";
|
vars["POST_BUILD"] = ":";
|
||||||
symlinkVars["POST_BUILD"] = postBuildCmdLine;
|
symlinkVars["POST_BUILD"] = postBuildCmdLine;
|
||||||
}
|
}
|
||||||
|
|
||||||
cmGlobalNinjaGenerator& globalGen = *this->GetGlobalGenerator();
|
cmGlobalNinjaGenerator& globalGen = *this->GetGlobalGenerator();
|
||||||
|
|
||||||
int commandLineLengthLimit = -1;
|
int commandLineLengthLimit = -1;
|
||||||
|
|
|
@ -139,6 +139,7 @@ void cmTarget::SetMakefile(cmMakefile* mf)
|
||||||
this->SetPropertyDefault("C_CLANG_TIDY", 0);
|
this->SetPropertyDefault("C_CLANG_TIDY", 0);
|
||||||
this->SetPropertyDefault("C_COMPILER_LAUNCHER", 0);
|
this->SetPropertyDefault("C_COMPILER_LAUNCHER", 0);
|
||||||
this->SetPropertyDefault("C_INCLUDE_WHAT_YOU_USE", 0);
|
this->SetPropertyDefault("C_INCLUDE_WHAT_YOU_USE", 0);
|
||||||
|
this->SetPropertyDefault("LINK_WHAT_YOU_USE", 0);
|
||||||
this->SetPropertyDefault("C_STANDARD", 0);
|
this->SetPropertyDefault("C_STANDARD", 0);
|
||||||
this->SetPropertyDefault("C_STANDARD_REQUIRED", 0);
|
this->SetPropertyDefault("C_STANDARD_REQUIRED", 0);
|
||||||
this->SetPropertyDefault("C_EXTENSIONS", 0);
|
this->SetPropertyDefault("C_EXTENSIONS", 0);
|
||||||
|
|
|
@ -271,6 +271,7 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string>& args)
|
||||||
std::string iwyu;
|
std::string iwyu;
|
||||||
std::string tidy;
|
std::string tidy;
|
||||||
std::string sourceFile;
|
std::string sourceFile;
|
||||||
|
std::string lwyu;
|
||||||
for (std::string::size_type cc = 2; cc < args.size(); cc++) {
|
for (std::string::size_type cc = 2; cc < args.size(); cc++) {
|
||||||
std::string const& arg = args[cc];
|
std::string const& arg = args[cc];
|
||||||
if (arg == "--") {
|
if (arg == "--") {
|
||||||
|
@ -281,6 +282,8 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string>& args)
|
||||||
tidy = arg.substr(7);
|
tidy = arg.substr(7);
|
||||||
} else if (doing_options && cmHasLiteralPrefix(arg, "--source=")) {
|
} else if (doing_options && cmHasLiteralPrefix(arg, "--source=")) {
|
||||||
sourceFile = arg.substr(9);
|
sourceFile = arg.substr(9);
|
||||||
|
} else if (doing_options && cmHasLiteralPrefix(arg, "--lwyu=")) {
|
||||||
|
lwyu = arg.substr(7);
|
||||||
} else if (doing_options) {
|
} else if (doing_options) {
|
||||||
std::cerr << "__run_iwyu given unknown argument: " << arg << "\n";
|
std::cerr << "__run_iwyu given unknown argument: " << arg << "\n";
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -288,7 +291,7 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string>& args)
|
||||||
orig_cmd.push_back(arg);
|
orig_cmd.push_back(arg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (tidy.empty() && iwyu.empty()) {
|
if (tidy.empty() && iwyu.empty() && lwyu.empty()) {
|
||||||
std::cerr << "__run_iwyu missing --tidy= or --iwyu=\n";
|
std::cerr << "__run_iwyu missing --tidy= or --iwyu=\n";
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -296,7 +299,7 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string>& args)
|
||||||
std::cerr << "__run_iwyu --tidy= requires --source=\n";
|
std::cerr << "__run_iwyu --tidy= requires --source=\n";
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (orig_cmd.empty()) {
|
if (orig_cmd.empty() && lwyu.empty()) {
|
||||||
std::cerr << "__run_iwyu missing compile command after --\n";
|
std::cerr << "__run_iwyu missing compile command after --\n";
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -345,13 +348,37 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string>& args)
|
||||||
std::cerr << "Error running '" << tidy_cmd[0] << "'\n";
|
std::cerr << "Error running '" << tidy_cmd[0] << "'\n";
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Output the stdout from clang-tidy to stderr
|
// Output the stdout from clang-tidy to stderr
|
||||||
std::cerr << stdOut;
|
std::cerr << stdOut;
|
||||||
}
|
}
|
||||||
|
if (!lwyu.empty()) {
|
||||||
|
// 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.push_back("ldd");
|
||||||
|
lwyu_cmd.push_back("-u");
|
||||||
|
lwyu_cmd.push_back("-r");
|
||||||
|
lwyu_cmd.push_back(lwyu);
|
||||||
|
|
||||||
|
// Run the ldd -u -r command line.
|
||||||
|
// Capture its stdout and hide its stderr.
|
||||||
|
std::string stdOut;
|
||||||
|
if (!cmSystemTools::RunSingleCommand(lwyu_cmd, &stdOut, 0, &ret, 0,
|
||||||
|
cmSystemTools::OUTPUT_NONE)) {
|
||||||
|
std::cerr << "Error running '" << lwyu_cmd[0] << "'\n";
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output the stdout from ldd -r -u to stderr
|
||||||
|
// Warn if lwyu reported anything.
|
||||||
|
if (stdOut.find("Unused direct dependencies:") != stdOut.npos) {
|
||||||
|
std::cerr << "Warning: " << stdOut;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ret = 0;
|
||||||
// Now run the real compiler command and return its result value.
|
// Now run the real compiler command and return its result value.
|
||||||
if (!cmSystemTools::RunSingleCommand(
|
if (lwyu.empty() &&
|
||||||
|
!cmSystemTools::RunSingleCommand(
|
||||||
orig_cmd, 0, 0, &ret, 0, cmSystemTools::OUTPUT_PASSTHROUGH)) {
|
orig_cmd, 0, 0, &ret, 0, cmSystemTools::OUTPUT_PASSTHROUGH)) {
|
||||||
std::cerr << "Error running '" << orig_cmd[0] << "'\n";
|
std::cerr << "Error running '" << orig_cmd[0] << "'\n";
|
||||||
return 1;
|
return 1;
|
||||||
|
|
|
@ -307,6 +307,14 @@ if(CMAKE_OSX_ARCHITECTURES AND XCODE AND NOT "${XCODE_VERSION}" MATCHES "^[^12]"
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if("${CMAKE_GENERATOR}" MATCHES "Make|Ninja")
|
if("${CMAKE_GENERATOR}" MATCHES "Make|Ninja")
|
||||||
|
if(UNIX AND NOT CYGWIN)
|
||||||
|
execute_process(COMMAND ldd --help
|
||||||
|
OUTPUT_VARIABLE LDD_HELP)
|
||||||
|
if("${LDD_HELP}" MATCHES
|
||||||
|
"(-r, --function-relocs.*process data and function relocations.*-u, --unused.*print unused direct dependencies)")
|
||||||
|
add_RunCMake_test(LinkWhatYouUse)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
add_executable(pseudo_tidy pseudo_tidy.c)
|
add_executable(pseudo_tidy pseudo_tidy.c)
|
||||||
add_executable(pseudo_iwyu pseudo_iwyu.c)
|
add_executable(pseudo_iwyu pseudo_iwyu.c)
|
||||||
add_RunCMake_test(ClangTidy -DPSEUDO_TIDY=$<TARGET_FILE:pseudo_tidy>)
|
add_RunCMake_test(ClangTidy -DPSEUDO_TIDY=$<TARGET_FILE:pseudo_tidy>)
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
.*Warning: Unused direct dependencies.*
|
||||||
|
.*libm.*
|
|
@ -0,0 +1,2 @@
|
||||||
|
.*Warning: Unused direct dependencies.*
|
||||||
|
.*libm.*
|
|
@ -0,0 +1,3 @@
|
||||||
|
set(CTEST_USE_LAUNCHERS 1)
|
||||||
|
include(CTestUseLaunchers)
|
||||||
|
include(C.cmake)
|
|
@ -0,0 +1,4 @@
|
||||||
|
enable_language(C)
|
||||||
|
set(CMAKE_LINK_WHAT_YOU_USE TRUE)
|
||||||
|
add_executable(main main.c)
|
||||||
|
target_link_libraries(main m)
|
|
@ -0,0 +1,3 @@
|
||||||
|
cmake_minimum_required(VERSION 3.2)
|
||||||
|
project(${RunCMake_TEST} NONE)
|
||||||
|
include(${RunCMake_TEST}.cmake)
|
|
@ -0,0 +1,2 @@
|
||||||
|
.*Warning: Unused direct dependencies.*
|
||||||
|
.*libm.*
|
|
@ -0,0 +1,2 @@
|
||||||
|
.*Warning: Unused direct dependencies.*
|
||||||
|
.*libm.*
|
|
@ -0,0 +1,3 @@
|
||||||
|
set(CTEST_USE_LAUNCHERS 1)
|
||||||
|
include(CTestUseLaunchers)
|
||||||
|
include(CXX.cmake)
|
|
@ -0,0 +1,4 @@
|
||||||
|
enable_language(CXX)
|
||||||
|
set(CMAKE_LINK_WHAT_YOU_USE TRUE)
|
||||||
|
add_executable(main main.cxx)
|
||||||
|
target_link_libraries(main m)
|
|
@ -0,0 +1,21 @@
|
||||||
|
include(RunCMake)
|
||||||
|
|
||||||
|
|
||||||
|
function(run_lwyu lang)
|
||||||
|
# Use a single build tree for tests without cleaning.
|
||||||
|
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)
|
||||||
|
run_cmake_command(${lang}-Build ${CMAKE_COMMAND} --build .)
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
run_lwyu(CXX)
|
||||||
|
run_lwyu(C)
|
||||||
|
if (NOT RunCMake_GENERATOR STREQUAL "Watcom WMake")
|
||||||
|
run_lwyu(C-launch)
|
||||||
|
run_lwyu(CXX-launch)
|
||||||
|
endif()
|
|
@ -0,0 +1,4 @@
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,4 @@
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
Reference in New Issue