summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2023-05-18 13:24:01 (GMT)
committerKitware Robot <kwrobot@kitware.com>2023-05-18 13:24:17 (GMT)
commit4d5c32fa2cd0170617d1ab489b17ec7fee87b89d (patch)
tree62d181c52c9750f9dfce98765f1f029762afa277
parentb6c45d28b2e2cd45fe69fc68c6ca2f1fefe9afd9 (diff)
parent775c369420ece1500c2de46b83d5564480d05f70 (diff)
downloadCMake-4d5c32fa2cd0170617d1ab489b17ec7fee87b89d.zip
CMake-4d5c32fa2cd0170617d1ab489b17ec7fee87b89d.tar.gz
CMake-4d5c32fa2cd0170617d1ab489b17ec7fee87b89d.tar.bz2
Merge topic 'skip-linting'
775c369420 Autogen: set SKIP_LINTING ON for generated files b480315e0c TargetGenerator: Add SKIP_LINTING source property 993dde925f TargetGenerator: Factor out generation of code check rules 023af4ab2f Improve Const Correctness Acked-by: Kitware Robot <kwrobot@kitware.com> Acked-by: buildbot <buildbot@kitware.com> Merge-request: !8467
-rw-r--r--Auxiliary/vim/syntax/cmake.vim1
-rw-r--r--Help/manual/cmake-properties.7.rst1
-rw-r--r--Help/prop_sf/SKIP_LINTING.rst41
-rw-r--r--Help/prop_tgt/LANG_CLANG_TIDY.rst7
-rw-r--r--Help/prop_tgt/LANG_CPPCHECK.rst7
-rw-r--r--Help/prop_tgt/LANG_CPPLINT.rst7
-rw-r--r--Help/prop_tgt/LANG_INCLUDE_WHAT_YOU_USE.rst7
-rw-r--r--Help/release/dev/skip-linting.rst5
-rw-r--r--Source/cmCommonTargetGenerator.cxx165
-rw-r--r--Source/cmCommonTargetGenerator.h10
-rw-r--r--Source/cmGlobalNinjaGenerator.cxx12
-rw-r--r--Source/cmMakefileTargetGenerator.cxx245
-rw-r--r--Source/cmMakefileTargetGenerator.h4
-rw-r--r--Source/cmNinjaTargetGenerator.cxx207
-rw-r--r--Source/cmNinjaTargetGenerator.h4
-rw-r--r--Source/cmQtAutoGenInitializer.cxx1
-rw-r--r--Tests/RunCMake/Autogen/AutogenSkipLinting-build-stderr.txt1
-rw-r--r--Tests/RunCMake/Autogen/AutogenSkipLinting.cmake16
-rw-r--r--Tests/RunCMake/Autogen/RunCMakeTest.cmake15
-rw-r--r--Tests/RunCMake/Autogen/SkipLinting.cxx6
-rw-r--r--Tests/RunCMake/Autogen/SkipLinting.h11
-rw-r--r--Tests/RunCMake/CMakeLists.txt4
-rw-r--r--Tests/RunCMake/MultiLint/C-launch_skip_linting_ON.cmake3
-rw-r--r--Tests/RunCMake/MultiLint/CMakeLists copy.txt3
-rw-r--r--Tests/RunCMake/MultiLint/CXX-launch_skip_linting_ON.cmake3
-rw-r--r--Tests/RunCMake/MultiLint/CXX_skip_linting_OFF-Build-result.txt1
-rw-r--r--Tests/RunCMake/MultiLint/CXX_skip_linting_OFF.cmake7
-rw-r--r--Tests/RunCMake/MultiLint/CXX_skip_linting_ON.cmake7
-rw-r--r--Tests/RunCMake/MultiLint/C_skip_linting_OFF-Build-result.txt1
-rw-r--r--Tests/RunCMake/MultiLint/C_skip_linting_OFF.cmake7
-rw-r--r--Tests/RunCMake/MultiLint/C_skip_linting_ON.cmake7
-rw-r--r--Tests/RunCMake/MultiLint/RunCMakeTest.cmake19
32 files changed, 479 insertions, 356 deletions
diff --git a/Auxiliary/vim/syntax/cmake.vim b/Auxiliary/vim/syntax/cmake.vim
index aefdcee..2e83a07 100644
--- a/Auxiliary/vim/syntax/cmake.vim
+++ b/Auxiliary/vim/syntax/cmake.vim
@@ -329,6 +329,7 @@ syn keyword cmakeProperty contained
\ SKIP_REGULAR_EXPRESSION
\ SKIP_RETURN_CODE
\ SKIP_UNITY_BUILD_INCLUSION
+ \ SKIP_LINTING
\ SOURCES
\ SOURCE_DIR
\ SOVERSION
diff --git a/Help/manual/cmake-properties.7.rst b/Help/manual/cmake-properties.7.rst
index 8ee5573..b8026ef 100644
--- a/Help/manual/cmake-properties.7.rst
+++ b/Help/manual/cmake-properties.7.rst
@@ -559,6 +559,7 @@ Properties on Source Files
/prop_sf/SKIP_AUTOUIC
/prop_sf/SKIP_PRECOMPILE_HEADERS
/prop_sf/SKIP_UNITY_BUILD_INCLUSION
+ /prop_sf/SKIP_LINTING
/prop_sf/Swift_DEPENDENCIES_FILE
/prop_sf/Swift_DIAGNOSTICS_FILE
/prop_sf/SYMBOLIC
diff --git a/Help/prop_sf/SKIP_LINTING.rst b/Help/prop_sf/SKIP_LINTING.rst
new file mode 100644
index 0000000..2be47cb
--- /dev/null
+++ b/Help/prop_sf/SKIP_LINTING.rst
@@ -0,0 +1,41 @@
+SKIP_LINTING
+------------
+
+.. versionadded:: 3.27
+
+This property allows you to exclude a specific source file
+from the linting process. The linting process involves running
+tools such as :prop_tgt:`<LANG>_CPPLINT`, :prop_tgt:`<LANG>_CLANG_TIDY`,
+:prop_tgt:`<LANG>_CPPCHECK`, and :prop_tgt:`<LANG>_INCLUDE_WHAT_YOU_USE`
+on the source files. By setting `SKIP_LINTING` on a source file,
+the mentioned linting tools will not be executed for that
+particular file.
+
+EXAMPLE
+^^^^^^^
+
+Consider a `C++` project that includes multiple source files,
+such as `main.cpp`, `things.cpp`, and `generatedBindings.cpp`.
+In this example, you want to exclude the `generatedBindings.cpp`
+file from the linting process. To achieve this, you can utilize
+the `SKIP_LINTING` property with the `set_source_files_properties`
+command as shown below:
+
+.. code-block:: cmake
+
+ add_executable(MyApp main.cpp things.cpp generatedBindings.cpp)
+
+ set_source_files_properties(generatedBindings.cpp PROPERTIES
+ SKIP_LINTING ON
+ )
+
+In the provided code snippet, the `SKIP_LINTING` property is set to `ON`
+for the `generatedBindings.cpp` source file. As a result, when the linting
+tools, such as :prop_tgt:`<LANG>_CPPLINT`, :prop_tgt:`<LANG>_CLANG_TIDY`,
+:prop_tgt:`<LANG>_CPPCHECK`, and :prop_tgt:`<LANG>_INCLUDE_WHAT_YOU_USE`,
+are executed, they will skip analyzing the `generatedBindings.cpp` file.
+
+By using the `SKIP_LINTING` property, you can selectively exclude specific
+source files from the linting process. This allows you to focus the
+linting tools on the relevant parts of your project, enhancing the efficiency
+and effectiveness of the linting workflow.
diff --git a/Help/prop_tgt/LANG_CLANG_TIDY.rst b/Help/prop_tgt/LANG_CLANG_TIDY.rst
index 1e10933..0e46643 100644
--- a/Help/prop_tgt/LANG_CLANG_TIDY.rst
+++ b/Help/prop_tgt/LANG_CLANG_TIDY.rst
@@ -30,3 +30,10 @@ when a target is created.
This property supports
:manual:`generator expressions <cmake-generator-expressions(7)>`.
+
+ :prop_sf:`SKIP_LINTING` can be set on individual source files to exclude
+ them from the linting process, which includes tools like
+ :prop_tgt:`<LANG>_CPPLINT`, :prop_tgt:`<LANG>_CLANG_TIDY`,
+ :prop_tgt:`<LANG>_CPPCHECK`, and :prop_tgt:`<LANG>_INCLUDE_WHAT_YOU_USE`.
+ When :prop_sf:`SKIP_LINTING` is set on a source file, the mentioned tools
+ will not be run on that specific file.
diff --git a/Help/prop_tgt/LANG_CPPCHECK.rst b/Help/prop_tgt/LANG_CPPCHECK.rst
index 0b2dee6..3ab2b58 100644
--- a/Help/prop_tgt/LANG_CPPCHECK.rst
+++ b/Help/prop_tgt/LANG_CPPCHECK.rst
@@ -20,3 +20,10 @@ created.
This property supports
:manual:`generator expressions <cmake-generator-expressions(7)>`.
+
+ :prop_sf:`SKIP_LINTING` can be set on individual source files to exclude
+ them from the linting process, which includes tools like
+ :prop_tgt:`<LANG>_CPPLINT`, :prop_tgt:`<LANG>_CLANG_TIDY`,
+ :prop_tgt:`<LANG>_CPPCHECK`, and :prop_tgt:`<LANG>_INCLUDE_WHAT_YOU_USE`.
+ When :prop_sf:`SKIP_LINTING` is set on a source file, the mentioned tools
+ will not be run on that specific file.
diff --git a/Help/prop_tgt/LANG_CPPLINT.rst b/Help/prop_tgt/LANG_CPPLINT.rst
index 38a1669..cb230d3 100644
--- a/Help/prop_tgt/LANG_CPPLINT.rst
+++ b/Help/prop_tgt/LANG_CPPLINT.rst
@@ -18,3 +18,10 @@ created.
This property supports
:manual:`generator expressions <cmake-generator-expressions(7)>`.
+
+ :prop_sf:`SKIP_LINTING` can be set on individual source files to exclude
+ them from the linting process, which includes tools like
+ :prop_tgt:`<LANG>_CPPLINT`, :prop_tgt:`<LANG>_CLANG_TIDY`,
+ :prop_tgt:`<LANG>_CPPCHECK`, and :prop_tgt:`<LANG>_INCLUDE_WHAT_YOU_USE`.
+ When :prop_sf:`SKIP_LINTING` is set on a source file, the mentioned tools
+ will not be run on that specific file.
diff --git a/Help/prop_tgt/LANG_INCLUDE_WHAT_YOU_USE.rst b/Help/prop_tgt/LANG_INCLUDE_WHAT_YOU_USE.rst
index 19b97f7..8fbe84a 100644
--- a/Help/prop_tgt/LANG_INCLUDE_WHAT_YOU_USE.rst
+++ b/Help/prop_tgt/LANG_INCLUDE_WHAT_YOU_USE.rst
@@ -18,3 +18,10 @@ when a target is created.
This property supports
:manual:`generator expressions <cmake-generator-expressions(7)>`.
+
+ :prop_sf:`SKIP_LINTING` can be set on individual source files to exclude
+ them from the linting process, which includes tools like
+ :prop_tgt:`<LANG>_CPPLINT`, :prop_tgt:`<LANG>_CLANG_TIDY`,
+ :prop_tgt:`<LANG>_CPPCHECK`, and :prop_tgt:`<LANG>_INCLUDE_WHAT_YOU_USE`.
+ When :prop_sf:`SKIP_LINTING` is set on a source file, the mentioned tools
+ will not be run on that specific file.
diff --git a/Help/release/dev/skip-linting.rst b/Help/release/dev/skip-linting.rst
new file mode 100644
index 0000000..199571c
--- /dev/null
+++ b/Help/release/dev/skip-linting.rst
@@ -0,0 +1,5 @@
+skip-linting
+------------
+
+* The :prop_sf:`SKIP_LINTING` source file property was added to suppress
+ target-wide code checks on specific sources.
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)
{
diff --git a/Source/cmCommonTargetGenerator.h b/Source/cmCommonTargetGenerator.h
index 2d23037..c9886d0 100644
--- a/Source/cmCommonTargetGenerator.h
+++ b/Source/cmCommonTargetGenerator.h
@@ -4,6 +4,7 @@
#include "cmConfigure.h" // IWYU pragma: keep
+#include <functional>
#include <map>
#include <set>
#include <string>
@@ -53,6 +54,9 @@ protected:
virtual void AddIncludeFlags(std::string& flags, std::string const& lang,
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,
const char* name, bool so);
@@ -63,7 +67,13 @@ protected:
std::string GetIncludes(std::string const& l, const std::string& config);
std::string GetManifests(const std::string& 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(
const std::string& lang, const std::string& config) const;
std::string ComputeTargetCompilePDB(const std::string& config) const;
diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx
index 7626fa3..b598c9b 100644
--- a/Source/cmGlobalNinjaGenerator.cxx
+++ b/Source/cmGlobalNinjaGenerator.cxx
@@ -507,8 +507,18 @@ void cmGlobalNinjaGenerator::WriteVariable(std::ostream& os,
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.
- std::string val = cmTrimWhitespace(value);
if (val.empty()) {
return;
}
diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx
index 02cdf57..c915e26 100644
--- a/Source/cmMakefileTargetGenerator.cxx
+++ b/Source/cmMakefileTargetGenerator.cxx
@@ -26,7 +26,6 @@
#include "cmGeneratedFileStream.h"
#include "cmGeneratorExpression.h"
#include "cmGeneratorTarget.h"
-#include "cmGlobalCommonGenerator.h"
#include "cmGlobalUnixMakefileGenerator3.h"
#include "cmLinkLineComputer.h" // IWYU pragma: keep
#include "cmList.h"
@@ -420,7 +419,7 @@ void cmMakefileTargetGenerator::WriteCommonCodeRules()
this->GeneratorTarget->HasLinkDependencyFile(this->GetConfigName());
if (compilerGenerateDeps || linkerGenerateDeps || ccGenerateDeps) {
- std::string compilerDependFile =
+ std::string const compilerDependFile =
cmStrCat(this->TargetBuildDirectoryFull, "/compiler_depend.make");
*this->BuildFileStream << "# Include any dependencies generated by the "
"compiler for this target.\n"
@@ -613,17 +612,17 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
}
// Use compiler to generate dependencies, if supported.
- bool compilerGenerateDeps =
+ bool const compilerGenerateDeps =
this->GlobalGenerator->SupportsCompilerDependencies() &&
cmIsOn(this->Makefile->GetDefinition(
cmStrCat("CMAKE_", lang, "_DEPENDS_USE_COMPILER")));
- auto scanner = compilerGenerateDeps ? cmDependencyScannerKind::Compiler
- : cmDependencyScannerKind::CMake;
+ auto const scanner = compilerGenerateDeps ? cmDependencyScannerKind::Compiler
+ : cmDependencyScannerKind::CMake;
// Get the full path name of the object file.
std::string const& objectName =
this->GeneratorTarget->GetObjectName(&source);
- std::string obj =
+ std::string const obj =
cmStrCat(this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget),
'/', objectName);
@@ -642,7 +641,7 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
// Create the directory containing the object file. This may be a
// subdirectory under the target's directory.
{
- std::string dir = cmSystemTools::GetFilenamePath(obj);
+ std::string const dir = cmSystemTools::GetFilenamePath(obj);
cmSystemTools::MakeDirectory(this->LocalGenerator->ConvertToFullPath(dir));
}
@@ -656,7 +655,7 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
std::string objFullPath =
cmStrCat(this->LocalGenerator->GetCurrentBinaryDirectory(), '/', obj);
objFullPath = cmSystemTools::CollapseFullPath(objFullPath);
- std::string srcFullPath =
+ std::string const srcFullPath =
cmSystemTools::CollapseFullPath(source.GetFullPath());
this->LocalGenerator->AddImplicitDepends(this->GeneratorTarget, lang,
objFullPath, srcFullPath, scanner);
@@ -669,8 +668,8 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
// generate the depend scanning rule
this->WriteObjectDependRules(source, depends);
- std::string config = this->GetConfigName();
- std::string configUpper = cmSystemTools::UpperCase(config);
+ std::string const config = this->GetConfigName();
+ std::string const configUpper = cmSystemTools::UpperCase(config);
// Add precompile headers dependencies
std::vector<std::string> architectures =
@@ -726,7 +725,8 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
this->GeneratorTarget->AddExplicitLanguageFlags(flags, source);
// Add language-specific flags.
- std::string langFlags = cmStrCat("$(", lang, "_FLAGS", filterArch, ")");
+ std::string const langFlags =
+ cmStrCat("$(", lang, "_FLAGS", filterArch, ")");
this->LocalGenerator->AppendFlags(flags, langFlags);
cmGeneratorExpressionInterpreter genexInterpreter(
@@ -745,7 +745,7 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
cmSystemTools::GetFilenameWithoutLastExtension(objectName);
ispcSource = cmSystemTools::GetFilenameWithoutLastExtension(ispcSource);
- cmValue ispcSuffixProp =
+ cmValue const ispcSuffixProp =
this->GeneratorTarget->GetProperty("ISPC_HEADER_SUFFIX");
assert(ispcSuffixProp);
@@ -784,7 +784,7 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
// Add precompile headers compile options.
if (!pchSources.empty() && !source.GetProperty("SKIP_PRECOMPILE_HEADERS")) {
std::string pchOptions;
- auto pchIt = pchSources.find(source.GetFullPath());
+ auto const pchIt = pchSources.find(source.GetFullPath());
if (pchIt != pchSources.end()) {
pchOptions = this->GeneratorTarget->GetPchCreateCompileOptions(
config, lang, pchIt->second);
@@ -830,7 +830,8 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
<< "_DEFINES = " << evaluatedDefs << "\n"
<< "\n";
}
- std::string defPropName = cmStrCat("COMPILE_DEFINITIONS_", configUpper);
+ std::string const defPropName =
+ cmStrCat("COMPILE_DEFINITIONS_", configUpper);
if (cmValue config_compile_defs = source.GetProperty(defPropName)) {
const std::string& evaluatedDefs =
genexInterpreter.Evaluate(*config_compile_defs, COMPILE_DEFINITIONS);
@@ -841,7 +842,7 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
}
// Get the output paths for source and object files.
- std::string sourceFile = this->LocalGenerator->ConvertToOutputFormat(
+ std::string const sourceFile = this->LocalGenerator->ConvertToOutputFormat(
source.GetFullPath(), cmOutputConverter::SHELL);
// Construct the build message.
@@ -897,7 +898,7 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
targetOutPathCompilePDB.back() = '/';
}
- std::string compilePdbOutputPath =
+ std::string const compilePdbOutputPath =
this->GeneratorTarget->GetCompilePDBDirectory(this->GetConfigName());
cmSystemTools::MakeDirectory(compilePdbOutputPath);
}
@@ -910,7 +911,7 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
vars.TargetPDB = targetOutPathPDB.c_str();
vars.TargetCompilePDB = targetOutPathCompilePDB.c_str();
vars.Source = sourceFile.c_str();
- std::string shellObj =
+ std::string const shellObj =
this->LocalGenerator->ConvertToOutputFormat(obj, cmOutputConverter::SHELL);
vars.Object = shellObj.c_str();
std::string objectDir = this->GeneratorTarget->GetSupportDirectory();
@@ -960,7 +961,7 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
// At the moment, it is assumed that C, C++, Fortran, and CUDA have both
// assembly and preprocessor capabilities. The same is true for the
// ability to export compile commands
- bool lang_has_preprocessor =
+ bool const lang_has_preprocessor =
((lang == "C") || (lang == "CXX") || (lang == "OBJC") ||
(lang == "OBJCXX") || (lang == "Fortran") || (lang == "CUDA") ||
lang == "ISPC" || lang == "HIP" || lang == "ASM");
@@ -1016,31 +1017,31 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
// no launcher for CMAKE_EXPORT_COMPILE_COMMANDS
rulePlaceholderExpander->ExpandRuleVariables(this->LocalGenerator,
compileCommand, vars);
- std::string workingDirectory =
+ std::string const workingDirectory =
this->LocalGenerator->GetCurrentBinaryDirectory();
std::string::size_type lfPos = compileCommand.find(langFlags);
if (lfPos != std::string::npos) {
compileCommand.replace(lfPos, langFlags.size(),
this->GetFlags(lang, this->GetConfigName()));
}
- std::string langDefines = std::string("$(") + lang + "_DEFINES)";
- std::string::size_type ldPos = compileCommand.find(langDefines);
+ std::string const langDefines = std::string("$(") + lang + "_DEFINES)";
+ std::string::size_type const ldPos = compileCommand.find(langDefines);
if (ldPos != std::string::npos) {
compileCommand.replace(ldPos, langDefines.size(),
this->GetDefines(lang, this->GetConfigName()));
}
- std::string langIncludes = std::string("$(") + lang + "_INCLUDES)";
- std::string::size_type liPos = compileCommand.find(langIncludes);
+ std::string const langIncludes = std::string("$(") + lang + "_INCLUDES)";
+ std::string::size_type const liPos = compileCommand.find(langIncludes);
if (liPos != std::string::npos) {
compileCommand.replace(liPos, langIncludes.size(),
this->GetIncludes(lang, this->GetConfigName()));
}
- cmValue eliminate[] = {
+ cmValue const eliminate[] = {
this->Makefile->GetDefinition("CMAKE_START_TEMP_FILE"),
this->Makefile->GetDefinition("CMAKE_END_TEMP_FILE")
};
- for (cmValue el : eliminate) {
+ for (cmValue const& el : eliminate) {
if (el) {
cmSystemTools::ReplaceString(compileCommand, *el, "");
}
@@ -1052,150 +1053,16 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
// 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" ||
- 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;
- }
+ if (!compileCommands.empty()) {
+ compilerLauncher = GetCompilerLauncher(lang, config);
}
- // Maybe insert an include-what-you-use runner.
- if (!compileCommands.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 = "$(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);
+ cmValue const skipCodeCheck = source.GetProperty("SKIP_LINTING");
+ if (!skipCodeCheck.IsOn()) {
+ std::string const codeCheck = this->GenerateCodeCheckRules(
+ source, compilerLauncher, "$(CMAKE_COMMAND)", config, nullptr);
+ if (!codeCheck.empty()) {
+ compileCommands.front().insert(0, codeCheck);
}
}
@@ -1330,8 +1197,8 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
if (do_preprocess_rules) {
commands.clear();
- std::string relativeObjI = relativeObjBase + ".i";
- std::string objI = objBase + ".i";
+ std::string const relativeObjI = relativeObjBase + ".i";
+ std::string const objI = objBase + ".i";
std::string preprocessEcho =
cmStrCat("Preprocessing ", lang, " source to ", objI);
@@ -1423,7 +1290,7 @@ void cmMakefileTargetGenerator::WriteTargetCleanRules()
std::vector<std::string> commands;
// Construct the clean target name.
- std::string cleanTarget = cmStrCat(
+ std::string const cleanTarget = cmStrCat(
this->LocalGenerator->GetRelativeTargetDirectory(this->GeneratorTarget),
"/clean");
@@ -1451,7 +1318,7 @@ bool cmMakefileTargetGenerator::WriteMakeRule(
}
// Check whether we need to bother checking for a symbolic output.
- bool need_symbolic = this->GlobalGenerator->GetNeedSymbolicMark();
+ bool const need_symbolic = this->GlobalGenerator->GetNeedSymbolicMark();
// Check whether the first output is marked as symbolic.
if (need_symbolic) {
@@ -1481,7 +1348,7 @@ bool cmMakefileTargetGenerator::WriteMakeRule(
bool o_symbolic = false;
if (need_symbolic) {
- if (cmSourceFile* sf = this->Makefile->GetSource(output)) {
+ if (cmSourceFile const* sf = this->Makefile->GetSource(output)) {
o_symbolic = sf->GetPropertyAsBool("SYMBOLIC");
}
}
@@ -1517,6 +1384,23 @@ void cmMakefileTargetGenerator::WriteTargetLinkDependRules()
this->GeneratorTarget->GetFullPath(this->GetConfigName()), depFile,
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()
{
@@ -1559,7 +1443,7 @@ void cmMakefileTargetGenerator::WriteTargetDependRules()
"# Targets to which this target links which contain Fortran sources.\n"
"set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES\n";
/* clang-format on */
- std::vector<std::string> dirs =
+ std::vector<std::string> const dirs =
this->GetLinkedTargetDirectories("Fortran", this->GetConfigName());
for (std::string const& d : dirs) {
*this->InfoFileStream << " \"" << d << "/DependInfo.cmake\"\n";
@@ -1591,7 +1475,7 @@ void cmMakefileTargetGenerator::WriteTargetDependRules()
std::vector<std::string> commands;
// Construct the name of the dependency generation target.
- std::string depTarget = cmStrCat(
+ std::string const depTarget = cmStrCat(
this->LocalGenerator->GetRelativeTargetDirectory(this->GeneratorTarget),
"/depend");
@@ -1701,7 +1585,7 @@ void cmMakefileTargetGenerator::WriteDeviceLinkRule(
deps.emplace_back(cmStrCat(relPath, obj));
}
- std::unordered_set<std::string> depsSet(deps.begin(), deps.end());
+ std::unordered_set<std::string> const depsSet(deps.begin(), deps.end());
deps.clear();
std::copy(depsSet.begin(), depsSet.end(), std::back_inserter(deps));
return deps;
@@ -1785,7 +1669,7 @@ void cmMakefileTargetGenerator::WriteDeviceLinkRule(
this->GetDeviceLinkFlags(linkFlags, "CUDA");
vars.LinkFlags = linkFlags.c_str();
- std::string flags = this->GetFlags("CUDA", this->GetConfigName());
+ std::string const flags = this->GetFlags("CUDA", this->GetConfigName());
vars.Flags = flags.c_str();
std::string compileCmd = this->GetLinkRule("CMAKE_CUDA_DEVICE_LINK_COMPILE");
@@ -1839,8 +1723,8 @@ void cmMakefileTargetGenerator::GenerateCustomRuleFile(
// Write the rule.
const std::vector<std::string>& outputs = ccg.GetOutputs();
- bool symbolic = this->WriteMakeRule(*this->BuildFileStream, nullptr, outputs,
- depends, commands);
+ bool const symbolic = this->WriteMakeRule(*this->BuildFileStream, nullptr,
+ outputs, depends, commands);
// Symbolic inputs are not expected to exist, so add dummy rules.
if (this->CMP0113New && !depends.empty()) {
@@ -2328,7 +2212,7 @@ void cmMakefileTargetGenerator::CreateObjectLists(
useWatcomQuote);
if (useResponseFile) {
// MSVC response files cannot exceed 128K.
- std::string::size_type const responseFileLimit = 131000;
+ std::string::size_type constexpr responseFileLimit = 131000;
// Construct the individual object list strings.
std::vector<std::string> object_strings;
@@ -2461,7 +2345,8 @@ std::string cmMakefileTargetGenerator::GetResponseFlag(
std::string responseFlag = "@";
std::string responseFlagVar;
- auto lang = this->GeneratorTarget->GetLinkerLanguage(this->GetConfigName());
+ auto const lang =
+ this->GeneratorTarget->GetLinkerLanguage(this->GetConfigName());
if (mode == cmMakefileTargetGenerator::ResponseFlagFor::Link) {
responseFlagVar = cmStrCat("CMAKE_", lang, "_RESPONSE_FILE_LINK_FLAG");
} else if (mode == cmMakefileTargetGenerator::ResponseFlagFor::DeviceLink) {
diff --git a/Source/cmMakefileTargetGenerator.h b/Source/cmMakefileTargetGenerator.h
index ef7a60f..08d6945 100644
--- a/Source/cmMakefileTargetGenerator.h
+++ b/Source/cmMakefileTargetGenerator.h
@@ -82,6 +82,10 @@ protected:
// write the depend rules for this target
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.
struct MacOSXContentGeneratorType
: cmOSXBundleGenerator::MacOSXContentGeneratorType
diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx
index 5bf6a2b..25e00d3 100644
--- a/Source/cmNinjaTargetGenerator.cxx
+++ b/Source/cmNinjaTargetGenerator.cxx
@@ -29,7 +29,6 @@
#include "cmGeneratedFileStream.h"
#include "cmGeneratorExpression.h"
#include "cmGeneratorTarget.h"
-#include "cmGlobalCommonGenerator.h"
#include "cmGlobalNinjaGenerator.h"
#include "cmList.h"
#include "cmLocalGenerator.h"
@@ -399,15 +398,15 @@ std::string cmNinjaTargetGenerator::GetObjectFilePath(
}
std::string cmNinjaTargetGenerator::GetClangTidyReplacementsFilePath(
- const std::string& directory, cmSourceFile const* source,
- const std::string& config) const
+ std::string const& directory, cmSourceFile const& source,
+ std::string const& config) const
{
- std::string path = this->LocalGenerator->GetHomeRelativeOutputPath();
+ auto path = this->LocalGenerator->GetHomeRelativeOutputPath();
if (!path.empty()) {
path += '/';
}
path = cmStrCat(directory, '/', path);
- std::string const& objectName = this->GeneratorTarget->GetObjectName(source);
+ auto const& objectName = this->GeneratorTarget->GetObjectName(&source);
path =
cmStrCat(std::move(path),
this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget),
@@ -890,162 +889,9 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang,
const std::string& compileCmd = mf->GetRequiredDefinition(cmdVar);
cmList compileCmds(compileCmd);
- // 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" ||
- 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()) {
+ compileCmds.front().insert(0, "${CODE_CHECK}");
+ compileCmds.front().insert(0, "${LAUNCHER}");
}
if (!compileCmds.empty()) {
@@ -1374,6 +1220,33 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
vars["DEFINES"] = this->ComputeDefines(source, language, config);
vars["INCLUDES"] = this->ComputeIncludes(source, language, config);
+ auto compilerLauncher = this->GetCompilerLauncher(language, config);
+
+ cmValue const skipCodeCheck = source->GetProperty("SKIP_LINTING");
+ if (!skipCodeCheck.IsOn()) {
+ auto const cmakeCmd = this->GetLocalGenerator()->ConvertToOutputFormat(
+ cmSystemTools::GetCMakeCommand(), cmLocalGenerator::SHELL);
+ vars["CODE_CHECK"] =
+ this->GenerateCodeCheckRules(*source, compilerLauncher, cmakeCmd, config,
+ [this](const std::string& 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(
cmStrCat("CMAKE_", language, "_DEPFILE_FORMAT")) != "msvc"_s) {
bool replaceExt(false);
@@ -1397,18 +1270,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) {
this->ExportObjectCompileCommand(
language, sourceFilePath, objectDir, objectFileName, objectFileDir,
diff --git a/Source/cmNinjaTargetGenerator.h b/Source/cmNinjaTargetGenerator.h
index 8f4a764..8c38499 100644
--- a/Source/cmNinjaTargetGenerator.h
+++ b/Source/cmNinjaTargetGenerator.h
@@ -136,8 +136,8 @@ protected:
/// @return the clang-tidy replacements file path for the given @a source.
std::string GetClangTidyReplacementsFilePath(
- const std::string& directory, cmSourceFile const* source,
- const std::string& config) const;
+ std::string const& directory, cmSourceFile const& source,
+ std::string const& config) const override;
/// @return the dyndep file path for this target.
std::string GetDyndepFilePath(std::string const& lang,
diff --git a/Source/cmQtAutoGenInitializer.cxx b/Source/cmQtAutoGenInitializer.cxx
index d897f0e..76bb0cd 100644
--- a/Source/cmQtAutoGenInitializer.cxx
+++ b/Source/cmQtAutoGenInitializer.cxx
@@ -1834,6 +1834,7 @@ cmSourceFile* cmQtAutoGenInitializer::RegisterGeneratedSource(
cmSourceFile* gFile = this->Makefile->GetOrCreateSource(filename, true);
gFile->MarkAsGenerated();
gFile->SetProperty("SKIP_AUTOGEN", "1");
+ gFile->SetProperty("SKIP_LINTING", "ON");
return gFile;
}
diff --git a/Tests/RunCMake/Autogen/AutogenSkipLinting-build-stderr.txt b/Tests/RunCMake/Autogen/AutogenSkipLinting-build-stderr.txt
new file mode 100644
index 0000000..8d98f9d
--- /dev/null
+++ b/Tests/RunCMake/Autogen/AutogenSkipLinting-build-stderr.txt
@@ -0,0 +1 @@
+.*
diff --git a/Tests/RunCMake/Autogen/AutogenSkipLinting.cmake b/Tests/RunCMake/Autogen/AutogenSkipLinting.cmake
new file mode 100644
index 0000000..3ce2092
--- /dev/null
+++ b/Tests/RunCMake/Autogen/AutogenSkipLinting.cmake
@@ -0,0 +1,16 @@
+enable_language(CXX)
+
+find_package(Qt${with_qt_version} REQUIRED COMPONENTS Core Widgets Gui)
+
+set(CMAKE_AUTOMOC ON)
+set(CMAKE_CXX_INCLUDE_WHAT_YOU_USE "$<1:${PSEUDO_IWYU}>" -some -args)
+set(CMAKE_CXX_CLANG_TIDY "$<1:${PSEUDO_TIDY}>" -bad)
+set(CMAKE_CXX_CPPLINT "$<1:${PSEUDO_CPPLINT}>" --error)
+set(CMAKE_CXX_CPPCHECK "$<1:${PSEUDO_CPPCHECK}>" -error)
+
+add_executable(SkipLinting SkipLinting.cxx SkipLinting.h)
+set_source_files_properties(SkipLinting.cxx PROPERTIES SKIP_LINTING TRUE)
+
+target_link_libraries(SkipLinting Qt${with_qt_version}::Core
+ Qt${with_qt_version}::Widgets
+ Qt${with_qt_version}::Gui)
diff --git a/Tests/RunCMake/Autogen/RunCMakeTest.cmake b/Tests/RunCMake/Autogen/RunCMakeTest.cmake
index 4505132..97b64ed 100644
--- a/Tests/RunCMake/Autogen/RunCMakeTest.cmake
+++ b/Tests/RunCMake/Autogen/RunCMakeTest.cmake
@@ -87,5 +87,20 @@ if (DEFINED with_qt_version)
message(STATUS "RunCMake_TEST_EXPECT_stdout: ${RunCMake_TEST_EXPECT_stdout}")
run_cmake_command(AutogenUseSystemIncludeOff ${CMAKE_COMMAND} --build . --config Debug --verbose)
endblock()
+
+ if(RunCMake_GENERATOR MATCHES "Make|Ninja")
+ block()
+ set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/AutogenSkipLinting-build)
+ list(APPEND RunCMake_TEST_OPTIONS
+ "-DPSEUDO_CPPCHECK=${PSEUDO_CPPCHECK}"
+ "-DPSEUDO_CPPLINT=${PSEUDO_CPPLINT}"
+ "-DPSEUDO_IWYU=${PSEUDO_IWYU}"
+ "-DPSEUDO_TIDY=${PSEUDO_TIDY}")
+
+ run_cmake(AutogenSkipLinting)
+ set(RunCMake_TEST_NO_CLEAN 1)
+ run_cmake_command(AutogenSkipLinting-build ${CMAKE_COMMAND} --build . --config Debug --verbose)
+ endblock()
+ endif()
endif()
endif ()
diff --git a/Tests/RunCMake/Autogen/SkipLinting.cxx b/Tests/RunCMake/Autogen/SkipLinting.cxx
new file mode 100644
index 0000000..9e09b27
--- /dev/null
+++ b/Tests/RunCMake/Autogen/SkipLinting.cxx
@@ -0,0 +1,6 @@
+#include "SkipLinting.h"
+
+int main()
+{
+ return 0;
+}
diff --git a/Tests/RunCMake/Autogen/SkipLinting.h b/Tests/RunCMake/Autogen/SkipLinting.h
new file mode 100644
index 0000000..def56a0
--- /dev/null
+++ b/Tests/RunCMake/Autogen/SkipLinting.h
@@ -0,0 +1,11 @@
+#ifndef SKIP_LINTING_H
+#define SKIP_LINTING_H
+
+#include <QObject>
+
+class SkipMe : public QObject
+{
+ Q_OBJECT
+};
+
+#endif
diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt
index e87239e..3997a74 100644
--- a/Tests/RunCMake/CMakeLists.txt
+++ b/Tests/RunCMake/CMakeLists.txt
@@ -266,6 +266,10 @@ if(CMake_TEST_Qt6 AND Qt6Widgets_FOUND)
-Dwith_qt_version=6
"-DQt6_DIR:PATH=${Qt6_DIR}"
"-DCMAKE_PREFIX_PATH:STRING=${base_dir}"
+ -DPSEUDO_TIDY=$<TARGET_FILE:pseudo_tidy>
+ -DPSEUDO_IWYU=$<TARGET_FILE:pseudo_iwyu>
+ -DPSEUDO_CPPLINT=$<TARGET_FILE:pseudo_cpplint>
+ -DPSEUDO_CPPCHECK=$<TARGET_FILE:pseudo_cppcheck>
)
set(want_NoQt_test FALSE)
endif ()
diff --git a/Tests/RunCMake/MultiLint/C-launch_skip_linting_ON.cmake b/Tests/RunCMake/MultiLint/C-launch_skip_linting_ON.cmake
new file mode 100644
index 0000000..d0d9866
--- /dev/null
+++ b/Tests/RunCMake/MultiLint/C-launch_skip_linting_ON.cmake
@@ -0,0 +1,3 @@
+set(CTEST_USE_LAUNCHERS 1)
+include(CTestUseLaunchers)
+include(C_skip_linting_ON.cmake)
diff --git a/Tests/RunCMake/MultiLint/CMakeLists copy.txt b/Tests/RunCMake/MultiLint/CMakeLists copy.txt
new file mode 100644
index 0000000..93ee9df
--- /dev/null
+++ b/Tests/RunCMake/MultiLint/CMakeLists copy.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.5)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/MultiLint/CXX-launch_skip_linting_ON.cmake b/Tests/RunCMake/MultiLint/CXX-launch_skip_linting_ON.cmake
new file mode 100644
index 0000000..6347e60
--- /dev/null
+++ b/Tests/RunCMake/MultiLint/CXX-launch_skip_linting_ON.cmake
@@ -0,0 +1,3 @@
+set(CTEST_USE_LAUNCHERS 1)
+include(CTestUseLaunchers)
+include(CXX_skip_linting_ON.cmake)
diff --git a/Tests/RunCMake/MultiLint/CXX_skip_linting_OFF-Build-result.txt b/Tests/RunCMake/MultiLint/CXX_skip_linting_OFF-Build-result.txt
new file mode 100644
index 0000000..3beecb0
--- /dev/null
+++ b/Tests/RunCMake/MultiLint/CXX_skip_linting_OFF-Build-result.txt
@@ -0,0 +1 @@
+(1|2)
diff --git a/Tests/RunCMake/MultiLint/CXX_skip_linting_OFF.cmake b/Tests/RunCMake/MultiLint/CXX_skip_linting_OFF.cmake
new file mode 100644
index 0000000..a0311a6
--- /dev/null
+++ b/Tests/RunCMake/MultiLint/CXX_skip_linting_OFF.cmake
@@ -0,0 +1,7 @@
+enable_language(CXX)
+set(CMAKE_CXX_INCLUDE_WHAT_YOU_USE "$<1:${PSEUDO_IWYU}>" -some -args)
+set(CMAKE_CXX_CLANG_TIDY "$<1:${PSEUDO_TIDY}>" -bad)
+set(CMAKE_CXX_CPPLINT "$<1:${PSEUDO_CPPLINT}>" --error)
+set(CMAKE_CXX_CPPCHECK "$<1:${PSEUDO_CPPCHECK}>" -error)
+add_executable(main main.cxx)
+set_source_files_properties(main.cxx PROPERTIES SKIP_LINTING OFF)
diff --git a/Tests/RunCMake/MultiLint/CXX_skip_linting_ON.cmake b/Tests/RunCMake/MultiLint/CXX_skip_linting_ON.cmake
new file mode 100644
index 0000000..39cfe87
--- /dev/null
+++ b/Tests/RunCMake/MultiLint/CXX_skip_linting_ON.cmake
@@ -0,0 +1,7 @@
+enable_language(CXX)
+set(CMAKE_CXX_INCLUDE_WHAT_YOU_USE "$<1:${PSEUDO_IWYU}>" -some -args)
+set(CMAKE_CXX_CLANG_TIDY "$<1:${PSEUDO_TIDY}>" -bad)
+set(CMAKE_CXX_CPPLINT "$<1:${PSEUDO_CPPLINT}>" --error)
+set(CMAKE_CXX_CPPCHECK "$<1:${PSEUDO_CPPCHECK}>" -error)
+add_executable(main main.cxx)
+set_source_files_properties(main.cxx PROPERTIES SKIP_LINTING ON)
diff --git a/Tests/RunCMake/MultiLint/C_skip_linting_OFF-Build-result.txt b/Tests/RunCMake/MultiLint/C_skip_linting_OFF-Build-result.txt
new file mode 100644
index 0000000..3beecb0
--- /dev/null
+++ b/Tests/RunCMake/MultiLint/C_skip_linting_OFF-Build-result.txt
@@ -0,0 +1 @@
+(1|2)
diff --git a/Tests/RunCMake/MultiLint/C_skip_linting_OFF.cmake b/Tests/RunCMake/MultiLint/C_skip_linting_OFF.cmake
new file mode 100644
index 0000000..2968a21
--- /dev/null
+++ b/Tests/RunCMake/MultiLint/C_skip_linting_OFF.cmake
@@ -0,0 +1,7 @@
+enable_language(C)
+set(CMAKE_C_INCLUDE_WHAT_YOU_USE "${PSEUDO_IWYU}" -some -args)
+set(CMAKE_C_CLANG_TIDY "${PSEUDO_TIDY}" -bad)
+set(CMAKE_C_CPPLINT "${PSEUDO_CPPLINT}" --error)
+set(CMAKE_C_CPPCHECK "${PSEUDO_CPPCHECK}" -error)
+add_executable(main main.c)
+set_source_files_properties(main.c PROPERTIES SKIP_LINTING OFF)
diff --git a/Tests/RunCMake/MultiLint/C_skip_linting_ON.cmake b/Tests/RunCMake/MultiLint/C_skip_linting_ON.cmake
new file mode 100644
index 0000000..09fc761
--- /dev/null
+++ b/Tests/RunCMake/MultiLint/C_skip_linting_ON.cmake
@@ -0,0 +1,7 @@
+enable_language(C)
+set(CMAKE_C_INCLUDE_WHAT_YOU_USE "${PSEUDO_IWYU}" -some -args)
+set(CMAKE_C_CLANG_TIDY "${PSEUDO_TIDY}" -bad)
+set(CMAKE_C_CPPLINT "${PSEUDO_CPPLINT}" --error)
+set(CMAKE_C_CPPCHECK "${PSEUDO_CPPCHECK}" -error)
+add_executable(main main.c)
+set_source_files_properties(main.c PROPERTIES SKIP_LINTING ON)
diff --git a/Tests/RunCMake/MultiLint/RunCMakeTest.cmake b/Tests/RunCMake/MultiLint/RunCMakeTest.cmake
index afd98fd..9b7a6a9 100644
--- a/Tests/RunCMake/MultiLint/RunCMakeTest.cmake
+++ b/Tests/RunCMake/MultiLint/RunCMakeTest.cmake
@@ -25,3 +25,22 @@ if(NOT RunCMake_GENERATOR STREQUAL "Watcom WMake")
run_multilint(C-launch)
run_multilint(CXX-launch)
endif()
+
+function(run_skip_linting test_name)
+ set(RunCMake_TEST_BINARY_DIR "${RunCMake_BINARY_DIR}/${test_name}-build")
+ set(RunCMake_TEST_NO_CLEAN 1)
+
+ run_cmake(${test_name})
+ set(RunCMake_TEST_OUTPUT_MERGE 1)
+ run_cmake_command(${test_name}-Build ${CMAKE_COMMAND} --build .)
+endfunction()
+
+run_skip_linting(C_skip_linting_ON)
+run_skip_linting(CXX_skip_linting_ON)
+run_skip_linting(C_skip_linting_OFF)
+run_skip_linting(CXX_skip_linting_OFF)
+
+if(NOT RunCMake_GENERATOR STREQUAL "Watcom WMake")
+ run_skip_linting(C-launch_skip_linting_ON)
+ run_skip_linting(CXX-launch_skip_linting_ON)
+endif()