diff --git a/Help/manual/cmake-properties.7.rst b/Help/manual/cmake-properties.7.rst index ff7446483b..749188c4f3 100644 --- a/Help/manual/cmake-properties.7.rst +++ b/Help/manual/cmake-properties.7.rst @@ -404,6 +404,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 diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst index da89f687c8..aabf61365f 100644 --- a/Help/manual/cmake-variables.7.rst +++ b/Help/manual/cmake-variables.7.rst @@ -574,6 +574,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 diff --git a/Help/prop_sf/SKIP_LINTING.rst b/Help/prop_sf/SKIP_LINTING.rst index fe0f2d4dbd..f995cb434b 100644 --- a/Help/prop_sf/SKIP_LINTING.rst +++ b/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 diff --git a/Help/prop_tgt/SKIP_LINTING.rst b/Help/prop_tgt/SKIP_LINTING.rst new file mode 100644 index 0000000000..031f653359 --- /dev/null +++ b/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:`_CPPLINT`, :prop_tgt:`_CLANG_TIDY`, +:prop_tgt:`_CPPCHECK`, :prop_tgt:`_ICSTAT` and +:prop_tgt:`_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 diff --git a/Help/release/dev/target-SKIP_LINTING.rst b/Help/release/dev/target-SKIP_LINTING.rst new file mode 100644 index 0000000000..21d62eb360 --- /dev/null +++ b/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. diff --git a/Help/variable/CMAKE_SKIP_LINTING.rst b/Help/variable/CMAKE_SKIP_LINTING.rst new file mode 100644 index 0000000000..72fe63574d --- /dev/null +++ b/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*. diff --git a/Source/cmFastbuildNormalTargetGenerator.cxx b/Source/cmFastbuildNormalTargetGenerator.cxx index 8ce597c316..7873bbac97 100644 --- a/Source/cmFastbuildNormalTargetGenerator.cxx +++ b/Source/cmFastbuildNormalTargetGenerator.cxx @@ -1011,14 +1011,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; } diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx index 44de1fe24f..9d5d80dc8e 100644 --- a/Source/cmMakefileTargetGenerator.cxx +++ b/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()) { diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx index 25f6d36359..c11b693f63 100644 --- a/Source/cmNinjaTargetGenerator.cxx +++ b/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"] = diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 1dbb2ee2f0..f66939288b 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -465,6 +465,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 }, @@ -1805,6 +1806,7 @@ void cmTarget::CopyImportedCxxModulesProperties(cmTarget const* tgt) "CXX_CPPCHECK", "CXX_ICSTAT", "CXX_INCLUDE_WHAT_YOU_USE", + "SKIP_LINTING", // Build graph properties "EXCLUDE_FROM_ALL", diff --git a/Tests/RunCMake/MultiLint/CXX_skip_linting_OFF.cmake b/Tests/RunCMake/MultiLint/CXX_skip_linting_OFF.cmake index a0311a605b..a82eae227b 100644 --- a/Tests/RunCMake/MultiLint/CXX_skip_linting_OFF.cmake +++ b/Tests/RunCMake/MultiLint/CXX_skip_linting_OFF.cmake @@ -1,7 +1,3 @@ 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) +include(${CMAKE_CURRENT_LIST_DIR}/setup_skip_linter_test.cmake) +setup_skip_linter_test(CXX) diff --git a/Tests/RunCMake/MultiLint/CXX_skip_linting_ON.cmake b/Tests/RunCMake/MultiLint/CXX_skip_linting_ON.cmake index 39cfe87a2f..a82eae227b 100644 --- a/Tests/RunCMake/MultiLint/CXX_skip_linting_ON.cmake +++ b/Tests/RunCMake/MultiLint/CXX_skip_linting_ON.cmake @@ -1,7 +1,3 @@ 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) +include(${CMAKE_CURRENT_LIST_DIR}/setup_skip_linter_test.cmake) +setup_skip_linter_test(CXX) diff --git a/Tests/RunCMake/MultiLint/C_skip_linting_OFF.cmake b/Tests/RunCMake/MultiLint/C_skip_linting_OFF.cmake index 2968a21ff5..1658f33138 100644 --- a/Tests/RunCMake/MultiLint/C_skip_linting_OFF.cmake +++ b/Tests/RunCMake/MultiLint/C_skip_linting_OFF.cmake @@ -1,7 +1,3 @@ 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) +include(${CMAKE_CURRENT_LIST_DIR}/setup_skip_linter_test.cmake) +setup_skip_linter_test(C) diff --git a/Tests/RunCMake/MultiLint/C_skip_linting_ON.cmake b/Tests/RunCMake/MultiLint/C_skip_linting_ON.cmake index 09fc761b1c..1658f33138 100644 --- a/Tests/RunCMake/MultiLint/C_skip_linting_ON.cmake +++ b/Tests/RunCMake/MultiLint/C_skip_linting_ON.cmake @@ -1,7 +1,3 @@ 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) +include(${CMAKE_CURRENT_LIST_DIR}/setup_skip_linter_test.cmake) +setup_skip_linter_test(C) diff --git a/Tests/RunCMake/MultiLint/RunCMakeTest.cmake b/Tests/RunCMake/MultiLint/RunCMakeTest.cmake index f2df29019b..17e47c3464 100644 --- a/Tests/RunCMake/MultiLint/RunCMakeTest.cmake +++ b/Tests/RunCMake/MultiLint/RunCMakeTest.cmake @@ -27,21 +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() -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) +# 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 -if(NOT RunCMake_GENERATOR STREQUAL "Watcom WMake") - run_skip_linting(C-launch_skip_linting_ON) - run_skip_linting(CXX-launch_skip_linting_ON) -endif() +foreach(lang IN ITEMS C CXX) + # 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() diff --git a/Tests/RunCMake/MultiLint/setup_skip_linter_test.cmake b/Tests/RunCMake/MultiLint/setup_skip_linter_test.cmake new file mode 100644 index 0000000000..ab8d646fdf --- /dev/null +++ b/Tests/RunCMake/MultiLint/setup_skip_linter_test.cmake @@ -0,0 +1,24 @@ +include_guard() + +function(setup_skip_linter_test lang) + if(lang STREQUAL "CXX") + set(maybe_genex_pre "$<1:") + set(maybe_genex_post ">") + endif() + + set(CMAKE_${lang}_INCLUDE_WHAT_YOU_USE "${maybe_genex_pre}${PSEUDO_IWYU}${maybe_genex_post}" -some -args) + set(CMAKE_${lang}_CLANG_TIDY "${maybe_genex_pre}${PSEUDO_TIDY}${maybe_genex_post}" -bad) + set(CMAKE_${lang}_CPPLINT "${maybe_genex_pre}${PSEUDO_CPPLINT}${maybe_genex_post}" --error) + set(CMAKE_${lang}_CPPCHECK "${maybe_genex_pre}${PSEUDO_CPPCHECK}${maybe_genex_post}" -error) + + string(TOLOWER "${lang}" ext) + add_executable(main main.${ext}) + + 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() diff --git a/Tests/RunCMake/property_init/CompileSources.cmake b/Tests/RunCMake/property_init/CompileSources.cmake index 8a20ef0251..ca3871d7ea 100644 --- a/Tests/RunCMake/property_init/CompileSources.cmake +++ b/Tests/RunCMake/property_init/CompileSources.cmake @@ -114,6 +114,7 @@ set(properties "OBJCXX_LINKER_LAUNCHER" "ccache" "" # Static analysis + "SKIP_LINTING" "OFF" "" ## C "C_CLANG_TIDY" "clang-tidy" "" "C_CLANG_TIDY_EXPORT_FIXES_DIR" "${dir}" ""