FILE_SET: add SKIP_LINTING property support
diff --git a/Help/manual/cmake-properties.7.rst b/Help/manual/cmake-properties.7.rst index 571585d..73f880f1 100644 --- a/Help/manual/cmake-properties.7.rst +++ b/Help/manual/cmake-properties.7.rst
@@ -552,6 +552,7 @@ /prop_fs/INTERFACE_INCLUDE_DIRECTORIES /prop_fs/INTERFACE_SOURCES /prop_fs/SCOPE + /prop_fs/SKIP_LINTING /prop_fs/SOURCES /prop_fs/TYPE
diff --git a/Help/prop_fs/SKIP_LINTING.rst b/Help/prop_fs/SKIP_LINTING.rst new file mode 100644 index 0000000..7c6546e --- /dev/null +++ b/Help/prop_fs/SKIP_LINTING.rst
@@ -0,0 +1,54 @@ +SKIP_LINTING +------------ + +.. versionadded:: 4.4 + +This property allows you to exclude a source files of the specific file set +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`, :prop_tgt:`<LANG>_ICSTAT`, +:prop_tgt:`<LANG>_PVS_STUDIO` and :prop_tgt:`<LANG>_INCLUDE_WHAT_YOU_USE` on +the source files, as well as compiling header files as part of +:prop_tgt:`VERIFY_INTERFACE_HEADER_SETS`. By setting ``SKIP_LINTING`` on a +file set, the mentioned linting tools will not be executed for the files of +that particular file set. If the :prop_fs:`SKIP_LINTING` file set property +is set, it takes precedence over this source-file and target-wide properties. + +This is a convenience alternative to setting the :prop_sf:`SKIP_LINTING` +source file property individually on each source. + +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 ``things.cpp`` and +``generatedBindings.cpp`` files from the linting process. To achieve this, you +can use a file set and utilize the ``SKIP_LINTING`` property with the +:command:`set_property(FILE_SET) <set_property>` command as shown below: + +.. code-block:: cmake + + add_executable(MyApp main.cpp) + target_sources(MyApp PRIVATE FILE_SET skip_lint TYPE SOURCES + FILES things.cpp generatedBindings.cpp) + + set_property(FILE_SET skip_lint TARGET MyApp PROPERTY SKIP_LINTING ON) + +In the provided code snippet, the ``SKIP_LINTING`` property is set to true +for the ``skip_lint`` file set. As a result, when the linting +tools specified by :prop_tgt:`<LANG>_CPPLINT`, :prop_tgt:`<LANG>_CLANG_TIDY`, +:prop_tgt:`<LANG>_CPPCHECK`, :prop_tgt:`<LANG>_ICSTAT` or +:prop_tgt:`<LANG>_INCLUDE_WHAT_YOU_USE` are executed, they will skip analyzing +the ``things.cpp`` and ``generatedBindings.cpp`` files. + +By using the ``SKIP_LINTING`` file set 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_sf:`SKIP_LINTING` source file property +* :prop_tgt:`SKIP_LINTING` target property
diff --git a/Help/prop_sf/SKIP_LINTING.rst b/Help/prop_sf/SKIP_LINTING.rst index 5d2c0c4..07e5cd1 100644 --- a/Help/prop_sf/SKIP_LINTING.rst +++ b/Help/prop_sf/SKIP_LINTING.rst
@@ -43,7 +43,11 @@ linting tools on the relevant parts of your project, enhancing the efficiency and effectiveness of the linting workflow. +A convenient alternative, when multiple sources should be excluded from the +linting process, is to use the file set's :prop_fs:`SKIP_LINTING` property. + See Also ^^^^^^^^ +* :prop_fs:`SKIP_LINTING` file set property * :prop_tgt:`SKIP_LINTING` target property
diff --git a/Help/prop_tgt/SKIP_LINTING.rst b/Help/prop_tgt/SKIP_LINTING.rst index 031f653..996c4ee 100644 --- a/Help/prop_tgt/SKIP_LINTING.rst +++ b/Help/prop_tgt/SKIP_LINTING.rst
@@ -10,16 +10,19 @@ :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. +is set on a specific source or if the :prop_fs:`SKIP_LINTING` file set property +is set, 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. +:prop_tgt:`SKIP_LINTING` or file set's :prop_fs:`SKIP_LINTING` including this +source 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_fs:`SKIP_LINTING` file set property * :prop_sf:`SKIP_LINTING` source file property
diff --git a/Help/release/dev/FILE_SET-SKIP_LINTING.rst b/Help/release/dev/FILE_SET-SKIP_LINTING.rst new file mode 100644 index 0000000..eeca0cd --- /dev/null +++ b/Help/release/dev/FILE_SET-SKIP_LINTING.rst
@@ -0,0 +1,5 @@ +FILE_SET-SKIP_LINTING +--------------------- + +* File sets gained the support of the :prop_fs:`SKIP_LINTING` file set + property.
diff --git a/Source/cmFastbuildNormalTargetGenerator.cxx b/Source/cmFastbuildNormalTargetGenerator.cxx index 6aa2ee4..615c45b 100644 --- a/Source/cmFastbuildNormalTargetGenerator.cxx +++ b/Source/cmFastbuildNormalTargetGenerator.cxx
@@ -1141,10 +1141,16 @@ std::string cmFastbuildNormalTargetGenerator::ComputeCodeCheckOptions( cmSourceFile const& srcFile) { + cmGeneratorFileSet const* fileSet = + this->GeneratorTarget->GetFileSetForSource(Config, &srcFile); + cmValue const fsSkipCodeCheckVal = + fileSet ? fileSet->GetProperty("SKIP_LINTING") : nullptr; cmValue const srcSkipCodeCheckVal = srcFile.GetProperty("SKIP_LINTING"); - bool const skipCodeCheck = srcSkipCodeCheckVal.IsSet() - ? srcSkipCodeCheckVal.IsOn() - : this->GetGeneratorTarget()->GetPropertyAsBool("SKIP_LINTING"); + bool const skipCodeCheck = fsSkipCodeCheckVal.IsSet() + ? fsSkipCodeCheckVal.IsOn() + : (srcSkipCodeCheckVal.IsSet() + ? srcSkipCodeCheckVal.IsOn() + : this->GetGeneratorTarget()->GetPropertyAsBool("SKIP_LINTING")); if (skipCodeCheck) { return {};
diff --git a/Source/cmGeneratorTarget_HeaderSetVerification.cxx b/Source/cmGeneratorTarget_HeaderSetVerification.cxx index 57d82b2..a84ad97 100644 --- a/Source/cmGeneratorTarget_HeaderSetVerification.cxx +++ b/Source/cmGeneratorTarget_HeaderSetVerification.cxx
@@ -89,8 +89,11 @@ std::set<cmGeneratorFileSet const*> fileSets; for (auto const& fileSet : fileSetEntries) { if (all || verifySet.count(fileSet->GetName())) { - fileSets.insert(fileSet); verifySet.erase(fileSet->GetName()); + if (fileSet->GetProperty("SKIP_LINTING").IsOn()) { + continue; + } + fileSets.insert(fileSet); } }
diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx index 77b1550..31300f4 100644 --- a/Source/cmMakefileTargetGenerator.cxx +++ b/Source/cmMakefileTargetGenerator.cxx
@@ -1107,10 +1107,14 @@ compilerLauncher = GetCompilerLauncher(lang, config); } + cmValue const fsSkipCodeCheckVal = + fileSet ? fileSet->GetProperty("SKIP_LINTING") : nullptr; cmValue const srcSkipCodeCheckVal = source.GetProperty("SKIP_LINTING"); - bool const skipCodeCheck = srcSkipCodeCheckVal.IsSet() - ? srcSkipCodeCheckVal.IsOn() - : this->GetGeneratorTarget()->GetPropertyAsBool("SKIP_LINTING"); + bool const skipCodeCheck = fsSkipCodeCheckVal.IsSet() + ? fsSkipCodeCheckVal.IsOn() + : (srcSkipCodeCheckVal.IsSet() + ? srcSkipCodeCheckVal.IsOn() + : this->GetGeneratorTarget()->GetPropertyAsBool("SKIP_LINTING")); if (!skipCodeCheck) { std::string const codeCheck = this->GenerateCodeCheckRules(
diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx index 762da6c..c20ceb5 100644 --- a/Source/cmNinjaTargetGenerator.cxx +++ b/Source/cmNinjaTargetGenerator.cxx
@@ -1585,10 +1585,17 @@ auto compilerLauncher = this->GetCompilerLauncher(language, config); + cmGeneratorFileSet const* fileSet = + this->GeneratorTarget->GetFileSetForSource(config, source); + + cmValue const fsSkipCodeCheckVal = + fileSet ? fileSet->GetProperty("SKIP_LINTING") : nullptr; cmValue const srcSkipCodeCheckVal = source->GetProperty("SKIP_LINTING"); - bool const skipCodeCheck = srcSkipCodeCheckVal.IsSet() - ? srcSkipCodeCheckVal.IsOn() - : this->GetGeneratorTarget()->GetPropertyAsBool("SKIP_LINTING"); + bool const skipCodeCheck = fsSkipCodeCheckVal.IsSet() + ? fsSkipCodeCheckVal.IsOn() + : (srcSkipCodeCheckVal.IsSet() + ? srcSkipCodeCheckVal.IsOn() + : this->GetGeneratorTarget()->GetPropertyAsBool("SKIP_LINTING")); if (!skipCodeCheck) { auto const cmakeCmd =
diff --git a/Tests/RunCMake/MultiLint/RunCMakeTest.cmake b/Tests/RunCMake/MultiLint/RunCMakeTest.cmake index b9b69fb..a42945a 100644 --- a/Tests/RunCMake/MultiLint/RunCMakeTest.cmake +++ b/Tests/RunCMake/MultiLint/RunCMakeTest.cmake
@@ -28,9 +28,9 @@ run_multilint(genex) endif() -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}") +function(run_skip_linting test_name prop_fs prop_sf prop_tgt) + set(RunCMake_TEST_VARIANT_DESCRIPTION " (prop_fs=${prop_fs}, prop_sf=${prop_sf}, prop_tgt=${prop_tgt})") + list(APPEND RunCMake_TEST_OPTIONS "-Dprop_fs=${prop_fs}" "-Dprop_sf=${prop_sf}" "-Dprop_tgt=${prop_tgt}") set(RunCMake_TEST_BINARY_DIR "${RunCMake_BINARY_DIR}/${test_name}-build") set(RunCMake_TEST_NO_CLEAN 1) @@ -40,52 +40,90 @@ run_cmake_command(${test_name}-Build ${CMAKE_COMMAND} --build .) endfunction() -# There are a few `SKIP_LINTING` source/target propertiy combinations +# There are a few `SKIP_LINTING` file set/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 +# prop_fs 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 +# - - OFF OFF +# OFF - OFF OFF +# ON - OFF ON +# - - ON ON +# OFF - ON OFF +# ON - ON ON +# - OFF OFF OFF +# OFF OFF OFF OFF +# ON OFF OFF ON +# - OFF ON OFF +# OFF OFF ON OFF +# ON OFF ON ON +# - ON OFF ON +# OFF ON OFF OFF +# ON ON OFF ON +# - ON ON ON +# OFF ON ON OFF +# ON 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 +# prop_fs prop_sf prop_tgt result +# ------------------------------------ +# - - - OFF +# OFF - - OFF +# - OFF - OFF +# OFF OFF - OFF +# OFF ON - OFF +# - - OFF OFF +# OFF - OFF OFF +# OFF - ON OFF +# - OFF OFF OFF +# OFF OFF OFF OFF +# - OFF ON OFF +# OFF OFF ON OFF +# OFF ON OFF OFF +# OFF ON ON OFF +# ON - - ON +# ON OFF - ON +# - ON - ON +# ON ON - ON +# ON - OFF ON +# - - ON ON +# ON - ON ON +# ON OFF OFF ON +# ON OFF ON ON +# - ON OFF ON +# ON ON OFF ON +# - ON ON ON +# ON ON ON ON 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}") + set(prop_fs_OFF_variants "-" OFF "-" OFF OFF "-" OFF OFF "-" OFF "-" OFF OFF OFF) + set(prop_sf_OFF_variants "-" "-" OFF OFF ON "-" "-" "-" OFF OFF OFF OFF ON ON) + set(prop_tgt_OFF_variants "-" "-" "-" "-" "-" OFF OFF ON OFF OFF ON ON OFF ON) + foreach(prop_fs prop_sf prop_tgt IN ZIP_LISTS prop_fs_OFF_variants prop_sf_OFF_variants prop_tgt_OFF_variants) + run_skip_linting(${lang}_skip_linting_OFF "${prop_fs}" "${prop_sf}" "${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}") + set(prop_fs_ON_variants ON ON "-" ON ON "-" ON ON ON "-" ON "-" ON) + set(prop_sf_ON_variants "-" OFF ON ON "-" "-" "-" OFF OFF ON ON ON ON) + set(prop_tgt_ON_variants "-" "-" "-" "-" OFF ON ON OFF ON OFF OFF ON ON) + foreach(prop_fs prop_sf prop_tgt IN ZIP_LISTS prop_fs_ON_variants prop_sf_ON_variants prop_tgt_ON_variants) + run_skip_linting(${lang}_skip_linting_ON "${prop_fs}" "${prop_sf}" "${prop_tgt}") if(NOT RunCMake_GENERATOR STREQUAL "Watcom WMake") - run_skip_linting(${lang}-launch_skip_linting_ON "${prop_fs}" "${prop_tgt}") + run_skip_linting(${lang}-launch_skip_linting_ON "${prop_fs}" "${prop_sf}" "${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 index ab8d646..a655339 100644 --- a/Tests/RunCMake/MultiLint/setup_skip_linter_test.cmake +++ b/Tests/RunCMake/MultiLint/setup_skip_linter_test.cmake
@@ -12,7 +12,12 @@ set(CMAKE_${lang}_CPPCHECK "${maybe_genex_pre}${PSEUDO_CPPCHECK}${maybe_genex_post}" -error) string(TOLOWER "${lang}" ext) - add_executable(main main.${ext}) + add_executable(main) + target_sources(main PRIVATE FILE_SET SOURCES FILES main.${ext}) + + if(NOT prop_fs STREQUAL "-") + set_property(FILE_SET SOURCES TARGET main PROPERTY SKIP_LINTING ${prop_fs}) + endif() if(NOT prop_sf STREQUAL "-") set_source_files_properties(main.${ext} PROPERTIES SKIP_LINTING ${prop_sf})
diff --git a/Tests/RunCMake/VerifyHeaderSets/VerifyInterfaceHeaderSets.cmake b/Tests/RunCMake/VerifyHeaderSets/VerifyInterfaceHeaderSets.cmake index 2efd560..c96279a 100644 --- a/Tests/RunCMake/VerifyHeaderSets/VerifyInterfaceHeaderSets.cmake +++ b/Tests/RunCMake/VerifyHeaderSets/VerifyInterfaceHeaderSets.cmake
@@ -83,3 +83,10 @@ target_sources(skip_linting INTERFACE FILE_SET HEADERS FILES lang_test.h skip_linting.h) set_property(SOURCE skip_linting.h PROPERTY LANGUAGE C) set_property(SOURCE skip_linting.h PROPERTY SKIP_LINTING TRUE) + +add_library(skip_linting2 STATIC lib.c) +target_sources(skip_linting2 INTERFACE FILE_SET HEADERS FILES lang_test.h) +target_sources(skip_linting2 INTERFACE FILE_SET skip_headers TYPE HEADERS FILES skip_linting2.h) +set_property(FILE_SET skip_headers TARGET skip_linting2 PROPERTY SKIP_LINTING TRUE) + +set_property(SOURCE skip_linting2.h PROPERTY LANGUAGE C)
diff --git a/Tests/RunCMake/VerifyHeaderSets/VerifyPrivateHeaderSets.cmake b/Tests/RunCMake/VerifyHeaderSets/VerifyPrivateHeaderSets.cmake index 1fc92e1..975a398 100644 --- a/Tests/RunCMake/VerifyHeaderSets/VerifyPrivateHeaderSets.cmake +++ b/Tests/RunCMake/VerifyHeaderSets/VerifyPrivateHeaderSets.cmake
@@ -86,3 +86,10 @@ target_sources(skip_linting PRIVATE FILE_SET HEADERS FILES lang_test.h skip_linting.h) set_property(SOURCE skip_linting.h PROPERTY LANGUAGE C) set_property(SOURCE skip_linting.h PROPERTY SKIP_LINTING TRUE) + +add_library(skip_linting2 STATIC lib.c) +target_sources(skip_linting2 PRIVATE FILE_SET HEADERS FILES lang_test.h) +target_sources(skip_linting2 PRIVATE FILE_SET skip_headers TYPE HEADERS FILES skip_linting2.h) +set_property(FILE_SET skip_headers TARGET skip_linting2 PROPERTY SKIP_LINTING TRUE) + +set_property(SOURCE skip_linting2.h PROPERTY LANGUAGE C)
diff --git a/Tests/RunCMake/VerifyHeaderSets/skip_linting2.h b/Tests/RunCMake/VerifyHeaderSets/skip_linting2.h new file mode 100644 index 0000000..8a268bd --- /dev/null +++ b/Tests/RunCMake/VerifyHeaderSets/skip_linting2.h
@@ -0,0 +1,3 @@ +#error "This file should not be included" + +extern void skip_linting2_h(void);