diff options
74 files changed, 777 insertions, 90 deletions
diff --git a/.clang-tidy b/.clang-tidy index a86f39a..1e9b78a 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -33,6 +33,7 @@ readability-*,\ -readability-redundant-member-init,\ -readability-suspicious-call-argument,\ -readability-uppercase-literal-suffix,\ +cmake-*,\ " HeaderFilterRegex: 'Source/cm[^/]*\.(h|hxx|cxx)$' CheckOptions: diff --git a/.gitlab/ci/configure_fedora36_tidy.cmake b/.gitlab/ci/configure_fedora36_tidy.cmake index 38414d3..2d0eeeb 100644 --- a/.gitlab/ci/configure_fedora36_tidy.cmake +++ b/.gitlab/ci/configure_fedora36_tidy.cmake @@ -1,3 +1,5 @@ set(CMake_RUN_CLANG_TIDY ON CACHE BOOL "") +set(CMake_USE_CLANG_TIDY_MODULE ON CACHE BOOL "") +set(CMake_CLANG_TIDY_MODULE "$ENV{CI_PROJECT_DIR}/Utilities/ClangTidyModule/build/libcmake-clang-tidy-module.so" CACHE FILEPATH "") include("${CMAKE_CURRENT_LIST_DIR}/configure_fedora36_common.cmake") diff --git a/.gitlab/ci/env_fedora36_tidy.sh b/.gitlab/ci/env_fedora36_tidy.sh new file mode 100644 index 0000000..d5b1989 --- /dev/null +++ b/.gitlab/ci/env_fedora36_tidy.sh @@ -0,0 +1,6 @@ +cmake \ + -S Utilities/ClangTidyModule \ + -B Utilities/ClangTidyModule/build \ + -DRUN_TESTS=ON +cmake --build Utilities/ClangTidyModule/build +ctest --test-dir Utilities/ClangTidyModule/build diff --git a/CMakeLists.txt b/CMakeLists.txt index 2b9eb2d..73c2c2e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,14 +1,10 @@ # Distributed under the OSI-approved BSD 3-Clause License. See accompanying # file Copyright.txt or https://cmake.org/licensing for details. -cmake_minimum_required(VERSION 3.13...3.23 FATAL_ERROR) +cmake_minimum_required(VERSION 3.13...3.24 FATAL_ERROR) set(CMAKE_USER_MAKE_RULES_OVERRIDE_C ${CMAKE_CURRENT_SOURCE_DIR}/Source/Modules/OverrideC.cmake) set(CMAKE_USER_MAKE_RULES_OVERRIDE_CXX ${CMAKE_CURRENT_SOURCE_DIR}/Source/Modules/OverrideCXX.cmake) -if(POLICY CMP0129) - cmake_policy(SET CMP0129 NEW) # CMake 3.23 -endif() - project(CMake) unset(CMAKE_USER_MAKE_RULES_OVERRIDE_CXX) unset(CMAKE_USER_MAKE_RULES_OVERRIDE_C) @@ -277,6 +273,16 @@ if(CMake_RUN_CLANG_TIDY) endif() set(CMAKE_CXX_CLANG_TIDY "${CLANG_TIDY_COMMAND}") + option(CMake_USE_CLANG_TIDY_MODULE "Use CMake's clang-tidy module." OFF) + if(CMake_USE_CLANG_TIDY_MODULE) + find_library(CMake_CLANG_TIDY_MODULE NAMES cmake-clang-tidy-module DOC "Location of the clang-tidy module") + if(NOT CMake_CLANG_TIDY_MODULE) + message(FATAL_ERROR "CMake_USE_CLANG_TIDY_MODULE is ON but cmake-clang-tidy-module is not found!") + endif() + list(APPEND CMAKE_CXX_CLANG_TIDY "--load=${CMake_CLANG_TIDY_MODULE}") + set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${CMake_CLANG_TIDY_MODULE}") + endif() + # Create a preprocessor definition that depends on .clang-tidy content so # the compile command will change when .clang-tidy changes. This ensures # that a subsequent build re-runs clang-tidy on all sources even if they @@ -286,6 +292,11 @@ if(CMake_RUN_CLANG_TIDY) file(SHA1 ${CMAKE_CURRENT_SOURCE_DIR}/.clang-tidy clang_tidy_sha1) set(CLANG_TIDY_DEFINITIONS "CLANG_TIDY_SHA1=${clang_tidy_sha1}") unset(clang_tidy_sha1) + if(CMake_USE_CLANG_TIDY_MODULE) + file(SHA1 "${CMake_CLANG_TIDY_MODULE}" clang_tidy_module_sha1) + list(APPEND CLANG_TIDY_DEFINITIONS "CLANG_TIDY_MODULE_SHA1=${clang_tidy_module_sha1}") + unset(clang_tidy_module_sha1) + endif() endif() configure_file(.clang-tidy .clang-tidy COPYONLY) diff --git a/Help/guide/tutorial/Adding Support for a Testing Dashboard.rst b/Help/guide/tutorial/Adding Support for a Testing Dashboard.rst index 45d5976..787e777 100644 --- a/Help/guide/tutorial/Adding Support for a Testing Dashboard.rst +++ b/Help/guide/tutorial/Adding Support for a Testing Dashboard.rst @@ -4,33 +4,40 @@ Step 6: Adding Support for a Testing Dashboard Adding support for submitting our test results to a dashboard is simple. We already defined a number of tests for our project in :ref:`Testing Support <Tutorial Testing Support>`. Now we just have to run -those tests and submit them to a dashboard. To include support for dashboards -we include the :module:`CTest` module in our top-level ``CMakeLists.txt``. +those tests and submit them to CDash. -Replace: -.. literalinclude:: Step6/CMakeLists.txt - :caption: CMakeLists.txt - :name: CMakeLists.txt-enable_testing-remove - :language: cmake - :start-after: # enable testing - :end-before: # does the application run +Exercise 1 - Send Results to a Testing Dashboard +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -With: +Goal +---- -.. literalinclude:: Step7/CMakeLists.txt - :caption: CMakeLists.txt - :name: CMakeLists.txt-include-CTest - :language: cmake - :start-after: # enable testing - :end-before: # does the application run +Display our CTest results with CDash. + +Helpful Resources +----------------- + +* :manual:`ctest(1)` +* :command:`include` +* :module:`CTest` + +Files to Edit +------------- -The :module:`CTest` module will automatically call ``enable_testing()``, so we -can remove it from our CMake files. +* ``CMakeLists.txt`` + +Getting Started +--------------- + +For this exercise, complete ``TODO 1`` in the top-level ``CMakeLists.txt`` by +including the :module:`CTest` module. This will enable testing with CTest as +well as dashboard submissions to CDash, so we can safely remove the call to +:command:`enable_testing`. We will also need to acquire a ``CTestConfig.cmake`` file to be placed in the -top-level directory where we can specify information to CTest about the -project. It contains: +top-level directory. When run, the :manual:`ctest <ctest(1)>` executable will +read this file to gather information about the testing dashboard. It contains: * The project name @@ -41,9 +48,10 @@ project. It contains: * The URL of the CDash instance where the submission's generated documents will be sent -One has been provided for you in this directory. It would normally be -downloaded from the ``Settings`` page of the project on the CDash -instance that will host and display the test results. Once downloaded from +For this tutorial, a public dashboard server is used and its corresponding +``CTestConfig.cmake`` file is provided for you in this step's root directory. +In practice, this file would be downloaded from a project's ``Settings`` page +on the CDash instance intended to host the test results. Once downloaded from CDash, the file should not be modified locally. .. literalinclude:: Step7/CTestConfig.cmake @@ -51,11 +59,16 @@ CDash, the file should not be modified locally. :name: CTestConfig.cmake :language: cmake -The :manual:`ctest <ctest(1)>` executable will read in this file when it runs. -To create a simple dashboard you can run the :manual:`cmake <cmake(1)>` -executable or the :manual:`cmake-gui <cmake-gui(1)>` to configure the project, -but do not build it yet. Instead, change directory to the binary tree, and then -run: + +Build and Run +------------- + +Note that as part of the CDash submission some information about your +development system (e.g. site name or full pathnames) may displayed publicly. + +To create a simple test dashboard, run the :manual:`cmake <cmake(1)>` +executable or the :manual:`cmake-gui <cmake-gui(1)>` to configure the project +but do not build it yet. Instead, navigate to the build directory and run: .. code-block:: console @@ -70,6 +83,28 @@ type must be specified: Or, from an IDE, build the ``Experimental`` target. -The :manual:`ctest <ctest(1)>` executable will build and test the project and -submit the results to Kitware's public dashboard: +The :manual:`ctest <ctest(1)>` executable will build the project, run any +tests, and submit the results to Kitware's public dashboard: https://my.cdash.org/index.php?project=CMakeTutorial. + +Solution +-------- + +The only CMake code changed needed in this step was to enable dashboard +submissions to CDash by including the :module:`CTest` module in our top-level +``CMakeLists.txt``: + +.. raw:: html + + <details><summary>TODO 1: Click to show/hide answer</summary> + +.. literalinclude:: Step7/CMakeLists.txt + :caption: TODO 1: CMakeLists.txt + :name: CMakeLists.txt-include-CTest + :language: cmake + :start-after: # enable testing + :end-before: # does the application run + +.. raw:: html + + </details> diff --git a/Help/guide/tutorial/Step6/CMakeLists.txt b/Help/guide/tutorial/Step6/CMakeLists.txt index da9e852..c11e307 100644 --- a/Help/guide/tutorial/Step6/CMakeLists.txt +++ b/Help/guide/tutorial/Step6/CMakeLists.txt @@ -45,6 +45,7 @@ install(FILES "${PROJECT_BINARY_DIR}/TutorialConfig.h" DESTINATION include ) +# TODO 1: Replace enable_testing() with include(CTest) # enable testing enable_testing() diff --git a/Help/prop_tgt/CONFIG_POSTFIX.rst b/Help/prop_tgt/CONFIG_POSTFIX.rst index 5c2fbd7..69caa39 100644 --- a/Help/prop_tgt/CONFIG_POSTFIX.rst +++ b/Help/prop_tgt/CONFIG_POSTFIX.rst @@ -1,13 +1,13 @@ <CONFIG>_POSTFIX ---------------- -Postfix to append to the target file name for configuration <CONFIG>. +Postfix to append to the target file name for configuration ``<CONFIG>``. -When building with configuration <CONFIG> the value of this property +When building with configuration ``<CONFIG>`` the value of this property is appended to the target file name built on disk. For non-executable -targets, this property is initialized by the value of the variable -CMAKE_<CONFIG>_POSTFIX if it is set when a target is created. This -property is ignored on the Mac for Frameworks and App Bundles. +targets, this property is initialized by the value of the +:variable:`CMAKE_<CONFIG>_POSTFIX` variable if it is set when a target is +created. This property is ignored on macOS for Frameworks and App Bundles. For macOS see also the :prop_tgt:`FRAMEWORK_MULTI_CONFIG_POSTFIX_<CONFIG>` target property. diff --git a/Help/release/dev/0-sample-topic.rst b/Help/release/dev/0-sample-topic.rst new file mode 100644 index 0000000..e4cc01e --- /dev/null +++ b/Help/release/dev/0-sample-topic.rst @@ -0,0 +1,7 @@ +0-sample-topic +-------------- + +* This is a sample release note for the change in a topic. + Developers should add similar notes for each topic branch + making a noteworthy change. Each document should be named + and titled to match the topic name to avoid merge conflicts. diff --git a/Help/release/dev/UseSWIG-perl5.rst b/Help/release/dev/UseSWIG-perl5.rst new file mode 100644 index 0000000..67d4161 --- /dev/null +++ b/Help/release/dev/UseSWIG-perl5.rst @@ -0,0 +1,4 @@ +UseSWIG-perl5 +------------- + +* The :module:`UseSWIG` module gained the support of ``perl5`` language. diff --git a/Help/release/dev/trace-try_compile.rst b/Help/release/dev/trace-try_compile.rst new file mode 100644 index 0000000..886aaad --- /dev/null +++ b/Help/release/dev/trace-try_compile.rst @@ -0,0 +1,5 @@ +trace-try_compile +----------------- + +* The :option:`cmake --trace` option now follows :command:`try_compile` and + :command:`try_run` invocations. diff --git a/Help/release/index.rst b/Help/release/index.rst index b6ecf7b..50e06bb 100644 --- a/Help/release/index.rst +++ b/Help/release/index.rst @@ -7,6 +7,8 @@ CMake Release Notes This file should include the adjacent "dev.txt" file in development versions but not in release versions. +.. include:: dev.txt + Releases ======== diff --git a/Modules/CMakeSwiftInformation.cmake b/Modules/CMakeSwiftInformation.cmake index 16726d2..a0cd9da 100644 --- a/Modules/CMakeSwiftInformation.cmake +++ b/Modules/CMakeSwiftInformation.cmake @@ -65,10 +65,22 @@ set(CMAKE_Swift_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDLL -libc MD) set(CMAKE_Swift_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDebug -libc MTd) set(CMAKE_Swift_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDebugDLL -libc MDd) -set(CMAKE_Swift_FLAGS_DEBUG_INIT "-Onone -g") -set(CMAKE_Swift_FLAGS_RELEASE_INIT "-O") -set(CMAKE_Swift_FLAGS_RELWITHDEBINFO_INIT "-O -g") -set(CMAKE_Swift_FLAGS_MINSIZEREL_INIT "-Osize") +if(CMAKE_GENERATOR STREQUAL "Xcode") + # Xcode has a separate Xcode project option (SWIFT_COMPILATION_MODE) used to set + # whether compiling with whole-module optimizations or incrementally. Setting + # these options here will have no effect when compiling with the built-in driver, + # and will explode violently, leaving build products in the source directory, when + # using the old swift driver. + set(CMAKE_Swift_FLAGS_DEBUG_INIT "-Onone -g") + set(CMAKE_Swift_FLAGS_RELEASE_INIT "-O") + set(CMAKE_Swift_FLAGS_RELWITHDEBINFO_INIT "-O -g") + set(CMAKE_Swift_FLAGS_MINSIZEREL_INIT "-Osize") +else() + set(CMAKE_Swift_FLAGS_DEBUG_INIT "-Onone -g -incremental") + set(CMAKE_Swift_FLAGS_RELEASE_INIT "-O -wmo") + set(CMAKE_Swift_FLAGS_RELWITHDEBINFO_INIT "-O -g -wmo") + set(CMAKE_Swift_FLAGS_MINSIZEREL_INIT "-Osize -wmo") +endif() if(CMAKE_EXECUTABLE_FORMAT STREQUAL "ELF") if(NOT DEFINED CMAKE_Swift_LINK_WHAT_YOU_USE_FLAG) @@ -91,7 +103,7 @@ if(NOT CMAKE_Swift_NUM_THREADS MATCHES "^[0-9]+$") endif() if(NOT CMAKE_Swift_CREATE_SHARED_LIBRARY) - set(CMAKE_Swift_CREATE_SHARED_LIBRARY "<CMAKE_Swift_COMPILER> -output-file-map <SWIFT_OUTPUT_FILE_MAP> -incremental -j ${CMAKE_Swift_NUM_THREADS} -emit-library -o <TARGET> -module-name <SWIFT_MODULE_NAME> -module-link-name <SWIFT_LIBRARY_NAME> -emit-module -emit-module-path <SWIFT_MODULE> -emit-dependencies <DEFINES> <FLAGS> <INCLUDES> <SWIFT_SOURCES> <LINK_FLAGS> <SONAME_FLAG> <TARGET_INSTALLNAME_DIR><TARGET_SONAME> ${CMAKE_Swift_IMPLIB_LINKER_FLAGS} <LINK_LIBRARIES>") + set(CMAKE_Swift_CREATE_SHARED_LIBRARY "<CMAKE_Swift_COMPILER> -output-file-map <SWIFT_OUTPUT_FILE_MAP> -j ${CMAKE_Swift_NUM_THREADS} -num-threads ${CMAKE_Swift_NUM_THREADS} -emit-library -o <TARGET> -module-name <SWIFT_MODULE_NAME> -module-link-name <SWIFT_LIBRARY_NAME> -emit-module -emit-module-path <SWIFT_MODULE> -emit-dependencies <DEFINES> <FLAGS> <INCLUDES> <SWIFT_SOURCES> <LINK_FLAGS> <SONAME_FLAG> <TARGET_INSTALLNAME_DIR><TARGET_SONAME> ${CMAKE_Swift_IMPLIB_LINKER_FLAGS} <LINK_LIBRARIES>") endif() if(NOT CMAKE_Swift_CREATE_SHARED_MODULE) @@ -99,11 +111,11 @@ if(NOT CMAKE_Swift_CREATE_SHARED_MODULE) endif() if(NOT CMAKE_Swift_LINK_EXECUTABLE) - set(CMAKE_Swift_LINK_EXECUTABLE "<CMAKE_Swift_COMPILER> -output-file-map <SWIFT_OUTPUT_FILE_MAP> -incremental -j ${CMAKE_Swift_NUM_THREADS} -emit-executable -o <TARGET> -emit-dependencies <DEFINES> <FLAGS> <INCLUDES> <SWIFT_SOURCES> <LINK_FLAGS> <LINK_LIBRARIES>") + set(CMAKE_Swift_LINK_EXECUTABLE "<CMAKE_Swift_COMPILER> -output-file-map <SWIFT_OUTPUT_FILE_MAP> -j ${CMAKE_Swift_NUM_THREADS} -num-threads ${CMAKE_Swift_NUM_THREADS} -emit-executable -o <TARGET> -emit-dependencies <DEFINES> <FLAGS> <INCLUDES> <SWIFT_SOURCES> <LINK_FLAGS> <LINK_LIBRARIES>") endif() if(NOT CMAKE_Swift_CREATE_STATIC_LIBRARY) - set(CMAKE_Swift_CREATE_STATIC_LIBRARY "<CMAKE_Swift_COMPILER> -output-file-map <SWIFT_OUTPUT_FILE_MAP> -incremental -j ${CMAKE_Swift_NUM_THREADS} -emit-library -static -o <TARGET> -module-name <SWIFT_MODULE_NAME> -module-link-name <SWIFT_LIBRARY_NAME> -emit-module -emit-module-path <SWIFT_MODULE> -emit-dependencies <DEFINES> <FLAGS> <INCLUDES> <SWIFT_SOURCES> <LINK_FLAGS> <LINK_LIBRARIES>") + set(CMAKE_Swift_CREATE_STATIC_LIBRARY "<CMAKE_Swift_COMPILER> -output-file-map <SWIFT_OUTPUT_FILE_MAP> -j ${CMAKE_Swift_NUM_THREADS} -num-threads ${CMAKE_Swift_NUM_THREADS} -emit-library -static -o <TARGET> -module-name <SWIFT_MODULE_NAME> -module-link-name <SWIFT_LIBRARY_NAME> -emit-module -emit-module-path <SWIFT_MODULE> -emit-dependencies <DEFINES> <FLAGS> <INCLUDES> <SWIFT_SOURCES> <LINK_FLAGS> <LINK_LIBRARIES>") set(CMAKE_Swift_ARCHIVE_CREATE "<CMAKE_AR> crs <TARGET> <OBJECTS>") set(CMAKE_Swift_ARCHIVE_FINISH "") diff --git a/Modules/ExternalProject.cmake b/Modules/ExternalProject.cmake index 22a25bd..141b185 100644 --- a/Modules/ExternalProject.cmake +++ b/Modules/ExternalProject.cmake @@ -3642,7 +3642,7 @@ function(_ep_extract_configure_command var name) ) endif() - list(APPEND cmd "<SOURCE_DIR><SOURCE_SUBDIR>") + list(APPEND cmd -S "<SOURCE_DIR><SOURCE_SUBDIR>" -B "<BINARY_DIR>") endif() set("${var}" "${cmd}" PARENT_SCOPE) diff --git a/Modules/FindZLIB.cmake b/Modules/FindZLIB.cmake index be5c775..cfe6715 100644 --- a/Modules/FindZLIB.cmake +++ b/Modules/FindZLIB.cmake @@ -60,6 +60,14 @@ module where to look. #]=======================================================================] +if(ZLIB_FIND_COMPONENTS AND NOT ZLIB_FIND_QUIETLY) + message(AUTHOR_WARNING + "ZLIB does not provide any COMPONENTS. Calling\n" + " find_package(ZLIB COMPONENTS ...)\n" + "will always fail." + ) +endif() + set(_ZLIB_SEARCHES) # Search ZLIB_ROOT first if it is set. @@ -164,7 +172,8 @@ endif() include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) FIND_PACKAGE_HANDLE_STANDARD_ARGS(ZLIB REQUIRED_VARS ZLIB_LIBRARY ZLIB_INCLUDE_DIR - VERSION_VAR ZLIB_VERSION_STRING) + VERSION_VAR ZLIB_VERSION_STRING + HANDLE_COMPONENTS) if(ZLIB_FOUND) set(ZLIB_INCLUDE_DIRS ${ZLIB_INCLUDE_DIR}) diff --git a/Modules/Internal/CheckSourceCompiles.cmake b/Modules/Internal/CheckSourceCompiles.cmake index eadf3da..bf5a82d 100644 --- a/Modules/Internal/CheckSourceCompiles.cmake +++ b/Modules/Internal/CheckSourceCompiles.cmake @@ -9,7 +9,7 @@ cmake_policy(SET CMP0057 NEW) # if() supports IN_LIST function(CMAKE_CHECK_SOURCE_COMPILES _lang _source _var) if(NOT DEFINED "${_var}") - + set(_lang_filename "src") if(_lang STREQUAL "C") set(_lang_textual "C") set(_lang_ext "c") @@ -34,6 +34,13 @@ function(CMAKE_CHECK_SOURCE_COMPILES _lang _source _var) elseif(_lang STREQUAL "OBJCXX") set(_lang_textual "Objective-C++") set(_lang_ext "mm") + elseif(_lang STREQUAL "Swift") + set(_lang_textual "Swift") + set(_lang_ext "swift") + if (NOT DEFINED CMAKE_TRY_COMPILE_TARGET_TYPE + OR CMAKE_TRY_COMPILE_TARGET_TYPE STREQUAL "EXECUTABLE") + set(_lang_filename "main") + endif() else() message (SEND_ERROR "check_source_compiles: ${_lang}: unknown language.") return() @@ -92,7 +99,7 @@ function(CMAKE_CHECK_SOURCE_COMPILES _lang _source _var) endif() string(APPEND _source "\n") try_compile(${_var} - SOURCE_FROM_VAR "src.${_SRC_EXT}" _source + SOURCE_FROM_VAR "${_lang_filename}.${_SRC_EXT}" _source COMPILE_DEFINITIONS -D${_var} ${CMAKE_REQUIRED_DEFINITIONS} ${CHECK_${LANG}_SOURCE_COMPILES_ADD_LINK_OPTIONS} ${CHECK_${LANG}_SOURCE_COMPILES_ADD_LIBRARIES} diff --git a/Modules/UseSWIG.cmake b/Modules/UseSWIG.cmake index fd6596b..e0e01f5 100644 --- a/Modules/UseSWIG.cmake +++ b/Modules/UseSWIG.cmake @@ -378,6 +378,7 @@ set(SWIG_PYTHON_EXTRA_FILE_EXTENSIONS ".py") set(SWIG_JAVA_EXTRA_FILE_EXTENSIONS ".java" "JNI.java") set(SWIG_CSHARP_EXTRA_FILE_EXTENSIONS ".cs" "PINVOKE.cs") set(SWIG_PERL_EXTRA_FILE_EXTENSIONS ".pm") +set(SWIG_PERL5_EXTRA_FILE_EXTENSIONS ".pm") set(SWIG_MANAGE_SUPPORT_FILES_SCRIPT "${CMAKE_CURRENT_LIST_DIR}/UseSWIG/ManageSupportFiles.cmake") @@ -414,8 +415,8 @@ macro(SWIG_MODULE_INITIALIZE name language) endif() if(SWIG_MODULE_${name}_LANGUAGE STREQUAL "UNKNOWN") message(FATAL_ERROR "SWIG Error: Language \"${language}\" not found") - elseif(SWIG_MODULE_${name}_LANGUAGE STREQUAL "PERL" AND - NOT "-shadow" IN_LIST SWIG_MODULE_${name}_EXTRA_FLAGS) + elseif((SWIG_MODULE_${name}_LANGUAGE STREQUAL "PERL" OR SWIG_MODULE_${name}_LANGUAGE STREQUAL "PERL5") + AND NOT "-shadow" IN_LIST SWIG_MODULE_${name}_EXTRA_FLAGS) list(APPEND SWIG_MODULE_${name}_EXTRA_FLAGS "-shadow") endif() endmacro() @@ -971,7 +972,7 @@ function(SWIG_ADD_LIBRARY name) if (APPLE) set_target_properties (${target_name} PROPERTIES SUFFIX ".bundle") endif () - elseif (swig_lowercase_language STREQUAL "perl") + elseif (swig_lowercase_language STREQUAL "perl" OR swig_lowercase_language STREQUAL "perl5") # assume empty prefix because we expect the module to be dynamically loaded set_target_properties (${target_name} PROPERTIES PREFIX "") if (APPLE) diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index c51f421..fa9b2b5 100644 --- a/Source/CMakeVersion.cmake +++ b/Source/CMakeVersion.cmake @@ -1,8 +1,8 @@ # CMake version number components. set(CMake_VERSION_MAJOR 3) set(CMake_VERSION_MINOR 25) -set(CMake_VERSION_PATCH 0) -set(CMake_VERSION_RC 2) +set(CMake_VERSION_PATCH 20221028) +#set(CMake_VERSION_RC 0) set(CMake_VERSION_IS_DIRTY 0) # Start with the full version number used in tags. It has no dev info. diff --git a/Source/CursesDialog/ccmake.cxx b/Source/CursesDialog/ccmake.cxx index 1f7776c..70ed648 100644 --- a/Source/CursesDialog/ccmake.cxx +++ b/Source/CursesDialog/ccmake.cxx @@ -77,7 +77,7 @@ int main(int argc, char const* const* argv) cmDocumentation doc; doc.addCMakeStandardDocSections(); if (doc.CheckOptions(argc, argv)) { - cmake hcm(cmake::RoleInternal, cmState::Unknown); + cmake hcm(cmake::RoleInternal, cmState::Help); hcm.SetHomeDirectory(""); hcm.SetHomeOutputDirectory(""); hcm.AddCMakePaths(); diff --git a/Source/QtDialog/CMakeSetup.cxx b/Source/QtDialog/CMakeSetup.cxx index fb12b7d..591b793 100644 --- a/Source/QtDialog/CMakeSetup.cxx +++ b/Source/QtDialog/CMakeSetup.cxx @@ -79,7 +79,7 @@ int main(int argc, char** argv) doc.addCMakeStandardDocSections(); if (argc2 > 1 && doc.CheckOptions(argc2, argv2)) { // Construct and print requested documentation. - cmake hcm(cmake::RoleInternal, cmState::Unknown); + cmake hcm(cmake::RoleInternal, cmState::Help); hcm.SetHomeDirectory(""); hcm.SetHomeOutputDirectory(""); hcm.AddCMakePaths(); diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx index 50bc78c..2c61163 100644 --- a/Source/cmExportFileGenerator.cxx +++ b/Source/cmExportFileGenerator.cxx @@ -939,13 +939,13 @@ void cmExportFileGenerator::GeneratePolicyHeaderCode(std::ostream& os) // Isolate the file policy level. // Support CMake versions as far back as 2.6 but also support using NEW - // policy settings for up to CMake 3.23 (this upper limit may be reviewed + // policy settings for up to CMake 3.24 (this upper limit may be reviewed // and increased from time to time). This reduces the opportunity for CMake // warnings when an older export file is later used with newer CMake // versions. /* clang-format off */ os << "cmake_policy(PUSH)\n" - << "cmake_policy(VERSION 2.8.3...3.23)\n"; + << "cmake_policy(VERSION 2.8.3...3.24)\n"; /* clang-format on */ } diff --git a/Source/cmFindPackageCommand.cxx b/Source/cmFindPackageCommand.cxx index 3f8378b..60b0a7b 100644 --- a/Source/cmFindPackageCommand.cxx +++ b/Source/cmFindPackageCommand.cxx @@ -377,6 +377,8 @@ private: # pragma diag_suppress 1222 // invalid error number (3288, but works anyway) # define CM_LCC_DIAG_SUPPRESS_3288 # pragma diag_suppress 3288 // parameter was declared but never referenced +# define CM_LCC_DIAG_SUPPRESS_3301 +# pragma diag_suppress 3301 // parameter was declared but never referenced #endif void ResetGenerator() @@ -421,6 +423,11 @@ bool TryGeneratedPaths(CallbackFn&& filesCollector, return false; } +#ifdef CM_LCC_DIAG_SUPPRESS_3301 +# undef CM_LCC_DIAG_SUPPRESS_3301 +# pragma diag_default 3301 +#endif + #ifdef CM_LCC_DIAG_SUPPRESS_3288 # undef CM_LCC_DIAG_SUPPRESS_3288 # pragma diag_default 3288 diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index 6195d1f..321122a 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -5532,7 +5532,7 @@ cmGeneratorTarget::GetTargetSourceFileFlags(const cmSourceFile* sf) const } else if (cmHasLiteralPrefix(*location, "Resources/")) { flags.Type = cmGeneratorTarget::SourceFileTypeDeepResource; if (stripResources) { - flags.MacFolder += strlen("Resources/"); + flags.MacFolder += cmStrLen("Resources/"); } } else { flags.Type = cmGeneratorTarget::SourceFileTypeMacContent; diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx index dd470f8..6cba943 100644 --- a/Source/cmGlobalXCodeGenerator.cxx +++ b/Source/cmGlobalXCodeGenerator.cxx @@ -4407,12 +4407,20 @@ bool cmGlobalXCodeGenerator::CreateXCodeObjects( buildSettings->AddAttribute("CODE_SIGNING_ALLOWED", this->CreateString("NO")); } + auto debugConfigs = this->GetCMakeInstance()->GetDebugConfigs(); + std::set<std::string> debugConfigSet(debugConfigs.begin(), + debugConfigs.end()); for (auto& config : configs) { CreateGlobalXCConfigSettings(root, config.second, config.first); cmXCodeObject* buildSettingsForCfg = this->CreateFlatClone(buildSettings); + if (debugConfigSet.count(cmSystemTools::UpperCase(config.first)) == 0) { + buildSettingsForCfg->AddAttribute("SWIFT_COMPILATION_MODE", + this->CreateString("wholemodule")); + } + // Put this last so it can override existing settings // Convert "CMAKE_XCODE_ATTRIBUTE_*" variables directly. for (const auto& var : this->CurrentMakefile->GetDefinitions()) { diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index 6e0d704..90a38be 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -3584,6 +3584,9 @@ int cmMakefile::TryCompile(const std::string& srcdir, gg->RecursionDepth = this->RecursionDepth; cm.SetGlobalGenerator(std::move(gg)); + // copy trace state + cm.SetTraceRedirect(this->GetCMakeInstance()); + // do a configure cm.SetHomeDirectory(srcdir); cm.SetHomeOutputDirectory(bindir); @@ -4470,12 +4473,12 @@ bool cmMakefile::SetPolicy(cmPolicies::PolicyID id, } // Deprecate old policies. - if (status == cmPolicies::OLD && id <= cmPolicies::CMP0102 && + if (status == cmPolicies::OLD && id <= cmPolicies::CMP0108 && !(this->GetCMakeInstance()->GetIsInTryCompile() && ( // Policies set by cmCoreTryCompile::TryCompileCode. id == cmPolicies::CMP0065 || id == cmPolicies::CMP0083 || - id == cmPolicies::CMP0091)) && + id == cmPolicies::CMP0091 || id == cmPolicies::CMP0104)) && (!this->IsSet("CMAKE_WARN_DEPRECATED") || this->IsOn("CMAKE_WARN_DEPRECATED"))) { this->IssueMessage(MessageType::DEPRECATION_WARNING, diff --git a/Source/cmState.cxx b/Source/cmState.cxx index 3d38e73..17ee7f3 100644 --- a/Source/cmState.cxx +++ b/Source/cmState.cxx @@ -786,6 +786,8 @@ std::string cmState::ModeToString(cmState::Mode mode) return "CTEST"; case CPack: return "CPACK"; + case Help: + return "HELP"; case Unknown: return "UNKNOWN"; } diff --git a/Source/cmState.h b/Source/cmState.h index 2d0c521..9a17b22 100644 --- a/Source/cmState.h +++ b/Source/cmState.h @@ -53,6 +53,7 @@ public: FindPackage, CTest, CPack, + Help }; enum class ProjectKind diff --git a/Source/cmake.cxx b/Source/cmake.cxx index 013a87b..c068894 100644 --- a/Source/cmake.cxx +++ b/Source/cmake.cxx @@ -196,7 +196,7 @@ cmake::cmake(Role role, cmState::Mode mode, cmState::ProjectKind projectKind) this->AddProjectCommands(); } - if (mode == cmState::Project) { + if (mode == cmState::Project || mode == cmState::Help) { this->LoadEnvironmentPresets(); } @@ -1542,6 +1542,16 @@ void cmake::PrintTraceFormatVersion() } } +void cmake::SetTraceRedirect(cmake* other) +{ + this->Trace = other->Trace; + this->TraceExpand = other->TraceExpand; + this->TraceFormatVar = other->TraceFormatVar; + this->TraceOnlyThisSources = other->TraceOnlyThisSources; + + this->TraceRedirect = other; +} + bool cmake::SetDirectoriesFromFile(const std::string& arg) { // Check if the argument refers to a CMakeCache.txt or diff --git a/Source/cmake.h b/Source/cmake.h index 3183577..4e7bb54 100644 --- a/Source/cmake.h +++ b/Source/cmake.h @@ -513,10 +513,19 @@ public: { return this->TraceOnlyThisSources; } - cmGeneratedFileStream& GetTraceFile() { return this->TraceFile; } + cmGeneratedFileStream& GetTraceFile() + { + if (this->TraceRedirect) { + return this->TraceRedirect->GetTraceFile(); + } + return this->TraceFile; + } void SetTraceFile(std::string const& file); void PrintTraceFormatVersion(); + //! Use trace from another ::cmake instance. + void SetTraceRedirect(cmake* other); + bool GetWarnUninitialized() const { return this->WarnUninitialized; } void SetWarnUninitialized(bool b) { this->WarnUninitialized = b; } bool GetWarnUnusedCli() const { return this->WarnUnusedCli; } @@ -688,6 +697,7 @@ private: bool TraceExpand = false; TraceFormat TraceFormatVar = TRACE_HUMAN; cmGeneratedFileStream TraceFile; + cmake* TraceRedirect = nullptr; bool WarnUninitialized = false; bool WarnUnusedCli = true; bool CheckSystemVars = false; diff --git a/Source/cmakemain.cxx b/Source/cmakemain.cxx index 723932e..43bebc1 100644 --- a/Source/cmakemain.cxx +++ b/Source/cmakemain.cxx @@ -208,7 +208,7 @@ int do_cmake(int ac, char const* const* av) doc.addCMakeStandardDocSections(); if (doc.CheckOptions(ac, av, "--")) { // Construct and print requested documentation. - cmake hcm(cmake::RoleInternal, cmState::Unknown); + cmake hcm(cmake::RoleInternal, cmState::Help); hcm.SetHomeDirectory(""); hcm.SetHomeOutputDirectory(""); hcm.AddCMakePaths(); diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index 6e35df9..850e743 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -271,14 +271,6 @@ if(BUILD_TESTING) find_package(Qt5Widgets QUIET NO_MODULE) endif() - if(NOT CMake_TEST_EXTERNAL_CMAKE) - add_subdirectory(CMakeLib) - endif() - add_subdirectory(CMakeOnly) - add_subdirectory(RunCMake) - - add_subdirectory(FindPackageModeMakefileTest) - # Collect a list of all test build directories. set(TEST_BUILD_DIRS) @@ -342,6 +334,21 @@ if(BUILD_TESTING) endif() endif() + if(CMake_TEST_XCODE_VERSION AND CMAKE_OSX_SDKVERSION AND CMAKE_OSX_SDKPRODUCT) + if((NOT CMake_TEST_XCODE_VERSION VERSION_LESS 6.1) AND + ((NOT CMAKE_OSX_SDKPRODUCT STREQUAL "Mac OS X") OR + (NOT CMAKE_OSX_SDKVERSION VERSION_LESS 10.10))) + if(CMAKE_GENERATOR STREQUAL "Xcode") + set(CMake_TEST_XCODE_SWIFT 1) + endif() + endif() + endif() + if(NOT DEFINED CMake_TEST_Swift) + if(CMAKE_Swift_COMPILER OR CMake_TEST_XCODE_SWIFT) + set(CMake_TEST_Swift 1) + endif() + endif() + # Use 1500 or CTEST_TEST_TIMEOUT for long test timeout value, # whichever is greater. set(CMAKE_LONG_TEST_TIMEOUT 1500) @@ -352,6 +359,14 @@ if(BUILD_TESTING) set(CMAKE_LONG_TEST_TIMEOUT 1500) endif() + if(NOT CMake_TEST_EXTERNAL_CMAKE) + add_subdirectory(CMakeLib) + endif() + add_subdirectory(CMakeOnly) + add_subdirectory(RunCMake) + + add_subdirectory(FindPackageModeMakefileTest) + add_test(NAME CMake.Copyright COMMAND ${CMAKE_CMAKE_COMMAND} -P ${CMAKE_CURRENT_SOURCE_DIR}/CMakeCopyright.cmake) @@ -380,16 +395,7 @@ if(BUILD_TESTING) ADD_TEST_MACRO(MissingSourceFile MissingSourceFile) set_tests_properties(MissingSourceFile PROPERTIES PASS_REGULAR_EXPRESSION "CMake Error at CMakeLists.txt:3 \\(add_executable\\):[ \r\n]*Cannot find source file:[ \r\n]*DoesNotExist/MissingSourceFile.c") - if(CMake_TEST_XCODE_VERSION AND CMAKE_OSX_SDKVERSION AND CMAKE_OSX_SDKPRODUCT) - if((NOT CMake_TEST_XCODE_VERSION VERSION_LESS 6.1) AND - ((NOT CMAKE_OSX_SDKPRODUCT STREQUAL "Mac OS X") OR - (NOT CMAKE_OSX_SDKVERSION VERSION_LESS 10.10))) - if(CMAKE_GENERATOR STREQUAL "Xcode") - set(CMake_TEST_XCODE_SWIFT 1) - endif() - endif() - endif() - if(CMAKE_Swift_COMPILER OR CMake_TEST_XCODE_SWIFT) + if(CMake_TEST_Swift) ADD_TEST_MACRO(SwiftOnly SwiftOnly) if(CMake_TEST_XCODE_SWIFT) ADD_TEST_MACRO(SwiftMix SwiftMix) diff --git a/Tests/CheckSourceTree/check.cmake b/Tests/CheckSourceTree/check.cmake index c2e3529..a59ffb5 100644 --- a/Tests/CheckSourceTree/check.cmake +++ b/Tests/CheckSourceTree/check.cmake @@ -3,6 +3,13 @@ if(DEFINED ENV{CTEST_REAL_HOME}) set(ENV{HOME} "$ENV{CTEST_REAL_HOME}") endif() +file(GLOB known_files + "${CMake_SOURCE_DIR}/Tests/JavaExportImport/InstallExport/hs_err_pid*.log" + ) +if(known_files) + file(REMOVE ${known_files}) +endif() + execute_process( COMMAND "${GIT_EXECUTABLE}" status WORKING_DIRECTORY "${CMake_SOURCE_DIR}" diff --git a/Tests/RunCMake/CMP0104/CMP0104-OLD-stderr.txt b/Tests/RunCMake/CMP0104/CMP0104-OLD-stderr.txt new file mode 100644 index 0000000..66d3016 --- /dev/null +++ b/Tests/RunCMake/CMP0104/CMP0104-OLD-stderr.txt @@ -0,0 +1,10 @@ +^CMake Deprecation Warning at CMP0104-OLD.cmake:[0-9]+ \(cmake_policy\): + The OLD behavior for policy CMP0104 will be removed from a future version + of CMake. + + The cmake-policies\(7\) manual explains that the OLD behaviors of all + policies are deprecated and that a policy should be set to OLD only under + specific short-term circumstances. Projects should be ported to the NEW + behavior and not rely on setting a policy to OLD. +Call Stack \(most recent call first\): + CMakeLists.txt:[0-9]+ \(include\)$ diff --git a/Tests/RunCMake/CMP0106/CMP0106-OLD-stderr.txt b/Tests/RunCMake/CMP0106/CMP0106-OLD-stderr.txt new file mode 100644 index 0000000..ef48d5c --- /dev/null +++ b/Tests/RunCMake/CMP0106/CMP0106-OLD-stderr.txt @@ -0,0 +1,10 @@ +^CMake Deprecation Warning at CMP0106-OLD.cmake:[0-9]+ \(cmake_policy\): + The OLD behavior for policy CMP0106 will be removed from a future version + of CMake. + + The cmake-policies\(7\) manual explains that the OLD behaviors of all + policies are deprecated and that a policy should be set to OLD only under + specific short-term circumstances. Projects should be ported to the NEW + behavior and not rely on setting a policy to OLD. +Call Stack \(most recent call first\): + CMakeLists.txt:[0-9]+ \(include\)$ diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt index 6c5ab7f..3f92829 100644 --- a/Tests/RunCMake/CMakeLists.txt +++ b/Tests/RunCMake/CMakeLists.txt @@ -752,7 +752,8 @@ add_RunCMake_test(CheckCompilerFlag -DCMake_TEST_CUDA=${CMake_TEST_CUDA} add_RunCMake_test(CheckSourceCompiles -DCMake_TEST_CUDA=${CMake_TEST_CUDA} -DCMake_TEST_ISPC=${CMake_TEST_ISPC} -DCMAKE_Fortran_COMPILER_ID=${CMAKE_Fortran_COMPILER_ID} - -DCMake_TEST_HIP=${CMake_TEST_HIP}) + -DCMake_TEST_HIP=${CMake_TEST_HIP} + -DCMake_TEST_Swift=${CMake_TEST_Swift}) add_RunCMake_test(CheckSourceRuns -DCMake_TEST_CUDA=${CMake_TEST_CUDA} -DCMAKE_Fortran_COMPILER_ID=${CMAKE_Fortran_COMPILER_ID} -DCMake_TEST_HIP=${CMake_TEST_HIP}) diff --git a/Tests/RunCMake/CXXModules/RunCMakeTest.cmake b/Tests/RunCMake/CXXModules/RunCMakeTest.cmake index 3f17c1f..921fabd 100644 --- a/Tests/RunCMake/CXXModules/RunCMakeTest.cmake +++ b/Tests/RunCMake/CXXModules/RunCMakeTest.cmake @@ -120,7 +120,9 @@ function (run_cxx_module_test directory) if (RunCMake_CXXModules_INSTALL) run_cmake_command("examples/${test_name}-install" "${CMAKE_COMMAND}" --build . --target install --config Debug) endif () - run_cmake_command("examples/${test_name}-test" "${CMAKE_CTEST_COMMAND}" -C Debug --output-on-failure) + if (NOT RunCMake_CXXModules_NO_TEST) + run_cmake_command("examples/${test_name}-test" "${CMAKE_CTEST_COMMAND}" -C Debug --output-on-failure) + endif () endfunction () string(REPLACE "," ";" CMake_TEST_MODULE_COMPILATION "${CMake_TEST_MODULE_COMPILATION}") @@ -132,6 +134,10 @@ if ("named" IN_LIST CMake_TEST_MODULE_COMPILATION) run_cxx_module_test(generated) run_cxx_module_test(public-req-private) run_cxx_module_test(deep-chain) + run_cxx_module_test(duplicate) + set(RunCMake_CXXModules_NO_TEST 1) + run_cxx_module_test(circular) + unset(RunCMake_CXXModules_NO_TEST) endif () # Tests which use named modules in shared libraries. diff --git a/Tests/RunCMake/CXXModules/examples/circular-build-result.txt b/Tests/RunCMake/CXXModules/examples/circular-build-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CXXModules/examples/circular-build-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CXXModules/examples/circular-build-stdout.txt b/Tests/RunCMake/CXXModules/examples/circular-build-stdout.txt new file mode 100644 index 0000000..433b461 --- /dev/null +++ b/Tests/RunCMake/CXXModules/examples/circular-build-stdout.txt @@ -0,0 +1 @@ +(Ninja generators)?(build stopped: dependency cycle:) diff --git a/Tests/RunCMake/CXXModules/examples/circular-stderr.txt b/Tests/RunCMake/CXXModules/examples/circular-stderr.txt new file mode 100644 index 0000000..5e4392a --- /dev/null +++ b/Tests/RunCMake/CXXModules/examples/circular-stderr.txt @@ -0,0 +1,9 @@ +CMake Warning \(dev\) at CMakeLists.txt:7 \(target_sources\): + CMake's C\+\+ module support is experimental. It is meant only for + experimentation and feedback to CMake developers. +This warning is for project developers. Use -Wno-dev to suppress it. + +CMake Warning \(dev\): + C\+\+20 modules support via CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP is + experimental. It is meant only for compiler developers to try. +This warning is for project developers. Use -Wno-dev to suppress it. diff --git a/Tests/RunCMake/CXXModules/examples/circular/CMakeLists.txt b/Tests/RunCMake/CXXModules/examples/circular/CMakeLists.txt new file mode 100644 index 0000000..4d1997c --- /dev/null +++ b/Tests/RunCMake/CXXModules/examples/circular/CMakeLists.txt @@ -0,0 +1,15 @@ +cmake_minimum_required(VERSION 3.24) +project(cxx_modules_circular CXX) + +include("${CMAKE_SOURCE_DIR}/../cxx-modules-rules.cmake") + +add_library(circular STATIC) +target_sources(circular + PUBLIC + FILE_SET CXX_MODULES + BASE_DIRS + "${CMAKE_CURRENT_SOURCE_DIR}" + FILES + circular-a.cppm + circular-b.cppm) +target_compile_features(circular PUBLIC cxx_std_20) diff --git a/Tests/RunCMake/CXXModules/examples/circular/circular-a.cppm b/Tests/RunCMake/CXXModules/examples/circular/circular-a.cppm new file mode 100644 index 0000000..eea842b --- /dev/null +++ b/Tests/RunCMake/CXXModules/examples/circular/circular-a.cppm @@ -0,0 +1,6 @@ +export module a; +import b; + +export int a() { + return b(); +} diff --git a/Tests/RunCMake/CXXModules/examples/circular/circular-b.cppm b/Tests/RunCMake/CXXModules/examples/circular/circular-b.cppm new file mode 100644 index 0000000..fc6dc42 --- /dev/null +++ b/Tests/RunCMake/CXXModules/examples/circular/circular-b.cppm @@ -0,0 +1,6 @@ +export module b; +import a; + +export int b() { + return a(); +} diff --git a/Tests/RunCMake/CXXModules/examples/duplicate-stderr.txt b/Tests/RunCMake/CXXModules/examples/duplicate-stderr.txt new file mode 100644 index 0000000..5e4392a --- /dev/null +++ b/Tests/RunCMake/CXXModules/examples/duplicate-stderr.txt @@ -0,0 +1,9 @@ +CMake Warning \(dev\) at CMakeLists.txt:7 \(target_sources\): + CMake's C\+\+ module support is experimental. It is meant only for + experimentation and feedback to CMake developers. +This warning is for project developers. Use -Wno-dev to suppress it. + +CMake Warning \(dev\): + C\+\+20 modules support via CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP is + experimental. It is meant only for compiler developers to try. +This warning is for project developers. Use -Wno-dev to suppress it. diff --git a/Tests/RunCMake/CXXModules/examples/duplicate/CMakeLists.txt b/Tests/RunCMake/CXXModules/examples/duplicate/CMakeLists.txt new file mode 100644 index 0000000..27be7a8 --- /dev/null +++ b/Tests/RunCMake/CXXModules/examples/duplicate/CMakeLists.txt @@ -0,0 +1,39 @@ +cmake_minimum_required(VERSION 3.24) +project(cxx_modules_duplicate CXX) + +include("${CMAKE_SOURCE_DIR}/../cxx-modules-rules.cmake") + +add_executable(duplicate) +target_sources(duplicate + PRIVATE + main.cxx + PRIVATE + FILE_SET CXX_MODULES + BASE_DIRS + "${CMAKE_CURRENT_SOURCE_DIR}" + FILES + duplicate.cxx) +target_compile_features(duplicate PRIVATE cxx_std_20) +target_compile_definitions(duplicate PRIVATE NDUPLICATE=1) + +add_executable(duplicate2) +target_sources(duplicate2 + PRIVATE + main.cxx + PRIVATE + FILE_SET CXX_MODULES + BASE_DIRS + "${CMAKE_CURRENT_SOURCE_DIR}" + FILES + duplicate.cxx) +target_compile_features(duplicate2 PRIVATE cxx_std_20) +target_compile_definitions(duplicate2 PRIVATE NDUPLICATE=2) + +add_test(NAME duplicate COMMAND duplicate) +set_property(TEST duplicate + PROPERTY + PASS_REGULAR_EXPRESSION "From duplicate #1") +add_test(NAME duplicate2 COMMAND duplicate2) +set_property(TEST duplicate2 + PROPERTY + PASS_REGULAR_EXPRESSION "From duplicate #2") diff --git a/Tests/RunCMake/CXXModules/examples/duplicate/duplicate.cxx b/Tests/RunCMake/CXXModules/examples/duplicate/duplicate.cxx new file mode 100644 index 0000000..c0c820b --- /dev/null +++ b/Tests/RunCMake/CXXModules/examples/duplicate/duplicate.cxx @@ -0,0 +1,11 @@ +module; + +#include <iostream> + +export module duplicate; + +export int from_import() +{ + std::cerr << "From duplicate #" << NDUPLICATE << std::endl; + return 0; +} diff --git a/Tests/RunCMake/CXXModules/examples/duplicate/main.cxx b/Tests/RunCMake/CXXModules/examples/duplicate/main.cxx new file mode 100644 index 0000000..c2c0636 --- /dev/null +++ b/Tests/RunCMake/CXXModules/examples/duplicate/main.cxx @@ -0,0 +1,6 @@ +import duplicate; + +int main(int argc, char* argv[]) +{ + return from_import(); +} diff --git a/Tests/RunCMake/CheckSourceCompiles/CheckSourceCompilesSwift.cmake b/Tests/RunCMake/CheckSourceCompiles/CheckSourceCompilesSwift.cmake new file mode 100644 index 0000000..767fa69 --- /dev/null +++ b/Tests/RunCMake/CheckSourceCompiles/CheckSourceCompilesSwift.cmake @@ -0,0 +1,15 @@ +enable_language(Swift) +include(CheckSourceCompiles) + +set(Swift 1) # test that this is tolerated + +check_source_compiles(Swift "baz()" SHOULD_FAIL) + +if(SHOULD_FAIL) + message(SEND_ERROR "invalid Swift source didn't fail.") +endif() + +check_source_compiles(Swift "print(\"Hello, CMake\")" SHOULD_BUILD) +if(NOT SHOULD_BUILD) + message(SEND_ERROR "Test failed for valid Swift source.") +endif() diff --git a/Tests/RunCMake/CheckSourceCompiles/RunCMakeTest.cmake b/Tests/RunCMake/CheckSourceCompiles/RunCMakeTest.cmake index df77d3d..2ed3e36 100644 --- a/Tests/RunCMake/CheckSourceCompiles/RunCMakeTest.cmake +++ b/Tests/RunCMake/CheckSourceCompiles/RunCMakeTest.cmake @@ -31,3 +31,7 @@ endif() if(CMake_TEST_HIP) run_cmake(CheckSourceCompilesHIP) endif() + +if(CMake_TEST_Swift) + run_cmake(CheckSourceCompilesSwift) +endif() diff --git a/Tests/RunCMake/CommandLine/Envgen-bad-help-stderr.txt b/Tests/RunCMake/CommandLine/Envgen-bad-help-stderr.txt new file mode 100644 index 0000000..cdfe857 --- /dev/null +++ b/Tests/RunCMake/CommandLine/Envgen-bad-help-stderr.txt @@ -0,0 +1 @@ +CMake Error: CMAKE_GENERATOR was set but the specified generator doesn't exist. Using CMake default. diff --git a/Tests/RunCMake/CommandLine/Envgen-bad-help-stdout.txt b/Tests/RunCMake/CommandLine/Envgen-bad-help-stdout.txt new file mode 100644 index 0000000..075c48c --- /dev/null +++ b/Tests/RunCMake/CommandLine/Envgen-bad-help-stdout.txt @@ -0,0 +1,2 @@ +Generators.* +\* (Unix Makefiles|Visual Studio).* diff --git a/Tests/RunCMake/CommandLine/Envgen-ninja-multi-help-stdout.txt b/Tests/RunCMake/CommandLine/Envgen-ninja-multi-help-stdout.txt new file mode 100644 index 0000000..ece6e5d --- /dev/null +++ b/Tests/RunCMake/CommandLine/Envgen-ninja-multi-help-stdout.txt @@ -0,0 +1 @@ +\* Ninja Multi-Config[ ]+= Generates build-<Config>.ninja files. diff --git a/Tests/RunCMake/CommandLine/RunCMakeTest.cmake b/Tests/RunCMake/CommandLine/RunCMakeTest.cmake index a2eeddf..327b772 100644 --- a/Tests/RunCMake/CommandLine/RunCMakeTest.cmake +++ b/Tests/RunCMake/CommandLine/RunCMakeTest.cmake @@ -349,6 +349,13 @@ function(run_EnvironmentGenerator) run_cmake_command(Envgen-bad ${CMAKE_COMMAND} -G) unset(ENV{CMAKE_GENERATOR}) + # Honor CMAKE_GENERATOR env var in --help output + set(ENV{CMAKE_GENERATOR} "Ninja Multi-Config") + run_cmake_command(Envgen-ninja-multi-help ${CMAKE_COMMAND} --help) + set(ENV{CMAKE_GENERATOR} "NoSuchGenerator") + run_cmake_command(Envgen-bad-help ${CMAKE_COMMAND} --help) + unset(ENV{CMAKE_GENERATOR}) + if(RunCMake_GENERATOR MATCHES "Visual Studio.*") set(ENV{CMAKE_GENERATOR} "${RunCMake_GENERATOR}") run_cmake_command(Envgen ${CMAKE_COMMAND} ${source_dir}) @@ -940,6 +947,7 @@ unset(RunCMake_TEST_OPTIONS) set(RunCMake_TEST_OPTIONS --trace) run_cmake(trace) +run_cmake(trace-try_compile) unset(RunCMake_TEST_OPTIONS) set(RunCMake_TEST_OPTIONS --trace-expand) @@ -952,6 +960,7 @@ unset(RunCMake_TEST_OPTIONS) set(RunCMake_TEST_OPTIONS --trace-redirect=${RunCMake_BINARY_DIR}/redirected.trace) run_cmake(trace-redirect) +run_cmake(trace-try_compile-redirect) unset(RunCMake_TEST_OPTIONS) set(RunCMake_TEST_OPTIONS --trace-redirect=/no/such/file.txt) diff --git a/Tests/RunCMake/CommandLine/trace-try_compile-redirect-check.cmake b/Tests/RunCMake/CommandLine/trace-try_compile-redirect-check.cmake new file mode 100644 index 0000000..94a7c95 --- /dev/null +++ b/Tests/RunCMake/CommandLine/trace-try_compile-redirect-check.cmake @@ -0,0 +1,13 @@ +file(READ ${RunCMake_SOURCE_DIR}/trace-try_compile-stderr.txt expected_content) +string(REGEX REPLACE "\n+$" "" expected_content "${expected_content}") + +file(READ ${RunCMake_BINARY_DIR}/redirected.trace actual_content) +string(REGEX REPLACE "\r\n" "\n" actual_content "${actual_content}") +string(REGEX REPLACE "\n+$" "" actual_content "${actual_content}") +if(NOT "${actual_content}" MATCHES "${expected_content}") + set(RunCMake_TEST_FAILED + "Trace file content does not match that expected." + "Expected to match:\n${expected_content}\n" + "Actual content:\n${actual_content}\n" + ) +endif() diff --git a/Tests/RunCMake/CommandLine/trace-try_compile-redirect.cmake b/Tests/RunCMake/CommandLine/trace-try_compile-redirect.cmake new file mode 100644 index 0000000..982cb89 --- /dev/null +++ b/Tests/RunCMake/CommandLine/trace-try_compile-redirect.cmake @@ -0,0 +1,2 @@ +cmake_minimum_required(VERSION 3.24) +project(test C) diff --git a/Tests/RunCMake/CommandLine/trace-try_compile-stderr.txt b/Tests/RunCMake/CommandLine/trace-try_compile-stderr.txt new file mode 100644 index 0000000..1674b8f --- /dev/null +++ b/Tests/RunCMake/CommandLine/trace-try_compile-stderr.txt @@ -0,0 +1,4 @@ +.*Modules/CMakeDetermineCompilerABI.cmake\([0-9]+\): try_compile\([^)]+\) +.*Tests/RunCMake/CommandLine/trace-try_compile(-redirect)?-build/CMakeFiles/CMakeScratch/TryCompile-[^/]+/CMakeLists.txt\([0-9]+\): cmake_minimum_required.* +.*Tests/RunCMake/CommandLine/trace-try_compile(-redirect)?-build/CMakeFiles/CMakeScratch/TryCompile-[^/]+/CMakeLists.txt\([0-9]+\): project\(CMAKE_TRY_COMPILE.* +.*Tests/RunCMake/CommandLine/trace-try_compile(-redirect)?-build/CMakeFiles/CMakeScratch/TryCompile-[^/]+/CMakeLists.txt\([0-9]+\): add_executable\(cmTC_.* diff --git a/Tests/RunCMake/CommandLine/trace-try_compile.cmake b/Tests/RunCMake/CommandLine/trace-try_compile.cmake new file mode 100644 index 0000000..982cb89 --- /dev/null +++ b/Tests/RunCMake/CommandLine/trace-try_compile.cmake @@ -0,0 +1,2 @@ +cmake_minimum_required(VERSION 3.24) +project(test C) diff --git a/Tests/RunCMake/alias_targets/duplicate-target-CMP0107-OLD-stderr.txt b/Tests/RunCMake/alias_targets/duplicate-target-CMP0107-OLD-stderr.txt new file mode 100644 index 0000000..f5247ca --- /dev/null +++ b/Tests/RunCMake/alias_targets/duplicate-target-CMP0107-OLD-stderr.txt @@ -0,0 +1,10 @@ +^CMake Deprecation Warning at duplicate-target-CMP0107-OLD.cmake:[0-9]+ \(cmake_policy\): + The OLD behavior for policy CMP0107 will be removed from a future version + of CMake. + + The cmake-policies\(7\) manual explains that the OLD behaviors of all + policies are deprecated and that a policy should be set to OLD only under + specific short-term circumstances. Projects should be ported to the NEW + behavior and not rely on setting a policy to OLD. +Call Stack \(most recent call first\): + CMakeLists.txt:[0-9]+ \(include\)$ diff --git a/Tests/RunCMake/export/Repeat-CMP0103-OLD-stderr.txt b/Tests/RunCMake/export/Repeat-CMP0103-OLD-stderr.txt new file mode 100644 index 0000000..1183f86 --- /dev/null +++ b/Tests/RunCMake/export/Repeat-CMP0103-OLD-stderr.txt @@ -0,0 +1,10 @@ +^CMake Deprecation Warning at Repeat-CMP0103-OLD.cmake:[0-9]+ \(cmake_policy\): + The OLD behavior for policy CMP0103 will be removed from a future version + of CMake. + + The cmake-policies\(7\) manual explains that the OLD behaviors of all + policies are deprecated and that a policy should be set to OLD only under + specific short-term circumstances. Projects should be ported to the NEW + behavior and not rely on setting a policy to OLD. +Call Stack \(most recent call first\): + CMakeLists.txt:[0-9]+ \(include\)$ diff --git a/Tests/RunCMake/target_link_libraries/CMP0108-OLD-self-link-stderr.txt b/Tests/RunCMake/target_link_libraries/CMP0108-OLD-self-link-stderr.txt new file mode 100644 index 0000000..07e9a9f --- /dev/null +++ b/Tests/RunCMake/target_link_libraries/CMP0108-OLD-self-link-stderr.txt @@ -0,0 +1,10 @@ +^CMake Deprecation Warning at CMP0108-OLD-self-link.cmake:[0-9]+ \(cmake_policy\): + The OLD behavior for policy CMP0108 will be removed from a future version + of CMake. + + The cmake-policies\(7\) manual explains that the OLD behaviors of all + policies are deprecated and that a policy should be set to OLD only under + specific short-term circumstances. Projects should be ported to the NEW + behavior and not rely on setting a policy to OLD. +Call Stack \(most recent call first\): + CMakeLists.txt:[0-9]+ \(include\)$ diff --git a/Tests/UseSWIG/BasicPerl/CMakeLists.txt b/Tests/UseSWIG/BasicPerl/CMakeLists.txt index 671d529..1151739 100644 --- a/Tests/UseSWIG/BasicPerl/CMakeLists.txt +++ b/Tests/UseSWIG/BasicPerl/CMakeLists.txt @@ -4,7 +4,9 @@ project(TestBasicPerl CXX) include(CTest) -set(language "perl") +if(NOT DEFINED language) + set(language "perl") +endif() include (../BasicConfiguration.cmake) diff --git a/Tests/UseSWIG/CMakeLists.txt b/Tests/UseSWIG/CMakeLists.txt index c76e8a0..7c4925e 100644 --- a/Tests/UseSWIG/CMakeLists.txt +++ b/Tests/UseSWIG/CMakeLists.txt @@ -20,6 +20,16 @@ add_test(NAME UseSWIG.LegacyPerl COMMAND --build-options ${build_options} --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION> ) +add_test(NAME UseSWIG.LegacyPerl5 COMMAND + ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION> + --build-and-test + "${CMake_SOURCE_DIR}/Tests/UseSWIG/LegacyPerl" + "${CMake_BINARY_DIR}/Tests/UseSWIG/LegacyPerl5" + ${build_generator_args} + --build-project TestLegacyPerl + --build-options ${build_options} -Dlanguage=perl5 + --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION> + ) include(CheckLanguage) check_language(CSharp) @@ -66,6 +76,16 @@ add_test(NAME UseSWIG.BasicPerl COMMAND --build-options ${build_options} --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION> ) +add_test(NAME UseSWIG.BasicPerl5 COMMAND + ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION> + --build-and-test + "${CMake_SOURCE_DIR}/Tests/UseSWIG/BasicPerl" + "${CMake_BINARY_DIR}/Tests/UseSWIG/BasicPerl5" + ${build_generator_args} + --build-project TestBasicPerl + --build-options ${build_options} -Dlanguage=perl5 + --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION> + ) if(SWIG_FOUND AND NOT SWIG_VERSION VERSION_LESS "4.0.2" AND CMAKE_GENERATOR MATCHES "Make|Ninja|Xcode|Visual Studio (1[1-9]|[2-9][0-9])") add_test(NAME UseSWIG.Depfile.BasicPython COMMAND @@ -89,6 +109,16 @@ if(SWIG_FOUND AND NOT SWIG_VERSION VERSION_LESS "4.0.2" --build-options ${build_options} -DSWIG_USE_SWIG_DEPENDENCIES=ON --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION> ) + add_test(NAME UseSWIG.Depfile.BasicPerl5 COMMAND + ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION> + --build-and-test + "${CMake_SOURCE_DIR}/Tests/UseSWIG/BasicPerl" + "${CMake_BINARY_DIR}/Tests/UseSWIG/BasicPerl5.Depfile" + ${build_generator_args} + --build-project TestBasicPerl + --build-options ${build_options} -DSWIG_USE_SWIG_DEPENDENCIES=ON -Dlanguage=perl5 + --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION> + ) endif() if (CMake_TEST_UseSWIG_Fortran) diff --git a/Tests/UseSWIG/LegacyPerl/CMakeLists.txt b/Tests/UseSWIG/LegacyPerl/CMakeLists.txt index 90d92f4..be0b465 100644 --- a/Tests/UseSWIG/LegacyPerl/CMakeLists.txt +++ b/Tests/UseSWIG/LegacyPerl/CMakeLists.txt @@ -4,7 +4,9 @@ project(TestLegacyPerl CXX) include(CTest) -set(language "perl") +if(NOT DEFINED language) + set(language "perl") +endif() include (../LegacyConfiguration.cmake) diff --git a/Utilities/ClangTidyModule/CMakeLists.txt b/Utilities/ClangTidyModule/CMakeLists.txt new file mode 100644 index 0000000..6be13d6 --- /dev/null +++ b/Utilities/ClangTidyModule/CMakeLists.txt @@ -0,0 +1,27 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. +cmake_minimum_required(VERSION 3.13) +project(CMakeClangTidyModule C CXX) + +get_filename_component(tmp "${CMAKE_CURRENT_SOURCE_DIR}" PATH) +get_filename_component(CMake_SOURCE_DIR "${tmp}" PATH) + +set(CMAKE_CXX_STANDARD 14) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Clang REQUIRED) + +add_library(cmake-clang-tidy-module MODULE + Module.cxx + + UseCmstrlenCheck.cxx + UseCmstrlenCheck.h + ) +target_include_directories(cmake-clang-tidy-module PRIVATE ${CLANG_INCLUDE_DIRS}) +target_link_libraries(cmake-clang-tidy-module PRIVATE clang-tidy) + +option(RUN_TESTS "Run the tests for the clang-tidy module" OFF) +if(RUN_TESTS) + enable_testing() + add_subdirectory(Tests) +endif() diff --git a/Utilities/ClangTidyModule/Module.cxx b/Utilities/ClangTidyModule/Module.cxx new file mode 100644 index 0000000..a35c336 --- /dev/null +++ b/Utilities/ClangTidyModule/Module.cxx @@ -0,0 +1,24 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#include <clang-tidy/ClangTidyModule.h> +#include <clang-tidy/ClangTidyModuleRegistry.h> + +#include "UseCmstrlenCheck.h" + +namespace clang { +namespace tidy { +namespace cmake { +class CMakeClangTidyModule : public ClangTidyModule +{ +public: + void addCheckFactories(ClangTidyCheckFactories& CheckFactories) override + { + CheckFactories.registerCheck<UseCmstrlenCheck>("cmake-use-cmstrlen"); + } +}; + +static ClangTidyModuleRegistry::Add<CMakeClangTidyModule> X( + "cmake-clang-tidy", "Adds lint checks for the CMake code base."); +} +} +} diff --git a/Utilities/ClangTidyModule/Tests/CMakeLists.txt b/Utilities/ClangTidyModule/Tests/CMakeLists.txt new file mode 100644 index 0000000..42027ed --- /dev/null +++ b/Utilities/ClangTidyModule/Tests/CMakeLists.txt @@ -0,0 +1,13 @@ +configure_file("${CMake_SOURCE_DIR}/.clang-format" ".clang-format" COPYONLY) + +function(add_run_clang_tidy_test check_name) + add_test(NAME "RunClangTidy.${check_name}" COMMAND ${CMAKE_COMMAND} + "-DCLANG_TIDY_COMMAND=$<TARGET_FILE:clang-tidy>" + "-DCLANG_TIDY_MODULE=$<TARGET_FILE:cmake-clang-tidy-module>" + "-DCHECK_NAME=${check_name}" + "-DRunClangTidy_BINARY_DIR=${CMAKE_CURRENT_BINARY_DIR}" + -P "${CMAKE_CURRENT_SOURCE_DIR}/RunClangTidy.cmake" + ) +endfunction() + +add_run_clang_tidy_test(cmake-use-cmstrlen) diff --git a/Utilities/ClangTidyModule/Tests/RunClangTidy.cmake b/Utilities/ClangTidyModule/Tests/RunClangTidy.cmake new file mode 100644 index 0000000..486d592 --- /dev/null +++ b/Utilities/ClangTidyModule/Tests/RunClangTidy.cmake @@ -0,0 +1,67 @@ +set(config_arg) +if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/${CHECK_NAME}.clang-tidy") + set(config_arg "--config-file=${CMAKE_CURRENT_LIST_DIR}/${CHECK_NAME}.clang-tidy") +endif() + +foreach(o out err) + if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/${CHECK_NAME}-std${o}.txt") + file(READ "${CMAKE_CURRENT_LIST_DIR}/${CHECK_NAME}-std${o}.txt" expect_std${o}) + string(REGEX REPLACE "\n+$" "" expect_std${o} "${expect_std${o}}") + else() + set(expect_std${o} "") + endif() +endforeach() + +set(source_file "${RunClangTidy_BINARY_DIR}/${CHECK_NAME}.cxx") +configure_file("${CMAKE_CURRENT_LIST_DIR}/${CHECK_NAME}.cxx" "${source_file}" COPYONLY) + +set(command + "${CLANG_TIDY_COMMAND}" + "--load=${CLANG_TIDY_MODULE}" + "--checks=-*,${CHECK_NAME}" + "--fix" + "--format-style=file" + ${config_arg} + "${source_file}" + -- + ) +execute_process( + COMMAND ${command} + RESULT_VARIABLE result + OUTPUT_VARIABLE actual_stdout + ERROR_VARIABLE actual_stderr + ) +string(REPLACE "${RunClangTidy_BINARY_DIR}/" "" actual_stdout "${actual_stdout}") + +set(RunClangTidy_TEST_FAILED) + +if(NOT result EQUAL 0) + string(APPEND RunClangTidy_TEST_FAILED "Expected result: 0, actual result: ${result}\n") +endif() + +foreach(o out err) + string(REGEX REPLACE "\n+$" "" actual_std${o} "${actual_std${o}}") + if(NOT actual_std${o} STREQUAL expect_std${o}) + string(REPLACE "\n" "\n " expect_std${o}_formatted " ${expect_std${o}}") + string(REPLACE "\n" "\n " actual_std${o}_formatted " ${actual_std${o}}") + string(APPEND RunClangTidy_TEST_FAILED "Expected std${o}:\n${expect_std${o}_formatted}\nActual std${o}:\n${actual_std${o}_formatted}\n") + endif() +endforeach() + +if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/${CHECK_NAME}-fixit.cxx") + set(expect_fixit_file "${CMAKE_CURRENT_LIST_DIR}/${CHECK_NAME}-fixit.cxx") +else() + set(expect_fixit_file "${CMAKE_CURRENT_LIST_DIR}/${CHECK_NAME}.cxx") +endif() +file(READ "${expect_fixit_file}" expect_fixit) +file(READ "${source_file}" actual_fixit) +if(NOT expect_fixit STREQUAL actual_fixit) + string(REPLACE "\n" "\n " expect_fixit_formatted " ${expect_fixit}") + string(REPLACE "\n" "\n " actual_fixit_formatted " ${actual_fixit}") + string(APPEND RunClangTidy_TEST_FAILED "Expected fixit:\n${expect_fixit_formatted}\nActual fixit:\n${actual_fixit_formatted}\n") +endif() + +if(RunClangTidy_TEST_FAILED) + string(REPLACE ";" " " command_formatted "${command}") + message(FATAL_ERROR "Command:\n ${command_formatted}\n${RunClangTidy_TEST_FAILED}") +endif() diff --git a/Utilities/ClangTidyModule/Tests/cmake-use-cmstrlen-fixit.cxx b/Utilities/ClangTidyModule/Tests/cmake-use-cmstrlen-fixit.cxx new file mode 100644 index 0000000..c93d557 --- /dev/null +++ b/Utilities/ClangTidyModule/Tests/cmake-use-cmstrlen-fixit.cxx @@ -0,0 +1,37 @@ +#include <cstring> + +template <size_t N> +constexpr size_t cmStrLen(const char (&/*str*/)[N]) +{ + return N - 1; +} + +namespace ns1 { +using std::strlen; +} + +namespace ns2 { +std::size_t strlen(const char* str) +{ + return std::strlen(str); +} +} + +int main() +{ + // String variable used for calling strlen() on a variable + auto s0 = "howdy"; + + // Correction needed + (void)cmStrLen("Hello"); + (void)cmStrLen("Goodbye"); + (void)cmStrLen("Hola"); + (void)cmStrLen("Bonjour"); + + // No correction needed + (void)ns2::strlen("Salve"); + (void)cmStrLen("Konnichiwa"); + (void)strlen(s0); + + return 0; +} diff --git a/Utilities/ClangTidyModule/Tests/cmake-use-cmstrlen-stderr.txt b/Utilities/ClangTidyModule/Tests/cmake-use-cmstrlen-stderr.txt new file mode 100644 index 0000000..9d9d2ed --- /dev/null +++ b/Utilities/ClangTidyModule/Tests/cmake-use-cmstrlen-stderr.txt @@ -0,0 +1,2 @@ +4 warnings generated. +clang-tidy applied 4 of 4 suggested fixes. diff --git a/Utilities/ClangTidyModule/Tests/cmake-use-cmstrlen-stdout.txt b/Utilities/ClangTidyModule/Tests/cmake-use-cmstrlen-stdout.txt new file mode 100644 index 0000000..6c52ad5 --- /dev/null +++ b/Utilities/ClangTidyModule/Tests/cmake-use-cmstrlen-stdout.txt @@ -0,0 +1,20 @@ +cmake-use-cmstrlen.cxx:26:9: warning: use cmStrLen() for string literals [cmake-use-cmstrlen] + (void)strlen("Hello"); + ^~~~~~ + cmStrLen +cmake-use-cmstrlen.cxx:26:9: note: FIX-IT applied suggested code changes +cmake-use-cmstrlen.cxx:27:9: warning: use cmStrLen() for string literals [cmake-use-cmstrlen] + (void)::strlen("Goodbye"); + ^~~~~~~~ + cmStrLen +cmake-use-cmstrlen.cxx:27:9: note: FIX-IT applied suggested code changes +cmake-use-cmstrlen.cxx:28:9: warning: use cmStrLen() for string literals [cmake-use-cmstrlen] + (void)std::strlen("Hola"); + ^~~~~~~~~~~ + cmStrLen +cmake-use-cmstrlen.cxx:28:9: note: FIX-IT applied suggested code changes +cmake-use-cmstrlen.cxx:29:9: warning: use cmStrLen() for string literals [cmake-use-cmstrlen] + (void)ns1::strlen("Bonjour"); + ^~~~~~~~~~~ + cmStrLen +cmake-use-cmstrlen.cxx:29:9: note: FIX-IT applied suggested code changes diff --git a/Utilities/ClangTidyModule/Tests/cmake-use-cmstrlen.cxx b/Utilities/ClangTidyModule/Tests/cmake-use-cmstrlen.cxx new file mode 100644 index 0000000..f36262b --- /dev/null +++ b/Utilities/ClangTidyModule/Tests/cmake-use-cmstrlen.cxx @@ -0,0 +1,37 @@ +#include <cstring> + +template <size_t N> +constexpr size_t cmStrLen(const char (&/*str*/)[N]) +{ + return N - 1; +} + +namespace ns1 { +using std::strlen; +} + +namespace ns2 { +std::size_t strlen(const char* str) +{ + return std::strlen(str); +} +} + +int main() +{ + // String variable used for calling strlen() on a variable + auto s0 = "howdy"; + + // Correction needed + (void)strlen("Hello"); + (void)::strlen("Goodbye"); + (void)std::strlen("Hola"); + (void)ns1::strlen("Bonjour"); + + // No correction needed + (void)ns2::strlen("Salve"); + (void)cmStrLen("Konnichiwa"); + (void)strlen(s0); + + return 0; +} diff --git a/Utilities/ClangTidyModule/UseCmstrlenCheck.cxx b/Utilities/ClangTidyModule/UseCmstrlenCheck.cxx new file mode 100644 index 0000000..590d260 --- /dev/null +++ b/Utilities/ClangTidyModule/UseCmstrlenCheck.cxx @@ -0,0 +1,34 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#include "UseCmstrlenCheck.h" + +#include <clang/ASTMatchers/ASTMatchFinder.h> + +namespace clang { +namespace tidy { +namespace cmake { +using namespace ast_matchers; + +UseCmstrlenCheck::UseCmstrlenCheck(StringRef Name, ClangTidyContext* Context) + : ClangTidyCheck(Name, Context) +{ +} + +void UseCmstrlenCheck::registerMatchers(MatchFinder* Finder) +{ + Finder->addMatcher(callExpr(callee(functionDecl(hasName("::strlen"))), + callee(expr().bind("callee")), + hasArgument(0, stringLiteral())), + this); +} + +void UseCmstrlenCheck::check(const MatchFinder::MatchResult& Result) +{ + const Expr* Node = Result.Nodes.getNodeAs<Expr>("callee"); + + this->diag(Node->getBeginLoc(), "use cmStrLen() for string literals") + << FixItHint::CreateReplacement(Node->getSourceRange(), "cmStrLen"); +} +} +} +} diff --git a/Utilities/ClangTidyModule/UseCmstrlenCheck.h b/Utilities/ClangTidyModule/UseCmstrlenCheck.h new file mode 100644 index 0000000..08f77c2 --- /dev/null +++ b/Utilities/ClangTidyModule/UseCmstrlenCheck.h @@ -0,0 +1,21 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#pragma once + +#include <clang-tidy/ClangTidyCheck.h> +#include <clang/ASTMatchers/ASTMatchFinder.h> + +namespace clang { +namespace tidy { +namespace cmake { +class UseCmstrlenCheck : public ClangTidyCheck +{ +public: + UseCmstrlenCheck(StringRef Name, ClangTidyContext* Context); + void registerMatchers(ast_matchers::MatchFinder* Finder) override; + + void check(const ast_matchers::MatchFinder::MatchResult& Result) override; +}; +} +} +} diff --git a/Utilities/Doxygen/CMakeLists.txt b/Utilities/Doxygen/CMakeLists.txt index bc16350..b084dd5 100644 --- a/Utilities/Doxygen/CMakeLists.txt +++ b/Utilities/Doxygen/CMakeLists.txt @@ -3,7 +3,7 @@ if(NOT CMake_SOURCE_DIR) set(CMakeDeveloperReference_STANDALONE 1) - cmake_minimum_required(VERSION 3.13...3.23 FATAL_ERROR) + cmake_minimum_required(VERSION 3.13...3.24 FATAL_ERROR) get_filename_component(tmp "${CMAKE_CURRENT_SOURCE_DIR}" PATH) get_filename_component(CMake_SOURCE_DIR "${tmp}" PATH) include(${CMake_SOURCE_DIR}/Modules/CTestUseLaunchers.cmake) diff --git a/Utilities/Sphinx/CMakeLists.txt b/Utilities/Sphinx/CMakeLists.txt index 886f4e0..bd2f305 100644 --- a/Utilities/Sphinx/CMakeLists.txt +++ b/Utilities/Sphinx/CMakeLists.txt @@ -3,7 +3,7 @@ if(NOT CMake_SOURCE_DIR) set(CMakeHelp_STANDALONE 1) - cmake_minimum_required(VERSION 3.13...3.23 FATAL_ERROR) + cmake_minimum_required(VERSION 3.13...3.24 FATAL_ERROR) get_filename_component(tmp "${CMAKE_CURRENT_SOURCE_DIR}" PATH) get_filename_component(CMake_SOURCE_DIR "${tmp}" PATH) include(${CMake_SOURCE_DIR}/Modules/CTestUseLaunchers.cmake) diff --git a/Utilities/Sphinx/cmake.py b/Utilities/Sphinx/cmake.py index c7b1233..47e4909 100644 --- a/Utilities/Sphinx/cmake.py +++ b/Utilities/Sphinx/cmake.py @@ -475,3 +475,4 @@ def setup(app): app.add_transform(CMakeTransform) app.add_transform(CMakeXRefTransform) app.add_domain(CMakeDomain) + return {"parallel_read_safe": True} |