diff options
author | Orkun Tokdemir <ilhanorkuntokdemir@gmail.com> | 2023-05-12 14:40:28 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2023-05-16 14:46:35 (GMT) |
commit | 993dde925f208d98c68edcd451b0d6979e0abdd4 (patch) | |
tree | d6d039fd0952b192ca8ffb4d0d01bae3bab78e5d /Source/cmCommonTargetGenerator.cxx | |
parent | 023af4ab2f8d45d0ed5ca6acdf3018cd4cee4624 (diff) | |
download | CMake-993dde925f208d98c68edcd451b0d6979e0abdd4.zip CMake-993dde925f208d98c68edcd451b0d6979e0abdd4.tar.gz CMake-993dde925f208d98c68edcd451b0d6979e0abdd4.tar.bz2 |
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.
Diffstat (limited to 'Source/cmCommonTargetGenerator.cxx')
-rw-r--r-- | Source/cmCommonTargetGenerator.cxx | 165 |
1 files changed, 165 insertions, 0 deletions
diff --git a/Source/cmCommonTargetGenerator.cxx b/Source/cmCommonTargetGenerator.cxx index 1cb62b3..2615494 100644 --- a/Source/cmCommonTargetGenerator.cxx +++ b/Source/cmCommonTargetGenerator.cxx @@ -26,6 +26,7 @@ #include "cmState.h" #include "cmStateTypes.h" #include "cmStringAlgorithms.h" +#include "cmSystemTools.h" #include "cmValue.h" 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( const std::string& config) { |