瀏覽代碼

Add `SKIP_LINTING` target property and `CMAKE_SKIP_LINTING` variable

These offer target-wide settings to disable lints.

Closes: #27191
Alex Turbov 1 月之前
父節點
當前提交
f100769d72

+ 1 - 0
Help/manual/cmake-properties.7.rst

@@ -401,6 +401,7 @@ Properties on Targets
    /prop_tgt/RUNTIME_OUTPUT_NAME
    /prop_tgt/RUNTIME_OUTPUT_NAME_CONFIG
    /prop_tgt/SKIP_BUILD_RPATH
+   /prop_tgt/SKIP_LINTING
    /prop_tgt/SOURCE_DIR
    /prop_tgt/SOURCES
    /prop_tgt/SOVERSION

+ 1 - 0
Help/manual/cmake-variables.7.rst

@@ -573,6 +573,7 @@ Variables that Control the Build
    /variable/CMAKE_SHARED_LINKER_FLAGS_INIT
    /variable/CMAKE_SKIP_BUILD_RPATH
    /variable/CMAKE_SKIP_INSTALL_RPATH
+   /variable/CMAKE_SKIP_LINTING
    /variable/CMAKE_STATIC_LINKER_FLAGS
    /variable/CMAKE_STATIC_LINKER_FLAGS_CONFIG
    /variable/CMAKE_STATIC_LINKER_FLAGS_CONFIG_INIT

+ 5 - 0
Help/prop_sf/SKIP_LINTING.rst

@@ -41,3 +41,8 @@ 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.
+
+See Also
+^^^^^^^^
+
+* :prop_tgt:`SKIP_LINTING` target property

+ 25 - 0
Help/prop_tgt/SKIP_LINTING.rst

@@ -0,0 +1,25 @@
+SKIP_LINTING
+------------
+
+.. versionadded:: 4.2
+
+Exclude all sources of a target from running configured linting tools.
+
+When this boolean property is enabled on a target, C/C++ linting tools enabled
+for that target (e.g. :prop_tgt:`<LANG>_CPPLINT`, :prop_tgt:`<LANG>_CLANG_TIDY`,
+:prop_tgt:`<LANG>_CPPCHECK`, :prop_tgt:`<LANG>_ICSTAT` and
+:prop_tgt:`<LANG>_INCLUDE_WHAT_YOU_USE`) will not be invoked for source files
+compiled by the target.  If the :prop_sf:`SKIP_LINTING` source-file property
+is set on a specific source, it takes precedence over this target-wide property.
+
+This is a convenience alternative to setting the :prop_sf:`SKIP_LINTING`
+source file property individually on each source.  If either the target's
+:prop_tgt:`SKIP_LINTING` or a source’s :prop_sf:`SKIP_LINTING` is enabled,
+that source will be excluded from linting.
+
+The property has no effect on targets that do not have sources.
+
+See Also
+^^^^^^^^
+
+* :prop_sf:`SKIP_LINTING` source file property

+ 7 - 0
Help/release/dev/target-SKIP_LINTING.rst

@@ -0,0 +1,7 @@
+target-SKIP_LINTING
+-------------------
+
+* The :variable:`CMAKE_SKIP_LINTING` variable and corresponding
+  :prop_tgt:`SKIP_LINTING` target property were added to tell the
+  :ref:`Command-Line Build Tool Generators` to skip linting all
+  sources in a target.

+ 9 - 0
Help/variable/CMAKE_SKIP_LINTING.rst

@@ -0,0 +1,9 @@
+CMAKE_SKIP_LINTING
+------------------
+
+.. versionadded:: 4.2
+
+Default value for the :prop_tgt:`SKIP_LINTING` target property.
+
+This is used to initialize the :prop_tgt:`SKIP_LINTING` target property
+for all targets created *afterward*.

+ 12 - 8
Source/cmFastbuildNormalTargetGenerator.cxx

@@ -1008,14 +1008,18 @@ void cmFastbuildNormalTargetGenerator::CollapseAllExecsIntoOneScriptfile(
 std::string cmFastbuildNormalTargetGenerator::ComputeCodeCheckOptions(
   cmSourceFile const& srcFile)
 {
-  cmValue const skipCodeCheck = srcFile.GetProperty("SKIP_LINTING");
-  std::string staticCheckRule;
-  if (!skipCodeCheck.IsOn()) {
-    std::string compilerLauncher;
-    staticCheckRule = this->GenerateCodeCheckRules(srcFile, compilerLauncher,
-                                                   "", Config, nullptr);
-    LogMessage(cmStrCat("CodeCheck: ", staticCheckRule));
-  }
+  cmValue const srcSkipCodeCheckVal = srcFile.GetProperty("SKIP_LINTING");
+  bool const skipCodeCheck = srcSkipCodeCheckVal.IsSet()
+    ? srcSkipCodeCheckVal.IsOn()
+    : this->GetGeneratorTarget()->GetPropertyAsBool("SKIP_LINTING");
+
+  if (skipCodeCheck) {
+    return {};
+  }
+  std::string compilerLauncher;
+  std::string staticCheckRule = this->GenerateCodeCheckRules(
+    srcFile, compilerLauncher, "", Config, nullptr);
+  LogMessage(cmStrCat("CodeCheck: ", staticCheckRule));
   return staticCheckRule;
 }
 

+ 6 - 2
Source/cmMakefileTargetGenerator.cxx

@@ -1091,8 +1091,12 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
       compilerLauncher = GetCompilerLauncher(lang, config);
     }
 
-    cmValue const skipCodeCheck = source.GetProperty("SKIP_LINTING");
-    if (!skipCodeCheck.IsOn()) {
+    cmValue const srcSkipCodeCheckVal = source.GetProperty("SKIP_LINTING");
+    bool const skipCodeCheck = srcSkipCodeCheckVal.IsSet()
+      ? srcSkipCodeCheckVal.IsOn()
+      : this->GetGeneratorTarget()->GetPropertyAsBool("SKIP_LINTING");
+
+    if (!skipCodeCheck) {
       std::string const codeCheck = this->GenerateCodeCheckRules(
         source, compilerLauncher, "$(CMAKE_COMMAND)", config, nullptr);
       if (!codeCheck.empty()) {

+ 6 - 2
Source/cmNinjaTargetGenerator.cxx

@@ -1423,8 +1423,12 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
 
   auto compilerLauncher = this->GetCompilerLauncher(language, config);
 
-  cmValue const skipCodeCheck = source->GetProperty("SKIP_LINTING");
-  if (!skipCodeCheck.IsOn()) {
+  cmValue const srcSkipCodeCheckVal = source->GetProperty("SKIP_LINTING");
+  bool const skipCodeCheck = srcSkipCodeCheckVal.IsSet()
+    ? srcSkipCodeCheckVal.IsOn()
+    : this->GetGeneratorTarget()->GetPropertyAsBool("SKIP_LINTING");
+
+  if (!skipCodeCheck) {
     auto const cmakeCmd = this->GetLocalGenerator()->ConvertToOutputFormat(
       cmSystemTools::GetCMakeCommand(), cmLocalGenerator::SHELL);
     vars["CODE_CHECK"] =

+ 2 - 0
Source/cmTarget.cxx

@@ -464,6 +464,7 @@ TargetProperty const StaticTargetProperties[] = {
   { "Fortran_LINKER_LAUNCHER"_s, IC::CanCompileSources },
 
   // Static analysis
+  { "SKIP_LINTING"_s, IC::CanCompileSources },
   // -- C
   { "C_CLANG_TIDY"_s, IC::CanCompileSources },
   { "C_CLANG_TIDY_EXPORT_FIXES_DIR"_s, IC::CanCompileSources },
@@ -1804,6 +1805,7 @@ void cmTarget::CopyImportedCxxModulesProperties(cmTarget const* tgt)
     "CXX_CPPCHECK",
     "CXX_ICSTAT",
     "CXX_INCLUDE_WHAT_YOU_USE",
+    "SKIP_LINTING",
 
     // Build graph properties
     "EXCLUDE_FROM_ALL",

+ 1 - 1
Tests/RunCMake/MultiLint/CXX_skip_linting_OFF.cmake

@@ -1,3 +1,3 @@
 enable_language(CXX)
 include(${CMAKE_CURRENT_LIST_DIR}/setup_skip_linter_test.cmake)
-setup_skip_linter_test(CXX OFF)
+setup_skip_linter_test(CXX)

+ 1 - 1
Tests/RunCMake/MultiLint/CXX_skip_linting_ON.cmake

@@ -1,3 +1,3 @@
 enable_language(CXX)
 include(${CMAKE_CURRENT_LIST_DIR}/setup_skip_linter_test.cmake)
-setup_skip_linter_test(CXX ON)
+setup_skip_linter_test(CXX)

+ 1 - 1
Tests/RunCMake/MultiLint/C_skip_linting_OFF.cmake

@@ -1,3 +1,3 @@
 enable_language(C)
 include(${CMAKE_CURRENT_LIST_DIR}/setup_skip_linter_test.cmake)
-setup_skip_linter_test(C OFF)
+setup_skip_linter_test(C)

+ 1 - 1
Tests/RunCMake/MultiLint/C_skip_linting_ON.cmake

@@ -1,3 +1,3 @@
 enable_language(C)
 include(${CMAKE_CURRENT_LIST_DIR}/setup_skip_linter_test.cmake)
-setup_skip_linter_test(C ON)
+setup_skip_linter_test(C)

+ 56 - 14
Tests/RunCMake/MultiLint/RunCMakeTest.cmake

@@ -27,22 +27,64 @@ if(NOT RunCMake_GENERATOR STREQUAL "Watcom WMake")
   run_multilint(genex)
 endif()
 
-function(run_skip_linting test_name)
-    set(RunCMake_TEST_BINARY_DIR "${RunCMake_BINARY_DIR}/${test_name}-build")
-    set(RunCMake_TEST_NO_CLEAN 1)
+function(run_skip_linting test_name prop_sf prop_tgt)
+  set(RunCMake_TEST_VARIANT_DESCRIPTION " (prop_sf=${prop_sf}, prop_tgt=${prop_tgt})")
+  list(APPEND RunCMake_TEST_OPTIONS "-Dprop_sf=${prop_sf}" "-Dprop_tgt=${prop_tgt}")
 
-    run_cmake(${test_name})
-    set(RunCMake_TEST_OUTPUT_MERGE 1)
-    run_cmake_command(${test_name}-Build ${CMAKE_COMMAND} --build .)
+  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()
 
+# There are a few `SKIP_LINTING` source/target propertiy combinations
+# that affect the final result:
+#
+#  prop_sf   prop_tgt   result
+#  ---------------------------
+#    -         -         OFF
+#    OFF       -         OFF
+#    ON        -         ON
+#    -         OFF       OFF
+#    OFF       OFF       OFF
+#    ON        OFF       ON
+#    -         ON        ON
+#    OFF       ON        OFF
+#    ON        ON        ON
+#
+# where `-` means unset property.
+#
+# Here's the same table for convenience sorted by `result`:
+#
+#  prop_sf   prop_tgt   result
+#  ---------------------------
+#    -         -         OFF
+#    OFF       -         OFF
+#    -         OFF       OFF
+#    OFF       OFF       OFF
+#    OFF       ON        OFF
+#    ON        -         ON
+#    ON        OFF       ON
+#    -         ON        ON
+#    ON        ON        ON
+
 foreach(lang IN ITEMS C CXX)
-  # Testing `SKIP_LINTING=ON`
-  run_skip_linting(${lang}_skip_linting_ON)
-  if(NOT RunCMake_GENERATOR STREQUAL "Watcom WMake")
-    run_skip_linting(${lang}-launch_skip_linting_ON)
-  endif()
-
-  # Testing `SKIP_LINTING=OFF`
-  run_skip_linting(${lang}_skip_linting_OFF)
+  # Testing `SKIP_LINTING=OFF` (first half of the table above)
+  set(prop_sf_OFF_variants "-" OFF "-" OFF OFF)
+  set(prop_tgt_OFF_variants "-" "-" OFF OFF ON)
+  foreach(prop_fs prop_tgt IN ZIP_LISTS prop_sf_OFF_variants prop_tgt_OFF_variants)
+    run_skip_linting(${lang}_skip_linting_OFF "${prop_fs}" "${prop_tgt}")
+  endforeach()
+
+  # Testing `SKIP_LINTING=ON` (second half of the table above)
+  set(prop_sf_ON_variants ON ON "-" ON)
+  set(prop_tgt_ON_variants "-" OFF ON ON)
+  foreach(prop_fs prop_tgt IN ZIP_LISTS prop_sf_ON_variants prop_tgt_ON_variants)
+    run_skip_linting(${lang}_skip_linting_ON "${prop_fs}" "${prop_tgt}")
+    if(NOT RunCMake_GENERATOR STREQUAL "Watcom WMake")
+      run_skip_linting(${lang}-launch_skip_linting_ON "${prop_fs}" "${prop_tgt}")
+    endif()
+  endforeach()
 endforeach()

+ 9 - 2
Tests/RunCMake/MultiLint/setup_skip_linter_test.cmake

@@ -1,6 +1,6 @@
 include_guard()
 
-function(setup_skip_linter_test lang state)
+function(setup_skip_linter_test lang)
   if(lang STREQUAL "CXX")
     set(maybe_genex_pre "$<1:")
     set(maybe_genex_post ">")
@@ -13,5 +13,12 @@ function(setup_skip_linter_test lang state)
 
   string(TOLOWER "${lang}" ext)
   add_executable(main main.${ext})
-  set_source_files_properties(main.${ext} PROPERTIES SKIP_LINTING ${state})
+
+  if(NOT prop_sf STREQUAL "-")
+    set_source_files_properties(main.${ext} PROPERTIES SKIP_LINTING ${prop_sf})
+  endif()
+
+  if(NOT prop_tgt STREQUAL "-")
+    set_target_properties(main PROPERTIES SKIP_LINTING ${prop_tgt})
+  endif()
 endfunction()

+ 1 - 0
Tests/RunCMake/property_init/CompileSources.cmake

@@ -113,6 +113,7 @@ set(properties
   "OBJCXX_LINKER_LAUNCHER"                  "ccache"            "<SAME>"
 
   # Static analysis
+  "SKIP_LINTING"                            "OFF"               "<SAME>"
   ## C
   "C_CLANG_TIDY"                            "clang-tidy"        "<SAME>"
   "C_CLANG_TIDY_EXPORT_FIXES_DIR"           "${dir}"            "<SAME>"