mirror of
https://github.com/Kitware/CMake.git
synced 2026-01-08 06:40:48 -06:00
TargetGenerator: Factor out generation of code check rules
De-duplicate code check rule generation in Ninja and Makefile generators by moving their implementation to `cmCommonTargetGenerator`. Previously Ninja was generating code check rules per language. It was changed to generate code check rules for each source file.
This commit is contained in:
committed by
Brad King
parent
023af4ab2f
commit
993dde925f
@@ -26,6 +26,7 @@
|
|||||||
#include "cmState.h"
|
#include "cmState.h"
|
||||||
#include "cmStateTypes.h"
|
#include "cmStateTypes.h"
|
||||||
#include "cmStringAlgorithms.h"
|
#include "cmStringAlgorithms.h"
|
||||||
|
#include "cmSystemTools.h"
|
||||||
#include "cmValue.h"
|
#include "cmValue.h"
|
||||||
|
|
||||||
cmCommonTargetGenerator::cmCommonTargetGenerator(cmGeneratorTarget* gt)
|
cmCommonTargetGenerator::cmCommonTargetGenerator(cmGeneratorTarget* gt)
|
||||||
@@ -291,6 +292,170 @@ void cmCommonTargetGenerator::AppendOSXVerFlag(std::string& flags,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string cmCommonTargetGenerator::GetCompilerLauncher(
|
||||||
|
std::string const& lang, std::string const& config)
|
||||||
|
{
|
||||||
|
std::string compilerLauncher;
|
||||||
|
if (lang == "C" || lang == "CXX" || lang == "Fortran" || lang == "CUDA" ||
|
||||||
|
lang == "HIP" || lang == "ISPC" || lang == "OBJC" || lang == "OBJCXX") {
|
||||||
|
std::string const clauncher_prop = cmStrCat(lang, "_COMPILER_LAUNCHER");
|
||||||
|
cmValue clauncher = this->GeneratorTarget->GetProperty(clauncher_prop);
|
||||||
|
std::string const evaluatedClauncher = cmGeneratorExpression::Evaluate(
|
||||||
|
*clauncher, this->GeneratorTarget->GetLocalGenerator(), config,
|
||||||
|
this->GeneratorTarget, nullptr, this->GeneratorTarget, lang);
|
||||||
|
if (!evaluatedClauncher.empty()) {
|
||||||
|
compilerLauncher = evaluatedClauncher;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return compilerLauncher;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string cmCommonTargetGenerator::GenerateCodeCheckRules(
|
||||||
|
cmSourceFile const& source, std::string& compilerLauncher,
|
||||||
|
std::string const& cmakeCmd, std::string const& config,
|
||||||
|
std::function<std::string(std::string const&)> const& pathConverter)
|
||||||
|
{
|
||||||
|
auto const lang = source.GetLanguage();
|
||||||
|
std::string tidy;
|
||||||
|
std::string iwyu;
|
||||||
|
std::string cpplint;
|
||||||
|
std::string cppcheck;
|
||||||
|
|
||||||
|
auto evaluateProp = [&](std::string const& prop) -> std::string {
|
||||||
|
auto const value = this->GeneratorTarget->GetProperty(prop);
|
||||||
|
if (!value) {
|
||||||
|
return std::string{};
|
||||||
|
}
|
||||||
|
auto evaluatedProp = cmGeneratorExpression::Evaluate(
|
||||||
|
*value, this->GeneratorTarget->GetLocalGenerator(), config,
|
||||||
|
this->GeneratorTarget, nullptr, this->GeneratorTarget, lang);
|
||||||
|
if (!evaluatedProp.empty()) {
|
||||||
|
return evaluatedProp;
|
||||||
|
}
|
||||||
|
return *value;
|
||||||
|
};
|
||||||
|
std::string const tidy_prop = cmStrCat(lang, "_CLANG_TIDY");
|
||||||
|
tidy = evaluateProp(tidy_prop);
|
||||||
|
|
||||||
|
if (lang == "C" || lang == "CXX") {
|
||||||
|
std::string const iwyu_prop = cmStrCat(lang, "_INCLUDE_WHAT_YOU_USE");
|
||||||
|
iwyu = evaluateProp(iwyu_prop);
|
||||||
|
|
||||||
|
std::string const cpplint_prop = cmStrCat(lang, "_CPPLINT");
|
||||||
|
cpplint = evaluateProp(cpplint_prop);
|
||||||
|
|
||||||
|
std::string const cppcheck_prop = cmStrCat(lang, "_CPPCHECK");
|
||||||
|
cppcheck = evaluateProp(cppcheck_prop);
|
||||||
|
}
|
||||||
|
if (cmNonempty(iwyu) || cmNonempty(tidy) || cmNonempty(cpplint) ||
|
||||||
|
cmNonempty(cppcheck)) {
|
||||||
|
std::string code_check = cmakeCmd + " -E __run_co_compile";
|
||||||
|
if (!compilerLauncher.empty()) {
|
||||||
|
// In __run_co_compile case the launcher command is supplied
|
||||||
|
// via --launcher=<maybe-list> and consumed
|
||||||
|
code_check += " --launcher=";
|
||||||
|
code_check += this->GeneratorTarget->GetLocalGenerator()->EscapeForShell(
|
||||||
|
compilerLauncher);
|
||||||
|
compilerLauncher.clear();
|
||||||
|
}
|
||||||
|
if (cmNonempty(iwyu)) {
|
||||||
|
code_check += " --iwyu=";
|
||||||
|
|
||||||
|
// Only add --driver-mode if it is not already specified, as adding
|
||||||
|
// it unconditionally might override a user-specified driver-mode
|
||||||
|
if (iwyu.find("--driver-mode=") == std::string::npos) {
|
||||||
|
cmValue const p = this->Makefile->GetDefinition(
|
||||||
|
cmStrCat("CMAKE_", lang, "_INCLUDE_WHAT_YOU_USE_DRIVER_MODE"));
|
||||||
|
std::string driverMode;
|
||||||
|
|
||||||
|
if (cmNonempty(p)) {
|
||||||
|
driverMode = *p;
|
||||||
|
} else {
|
||||||
|
driverMode = lang == "C" ? "gcc" : "g++";
|
||||||
|
}
|
||||||
|
|
||||||
|
code_check +=
|
||||||
|
this->GeneratorTarget->GetLocalGenerator()->EscapeForShell(
|
||||||
|
cmStrCat(iwyu, ";--driver-mode=", driverMode));
|
||||||
|
} else {
|
||||||
|
code_check +=
|
||||||
|
this->GeneratorTarget->GetLocalGenerator()->EscapeForShell(iwyu);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (cmNonempty(tidy)) {
|
||||||
|
code_check += " --tidy=";
|
||||||
|
cmValue const p = this->Makefile->GetDefinition(
|
||||||
|
"CMAKE_" + lang + "_CLANG_TIDY_DRIVER_MODE");
|
||||||
|
std::string driverMode;
|
||||||
|
if (cmNonempty(p)) {
|
||||||
|
driverMode = *p;
|
||||||
|
} else {
|
||||||
|
driverMode = lang == "C" ? "gcc" : "g++";
|
||||||
|
}
|
||||||
|
|
||||||
|
auto const generatorName = this->GeneratorTarget->GetLocalGenerator()
|
||||||
|
->GetGlobalGenerator()
|
||||||
|
->GetName();
|
||||||
|
auto const clangTidyExportFixedDir =
|
||||||
|
this->GeneratorTarget->GetClangTidyExportFixesDirectory(lang);
|
||||||
|
auto fixesFile = this->GetClangTidyReplacementsFilePath(
|
||||||
|
clangTidyExportFixedDir, source, config);
|
||||||
|
std::string exportFixes;
|
||||||
|
if (!clangTidyExportFixedDir.empty()) {
|
||||||
|
this->GlobalCommonGenerator->AddClangTidyExportFixesDir(
|
||||||
|
clangTidyExportFixedDir);
|
||||||
|
}
|
||||||
|
if (generatorName.find("Make") != std::string::npos) {
|
||||||
|
if (!clangTidyExportFixedDir.empty()) {
|
||||||
|
this->GlobalCommonGenerator->AddClangTidyExportFixesFile(fixesFile);
|
||||||
|
cmSystemTools::MakeDirectory(
|
||||||
|
cmSystemTools::GetFilenamePath(fixesFile));
|
||||||
|
fixesFile = this->GeneratorTarget->GetLocalGenerator()
|
||||||
|
->MaybeRelativeToCurBinDir(fixesFile);
|
||||||
|
exportFixes = cmStrCat(";--export-fixes=", fixesFile);
|
||||||
|
}
|
||||||
|
code_check +=
|
||||||
|
this->GeneratorTarget->GetLocalGenerator()->EscapeForShell(
|
||||||
|
cmStrCat(tidy, ";--extra-arg-before=--driver-mode=", driverMode,
|
||||||
|
exportFixes));
|
||||||
|
} else if (generatorName.find("Ninja") != std::string::npos) {
|
||||||
|
if (!clangTidyExportFixedDir.empty()) {
|
||||||
|
this->GlobalCommonGenerator->AddClangTidyExportFixesFile(fixesFile);
|
||||||
|
cmSystemTools::MakeDirectory(
|
||||||
|
cmSystemTools::GetFilenamePath(fixesFile));
|
||||||
|
if (!pathConverter) {
|
||||||
|
fixesFile = pathConverter(fixesFile);
|
||||||
|
}
|
||||||
|
exportFixes = cmStrCat(";--export-fixes=", fixesFile);
|
||||||
|
}
|
||||||
|
code_check +=
|
||||||
|
this->GeneratorTarget->GetLocalGenerator()->EscapeForShell(
|
||||||
|
cmStrCat(tidy, ";--extra-arg-before=--driver-mode=", driverMode,
|
||||||
|
exportFixes));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (cmNonempty(cpplint)) {
|
||||||
|
code_check += " --cpplint=";
|
||||||
|
code_check +=
|
||||||
|
this->GeneratorTarget->GetLocalGenerator()->EscapeForShell(cpplint);
|
||||||
|
}
|
||||||
|
if (cmNonempty(cppcheck)) {
|
||||||
|
code_check += " --cppcheck=";
|
||||||
|
code_check +=
|
||||||
|
this->GeneratorTarget->GetLocalGenerator()->EscapeForShell(cppcheck);
|
||||||
|
}
|
||||||
|
if (cmNonempty(tidy) || (cmNonempty(cpplint)) || (cmNonempty(cppcheck))) {
|
||||||
|
code_check += " --source=";
|
||||||
|
code_check +=
|
||||||
|
this->GeneratorTarget->GetLocalGenerator()->ConvertToOutputFormat(
|
||||||
|
source.GetFullPath(), cmOutputConverter::SHELL);
|
||||||
|
}
|
||||||
|
code_check += " -- ";
|
||||||
|
return code_check;
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
std::string cmCommonTargetGenerator::GetLinkerLauncher(
|
std::string cmCommonTargetGenerator::GetLinkerLauncher(
|
||||||
const std::string& config)
|
const std::string& config)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
#include "cmConfigure.h" // IWYU pragma: keep
|
#include "cmConfigure.h" // IWYU pragma: keep
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <string>
|
#include <string>
|
||||||
@@ -53,6 +54,9 @@ protected:
|
|||||||
|
|
||||||
virtual void AddIncludeFlags(std::string& flags, std::string const& lang,
|
virtual void AddIncludeFlags(std::string& flags, std::string const& lang,
|
||||||
const std::string& config) = 0;
|
const std::string& config) = 0;
|
||||||
|
virtual std::string GetClangTidyReplacementsFilePath(
|
||||||
|
std::string const& directory, cmSourceFile const& source,
|
||||||
|
std::string const& config) const = 0;
|
||||||
|
|
||||||
void AppendOSXVerFlag(std::string& flags, const std::string& lang,
|
void AppendOSXVerFlag(std::string& flags, const std::string& lang,
|
||||||
const char* name, bool so);
|
const char* name, bool so);
|
||||||
@@ -63,7 +67,13 @@ protected:
|
|||||||
std::string GetIncludes(std::string const& l, const std::string& config);
|
std::string GetIncludes(std::string const& l, const std::string& config);
|
||||||
std::string GetManifests(const std::string& config);
|
std::string GetManifests(const std::string& config);
|
||||||
std::string GetAIXExports(std::string const& config);
|
std::string GetAIXExports(std::string const& config);
|
||||||
|
std::string GenerateCodeCheckRules(
|
||||||
|
cmSourceFile const& source, std::string& compilerLauncher,
|
||||||
|
std::string const& cmakeCmd, std::string const& config,
|
||||||
|
std::function<std::string(std::string const&)> const& pathConverter);
|
||||||
|
|
||||||
|
std::string GetCompilerLauncher(std::string const& lang,
|
||||||
|
std::string const& config);
|
||||||
std::vector<std::string> GetLinkedTargetDirectories(
|
std::vector<std::string> GetLinkedTargetDirectories(
|
||||||
const std::string& lang, const std::string& config) const;
|
const std::string& lang, const std::string& config) const;
|
||||||
std::string ComputeTargetCompilePDB(const std::string& config) const;
|
std::string ComputeTargetCompilePDB(const std::string& config) const;
|
||||||
|
|||||||
@@ -507,8 +507,18 @@ void cmGlobalNinjaGenerator::WriteVariable(std::ostream& os,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string val;
|
||||||
|
static std::unordered_set<std::string> const variablesShouldNotBeTrimmed = {
|
||||||
|
"CODE_CHECK", "LAUNCHER"
|
||||||
|
};
|
||||||
|
if (variablesShouldNotBeTrimmed.find(name) ==
|
||||||
|
variablesShouldNotBeTrimmed.end()) {
|
||||||
|
val = cmTrimWhitespace(value);
|
||||||
|
} else {
|
||||||
|
val = value;
|
||||||
|
}
|
||||||
|
|
||||||
// Do not add a variable if the value is empty.
|
// Do not add a variable if the value is empty.
|
||||||
std::string val = cmTrimWhitespace(value);
|
|
||||||
if (val.empty()) {
|
if (val.empty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,7 +26,6 @@
|
|||||||
#include "cmGeneratedFileStream.h"
|
#include "cmGeneratedFileStream.h"
|
||||||
#include "cmGeneratorExpression.h"
|
#include "cmGeneratorExpression.h"
|
||||||
#include "cmGeneratorTarget.h"
|
#include "cmGeneratorTarget.h"
|
||||||
#include "cmGlobalCommonGenerator.h"
|
|
||||||
#include "cmGlobalUnixMakefileGenerator3.h"
|
#include "cmGlobalUnixMakefileGenerator3.h"
|
||||||
#include "cmLinkLineComputer.h" // IWYU pragma: keep
|
#include "cmLinkLineComputer.h" // IWYU pragma: keep
|
||||||
#include "cmList.h"
|
#include "cmList.h"
|
||||||
@@ -1054,151 +1053,14 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
|
|||||||
|
|
||||||
// See if we need to use a compiler launcher like ccache or distcc
|
// See if we need to use a compiler launcher like ccache or distcc
|
||||||
std::string compilerLauncher;
|
std::string compilerLauncher;
|
||||||
if (!compileCommands.empty() &&
|
if (!compileCommands.empty()) {
|
||||||
(lang == "C" || lang == "CXX" || lang == "Fortran" || lang == "CUDA" ||
|
compilerLauncher = GetCompilerLauncher(lang, config);
|
||||||
lang == "HIP" || lang == "ISPC" || lang == "OBJC" ||
|
|
||||||
lang == "OBJCXX")) {
|
|
||||||
std::string const clauncher_prop = lang + "_COMPILER_LAUNCHER";
|
|
||||||
cmValue clauncher = this->GeneratorTarget->GetProperty(clauncher_prop);
|
|
||||||
std::string evaluatedClauncher = cmGeneratorExpression::Evaluate(
|
|
||||||
*clauncher, this->LocalGenerator, config, this->GeneratorTarget,
|
|
||||||
nullptr, this->GeneratorTarget, lang);
|
|
||||||
if (!evaluatedClauncher.empty()) {
|
|
||||||
compilerLauncher = evaluatedClauncher;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Maybe insert an include-what-you-use runner.
|
std::string const codeCheck = this->GenerateCodeCheckRules(
|
||||||
if (!compileCommands.empty() &&
|
source, compilerLauncher, "$(CMAKE_COMMAND)", config, nullptr);
|
||||||
(lang == "C" || lang == "CXX" || lang == "OBJC" || lang == "OBJCXX")) {
|
if (!codeCheck.empty()) {
|
||||||
cmValue tidy = nullptr;
|
compileCommands.front().insert(0, codeCheck);
|
||||||
cmValue iwyu = nullptr;
|
|
||||||
cmValue cpplint = nullptr;
|
|
||||||
cmValue cppcheck = nullptr;
|
|
||||||
std::string evaluatedTIDY;
|
|
||||||
std::string evaluatedIWYU;
|
|
||||||
std::string evaluatedCPPlint;
|
|
||||||
std::string evaluatedCPPcheck;
|
|
||||||
|
|
||||||
std::string const tidy_prop = cmStrCat(lang, "_CLANG_TIDY");
|
|
||||||
tidy = this->GeneratorTarget->GetProperty(tidy_prop);
|
|
||||||
evaluatedTIDY = cmGeneratorExpression::Evaluate(
|
|
||||||
*tidy, this->LocalGenerator, config, this->GeneratorTarget, nullptr,
|
|
||||||
this->GeneratorTarget, lang);
|
|
||||||
if (!evaluatedTIDY.empty()) {
|
|
||||||
tidy = cmValue(&evaluatedTIDY);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lang == "C" || lang == "CXX") {
|
|
||||||
std::string const iwyu_prop = cmStrCat(lang, "_INCLUDE_WHAT_YOU_USE");
|
|
||||||
iwyu = this->GeneratorTarget->GetProperty(iwyu_prop);
|
|
||||||
evaluatedIWYU = cmGeneratorExpression::Evaluate(
|
|
||||||
*iwyu, this->LocalGenerator, config, this->GeneratorTarget, nullptr,
|
|
||||||
this->GeneratorTarget, lang);
|
|
||||||
if (!evaluatedIWYU.empty()) {
|
|
||||||
iwyu = cmValue(&evaluatedIWYU);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string const cpplint_prop = cmStrCat(lang, "_CPPLINT");
|
|
||||||
cpplint = this->GeneratorTarget->GetProperty(cpplint_prop);
|
|
||||||
evaluatedCPPlint = cmGeneratorExpression::Evaluate(
|
|
||||||
*cpplint, this->LocalGenerator, config, this->GeneratorTarget,
|
|
||||||
nullptr, this->GeneratorTarget, lang);
|
|
||||||
if (!evaluatedCPPlint.empty()) {
|
|
||||||
cpplint = cmValue(&evaluatedCPPlint);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string const cppcheck_prop = cmStrCat(lang, "_CPPCHECK");
|
|
||||||
cppcheck = this->GeneratorTarget->GetProperty(cppcheck_prop);
|
|
||||||
evaluatedCPPcheck = cmGeneratorExpression::Evaluate(
|
|
||||||
*cppcheck, this->LocalGenerator, config, this->GeneratorTarget,
|
|
||||||
nullptr, this->GeneratorTarget, lang);
|
|
||||||
if (!evaluatedCPPcheck.empty()) {
|
|
||||||
cppcheck = cmValue(&evaluatedCPPcheck);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (cmNonempty(iwyu) || cmNonempty(tidy) || cmNonempty(cpplint) ||
|
|
||||||
cmNonempty(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 (cmNonempty(iwyu)) {
|
|
||||||
run_iwyu += " --iwyu=";
|
|
||||||
|
|
||||||
// Only add --driver-mode if it is not already specified, as adding
|
|
||||||
// it unconditionally might override a user-specified driver-mode
|
|
||||||
if (iwyu.Get()->find("--driver-mode=") == std::string::npos) {
|
|
||||||
cmValue p = this->Makefile->GetDefinition(
|
|
||||||
cmStrCat("CMAKE_", lang, "_INCLUDE_WHAT_YOU_USE_DRIVER_MODE"));
|
|
||||||
std::string driverMode;
|
|
||||||
|
|
||||||
if (cmNonempty(p)) {
|
|
||||||
driverMode = *p;
|
|
||||||
} else {
|
|
||||||
driverMode = lang == "C" ? "gcc" : "g++";
|
|
||||||
}
|
|
||||||
|
|
||||||
run_iwyu += this->LocalGenerator->EscapeForShell(
|
|
||||||
cmStrCat(*iwyu, ";--driver-mode=", driverMode));
|
|
||||||
} else {
|
|
||||||
run_iwyu += this->LocalGenerator->EscapeForShell(*iwyu);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (cmNonempty(tidy)) {
|
|
||||||
run_iwyu += " --tidy=";
|
|
||||||
cmValue p = this->Makefile->GetDefinition("CMAKE_" + lang +
|
|
||||||
"_CLANG_TIDY_DRIVER_MODE");
|
|
||||||
std::string driverMode;
|
|
||||||
if (cmNonempty(p)) {
|
|
||||||
driverMode = *p;
|
|
||||||
} else {
|
|
||||||
driverMode = lang == "C" ? "gcc" : "g++";
|
|
||||||
}
|
|
||||||
std::string d =
|
|
||||||
this->GeneratorTarget->GetClangTidyExportFixesDirectory(lang);
|
|
||||||
std::string exportFixes;
|
|
||||||
if (!d.empty()) {
|
|
||||||
this->GlobalCommonGenerator->AddClangTidyExportFixesDir(d);
|
|
||||||
std::string fixesFile = cmSystemTools::CollapseFullPath(cmStrCat(
|
|
||||||
d, '/',
|
|
||||||
this->LocalGenerator->MaybeRelativeToTopBinDir(cmStrCat(
|
|
||||||
this->LocalGenerator->GetCurrentBinaryDirectory(), '/',
|
|
||||||
this->LocalGenerator->GetTargetDirectory(
|
|
||||||
this->GeneratorTarget),
|
|
||||||
'/', objectName, ".yaml"))));
|
|
||||||
this->GlobalCommonGenerator->AddClangTidyExportFixesFile(
|
|
||||||
fixesFile);
|
|
||||||
cmSystemTools::MakeDirectory(
|
|
||||||
cmSystemTools::GetFilenamePath(fixesFile));
|
|
||||||
fixesFile =
|
|
||||||
this->LocalGenerator->MaybeRelativeToCurBinDir(fixesFile);
|
|
||||||
exportFixes = cmStrCat(";--export-fixes=", fixesFile);
|
|
||||||
}
|
|
||||||
run_iwyu += this->LocalGenerator->EscapeForShell(
|
|
||||||
cmStrCat(*tidy, ";--extra-arg-before=--driver-mode=", driverMode,
|
|
||||||
exportFixes));
|
|
||||||
}
|
|
||||||
if (cmNonempty(cpplint)) {
|
|
||||||
run_iwyu += " --cpplint=";
|
|
||||||
run_iwyu += this->LocalGenerator->EscapeForShell(*cpplint);
|
|
||||||
}
|
|
||||||
if (cmNonempty(cppcheck)) {
|
|
||||||
run_iwyu += " --cppcheck=";
|
|
||||||
run_iwyu += this->LocalGenerator->EscapeForShell(*cppcheck);
|
|
||||||
}
|
|
||||||
if (cmNonempty(tidy) || (cmNonempty(cpplint)) ||
|
|
||||||
(cmNonempty(cppcheck))) {
|
|
||||||
run_iwyu += " --source=";
|
|
||||||
run_iwyu += sourceFile;
|
|
||||||
}
|
|
||||||
run_iwyu += " -- ";
|
|
||||||
compileCommands.front().insert(0, run_iwyu);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If compiler launcher was specified and not consumed above, it
|
// If compiler launcher was specified and not consumed above, it
|
||||||
@@ -1519,6 +1381,23 @@ void cmMakefileTargetGenerator::WriteTargetLinkDependRules()
|
|||||||
this->GeneratorTarget->GetFullPath(this->GetConfigName()), depFile,
|
this->GeneratorTarget->GetFullPath(this->GetConfigName()), depFile,
|
||||||
cmDependencyScannerKind::Compiler);
|
cmDependencyScannerKind::Compiler);
|
||||||
}
|
}
|
||||||
|
std::string cmMakefileTargetGenerator::GetClangTidyReplacementsFilePath(
|
||||||
|
std::string const& directory, cmSourceFile const& source,
|
||||||
|
std::string const& config) const
|
||||||
|
{
|
||||||
|
(void)config;
|
||||||
|
auto const& objectName = this->GeneratorTarget->GetObjectName(&source);
|
||||||
|
auto fixesFile = cmSystemTools::CollapseFullPath(cmStrCat(
|
||||||
|
directory, '/',
|
||||||
|
this->GeneratorTarget->GetLocalGenerator()->MaybeRelativeToTopBinDir(
|
||||||
|
cmStrCat(this->GeneratorTarget->GetLocalGenerator()
|
||||||
|
->GetCurrentBinaryDirectory(),
|
||||||
|
'/',
|
||||||
|
this->GeneratorTarget->GetLocalGenerator()->GetTargetDirectory(
|
||||||
|
this->GeneratorTarget),
|
||||||
|
'/', objectName, ".yaml"))));
|
||||||
|
return fixesFile;
|
||||||
|
}
|
||||||
|
|
||||||
void cmMakefileTargetGenerator::WriteTargetDependRules()
|
void cmMakefileTargetGenerator::WriteTargetDependRules()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -82,6 +82,10 @@ protected:
|
|||||||
// write the depend rules for this target
|
// write the depend rules for this target
|
||||||
void WriteTargetDependRules();
|
void WriteTargetDependRules();
|
||||||
|
|
||||||
|
std::string GetClangTidyReplacementsFilePath(
|
||||||
|
std::string const& directory, cmSourceFile const& source,
|
||||||
|
std::string const& config) const override;
|
||||||
|
|
||||||
// write rules for macOS Application Bundle content.
|
// write rules for macOS Application Bundle content.
|
||||||
struct MacOSXContentGeneratorType
|
struct MacOSXContentGeneratorType
|
||||||
: cmOSXBundleGenerator::MacOSXContentGeneratorType
|
: cmOSXBundleGenerator::MacOSXContentGeneratorType
|
||||||
|
|||||||
@@ -29,7 +29,6 @@
|
|||||||
#include "cmGeneratedFileStream.h"
|
#include "cmGeneratedFileStream.h"
|
||||||
#include "cmGeneratorExpression.h"
|
#include "cmGeneratorExpression.h"
|
||||||
#include "cmGeneratorTarget.h"
|
#include "cmGeneratorTarget.h"
|
||||||
#include "cmGlobalCommonGenerator.h"
|
|
||||||
#include "cmGlobalNinjaGenerator.h"
|
#include "cmGlobalNinjaGenerator.h"
|
||||||
#include "cmList.h"
|
#include "cmList.h"
|
||||||
#include "cmLocalGenerator.h"
|
#include "cmLocalGenerator.h"
|
||||||
@@ -399,15 +398,15 @@ std::string cmNinjaTargetGenerator::GetObjectFilePath(
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::string cmNinjaTargetGenerator::GetClangTidyReplacementsFilePath(
|
std::string cmNinjaTargetGenerator::GetClangTidyReplacementsFilePath(
|
||||||
const std::string& directory, cmSourceFile const* source,
|
std::string const& directory, cmSourceFile const& source,
|
||||||
const std::string& config) const
|
std::string const& config) const
|
||||||
{
|
{
|
||||||
std::string path = this->LocalGenerator->GetHomeRelativeOutputPath();
|
auto path = this->LocalGenerator->GetHomeRelativeOutputPath();
|
||||||
if (!path.empty()) {
|
if (!path.empty()) {
|
||||||
path += '/';
|
path += '/';
|
||||||
}
|
}
|
||||||
path = cmStrCat(directory, '/', path);
|
path = cmStrCat(directory, '/', path);
|
||||||
std::string const& objectName = this->GeneratorTarget->GetObjectName(source);
|
auto const& objectName = this->GeneratorTarget->GetObjectName(&source);
|
||||||
path =
|
path =
|
||||||
cmStrCat(std::move(path),
|
cmStrCat(std::move(path),
|
||||||
this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget),
|
this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget),
|
||||||
@@ -890,162 +889,9 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang,
|
|||||||
const std::string& compileCmd = mf->GetRequiredDefinition(cmdVar);
|
const std::string& compileCmd = mf->GetRequiredDefinition(cmdVar);
|
||||||
cmList compileCmds(compileCmd);
|
cmList compileCmds(compileCmd);
|
||||||
|
|
||||||
// See if we need to use a compiler launcher like ccache or distcc
|
if (!compileCmds.empty()) {
|
||||||
std::string compilerLauncher;
|
compileCmds.front().insert(0, "${CODE_CHECK}");
|
||||||
if (!compileCmds.empty() &&
|
compileCmds.front().insert(0, "${LAUNCHER}");
|
||||||
(lang == "C" || lang == "CXX" || lang == "Fortran" || lang == "CUDA" ||
|
|
||||||
lang == "HIP" || lang == "ISPC" || lang == "OBJC" ||
|
|
||||||
lang == "OBJCXX")) {
|
|
||||||
std::string const clauncher_prop = cmStrCat(lang, "_COMPILER_LAUNCHER");
|
|
||||||
cmValue clauncher = this->GeneratorTarget->GetProperty(clauncher_prop);
|
|
||||||
std::string evaluatedClauncher = cmGeneratorExpression::Evaluate(
|
|
||||||
*clauncher, this->LocalGenerator, config, this->GeneratorTarget, nullptr,
|
|
||||||
this->GeneratorTarget, lang);
|
|
||||||
if (!evaluatedClauncher.empty()) {
|
|
||||||
compilerLauncher = evaluatedClauncher;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Maybe insert an include-what-you-use runner.
|
|
||||||
if (!compileCmds.empty() &&
|
|
||||||
(lang == "C" || lang == "CXX" || lang == "OBJC" || lang == "OBJCXX")) {
|
|
||||||
cmValue tidy = nullptr;
|
|
||||||
cmValue iwyu = nullptr;
|
|
||||||
cmValue cpplint = nullptr;
|
|
||||||
cmValue cppcheck = nullptr;
|
|
||||||
std::string evaluatedTIDY;
|
|
||||||
std::string evaluatedIWYU;
|
|
||||||
std::string evaluatedCPPlint;
|
|
||||||
std::string evaluatedCPPcheck;
|
|
||||||
|
|
||||||
std::string const tidy_prop = cmStrCat(lang, "_CLANG_TIDY");
|
|
||||||
tidy = this->GeneratorTarget->GetProperty(tidy_prop);
|
|
||||||
evaluatedTIDY = cmGeneratorExpression::Evaluate(
|
|
||||||
*tidy, this->LocalGenerator, config, this->GeneratorTarget, nullptr,
|
|
||||||
this->GeneratorTarget, lang);
|
|
||||||
if (!evaluatedTIDY.empty()) {
|
|
||||||
tidy = cmValue(&evaluatedTIDY);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lang == "C" || lang == "CXX") {
|
|
||||||
std::string const iwyu_prop = cmStrCat(lang, "_INCLUDE_WHAT_YOU_USE");
|
|
||||||
iwyu = this->GeneratorTarget->GetProperty(iwyu_prop);
|
|
||||||
evaluatedIWYU = cmGeneratorExpression::Evaluate(
|
|
||||||
*iwyu, this->LocalGenerator, config, this->GeneratorTarget, nullptr,
|
|
||||||
this->GeneratorTarget, lang);
|
|
||||||
if (!evaluatedIWYU.empty()) {
|
|
||||||
iwyu = cmValue(&evaluatedIWYU);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string const cpplint_prop = cmStrCat(lang, "_CPPLINT");
|
|
||||||
cpplint = this->GeneratorTarget->GetProperty(cpplint_prop);
|
|
||||||
evaluatedCPPlint = cmGeneratorExpression::Evaluate(
|
|
||||||
*cpplint, this->LocalGenerator, config, this->GeneratorTarget, nullptr,
|
|
||||||
this->GeneratorTarget, lang);
|
|
||||||
if (!evaluatedCPPlint.empty()) {
|
|
||||||
cpplint = cmValue(&evaluatedCPPlint);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string const cppcheck_prop = cmStrCat(lang, "_CPPCHECK");
|
|
||||||
cppcheck = this->GeneratorTarget->GetProperty(cppcheck_prop);
|
|
||||||
evaluatedCPPcheck = cmGeneratorExpression::Evaluate(
|
|
||||||
*cppcheck, this->LocalGenerator, config, this->GeneratorTarget,
|
|
||||||
nullptr, this->GeneratorTarget, lang);
|
|
||||||
if (!evaluatedCPPcheck.empty()) {
|
|
||||||
cppcheck = cmValue(&evaluatedCPPcheck);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (cmNonempty(iwyu) || cmNonempty(tidy) || cmNonempty(cpplint) ||
|
|
||||||
cmNonempty(cppcheck)) {
|
|
||||||
std::string run_iwyu = cmStrCat(cmakeCmd, " -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 +=
|
|
||||||
cmStrCat(" --launcher=",
|
|
||||||
this->LocalGenerator->EscapeForShell(compilerLauncher));
|
|
||||||
compilerLauncher.clear();
|
|
||||||
}
|
|
||||||
if (cmNonempty(iwyu)) {
|
|
||||||
run_iwyu += " --iwyu=";
|
|
||||||
|
|
||||||
// Only add --driver-mode if it is not already specified, as adding
|
|
||||||
// it unconditionally might override a user-specified driver-mode
|
|
||||||
if (iwyu.Get()->find("--driver-mode=") == std::string::npos) {
|
|
||||||
cmValue p = this->Makefile->GetDefinition(
|
|
||||||
cmStrCat("CMAKE_", lang, "_INCLUDE_WHAT_YOU_USE_DRIVER_MODE"));
|
|
||||||
std::string driverMode;
|
|
||||||
|
|
||||||
if (cmNonempty(p)) {
|
|
||||||
driverMode = *p;
|
|
||||||
} else {
|
|
||||||
driverMode = lang == "C" ? "gcc" : "g++";
|
|
||||||
}
|
|
||||||
|
|
||||||
run_iwyu += this->LocalGenerator->EscapeForShell(
|
|
||||||
cmStrCat(*iwyu, ";--driver-mode=", driverMode));
|
|
||||||
} else {
|
|
||||||
run_iwyu += this->LocalGenerator->EscapeForShell(*iwyu);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (cmNonempty(tidy)) {
|
|
||||||
run_iwyu += " --tidy=";
|
|
||||||
cmValue p = this->Makefile->GetDefinition(
|
|
||||||
cmStrCat("CMAKE_", lang, "_CLANG_TIDY_DRIVER_MODE"));
|
|
||||||
std::string driverMode;
|
|
||||||
if (cmNonempty(p)) {
|
|
||||||
driverMode = *p;
|
|
||||||
} else {
|
|
||||||
driverMode = lang == "C" ? "gcc" : "g++";
|
|
||||||
}
|
|
||||||
const bool haveClangTidyExportFixesDir =
|
|
||||||
!this->GeneratorTarget->GetClangTidyExportFixesDirectory(lang)
|
|
||||||
.empty();
|
|
||||||
std::string exportFixes;
|
|
||||||
if (haveClangTidyExportFixesDir) {
|
|
||||||
exportFixes = ";--export-fixes=$CLANG_TIDY_EXPORT_FIXES";
|
|
||||||
}
|
|
||||||
run_iwyu += this->GetLocalGenerator()->EscapeForShell(
|
|
||||||
cmStrCat(*tidy, ";--extra-arg-before=--driver-mode=", driverMode,
|
|
||||||
exportFixes));
|
|
||||||
if (haveClangTidyExportFixesDir) {
|
|
||||||
std::string search = cmStrCat(
|
|
||||||
this->GetLocalGenerator()->GetState()->UseWindowsShell() ? ""
|
|
||||||
: "\\",
|
|
||||||
"$$CLANG_TIDY_EXPORT_FIXES");
|
|
||||||
auto loc = run_iwyu.rfind(search);
|
|
||||||
run_iwyu.replace(loc, search.length(), "$CLANG_TIDY_EXPORT_FIXES");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (cmNonempty(cpplint)) {
|
|
||||||
run_iwyu += cmStrCat(
|
|
||||||
" --cpplint=", this->GetLocalGenerator()->EscapeForShell(*cpplint));
|
|
||||||
}
|
|
||||||
if (cmNonempty(cppcheck)) {
|
|
||||||
run_iwyu +=
|
|
||||||
cmStrCat(" --cppcheck=",
|
|
||||||
this->GetLocalGenerator()->EscapeForShell(*cppcheck));
|
|
||||||
}
|
|
||||||
if (cmNonempty(tidy) || cmNonempty(cpplint) || cmNonempty(cppcheck)) {
|
|
||||||
run_iwyu += " --source=$in";
|
|
||||||
}
|
|
||||||
run_iwyu += " -- ";
|
|
||||||
compileCmds.front().insert(0, run_iwyu);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If compiler launcher was specified and not consumed above, it
|
|
||||||
// goes to the beginning of the command line.
|
|
||||||
if (!compileCmds.empty() && !compilerLauncher.empty()) {
|
|
||||||
cmList args{ compilerLauncher, cmList::EmptyElements::Yes };
|
|
||||||
if (!args.empty()) {
|
|
||||||
args[0] = this->LocalGenerator->ConvertToOutputFormat(
|
|
||||||
args[0], cmOutputConverter::SHELL);
|
|
||||||
for (std::string& i : cmMakeRange(args.begin() + 1, args.end())) {
|
|
||||||
i = this->LocalGenerator->EscapeForShell(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
compileCmds.front().insert(0, cmStrCat(args.join(" "), ' '));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!compileCmds.empty()) {
|
if (!compileCmds.empty()) {
|
||||||
@@ -1373,6 +1219,29 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
|
|||||||
vars["FLAGS"] = this->ComputeFlagsForObject(source, language, config);
|
vars["FLAGS"] = this->ComputeFlagsForObject(source, language, config);
|
||||||
vars["DEFINES"] = this->ComputeDefines(source, language, config);
|
vars["DEFINES"] = this->ComputeDefines(source, language, config);
|
||||||
vars["INCLUDES"] = this->ComputeIncludes(source, language, config);
|
vars["INCLUDES"] = this->ComputeIncludes(source, language, config);
|
||||||
|
auto const cmakeCmd = this->GetLocalGenerator()->ConvertToOutputFormat(
|
||||||
|
cmSystemTools::GetCMakeCommand(), cmLocalGenerator::SHELL);
|
||||||
|
|
||||||
|
auto compilerLauncher = this->GetCompilerLauncher(language, config);
|
||||||
|
vars["CODE_CHECK"] =
|
||||||
|
this->GenerateCodeCheckRules(*source, compilerLauncher, cmakeCmd, config,
|
||||||
|
[this](std::string const& path) {
|
||||||
|
return this->ConvertToNinjaPath(path);
|
||||||
|
});
|
||||||
|
|
||||||
|
// If compiler launcher was specified and not consumed above, it
|
||||||
|
// goes to the beginning of the command line.
|
||||||
|
if (!compilerLauncher.empty()) {
|
||||||
|
cmList args{ compilerLauncher, cmList::EmptyElements::Yes };
|
||||||
|
if (!args.empty()) {
|
||||||
|
args[0] = this->LocalGenerator->ConvertToOutputFormat(
|
||||||
|
args[0], cmOutputConverter::SHELL);
|
||||||
|
for (std::string& i : cmMakeRange(args.begin() + 1, args.end())) {
|
||||||
|
i = this->LocalGenerator->EscapeForShell(i);
|
||||||
|
}
|
||||||
|
vars["LAUNCHER"] = args.join(" ") + " ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (this->GetMakefile()->GetSafeDefinition(
|
if (this->GetMakefile()->GetSafeDefinition(
|
||||||
cmStrCat("CMAKE_", language, "_DEPFILE_FORMAT")) != "msvc"_s) {
|
cmStrCat("CMAKE_", language, "_DEPFILE_FORMAT")) != "msvc"_s) {
|
||||||
@@ -1397,18 +1266,6 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string d =
|
|
||||||
this->GeneratorTarget->GetClangTidyExportFixesDirectory(language);
|
|
||||||
if (!d.empty()) {
|
|
||||||
this->GlobalCommonGenerator->AddClangTidyExportFixesDir(d);
|
|
||||||
std::string fixesFile =
|
|
||||||
this->GetClangTidyReplacementsFilePath(d, source, config);
|
|
||||||
this->GlobalCommonGenerator->AddClangTidyExportFixesFile(fixesFile);
|
|
||||||
cmSystemTools::MakeDirectory(cmSystemTools::GetFilenamePath(fixesFile));
|
|
||||||
fixesFile = this->ConvertToNinjaPath(fixesFile);
|
|
||||||
vars["CLANG_TIDY_EXPORT_FIXES"] = fixesFile;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (firstForConfig) {
|
if (firstForConfig) {
|
||||||
this->ExportObjectCompileCommand(
|
this->ExportObjectCompileCommand(
|
||||||
language, sourceFilePath, objectDir, objectFileName, objectFileDir,
|
language, sourceFilePath, objectDir, objectFileName, objectFileDir,
|
||||||
|
|||||||
@@ -136,8 +136,8 @@ protected:
|
|||||||
|
|
||||||
/// @return the clang-tidy replacements file path for the given @a source.
|
/// @return the clang-tidy replacements file path for the given @a source.
|
||||||
std::string GetClangTidyReplacementsFilePath(
|
std::string GetClangTidyReplacementsFilePath(
|
||||||
const std::string& directory, cmSourceFile const* source,
|
std::string const& directory, cmSourceFile const& source,
|
||||||
const std::string& config) const;
|
std::string const& config) const override;
|
||||||
|
|
||||||
/// @return the dyndep file path for this target.
|
/// @return the dyndep file path for this target.
|
||||||
std::string GetDyndepFilePath(std::string const& lang,
|
std::string GetDyndepFilePath(std::string const& lang,
|
||||||
|
|||||||
Reference in New Issue
Block a user