summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitlab/ci/configure_linux_gcc_cxx_modules_ninja.cmake2
-rw-r--r--.gitlab/ci/configure_linux_gcc_cxx_modules_ninja_multi.cmake2
-rwxr-xr-x.gitlab/ci/wix.ps15
-rw-r--r--.gitlab/os-linux.yml2
-rw-r--r--CMakeLists.txt3
-rw-r--r--CTestCustom.cmake.in6
-rw-r--r--Help/dev/experimental.rst4
-rw-r--r--Help/prop_tgt/VERIFY_INTERFACE_HEADER_SETS.rst6
-rw-r--r--Help/release/dev/cuda-device-lto.rst7
-rw-r--r--Help/release/dev/p1689r5.rst6
-rw-r--r--Modules/CheckIPOSupported.cmake40
-rw-r--r--Modules/Compiler/Clang-CUDA.cmake4
-rw-r--r--Modules/Compiler/NVIDIA-CUDA.cmake8
-rw-r--r--Modules/FetchContent.cmake71
-rw-r--r--Modules/FindCoin3D.cmake4
-rw-r--r--Modules/FindGTest.cmake2
-rw-r--r--Modules/FindOpenMP.cmake4
-rw-r--r--Source/CMakeVersion.cmake2
-rw-r--r--Source/cmCxxModuleMapper.cxx234
-rw-r--r--Source/cmCxxModuleMapper.h41
-rw-r--r--Source/cmFindPackageCommand.cxx1249
-rw-r--r--Source/cmFindPackageCommand.h2
-rw-r--r--Source/cmGeneratedFileStream.cxx6
-rw-r--r--Source/cmGeneratorTarget.cxx30
-rw-r--r--Source/cmGeneratorTarget.h5
-rw-r--r--Source/cmGhsMultiTargetGenerator.cxx4
-rw-r--r--Source/cmGlobalNinjaGenerator.cxx100
-rw-r--r--Source/cmGlobalVisualStudioVersionedGenerator.cxx2
-rw-r--r--Source/cmGlobalXCodeGenerator.cxx4
-rw-r--r--Source/cmLinkLineDeviceComputer.cxx21
-rw-r--r--Source/cmLinkLineDeviceComputer.h1
-rw-r--r--Source/cmLocalGenerator.cxx25
-rw-r--r--Source/cmLocalGenerator.h13
-rw-r--r--Source/cmLocalVisualStudio7Generator.cxx3
-rw-r--r--Source/cmMakefileExecutableTargetGenerator.cxx17
-rw-r--r--Source/cmMakefileLibraryTargetGenerator.cxx13
-rw-r--r--Source/cmNinjaNormalTargetGenerator.cxx1
-rw-r--r--Source/cmScanDepFormat.cxx37
-rw-r--r--Source/cmScanDepFormat.h5
-rw-r--r--Source/cmSystemTools.cxx14
-rw-r--r--Source/cmVisualStudio10TargetGenerator.cxx11
-rw-r--r--Tests/CMakeLists.txt5
-rw-r--r--Tests/CudaOnly/CMakeLists.txt24
-rw-r--r--Tests/CudaOnly/DeviceLTO/CMakeLists.txt37
-rw-r--r--Tests/CudaOnly/DeviceLTO/file1.cu17
-rw-r--r--Tests/CudaOnly/DeviceLTO/file2.cu5
-rw-r--r--Tests/CudaOnly/DeviceLTO/file3.cu4
-rw-r--r--Tests/CudaOnly/DeviceLTO/main.cu62
-rw-r--r--Tests/Module/CheckIPOSupported-CUDA/CMakeLists.txt32
-rw-r--r--Tests/Module/CheckIPOSupported-CUDA/bar.cu12
-rw-r--r--Tests/Module/CheckIPOSupported-CUDA/foo.cu4
-rw-r--r--Tests/Module/CheckIPOSupported-CUDA/main.cu62
-rw-r--r--Tests/RunCMake/CXXModules/RunCMakeTest.cmake1
-rw-r--r--Tests/RunCMake/CXXModules/examples/cxx-modules-find-bmi.cmake2
-rw-r--r--Tests/RunCMake/CXXModules/examples/deep-chain-stderr.txt9
-rw-r--r--Tests/RunCMake/CXXModules/examples/deep-chain/CMakeLists.txt66
-rw-r--r--Tests/RunCMake/CXXModules/examples/deep-chain/a.cxx6
-rw-r--r--Tests/RunCMake/CXXModules/examples/deep-chain/b.cxx7
-rw-r--r--Tests/RunCMake/CXXModules/examples/deep-chain/c.cxx7
-rw-r--r--Tests/RunCMake/CXXModules/examples/deep-chain/d.cxx7
-rw-r--r--Tests/RunCMake/CXXModules/examples/deep-chain/e.cxx7
-rw-r--r--Tests/RunCMake/CXXModules/examples/deep-chain/main.cxx6
-rw-r--r--Tests/RunCMake/CXXModules/examples/internal-partitions/importable.cxx2
-rw-r--r--Tests/RunCMake/CXXModules/examples/partitions/importable.cxx2
-rw-r--r--Tests/RunCMake/CheckIPOSupported/default-lang-none-stderr.txt4
-rw-r--r--Tests/RunCMake/find_package/RunCMakeTest.cmake16
-rw-r--r--Tests/RunCMake/find_package/SearchPaths.cmake2
-rw-r--r--Tests/RunCMake/find_package/SearchPaths/prefix/SearchPathsConfig.cmake0
-rw-r--r--Tests/RunCMake/find_package/SearchPaths/prefix_cmake/cmake/SearchPathsConfig.cmake0
-rw-r--r--Tests/RunCMake/find_package/SearchPaths/prefix_lib_cmake_pkg/lib/cmake/SearchPaths-1.2.3/SearchPathsConfig.cmake0
-rw-r--r--Tests/RunCMake/find_package/SearchPaths/prefix_lib_pkg/lib/SearchPaths-1.2.3/SearchPathsConfig.cmake0
-rw-r--r--Tests/RunCMake/find_package/SearchPaths/prefix_lib_pkg_cmake/lib/SearchPaths-1.2.3/cmake/SearchPathsConfig.cmake0
-rw-r--r--Tests/RunCMake/find_package/SearchPaths/prefix_pkg/SearchPaths-1.2.3/SearchPathsConfig.cmake0
-rw-r--r--Tests/RunCMake/find_package/SearchPaths/prefix_pkg_cmake/SearchPaths-1.2.3/cmake/SearchPathsConfig.cmake0
-rw-r--r--Tests/RunCMake/find_package/SearchPaths/prefix_pkg_lib_cmake_pkg/SearchPaths-1.2.3/lib/cmake/SearchPaths-1.2.3/SearchPathsConfig.cmake0
-rw-r--r--Tests/RunCMake/find_package/SearchPaths/prefix_pkg_lib_pkg/SearchPaths-1.2.3/lib/SearchPaths-1.2.3/SearchPathsConfig.cmake0
-rw-r--r--Tests/RunCMake/find_package/SearchPaths/prefix_pkg_lib_pkg_cmake/SearchPaths-1.2.3/lib/SearchPaths-1.2.3/cmake/SearchPathsConfig.cmake0
-rw-r--r--Tests/RunCMake/find_package/SearchPaths/prefix_pkg_share_cmake_pkg/SearchPaths-1.2.3/share/cmake/SearchPaths-1.2.3/SearchPathsConfig.cmake0
-rw-r--r--Tests/RunCMake/find_package/SearchPaths/prefix_pkg_share_pkg/SearchPaths-1.2.3/share/SearchPaths-1.2.3/SearchPathsConfig.cmake0
-rw-r--r--Tests/RunCMake/find_package/SearchPaths/prefix_pkg_share_pkg_cmake/SearchPaths-1.2.3/share/SearchPaths-1.2.3/cmake/SearchPathsConfig.cmake0
-rw-r--r--Tests/RunCMake/find_package/SearchPaths/prefix_share_cmake_pkg/share/cmake/SearchPaths-1.2.3/SearchPathsConfig.cmake0
-rw-r--r--Tests/RunCMake/find_package/SearchPaths/prefix_share_pkg/share/SearchPaths-1.2.3/SearchPathsConfig.cmake0
-rw-r--r--Tests/RunCMake/find_package/SearchPaths/prefix_share_pkg_cmake/share/SearchPaths-1.2.3/cmake/SearchPathsConfig.cmake0
-rw-r--r--Tests/RunCMake/find_package/SearchPaths_prefix-stderr.txt10
-rw-r--r--Tests/RunCMake/find_package/SearchPaths_prefix.cmake1
-rw-r--r--Tests/RunCMake/find_package/SearchPaths_prefix_cmake-stderr.txt12
-rw-r--r--Tests/RunCMake/find_package/SearchPaths_prefix_cmake.cmake1
-rw-r--r--Tests/RunCMake/find_package/SearchPaths_prefix_lib_cmake_pkg-stderr.txt12
-rw-r--r--Tests/RunCMake/find_package/SearchPaths_prefix_lib_cmake_pkg.cmake1
-rw-r--r--Tests/RunCMake/find_package/SearchPaths_prefix_lib_pkg-stderr.txt12
-rw-r--r--Tests/RunCMake/find_package/SearchPaths_prefix_lib_pkg.cmake1
-rw-r--r--Tests/RunCMake/find_package/SearchPaths_prefix_lib_pkg_cmake-stderr.txt12
-rw-r--r--Tests/RunCMake/find_package/SearchPaths_prefix_lib_pkg_cmake.cmake1
-rw-r--r--Tests/RunCMake/find_package/SearchPaths_prefix_pkg-stderr.txt12
-rw-r--r--Tests/RunCMake/find_package/SearchPaths_prefix_pkg.cmake1
-rw-r--r--Tests/RunCMake/find_package/SearchPaths_prefix_pkg_cmake-stderr.txt14
-rw-r--r--Tests/RunCMake/find_package/SearchPaths_prefix_pkg_cmake.cmake1
-rw-r--r--Tests/RunCMake/find_package/SearchPaths_prefix_pkg_lib_cmake_pkg-stderr.txt14
-rw-r--r--Tests/RunCMake/find_package/SearchPaths_prefix_pkg_lib_cmake_pkg.cmake1
-rw-r--r--Tests/RunCMake/find_package/SearchPaths_prefix_pkg_lib_pkg-stderr.txt14
-rw-r--r--Tests/RunCMake/find_package/SearchPaths_prefix_pkg_lib_pkg.cmake1
-rw-r--r--Tests/RunCMake/find_package/SearchPaths_prefix_pkg_lib_pkg_cmake-stderr.txt14
-rw-r--r--Tests/RunCMake/find_package/SearchPaths_prefix_pkg_lib_pkg_cmake.cmake1
-rw-r--r--Tests/RunCMake/find_package/SearchPaths_prefix_pkg_share_cmake_pkg-stderr.txt14
-rw-r--r--Tests/RunCMake/find_package/SearchPaths_prefix_pkg_share_cmake_pkg.cmake1
-rw-r--r--Tests/RunCMake/find_package/SearchPaths_prefix_pkg_share_pkg-stderr.txt14
-rw-r--r--Tests/RunCMake/find_package/SearchPaths_prefix_pkg_share_pkg.cmake1
-rw-r--r--Tests/RunCMake/find_package/SearchPaths_prefix_pkg_share_pkg_cmake-stderr.txt14
-rw-r--r--Tests/RunCMake/find_package/SearchPaths_prefix_pkg_share_pkg_cmake.cmake1
-rw-r--r--Tests/RunCMake/find_package/SearchPaths_prefix_share_cmake_pkg-stderr.txt12
-rw-r--r--Tests/RunCMake/find_package/SearchPaths_prefix_share_cmake_pkg.cmake1
-rw-r--r--Tests/RunCMake/find_package/SearchPaths_prefix_share_pkg-stderr.txt12
-rw-r--r--Tests/RunCMake/find_package/SearchPaths_prefix_share_pkg.cmake1
-rw-r--r--Tests/RunCMake/find_package/SearchPaths_prefix_share_pkg_cmake-stderr.txt12
-rw-r--r--Tests/RunCMake/find_package/SearchPaths_prefix_share_pkg_cmake.cmake1
-rw-r--r--Utilities/Release/linux/aarch64/Dockerfile2
-rw-r--r--Utilities/Release/linux/x86_64/Dockerfile2
117 files changed, 1831 insertions, 817 deletions
diff --git a/.gitlab/ci/configure_linux_gcc_cxx_modules_ninja.cmake b/.gitlab/ci/configure_linux_gcc_cxx_modules_ninja.cmake
index bf990c8..2b04e89 100644
--- a/.gitlab/ci/configure_linux_gcc_cxx_modules_ninja.cmake
+++ b/.gitlab/ci/configure_linux_gcc_cxx_modules_ninja.cmake
@@ -1,4 +1,4 @@
-set(CMake_TEST_MODULE_COMPILATION "named,partitions,internal_partitions" CACHE STRING "")
+set(CMake_TEST_MODULE_COMPILATION "named,partitions,internal_partitions,export_bmi,install_bmi" CACHE STRING "")
set(CMake_TEST_MODULE_COMPILATION_RULES "${CMAKE_CURRENT_LIST_DIR}/cxx_modules_rules_gcc.cmake" CACHE STRING "")
include("${CMAKE_CURRENT_LIST_DIR}/configure_external_test.cmake")
diff --git a/.gitlab/ci/configure_linux_gcc_cxx_modules_ninja_multi.cmake b/.gitlab/ci/configure_linux_gcc_cxx_modules_ninja_multi.cmake
index bf990c8..2b04e89 100644
--- a/.gitlab/ci/configure_linux_gcc_cxx_modules_ninja_multi.cmake
+++ b/.gitlab/ci/configure_linux_gcc_cxx_modules_ninja_multi.cmake
@@ -1,4 +1,4 @@
-set(CMake_TEST_MODULE_COMPILATION "named,partitions,internal_partitions" CACHE STRING "")
+set(CMake_TEST_MODULE_COMPILATION "named,partitions,internal_partitions,export_bmi,install_bmi" CACHE STRING "")
set(CMake_TEST_MODULE_COMPILATION_RULES "${CMAKE_CURRENT_LIST_DIR}/cxx_modules_rules_gcc.cmake" CACHE STRING "")
include("${CMAKE_CURRENT_LIST_DIR}/configure_external_test.cmake")
diff --git a/.gitlab/ci/wix.ps1 b/.gitlab/ci/wix.ps1
index a690533..b7cb3f3 100755
--- a/.gitlab/ci/wix.ps1
+++ b/.gitlab/ci/wix.ps1
@@ -2,13 +2,14 @@ $erroractionpreference = "stop"
$release = "v3.14.0.6526"
$sha256sum = "4C89898DF3BCAB13E12F7CA54399C35AD273475AD2CB6284611D00AE2D063C2C"
-$filename = "wix314-binaries"
+$filename = "wix-3.14.0.6526-win-i386"
$tarball = "$filename.zip"
$outdir = $pwd.Path
$outdir = "$outdir\.gitlab"
$ProgressPreference = 'SilentlyContinue'
-Invoke-WebRequest -Uri "https://wixtoolset.org/downloads/$release/$tarball" -OutFile "$outdir\$tarball"
+#Invoke-WebRequest -Uri "https://wixtoolset.org/downloads/$release/$tarball" -OutFile "$outdir\$tarball"
+Invoke-WebRequest -Uri "https://cmake.org/files/dependencies/$tarball" -OutFile "$outdir\$tarball"
$hash = Get-FileHash "$outdir\$tarball" -Algorithm SHA256
if ($hash.Hash -ne $sha256sum) {
exit 1
diff --git a/.gitlab/os-linux.yml b/.gitlab/os-linux.yml
index 25d5365..37e5c22 100644
--- a/.gitlab/os-linux.yml
+++ b/.gitlab/os-linux.yml
@@ -481,7 +481,7 @@
# use the scripts here.
- "$LAUNCHER make -j$(nproc)"
# NOTE: This regex matches that used in the release build.
- - "$LAUNCHER bin/ctest --output-on-failure -j$(nproc) -R '^(CMake\\.|CMakeLib\\.|CMakeServerLib\\.|RunCMake\\.ctest_memcheck)'"
+ - "$LAUNCHER bin/ctest --output-on-failure -j$(nproc) -R '^(CMake\\.|CMakeLib\\.|RunCMake\\.ctest_memcheck)'"
# Make a package.
- bin/cpack -G TGZ
- bin/cpack -G STGZ
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 4d9d3ca..267518b 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -883,9 +883,6 @@ add_subdirectory(Tests)
if(NOT CMake_TEST_EXTERNAL_CMAKE)
if(BUILD_TESTING)
CMAKE_SET_TARGET_FOLDER(CMakeLibTests "Tests")
- IF(TARGET CMakeServerLibTests)
- CMAKE_SET_TARGET_FOLDER(CMakeServerLibTests "Tests")
- ENDIF()
endif()
if(TARGET documentation)
CMAKE_SET_TARGET_FOLDER(documentation "Documentation")
diff --git a/CTestCustom.cmake.in b/CTestCustom.cmake.in
index 49026a3..85af8ed 100644
--- a/CTestCustom.cmake.in
+++ b/CTestCustom.cmake.in
@@ -74,6 +74,7 @@ list(APPEND CTEST_CUSTOM_WARNING_EXCEPTION
"cm(StringCommand|CTestTestHandler)\\.cxx.*warning.*rand.*may return deterministic values"
"cm(StringCommand|CTestTestHandler)\\.cxx.*warning.*rand.*isn.*t random" # we do not do crypto
"cm(StringCommand|CTestTestHandler)\\.cxx.*warning.*srand.*seed choices are.*poor" # we do not do crypto
+ "cmFindPackageCommand.cxx.*: warning #177-D: parameter .* was declared but never referenced"
"IPA warning: function.*multiply defined in"
"LICENSE WARNING" # PGI license expiry. Not useful in nightly testing.
@@ -83,6 +84,11 @@ list(APPEND CTEST_CUSTOM_WARNING_EXCEPTION
"compilation completed with warnings" # PGI
"[0-9]+ Warning\\(s\\) detected" # SunPro
+ # Ignore false positive on `cm::optional` usage from GCC
+ "cmGlobalNinjaGenerator.cxx:[0-9]*:[0-9]*: warning: '.*cm::optional<CxxModuleMapFormat>::_mem\\)\\)' may be used uninitialized \\[-Wmaybe-uninitialized\\]"
+ "cmGlobalNinjaGenerator.cxx:[0-9]*:[0-9]*: note: '.*cm::optional<CxxModuleMapFormat>::_mem\\)\\)' was declared here"
+ "cmGlobalNinjaGenerator.cxx:[0-9]*:[0-9]*: warning: '\\*\\(\\(void\\*\\)& modmap_fmt \\+4\\)' may be used uninitialized in this function \\[-Wmaybe-uninitialized\\]"
+
# clang-analyzer exceptions
"cmListFileLexer.c:[0-9]+:[0-9]+: warning: Array subscript is undefined"
"jsoncpp/src/.*:[0-9]+:[0-9]+: warning: Value stored to .* is never read"
diff --git a/Help/dev/experimental.rst b/Help/dev/experimental.rst
index b8d681c..adfa36f 100644
--- a/Help/dev/experimental.rst
+++ b/Help/dev/experimental.rst
@@ -58,7 +58,7 @@ dependencies to the file specified by the ``<DYNDEP_FILE>`` placeholder. The
for scandep rules which use ``msvc``-style dependency reporting.
The module dependencies should be written in the format described
-by the `P1689r4`_ paper.
+by the `P1689r5`_ paper.
Compiler writers may try out their scanning functionality using
the `cxx-modules-sandbox`_ test project, modified to set variables
@@ -85,5 +85,5 @@ the GCC documentation, but the relevant section for the purposes of CMake is:
-- GCC module mapper documentation
.. _`D1483r1`: https://mathstuf.fedorapeople.org/fortran-modules/fortran-modules.html
-.. _`P1689r4`: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p1689r4.html
+.. _`P1689r5`: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p1689r5.html
.. _`cxx-modules-sandbox`: https://github.com/mathstuf/cxx-modules-sandbox
diff --git a/Help/prop_tgt/VERIFY_INTERFACE_HEADER_SETS.rst b/Help/prop_tgt/VERIFY_INTERFACE_HEADER_SETS.rst
index 1b3f878..da461a7 100644
--- a/Help/prop_tgt/VERIFY_INTERFACE_HEADER_SETS.rst
+++ b/Help/prop_tgt/VERIFY_INTERFACE_HEADER_SETS.rst
@@ -26,5 +26,9 @@ Otherwise, if C++ is enabled globally, the header is compiled as C++.
Otherwise, if C is enabled globally, the header is compiled as C. Otherwise,
the header file is not compiled.
+This property is initialized by the value of the
+:variable:`CMAKE_VERIFY_INTERFACE_HEADER_SETS` variable if it is set when
+a target is created.
+
If the project wishes to control which header sets are verified by this
-property, you can set :prop_tgt:`INTERFACE_HEADER_SETS_TO_VERIFY`.
+property, it can set :prop_tgt:`INTERFACE_HEADER_SETS_TO_VERIFY`.
diff --git a/Help/release/dev/cuda-device-lto.rst b/Help/release/dev/cuda-device-lto.rst
new file mode 100644
index 0000000..113062b
--- /dev/null
+++ b/Help/release/dev/cuda-device-lto.rst
@@ -0,0 +1,7 @@
+cuda-device-lto
+---------------
+
+* ``CUDA`` language now supports device link time optimization when using
+ ``nvcc``. The :variable:`CMAKE_INTERPROCEDURAL_OPTIMIZATION` variable and
+ the associated :prop_tgt:`INTERPROCEDURAL_OPTIMIZATION` target property will
+ activate device LTO.
diff --git a/Help/release/dev/p1689r5.rst b/Help/release/dev/p1689r5.rst
new file mode 100644
index 0000000..a630dc4
--- /dev/null
+++ b/Help/release/dev/p1689r5.rst
@@ -0,0 +1,6 @@
+p1689r5
+-------
+
+* C++ module scanning now supports the latest revision, `P1689R5`_.
+
+.. _`P1689r5`: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p1689r5.html
diff --git a/Modules/CheckIPOSupported.cmake b/Modules/CheckIPOSupported.cmake
index cca1be9..14262a1 100644
--- a/Modules/CheckIPOSupported.cmake
+++ b/Modules/CheckIPOSupported.cmake
@@ -76,6 +76,23 @@ endmacro()
# Run IPO/LTO test
macro(_ipo_run_language_check language)
+ set(_C_ext "c")
+ set(_CXX_ext "cpp")
+ set(_Fortran_ext "f")
+ string(COMPARE EQUAL "${language}" "CUDA" is_cuda)
+
+ set(ext ${_${language}_ext})
+ if(NOT "${ext}" STREQUAL "")
+ set(copy_sources foo.${ext} main.${ext})
+ elseif(is_cuda)
+ if(_CMAKE_CUDA_IPO_SUPPORTED_BY_CMAKE)
+ set("${X_RESULT}" YES PARENT_SCOPE)
+ endif()
+ return()
+ else()
+ message(FATAL_ERROR "Language not supported")
+ endif()
+
set(testdir "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/_CMakeLTOTest-${language}")
file(REMOVE_RECURSE "${testdir}")
@@ -100,20 +117,6 @@ macro(_ipo_run_language_check language)
@ONLY
)
- string(COMPARE EQUAL "${language}" "C" is_c)
- string(COMPARE EQUAL "${language}" "CXX" is_cxx)
- string(COMPARE EQUAL "${language}" "Fortran" is_fortran)
-
- if(is_c)
- set(copy_sources foo.c main.c)
- elseif(is_cxx)
- set(copy_sources foo.cpp main.cpp)
- elseif(is_fortran)
- set(copy_sources foo.f main.f)
- else()
- message(FATAL_ERROR "Language not supported")
- endif()
-
foreach(x ${copy_sources})
configure_file(
"${try_compile_src}/${x}"
@@ -214,6 +217,11 @@ function(check_ipo_supported)
list(APPEND languages "C")
endif()
+ list(FIND enabled_languages "CUDA" result)
+ if(NOT result EQUAL -1)
+ list(APPEND languages "CUDA")
+ endif()
+
list(FIND enabled_languages "Fortran" result)
if(NOT result EQUAL -1)
list(APPEND languages "Fortran")
@@ -222,7 +230,7 @@ function(check_ipo_supported)
string(COMPARE EQUAL "${languages}" "" no_languages)
if(no_languages)
_ipo_not_supported(
- "no C/CXX/Fortran languages found in ENABLED_LANGUAGES global property"
+ "no C/CXX/CUDA/Fortran languages found in ENABLED_LANGUAGES global property"
)
return()
endif()
@@ -230,7 +238,7 @@ function(check_ipo_supported)
set(languages "${X_LANGUAGES}")
set(unsupported_languages "${languages}")
- list(REMOVE_ITEM unsupported_languages "C" "CXX" "Fortran")
+ list(REMOVE_ITEM unsupported_languages "C" "CXX" "CUDA" "Fortran")
string(COMPARE NOTEQUAL "${unsupported_languages}" "" has_unsupported)
if(has_unsupported)
_ipo_not_supported(
diff --git a/Modules/Compiler/Clang-CUDA.cmake b/Modules/Compiler/Clang-CUDA.cmake
index 219897e..d9929f1 100644
--- a/Modules/Compiler/Clang-CUDA.cmake
+++ b/Modules/Compiler/Clang-CUDA.cmake
@@ -35,6 +35,10 @@ set(CMAKE_CUDA_RUNTIME_LIBRARY_LINK_OPTIONS_STATIC "cudadevrt;cudart_static")
set(CMAKE_CUDA_RUNTIME_LIBRARY_LINK_OPTIONS_SHARED "cudadevrt;cudart")
set(CMAKE_CUDA_RUNTIME_LIBRARY_LINK_OPTIONS_NONE "")
+# Clang doesn't support CUDA device LTO
+set(_CMAKE_CUDA_IPO_SUPPORTED_BY_CMAKE NO)
+set(_CMAKE_CUDA_IPO_MAY_BE_SUPPORTED_BY_COMPILER NO)
+
if(UNIX)
list(APPEND CMAKE_CUDA_RUNTIME_LIBRARY_LINK_OPTIONS_STATIC "rt" "pthread" "dl")
endif()
diff --git a/Modules/Compiler/NVIDIA-CUDA.cmake b/Modules/Compiler/NVIDIA-CUDA.cmake
index 33509ac..2b8a1ea 100644
--- a/Modules/Compiler/NVIDIA-CUDA.cmake
+++ b/Modules/Compiler/NVIDIA-CUDA.cmake
@@ -48,6 +48,13 @@ if((NOT DEFINED CMAKE_DEPENDS_USE_COMPILER OR CMAKE_DEPENDS_USE_COMPILER)
set(CMAKE_CUDA_DEPENDS_USE_COMPILER TRUE)
endif()
+if(CMAKE_CUDA_COMPILER_VERSION VERSION_GREATER_EQUAL 11.2)
+ set(_CMAKE_CUDA_IPO_SUPPORTED_BY_CMAKE YES)
+ set(_CMAKE_CUDA_IPO_MAY_BE_SUPPORTED_BY_COMPILER YES)
+
+ set(CMAKE_CUDA_DEVICE_LINK_OPTIONS_IPO " -dlto")
+endif()
+
if(NOT "x${CMAKE_CUDA_SIMULATE_ID}" STREQUAL "xMSVC")
set(CMAKE_CUDA_COMPILE_OPTIONS_PIE -Xcompiler=-fPIE)
set(CMAKE_CUDA_COMPILE_OPTIONS_PIC -Xcompiler=-fPIC)
@@ -61,6 +68,7 @@ if(NOT "x${CMAKE_CUDA_SIMULATE_ID}" STREQUAL "xMSVC")
string(APPEND CMAKE_CUDA_FLAGS_MINSIZEREL_INIT " -O1 -DNDEBUG")
string(APPEND CMAKE_CUDA_FLAGS_RELWITHDEBINFO_INIT " -O2 -g -DNDEBUG")
endif()
+
set(CMAKE_SHARED_LIBRARY_CREATE_CUDA_FLAGS -shared)
set(CMAKE_INCLUDE_SYSTEM_FLAG_CUDA -isystem=)
diff --git a/Modules/FetchContent.cmake b/Modules/FetchContent.cmake
index df40c85..27070c0 100644
--- a/Modules/FetchContent.cmake
+++ b/Modules/FetchContent.cmake
@@ -1189,19 +1189,18 @@ function(FetchContent_Declare contentName)
)
endif()
- set(options "")
+ # Because we are only looking for a subset of the supported keywords, we
+ # cannot check for multi-value arguments with this method. We will have to
+ # handle the URL keyword differently.
set(oneValueArgs
SVN_REPOSITORY
DOWNLOAD_NO_EXTRACT
DOWNLOAD_EXTRACT_TIMESTAMP
- URL
BINARY_DIR
SOURCE_DIR
)
- set(multiValueArgs "")
- cmake_parse_arguments(PARSE_ARGV 1 ARG
- "${options}" "${oneValueArgs}" "${multiValueArgs}")
+ cmake_parse_arguments(PARSE_ARGV 1 ARG "" "${oneValueArgs}" "")
string(TOLOWER ${contentName} contentNameLower)
@@ -1230,31 +1229,45 @@ function(FetchContent_Declare contentName)
# explicitly set the relevant option if not already provided. The condition
# here is essentially an abbreviated version of the logic in
# ExternalProject's _ep_add_download_command() function.
- if(ARG_URL AND
- NOT IS_DIRECTORY "${ARG_URL}" AND
- NOT ARG_DOWNLOAD_NO_EXTRACT AND
+ if(NOT ARG_DOWNLOAD_NO_EXTRACT AND
NOT DEFINED ARG_DOWNLOAD_EXTRACT_TIMESTAMP)
- cmake_policy(GET CMP0135 _FETCHCONTENT_CMP0135
- PARENT_SCOPE # undocumented, do not use outside of CMake
- )
- if(_FETCHCONTENT_CMP0135 STREQUAL "")
- message(AUTHOR_WARNING
- "The DOWNLOAD_EXTRACT_TIMESTAMP option was not given and policy "
- "CMP0135 is not set. The policy's OLD behavior will be used. "
- "When using a URL download, the timestamps of extracted files "
- "should preferably be that of the time of extraction, otherwise "
- "code that depends on the extracted contents might not be "
- "rebuilt if the URL changes. The OLD behavior preserves the "
- "timestamps from the archive instead, but this is usually not "
- "what you want. Update your project to the NEW behavior or "
- "specify the DOWNLOAD_EXTRACT_TIMESTAMP option with a value of "
- "true to avoid this robustness issue."
- )
- set(ARG_DOWNLOAD_EXTRACT_TIMESTAMP TRUE)
- elseif(_FETCHCONTENT_CMP0135 STREQUAL "NEW")
- set(ARG_DOWNLOAD_EXTRACT_TIMESTAMP FALSE)
- else()
- set(ARG_DOWNLOAD_EXTRACT_TIMESTAMP TRUE)
+ list(FIND ARGN URL urlIndex)
+ if(urlIndex GREATER_EQUAL 0)
+ math(EXPR urlIndex "${urlIndex} + 1")
+ list(LENGTH ARGN numArgs)
+ if(urlIndex GREATER_EQUAL numArgs)
+ message(FATAL_ERROR
+ "URL keyword needs to be followed by at least one URL"
+ )
+ endif()
+ # If we have multiple URLs, none of them are allowed to be local paths.
+ # Therefore, we can test just the first URL, and if it is non-local, so
+ # will be the others if there are more.
+ list(GET ARGN ${urlIndex} firstUrl)
+ if(NOT IS_DIRECTORY "${firstUrl}")
+ cmake_policy(GET CMP0135 _FETCHCONTENT_CMP0135
+ PARENT_SCOPE # undocumented, do not use outside of CMake
+ )
+ if(_FETCHCONTENT_CMP0135 STREQUAL "")
+ message(AUTHOR_WARNING
+ "The DOWNLOAD_EXTRACT_TIMESTAMP option was not given and policy "
+ "CMP0135 is not set. The policy's OLD behavior will be used. "
+ "When using a URL download, the timestamps of extracted files "
+ "should preferably be that of the time of extraction, otherwise "
+ "code that depends on the extracted contents might not be "
+ "rebuilt if the URL changes. The OLD behavior preserves the "
+ "timestamps from the archive instead, but this is usually not "
+ "what you want. Update your project to the NEW behavior or "
+ "specify the DOWNLOAD_EXTRACT_TIMESTAMP option with a value of "
+ "true to avoid this robustness issue."
+ )
+ set(ARG_DOWNLOAD_EXTRACT_TIMESTAMP TRUE)
+ elseif(_FETCHCONTENT_CMP0135 STREQUAL "NEW")
+ set(ARG_DOWNLOAD_EXTRACT_TIMESTAMP FALSE)
+ else()
+ set(ARG_DOWNLOAD_EXTRACT_TIMESTAMP TRUE)
+ endif()
+ endif()
endif()
endif()
diff --git a/Modules/FindCoin3D.cmake b/Modules/FindCoin3D.cmake
index 301e70b..5910ad1 100644
--- a/Modules/FindCoin3D.cmake
+++ b/Modules/FindCoin3D.cmake
@@ -31,11 +31,11 @@ if (WIN32)
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\SIM\\Coin3D\\2;Installation Path]/include"
)
- find_library(COIN3D_LIBRARY_DEBUG coin2d
+ find_library(COIN3D_LIBRARY_DEBUG NAMES coin2d coin4d
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\SIM\\Coin3D\\2;Installation Path]/lib"
)
- find_library(COIN3D_LIBRARY_RELEASE coin2
+ find_library(COIN3D_LIBRARY_RELEASE NAMES coin2 coin4
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\SIM\\Coin3D\\2;Installation Path]/lib"
)
diff --git a/Modules/FindGTest.cmake b/Modules/FindGTest.cmake
index 60bb401..92334e4 100644
--- a/Modules/FindGTest.cmake
+++ b/Modules/FindGTest.cmake
@@ -314,7 +314,7 @@ if(GTest_FOUND)
__gtest_define_backwards_compatible_library_targets()
endif()
-if(GMock_FOUND)
+if(GMock_FOUND AND GTest_FOUND)
if(NOT TARGET GTest::gmock)
__gtest_determine_library_type(GMOCK_LIBRARY)
add_library(GTest::gmock ${GMOCK_LIBRARY_TYPE} IMPORTED)
diff --git a/Modules/FindOpenMP.cmake b/Modules/FindOpenMP.cmake
index 0590a28..844ceb3 100644
--- a/Modules/FindOpenMP.cmake
+++ b/Modules/FindOpenMP.cmake
@@ -279,7 +279,9 @@ function(_OPENMP_GET_FLAGS LANG FLAG_MODE OPENMP_FLAG_VAR OPENMP_LIB_NAMES_VAR)
DOC "Path to the ${_OPENMP_IMPLICIT_LIB_PLAIN} library for OpenMP"
HINTS ${OpenMP_${LANG}_IMPLICIT_LINK_DIRS}
CMAKE_FIND_ROOT_PATH_BOTH
- NO_DEFAULT_PATH
+ NO_PACKAGE_ROOT_PATH
+ NO_CMAKE_PATH
+ NO_CMAKE_ENVIRONMENT_PATH
)
endif()
mark_as_advanced(OpenMP_${_OPENMP_IMPLICIT_LIB_PLAIN}_LIBRARY)
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index 376943f..5190ab1 100644
--- a/Source/CMakeVersion.cmake
+++ b/Source/CMakeVersion.cmake
@@ -1,7 +1,7 @@
# CMake version number components.
set(CMake_VERSION_MAJOR 3)
set(CMake_VERSION_MINOR 24)
-set(CMake_VERSION_PATCH 20220729)
+set(CMake_VERSION_PATCH 20220803)
#set(CMake_VERSION_RC 0)
set(CMake_VERSION_IS_DIRTY 0)
diff --git a/Source/cmCxxModuleMapper.cxx b/Source/cmCxxModuleMapper.cxx
index 94ad721..84691c9 100644
--- a/Source/cmCxxModuleMapper.cxx
+++ b/Source/cmCxxModuleMapper.cxx
@@ -3,10 +3,19 @@
#include "cmCxxModuleMapper.h"
#include <cassert>
+#include <cstddef>
+#include <set>
#include <sstream>
+#include <string>
+#include <utility>
#include <vector>
+#include <cm/string_view>
+#include <cmext/string_view>
+
#include "cmScanDepFormat.h"
+#include "cmStringAlgorithms.h"
+#include "cmSystemTools.h"
cm::optional<std::string> CxxModuleLocations::BmiGeneratorPathForModule(
std::string const& logical_name) const
@@ -47,6 +56,122 @@ std::string CxxModuleMapContentGcc(CxxModuleLocations const& loc,
return mm.str();
}
+
+std::string CxxModuleMapContentMsvc(CxxModuleLocations const& loc,
+ cmScanDepInfo const& obj,
+ CxxModuleUsage const& usages)
+{
+ std::stringstream mm;
+
+ // A response file of `-reference NAME=PATH` arguments.
+
+ // MSVC's command line only supports a single output. If more than one is
+ // expected, we cannot make a useful module map file.
+ if (obj.Provides.size() > 1) {
+ return {};
+ }
+
+ auto flag_for_method = [](LookupMethod method) -> cm::static_string_view {
+ switch (method) {
+ case LookupMethod::ByName:
+ return "-reference"_s;
+ case LookupMethod::IncludeAngle:
+ return "-headerUnit:angle"_s;
+ case LookupMethod::IncludeQuote:
+ return "-headerUnit:quote"_s;
+ }
+ assert(false && "unsupported lookup method");
+ return ""_s;
+ };
+
+ for (auto const& p : obj.Provides) {
+ if (p.IsInterface) {
+ mm << "-interface\n";
+ } else {
+ mm << "-internalPartition\n";
+ }
+
+ if (auto bmi_loc = loc.BmiGeneratorPathForModule(p.LogicalName)) {
+ mm << "-ifcOutput " << *bmi_loc << '\n';
+ }
+ }
+
+ std::set<std::string> transitive_usage_directs;
+ std::set<std::string> transitive_usage_names;
+
+ for (auto const& r : obj.Requires) {
+ if (auto bmi_loc = loc.BmiGeneratorPathForModule(r.LogicalName)) {
+ auto flag = flag_for_method(r.Method);
+
+ mm << flag << ' ' << r.LogicalName << '=' << *bmi_loc << "\n";
+ transitive_usage_directs.insert(r.LogicalName);
+
+ // Insert transitive usages.
+ auto transitive_usages = usages.Usage.find(r.LogicalName);
+ if (transitive_usages != usages.Usage.end()) {
+ transitive_usage_names.insert(transitive_usages->second.begin(),
+ transitive_usages->second.end());
+ }
+ }
+ }
+
+ for (auto const& transitive_name : transitive_usage_names) {
+ if (transitive_usage_directs.count(transitive_name)) {
+ continue;
+ }
+
+ auto module_ref = usages.Reference.find(transitive_name);
+ if (module_ref != usages.Reference.end()) {
+ auto flag = flag_for_method(module_ref->second.Method);
+ mm << flag << ' ' << transitive_name << '=' << module_ref->second.Path
+ << "\n";
+ }
+ }
+
+ return mm.str();
+}
+}
+
+bool CxxModuleUsage::AddReference(std::string const& logical,
+ std::string const& loc, LookupMethod method)
+{
+ auto r = this->Reference.find(logical);
+ if (r != this->Reference.end()) {
+ auto& ref = r->second;
+
+ if (ref.Path == loc && ref.Method == method) {
+ return true;
+ }
+
+ auto method_name = [](LookupMethod m) -> cm::static_string_view {
+ switch (m) {
+ case LookupMethod::ByName:
+ return "by-name"_s;
+ case LookupMethod::IncludeAngle:
+ return "include-angle"_s;
+ case LookupMethod::IncludeQuote:
+ return "include-quote"_s;
+ }
+ assert(false && "unsupported lookup method");
+ return ""_s;
+ };
+
+ cmSystemTools::Error(cmStrCat("Disagreement of the location of the '",
+ logical,
+ "' module. "
+ "Location A: '",
+ ref.Path, "' via ", method_name(ref.Method),
+ "; "
+ "Location B: '",
+ loc, "' via ", method_name(method), "."));
+ return false;
+ }
+
+ auto& ref = this->Reference[logical];
+ ref.Path = loc;
+ ref.Method = method;
+
+ return true;
}
cm::static_string_view CxxModuleMapExtension(
@@ -56,19 +181,126 @@ cm::static_string_view CxxModuleMapExtension(
switch (*format) {
case CxxModuleMapFormat::Gcc:
return ".gcm"_s;
+ case CxxModuleMapFormat::Msvc:
+ return ".ifc"_s;
}
}
return ".bmi"_s;
}
+std::set<std::string> CxxModuleUsageSeed(
+ CxxModuleLocations const& loc, std::vector<cmScanDepInfo> const& objects,
+ CxxModuleUsage& usages)
+{
+ // Track inner usages to populate usages from internal bits.
+ //
+ // This is a map of modules that required some other module that was not
+ // found to those that were not found.
+ std::map<std::string, std::set<std::string>> internal_usages;
+ std::set<std::string> unresolved;
+
+ for (cmScanDepInfo const& object : objects) {
+ // Add references for each of the provided modules.
+ for (auto const& p : object.Provides) {
+ if (auto bmi_loc = loc.BmiGeneratorPathForModule(p.LogicalName)) {
+ // XXX(cxx-modules): How to support header units?
+ usages.AddReference(p.LogicalName, loc.PathForGenerator(*bmi_loc),
+ LookupMethod::ByName);
+ }
+ }
+
+ // For each requires, pull in what is required.
+ for (auto const& r : object.Requires) {
+ // Find transitive usages.
+ auto transitive_usages = usages.Usage.find(r.LogicalName);
+ // Find the required name in the current target.
+ auto bmi_loc = loc.BmiGeneratorPathForModule(r.LogicalName);
+
+ for (auto const& p : object.Provides) {
+ auto& this_usages = usages.Usage[p.LogicalName];
+
+ // Add the direct usage.
+ this_usages.insert(r.LogicalName);
+
+ // Add the transitive usage.
+ if (transitive_usages != usages.Usage.end()) {
+ this_usages.insert(transitive_usages->second.begin(),
+ transitive_usages->second.end());
+ } else if (bmi_loc) {
+ // Mark that we need to update transitive usages later.
+ internal_usages[p.LogicalName].insert(r.LogicalName);
+ }
+ }
+
+ if (bmi_loc) {
+ usages.AddReference(r.LogicalName, loc.PathForGenerator(*bmi_loc),
+ r.Method);
+ }
+ }
+ }
+
+ // While we have internal usages to manage.
+ while (!internal_usages.empty()) {
+ size_t starting_size = internal_usages.size();
+
+ // For each internal usage.
+ for (auto usage = internal_usages.begin(); usage != internal_usages.end();
+ /* see end of loop */) {
+ auto& this_usages = usages.Usage[usage->first];
+
+ for (auto use = usage->second.begin(); use != usage->second.end();
+ /* see end of loop */) {
+ // Check if this required module uses other internal modules; defer
+ // if so.
+ if (internal_usages.count(*use)) {
+ // Advance the iterator.
+ ++use;
+ continue;
+ }
+
+ auto transitive_usages = usages.Usage.find(*use);
+ if (transitive_usages != usages.Usage.end()) {
+ this_usages.insert(transitive_usages->second.begin(),
+ transitive_usages->second.end());
+ }
+
+ // Remove the entry and advance the iterator.
+ use = usage->second.erase(use);
+ }
+
+ // Erase the entry if it doesn't have any remaining usages.
+ if (usage->second.empty()) {
+ usage = internal_usages.erase(usage);
+ } else {
+ ++usage;
+ }
+ }
+
+ // Check that at least one usage was resolved.
+ if (starting_size == internal_usages.size()) {
+ // Nothing could be resolved this loop; we have a cycle, so record the
+ // cycle and exit.
+ for (auto const& usage : internal_usages) {
+ unresolved.insert(usage.first);
+ }
+ break;
+ }
+ }
+
+ return unresolved;
+}
+
std::string CxxModuleMapContent(CxxModuleMapFormat format,
CxxModuleLocations const& loc,
- cmScanDepInfo const& obj)
+ cmScanDepInfo const& obj,
+ CxxModuleUsage const& usages)
{
switch (format) {
case CxxModuleMapFormat::Gcc:
return CxxModuleMapContentGcc(loc, obj);
+ case CxxModuleMapFormat::Msvc:
+ return CxxModuleMapContentMsvc(loc, obj, usages);
}
assert(false);
diff --git a/Source/cmCxxModuleMapper.h b/Source/cmCxxModuleMapper.h
index 99384c9..8526a07 100644
--- a/Source/cmCxxModuleMapper.h
+++ b/Source/cmCxxModuleMapper.h
@@ -5,16 +5,20 @@
#include "cmConfigure.h" // IWYU pragma: keep
#include <functional>
+#include <map>
+#include <set>
#include <string>
+#include <vector>
#include <cm/optional>
#include <cmext/string_view>
-struct cmScanDepInfo;
+#include "cmScanDepFormat.h"
enum class CxxModuleMapFormat
{
Gcc,
+ Msvc,
};
struct CxxModuleLocations
@@ -37,12 +41,45 @@ struct CxxModuleLocations
std::string const& logical_name) const;
};
+struct CxxModuleReference
+{
+ // The path to the module file used.
+ std::string Path;
+ // How the module was looked up.
+ LookupMethod Method;
+};
+
+struct CxxModuleUsage
+{
+ // The usage requirements for this object.
+ std::map<std::string, std::set<std::string>> Usage;
+
+ // The references for this object.
+ std::map<std::string, CxxModuleReference> Reference;
+
+ // Add a reference to a module.
+ //
+ // Returns `true` if it matches how it was found previously, `false` if it
+ // conflicts.
+ bool AddReference(std::string const& logical, std::string const& loc,
+ LookupMethod method);
+};
+
// Return the extension to use for a given modulemap format.
cm::static_string_view CxxModuleMapExtension(
cm::optional<CxxModuleMapFormat> format);
+// Fill in module usage information for internal usages.
+//
+// Returns the set of unresolved module usage requirements (these form an
+// import cycle).
+std::set<std::string> CxxModuleUsageSeed(
+ CxxModuleLocations const& loc, std::vector<cmScanDepInfo> const& objects,
+ CxxModuleUsage& usages);
+
// Return the contents of the module map in the given format for the
// object file.
std::string CxxModuleMapContent(CxxModuleMapFormat format,
CxxModuleLocations const& loc,
- cmScanDepInfo const& obj);
+ cmScanDepInfo const& obj,
+ CxxModuleUsage const& usages);
diff --git a/Source/cmFindPackageCommand.cxx b/Source/cmFindPackageCommand.cxx
index 4ad9124..f260ec7 100644
--- a/Source/cmFindPackageCommand.cxx
+++ b/Source/cmFindPackageCommand.cxx
@@ -5,7 +5,6 @@
#include <algorithm>
#include <cassert>
#include <cstdio>
-#include <cstring>
#include <deque>
#include <functional>
#include <iterator>
@@ -43,8 +42,403 @@
# include <StorageDefs.h>
#endif
+#if defined(_WIN32) && !defined(__CYGWIN__)
+# include <windows.h>
+// http://msdn.microsoft.com/en-us/library/aa384253%28v=vs.85%29.aspx
+# if !defined(KEY_WOW64_32KEY)
+# define KEY_WOW64_32KEY 0x0200
+# endif
+# if !defined(KEY_WOW64_64KEY)
+# define KEY_WOW64_64KEY 0x0100
+# endif
+#endif
+
class cmExecutionStatus;
-class cmFileList;
+
+namespace {
+
+template <template <typename> class Op>
+struct StrverscmpOp
+{
+ bool operator()(const std::string& lhs, const std::string& rhs) const
+ {
+ return Op<int>()(cmSystemTools::strverscmp(lhs, rhs), 0);
+ }
+};
+
+std::size_t collectPathsForDebug(std::string& buffer,
+ cmSearchPath const& searchPath,
+ std::size_t const startIndex = 0)
+{
+ const auto& paths = searchPath.GetPaths();
+ if (paths.empty()) {
+ buffer += " none\n";
+ return 0;
+ }
+ for (auto i = startIndex; i < paths.size(); i++) {
+ buffer += " " + paths[i].Path + "\n";
+ }
+ return paths.size();
+}
+
+#if !(defined(_WIN32) && !defined(__CYGWIN__))
+class cmFindPackageCommandHoldFile
+{
+ const char* File;
+
+public:
+ cmFindPackageCommandHoldFile(const char* const f)
+ : File(f)
+ {
+ }
+ ~cmFindPackageCommandHoldFile()
+ {
+ if (this->File) {
+ cmSystemTools::RemoveFile(this->File);
+ }
+ }
+ cmFindPackageCommandHoldFile(const cmFindPackageCommandHoldFile&) = delete;
+ cmFindPackageCommandHoldFile& operator=(
+ const cmFindPackageCommandHoldFile&) = delete;
+ void Release() { this->File = nullptr; }
+};
+#endif
+
+bool isDirentryToIgnore(const char* const fname)
+{
+ assert(fname != nullptr);
+ assert(fname[0] != 0);
+ return fname[0] == '.' &&
+ (fname[1] == 0 || (fname[1] == '.' && fname[2] == 0));
+}
+
+class cmAppendPathSegmentGenerator
+{
+public:
+ cmAppendPathSegmentGenerator(cm::string_view dirName)
+ : DirName{ dirName }
+ {
+ }
+
+ std::string GetNextCandidate(const std::string& parent)
+ {
+ if (this->NeedReset) {
+ return {};
+ }
+ this->NeedReset = true;
+ return cmStrCat(parent, '/', this->DirName);
+ }
+
+ void Reset() { this->NeedReset = false; }
+
+private:
+ const cm::string_view DirName;
+ bool NeedReset = false;
+};
+
+class cmEnumPathSegmentsGenerator
+{
+public:
+ cmEnumPathSegmentsGenerator(const std::vector<cm::string_view>& init)
+ : Names{ init }
+ , Current{ this->Names.get().cbegin() }
+ {
+ }
+
+ std::string GetNextCandidate(const std::string& parent)
+ {
+ if (this->Current != this->Names.get().cend()) {
+ return cmStrCat(parent, '/', *this->Current++);
+ }
+ return {};
+ }
+
+ void Reset() { this->Current = this->Names.get().cbegin(); }
+
+private:
+ std::reference_wrapper<const std::vector<cm::string_view>> Names;
+ std::vector<cm::string_view>::const_iterator Current;
+};
+
+class cmCaseInsensitiveDirectoryListGenerator
+{
+public:
+ cmCaseInsensitiveDirectoryListGenerator(cm::string_view name)
+ : DirectoryLister{}
+ , DirName{ name }
+ {
+ }
+
+ std::string GetNextCandidate(const std::string& parent)
+ {
+ if (!this->Loaded) {
+ this->CurrentIdx = 0ul;
+ this->Loaded = true;
+ if (!this->DirectoryLister.Load(parent)) {
+ return {};
+ }
+ }
+
+ while (this->CurrentIdx < this->DirectoryLister.GetNumberOfFiles()) {
+ const char* const fname =
+ this->DirectoryLister.GetFile(this->CurrentIdx++);
+ if (isDirentryToIgnore(fname)) {
+ continue;
+ }
+ if (cmsysString_strcasecmp(fname, this->DirName.data()) == 0) {
+ auto candidate = cmStrCat(parent, '/', fname);
+ if (cmSystemTools::FileIsDirectory(candidate)) {
+ return candidate;
+ }
+ }
+ }
+ return {};
+ }
+
+ void Reset() { this->Loaded = false; }
+
+private:
+ cmsys::Directory DirectoryLister;
+ const cm::string_view DirName;
+ unsigned long CurrentIdx = 0ul;
+ bool Loaded = false;
+};
+
+class cmDirectoryListGenerator
+{
+public:
+ cmDirectoryListGenerator(std::vector<std::string> const& names)
+ : Names{ names }
+ , Matches{}
+ , Current{ this->Matches.cbegin() }
+ {
+ }
+ virtual ~cmDirectoryListGenerator() = default;
+
+ std::string GetNextCandidate(const std::string& parent)
+ {
+ // Construct a list of matches if not yet
+ if (this->Matches.empty()) {
+ cmsys::Directory directoryLister;
+ // ALERT `Directory::Load()` keeps only names
+ // internally and LOST entry type from `dirent`.
+ // So, `Directory::FileIsDirectory` gonna use
+ // `SystemTools::FileIsDirectory()` and waste a syscall.
+ // TODO Need to enhance the `Directory` class.
+ directoryLister.Load(parent);
+
+ // ATTENTION Is it guaranteed that first two entries are
+ // `.` and `..`?
+ // TODO If so, just start with index 2 and drop the
+ // `isDirentryToIgnore(i)` condition to check.
+ for (auto i = 0ul; i < directoryLister.GetNumberOfFiles(); ++i) {
+ const char* const fname = directoryLister.GetFile(i);
+ if (isDirentryToIgnore(fname)) {
+ continue;
+ }
+
+ for (const auto& n : this->Names.get()) {
+ // NOTE Customization point for `cmMacProjectDirectoryListGenerator`
+ const auto name = this->TransformNameBeforeCmp(n);
+ // Skip entries that don't match and non-directories.
+ // ATTENTION BTW, original code also didn't check if it's a symlink
+ // to a directory!
+ const auto equal =
+ (cmsysString_strncasecmp(fname, name.c_str(), name.length()) == 0);
+ if (equal && directoryLister.FileIsDirectory(i)) {
+ this->Matches.emplace_back(fname);
+ }
+ }
+ }
+ // NOTE Customization point for `cmProjectDirectoryListGenerator`
+ this->OnMatchesLoaded();
+
+ this->Current = this->Matches.cbegin();
+ }
+
+ if (this->Current != this->Matches.cend()) {
+ auto candidate = cmStrCat(parent, '/', *this->Current++);
+ return candidate;
+ }
+
+ return {};
+ }
+
+ void Reset()
+ {
+ this->Matches.clear();
+ this->Current = this->Matches.cbegin();
+ }
+
+protected:
+ virtual void OnMatchesLoaded() {}
+ virtual std::string TransformNameBeforeCmp(std::string same) { return same; }
+
+ std::reference_wrapper<const std::vector<std::string>> Names;
+ std::vector<std::string> Matches;
+ std::vector<std::string>::const_iterator Current;
+};
+
+class cmProjectDirectoryListGenerator : public cmDirectoryListGenerator
+{
+public:
+ cmProjectDirectoryListGenerator(std::vector<std::string> const& names,
+ cmFindPackageCommand::SortOrderType so,
+ cmFindPackageCommand::SortDirectionType sd)
+ : cmDirectoryListGenerator{ names }
+ , SortOrder{ so }
+ , SortDirection{ sd }
+ {
+ }
+
+ void OnMatchesLoaded() override
+ {
+ // check if there is a specific sorting order to perform
+ if (this->SortOrder != cmFindPackageCommand::None) {
+ cmFindPackageCommand::Sort(this->Matches.begin(), this->Matches.end(),
+ this->SortOrder, this->SortDirection);
+ }
+ }
+
+private:
+ // sort parameters
+ const cmFindPackageCommand::SortOrderType SortOrder;
+ const cmFindPackageCommand::SortDirectionType SortDirection;
+};
+
+class cmMacProjectDirectoryListGenerator : public cmDirectoryListGenerator
+{
+public:
+ cmMacProjectDirectoryListGenerator(const std::vector<std::string>& names,
+ cm::string_view ext)
+ : cmDirectoryListGenerator{ names }
+ , Extension{ ext }
+ {
+ }
+
+ std::string TransformNameBeforeCmp(std::string name) override
+ {
+ return cmStrCat(name, this->Extension);
+ }
+
+private:
+ const cm::string_view Extension;
+};
+
+class cmFileListGeneratorGlob
+{
+public:
+ cmFileListGeneratorGlob(cm::string_view pattern)
+ : Pattern(pattern)
+ , Files{}
+ , Current{}
+ {
+ }
+
+ std::string GetNextCandidate(const std::string& parent)
+ {
+ if (this->Files.empty()) {
+ // Glob the set of matching files.
+ std::string expr = cmStrCat(parent, this->Pattern);
+ cmsys::Glob g;
+ if (!g.FindFiles(expr)) {
+ return {};
+ }
+ this->Files = g.GetFiles();
+ this->Current = this->Files.cbegin();
+ }
+
+ // Skip non-directories
+ for (; this->Current != this->Files.cend() &&
+ !cmSystemTools::FileIsDirectory(*this->Current);
+ ++this->Current) {
+ }
+
+ return (this->Current != this->Files.cend()) ? *this->Current++
+ : std::string{};
+ }
+
+ void Reset()
+ {
+ this->Files.clear();
+ this->Current = this->Files.cbegin();
+ }
+
+private:
+ cm::string_view Pattern;
+ std::vector<std::string> Files;
+ std::vector<std::string>::const_iterator Current;
+};
+
+#if defined(__LCC__)
+# define CM_LCC_DIAG_SUPPRESS_1222
+# 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
+#endif
+
+void ResetGenerator()
+{
+}
+
+template <typename Generator>
+void ResetGenerator(Generator&& generator)
+{
+ std::forward<Generator&&>(generator).Reset();
+}
+
+template <typename Generator, typename... Generators>
+void ResetGenerator(Generator&& generator, Generators&&... generators)
+{
+ ResetGenerator(std::forward<Generator&&>(generator));
+ ResetGenerator(std::forward<Generators&&>(generators)...);
+}
+
+template <typename CallbackFn>
+bool TryGeneratedPaths(CallbackFn&& filesCollector,
+ const std::string& fullPath)
+{
+ assert(!fullPath.empty() && fullPath.back() != '/');
+ return std::forward<CallbackFn&&>(filesCollector)(fullPath + '/');
+}
+
+template <typename CallbackFn, typename Generator, typename... Rest>
+bool TryGeneratedPaths(CallbackFn&& filesCollector,
+ const std::string& startPath, Generator&& gen,
+ Rest&&... tail)
+{
+ ResetGenerator(std::forward<Generator&&>(gen));
+ for (auto path = gen.GetNextCandidate(startPath); !path.empty();
+ path = gen.GetNextCandidate(startPath)) {
+ ResetGenerator(std::forward<Rest&&>(tail)...);
+ if (TryGeneratedPaths(std::forward<CallbackFn&&>(filesCollector), path,
+ std::forward<Rest&&>(tail)...)) {
+ return true;
+ }
+ }
+ return false;
+}
+
+#ifdef CM_LCC_DIAG_SUPPRESS_3288
+# undef CM_LCC_DIAG_SUPPRESS_3288
+# pragma diag_default 3288
+#endif
+
+#ifdef CM_LCC_DIAG_SUPPRESS_1222
+# undef CM_LCC_DIAG_SUPPRESS_1222
+# pragma diag_default 1222
+#endif
+
+// Parse the version number and store the results that were
+// successfully parsed.
+int parseVersion(const std::string& version, unsigned int& major,
+ unsigned int& minor, unsigned int& patch, unsigned int& tweak)
+{
+ return std::sscanf(version.c_str(), "%u.%u.%u.%u", &major, &minor, &patch,
+ &tweak);
+}
+
+} // anonymous namespace
cmFindPackageCommand::PathLabel
cmFindPackageCommand::PathLabel::PackageRedirect("PACKAGE_REDIRECT");
@@ -60,25 +454,10 @@ const cm::string_view cmFindPackageCommand::VERSION_ENDPOINT_INCLUDED(
const cm::string_view cmFindPackageCommand::VERSION_ENDPOINT_EXCLUDED(
"EXCLUDE");
-struct StrverscmpGreater
-{
- bool operator()(const std::string& lhs, const std::string& rhs) const
- {
- return cmSystemTools::strverscmp(lhs, rhs) > 0;
- }
-};
-
-struct StrverscmpLesser
-{
- bool operator()(const std::string& lhs, const std::string& rhs) const
- {
- return cmSystemTools::strverscmp(lhs, rhs) < 0;
- }
-};
-
void cmFindPackageCommand::Sort(std::vector<std::string>::iterator begin,
std::vector<std::string>::iterator end,
- SortOrderType order, SortDirectionType dir)
+ SortOrderType const order,
+ SortDirectionType const dir)
{
if (order == Name_order) {
if (dir == Dec) {
@@ -86,14 +465,13 @@ void cmFindPackageCommand::Sort(std::vector<std::string>::iterator begin,
} else {
std::sort(begin, end);
}
- } else if (order == Natural)
- // natural order uses letters and numbers (contiguous numbers digit are
- // compared such that e.g. 000 00 < 01 < 010 < 09 < 0 < 1 < 9 < 10
- {
+ } else if (order == Natural) {
+ // natural order uses letters and numbers (contiguous numbers digit are
+ // compared such that e.g. 000 00 < 01 < 010 < 09 < 0 < 1 < 9 < 10
if (dir == Dec) {
- std::sort(begin, end, StrverscmpGreater());
+ std::sort(begin, end, StrverscmpOp<std::greater>());
} else {
- std::sort(begin, end, StrverscmpLesser());
+ std::sort(begin, end, StrverscmpOp<std::less>());
}
}
// else do not sort
@@ -113,11 +491,10 @@ cmFindPackageCommand::cmFindPackageCommand(cmExecutionStatus& status)
void cmFindPackageCommand::AppendSearchPathGroups()
{
- std::vector<cmFindCommon::PathLabel>* labels;
-
// Update the All group with new paths. Note that package redirection must
// take precedence over everything else, so it has to be first in the array.
- labels = &this->PathGroupLabelMap[PathGroup::All];
+ std::vector<cmFindCommon::PathLabel>* const labels =
+ &this->PathGroupLabelMap[PathGroup::All];
labels->insert(labels->begin(), PathLabel::PackageRedirect);
labels->insert(
std::find(labels->begin(), labels->end(), PathLabel::CMakeSystem),
@@ -147,15 +524,15 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args)
}
// Lookup required version of CMake.
- if (cmValue rv =
+ if (cmValue const rv =
this->Makefile->GetDefinition("CMAKE_MINIMUM_REQUIRED_VERSION")) {
unsigned int v[3] = { 0, 0, 0 };
- sscanf(rv->c_str(), "%u.%u.%u", &v[0], &v[1], &v[2]);
+ std::sscanf(rv->c_str(), "%u.%u.%u", &v[0], &v[1], &v[2]);
this->RequiredCMakeVersion = CMake_VERSION_ENCODE(v[0], v[1], v[2]);
}
// Lookup target architecture, if any.
- if (cmValue arch =
+ if (cmValue const arch =
this->Makefile->GetDefinition("CMAKE_LIBRARY_ARCHITECTURE")) {
this->LibraryArchitecture = *arch;
}
@@ -184,7 +561,7 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args)
// Check if User Package Registry should be disabled
// The `CMAKE_FIND_USE_PACKAGE_REGISTRY` has
// priority over the deprecated CMAKE_FIND_PACKAGE_NO_PACKAGE_REGISTRY
- if (cmValue def =
+ if (cmValue const def =
this->Makefile->GetDefinition("CMAKE_FIND_USE_PACKAGE_REGISTRY")) {
this->NoUserRegistry = !cmIsOn(*def);
} else if (this->Makefile->IsOn("CMAKE_FIND_PACKAGE_NO_PACKAGE_REGISTRY")) {
@@ -194,7 +571,7 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args)
// Check if System Package Registry should be disabled
// The `CMAKE_FIND_USE_SYSTEM_PACKAGE_REGISTRY` has
// priority over the deprecated CMAKE_FIND_PACKAGE_NO_SYSTEM_PACKAGE_REGISTRY
- if (cmValue def = this->Makefile->GetDefinition(
+ if (cmValue const def = this->Makefile->GetDefinition(
"CMAKE_FIND_USE_SYSTEM_PACKAGE_REGISTRY")) {
this->NoSystemRegistry = !cmIsOn(*def);
} else if (this->Makefile->IsOn(
@@ -208,7 +585,7 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args)
}
// Check if Sorting should be enabled
- if (cmValue so =
+ if (cmValue const so =
this->Makefile->GetDefinition("CMAKE_FIND_PACKAGE_SORT_ORDER")) {
if (*so == "NAME") {
@@ -219,7 +596,7 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args)
this->SortOrder = None;
}
}
- if (cmValue sd =
+ if (cmValue const sd =
this->Makefile->GetDefinition("CMAKE_FIND_PACKAGE_SORT_DIRECTION")) {
this->SortDirection = (*sd == "ASC") ? Asc : Dec;
}
@@ -265,9 +642,9 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args)
cmsys::RegularExpression versionRegex(
R"V(^([0-9]+(\.[0-9]+)*)(\.\.\.(<?)([0-9]+(\.[0-9]+)*))?$)V");
bool haveVersion = false;
- std::set<unsigned int> configArgs;
- std::set<unsigned int> moduleArgs;
- for (unsigned int i = 1; i < args.size(); ++i) {
+ std::vector<std::size_t> configArgs;
+ std::vector<std::size_t> moduleArgs;
+ for (std::size_t i = 1u; i < args.size(); ++i) {
if (args[i] == "QUIET") {
this->Quiet = true;
doing = DoingNone;
@@ -281,17 +658,17 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args)
this->GlobalScope = true;
doing = DoingNone;
} else if (args[i] == "MODULE") {
- moduleArgs.insert(i);
+ moduleArgs.push_back(i);
doing = DoingNone;
// XXX(clang-tidy): https://bugs.llvm.org/show_bug.cgi?id=44165
// NOLINTNEXTLINE(bugprone-branch-clone)
} else if (args[i] == "CONFIG") {
- configArgs.insert(i);
+ configArgs.push_back(i);
doing = DoingNone;
// XXX(clang-tidy): https://bugs.llvm.org/show_bug.cgi?id=44165
// NOLINTNEXTLINE(bugprone-branch-clone)
} else if (args[i] == "NO_MODULE") {
- configArgs.insert(i);
+ configArgs.push_back(i);
doing = DoingNone;
} else if (args[i] == "REQUIRED") {
this->Required = true;
@@ -301,36 +678,36 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args)
} else if (args[i] == "OPTIONAL_COMPONENTS") {
doing = DoingOptionalComponents;
} else if (args[i] == "NAMES") {
- configArgs.insert(i);
+ configArgs.push_back(i);
doing = DoingNames;
} else if (args[i] == "PATHS") {
- configArgs.insert(i);
+ configArgs.push_back(i);
doing = DoingPaths;
} else if (args[i] == "HINTS") {
- configArgs.insert(i);
+ configArgs.push_back(i);
doing = DoingHints;
} else if (args[i] == "PATH_SUFFIXES") {
- configArgs.insert(i);
+ configArgs.push_back(i);
doing = DoingPathSuffixes;
} else if (args[i] == "CONFIGS") {
- configArgs.insert(i);
+ configArgs.push_back(i);
doing = DoingConfigs;
} else if (args[i] == "NO_POLICY_SCOPE") {
this->PolicyScope = false;
doing = DoingNone;
} else if (args[i] == "NO_CMAKE_PACKAGE_REGISTRY") {
this->NoUserRegistry = true;
- configArgs.insert(i);
+ configArgs.push_back(i);
doing = DoingNone;
} else if (args[i] == "NO_CMAKE_SYSTEM_PACKAGE_REGISTRY") {
this->NoSystemRegistry = true;
- configArgs.insert(i);
+ configArgs.push_back(i);
doing = DoingNone;
// XXX(clang-tidy): https://bugs.llvm.org/show_bug.cgi?id=44165
// NOLINTNEXTLINE(bugprone-branch-clone)
} else if (args[i] == "NO_CMAKE_BUILDS_PATH") {
// Ignore legacy option.
- configArgs.insert(i);
+ configArgs.push_back(i);
doing = DoingNone;
} else if (args[i] == "REGISTRY_VIEW") {
if (++i == args.size()) {
@@ -347,7 +724,7 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args)
return false;
}
} else if (this->CheckCommonArgument(args[i])) {
- configArgs.insert(i);
+ configArgs.push_back(i);
doing = DoingNone;
} else if ((doing == DoingComponents) ||
(doing == DoingOptionalComponents)) {
@@ -361,8 +738,8 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args)
requiredComponents.insert(args[i]);
}
- std::string req_var = this->Name + "_FIND_REQUIRED_" + args[i];
- componentVarDefs.emplace_back(req_var, isRequired);
+ componentVarDefs.emplace_back(this->Name + "_FIND_REQUIRED_" + args[i],
+ isRequired);
// Append to the list of required components.
components += components_sep;
@@ -420,11 +797,11 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args)
if (!this->UseFindModules && !this->UseConfigFiles) {
std::ostringstream e;
e << "given options exclusive to Module mode:\n";
- for (unsigned int si : moduleArgs) {
+ for (auto si : moduleArgs) {
e << " " << args[si] << "\n";
}
e << "and options exclusive to Config mode:\n";
- for (unsigned int si : configArgs) {
+ for (auto si : configArgs) {
e << " " << args[si] << "\n";
}
e << "The options are incompatible.";
@@ -443,20 +820,20 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args)
if (this->VersionComplete.empty() || components.empty()) {
// Check whether we are recursing inside "Find<name>.cmake" within
// another find_package(<name>) call.
- std::string mod = cmStrCat(this->Name, "_FIND_MODULE");
+ std::string const mod = cmStrCat(this->Name, "_FIND_MODULE");
if (this->Makefile->IsOn(mod)) {
if (this->VersionComplete.empty()) {
// Get version information from the outer call if necessary.
// Requested version string.
- std::string ver = cmStrCat(this->Name, "_FIND_VERSION_COMPLETE");
+ std::string const ver = cmStrCat(this->Name, "_FIND_VERSION_COMPLETE");
this->VersionComplete = this->Makefile->GetSafeDefinition(ver);
// Whether an exact version is required.
- std::string exact = cmStrCat(this->Name, "_FIND_VERSION_EXACT");
+ std::string const exact = cmStrCat(this->Name, "_FIND_VERSION_EXACT");
this->VersionExact = this->Makefile->IsOn(exact);
}
if (components.empty()) {
- std::string components_var = this->Name + "_FIND_COMPONENTS";
+ std::string const components_var = this->Name + "_FIND_COMPONENTS";
components = this->Makefile->GetSafeDefinition(components_var);
}
}
@@ -497,15 +874,6 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args)
return false;
}
- // Parse the version number and store the results that were
- // successfully parsed.
- auto parseVersion = [](const std::string& version, unsigned int& major,
- unsigned int& minor, unsigned int& patch,
- unsigned int& tweak) -> unsigned int {
- return sscanf(version.c_str(), "%u.%u.%u.%u", &major, &minor, &patch,
- &tweak);
- };
-
if (!this->Version.empty()) {
this->VersionCount =
parseVersion(this->Version, this->VersionMajor, this->VersionMinor,
@@ -533,7 +901,7 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args)
}
}
- std::string disableFindPackageVar =
+ std::string const disableFindPackageVar =
cmStrCat("CMAKE_DISABLE_FIND_PACKAGE_", this->Name);
if (this->Makefile->IsOn(disableFindPackageVar)) {
if (this->Required) {
@@ -557,8 +925,8 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args)
// A dependency provider (if set) gets first look before other methods.
// We do this before modifying the package root path stack because a
// provider might use methods that ignore that.
- cmState* state = this->Makefile->GetState();
- cmState::Command providerCommand = state->GetDependencyProviderCommand(
+ cmState* const state = this->Makefile->GetState();
+ cmState::Command const providerCommand = state->GetDependencyProviderCommand(
cmDependencyProvider::Method::FindPackage);
if (bypassProvider) {
if (this->DebugMode && providerCommand) {
@@ -725,11 +1093,8 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args)
"package configuration file provided by "
<< this->Name << " (" << this->Name << "Config.cmake or "
<< cmSystemTools::LowerCase(this->Name)
- << "-config.cmake). "
- "Otherwise make Find"
- << this->Name
- << ".cmake available in "
- "CMAKE_MODULE_PATH.";
+ << "-config.cmake). Otherwise make Find" << this->Name
+ << ".cmake available in CMAKE_MODULE_PATH.";
}
aw << "\n"
"(Variable CMAKE_FIND_PACKAGE_WARN_NO_MODULE enabled this "
@@ -813,9 +1178,9 @@ bool cmFindPackageCommand::FindPackageUsingConfigMode()
void cmFindPackageCommand::SetVersionVariables(
const std::function<void(const std::string&, cm::string_view)>&
addDefinition,
- const std::string& prefix, const std::string& version, unsigned int count,
- unsigned int major, unsigned int minor, unsigned int patch,
- unsigned int tweak)
+ const std::string& prefix, const std::string& version,
+ const unsigned int count, const unsigned int major, const unsigned int minor,
+ const unsigned int patch, const unsigned int tweak)
{
addDefinition(prefix, version);
@@ -910,7 +1275,7 @@ void cmFindPackageCommand::SetModuleVariables(
}
void cmFindPackageCommand::AddFindDefinition(const std::string& var,
- cm::string_view value)
+ const cm::string_view value)
{
if (cmValue old = this->Makefile->GetDefinition(var)) {
this->OriginalDefs[var].exists = true;
@@ -954,7 +1319,7 @@ bool cmFindPackageCommand::FindModule(bool& found)
if (!mfile.empty()) {
if (system) {
- auto it = this->DeprecatedFindModules.find(this->Name);
+ auto const it = this->DeprecatedFindModules.find(this->Name);
if (it != this->DeprecatedFindModules.end()) {
cmPolicies::PolicyStatus status =
this->Makefile->GetPolicyStatus(it->second);
@@ -978,13 +1343,13 @@ bool cmFindPackageCommand::FindModule(bool& found)
// Load the module we found, and set "<name>_FIND_MODULE" to true
// while inside it.
found = true;
- std::string var = cmStrCat(this->Name, "_FIND_MODULE");
+ std::string const var = cmStrCat(this->Name, "_FIND_MODULE");
this->Makefile->AddDefinition(var, "1");
bool result = this->ReadListFile(mfile, DoPolicyScope);
this->Makefile->RemoveDefinition(var);
if (this->DebugMode) {
- std::string foundVar = cmStrCat(this->Name, "_FOUND");
+ std::string const foundVar = cmStrCat(this->Name, "_FOUND");
if (this->Makefile->IsDefinitionSet(foundVar) &&
!this->Makefile->IsOn(foundVar)) {
@@ -999,7 +1364,7 @@ bool cmFindPackageCommand::FindModule(bool& found)
}
bool cmFindPackageCommand::HandlePackageMode(
- HandlePackageModeType handlePackageModeType)
+ const HandlePackageModeType handlePackageModeType)
{
this->ConsideredConfigs.clear();
@@ -1042,8 +1407,9 @@ bool cmFindPackageCommand::HandlePackageMode(
}
}
- std::string foundVar = cmStrCat(this->Name, "_FOUND");
- std::string notFoundMessageVar = cmStrCat(this->Name, "_NOT_FOUND_MESSAGE");
+ std::string const foundVar = cmStrCat(this->Name, "_FOUND");
+ std::string const notFoundMessageVar =
+ cmStrCat(this->Name, "_NOT_FOUND_MESSAGE");
std::string notFoundMessage;
// If the directory for the config file was found, try to read the file.
@@ -1123,8 +1489,9 @@ bool cmFindPackageCommand::HandlePackageMode(
<< (this->VersionExact ? "exactly matches" : "is compatible with")
<< " requested version "
<< (this->VersionRange.empty() ? "" : "range ") << "\""
- << this->VersionComplete << "\".\n"
- << "The following configuration files were considered but not "
+ << this->VersionComplete
+ << "\".\n"
+ "The following configuration files were considered but not "
"accepted:\n";
for (ConfigFileInfo const& info :
@@ -1172,8 +1539,9 @@ bool cmFindPackageCommand::HandlePackageMode(
"package or SDK, be sure it has been installed.";
} else // if(!this->UseFindModules && !this->UseConfigFiles)
{
- e << "No \"Find" << this->Name << ".cmake\" found in "
- << "CMAKE_MODULE_PATH.";
+ e << "No \"Find" << this->Name
+ << ".cmake\" found in "
+ "CMAKE_MODULE_PATH.";
aw
<< "Find" << this->Name
@@ -1217,16 +1585,16 @@ bool cmFindPackageCommand::HandlePackageMode(
this->Makefile->AddDefinition(foundVar, found ? "1" : "0");
// Set a variable naming the configuration file that was found.
- std::string fileVar = cmStrCat(this->Name, "_CONFIG");
+ std::string const fileVar = cmStrCat(this->Name, "_CONFIG");
if (found) {
this->Makefile->AddDefinition(fileVar, this->FileFound);
} else {
this->Makefile->RemoveDefinition(fileVar);
}
- std::string consideredConfigsVar =
+ std::string const consideredConfigsVar =
cmStrCat(this->Name, "_CONSIDERED_CONFIGS");
- std::string consideredVersionsVar =
+ std::string const consideredVersionsVar =
cmStrCat(this->Name, "_CONSIDERED_VERSIONS");
std::string consideredConfigFiles;
@@ -1312,7 +1680,7 @@ bool cmFindPackageCommand::FindConfig()
void cmFindPackageCommand::SetConfigDirCacheVariable(const std::string& value)
{
- std::string help =
+ std::string const help =
cmStrCat("The directory containing a CMake configuration file for ",
this->Name, '.');
this->Makefile->AddCacheDefinition(this->Variable, value, help.c_str(),
@@ -1351,7 +1719,7 @@ bool cmFindPackageCommand::FindAppBundleConfig()
}
bool cmFindPackageCommand::ReadListFile(const std::string& f,
- PolicyScopeRule psr)
+ const PolicyScopeRule psr)
{
const bool noPolicyScope = !this->PolicyScope || psr == NoPolicyScope;
@@ -1362,12 +1730,12 @@ bool cmFindPackageCommand::ReadListFile(const std::string& f,
if (this->Makefile->ReadDependentFile(f, noPolicyScope)) {
return true;
}
- std::string e = cmStrCat("Error reading CMake code from \"", f, "\".");
+ std::string const e = cmStrCat("Error reading CMake code from \"", f, "\".");
this->SetError(e);
return false;
}
-void cmFindPackageCommand::AppendToFoundProperty(bool found)
+void cmFindPackageCommand::AppendToFoundProperty(const bool found)
{
std::vector<std::string> foundContents;
cmValue foundProp =
@@ -1410,27 +1778,28 @@ void cmFindPackageCommand::AppendToFoundProperty(bool found)
void cmFindPackageCommand::AppendSuccessInformation()
{
{
- std::string transitivePropName =
+ std::string const transitivePropName =
cmStrCat("_CMAKE_", this->Name, "_TRANSITIVE_DEPENDENCY");
this->Makefile->GetState()->SetGlobalProperty(transitivePropName, "False");
}
- std::string found = cmStrCat(this->Name, "_FOUND");
- std::string upperFound = cmSystemTools::UpperCase(found);
+ std::string const found = cmStrCat(this->Name, "_FOUND");
+ std::string const upperFound = cmSystemTools::UpperCase(found);
- bool upperResult = this->Makefile->IsOn(upperFound);
- bool result = this->Makefile->IsOn(found);
- bool packageFound = (result || upperResult);
+ bool const upperResult = this->Makefile->IsOn(upperFound);
+ bool const result = this->Makefile->IsOn(found);
+ bool const packageFound = (result || upperResult);
this->AppendToFoundProperty(packageFound);
// Record whether the find was quiet or not, so this can be used
// e.g. in FeatureSummary.cmake
- std::string quietInfoPropName = cmStrCat("_CMAKE_", this->Name, "_QUIET");
+ std::string const quietInfoPropName =
+ cmStrCat("_CMAKE_", this->Name, "_QUIET");
this->Makefile->GetState()->SetGlobalProperty(
quietInfoPropName, this->Quiet ? "TRUE" : "FALSE");
// set a global property to record the required version of this package
- std::string versionInfoPropName =
+ std::string const versionInfoPropName =
cmStrCat("_CMAKE_", this->Name, "_REQUIRED_VERSION");
std::string versionInfo;
if (!this->VersionRange.empty()) {
@@ -1442,28 +1811,13 @@ void cmFindPackageCommand::AppendSuccessInformation()
this->Makefile->GetState()->SetGlobalProperty(versionInfoPropName,
versionInfo.c_str());
if (this->Required) {
- std::string requiredInfoPropName =
+ std::string const requiredInfoPropName =
cmStrCat("_CMAKE_", this->Name, "_TYPE");
this->Makefile->GetState()->SetGlobalProperty(requiredInfoPropName,
"REQUIRED");
}
}
-inline std::size_t collectPathsForDebug(std::string& buffer,
- cmSearchPath const& searchPath,
- std::size_t startIndex = 0)
-{
- const auto& paths = searchPath.GetPaths();
- if (paths.empty()) {
- buffer += " none\n";
- return 0;
- }
- for (std::size_t i = startIndex; i < paths.size(); i++) {
- buffer += " " + paths[i].Path + "\n";
- }
- return paths.size();
-}
-
void cmFindPackageCommand::ComputePrefixes()
{
this->FillPrefixesPackageRedirect();
@@ -1674,14 +2028,6 @@ void cmFindPackageCommand::FillPrefixesSystemRegistry()
}
#if defined(_WIN32) && !defined(__CYGWIN__)
-# include <windows.h>
-// http://msdn.microsoft.com/en-us/library/aa384253%28v=vs.85%29.aspx
-# if !defined(KEY_WOW64_32KEY)
-# define KEY_WOW64_32KEY 0x0200
-# endif
-# if !defined(KEY_WOW64_64KEY)
-# define KEY_WOW64_64KEY 0x0100
-# endif
void cmFindPackageCommand::LoadPackageRegistryWinUser()
{
// HKEY_CURRENT_USER\\Software shares 32-bit and 64-bit views.
@@ -1704,7 +2050,8 @@ void cmFindPackageCommand::LoadPackageRegistryWinSystem()
}
}
-void cmFindPackageCommand::LoadPackageRegistryWin(bool user, unsigned int view,
+void cmFindPackageCommand::LoadPackageRegistryWin(const bool user,
+ const unsigned int view,
cmSearchPath& outPaths)
{
std::wstring key = L"Software\\Kitware\\CMake\\Packages\\";
@@ -1756,28 +2103,8 @@ void cmFindPackageCommand::LoadPackageRegistryWin(bool user, unsigned int view,
RegCloseKey(hKey);
}
}
-#else
-class cmFindPackageCommandHoldFile
-{
- const char* File;
-
-public:
- cmFindPackageCommandHoldFile(const char* f)
- : File(f)
- {
- }
- ~cmFindPackageCommandHoldFile()
- {
- if (this->File) {
- cmSystemTools::RemoveFile(this->File);
- }
- }
- cmFindPackageCommandHoldFile(const cmFindPackageCommandHoldFile&) = delete;
- cmFindPackageCommandHoldFile& operator=(
- const cmFindPackageCommandHoldFile&) = delete;
- void Release() { this->File = nullptr; }
-};
+#else
void cmFindPackageCommand::LoadPackageRegistryDir(std::string const& dir,
cmSearchPath& outPaths)
{
@@ -1877,7 +2204,7 @@ void cmFindPackageCommand::FillPrefixesCMakeSystemVariable()
std::vector<std::string> expanded = cmExpandedList(*prefix_paths);
long count = 0;
for (const auto& path : expanded) {
- bool to_add =
+ bool const to_add =
!(path == install_path_to_remove && ++count == install_prefix_count);
if (to_add) {
paths.AddPath(path);
@@ -1941,7 +2268,7 @@ bool cmFindPackageCommand::SearchDirectory(std::string const& dir)
std::string d = dir;
if (!s.empty()) {
d += s;
- d += "/";
+ d += '/';
}
if (this->CheckDirectory(d)) {
return true;
@@ -1955,7 +2282,7 @@ bool cmFindPackageCommand::CheckDirectory(std::string const& dir)
assert(!dir.empty() && dir.back() == '/');
// Look for the file in this directory.
- std::string d = dir.substr(0, dir.size() - 1);
+ std::string const d = dir.substr(0, dir.size() - 1);
if (this->FindConfigFile(d, this->FileFound)) {
// Remove duplicate slashes.
cmSystemTools::ConvertToUnixSlashes(this->FileFound);
@@ -2028,8 +2355,8 @@ bool cmFindPackageCommand::CheckVersionFile(std::string const& version_file,
std::string& result_version)
{
// The version file will be loaded in an isolated scope.
- cmMakefile::ScopePushPop varScope(this->Makefile);
- cmMakefile::PolicyPushPop polScope(this->Makefile);
+ cmMakefile::ScopePushPop const varScope(this->Makefile);
+ cmMakefile::PolicyPushPop const polScope(this->Makefile);
static_cast<void>(varScope);
static_cast<void>(polScope);
@@ -2076,7 +2403,7 @@ bool cmFindPackageCommand::CheckVersionFile(std::string const& version_file,
if (this->ReadListFile(version_file, NoPolicyScope)) {
// Check the output variables.
bool okay = this->Makefile->IsOn("PACKAGE_VERSION_EXACT");
- bool unsuitable = this->Makefile->IsOn("PACKAGE_VERSION_UNSUITABLE");
+ bool const unsuitable = this->Makefile->IsOn("PACKAGE_VERSION_UNSUITABLE");
if (!okay && !this->VersionExact) {
okay = this->Makefile->IsOn("PACKAGE_VERSION_COMPATIBLE");
}
@@ -2096,8 +2423,8 @@ bool cmFindPackageCommand::CheckVersionFile(std::string const& version_file,
unsigned int parsed_patch;
unsigned int parsed_tweak;
this->VersionFoundCount =
- sscanf(this->VersionFound.c_str(), "%u.%u.%u.%u", &parsed_major,
- &parsed_minor, &parsed_patch, &parsed_tweak);
+ parseVersion(this->VersionFound, parsed_major, parsed_minor,
+ parsed_patch, parsed_tweak);
switch (this->VersionFoundCount) {
case 4:
this->VersionFoundTweak = parsed_tweak;
@@ -2129,7 +2456,7 @@ bool cmFindPackageCommand::CheckVersionFile(std::string const& version_file,
void cmFindPackageCommand::StoreVersionFound()
{
// Store the whole version string.
- std::string ver = cmStrCat(this->Name, "_VERSION");
+ std::string const ver = cmStrCat(this->Name, "_VERSION");
auto addDefinition = [this](const std::string& variable,
cm::string_view value) {
this->Makefile->AddDefinition(variable, value);
@@ -2145,357 +2472,6 @@ void cmFindPackageCommand::StoreVersionFound()
}
}
-class cmFileListGeneratorBase
-{
-public:
- virtual ~cmFileListGeneratorBase() = default;
-
-protected:
- bool Consider(std::string const& fullPath, cmFileList& listing);
-
-private:
- bool Search(cmFileList&);
- virtual bool Search(std::string const& parent, cmFileList&) = 0;
- virtual std::unique_ptr<cmFileListGeneratorBase> Clone() const = 0;
- friend class cmFileList;
- cmFileListGeneratorBase* SetNext(cmFileListGeneratorBase const& next);
- std::unique_ptr<cmFileListGeneratorBase> Next;
-};
-
-class cmFileList
-{
-public:
- virtual ~cmFileList() = default;
- cmFileList& operator/(cmFileListGeneratorBase const& rhs)
- {
- if (this->Last) {
- this->Last = this->Last->SetNext(rhs);
- } else {
- this->First = rhs.Clone();
- this->Last = this->First.get();
- }
- return *this;
- }
- bool Search()
- {
- if (this->First) {
- return this->First->Search(*this);
- }
- return false;
- }
-
-private:
- virtual bool Visit(std::string const& fullPath) = 0;
- friend class cmFileListGeneratorBase;
- std::unique_ptr<cmFileListGeneratorBase> First;
- cmFileListGeneratorBase* Last = nullptr;
-};
-
-class cmFindPackageFileList : public cmFileList
-{
-public:
- cmFindPackageFileList(cmFindPackageCommand* fpc, bool use_suffixes = true)
- : FPC(fpc)
- , UseSuffixes(use_suffixes)
- {
- }
-
-private:
- bool Visit(std::string const& fullPath) override
- {
- if (this->UseSuffixes) {
- return this->FPC->SearchDirectory(fullPath);
- }
- return this->FPC->CheckDirectory(fullPath);
- }
- cmFindPackageCommand* FPC;
- bool UseSuffixes;
-};
-
-bool cmFileListGeneratorBase::Search(cmFileList& listing)
-{
- return this->Search("", listing);
-}
-
-cmFileListGeneratorBase* cmFileListGeneratorBase::SetNext(
- cmFileListGeneratorBase const& next)
-{
- this->Next = next.Clone();
- return this->Next.get();
-}
-
-bool cmFileListGeneratorBase::Consider(std::string const& fullPath,
- cmFileList& listing)
-{
- if (!fullPath.empty() && !cmSystemTools::FileIsDirectory(fullPath)) {
- return false;
- }
- if (this->Next) {
- return this->Next->Search(fullPath + "/", listing);
- }
- return listing.Visit(fullPath + "/");
-}
-
-class cmFileListGeneratorFixed : public cmFileListGeneratorBase
-{
-public:
- cmFileListGeneratorFixed(std::string str)
- : String(std::move(str))
- {
- }
- cmFileListGeneratorFixed(cmFileListGeneratorFixed const& r)
- : String(r.String)
- {
- }
-
-private:
- std::string String;
- bool Search(std::string const& parent, cmFileList& lister) override
- {
- std::string fullPath = parent + this->String;
- return this->Consider(fullPath, lister);
- }
- std::unique_ptr<cmFileListGeneratorBase> Clone() const override
- {
- std::unique_ptr<cmFileListGeneratorBase> g(
- new cmFileListGeneratorFixed(*this));
- return g;
- }
-};
-
-class cmFileListGeneratorEnumerate : public cmFileListGeneratorBase
-{
-public:
- cmFileListGeneratorEnumerate(std::vector<std::string> const& v)
- : Vector(v)
- {
- }
- cmFileListGeneratorEnumerate(cmFileListGeneratorEnumerate const& r)
- : Vector(r.Vector)
- {
- }
-
-private:
- std::vector<std::string> const& Vector;
- bool Search(std::string const& parent, cmFileList& lister) override
- {
- for (std::string const& i : this->Vector) {
- if (this->Consider(parent + i, lister)) {
- return true;
- }
- }
- return false;
- }
- std::unique_ptr<cmFileListGeneratorBase> Clone() const override
- {
- std::unique_ptr<cmFileListGeneratorBase> g(
- new cmFileListGeneratorEnumerate(*this));
- return g;
- }
-};
-
-class cmFileListGeneratorProject : public cmFileListGeneratorBase
-{
-public:
- cmFileListGeneratorProject(std::vector<std::string> const& names,
- cmFindPackageCommand::SortOrderType so,
- cmFindPackageCommand::SortDirectionType sd)
- : Names(names)
- {
- this->SetSort(so, sd);
- }
- cmFileListGeneratorProject(cmFileListGeneratorProject const& r)
- : Names(r.Names)
- {
- this->SetSort(r.SortOrder, r.SortDirection);
- }
-
- void SetSort(cmFindPackageCommand::SortOrderType o,
- cmFindPackageCommand::SortDirectionType d)
- {
- this->SortOrder = o;
- this->SortDirection = d;
- }
-
-protected:
- // sort parameters
- cmFindPackageCommand::SortOrderType SortOrder;
- cmFindPackageCommand::SortDirectionType SortDirection;
-
-private:
- std::vector<std::string> const& Names;
- bool Search(std::string const& parent, cmFileList& lister) override
- {
- // Construct a list of matches.
- std::vector<std::string> matches;
- cmsys::Directory d;
- d.Load(parent);
- for (unsigned long i = 0; i < d.GetNumberOfFiles(); ++i) {
- const char* fname = d.GetFile(i);
- if (strcmp(fname, ".") == 0 || strcmp(fname, "..") == 0) {
- continue;
- }
- for (std::string const& n : this->Names) {
- if (cmsysString_strncasecmp(fname, n.c_str(), n.length()) == 0) {
- matches.emplace_back(fname);
- }
- }
- }
-
- // before testing the matches check if there is a specific sorting order to
- // perform
- if (this->SortOrder != cmFindPackageCommand::None) {
- cmFindPackageCommand::Sort(matches.begin(), matches.end(),
- this->SortOrder, this->SortDirection);
- }
-
- for (std::string const& i : matches) {
- if (this->Consider(parent + i, lister)) {
- return true;
- }
- }
- return false;
- }
- std::unique_ptr<cmFileListGeneratorBase> Clone() const override
- {
- std::unique_ptr<cmFileListGeneratorBase> g(
- new cmFileListGeneratorProject(*this));
- return g;
- }
-};
-
-class cmFileListGeneratorMacProject : public cmFileListGeneratorBase
-{
-public:
- cmFileListGeneratorMacProject(std::vector<std::string> const& names,
- const char* ext)
- : Names(names)
- , Extension(ext)
- {
- }
- cmFileListGeneratorMacProject(cmFileListGeneratorMacProject const& r)
- : Names(r.Names)
- , Extension(r.Extension)
- {
- }
-
-private:
- std::vector<std::string> const& Names;
- std::string Extension;
- bool Search(std::string const& parent, cmFileList& lister) override
- {
- // Construct a list of matches.
- std::vector<std::string> matches;
- cmsys::Directory d;
- d.Load(parent);
- for (unsigned long i = 0; i < d.GetNumberOfFiles(); ++i) {
- const char* fname = d.GetFile(i);
- if (strcmp(fname, ".") == 0 || strcmp(fname, "..") == 0) {
- continue;
- }
- for (std::string name : this->Names) {
- name += this->Extension;
- if (cmsysString_strcasecmp(fname, name.c_str()) == 0) {
- matches.emplace_back(fname);
- }
- }
- }
-
- for (std::string const& i : matches) {
- if (this->Consider(parent + i, lister)) {
- return true;
- }
- }
- return false;
- }
- std::unique_ptr<cmFileListGeneratorBase> Clone() const override
- {
- std::unique_ptr<cmFileListGeneratorBase> g(
- new cmFileListGeneratorMacProject(*this));
- return g;
- }
-};
-
-class cmFileListGeneratorCaseInsensitive : public cmFileListGeneratorBase
-{
-public:
- cmFileListGeneratorCaseInsensitive(std::string str)
- : String(std::move(str))
- {
- }
- cmFileListGeneratorCaseInsensitive(
- cmFileListGeneratorCaseInsensitive const& r)
- : String(r.String)
- {
- }
-
-private:
- std::string String;
- bool Search(std::string const& parent, cmFileList& lister) override
- {
- // Look for matching files.
- std::vector<std::string> matches;
- cmsys::Directory d;
- d.Load(parent);
- for (unsigned long i = 0; i < d.GetNumberOfFiles(); ++i) {
- const char* fname = d.GetFile(i);
- if (strcmp(fname, ".") == 0 || strcmp(fname, "..") == 0) {
- continue;
- }
- if (cmsysString_strcasecmp(fname, this->String.c_str()) == 0) {
- if (this->Consider(parent + fname, lister)) {
- return true;
- }
- }
- }
- return false;
- }
- std::unique_ptr<cmFileListGeneratorBase> Clone() const override
- {
- std::unique_ptr<cmFileListGeneratorBase> g(
- new cmFileListGeneratorCaseInsensitive(*this));
- return g;
- }
-};
-
-class cmFileListGeneratorGlob : public cmFileListGeneratorBase
-{
-public:
- cmFileListGeneratorGlob(std::string str)
- : Pattern(std::move(str))
- {
- }
- cmFileListGeneratorGlob(cmFileListGeneratorGlob const& r)
- : Pattern(r.Pattern)
- {
- }
-
-private:
- std::string Pattern;
- bool Search(std::string const& parent, cmFileList& lister) override
- {
- // Glob the set of matching files.
- std::string expr = cmStrCat(parent, this->Pattern);
- cmsys::Glob g;
- if (!g.FindFiles(expr)) {
- return false;
- }
- std::vector<std::string> const& files = g.GetFiles();
-
- // Look for directories among the matches.
- for (std::string const& f : files) {
- if (this->Consider(f, lister)) {
- return true;
- }
- }
- return false;
- }
- std::unique_ptr<cmFileListGeneratorBase> Clone() const override
- {
- return cm::make_unique<cmFileListGeneratorGlob>(*this);
- }
-};
-
bool cmFindPackageCommand::SearchPrefix(std::string const& prefix_in)
{
assert(!prefix_in.empty() && prefix_in.back() == '/');
@@ -2515,148 +2491,95 @@ bool cmFindPackageCommand::SearchPrefix(std::string const& prefix_in)
return false;
}
- // PREFIX/ (useful on windows or in build trees)
+ // PREFIX/ (useful on windows or in build trees)
if (this->SearchDirectory(prefix_in)) {
return true;
}
// Strip the trailing slash because the path generator is about to
// add one.
- std::string prefix = prefix_in.substr(0, prefix_in.size() - 1);
+ std::string const prefix = prefix_in.substr(0, prefix_in.size() - 1);
- // PREFIX/(cmake|CMake)/ (useful on windows or in build trees)
- {
- cmFindPackageFileList lister(this);
- lister / cmFileListGeneratorFixed(prefix) /
- cmFileListGeneratorCaseInsensitive("cmake");
- if (lister.Search()) {
- return true;
- }
+ auto searchFn = [this](const std::string& fullPath) -> bool {
+ return this->SearchDirectory(fullPath);
+ };
+
+ auto iCMakeGen = cmCaseInsensitiveDirectoryListGenerator{ "cmake"_s };
+ auto firstPkgDirGen =
+ cmProjectDirectoryListGenerator{ this->Names, this->SortOrder,
+ this->SortDirection };
+
+ // PREFIX/(cmake|CMake)/ (useful on windows or in build trees)
+ if (TryGeneratedPaths(searchFn, prefix, iCMakeGen)) {
+ return true;
}
- // PREFIX/(Foo|foo|FOO).*/
- {
- cmFindPackageFileList lister(this);
- lister / cmFileListGeneratorFixed(prefix) /
- cmFileListGeneratorProject(this->Names, this->SortOrder,
- this->SortDirection);
- if (lister.Search()) {
- return true;
- }
+ // PREFIX/(Foo|foo|FOO).*/
+ if (TryGeneratedPaths(searchFn, prefix, firstPkgDirGen)) {
+ return true;
}
- // PREFIX/(Foo|foo|FOO).*/(cmake|CMake)/
- {
- cmFindPackageFileList lister(this);
- lister / cmFileListGeneratorFixed(prefix) /
- cmFileListGeneratorProject(this->Names, this->SortOrder,
- this->SortDirection) /
- cmFileListGeneratorCaseInsensitive("cmake");
- if (lister.Search()) {
- return true;
- }
+ // PREFIX/(Foo|foo|FOO).*/(cmake|CMake)/
+ if (TryGeneratedPaths(searchFn, prefix, firstPkgDirGen, iCMakeGen)) {
+ return true;
}
// Construct list of common install locations (lib and share).
- std::vector<std::string> common;
+ std::vector<cm::string_view> common;
+ std::string libArch;
if (!this->LibraryArchitecture.empty()) {
- common.push_back("lib/" + this->LibraryArchitecture);
+ libArch = "lib/" + this->LibraryArchitecture;
+ common.emplace_back(libArch);
}
if (this->UseLib32Paths) {
- common.emplace_back("lib32");
+ common.emplace_back("lib32"_s);
}
if (this->UseLib64Paths) {
- common.emplace_back("lib64");
+ common.emplace_back("lib64"_s);
}
if (this->UseLibx32Paths) {
- common.emplace_back("libx32");
+ common.emplace_back("libx32"_s);
}
- common.emplace_back("lib");
- common.emplace_back("share");
+ common.emplace_back("lib"_s);
+ common.emplace_back("share"_s);
- // PREFIX/(lib/ARCH|lib*|share)/cmake/(Foo|foo|FOO).*/
- {
- cmFindPackageFileList lister(this);
- lister / cmFileListGeneratorFixed(prefix) /
- cmFileListGeneratorEnumerate(common) /
- cmFileListGeneratorFixed("cmake") /
- cmFileListGeneratorProject(this->Names, this->SortOrder,
- this->SortDirection);
- if (lister.Search()) {
- return true;
- }
+ auto cmnGen = cmEnumPathSegmentsGenerator{ common };
+ auto cmakeGen = cmAppendPathSegmentGenerator{ "cmake"_s };
+
+ // PREFIX/(lib/ARCH|lib*|share)/cmake/(Foo|foo|FOO).*/
+ if (TryGeneratedPaths(searchFn, prefix, cmnGen, cmakeGen, firstPkgDirGen)) {
+ return true;
}
- // PREFIX/(lib/ARCH|lib*|share)/(Foo|foo|FOO).*/
- {
- cmFindPackageFileList lister(this);
- lister / cmFileListGeneratorFixed(prefix) /
- cmFileListGeneratorEnumerate(common) /
- cmFileListGeneratorProject(this->Names, this->SortOrder,
- this->SortDirection);
- if (lister.Search()) {
- return true;
- }
+ // PREFIX/(lib/ARCH|lib*|share)/(Foo|foo|FOO).*/
+ if (TryGeneratedPaths(searchFn, prefix, cmnGen, firstPkgDirGen)) {
+ return true;
}
- // PREFIX/(lib/ARCH|lib*|share)/(Foo|foo|FOO).*/(cmake|CMake)/
- {
- cmFindPackageFileList lister(this);
- lister / cmFileListGeneratorFixed(prefix) /
- cmFileListGeneratorEnumerate(common) /
- cmFileListGeneratorProject(this->Names, this->SortOrder,
- this->SortDirection) /
- cmFileListGeneratorCaseInsensitive("cmake");
- if (lister.Search()) {
- return true;
- }
+ // PREFIX/(lib/ARCH|lib*|share)/(Foo|foo|FOO).*/(cmake|CMake)/
+ if (TryGeneratedPaths(searchFn, prefix, cmnGen, firstPkgDirGen, iCMakeGen)) {
+ return true;
}
+ auto secondPkgDirGen =
+ cmProjectDirectoryListGenerator{ this->Names, this->SortOrder,
+ this->SortDirection };
+
// PREFIX/(Foo|foo|FOO).*/(lib/ARCH|lib*|share)/cmake/(Foo|foo|FOO).*/
- {
- cmFindPackageFileList lister(this);
- lister / cmFileListGeneratorFixed(prefix) /
- cmFileListGeneratorProject(this->Names, this->SortOrder,
- this->SortDirection) /
- cmFileListGeneratorEnumerate(common) /
- cmFileListGeneratorFixed("cmake") /
- cmFileListGeneratorProject(this->Names, this->SortOrder,
- this->SortDirection);
- if (lister.Search()) {
- return true;
- }
+ if (TryGeneratedPaths(searchFn, prefix, firstPkgDirGen, cmnGen, cmakeGen,
+ secondPkgDirGen)) {
+ return true;
}
// PREFIX/(Foo|foo|FOO).*/(lib/ARCH|lib*|share)/(Foo|foo|FOO).*/
- {
- cmFindPackageFileList lister(this);
- lister / cmFileListGeneratorFixed(prefix) /
- cmFileListGeneratorProject(this->Names, this->SortOrder,
- this->SortDirection) /
- cmFileListGeneratorEnumerate(common) /
- cmFileListGeneratorProject(this->Names, this->SortOrder,
- this->SortDirection);
- if (lister.Search()) {
- return true;
- }
+ if (TryGeneratedPaths(searchFn, prefix, firstPkgDirGen, cmnGen,
+ secondPkgDirGen)) {
+ return true;
}
// PREFIX/(Foo|foo|FOO).*/(lib/ARCH|lib*|share)/(Foo|foo|FOO).*/(cmake|CMake)/
- {
- cmFindPackageFileList lister(this);
- lister / cmFileListGeneratorFixed(prefix) /
- cmFileListGeneratorProject(this->Names, this->SortOrder,
- this->SortDirection) /
- cmFileListGeneratorEnumerate(common) /
- cmFileListGeneratorProject(this->Names, this->SortOrder,
- this->SortDirection) /
- cmFileListGeneratorCaseInsensitive("cmake");
- if (lister.Search()) {
- return true;
- }
- }
-
- return false;
+ return TryGeneratedPaths(searchFn, prefix, firstPkgDirGen, cmnGen,
+ secondPkgDirGen, iCMakeGen);
}
bool cmFindPackageCommand::SearchFrameworkPrefix(std::string const& prefix_in)
@@ -2665,56 +2588,36 @@ bool cmFindPackageCommand::SearchFrameworkPrefix(std::string const& prefix_in)
// Strip the trailing slash because the path generator is about to
// add one.
- std::string prefix = prefix_in.substr(0, prefix_in.size() - 1);
+ std::string const prefix = prefix_in.substr(0, prefix_in.size() - 1);
+
+ auto searchFn = [this](const std::string& fullPath) -> bool {
+ return this->SearchDirectory(fullPath);
+ };
+
+ auto iCMakeGen = cmCaseInsensitiveDirectoryListGenerator{ "cmake"_s };
+ auto fwGen =
+ cmMacProjectDirectoryListGenerator{ this->Names, ".framework"_s };
+ auto rGen = cmAppendPathSegmentGenerator{ "Resources"_s };
+ auto vGen = cmAppendPathSegmentGenerator{ "Versions"_s };
+ auto grGen = cmFileListGeneratorGlob{ "/*/Resources"_s };
// <prefix>/Foo.framework/Resources/
- {
- cmFindPackageFileList lister(this);
- lister / cmFileListGeneratorFixed(prefix) /
- cmFileListGeneratorMacProject(this->Names, ".framework") /
- cmFileListGeneratorFixed("Resources");
- if (lister.Search()) {
- return true;
- }
+ if (TryGeneratedPaths(searchFn, prefix, fwGen, rGen)) {
+ return true;
}
+
// <prefix>/Foo.framework/Resources/CMake/
- {
- cmFindPackageFileList lister(this);
- lister / cmFileListGeneratorFixed(prefix) /
- cmFileListGeneratorMacProject(this->Names, ".framework") /
- cmFileListGeneratorFixed("Resources") /
- cmFileListGeneratorCaseInsensitive("cmake");
- if (lister.Search()) {
- return true;
- }
+ if (TryGeneratedPaths(searchFn, prefix, fwGen, rGen, iCMakeGen)) {
+ return true;
}
// <prefix>/Foo.framework/Versions/*/Resources/
- {
- cmFindPackageFileList lister(this);
- lister / cmFileListGeneratorFixed(prefix) /
- cmFileListGeneratorMacProject(this->Names, ".framework") /
- cmFileListGeneratorFixed("Versions") /
- cmFileListGeneratorGlob("*/Resources");
- if (lister.Search()) {
- return true;
- }
+ if (TryGeneratedPaths(searchFn, prefix, fwGen, vGen, grGen)) {
+ return true;
}
// <prefix>/Foo.framework/Versions/*/Resources/CMake/
- {
- cmFindPackageFileList lister(this);
- lister / cmFileListGeneratorFixed(prefix) /
- cmFileListGeneratorMacProject(this->Names, ".framework") /
- cmFileListGeneratorFixed("Versions") /
- cmFileListGeneratorGlob("*/Resources") /
- cmFileListGeneratorCaseInsensitive("cmake");
- if (lister.Search()) {
- return true;
- }
- }
-
- return false;
+ return TryGeneratedPaths(searchFn, prefix, fwGen, vGen, grGen, iCMakeGen);
}
bool cmFindPackageCommand::SearchAppBundlePrefix(std::string const& prefix_in)
@@ -2723,32 +2626,24 @@ bool cmFindPackageCommand::SearchAppBundlePrefix(std::string const& prefix_in)
// Strip the trailing slash because the path generator is about to
// add one.
- std::string prefix = prefix_in.substr(0, prefix_in.size() - 1);
+ std::string const prefix = prefix_in.substr(0, prefix_in.size() - 1);
+
+ auto searchFn = [this](const std::string& fullPath) -> bool {
+ return this->SearchDirectory(fullPath);
+ };
+
+ auto appGen = cmMacProjectDirectoryListGenerator{ this->Names, ".app"_s };
+ auto crGen = cmAppendPathSegmentGenerator{ "Contents/Resources"_s };
// <prefix>/Foo.app/Contents/Resources
- {
- cmFindPackageFileList lister(this);
- lister / cmFileListGeneratorFixed(prefix) /
- cmFileListGeneratorMacProject(this->Names, ".app") /
- cmFileListGeneratorFixed("Contents/Resources");
- if (lister.Search()) {
- return true;
- }
+ if (TryGeneratedPaths(searchFn, prefix, appGen, crGen)) {
+ return true;
}
// <prefix>/Foo.app/Contents/Resources/CMake
- {
- cmFindPackageFileList lister(this);
- lister / cmFileListGeneratorFixed(prefix) /
- cmFileListGeneratorMacProject(this->Names, ".app") /
- cmFileListGeneratorFixed("Contents/Resources") /
- cmFileListGeneratorCaseInsensitive("cmake");
- if (lister.Search()) {
- return true;
- }
- }
-
- return false;
+ return TryGeneratedPaths(
+ searchFn, prefix, appGen, crGen,
+ cmCaseInsensitiveDirectoryListGenerator{ "cmake"_s });
}
// TODO: Debug cmsys::Glob double slash problem.
diff --git a/Source/cmFindPackageCommand.h b/Source/cmFindPackageCommand.h
index 80fd8f8..28e00a1 100644
--- a/Source/cmFindPackageCommand.h
+++ b/Source/cmFindPackageCommand.h
@@ -153,8 +153,6 @@ private:
bool SearchFrameworkPrefix(std::string const& prefix_in);
bool SearchAppBundlePrefix(std::string const& prefix_in);
- friend class cmFindPackageFileList;
-
struct OriginalDef
{
bool exists;
diff --git a/Source/cmGeneratedFileStream.cxx b/Source/cmGeneratedFileStream.cxx
index b529b8f..6212bbd 100644
--- a/Source/cmGeneratedFileStream.cxx
+++ b/Source/cmGeneratedFileStream.cxx
@@ -124,10 +124,10 @@ cmGeneratedFileStreamBase::~cmGeneratedFileStreamBase()
void cmGeneratedFileStreamBase::Open(std::string const& name)
{
// Save the original name of the file.
- this->Name = name;
+ this->Name = cmSystemTools::CollapseFullPath(name);
// Create the name of the temporary file.
- this->TempName = name;
+ this->TempName = this->Name;
#if defined(__VMS)
this->TempName += "_";
#else
@@ -231,7 +231,7 @@ int cmGeneratedFileStreamBase::RenameFile(std::string const& oldname,
void cmGeneratedFileStream::SetName(const std::string& fname)
{
- this->Name = fname;
+ this->Name = cmSystemTools::CollapseFullPath(fname);
}
void cmGeneratedFileStream::SetTempExt(std::string const& ext)
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index d9c0d3f..d59ac2b 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -917,11 +917,19 @@ bool cmGeneratorTarget::IsIPOEnabled(std::string const& lang,
return false;
}
- if (lang != "C" && lang != "CXX" && lang != "Fortran") {
+ if (lang != "C" && lang != "CXX" && lang != "CUDA" && lang != "Fortran") {
// We do not define IPO behavior for other languages.
return false;
}
+ if (lang == "CUDA") {
+ // CUDA IPO requires both CUDA_ARCHITECTURES and CUDA_SEPARABLE_COMPILATION
+ if (cmIsOff(this->GetSafeProperty("CUDA_ARCHITECTURES")) ||
+ cmIsOff(this->GetSafeProperty("CUDA_SEPARABLE_COMPILATION"))) {
+ return false;
+ }
+ }
+
cmPolicies::PolicyStatus cmp0069 = this->GetPolicyStatusCMP0069();
if (cmp0069 == cmPolicies::OLD || cmp0069 == cmPolicies::WARN) {
@@ -3429,7 +3437,9 @@ void cmGeneratorTarget::AddExplicitLanguageFlags(std::string& flags,
"EXPLICIT_LANGUAGE");
}
-void cmGeneratorTarget::AddCUDAArchitectureFlags(std::string& flags) const
+void cmGeneratorTarget::AddCUDAArchitectureFlags(cmBuildStep compileOrLink,
+ const std::string& config,
+ std::string& flags) const
{
std::string property = this->GetSafeProperty("CUDA_ARCHITECTURES");
@@ -3461,6 +3471,7 @@ void cmGeneratorTarget::AddCUDAArchitectureFlags(std::string& flags) const
std::string const& compiler =
this->Makefile->GetSafeDefinition("CMAKE_CUDA_COMPILER_ID");
+ const bool ipoEnabled = this->IsIPOEnabled("CUDA", config);
// Check for special modes: `all`, `all-major`.
if (property == "all" || property == "all-major") {
@@ -3540,6 +3551,13 @@ void cmGeneratorTarget::AddCUDAArchitectureFlags(std::string& flags) const
}
if (compiler == "NVIDIA") {
+ if (ipoEnabled && compileOrLink == cmBuildStep::Link) {
+ if (cmValue cudaIPOFlags =
+ this->Makefile->GetDefinition("CMAKE_CUDA_LINK_OPTIONS_IPO")) {
+ flags += cudaIPOFlags;
+ }
+ }
+
for (CudaArchitecture& architecture : architectures) {
flags +=
" --generate-code=arch=compute_" + architecture.name + ",code=[";
@@ -3552,7 +3570,13 @@ void cmGeneratorTarget::AddCUDAArchitectureFlags(std::string& flags) const
}
}
- if (architecture.real) {
+ if (ipoEnabled) {
+ if (compileOrLink == cmBuildStep::Compile) {
+ flags += "lto_" + architecture.name;
+ } else if (compileOrLink == cmBuildStep::Link) {
+ flags += "sm_" + architecture.name;
+ }
+ } else if (architecture.real) {
flags += "sm_" + architecture.name;
}
diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h
index 349afa7..25e6a81 100644
--- a/Source/cmGeneratorTarget.h
+++ b/Source/cmGeneratorTarget.h
@@ -23,6 +23,7 @@
#include "cmStateTypes.h"
#include "cmValue.h"
+enum class cmBuildStep;
class cmComputeLinkInformation;
class cmCustomCommand;
class cmGlobalGenerator;
@@ -471,7 +472,9 @@ public:
void AddExplicitLanguageFlags(std::string& flags,
cmSourceFile const& sf) const;
- void AddCUDAArchitectureFlags(std::string& flags) const;
+ void AddCUDAArchitectureFlags(cmBuildStep compileOrLink,
+ const std::string& config,
+ std::string& flags) const;
void AddCUDAToolkitFlags(std::string& flags) const;
void AddHIPArchitectureFlags(std::string& flags) const;
diff --git a/Source/cmGhsMultiTargetGenerator.cxx b/Source/cmGhsMultiTargetGenerator.cxx
index bf019c3..138d3f1 100644
--- a/Source/cmGhsMultiTargetGenerator.cxx
+++ b/Source/cmGhsMultiTargetGenerator.cxx
@@ -183,8 +183,8 @@ void cmGhsMultiTargetGenerator::SetCompilerFlags(std::string const& config,
auto i = this->FlagsByLanguage.find(language);
if (i == this->FlagsByLanguage.end()) {
std::string flags;
- this->LocalGenerator->AddLanguageFlags(flags, this->GeneratorTarget,
- language, config);
+ this->LocalGenerator->AddLanguageFlags(
+ flags, this->GeneratorTarget, cmBuildStep::Compile, language, config);
this->LocalGenerator->AddCMP0018Flags(flags, this->GeneratorTarget,
language, config);
this->LocalGenerator->AddVisibilityPresetFlags(
diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx
index b4d5746..c326ca6 100644
--- a/Source/cmGlobalNinjaGenerator.cxx
+++ b/Source/cmGlobalNinjaGenerator.cxx
@@ -3,6 +3,7 @@
#include "cmGlobalNinjaGenerator.h"
#include <algorithm>
+#include <cassert>
#include <cctype>
#include <cstdio>
#include <functional>
@@ -2555,6 +2556,8 @@ bool cmGlobalNinjaGenerator::WriteDyndepFile(
objects.push_back(std::move(info));
}
+ CxxModuleUsage usages;
+
// Map from module name to module file path, if known.
std::map<std::string, std::string> mod_files;
@@ -2572,8 +2575,47 @@ bool cmGlobalNinjaGenerator::WriteDyndepFile(
return false;
}
if (ltm.isObject()) {
- for (Json::Value::iterator i = ltm.begin(); i != ltm.end(); ++i) {
- mod_files[i.key().asString()] = i->asString();
+ Json::Value const& target_modules = ltm["modules"];
+ if (target_modules.isObject()) {
+ for (auto i = target_modules.begin(); i != target_modules.end(); ++i) {
+ mod_files[i.key().asString()] = i->asString();
+ }
+ }
+ Json::Value const& target_modules_references = ltm["references"];
+ if (target_modules_references.isObject()) {
+ for (auto i = target_modules_references.begin();
+ i != target_modules_references.end(); ++i) {
+ if (i->isObject()) {
+ Json::Value const& reference_path = (*i)["path"];
+ CxxModuleReference module_reference;
+ if (reference_path.isString()) {
+ module_reference.Path = reference_path.asString();
+ }
+ Json::Value const& reference_method = (*i)["lookup-method"];
+ if (reference_method.isString()) {
+ std::string reference = reference_method.asString();
+ if (reference == "by-name") {
+ module_reference.Method = LookupMethod::ByName;
+ } else if (reference == "include-angle") {
+ module_reference.Method = LookupMethod::IncludeAngle;
+ } else if (reference == "include-quote") {
+ module_reference.Method = LookupMethod::IncludeQuote;
+ }
+ }
+ usages.Reference[i.key().asString()] = module_reference;
+ }
+ }
+ }
+ Json::Value const& target_modules_usage = ltm["usages"];
+ if (target_modules_usage.isObject()) {
+ for (auto i = target_modules_usage.begin();
+ i != target_modules_usage.end(); ++i) {
+ if (i->isArray()) {
+ for (auto j = i->begin(); j != i->end(); ++j) {
+ usages.Usage[i.key().asString()].insert(j->asString());
+ }
+ }
+ }
}
}
}
@@ -2583,6 +2625,8 @@ bool cmGlobalNinjaGenerator::WriteDyndepFile(
// nothing to do.
} else if (arg_modmapfmt == "gcc") {
modmap_fmt = CxxModuleMapFormat::Gcc;
+ } else if (arg_modmapfmt == "msvc") {
+ modmap_fmt = CxxModuleMapFormat::Msvc;
} else {
cmSystemTools::Error(
cmStrCat("-E cmake_ninja_dyndep does not understand the ", arg_modmapfmt,
@@ -2595,7 +2639,7 @@ bool cmGlobalNinjaGenerator::WriteDyndepFile(
// Extend the module map with those provided by this target.
// We do this after loading the modules provided by linked targets
// in case we have one of the same name that must be preferred.
- Json::Value tm = Json::objectValue;
+ Json::Value target_modules = Json::objectValue;
for (cmScanDepInfo const& object : objects) {
for (auto const& p : object.Provides) {
std::string mod;
@@ -2614,7 +2658,7 @@ bool cmGlobalNinjaGenerator::WriteDyndepFile(
mod = cmStrCat(module_dir, safe_logical_name, module_ext);
}
mod_files[p.LogicalName] = mod;
- tm[p.LogicalName] = mod;
+ target_modules[p.LogicalName] = mod;
}
}
@@ -2636,6 +2680,18 @@ bool cmGlobalNinjaGenerator::WriteDyndepFile(
return {};
};
+ // Insert information about the current target's modules.
+ if (modmap_fmt) {
+ auto cycle_modules = CxxModuleUsageSeed(locs, objects, usages);
+ if (!cycle_modules.empty()) {
+ cmSystemTools::Error(
+ cmStrCat("Circular dependency detected in the C++ module import "
+ "graph. See modules named: \"",
+ cmJoin(cycle_modules, R"(", ")"_s), '"'));
+ return false;
+ }
+ }
+
cmNinjaBuild build("dyndep");
build.Outputs.emplace_back("");
for (cmScanDepInfo const& object : objects) {
@@ -2658,7 +2714,7 @@ bool cmGlobalNinjaGenerator::WriteDyndepFile(
}
if (modmap_fmt) {
- auto mm = CxxModuleMapContent(*modmap_fmt, locs, object);
+ auto mm = CxxModuleMapContent(*modmap_fmt, locs, object, usages);
// XXX(modmap): If changing this path construction, change
// `cmNinjaTargetGenerator::WriteObjectBuildStatements` to generate the
@@ -2671,12 +2727,44 @@ bool cmGlobalNinjaGenerator::WriteDyndepFile(
}
}
+ Json::Value target_module_info = Json::objectValue;
+ target_module_info["modules"] = target_modules;
+
+ auto& target_usages = target_module_info["usages"] = Json::objectValue;
+ for (auto const& u : usages.Usage) {
+ auto& mod_usage = target_usages[u.first] = Json::arrayValue;
+ for (auto const& v : u.second) {
+ mod_usage.append(v);
+ }
+ }
+
+ auto name_for_method = [](LookupMethod method) -> cm::static_string_view {
+ switch (method) {
+ case LookupMethod::ByName:
+ return "by-name"_s;
+ case LookupMethod::IncludeAngle:
+ return "include-angle"_s;
+ case LookupMethod::IncludeQuote:
+ return "include-quote"_s;
+ }
+ assert(false && "unsupported lookup method");
+ return ""_s;
+ };
+
+ auto& target_references = target_module_info["references"] =
+ Json::objectValue;
+ for (auto const& r : usages.Reference) {
+ auto& mod_ref = target_references[r.first] = Json::objectValue;
+ mod_ref["path"] = r.second.Path;
+ mod_ref["lookup-method"] = std::string(name_for_method(r.second.Method));
+ }
+
// Store the map of modules provided by this target in a file for
// use by dependents that reference this target in linked-target-dirs.
std::string const target_mods_file = cmStrCat(
cmSystemTools::GetFilenamePath(arg_dd), '/', arg_lang, "Modules.json");
cmGeneratedFileStream tmf(target_mods_file);
- tmf << tm;
+ tmf << target_module_info;
bool result = true;
diff --git a/Source/cmGlobalVisualStudioVersionedGenerator.cxx b/Source/cmGlobalVisualStudioVersionedGenerator.cxx
index 7eca963..7e36881 100644
--- a/Source/cmGlobalVisualStudioVersionedGenerator.cxx
+++ b/Source/cmGlobalVisualStudioVersionedGenerator.cxx
@@ -67,7 +67,7 @@ static bool VSHasDotNETFrameworkArm64()
std::string dotNetArm64;
return cmSystemTools::ReadRegistryValue(
"HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\.NETFramework;InstallRootArm64",
- dotNetArm64);
+ dotNetArm64, cmSystemTools::KeyWOW64_64);
}
static bool VSIsWindows11OrGreater()
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index 456f5bc..70a379e 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -2368,8 +2368,8 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt,
std::string& flags = cflags[lang];
// Add language-specific flags.
- this->CurrentLocalGenerator->AddLanguageFlags(flags, gtgt, lang,
- configName);
+ this->CurrentLocalGenerator->AddLanguageFlags(
+ flags, gtgt, cmBuildStep::Compile, lang, configName);
if (gtgt->IsIPOEnabled(lang, configName)) {
this->CurrentLocalGenerator->AppendFeatureOptions(flags, lang, "IPO");
diff --git a/Source/cmLinkLineDeviceComputer.cxx b/Source/cmLinkLineDeviceComputer.cxx
index 43f1b8e..b06dc3d 100644
--- a/Source/cmLinkLineDeviceComputer.cxx
+++ b/Source/cmLinkLineDeviceComputer.cxx
@@ -57,7 +57,6 @@ bool cmLinkLineDeviceComputer::ComputeRequiresDeviceLinking(
// For this we only consider targets
using ItemVector = cmComputeLinkInformation::ItemVector;
ItemVector const& items = cli.GetItems();
- std::string config = cli.GetConfig();
return std::any_of(
items.begin(), items.end(),
[](cmComputeLinkInformation::Item const& item) -> bool {
@@ -69,6 +68,26 @@ bool cmLinkLineDeviceComputer::ComputeRequiresDeviceLinking(
});
}
+bool cmLinkLineDeviceComputer::ComputeRequiresDeviceLinkingIPOFlag(
+ cmComputeLinkInformation& cli)
+{
+ // Determine if this item might requires device linking.
+ // For this we only consider targets
+ using ItemVector = cmComputeLinkInformation::ItemVector;
+ ItemVector const& items = cli.GetItems();
+ std::string config = cli.GetConfig();
+ return std::any_of(
+ items.begin(), items.end(),
+ [config](cmComputeLinkInformation::Item const& item) -> bool {
+ return item.Target &&
+ item.Target->GetType() == cmStateEnums::STATIC_LIBRARY &&
+ // this dependency requires us to device link it
+ !item.Target->GetPropertyAsBool("CUDA_RESOLVE_DEVICE_SYMBOLS") &&
+ item.Target->GetPropertyAsBool("CUDA_SEPARABLE_COMPILATION") &&
+ item.Target->IsIPOEnabled("CUDA", config);
+ });
+}
+
void cmLinkLineDeviceComputer::ComputeLinkLibraries(
cmComputeLinkInformation& cli, std::string const& stdLibString,
std::vector<BT<std::string>>& linkLibraries)
diff --git a/Source/cmLinkLineDeviceComputer.h b/Source/cmLinkLineDeviceComputer.h
index dee625b..0916307 100644
--- a/Source/cmLinkLineDeviceComputer.h
+++ b/Source/cmLinkLineDeviceComputer.h
@@ -30,6 +30,7 @@ public:
delete;
bool ComputeRequiresDeviceLinking(cmComputeLinkInformation& cli);
+ bool ComputeRequiresDeviceLinkingIPOFlag(cmComputeLinkInformation& cli);
void ComputeLinkLibraries(
cmComputeLinkInformation& cli, std::string const& stdLibString,
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index 67c8bf2..7b823da 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -36,6 +36,7 @@
#include "cmInstallScriptGenerator.h"
#include "cmInstallTargetGenerator.h"
#include "cmLinkLineComputer.h"
+#include "cmLinkLineDeviceComputer.h"
#include "cmMakefile.h"
#include "cmRange.h"
#include "cmRulePlaceholderExpander.h"
@@ -1381,7 +1382,7 @@ std::vector<BT<std::string>> cmLocalGenerator::GetStaticLibraryFlags(
}
void cmLocalGenerator::GetDeviceLinkFlags(
- cmLinkLineComputer& linkLineComputer, const std::string& config,
+ cmLinkLineDeviceComputer& linkLineComputer, const std::string& config,
std::string& linkLibs, std::string& linkFlags, std::string& frameworkPath,
std::string& linkPath, cmGeneratorTarget* target)
{
@@ -1389,6 +1390,18 @@ void cmLocalGenerator::GetDeviceLinkFlags(
cmComputeLinkInformation* pcli = target->GetLinkInformation(config);
+ auto linklang = linkLineComputer.GetLinkerLanguage(target, config);
+ auto ipoEnabled = target->IsIPOEnabled(linklang, config);
+ if (!ipoEnabled) {
+ ipoEnabled = linkLineComputer.ComputeRequiresDeviceLinkingIPOFlag(*pcli);
+ }
+ if (ipoEnabled) {
+ if (cmValue cudaIPOFlags = this->Makefile->GetDefinition(
+ "CMAKE_CUDA_DEVICE_LINK_OPTIONS_IPO")) {
+ linkFlags += cudaIPOFlags;
+ }
+ }
+
if (pcli) {
// Compute the required device link libraries when
// resolving gpu lang device symbols
@@ -1396,6 +1409,8 @@ void cmLocalGenerator::GetDeviceLinkFlags(
linkPath);
}
+ // iterate link deps and see if any of them need IPO
+
std::vector<std::string> linkOpts;
target->GetLinkOptions(linkOpts, config, "CUDA");
// LINK_OPTIONS are escaped.
@@ -1590,7 +1605,8 @@ std::vector<BT<std::string>> cmLocalGenerator::GetTargetCompileFlags(
cmMakefile* mf = this->GetMakefile();
// Add language-specific flags.
- this->AddLanguageFlags(compileFlags, target, lang, config);
+ this->AddLanguageFlags(compileFlags, target, cmBuildStep::Compile, lang,
+ config);
if (target->IsIPOEnabled(lang, config)) {
this->AppendFeatureOptions(compileFlags, lang, "IPO");
@@ -1903,6 +1919,7 @@ void cmLocalGenerator::AddArchitectureFlags(std::string& flags,
void cmLocalGenerator::AddLanguageFlags(std::string& flags,
cmGeneratorTarget const* target,
+ cmBuildStep compileOrLink,
const std::string& lang,
const std::string& config)
{
@@ -1926,7 +1943,7 @@ void cmLocalGenerator::AddLanguageFlags(std::string& flags,
}
}
} else if (lang == "CUDA") {
- target->AddCUDAArchitectureFlags(flags);
+ target->AddCUDAArchitectureFlags(compileOrLink, config, flags);
target->AddCUDAToolkitFlags(flags);
} else if (lang == "ISPC") {
target->AddISPCTargetFlags(flags);
@@ -2038,7 +2055,7 @@ void cmLocalGenerator::AddLanguageFlagsForLinking(
this->AddCompilerRequirementFlag(flags, target, lang, config);
}
- this->AddLanguageFlags(flags, target, lang, config);
+ this->AddLanguageFlags(flags, target, cmBuildStep::Link, lang, config);
if (target->IsIPOEnabled(lang, config)) {
this->AppendFeatureOptions(flags, lang, "IPO");
diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h
index 7cae1fc..0529431 100644
--- a/Source/cmLocalGenerator.h
+++ b/Source/cmLocalGenerator.h
@@ -35,6 +35,7 @@ class cmGeneratorTarget;
class cmGlobalGenerator;
class cmImplicitDependsList;
class cmLinkLineComputer;
+class cmLinkLineDeviceComputer;
class cmMakefile;
class cmRulePlaceholderExpander;
class cmSourceFile;
@@ -59,6 +60,13 @@ enum class cmDependencyScannerKind
Compiler
};
+/** What to compute language flags for */
+enum class cmBuildStep
+{
+ Compile,
+ Link
+};
+
/** Target and source file which have a specific output. */
struct cmSourcesWithOutput
{
@@ -143,7 +151,8 @@ public:
const std::string& filterArch = std::string());
void AddLanguageFlags(std::string& flags, cmGeneratorTarget const* target,
- const std::string& lang, const std::string& config);
+ cmBuildStep compileOrLink, const std::string& lang,
+ const std::string& config);
void AddLanguageFlagsForLinking(std::string& flags,
cmGeneratorTarget const* target,
const std::string& lang,
@@ -476,7 +485,7 @@ public:
/** Fill out these strings for the given target. Libraries to link,
* flags, and linkflags. */
- void GetDeviceLinkFlags(cmLinkLineComputer& linkLineComputer,
+ void GetDeviceLinkFlags(cmLinkLineDeviceComputer& linkLineComputer,
const std::string& config, std::string& linkLibs,
std::string& linkFlags, std::string& frameworkPath,
std::string& linkPath, cmGeneratorTarget* target);
diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx
index f65add1..0451d96 100644
--- a/Source/cmLocalVisualStudio7Generator.cxx
+++ b/Source/cmLocalVisualStudio7Generator.cxx
@@ -680,7 +680,8 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(
langForClCompile = linkLanguage;
if (langForClCompile == "C" || langForClCompile == "CXX" ||
langForClCompile == "Fortran") {
- this->AddLanguageFlags(flags, target, langForClCompile, configName);
+ this->AddLanguageFlags(flags, target, cmBuildStep::Compile,
+ langForClCompile, configName);
}
// set the correct language
if (linkLanguage == "C") {
diff --git a/Source/cmMakefileExecutableTargetGenerator.cxx b/Source/cmMakefileExecutableTargetGenerator.cxx
index 74574f7..54f03b9 100644
--- a/Source/cmMakefileExecutableTargetGenerator.cxx
+++ b/Source/cmMakefileExecutableTargetGenerator.cxx
@@ -136,17 +136,11 @@ void cmMakefileExecutableTargetGenerator::WriteNvidiaDeviceExecutableRule(
std::vector<std::string> depends;
this->AppendLinkDepends(depends, linkLanguage);
- // Build a list of compiler flags and linker flags.
- std::string langFlags;
- std::string linkFlags;
-
// Add language feature flags.
+ std::string langFlags;
this->LocalGenerator->AddLanguageFlagsForLinking(
langFlags, this->GeneratorTarget, linkLanguage, this->GetConfigName());
- // Add device-specific linker flags.
- this->GetDeviceLinkFlags(linkFlags, linkLanguage);
-
// Construct a list of files associated with this executable that
// may need to be cleaned.
std::vector<std::string> exeCleanFiles;
@@ -173,13 +167,20 @@ void cmMakefileExecutableTargetGenerator::WriteNvidiaDeviceExecutableRule(
// Set path conversion for link script shells.
this->LocalGenerator->SetLinkScriptShell(useLinkScript);
- std::unique_ptr<cmLinkLineComputer> linkLineComputer(
+ std::unique_ptr<cmLinkLineDeviceComputer> linkLineComputer(
new cmLinkLineDeviceComputer(
this->LocalGenerator,
this->LocalGenerator->GetStateSnapshot().GetDirectory()));
linkLineComputer->SetForResponse(useResponseFileForLibs);
linkLineComputer->SetRelink(relink);
+ // Create set of linking flags.
+ std::string linkFlags;
+ std::string ignored_;
+ this->LocalGenerator->GetDeviceLinkFlags(
+ *linkLineComputer, this->GetConfigName(), ignored_, linkFlags, ignored_,
+ ignored_, this->GeneratorTarget);
+
// Collect up flags to link in needed libraries.
std::string linkLibs;
this->CreateLinkLibs(
diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx
index 3f7d87d..45ef8c8 100644
--- a/Source/cmMakefileLibraryTargetGenerator.cxx
+++ b/Source/cmMakefileLibraryTargetGenerator.cxx
@@ -287,10 +287,6 @@ void cmMakefileLibraryTargetGenerator::WriteNvidiaDeviceLibraryRules(
this->LocalGenerator->AddLanguageFlagsForLinking(
langFlags, this->GeneratorTarget, linkLanguage, this->GetConfigName());
- // Create set of linking flags.
- std::string linkFlags;
- this->GetDeviceLinkFlags(linkFlags, linkLanguage);
-
// Clean files associated with this library.
std::set<std::string> libCleanFiles;
libCleanFiles.insert(
@@ -315,13 +311,20 @@ void cmMakefileLibraryTargetGenerator::WriteNvidiaDeviceLibraryRules(
// Collect up flags to link in needed libraries.
std::string linkLibs;
- std::unique_ptr<cmLinkLineComputer> linkLineComputer(
+ std::unique_ptr<cmLinkLineDeviceComputer> linkLineComputer(
new cmLinkLineDeviceComputer(
this->LocalGenerator,
this->LocalGenerator->GetStateSnapshot().GetDirectory()));
linkLineComputer->SetForResponse(useResponseFileForLibs);
linkLineComputer->SetRelink(relink);
+ // Create set of linking flags.
+ std::string linkFlags;
+ std::string ignored_;
+ this->LocalGenerator->GetDeviceLinkFlags(
+ *linkLineComputer, this->GetConfigName(), ignored_, linkFlags, ignored_,
+ ignored_, this->GeneratorTarget);
+
this->CreateLinkLibs(
linkLineComputer.get(), linkLibs, useResponseFileForLibs, depends,
cmMakefileTargetGenerator::ResponseFlagFor::DeviceLink);
diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx
index d4f1608..42f0329 100644
--- a/Source/cmNinjaNormalTargetGenerator.cxx
+++ b/Source/cmNinjaNormalTargetGenerator.cxx
@@ -537,7 +537,6 @@ std::vector<std::string> cmNinjaNormalTargetGenerator::ComputeDeviceLinkCmd()
// this target requires separable cuda compilation
// now build the correct command depending on if the target is
// an executable or a dynamic library.
- std::string linkCmd;
switch (this->GetGeneratorTarget()->GetType()) {
case cmStateEnums::STATIC_LIBRARY:
case cmStateEnums::SHARED_LIBRARY:
diff --git a/Source/cmScanDepFormat.cxx b/Source/cmScanDepFormat.cxx
index 82a374a..ec53af5 100644
--- a/Source/cmScanDepFormat.cxx
+++ b/Source/cmScanDepFormat.cxx
@@ -5,6 +5,7 @@
#include <cctype>
#include <cstdio>
+#include <iostream>
#include <utility>
#include <cm/optional>
@@ -188,6 +189,19 @@ bool cmScanDepFormat_P1689_Parse(std::string const& arg_pp,
return false;
}
+ if (provide.isMember("is-interface")) {
+ Json::Value const& is_interface = provide["is-interface"];
+ if (!is_interface.isBool()) {
+ cmSystemTools::Error(
+ cmStrCat("-E cmake_ninja_dyndep failed to parse ", arg_pp,
+ ": is-interface is not a boolean"));
+ return false;
+ }
+ provide_info.IsInterface = is_interface.asBool();
+ } else {
+ provide_info.IsInterface = true;
+ }
+
info->Provides.push_back(provide_info);
}
}
@@ -267,6 +281,27 @@ bool cmScanDepFormat_P1689_Parse(std::string const& arg_pp,
info->Requires.push_back(require_info);
}
}
+
+ // MSVC 17.3 toolchain bug. Remove when 17.4 is available.
+ if (rule.isMember("is-interface")) {
+ std::cerr
+ << "warning: acknowledging an VS 17.3 toolchain bug; accepting "
+ "until a new release which fixes it is available"
+ << std::endl;
+
+ Json::Value const& is_interface_json = rule["is-interface"];
+ if (!is_interface_json.isBool()) {
+ cmSystemTools::Error(
+ cmStrCat("-E cmake_ninja_dyndep failed to parse ", arg_pp,
+ ": is-interface is not a boolean"));
+ return false;
+ }
+ bool is_interface = is_interface_json.asBool();
+
+ for (auto& provide : info->Provides) {
+ provide.IsInterface = is_interface;
+ }
+ }
}
}
@@ -308,6 +343,8 @@ bool cmScanDepFormat_P1689_Write(std::string const& path,
provide_obj["source-path"] = EncodeFilename(provide.SourcePath);
}
+ provide_obj["is-interface"] = provide.IsInterface;
+
provides.append(provide_obj);
}
diff --git a/Source/cmScanDepFormat.h b/Source/cmScanDepFormat.h
index dae28d9..dc55bf1 100644
--- a/Source/cmScanDepFormat.h
+++ b/Source/cmScanDepFormat.h
@@ -18,6 +18,11 @@ struct cmSourceReqInfo
std::string SourcePath;
std::string CompiledModulePath;
bool UseSourcePath = false;
+
+ // Provides-only fields.
+ bool IsInterface = true;
+
+ // Requires-only fields.
LookupMethod Method = LookupMethod::ByName;
};
diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx
index 93a6f64..672cdc7 100644
--- a/Source/cmSystemTools.cxx
+++ b/Source/cmSystemTools.cxx
@@ -3357,22 +3357,12 @@ cmsys::Status cmSystemTools::CreateSymlink(std::string const& origName,
uv_fs_t req;
int flags = 0;
#if defined(_WIN32)
- bool const isDir = cmsys::SystemTools::FileIsDirectory(origName);
- if (isDir) {
- flags |= UV_FS_SYMLINK_JUNCTION;
+ if (cmsys::SystemTools::FileIsDirectory(origName)) {
+ flags |= UV_FS_SYMLINK_DIR;
}
#endif
int err = uv_fs_symlink(nullptr, &req, origName.c_str(), newName.c_str(),
flags, nullptr);
-#if defined(_WIN32)
- if (err && uv_fs_get_system_error(&req) == ERROR_NOT_SUPPORTED && isDir) {
- // Try fallback to symlink for network (requires additional permissions).
- flags ^= UV_FS_SYMLINK_JUNCTION | UV_FS_SYMLINK_DIR;
- err = uv_fs_symlink(nullptr, &req, origName.c_str(), newName.c_str(),
- flags, nullptr);
- }
-#endif
-
cmsys::Status status;
if (err) {
#if defined(_WIN32)
diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index 66b91cb..4c1fa01 100644
--- a/Source/cmVisualStudio10TargetGenerator.cxx
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -3137,6 +3137,7 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions(
this->LangForClCompile = langForClCompile;
if (!langForClCompile.empty()) {
this->LocalGenerator->AddLanguageFlags(flags, this->GeneratorTarget,
+ cmBuildStep::Compile,
langForClCompile, configName);
this->LocalGenerator->AddCompileOptions(flags, this->GeneratorTarget,
langForClCompile, configName);
@@ -3521,8 +3522,8 @@ bool cmVisualStudio10TargetGenerator::ComputeCudaOptions(
// Get compile flags for CUDA in this directory.
std::string flags;
- this->LocalGenerator->AddLanguageFlags(flags, this->GeneratorTarget, "CUDA",
- configName);
+ this->LocalGenerator->AddLanguageFlags(
+ flags, this->GeneratorTarget, cmBuildStep::Compile, "CUDA", configName);
this->LocalGenerator->AddCompileOptions(flags, this->GeneratorTarget, "CUDA",
configName);
@@ -3793,7 +3794,8 @@ bool cmVisualStudio10TargetGenerator::ComputeMasmOptions(
std::string flags;
this->LocalGenerator->AddLanguageFlags(flags, this->GeneratorTarget,
- "ASM_MASM", configName);
+ cmBuildStep::Compile, "ASM_MASM",
+ configName);
masmOptions.Parse(flags);
@@ -3845,7 +3847,8 @@ bool cmVisualStudio10TargetGenerator::ComputeNasmOptions(
std::string flags;
this->LocalGenerator->AddLanguageFlags(flags, this->GeneratorTarget,
- "ASM_NASM", configName);
+ cmBuildStep::Compile, "ASM_NASM",
+ configName);
flags += " -f";
flags += this->Makefile->GetSafeDefinition("CMAKE_ASM_NASM_OBJECT_FORMAT");
nasmOptions.Parse(flags);
diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt
index a54b6b5..ab1fba0 100644
--- a/Tests/CMakeLists.txt
+++ b/Tests/CMakeLists.txt
@@ -618,6 +618,11 @@ if(BUILD_TESTING)
set(Module.CheckIPOSupported-CXX_BUILD_OPTIONS -DCMake_TEST_IPO_WORKS_CXX=${CMake_TEST_IPO_WORKS_CXX})
ADD_TEST_MACRO(Module.CheckIPOSupported-CXX CheckIPOSupported-CXX)
+ if(CMake_TEST_CUDA)
+ ADD_TEST_MACRO(Module.CheckIPOSupported-CUDA CheckIPOSupported-CUDA)
+ set_property(TEST Module.CheckIPOSupported-CUDA APPEND PROPERTY LABELS "CUDA")
+ endif()
+
if(CMAKE_Fortran_COMPILER)
set(Module.CheckIPOSupported-Fortran_BUILD_OPTIONS -DCMake_TEST_IPO_WORKS_Fortran=${CMake_TEST_IPO_WORKS_Fortran})
ADD_TEST_MACRO(Module.CheckIPOSupported-Fortran CheckIPOSupported-Fortran)
diff --git a/Tests/CudaOnly/CMakeLists.txt b/Tests/CudaOnly/CMakeLists.txt
index aa4755d..091872d 100644
--- a/Tests/CudaOnly/CMakeLists.txt
+++ b/Tests/CudaOnly/CMakeLists.txt
@@ -7,7 +7,6 @@ endmacro ()
add_cuda_test_macro(CudaOnly.Architecture Architecture)
add_cuda_test_macro(CudaOnly.ArchSpecial CudaOnlyArchSpecial)
add_cuda_test_macro(CudaOnly.CompileFlags CudaOnlyCompileFlags)
-
add_cuda_test_macro(CudaOnly.EnableStandard CudaOnlyEnableStandard)
add_cuda_test_macro(CudaOnly.ExportPTX CudaOnlyExportPTX)
add_cuda_test_macro(CudaOnly.SharedRuntimePlusToolkit CudaOnlySharedRuntimePlusToolkit)
@@ -28,6 +27,19 @@ if(CMake_TEST_CUDA AND NOT CMake_TEST_CUDA STREQUAL "Clang")
add_cuda_test_macro(CudaOnly.GPUDebugFlag CudaOnlyGPUDebugFlag)
endif()
+# The CUDA only ships the shared version of the toolkit libraries
+# on windows
+if(NOT WIN32)
+ add_cuda_test_macro(CudaOnly.StaticRuntimePlusToolkit CudaOnlyStaticRuntimePlusToolkit)
+endif()
+
+add_cuda_test_macro(CudaOnly.DeviceLTO CudaOnlyDeviceLTO)
+
+if(MSVC)
+ # Tests for features that only work with MSVC
+ add_cuda_test_macro(CudaOnly.PDB CudaOnlyPDB)
+endif()
+
add_test(NAME CudaOnly.DontResolveDeviceSymbols COMMAND
${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
--build-and-test
@@ -41,16 +53,6 @@ add_test(NAME CudaOnly.DontResolveDeviceSymbols COMMAND
set_property(TEST "CudaOnly.DontResolveDeviceSymbols" APPEND
PROPERTY LABELS "CUDA")
-# The CUDA only ships the shared version of the toolkit libraries
-# on windows
-if(NOT WIN32)
- add_cuda_test_macro(CudaOnly.StaticRuntimePlusToolkit CudaOnlyStaticRuntimePlusToolkit)
-endif()
-
-if(MSVC)
- add_cuda_test_macro(CudaOnly.PDB CudaOnlyPDB)
-endif()
-
add_test(NAME CudaOnly.RuntimeControls COMMAND
${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
--build-and-test
diff --git a/Tests/CudaOnly/DeviceLTO/CMakeLists.txt b/Tests/CudaOnly/DeviceLTO/CMakeLists.txt
new file mode 100644
index 0000000..653b35d
--- /dev/null
+++ b/Tests/CudaOnly/DeviceLTO/CMakeLists.txt
@@ -0,0 +1,37 @@
+cmake_minimum_required(VERSION 3.18)
+project(DeviceLTO CUDA)
+
+# Goal:
+# Verify that we correctly compile with device LTO
+# Verify that device LTO requirements are propagated to
+# the final device link line
+
+add_library(CUDA_dlto STATIC file1.cu file2.cu file3.cu)
+add_executable(CudaOnlyDeviceLTO main.cu)
+
+set_target_properties(CUDA_dlto
+ PROPERTIES
+ CUDA_ARCHITECTURES "${CMAKE_CUDA_ARCHITECTURES_ALL}"
+ CUDA_SEPARABLE_COMPILATION ON
+ POSITION_INDEPENDENT_CODE ON)
+
+set_target_properties(CudaOnlyDeviceLTO
+ PROPERTIES
+ CUDA_SEPARABLE_COMPILATION ON
+ CUDA_ARCHITECTURES "${CMAKE_CUDA_ARCHITECTURES_ALL}"
+ )
+
+target_link_libraries(CudaOnlyDeviceLTO PRIVATE CUDA_dlto)
+
+include(CheckIPOSupported)
+check_ipo_supported(LANGUAGES CUDA RESULT ipo_supported)
+if(ipo_supported)
+ set_target_properties(CUDA_dlto
+ PROPERTIES
+ INTERPROCEDURAL_OPTIMIZATION ON)
+
+ # When non-LTO variants (i.e. virtual) are built together with LTO ones the
+ # linker warns about missing device LTO for the virtual architectures.
+ # Ignore these warnings.
+ target_link_options(CudaOnlyDeviceLTO PRIVATE "$<DEVICE_LINK:-w>")
+endif()
diff --git a/Tests/CudaOnly/DeviceLTO/file1.cu b/Tests/CudaOnly/DeviceLTO/file1.cu
new file mode 100644
index 0000000..703927c
--- /dev/null
+++ b/Tests/CudaOnly/DeviceLTO/file1.cu
@@ -0,0 +1,17 @@
+#ifdef _WIN32
+# define EXPORT __declspec(dllexport)
+#else
+# define EXPORT
+#endif
+
+extern __device__ int file2_func(int);
+void __global__ kernel(int x)
+{
+ file2_func(x);
+}
+
+EXPORT int launch_kernel(int x)
+{
+ kernel<<<1, 1>>>(x);
+ return x;
+}
diff --git a/Tests/CudaOnly/DeviceLTO/file2.cu b/Tests/CudaOnly/DeviceLTO/file2.cu
new file mode 100644
index 0000000..73d6468
--- /dev/null
+++ b/Tests/CudaOnly/DeviceLTO/file2.cu
@@ -0,0 +1,5 @@
+extern __device__ int file3_func(int);
+int __device__ file2_func(int x)
+{
+ return x + file3_func(x);
+}
diff --git a/Tests/CudaOnly/DeviceLTO/file3.cu b/Tests/CudaOnly/DeviceLTO/file3.cu
new file mode 100644
index 0000000..235ac06
--- /dev/null
+++ b/Tests/CudaOnly/DeviceLTO/file3.cu
@@ -0,0 +1,4 @@
+int __device__ file3_func(int x)
+{
+ return x * x * x;
+}
diff --git a/Tests/CudaOnly/DeviceLTO/main.cu b/Tests/CudaOnly/DeviceLTO/main.cu
new file mode 100644
index 0000000..8ef4873
--- /dev/null
+++ b/Tests/CudaOnly/DeviceLTO/main.cu
@@ -0,0 +1,62 @@
+#include <iostream>
+
+#include "cuda.h"
+
+#ifdef _WIN32
+# define IMPORT __declspec(dllimport)
+#else
+# define IMPORT
+#endif
+
+IMPORT int launch_kernel(int x);
+
+int choose_cuda_device()
+{
+ int nDevices = 0;
+ cudaError_t err = cudaGetDeviceCount(&nDevices);
+ if (err != cudaSuccess) {
+ std::cerr << "Failed to retrieve the number of CUDA enabled devices"
+ << std::endl;
+ return 1;
+ }
+ for (int i = 0; i < nDevices; ++i) {
+ cudaDeviceProp prop;
+ cudaError_t err = cudaGetDeviceProperties(&prop, i);
+ if (err != cudaSuccess) {
+ std::cerr << "Could not retrieve properties from CUDA device " << i
+ << std::endl;
+ return 1;
+ }
+ std::cout << "prop.major: " << prop.major << std::endl;
+ err = cudaSetDevice(i);
+ if (err != cudaSuccess) {
+ std::cout << "Could not select CUDA device " << i << std::endl;
+ } else {
+ return 0;
+ }
+ }
+
+ std::cout << "Could not find a CUDA enabled card" << std::endl;
+
+ return 1;
+}
+
+int main()
+{
+ int ret = choose_cuda_device();
+ if (ret) {
+ return 0;
+ }
+
+ cudaError_t err;
+ launch_kernel(1);
+ err = cudaGetLastError();
+ if (err != cudaSuccess) {
+ std::cerr << "launch_kernel: kernel launch should have passed.\n "
+ "Error message: "
+ << cudaGetErrorString(err) << std::endl;
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/Tests/Module/CheckIPOSupported-CUDA/CMakeLists.txt b/Tests/Module/CheckIPOSupported-CUDA/CMakeLists.txt
new file mode 100644
index 0000000..9dd670e
--- /dev/null
+++ b/Tests/Module/CheckIPOSupported-CUDA/CMakeLists.txt
@@ -0,0 +1,32 @@
+cmake_minimum_required(VERSION 3.8)
+project(CheckIPOSupported-CUDA LANGUAGES CUDA)
+
+cmake_policy(SET CMP0069 NEW)
+
+include(CheckIPOSupported)
+check_ipo_supported(RESULT ipo_supported OUTPUT ipo_output)
+if(ipo_supported)
+ set(CMAKE_INTERPROCEDURAL_OPTIMIZATION ON)
+endif()
+
+if(NOT ipo_supported AND CMAKE_CUDA_COMPILER_ID STREQUAL "NVIDIA"
+ AND CMAKE_CUDA_COMPILER_VERSION VERSION_GREATER_EQUAL 11.2)
+ message(FATAL_ERROR "CheckIPOSupported failed to correctly identify NVIDIA CUDA IPO support")
+endif()
+
+set(CMAKE_CUDA_SEPARABLE_COMPILATION ON)
+
+add_library(foo STATIC foo.cu)
+set_target_properties(foo PROPERTIES
+ WINDOWS_EXPORT_ALL_SYMBOLS ON
+ POSITION_INDEPENDENT_CODE ON)
+
+add_library(bar SHARED bar.cu)
+set_target_properties(bar PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS ON)
+target_link_libraries(bar PRIVATE foo)
+
+add_executable(CheckIPOSupported-CUDA main.cu)
+target_link_libraries(CheckIPOSupported-CUDA PUBLIC bar)
+
+enable_testing()
+add_test(NAME CheckIPOSupported-CUDA COMMAND CheckIPOSupported-CUDA)
diff --git a/Tests/Module/CheckIPOSupported-CUDA/bar.cu b/Tests/Module/CheckIPOSupported-CUDA/bar.cu
new file mode 100644
index 0000000..79b276d
--- /dev/null
+++ b/Tests/Module/CheckIPOSupported-CUDA/bar.cu
@@ -0,0 +1,12 @@
+__device__ int foo_func(int);
+
+void __global__ bar_kernel(int x)
+{
+ foo_func(x);
+}
+
+int launch_kernel(int x)
+{
+ bar_kernel<<<1, 1>>>(x);
+ return x;
+}
diff --git a/Tests/Module/CheckIPOSupported-CUDA/foo.cu b/Tests/Module/CheckIPOSupported-CUDA/foo.cu
new file mode 100644
index 0000000..416607b
--- /dev/null
+++ b/Tests/Module/CheckIPOSupported-CUDA/foo.cu
@@ -0,0 +1,4 @@
+extern __device__ int foo_func(int a)
+{
+ return a * 42 + 9;
+}
diff --git a/Tests/Module/CheckIPOSupported-CUDA/main.cu b/Tests/Module/CheckIPOSupported-CUDA/main.cu
new file mode 100644
index 0000000..8ef4873
--- /dev/null
+++ b/Tests/Module/CheckIPOSupported-CUDA/main.cu
@@ -0,0 +1,62 @@
+#include <iostream>
+
+#include "cuda.h"
+
+#ifdef _WIN32
+# define IMPORT __declspec(dllimport)
+#else
+# define IMPORT
+#endif
+
+IMPORT int launch_kernel(int x);
+
+int choose_cuda_device()
+{
+ int nDevices = 0;
+ cudaError_t err = cudaGetDeviceCount(&nDevices);
+ if (err != cudaSuccess) {
+ std::cerr << "Failed to retrieve the number of CUDA enabled devices"
+ << std::endl;
+ return 1;
+ }
+ for (int i = 0; i < nDevices; ++i) {
+ cudaDeviceProp prop;
+ cudaError_t err = cudaGetDeviceProperties(&prop, i);
+ if (err != cudaSuccess) {
+ std::cerr << "Could not retrieve properties from CUDA device " << i
+ << std::endl;
+ return 1;
+ }
+ std::cout << "prop.major: " << prop.major << std::endl;
+ err = cudaSetDevice(i);
+ if (err != cudaSuccess) {
+ std::cout << "Could not select CUDA device " << i << std::endl;
+ } else {
+ return 0;
+ }
+ }
+
+ std::cout << "Could not find a CUDA enabled card" << std::endl;
+
+ return 1;
+}
+
+int main()
+{
+ int ret = choose_cuda_device();
+ if (ret) {
+ return 0;
+ }
+
+ cudaError_t err;
+ launch_kernel(1);
+ err = cudaGetLastError();
+ if (err != cudaSuccess) {
+ std::cerr << "launch_kernel: kernel launch should have passed.\n "
+ "Error message: "
+ << cudaGetErrorString(err) << std::endl;
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/Tests/RunCMake/CXXModules/RunCMakeTest.cmake b/Tests/RunCMake/CXXModules/RunCMakeTest.cmake
index ca1bc81..3f17c1f 100644
--- a/Tests/RunCMake/CXXModules/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CXXModules/RunCMakeTest.cmake
@@ -131,6 +131,7 @@ if ("named" IN_LIST CMake_TEST_MODULE_COMPILATION)
run_cxx_module_test(library library-static -DBUILD_SHARED_LIBS=OFF)
run_cxx_module_test(generated)
run_cxx_module_test(public-req-private)
+ run_cxx_module_test(deep-chain)
endif ()
# Tests which use named modules in shared libraries.
diff --git a/Tests/RunCMake/CXXModules/examples/cxx-modules-find-bmi.cmake b/Tests/RunCMake/CXXModules/examples/cxx-modules-find-bmi.cmake
index 8efe508..91f3995 100644
--- a/Tests/RunCMake/CXXModules/examples/cxx-modules-find-bmi.cmake
+++ b/Tests/RunCMake/CXXModules/examples/cxx-modules-find-bmi.cmake
@@ -1,6 +1,6 @@
function (check_for_bmi prefix destination name)
set(found 0)
- foreach (ext IN ITEMS gcm)
+ foreach (ext IN ITEMS gcm ifc)
if (EXISTS "${prefix}/${destination}/${name}.${ext}")
set(found 1)
break ()
diff --git a/Tests/RunCMake/CXXModules/examples/deep-chain-stderr.txt b/Tests/RunCMake/CXXModules/examples/deep-chain-stderr.txt
new file mode 100644
index 0000000..5e4392a
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/deep-chain-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/deep-chain/CMakeLists.txt b/Tests/RunCMake/CXXModules/examples/deep-chain/CMakeLists.txt
new file mode 100644
index 0000000..515b240
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/deep-chain/CMakeLists.txt
@@ -0,0 +1,66 @@
+cmake_minimum_required(VERSION 3.24)
+project(cxx_modules_deep_chain CXX)
+
+include("${CMAKE_SOURCE_DIR}/../cxx-modules-rules.cmake")
+
+add_library(a STATIC)
+target_sources(a
+ PUBLIC
+ FILE_SET CXX_MODULES
+ BASE_DIRS
+ "${CMAKE_CURRENT_SOURCE_DIR}"
+ FILES
+ a.cxx)
+target_compile_features(a PUBLIC cxx_std_20)
+
+add_library(b STATIC)
+target_sources(b
+ PUBLIC
+ FILE_SET CXX_MODULES
+ BASE_DIRS
+ "${CMAKE_CURRENT_SOURCE_DIR}"
+ FILES
+ b.cxx)
+target_compile_features(b PUBLIC cxx_std_20)
+target_link_libraries(b PUBLIC a)
+
+add_library(c STATIC)
+target_sources(c
+ PUBLIC
+ FILE_SET CXX_MODULES
+ BASE_DIRS
+ "${CMAKE_CURRENT_SOURCE_DIR}"
+ FILES
+ c.cxx)
+target_compile_features(c PUBLIC cxx_std_20)
+target_link_libraries(c PUBLIC b)
+
+add_library(d STATIC)
+target_sources(d
+ PUBLIC
+ FILE_SET CXX_MODULES
+ BASE_DIRS
+ "${CMAKE_CURRENT_SOURCE_DIR}"
+ FILES
+ d.cxx)
+target_compile_features(d PUBLIC cxx_std_20)
+target_link_libraries(d PUBLIC c)
+
+add_library(e STATIC)
+target_sources(e
+ PUBLIC
+ FILE_SET CXX_MODULES
+ BASE_DIRS
+ "${CMAKE_CURRENT_SOURCE_DIR}"
+ FILES
+ e.cxx)
+target_compile_features(e PUBLIC cxx_std_20)
+target_link_libraries(e PUBLIC d)
+
+add_executable(exe)
+target_link_libraries(exe PRIVATE e)
+target_sources(exe
+ PRIVATE
+ main.cxx)
+
+add_test(NAME exe COMMAND exe)
diff --git a/Tests/RunCMake/CXXModules/examples/deep-chain/a.cxx b/Tests/RunCMake/CXXModules/examples/deep-chain/a.cxx
new file mode 100644
index 0000000..9edaec9
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/deep-chain/a.cxx
@@ -0,0 +1,6 @@
+export module a;
+
+export int a()
+{
+ return 0;
+}
diff --git a/Tests/RunCMake/CXXModules/examples/deep-chain/b.cxx b/Tests/RunCMake/CXXModules/examples/deep-chain/b.cxx
new file mode 100644
index 0000000..38ab0c2
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/deep-chain/b.cxx
@@ -0,0 +1,7 @@
+export module b;
+import a;
+
+export int b()
+{
+ return a();
+}
diff --git a/Tests/RunCMake/CXXModules/examples/deep-chain/c.cxx b/Tests/RunCMake/CXXModules/examples/deep-chain/c.cxx
new file mode 100644
index 0000000..580a458
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/deep-chain/c.cxx
@@ -0,0 +1,7 @@
+export module c;
+import b;
+
+export int c()
+{
+ return b();
+}
diff --git a/Tests/RunCMake/CXXModules/examples/deep-chain/d.cxx b/Tests/RunCMake/CXXModules/examples/deep-chain/d.cxx
new file mode 100644
index 0000000..78bc5ba
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/deep-chain/d.cxx
@@ -0,0 +1,7 @@
+export module d;
+import c;
+
+export int d()
+{
+ return c();
+}
diff --git a/Tests/RunCMake/CXXModules/examples/deep-chain/e.cxx b/Tests/RunCMake/CXXModules/examples/deep-chain/e.cxx
new file mode 100644
index 0000000..e019440
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/deep-chain/e.cxx
@@ -0,0 +1,7 @@
+export module e;
+import d;
+
+export int e()
+{
+ return d();
+}
diff --git a/Tests/RunCMake/CXXModules/examples/deep-chain/main.cxx b/Tests/RunCMake/CXXModules/examples/deep-chain/main.cxx
new file mode 100644
index 0000000..0b7c15d
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/deep-chain/main.cxx
@@ -0,0 +1,6 @@
+import e;
+
+int main(int argc, char* argv[])
+{
+ return e();
+}
diff --git a/Tests/RunCMake/CXXModules/examples/internal-partitions/importable.cxx b/Tests/RunCMake/CXXModules/examples/internal-partitions/importable.cxx
index 8be521b..b872ae9 100644
--- a/Tests/RunCMake/CXXModules/examples/internal-partitions/importable.cxx
+++ b/Tests/RunCMake/CXXModules/examples/internal-partitions/importable.cxx
@@ -1,5 +1,5 @@
export module importable;
-import importable : internal_partition;
+import : internal_partition;
#include "internal-partitions_export.h"
diff --git a/Tests/RunCMake/CXXModules/examples/partitions/importable.cxx b/Tests/RunCMake/CXXModules/examples/partitions/importable.cxx
index 1e81aaf..d0ac2f4 100644
--- a/Tests/RunCMake/CXXModules/examples/partitions/importable.cxx
+++ b/Tests/RunCMake/CXXModules/examples/partitions/importable.cxx
@@ -1,5 +1,5 @@
export module importable;
-export import importable : partition;
+export import : partition;
#include "partitions_export.h"
diff --git a/Tests/RunCMake/CheckIPOSupported/default-lang-none-stderr.txt b/Tests/RunCMake/CheckIPOSupported/default-lang-none-stderr.txt
index dc2c3ad..9a1ba04 100644
--- a/Tests/RunCMake/CheckIPOSupported/default-lang-none-stderr.txt
+++ b/Tests/RunCMake/CheckIPOSupported/default-lang-none-stderr.txt
@@ -1,6 +1,6 @@
^CMake Error at .*/Modules/CheckIPOSupported\.cmake:[0-9]+ \(message\):
- IPO is not supported \(no C/CXX/Fortran languages found in ENABLED_LANGUAGES
- global property\)\.
+ IPO is not supported \(no C/CXX/CUDA/Fortran languages found in
+ ENABLED_LANGUAGES global property\)\.
Call Stack \(most recent call first\):
.*/Modules/CheckIPOSupported\.cmake:[0-9]+ \(_ipo_not_supported\)
default-lang-none\.cmake:[0-9]+ \(check_ipo_supported\)
diff --git a/Tests/RunCMake/find_package/RunCMakeTest.cmake b/Tests/RunCMake/find_package/RunCMakeTest.cmake
index 32e54d5..fa41fc1 100644
--- a/Tests/RunCMake/find_package/RunCMakeTest.cmake
+++ b/Tests/RunCMake/find_package/RunCMakeTest.cmake
@@ -55,6 +55,22 @@ run_cmake(REGISTRY_VIEW-no-view)
run_cmake(REGISTRY_VIEW-wrong-view)
run_cmake(REGISTRY_VIEW-propagated)
+file(
+ GLOB SearchPaths_TEST_CASE_LIST
+ LIST_DIRECTORIES TRUE
+ "${RunCMake_SOURCE_DIR}/SearchPaths/*"
+ )
+foreach(TestCasePrefix IN LISTS SearchPaths_TEST_CASE_LIST)
+ if(IS_DIRECTORY "${TestCasePrefix}")
+ cmake_path(GET TestCasePrefix FILENAME TestSuffix)
+ run_cmake_with_options(
+ SearchPaths_${TestSuffix}
+ "-DSearchPaths_ROOT=${TestCasePrefix}"
+ "--debug-find-pkg=SearchPaths"
+ )
+ endif()
+endforeach()
+
if(UNIX
AND NOT MSYS # FIXME: This works on CYGWIN but not on MSYS
)
diff --git a/Tests/RunCMake/find_package/SearchPaths.cmake b/Tests/RunCMake/find_package/SearchPaths.cmake
new file mode 100644
index 0000000..a5a10fc
--- /dev/null
+++ b/Tests/RunCMake/find_package/SearchPaths.cmake
@@ -0,0 +1,2 @@
+cmake_policy(SET CMP0074 NEW)
+find_package(SearchPaths REQUIRED CONFIG)
diff --git a/Tests/RunCMake/find_package/SearchPaths/prefix/SearchPathsConfig.cmake b/Tests/RunCMake/find_package/SearchPaths/prefix/SearchPathsConfig.cmake
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/RunCMake/find_package/SearchPaths/prefix/SearchPathsConfig.cmake
diff --git a/Tests/RunCMake/find_package/SearchPaths/prefix_cmake/cmake/SearchPathsConfig.cmake b/Tests/RunCMake/find_package/SearchPaths/prefix_cmake/cmake/SearchPathsConfig.cmake
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/RunCMake/find_package/SearchPaths/prefix_cmake/cmake/SearchPathsConfig.cmake
diff --git a/Tests/RunCMake/find_package/SearchPaths/prefix_lib_cmake_pkg/lib/cmake/SearchPaths-1.2.3/SearchPathsConfig.cmake b/Tests/RunCMake/find_package/SearchPaths/prefix_lib_cmake_pkg/lib/cmake/SearchPaths-1.2.3/SearchPathsConfig.cmake
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/RunCMake/find_package/SearchPaths/prefix_lib_cmake_pkg/lib/cmake/SearchPaths-1.2.3/SearchPathsConfig.cmake
diff --git a/Tests/RunCMake/find_package/SearchPaths/prefix_lib_pkg/lib/SearchPaths-1.2.3/SearchPathsConfig.cmake b/Tests/RunCMake/find_package/SearchPaths/prefix_lib_pkg/lib/SearchPaths-1.2.3/SearchPathsConfig.cmake
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/RunCMake/find_package/SearchPaths/prefix_lib_pkg/lib/SearchPaths-1.2.3/SearchPathsConfig.cmake
diff --git a/Tests/RunCMake/find_package/SearchPaths/prefix_lib_pkg_cmake/lib/SearchPaths-1.2.3/cmake/SearchPathsConfig.cmake b/Tests/RunCMake/find_package/SearchPaths/prefix_lib_pkg_cmake/lib/SearchPaths-1.2.3/cmake/SearchPathsConfig.cmake
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/RunCMake/find_package/SearchPaths/prefix_lib_pkg_cmake/lib/SearchPaths-1.2.3/cmake/SearchPathsConfig.cmake
diff --git a/Tests/RunCMake/find_package/SearchPaths/prefix_pkg/SearchPaths-1.2.3/SearchPathsConfig.cmake b/Tests/RunCMake/find_package/SearchPaths/prefix_pkg/SearchPaths-1.2.3/SearchPathsConfig.cmake
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/RunCMake/find_package/SearchPaths/prefix_pkg/SearchPaths-1.2.3/SearchPathsConfig.cmake
diff --git a/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_cmake/SearchPaths-1.2.3/cmake/SearchPathsConfig.cmake b/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_cmake/SearchPaths-1.2.3/cmake/SearchPathsConfig.cmake
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_cmake/SearchPaths-1.2.3/cmake/SearchPathsConfig.cmake
diff --git a/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_lib_cmake_pkg/SearchPaths-1.2.3/lib/cmake/SearchPaths-1.2.3/SearchPathsConfig.cmake b/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_lib_cmake_pkg/SearchPaths-1.2.3/lib/cmake/SearchPaths-1.2.3/SearchPathsConfig.cmake
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_lib_cmake_pkg/SearchPaths-1.2.3/lib/cmake/SearchPaths-1.2.3/SearchPathsConfig.cmake
diff --git a/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_lib_pkg/SearchPaths-1.2.3/lib/SearchPaths-1.2.3/SearchPathsConfig.cmake b/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_lib_pkg/SearchPaths-1.2.3/lib/SearchPaths-1.2.3/SearchPathsConfig.cmake
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_lib_pkg/SearchPaths-1.2.3/lib/SearchPaths-1.2.3/SearchPathsConfig.cmake
diff --git a/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_lib_pkg_cmake/SearchPaths-1.2.3/lib/SearchPaths-1.2.3/cmake/SearchPathsConfig.cmake b/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_lib_pkg_cmake/SearchPaths-1.2.3/lib/SearchPaths-1.2.3/cmake/SearchPathsConfig.cmake
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_lib_pkg_cmake/SearchPaths-1.2.3/lib/SearchPaths-1.2.3/cmake/SearchPathsConfig.cmake
diff --git a/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_share_cmake_pkg/SearchPaths-1.2.3/share/cmake/SearchPaths-1.2.3/SearchPathsConfig.cmake b/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_share_cmake_pkg/SearchPaths-1.2.3/share/cmake/SearchPaths-1.2.3/SearchPathsConfig.cmake
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_share_cmake_pkg/SearchPaths-1.2.3/share/cmake/SearchPaths-1.2.3/SearchPathsConfig.cmake
diff --git a/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_share_pkg/SearchPaths-1.2.3/share/SearchPaths-1.2.3/SearchPathsConfig.cmake b/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_share_pkg/SearchPaths-1.2.3/share/SearchPaths-1.2.3/SearchPathsConfig.cmake
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_share_pkg/SearchPaths-1.2.3/share/SearchPaths-1.2.3/SearchPathsConfig.cmake
diff --git a/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_share_pkg_cmake/SearchPaths-1.2.3/share/SearchPaths-1.2.3/cmake/SearchPathsConfig.cmake b/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_share_pkg_cmake/SearchPaths-1.2.3/share/SearchPaths-1.2.3/cmake/SearchPathsConfig.cmake
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_share_pkg_cmake/SearchPaths-1.2.3/share/SearchPaths-1.2.3/cmake/SearchPathsConfig.cmake
diff --git a/Tests/RunCMake/find_package/SearchPaths/prefix_share_cmake_pkg/share/cmake/SearchPaths-1.2.3/SearchPathsConfig.cmake b/Tests/RunCMake/find_package/SearchPaths/prefix_share_cmake_pkg/share/cmake/SearchPaths-1.2.3/SearchPathsConfig.cmake
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/RunCMake/find_package/SearchPaths/prefix_share_cmake_pkg/share/cmake/SearchPaths-1.2.3/SearchPathsConfig.cmake
diff --git a/Tests/RunCMake/find_package/SearchPaths/prefix_share_pkg/share/SearchPaths-1.2.3/SearchPathsConfig.cmake b/Tests/RunCMake/find_package/SearchPaths/prefix_share_pkg/share/SearchPaths-1.2.3/SearchPathsConfig.cmake
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/RunCMake/find_package/SearchPaths/prefix_share_pkg/share/SearchPaths-1.2.3/SearchPathsConfig.cmake
diff --git a/Tests/RunCMake/find_package/SearchPaths/prefix_share_pkg_cmake/share/SearchPaths-1.2.3/cmake/SearchPathsConfig.cmake b/Tests/RunCMake/find_package/SearchPaths/prefix_share_pkg_cmake/share/SearchPaths-1.2.3/cmake/SearchPathsConfig.cmake
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/RunCMake/find_package/SearchPaths/prefix_share_pkg_cmake/share/SearchPaths-1.2.3/cmake/SearchPathsConfig.cmake
diff --git a/Tests/RunCMake/find_package/SearchPaths_prefix-stderr.txt b/Tests/RunCMake/find_package/SearchPaths_prefix-stderr.txt
new file mode 100644
index 0000000..fae13ef
--- /dev/null
+++ b/Tests/RunCMake/find_package/SearchPaths_prefix-stderr.txt
@@ -0,0 +1,10 @@
+ find_package considered the following locations for SearchPaths's Config
+ module:
+
+ .*/Tests/RunCMake/find_package/SearchPaths_prefix-build/CMakeFiles/pkgRedirects/SearchPathsConfig\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths_prefix-build/CMakeFiles/pkgRedirects/searchpaths-config\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix/SearchPathsConfig\.cmake
+
+ The file was found at
+
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix/SearchPathsConfig\.cmake
diff --git a/Tests/RunCMake/find_package/SearchPaths_prefix.cmake b/Tests/RunCMake/find_package/SearchPaths_prefix.cmake
new file mode 100644
index 0000000..d831313
--- /dev/null
+++ b/Tests/RunCMake/find_package/SearchPaths_prefix.cmake
@@ -0,0 +1 @@
+include("${CMAKE_CURRENT_SOURCE_DIR}/SearchPaths.cmake")
diff --git a/Tests/RunCMake/find_package/SearchPaths_prefix_cmake-stderr.txt b/Tests/RunCMake/find_package/SearchPaths_prefix_cmake-stderr.txt
new file mode 100644
index 0000000..eba88c9
--- /dev/null
+++ b/Tests/RunCMake/find_package/SearchPaths_prefix_cmake-stderr.txt
@@ -0,0 +1,12 @@
+ find_package considered the following locations for SearchPaths's Config
+ module:
+
+ .*/Tests/RunCMake/find_package/SearchPaths_prefix_cmake-build/CMakeFiles/pkgRedirects/SearchPathsConfig\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths_prefix_cmake-build/CMakeFiles/pkgRedirects/searchpaths-config\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_cmake/SearchPathsConfig\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_cmake/searchpaths-config\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_cmake/cmake/SearchPathsConfig\.cmake
+
+ The file was found at
+
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_cmake/cmake/SearchPathsConfig\.cmake
diff --git a/Tests/RunCMake/find_package/SearchPaths_prefix_cmake.cmake b/Tests/RunCMake/find_package/SearchPaths_prefix_cmake.cmake
new file mode 100644
index 0000000..d831313
--- /dev/null
+++ b/Tests/RunCMake/find_package/SearchPaths_prefix_cmake.cmake
@@ -0,0 +1 @@
+include("${CMAKE_CURRENT_SOURCE_DIR}/SearchPaths.cmake")
diff --git a/Tests/RunCMake/find_package/SearchPaths_prefix_lib_cmake_pkg-stderr.txt b/Tests/RunCMake/find_package/SearchPaths_prefix_lib_cmake_pkg-stderr.txt
new file mode 100644
index 0000000..cebc169
--- /dev/null
+++ b/Tests/RunCMake/find_package/SearchPaths_prefix_lib_cmake_pkg-stderr.txt
@@ -0,0 +1,12 @@
+ find_package considered the following locations for SearchPaths's Config
+ module:
+
+ .*/Tests/RunCMake/find_package/SearchPaths_prefix_lib_cmake_pkg-build/CMakeFiles/pkgRedirects/SearchPathsConfig\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths_prefix_lib_cmake_pkg-build/CMakeFiles/pkgRedirects/searchpaths-config\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_lib_cmake_pkg/SearchPathsConfig\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_lib_cmake_pkg/searchpaths-config\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_lib_cmake_pkg/lib/cmake/SearchPaths-1\.2\.3/SearchPathsConfig\.cmake
+
+ The file was found at
+
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_lib_cmake_pkg/lib/cmake/SearchPaths-1\.2\.3/SearchPathsConfig\.cmake
diff --git a/Tests/RunCMake/find_package/SearchPaths_prefix_lib_cmake_pkg.cmake b/Tests/RunCMake/find_package/SearchPaths_prefix_lib_cmake_pkg.cmake
new file mode 100644
index 0000000..d831313
--- /dev/null
+++ b/Tests/RunCMake/find_package/SearchPaths_prefix_lib_cmake_pkg.cmake
@@ -0,0 +1 @@
+include("${CMAKE_CURRENT_SOURCE_DIR}/SearchPaths.cmake")
diff --git a/Tests/RunCMake/find_package/SearchPaths_prefix_lib_pkg-stderr.txt b/Tests/RunCMake/find_package/SearchPaths_prefix_lib_pkg-stderr.txt
new file mode 100644
index 0000000..4e5d3f6
--- /dev/null
+++ b/Tests/RunCMake/find_package/SearchPaths_prefix_lib_pkg-stderr.txt
@@ -0,0 +1,12 @@
+ find_package considered the following locations for SearchPaths's Config
+ module:
+
+ .*/Tests/RunCMake/find_package/SearchPaths_prefix_lib_pkg-build/CMakeFiles/pkgRedirects/SearchPathsConfig\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths_prefix_lib_pkg-build/CMakeFiles/pkgRedirects/searchpaths-config\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_lib_pkg/SearchPathsConfig\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_lib_pkg/searchpaths-config\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_lib_pkg/lib/SearchPaths-1\.2\.3/SearchPathsConfig\.cmake
+
+ The file was found at
+
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_lib_pkg/lib/SearchPaths-1\.2\.3/SearchPathsConfig\.cmake
diff --git a/Tests/RunCMake/find_package/SearchPaths_prefix_lib_pkg.cmake b/Tests/RunCMake/find_package/SearchPaths_prefix_lib_pkg.cmake
new file mode 100644
index 0000000..d831313
--- /dev/null
+++ b/Tests/RunCMake/find_package/SearchPaths_prefix_lib_pkg.cmake
@@ -0,0 +1 @@
+include("${CMAKE_CURRENT_SOURCE_DIR}/SearchPaths.cmake")
diff --git a/Tests/RunCMake/find_package/SearchPaths_prefix_lib_pkg_cmake-stderr.txt b/Tests/RunCMake/find_package/SearchPaths_prefix_lib_pkg_cmake-stderr.txt
new file mode 100644
index 0000000..f290545
--- /dev/null
+++ b/Tests/RunCMake/find_package/SearchPaths_prefix_lib_pkg_cmake-stderr.txt
@@ -0,0 +1,12 @@
+ find_package considered the following locations for SearchPaths's Config
+ module:
+
+ .*/Tests/RunCMake/find_package/SearchPaths_prefix_lib_pkg_cmake-build/CMakeFiles/pkgRedirects/SearchPathsConfig\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths_prefix_lib_pkg_cmake-build/CMakeFiles/pkgRedirects/searchpaths-config\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_lib_pkg_cmake/SearchPathsConfig\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_lib_pkg_cmake/searchpaths-config\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_lib_pkg_cmake/lib/SearchPaths-1\.2\.3/cmake/SearchPathsConfig\.cmake
+
+ The file was found at
+
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_lib_pkg_cmake/lib/SearchPaths-1\.2\.3/cmake/SearchPathsConfig\.cmake
diff --git a/Tests/RunCMake/find_package/SearchPaths_prefix_lib_pkg_cmake.cmake b/Tests/RunCMake/find_package/SearchPaths_prefix_lib_pkg_cmake.cmake
new file mode 100644
index 0000000..d831313
--- /dev/null
+++ b/Tests/RunCMake/find_package/SearchPaths_prefix_lib_pkg_cmake.cmake
@@ -0,0 +1 @@
+include("${CMAKE_CURRENT_SOURCE_DIR}/SearchPaths.cmake")
diff --git a/Tests/RunCMake/find_package/SearchPaths_prefix_pkg-stderr.txt b/Tests/RunCMake/find_package/SearchPaths_prefix_pkg-stderr.txt
new file mode 100644
index 0000000..32b9fcb
--- /dev/null
+++ b/Tests/RunCMake/find_package/SearchPaths_prefix_pkg-stderr.txt
@@ -0,0 +1,12 @@
+ find_package considered the following locations for SearchPaths's Config
+ module:
+
+ .*/Tests/RunCMake/find_package/SearchPaths_prefix_pkg-build/CMakeFiles/pkgRedirects/SearchPathsConfig\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths_prefix_pkg-build/CMakeFiles/pkgRedirects/searchpaths-config\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_pkg/SearchPathsConfig\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_pkg/searchpaths-config\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_pkg/SearchPaths-1\.2\.3/SearchPathsConfig\.cmake
+
+ The file was found at
+
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_pkg/SearchPaths-1\.2\.3/SearchPathsConfig\.cmake
diff --git a/Tests/RunCMake/find_package/SearchPaths_prefix_pkg.cmake b/Tests/RunCMake/find_package/SearchPaths_prefix_pkg.cmake
new file mode 100644
index 0000000..d831313
--- /dev/null
+++ b/Tests/RunCMake/find_package/SearchPaths_prefix_pkg.cmake
@@ -0,0 +1 @@
+include("${CMAKE_CURRENT_SOURCE_DIR}/SearchPaths.cmake")
diff --git a/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_cmake-stderr.txt b/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_cmake-stderr.txt
new file mode 100644
index 0000000..7bf5cf8
--- /dev/null
+++ b/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_cmake-stderr.txt
@@ -0,0 +1,14 @@
+ find_package considered the following locations for SearchPaths's Config
+ module:
+
+ .*/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_cmake-build/CMakeFiles/pkgRedirects/SearchPathsConfig\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_cmake-build/CMakeFiles/pkgRedirects/searchpaths-config\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_cmake/SearchPathsConfig\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_cmake/searchpaths-config\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_cmake/SearchPaths-1\.2\.3/SearchPathsConfig\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_cmake/SearchPaths-1\.2\.3/searchpaths-config\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_cmake/SearchPaths-1\.2\.3/cmake/SearchPathsConfig\.cmake
+
+ The file was found at
+
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_cmake/SearchPaths-1\.2\.3/cmake/SearchPathsConfig\.cmake
diff --git a/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_cmake.cmake b/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_cmake.cmake
new file mode 100644
index 0000000..d831313
--- /dev/null
+++ b/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_cmake.cmake
@@ -0,0 +1 @@
+include("${CMAKE_CURRENT_SOURCE_DIR}/SearchPaths.cmake")
diff --git a/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_lib_cmake_pkg-stderr.txt b/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_lib_cmake_pkg-stderr.txt
new file mode 100644
index 0000000..3592f72
--- /dev/null
+++ b/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_lib_cmake_pkg-stderr.txt
@@ -0,0 +1,14 @@
+ find_package considered the following locations for SearchPaths's Config
+ module:
+
+ .*/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_lib_cmake_pkg-build/CMakeFiles/pkgRedirects/SearchPathsConfig\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_lib_cmake_pkg-build/CMakeFiles/pkgRedirects/searchpaths-config\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_lib_cmake_pkg/SearchPathsConfig\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_lib_cmake_pkg/searchpaths-config\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_lib_cmake_pkg/SearchPaths-1\.2\.3/SearchPathsConfig\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_lib_cmake_pkg/SearchPaths-1\.2\.3/searchpaths-config\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_lib_cmake_pkg/SearchPaths-1\.2\.3/lib/cmake/SearchPaths-1\.2\.3/SearchPathsConfig\.cmake
+
+ The file was found at
+
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_lib_cmake_pkg/SearchPaths-1\.2\.3/lib/cmake/SearchPaths-1\.2\.3/SearchPathsConfig\.cmake
diff --git a/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_lib_cmake_pkg.cmake b/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_lib_cmake_pkg.cmake
new file mode 100644
index 0000000..d831313
--- /dev/null
+++ b/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_lib_cmake_pkg.cmake
@@ -0,0 +1 @@
+include("${CMAKE_CURRENT_SOURCE_DIR}/SearchPaths.cmake")
diff --git a/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_lib_pkg-stderr.txt b/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_lib_pkg-stderr.txt
new file mode 100644
index 0000000..b196b7a
--- /dev/null
+++ b/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_lib_pkg-stderr.txt
@@ -0,0 +1,14 @@
+ find_package considered the following locations for SearchPaths's Config
+ module:
+
+ .*/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_lib_pkg-build/CMakeFiles/pkgRedirects/SearchPathsConfig\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_lib_pkg-build/CMakeFiles/pkgRedirects/searchpaths-config\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_lib_pkg/SearchPathsConfig\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_lib_pkg/searchpaths-config\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_lib_pkg/SearchPaths-1\.2\.3/SearchPathsConfig\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_lib_pkg/SearchPaths-1\.2\.3/searchpaths-config\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_lib_pkg/SearchPaths-1\.2\.3/lib/SearchPaths-1\.2\.3/SearchPathsConfig\.cmake
+
+ The file was found at
+
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_lib_pkg/SearchPaths-1\.2\.3/lib/SearchPaths-1\.2\.3/SearchPathsConfig\.cmake
diff --git a/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_lib_pkg.cmake b/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_lib_pkg.cmake
new file mode 100644
index 0000000..d831313
--- /dev/null
+++ b/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_lib_pkg.cmake
@@ -0,0 +1 @@
+include("${CMAKE_CURRENT_SOURCE_DIR}/SearchPaths.cmake")
diff --git a/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_lib_pkg_cmake-stderr.txt b/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_lib_pkg_cmake-stderr.txt
new file mode 100644
index 0000000..17e0399
--- /dev/null
+++ b/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_lib_pkg_cmake-stderr.txt
@@ -0,0 +1,14 @@
+ find_package considered the following locations for SearchPaths's Config
+ module:
+
+ .*/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_lib_pkg_cmake-build/CMakeFiles/pkgRedirects/SearchPathsConfig\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_lib_pkg_cmake-build/CMakeFiles/pkgRedirects/searchpaths-config\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_lib_pkg_cmake/SearchPathsConfig\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_lib_pkg_cmake/searchpaths-config\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_lib_pkg_cmake/SearchPaths-1\.2\.3/SearchPathsConfig\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_lib_pkg_cmake/SearchPaths-1\.2\.3/searchpaths-config\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_lib_pkg_cmake/SearchPaths-1\.2\.3/lib/SearchPaths-1\.2\.3/cmake/SearchPathsConfig\.cmake
+
+ The file was found at
+
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_lib_pkg_cmake/SearchPaths-1\.2\.3/lib/SearchPaths-1\.2\.3/cmake/SearchPathsConfig\.cmake
diff --git a/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_lib_pkg_cmake.cmake b/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_lib_pkg_cmake.cmake
new file mode 100644
index 0000000..d831313
--- /dev/null
+++ b/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_lib_pkg_cmake.cmake
@@ -0,0 +1 @@
+include("${CMAKE_CURRENT_SOURCE_DIR}/SearchPaths.cmake")
diff --git a/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_share_cmake_pkg-stderr.txt b/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_share_cmake_pkg-stderr.txt
new file mode 100644
index 0000000..ee01a50
--- /dev/null
+++ b/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_share_cmake_pkg-stderr.txt
@@ -0,0 +1,14 @@
+ find_package considered the following locations for SearchPaths's Config
+ module:
+
+ .*/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_share_cmake_pkg-build/CMakeFiles/pkgRedirects/SearchPathsConfig\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_share_cmake_pkg-build/CMakeFiles/pkgRedirects/searchpaths-config\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_share_cmake_pkg/SearchPathsConfig\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_share_cmake_pkg/searchpaths-config\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_share_cmake_pkg/SearchPaths-1\.2\.3/SearchPathsConfig\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_share_cmake_pkg/SearchPaths-1\.2\.3/searchpaths-config\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_share_cmake_pkg/SearchPaths-1\.2\.3/share/cmake/SearchPaths-1\.2\.3/SearchPathsConfig\.cmake
+
+ The file was found at
+
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_share_cmake_pkg/SearchPaths-1\.2\.3/share/cmake/SearchPaths-1\.2\.3/SearchPathsConfig\.cmake
diff --git a/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_share_cmake_pkg.cmake b/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_share_cmake_pkg.cmake
new file mode 100644
index 0000000..d831313
--- /dev/null
+++ b/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_share_cmake_pkg.cmake
@@ -0,0 +1 @@
+include("${CMAKE_CURRENT_SOURCE_DIR}/SearchPaths.cmake")
diff --git a/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_share_pkg-stderr.txt b/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_share_pkg-stderr.txt
new file mode 100644
index 0000000..d6abd2f
--- /dev/null
+++ b/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_share_pkg-stderr.txt
@@ -0,0 +1,14 @@
+ find_package considered the following locations for SearchPaths's Config
+ module:
+
+ .*/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_share_pkg-build/CMakeFiles/pkgRedirects/SearchPathsConfig\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_share_pkg-build/CMakeFiles/pkgRedirects/searchpaths-config\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_share_pkg/SearchPathsConfig\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_share_pkg/searchpaths-config\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_share_pkg/SearchPaths-1\.2\.3/SearchPathsConfig\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_share_pkg/SearchPaths-1\.2\.3/searchpaths-config\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_share_pkg/SearchPaths-1\.2\.3/share/SearchPaths-1\.2\.3/SearchPathsConfig\.cmake
+
+ The file was found at
+
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_share_pkg/SearchPaths-1\.2\.3/share/SearchPaths-1\.2\.3/SearchPathsConfig\.cmake
diff --git a/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_share_pkg.cmake b/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_share_pkg.cmake
new file mode 100644
index 0000000..d831313
--- /dev/null
+++ b/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_share_pkg.cmake
@@ -0,0 +1 @@
+include("${CMAKE_CURRENT_SOURCE_DIR}/SearchPaths.cmake")
diff --git a/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_share_pkg_cmake-stderr.txt b/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_share_pkg_cmake-stderr.txt
new file mode 100644
index 0000000..b578b2b
--- /dev/null
+++ b/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_share_pkg_cmake-stderr.txt
@@ -0,0 +1,14 @@
+ find_package considered the following locations for SearchPaths's Config
+ module:
+
+ .*/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_share_pkg_cmake-build/CMakeFiles/pkgRedirects/SearchPathsConfig\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_share_pkg_cmake-build/CMakeFiles/pkgRedirects/searchpaths-config\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_share_pkg_cmake/SearchPathsConfig\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_share_pkg_cmake/searchpaths-config\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_share_pkg_cmake/SearchPaths-1\.2\.3/SearchPathsConfig\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_share_pkg_cmake/SearchPaths-1\.2\.3/searchpaths-config\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_share_pkg_cmake/SearchPaths-1\.2\.3/share/SearchPaths-1\.2\.3/cmake/SearchPathsConfig\.cmake
+
+ The file was found at
+
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_share_pkg_cmake/SearchPaths-1\.2\.3/share/SearchPaths-1\.2\.3/cmake/SearchPathsConfig\.cmake
diff --git a/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_share_pkg_cmake.cmake b/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_share_pkg_cmake.cmake
new file mode 100644
index 0000000..d831313
--- /dev/null
+++ b/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_share_pkg_cmake.cmake
@@ -0,0 +1 @@
+include("${CMAKE_CURRENT_SOURCE_DIR}/SearchPaths.cmake")
diff --git a/Tests/RunCMake/find_package/SearchPaths_prefix_share_cmake_pkg-stderr.txt b/Tests/RunCMake/find_package/SearchPaths_prefix_share_cmake_pkg-stderr.txt
new file mode 100644
index 0000000..2f3f18a
--- /dev/null
+++ b/Tests/RunCMake/find_package/SearchPaths_prefix_share_cmake_pkg-stderr.txt
@@ -0,0 +1,12 @@
+ find_package considered the following locations for SearchPaths's Config
+ module:
+
+ .*/Tests/RunCMake/find_package/SearchPaths_prefix_share_cmake_pkg-build/CMakeFiles/pkgRedirects/SearchPathsConfig\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths_prefix_share_cmake_pkg-build/CMakeFiles/pkgRedirects/searchpaths-config\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_share_cmake_pkg/SearchPathsConfig\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_share_cmake_pkg/searchpaths-config\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_share_cmake_pkg/share/cmake/SearchPaths-1\.2\.3/SearchPathsConfig\.cmake
+
+ The file was found at
+
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_share_cmake_pkg/share/cmake/SearchPaths-1\.2\.3/SearchPathsConfig\.cmake
diff --git a/Tests/RunCMake/find_package/SearchPaths_prefix_share_cmake_pkg.cmake b/Tests/RunCMake/find_package/SearchPaths_prefix_share_cmake_pkg.cmake
new file mode 100644
index 0000000..d831313
--- /dev/null
+++ b/Tests/RunCMake/find_package/SearchPaths_prefix_share_cmake_pkg.cmake
@@ -0,0 +1 @@
+include("${CMAKE_CURRENT_SOURCE_DIR}/SearchPaths.cmake")
diff --git a/Tests/RunCMake/find_package/SearchPaths_prefix_share_pkg-stderr.txt b/Tests/RunCMake/find_package/SearchPaths_prefix_share_pkg-stderr.txt
new file mode 100644
index 0000000..3eef002
--- /dev/null
+++ b/Tests/RunCMake/find_package/SearchPaths_prefix_share_pkg-stderr.txt
@@ -0,0 +1,12 @@
+ find_package considered the following locations for SearchPaths's Config
+ module:
+
+ .*/Tests/RunCMake/find_package/SearchPaths_prefix_share_pkg-build/CMakeFiles/pkgRedirects/SearchPathsConfig\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths_prefix_share_pkg-build/CMakeFiles/pkgRedirects/searchpaths-config\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_share_pkg/SearchPathsConfig\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_share_pkg/searchpaths-config\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_share_pkg/share/SearchPaths-1\.2\.3/SearchPathsConfig\.cmake
+
+ The file was found at
+
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_share_pkg/share/SearchPaths-1\.2\.3/SearchPathsConfig\.cmake
diff --git a/Tests/RunCMake/find_package/SearchPaths_prefix_share_pkg.cmake b/Tests/RunCMake/find_package/SearchPaths_prefix_share_pkg.cmake
new file mode 100644
index 0000000..d831313
--- /dev/null
+++ b/Tests/RunCMake/find_package/SearchPaths_prefix_share_pkg.cmake
@@ -0,0 +1 @@
+include("${CMAKE_CURRENT_SOURCE_DIR}/SearchPaths.cmake")
diff --git a/Tests/RunCMake/find_package/SearchPaths_prefix_share_pkg_cmake-stderr.txt b/Tests/RunCMake/find_package/SearchPaths_prefix_share_pkg_cmake-stderr.txt
new file mode 100644
index 0000000..c962f8b
--- /dev/null
+++ b/Tests/RunCMake/find_package/SearchPaths_prefix_share_pkg_cmake-stderr.txt
@@ -0,0 +1,12 @@
+ find_package considered the following locations for SearchPaths's Config
+ module:
+
+ .*/Tests/RunCMake/find_package/SearchPaths_prefix_share_pkg_cmake-build/CMakeFiles/pkgRedirects/SearchPathsConfig\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths_prefix_share_pkg_cmake-build/CMakeFiles/pkgRedirects/searchpaths-config\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_share_pkg_cmake/SearchPathsConfig\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_share_pkg_cmake/searchpaths-config\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_share_pkg_cmake/share/SearchPaths-1\.2\.3/cmake/SearchPathsConfig\.cmake
+
+ The file was found at
+
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_share_pkg_cmake/share/SearchPaths-1\.2\.3/cmake/SearchPathsConfig\.cmake
diff --git a/Tests/RunCMake/find_package/SearchPaths_prefix_share_pkg_cmake.cmake b/Tests/RunCMake/find_package/SearchPaths_prefix_share_pkg_cmake.cmake
new file mode 100644
index 0000000..d831313
--- /dev/null
+++ b/Tests/RunCMake/find_package/SearchPaths_prefix_share_pkg_cmake.cmake
@@ -0,0 +1 @@
+include("${CMAKE_CURRENT_SOURCE_DIR}/SearchPaths.cmake")
diff --git a/Utilities/Release/linux/aarch64/Dockerfile b/Utilities/Release/linux/aarch64/Dockerfile
index 9abae2a..e232c01 100644
--- a/Utilities/Release/linux/aarch64/Dockerfile
+++ b/Utilities/Release/linux/aarch64/Dockerfile
@@ -25,7 +25,7 @@ RUN : \
&& nice make -j $(nproc) \
&& if $TEST; then \
# Run tests that require the full build tree.
- bin/ctest --output-on-failure -j 8 -R '^(CMake\.|CMakeLib\.|CMakeServerLib\.|RunCMake\.ctest_memcheck)'; \
+ bin/ctest --output-on-failure -j 8 -R '^(CMake\.|CMakeLib\.|RunCMake\.ctest_memcheck)'; \
fi \
&& bin/cpack -G TGZ \
&& bin/cpack -G STGZ \
diff --git a/Utilities/Release/linux/x86_64/Dockerfile b/Utilities/Release/linux/x86_64/Dockerfile
index 8c98d3e..736ee26 100644
--- a/Utilities/Release/linux/x86_64/Dockerfile
+++ b/Utilities/Release/linux/x86_64/Dockerfile
@@ -26,7 +26,7 @@ RUN : \
&& nice make -j $(nproc) \
&& if $TEST; then \
# Run tests that require the full build tree.
- bin/ctest --output-on-failure -j 8 -R '^(CMake\.|CMakeLib\.|CMakeServerLib\.|RunCMake\.ctest_memcheck)'; \
+ bin/ctest --output-on-failure -j 8 -R '^(CMake\.|CMakeLib\.|RunCMake\.ctest_memcheck)'; \
fi \
&& bin/cpack -G TGZ \
&& bin/cpack -G STGZ \