Merge branch 'release-3.25'
diff --git a/.clang-tidy b/.clang-tidy
index a86f39a..1e9b78a 100644
--- a/.clang-tidy
+++ b/.clang-tidy
@@ -33,6 +33,7 @@
-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 @@
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 @@
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/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 @@
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_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 @@
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 @@
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/FindZLIB.cmake b/Modules/FindZLIB.cmake
index be5c775..cfe6715 100644
--- a/Modules/FindZLIB.cmake
+++ b/Modules/FindZLIB.cmake
@@ -60,6 +60,14 @@
#]=======================================================================]
+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 @@
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/UseSWIG.cmake b/Modules/UseSWIG.cmake
index fd6596b..e0e01f5 100644
--- a/Modules/UseSWIG.cmake
+++ b/Modules/UseSWIG.cmake
@@ -378,6 +378,7 @@
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 @@
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 @@
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..d4b0490 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 20221021)
+#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/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx
index 50bc78c..2c61163 100644
--- a/Source/cmExportFileGenerator.cxx
+++ b/Source/cmExportFileGenerator.cxx
@@ -939,13 +939,13 @@
// 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 @@
# 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 @@
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 @@
} 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 a1af268..bc703e5 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -4386,12 +4386,20 @@
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 @@
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 @@
}
// 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/cmake.cxx b/Source/cmake.cxx
index 8800792..c4c638c 100644
--- a/Source/cmake.cxx
+++ b/Source/cmake.cxx
@@ -1537,6 +1537,16 @@
}
}
+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 54d0bb5..5b5425c 100644
--- a/Source/cmake.h
+++ b/Source/cmake.h
@@ -513,10 +513,19 @@
{
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; }
@@ -677,6 +686,7 @@
bool TraceExpand = false;
TraceFormat TraceFormatVar = TRACE_HUMAN;
cmGeneratedFileStream TraceFile;
+ cmake* TraceRedirect = nullptr;
bool WarnUninitialized = false;
bool WarnUnusedCli = true;
bool CheckSystemVars = false;
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 @@
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/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 @@
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 @@
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/CommandLine/RunCMakeTest.cmake b/Tests/RunCMake/CommandLine/RunCMakeTest.cmake
index a2eeddf..50b1f90 100644
--- a/Tests/RunCMake/CommandLine/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CommandLine/RunCMakeTest.cmake
@@ -940,6 +940,7 @@
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 +953,7 @@
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 @@
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 @@
--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 @@
--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 @@
--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 @@
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)