mirror of
https://github.com/Kitware/CMake.git
synced 2026-01-05 21:31:08 -06:00
Fix combined use of compiler launcher with lint tools
When using ccache with clang-tidy, ccache needs to wrap compiler
invocation, rather than cmake invocation. But it needs to do it without
affecting the command line that iwyu-like tools are receiving.
With this fix, if __run_co_compile is used, compile launcher is passed
using the new --launcher option, but if __run_co_compile is not needed,
compiler launcher is prepended to the command line as before.
To better illustrate the change: with this fix if running clang-tidy
with CXX_COMPILER_LAUNCHER set to "/usr/bin/time;-p;ccache" (time -p
added strictly for illustration purposes), the command line changes
from:
/usr/bin/time -p ccache cmake -E __run_co_compile \
--tidy=clang-tidy ... -- g++ ...
to:
cmake -E __run_co_compile \
--launcher="/usr/bin/time;-p;ccache" \
--tidy=clang-tidy ... -- g++ ...
This allows the compiler to be run via the launcher, but leaves tidy
(& friends) invocations unaffected.
Fixes: #16493
This commit is contained in:
committed by
Brad King
parent
020be379f4
commit
eaf9f69d41
@@ -643,6 +643,18 @@ void cmMakefileTargetGenerator::WriteObjectBuildFile(
|
||||
source.GetFullPath(), workingDirectory, compileCommand);
|
||||
}
|
||||
|
||||
// See if we need to use a compiler launcher like ccache or distcc
|
||||
std::string compilerLauncher;
|
||||
if (!compileCommands.empty() && (lang == "C" || lang == "CXX" ||
|
||||
lang == "Fortran" || lang == "CUDA")) {
|
||||
std::string const clauncher_prop = lang + "_COMPILER_LAUNCHER";
|
||||
const char* clauncher =
|
||||
this->GeneratorTarget->GetProperty(clauncher_prop);
|
||||
if (clauncher && *clauncher) {
|
||||
compilerLauncher = clauncher;
|
||||
}
|
||||
}
|
||||
|
||||
// Maybe insert an include-what-you-use runner.
|
||||
if (!compileCommands.empty() && (lang == "C" || lang == "CXX")) {
|
||||
std::string const iwyu_prop = lang + "_INCLUDE_WHAT_YOU_USE";
|
||||
@@ -656,6 +668,13 @@ void cmMakefileTargetGenerator::WriteObjectBuildFile(
|
||||
if ((iwyu && *iwyu) || (tidy && *tidy) || (cpplint && *cpplint) ||
|
||||
(cppcheck && *cppcheck)) {
|
||||
std::string run_iwyu = "$(CMAKE_COMMAND) -E __run_co_compile";
|
||||
if (!compilerLauncher.empty()) {
|
||||
// In __run_co_compile case the launcher command is supplied
|
||||
// via --launcher=<maybe-list> and consumed
|
||||
run_iwyu += " --launcher=";
|
||||
run_iwyu += this->LocalGenerator->EscapeForShell(compilerLauncher);
|
||||
compilerLauncher.clear();
|
||||
}
|
||||
if (iwyu && *iwyu) {
|
||||
run_iwyu += " --iwyu=";
|
||||
run_iwyu += this->LocalGenerator->EscapeForShell(iwyu);
|
||||
@@ -682,21 +701,15 @@ void cmMakefileTargetGenerator::WriteObjectBuildFile(
|
||||
}
|
||||
}
|
||||
|
||||
// Maybe insert a compiler launcher like ccache or distcc
|
||||
if (!compileCommands.empty() && (lang == "C" || lang == "CXX" ||
|
||||
lang == "Fortran" || lang == "CUDA")) {
|
||||
std::string const clauncher_prop = lang + "_COMPILER_LAUNCHER";
|
||||
const char* clauncher =
|
||||
this->GeneratorTarget->GetProperty(clauncher_prop);
|
||||
if (clauncher && *clauncher) {
|
||||
std::vector<std::string> launcher_cmd;
|
||||
cmSystemTools::ExpandListArgument(clauncher, launcher_cmd, true);
|
||||
for (std::string& i : launcher_cmd) {
|
||||
i = this->LocalGenerator->EscapeForShell(i);
|
||||
}
|
||||
std::string const& run_launcher = cmJoin(launcher_cmd, " ") + " ";
|
||||
compileCommands.front().insert(0, run_launcher);
|
||||
// If compiler launcher was specified and not consumed above, it
|
||||
// goes to the beginning of the command line.
|
||||
if (!compileCommands.empty() && !compilerLauncher.empty()) {
|
||||
std::vector<std::string> args;
|
||||
cmSystemTools::ExpandListArgument(compilerLauncher, args, true);
|
||||
for (std::string& i : args) {
|
||||
i = this->LocalGenerator->EscapeForShell(i);
|
||||
}
|
||||
compileCommands.front().insert(0, cmJoin(args, " ") + " ");
|
||||
}
|
||||
|
||||
std::string launcher;
|
||||
|
||||
@@ -653,6 +653,17 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang)
|
||||
cmSystemTools::ExpandListArgument(compileCmd, compileCmds);
|
||||
}
|
||||
|
||||
// See if we need to use a compiler launcher like ccache or distcc
|
||||
std::string compilerLauncher;
|
||||
if (!compileCmds.empty() &&
|
||||
(lang == "C" || lang == "CXX" || lang == "Fortran" || lang == "CUDA")) {
|
||||
std::string const clauncher_prop = lang + "_COMPILER_LAUNCHER";
|
||||
const char* clauncher = this->GeneratorTarget->GetProperty(clauncher_prop);
|
||||
if (clauncher && *clauncher) {
|
||||
compilerLauncher = clauncher;
|
||||
}
|
||||
}
|
||||
|
||||
// Maybe insert an include-what-you-use runner.
|
||||
if (!compileCmds.empty() && (lang == "C" || lang == "CXX")) {
|
||||
std::string const iwyu_prop = lang + "_INCLUDE_WHAT_YOU_USE";
|
||||
@@ -668,6 +679,13 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang)
|
||||
std::string run_iwyu = this->GetLocalGenerator()->ConvertToOutputFormat(
|
||||
cmSystemTools::GetCMakeCommand(), cmOutputConverter::SHELL);
|
||||
run_iwyu += " -E __run_co_compile";
|
||||
if (!compilerLauncher.empty()) {
|
||||
// In __run_co_compile case the launcher command is supplied
|
||||
// via --launcher=<maybe-list> and consumed
|
||||
run_iwyu += " --launcher=";
|
||||
run_iwyu += this->LocalGenerator->EscapeForShell(compilerLauncher);
|
||||
compilerLauncher.clear();
|
||||
}
|
||||
if (iwyu && *iwyu) {
|
||||
run_iwyu += " --iwyu=";
|
||||
run_iwyu += this->GetLocalGenerator()->EscapeForShell(iwyu);
|
||||
@@ -693,20 +711,15 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang)
|
||||
}
|
||||
}
|
||||
|
||||
// Maybe insert a compiler launcher like ccache or distcc
|
||||
if (!compileCmds.empty() &&
|
||||
(lang == "C" || lang == "CXX" || lang == "Fortran" || lang == "CUDA")) {
|
||||
std::string const clauncher_prop = lang + "_COMPILER_LAUNCHER";
|
||||
const char* clauncher = this->GeneratorTarget->GetProperty(clauncher_prop);
|
||||
if (clauncher && *clauncher) {
|
||||
std::vector<std::string> launcher_cmd;
|
||||
cmSystemTools::ExpandListArgument(clauncher, launcher_cmd, true);
|
||||
for (std::string& i : launcher_cmd) {
|
||||
i = this->LocalGenerator->EscapeForShell(i);
|
||||
}
|
||||
std::string const& run_launcher = cmJoin(launcher_cmd, " ") + " ";
|
||||
compileCmds.front().insert(0, run_launcher);
|
||||
// If compiler launcher was specified and not consumed above, it
|
||||
// goes to the beginning of the command line.
|
||||
if (!compileCmds.empty() && !compilerLauncher.empty()) {
|
||||
std::vector<std::string> args;
|
||||
cmSystemTools::ExpandListArgument(compilerLauncher, args, true);
|
||||
for (std::string& i : args) {
|
||||
i = this->LocalGenerator->EscapeForShell(i);
|
||||
}
|
||||
compileCmds.front().insert(0, cmJoin(args, " ") + " ");
|
||||
}
|
||||
|
||||
if (!compileCmds.empty()) {
|
||||
|
||||
@@ -359,7 +359,8 @@ struct CoCompileJob
|
||||
int cmcmd::HandleCoCompileCommands(std::vector<std::string>& args)
|
||||
{
|
||||
std::vector<CoCompileJob> jobs;
|
||||
std::string sourceFile; // store --source=
|
||||
std::string sourceFile; // store --source=
|
||||
std::vector<std::string> launchers; // store --launcher=
|
||||
|
||||
// Default is to run the original command found after -- if the option
|
||||
// does not need to do that, it should be specified here, currently only
|
||||
@@ -390,15 +391,17 @@ int cmcmd::HandleCoCompileCommands(std::vector<std::string>& args)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (cmHasLiteralPrefix(arg, "--source=")) {
|
||||
sourceFile = arg.substr(9);
|
||||
optionFound = true;
|
||||
}
|
||||
// if it was not a co-compiler or --source then error
|
||||
if (!optionFound) {
|
||||
std::cerr << "__run_co_compile given unknown argument: " << arg
|
||||
<< "\n";
|
||||
return 1;
|
||||
if (cmHasLiteralPrefix(arg, "--source=")) {
|
||||
sourceFile = arg.substr(9);
|
||||
} else if (cmHasLiteralPrefix(arg, "--launcher=")) {
|
||||
cmSystemTools::ExpandListArgument(arg.substr(11), launchers, true);
|
||||
} else {
|
||||
// if it was not a co-compiler or --source/--launcher then error
|
||||
std::cerr << "__run_co_compile given unknown argument: " << arg
|
||||
<< "\n";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
} else { // if not doing_options then push to orig_cmd
|
||||
orig_cmd.push_back(arg);
|
||||
@@ -436,6 +439,11 @@ int cmcmd::HandleCoCompileCommands(std::vector<std::string>& args)
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Prepend launcher argument(s), if any
|
||||
if (!launchers.empty()) {
|
||||
orig_cmd.insert(orig_cmd.begin(), launchers.begin(), launchers.end());
|
||||
}
|
||||
|
||||
// Now run the real compiler command and return its result value
|
||||
int ret;
|
||||
if (!cmSystemTools::RunSingleCommand(orig_cmd, nullptr, nullptr, &ret,
|
||||
|
||||
Reference in New Issue
Block a user