summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitlab-ci.yml20
-rw-r--r--.gitlab/ci/configure_fedora37_common_clang.cmake6
-rw-r--r--.gitlab/ci/configure_fedora37_makefiles_clang.cmake1
-rw-r--r--.gitlab/ci/configure_fedora37_ninja_clang.cmake1
-rw-r--r--.gitlab/ci/env_fedora37_common_clang.sh4
-rw-r--r--.gitlab/ci/env_fedora37_makefiles_clang.sh1
-rw-r--r--.gitlab/ci/env_fedora37_ninja_clang.sh1
-rw-r--r--.gitlab/os-linux.yml13
-rw-r--r--Help/manual/cmake-compile-features.7.rst22
-rw-r--r--Help/manual/cmake-properties.7.rst2
-rw-r--r--Help/manual/cmake-variables.7.rst1
-rw-r--r--Help/prop_sf/CXX_SCAN_FOR_MODULES.rst19
-rw-r--r--Help/prop_tgt/CXX_SCAN_FOR_MODULES.rst22
-rw-r--r--Help/release/dev/cxx-scanning-properties.rst5
-rw-r--r--Help/release/dev/lang-std-flag-order.rst7
-rw-r--r--Help/variable/CMAKE_CXX_SCAN_FOR_MODULES.rst10
-rw-r--r--Source/CMakeVersion.cmake2
-rw-r--r--Source/CPack/cmCPackDragNDropGenerator.cxx2
-rw-r--r--Source/cmExportFileGenerator.cxx7
-rw-r--r--Source/cmGeneratorExpression.cxx2
-rw-r--r--Source/cmGeneratorTarget.cxx2
-rw-r--r--Source/cmLocalGenerator.cxx58
-rw-r--r--Source/cmLocalGenerator.h4
-rw-r--r--Source/cmNinjaTargetGenerator.cxx171
-rw-r--r--Source/cmNinjaTargetGenerator.h19
-rw-r--r--Source/cmTarget.cxx1
-rw-r--r--Source/cmVisualStudio10TargetGenerator.cxx2
-rw-r--r--Tests/CMakeTests/CMakeLists.txt10
-rw-r--r--Tests/CMakeTests/FileDownloadBadHashTest.cmake.in13
-rw-r--r--Tests/CMakeTests/FileDownloadTest.cmake.in229
-rw-r--r--Tests/CMakeTests/FileUploadInput.png (renamed from Tests/CMakeTests/FileDownloadInput.png)bin194 -> 194 bytes
-rw-r--r--Tests/CMakeTests/FileUploadTest.cmake.in2
-rw-r--r--Tests/CompileFeatures/CMakeLists.txt13
-rw-r--r--Tests/CompileFeatures/msvc_permissive.cxx9
-rw-r--r--Tests/RunCMake/CMakeLists.txt1
-rw-r--r--Tests/RunCMake/CXXModules/RunCMakeTest.cmake1
-rw-r--r--Tests/RunCMake/CXXModules/examples/scan_properties-stderr.txt9
-rw-r--r--Tests/RunCMake/CXXModules/examples/scan_properties/CMakeLists.txt54
-rw-r--r--Tests/RunCMake/CXXModules/examples/scan_properties/always_scan.cxx10
-rw-r--r--Tests/RunCMake/CXXModules/examples/scan_properties/join.cxx17
-rw-r--r--Tests/RunCMake/CXXModules/examples/scan_properties/main.cxx16
-rw-r--r--Tests/RunCMake/CXXModules/examples/scan_properties/module.cxx10
-rw-r--r--Tests/RunCMake/CXXModules/examples/scan_properties/never_scan.cxx8
-rw-r--r--Tests/RunCMake/file-DOWNLOAD/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/file-DOWNLOAD/EXPECTED_HASH-stdout.txt8
-rw-r--r--Tests/RunCMake/file-DOWNLOAD/EXPECTED_HASH.cmake13
-rw-r--r--Tests/RunCMake/file-DOWNLOAD/RunCMakeTest.cmake26
-rw-r--r--Tests/RunCMake/file-DOWNLOAD/SHOW_PROGRESS-stdout.txt2
-rw-r--r--Tests/RunCMake/file-DOWNLOAD/SHOW_PROGRESS.cmake3
-rw-r--r--Tests/RunCMake/file-DOWNLOAD/bad-hostname-stdout.txt1
-rw-r--r--Tests/RunCMake/file-DOWNLOAD/bad-hostname.cmake9
-rw-r--r--Tests/RunCMake/file-DOWNLOAD/basic-stdout.txt1
-rw-r--r--Tests/RunCMake/file-DOWNLOAD/basic.cmake3
-rw-r--r--Tests/RunCMake/file-DOWNLOAD/common.cmake15
-rw-r--r--Tests/RunCMake/file-DOWNLOAD/file-without-path-stdout.txt1
-rw-r--r--Tests/RunCMake/file-DOWNLOAD/file-without-path.cmake10
-rw-r--r--Tests/RunCMake/file-DOWNLOAD/hash-mismatch-result.txt (renamed from Tests/RunCMake/file/DOWNLOAD-tls-verify-not-set-result.txt)0
-rw-r--r--Tests/RunCMake/file-DOWNLOAD/hash-mismatch-stderr.txt11
-rw-r--r--Tests/RunCMake/file-DOWNLOAD/hash-mismatch.cmake8
-rw-r--r--Tests/RunCMake/file-DOWNLOAD/httpheader-not-set-result.txt (renamed from Tests/RunCMake/file/DOWNLOAD-tls-cainfo-not-set-result.txt)0
-rw-r--r--Tests/RunCMake/file-DOWNLOAD/httpheader-not-set-stderr.txt (renamed from Tests/RunCMake/file/DOWNLOAD-httpheader-not-set-stderr.txt)2
-rw-r--r--Tests/RunCMake/file-DOWNLOAD/httpheader-not-set.cmake (renamed from Tests/RunCMake/file/DOWNLOAD-httpheader-not-set.cmake)0
-rw-r--r--Tests/RunCMake/file-DOWNLOAD/input.pngbin0 -> 194 bytes
-rw-r--r--Tests/RunCMake/file-DOWNLOAD/netrc-bad-result.txt (renamed from Tests/RunCMake/file/DOWNLOAD-pass-not-set-result.txt)0
-rw-r--r--Tests/RunCMake/file-DOWNLOAD/netrc-bad-stderr.txt (renamed from Tests/RunCMake/file/DOWNLOAD-netrc-bad-stderr.txt)8
-rw-r--r--Tests/RunCMake/file-DOWNLOAD/netrc-bad.cmake (renamed from Tests/RunCMake/file/DOWNLOAD-netrc-bad.cmake)4
-rw-r--r--Tests/RunCMake/file-DOWNLOAD/netrc-bad.txt (renamed from Tests/RunCMake/file/DOWNLOAD-unused-argument.txt)0
-rw-r--r--Tests/RunCMake/file-DOWNLOAD/no-file-arg.cmake11
-rw-r--r--Tests/RunCMake/file-DOWNLOAD/no-file-stdout.txt1
-rw-r--r--Tests/RunCMake/file-DOWNLOAD/no-file.cmake11
-rw-r--r--Tests/RunCMake/file-DOWNLOAD/no-save-hash-result.txt (renamed from Tests/RunCMake/file/DOWNLOAD-no-save-hash-result.txt)0
-rw-r--r--Tests/RunCMake/file-DOWNLOAD/no-save-hash-stderr.txt (renamed from Tests/RunCMake/file/DOWNLOAD-no-save-hash-stderr.txt)3
-rw-r--r--Tests/RunCMake/file-DOWNLOAD/no-save-hash.cmake5
-rw-r--r--Tests/RunCMake/file-DOWNLOAD/no-save-hash.txt (renamed from Tests/RunCMake/file/DOWNLOAD-unused-argument-result.txt)0
-rw-r--r--Tests/RunCMake/file-DOWNLOAD/pass-not-set-result.txt (renamed from Tests/RunCMake/file/DOWNLOAD-netrc-bad-result.txt)0
-rw-r--r--Tests/RunCMake/file-DOWNLOAD/pass-not-set-stderr.txt (renamed from Tests/RunCMake/file/DOWNLOAD-pass-not-set-stderr.txt)2
-rw-r--r--Tests/RunCMake/file-DOWNLOAD/pass-not-set.cmake (renamed from Tests/RunCMake/file/DOWNLOAD-pass-not-set.cmake)0
-rw-r--r--Tests/RunCMake/file-DOWNLOAD/range-stdout.txt4
-rw-r--r--Tests/RunCMake/file-DOWNLOAD/range.cmake15
-rw-r--r--Tests/RunCMake/file-DOWNLOAD/tls-cainfo-not-set-result.txt (renamed from Tests/RunCMake/file/DOWNLOAD-httpheader-not-set-result.txt)0
-rw-r--r--Tests/RunCMake/file-DOWNLOAD/tls-cainfo-not-set-stderr.txt (renamed from Tests/RunCMake/file/DOWNLOAD-tls-cainfo-not-set-stderr.txt)2
-rw-r--r--Tests/RunCMake/file-DOWNLOAD/tls-cainfo-not-set.cmake (renamed from Tests/RunCMake/file/DOWNLOAD-tls-cainfo-not-set.cmake)0
-rw-r--r--Tests/RunCMake/file-DOWNLOAD/tls-verify-not-set-result.txt (renamed from Tests/RunCMake/file/DOWNLOAD-hash-mismatch-result.txt)0
-rw-r--r--Tests/RunCMake/file-DOWNLOAD/tls-verify-not-set-stderr.txt (renamed from Tests/RunCMake/file/DOWNLOAD-tls-verify-not-set-stderr.txt)2
-rw-r--r--Tests/RunCMake/file-DOWNLOAD/tls-verify-not-set.cmake (renamed from Tests/RunCMake/file/DOWNLOAD-tls-verify-not-set.cmake)0
-rw-r--r--Tests/RunCMake/file-DOWNLOAD/unused-argument-result.txt (renamed from Tests/RunCMake/file/DOWNLOAD-no-save-hash.txt)0
-rw-r--r--Tests/RunCMake/file-DOWNLOAD/unused-argument-stderr.txt (renamed from Tests/RunCMake/file/DOWNLOAD-unused-argument-stderr.txt)3
-rw-r--r--Tests/RunCMake/file-DOWNLOAD/unused-argument.cmake3
-rw-r--r--Tests/RunCMake/file/DOWNLOAD-hash-mismatch-stderr.txt11
-rw-r--r--Tests/RunCMake/file/DOWNLOAD-hash-mismatch.cmake10
-rw-r--r--Tests/RunCMake/file/DOWNLOAD-hash-mismatch.txt0
-rw-r--r--Tests/RunCMake/file/DOWNLOAD-netrc-bad.txt0
-rw-r--r--Tests/RunCMake/file/DOWNLOAD-no-save-hash.cmake8
-rw-r--r--Tests/RunCMake/file/DOWNLOAD-unused-argument.cmake8
-rw-r--r--Tests/RunCMake/file/RunCMakeTest.cmake8
-rw-r--r--Utilities/ClangTidyModule/Tests/cmake-use-cmstrlen-fixit.cxx5
-rw-r--r--Utilities/ClangTidyModule/Tests/cmake-use-cmstrlen-stdout.txt32
-rw-r--r--Utilities/ClangTidyModule/Tests/cmake-use-cmstrlen.cxx5
-rw-r--r--Utilities/ClangTidyModule/UseCmstrlenCheck.cxx52
99 files changed, 720 insertions, 416 deletions
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 4c44b07..24e19c7 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -196,6 +196,26 @@ t:debian10-makefiles-clang:
variables:
CMAKE_CI_JOB_NIGHTLY: "true"
+t:fedora37-ninja-clang:
+ extends:
+ - .fedora37_ninja_clang
+ - .cmake_test_linux_release
+ - .linux_builder_tags_qt
+ - .run_dependent
+ - .needs_centos6_x86_64
+ variables:
+ CMAKE_CI_JOB_NIGHTLY: "true"
+
+t:fedora37-makefiles-clang:
+ extends:
+ - .fedora37_makefiles_clang
+ - .cmake_test_linux_release
+ - .linux_builder_tags_qt
+ - .run_dependent
+ - .needs_centos6_x86_64
+ variables:
+ CMAKE_CI_JOB_NIGHTLY: "true"
+
t:fedora37-makefiles:
extends:
- .fedora37_makefiles
diff --git a/.gitlab/ci/configure_fedora37_common_clang.cmake b/.gitlab/ci/configure_fedora37_common_clang.cmake
new file mode 100644
index 0000000..70c9df9
--- /dev/null
+++ b/.gitlab/ci/configure_fedora37_common_clang.cmake
@@ -0,0 +1,6 @@
+set(CMAKE_Fortran_COMPILER "/usr/bin/flang-new" CACHE FILEPATH "")
+set(CMAKE_Fortran_COMPILER_ID "LLVMFlang" CACHE STRING "")
+set(CMAKE_Fortran_COMPILER_SUPPORTS_F90 "1" CACHE BOOL "")
+set(CMAKE_Fortran_FLAGS "-flang-experimental-exec" CACHE STRING "")
+
+include("${CMAKE_CURRENT_LIST_DIR}/configure_external_test.cmake")
diff --git a/.gitlab/ci/configure_fedora37_makefiles_clang.cmake b/.gitlab/ci/configure_fedora37_makefiles_clang.cmake
new file mode 100644
index 0000000..7b82a9a
--- /dev/null
+++ b/.gitlab/ci/configure_fedora37_makefiles_clang.cmake
@@ -0,0 +1 @@
+include("${CMAKE_CURRENT_LIST_DIR}/configure_fedora37_common_clang.cmake")
diff --git a/.gitlab/ci/configure_fedora37_ninja_clang.cmake b/.gitlab/ci/configure_fedora37_ninja_clang.cmake
new file mode 100644
index 0000000..7b82a9a
--- /dev/null
+++ b/.gitlab/ci/configure_fedora37_ninja_clang.cmake
@@ -0,0 +1 @@
+include("${CMAKE_CURRENT_LIST_DIR}/configure_fedora37_common_clang.cmake")
diff --git a/.gitlab/ci/env_fedora37_common_clang.sh b/.gitlab/ci/env_fedora37_common_clang.sh
new file mode 100644
index 0000000..b03b757
--- /dev/null
+++ b/.gitlab/ci/env_fedora37_common_clang.sh
@@ -0,0 +1,4 @@
+export CC=/usr/bin/clang-15
+export CXX=/usr/bin/clang++-15
+export FC=/usr/bin/flang-new
+export FFLAGS=-flang-experimental-exec
diff --git a/.gitlab/ci/env_fedora37_makefiles_clang.sh b/.gitlab/ci/env_fedora37_makefiles_clang.sh
new file mode 100644
index 0000000..9ff1d84
--- /dev/null
+++ b/.gitlab/ci/env_fedora37_makefiles_clang.sh
@@ -0,0 +1 @@
+. .gitlab/ci/env_fedora37_common_clang.sh
diff --git a/.gitlab/ci/env_fedora37_ninja_clang.sh b/.gitlab/ci/env_fedora37_ninja_clang.sh
new file mode 100644
index 0000000..9ff1d84
--- /dev/null
+++ b/.gitlab/ci/env_fedora37_ninja_clang.sh
@@ -0,0 +1 @@
+. .gitlab/ci/env_fedora37_common_clang.sh
diff --git a/.gitlab/os-linux.yml b/.gitlab/os-linux.yml
index 6a99f33..8fc6ae1 100644
--- a/.gitlab/os-linux.yml
+++ b/.gitlab/os-linux.yml
@@ -200,6 +200,19 @@
variables:
CMAKE_CONFIGURATION: debian10_ninja_clang
+.fedora37_makefiles_clang:
+ extends: .fedora37
+
+ variables:
+ CMAKE_CONFIGURATION: fedora37_makefiles_clang
+ CMAKE_GENERATOR: "Unix Makefiles"
+
+.fedora37_ninja_clang:
+ extends: .fedora37
+
+ variables:
+ CMAKE_CONFIGURATION: fedora37_ninja_clang
+
### Sanitizers
.fedora_memcheck:
diff --git a/Help/manual/cmake-compile-features.7.rst b/Help/manual/cmake-compile-features.7.rst
index 8073511..1e87ec6 100644
--- a/Help/manual/cmake-compile-features.7.rst
+++ b/Help/manual/cmake-compile-features.7.rst
@@ -282,3 +282,25 @@ versions specified for each:
* ``Clang``: Clang compiler 5.0+.
* ``NVIDIA``: NVIDIA nvcc compiler 7.5+.
+
+.. _`Language Standard Flags`:
+
+Language Standard Flags
+=======================
+
+In order to satisfy requirements specified by the
+:command:`target_compile_features` command or the
+:variable:`CMAKE_<LANG>_STANDARD` variable, CMake may pass a
+language standard flag to the compiler, such as ``-std=c++11``.
+
+For :ref:`Visual Studio Generators`, CMake cannot precisely control
+the placement of the language standard flag on the compiler command line.
+For :ref:`Ninja Generators`, :ref:`Makefile Generators`, and
+:generator:`Xcode`, CMake places the language standard flag just after
+the language-wide flags from :variable:`CMAKE_<LANG>_FLAGS`
+and :variable:`CMAKE_<LANG>_FLAGS_<CONFIG>`.
+
+.. versionchanged:: 3.26
+ The language standard flag is placed before flags specified by other
+ abstractions such as the :command:`target_compile_options` command.
+ Prior to CMake 3.26, the language standard flag was placed after them.
diff --git a/Help/manual/cmake-properties.7.rst b/Help/manual/cmake-properties.7.rst
index b17be82..e9ee681 100644
--- a/Help/manual/cmake-properties.7.rst
+++ b/Help/manual/cmake-properties.7.rst
@@ -195,6 +195,7 @@ Properties on Targets
/prop_tgt/CXX_MODULE_SET
/prop_tgt/CXX_MODULE_SET_NAME
/prop_tgt/CXX_MODULE_SETS
+ /prop_tgt/CXX_SCAN_FOR_MODULES
/prop_tgt/CXX_STANDARD
/prop_tgt/CXX_STANDARD_REQUIRED
/prop_tgt/DEBUG_POSTFIX
@@ -533,6 +534,7 @@ Properties on Source Files
/prop_sf/COMPILE_DEFINITIONS
/prop_sf/COMPILE_FLAGS
/prop_sf/COMPILE_OPTIONS
+ /prop_sf/CXX_SCAN_FOR_MODULES
/prop_sf/EXTERNAL_OBJECT
/prop_sf/Fortran_FORMAT
/prop_sf/Fortran_PREPROCESS
diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst
index cd46615..d66bb2b 100644
--- a/Help/manual/cmake-variables.7.rst
+++ b/Help/manual/cmake-variables.7.rst
@@ -417,6 +417,7 @@ Variables that Control the Build
/variable/CMAKE_CUDA_RESOLVE_DEVICE_SYMBOLS
/variable/CMAKE_CUDA_RUNTIME_LIBRARY
/variable/CMAKE_CUDA_SEPARABLE_COMPILATION
+ /variable/CMAKE_CXX_SCAN_FOR_MODULES
/variable/CMAKE_DEBUG_POSTFIX
/variable/CMAKE_DEFAULT_BUILD_TYPE
/variable/CMAKE_DEFAULT_CONFIGS
diff --git a/Help/prop_sf/CXX_SCAN_FOR_MODULES.rst b/Help/prop_sf/CXX_SCAN_FOR_MODULES.rst
new file mode 100644
index 0000000..9d6c0a5
--- /dev/null
+++ b/Help/prop_sf/CXX_SCAN_FOR_MODULES.rst
@@ -0,0 +1,19 @@
+CXX_SCAN_FOR_MODULES
+--------------------
+
+.. versionadded:: 3.26
+
+``CXX_SCAN_FOR_MODULES`` is a boolean specifying whether CMake will scan the
+source for C++ module dependencies. See also the
+:prop_tgt:`CXX_SCAN_FOR_MODULES` for target-wide settings.
+
+When this property is set ``ON``, CMake will scan the source at build time and
+add module dependency information to the compile line as necessary. When this
+property is set ``OFF``, CMake will not scan the source at build time. When
+this property is unset, the :prop_tgt:`CXX_SCAN_FOR_MODULES` property is
+consulted.
+
+Note that scanning is only performed if C++20 or higher is enabled for the
+target and the source uses the ``CXX`` language. Scanning for modules in
+sources belonging to file sets of type ``CXX_MODULES`` and
+``CXX_MODULES_HEADER_UNITS`` is always performed.
diff --git a/Help/prop_tgt/CXX_SCAN_FOR_MODULES.rst b/Help/prop_tgt/CXX_SCAN_FOR_MODULES.rst
new file mode 100644
index 0000000..5e89ba2
--- /dev/null
+++ b/Help/prop_tgt/CXX_SCAN_FOR_MODULES.rst
@@ -0,0 +1,22 @@
+CXX_SCAN_FOR_MODULES
+--------------------
+
+.. versionadded:: 3.26
+
+``CXX_SCAN_FOR_MODULES`` is a boolean specifying whether CMake will scan C++
+sources in the target for module dependencies. See also the
+:prop_sf:`CXX_SCAN_FOR_MODULES` for per-source settings which, if set,
+overrides the target-wide settings.
+
+This property is initialized by the value of the
+:variable:`CMAKE_CXX_SCAN_FOR_MODULES` variable if it is set when a target is
+created.
+
+When this property is set ``ON`` or unset, CMake will scan the target's
+``CXX`` sources at build time and add module dependency information to the
+compile line as necessary. When this property is set ``OFF``, CMake will not
+scan the target's ``CXX`` sources at build time.
+
+Note that scanning is only performed if C++20 or higher is enabled for the
+target. Scanning for modules in the target's sources belonging to file sets
+of type ``CXX_MODULES`` and ``CXX_MODULES_HEADER_UNITS`` is always performed.
diff --git a/Help/release/dev/cxx-scanning-properties.rst b/Help/release/dev/cxx-scanning-properties.rst
new file mode 100644
index 0000000..b393728
--- /dev/null
+++ b/Help/release/dev/cxx-scanning-properties.rst
@@ -0,0 +1,5 @@
+cxx-scanning-properties
+-----------------------
+
+* The :prop_tgt:`CXX_SCAN_FOR_MODULES` target and source file properties may
+ be used to enable or disable scanning for C++ module dependencies.
diff --git a/Help/release/dev/lang-std-flag-order.rst b/Help/release/dev/lang-std-flag-order.rst
new file mode 100644
index 0000000..4ef4123
--- /dev/null
+++ b/Help/release/dev/lang-std-flag-order.rst
@@ -0,0 +1,7 @@
+lang-std-flag-order
+-------------------
+
+* :ref:`Language Standard Flags`, such as ``-std=c++11``, when generated due
+ to :command:`target_compile_features` or :variable:`CMAKE_<LANG>_STANDARD`,
+ are now placed before flags added by :command:`target_compile_options`,
+ rather than after them.
diff --git a/Help/variable/CMAKE_CXX_SCAN_FOR_MODULES.rst b/Help/variable/CMAKE_CXX_SCAN_FOR_MODULES.rst
new file mode 100644
index 0000000..0d6c636
--- /dev/null
+++ b/Help/variable/CMAKE_CXX_SCAN_FOR_MODULES.rst
@@ -0,0 +1,10 @@
+CMAKE_CXX_SCAN_FOR_MODULES
+--------------------------
+
+.. versionadded:: 3.26
+
+Whether to scan C++ source files for module dependencies.
+
+This variable is used to initialize the :prop_tgt:`CXX_SCAN_FOR_MODULES`
+property on all the targets. See that target property for additional
+information.
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index ee7639f..f239c4c 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 25)
-set(CMake_VERSION_PATCH 20221118)
+set(CMake_VERSION_PATCH 20221121)
#set(CMake_VERSION_RC 0)
set(CMake_VERSION_IS_DIRTY 0)
diff --git a/Source/CPack/cmCPackDragNDropGenerator.cxx b/Source/CPack/cmCPackDragNDropGenerator.cxx
index 0579066..68e7ba3 100644
--- a/Source/CPack/cmCPackDragNDropGenerator.cxx
+++ b/Source/CPack/cmCPackDragNDropGenerator.cxx
@@ -451,7 +451,7 @@ int cmCPackDragNDropGenerator::CreateDMG(const std::string& src_dir,
mountpoint_regex.find(attach_output.c_str());
std::string const temp_mount = mountpoint_regex.match(1);
std::string const temp_mount_name =
- temp_mount.substr(sizeof("/Volumes/") - 1);
+ temp_mount.substr(cmStrLen("/Volumes/"));
// Remove dummy padding file so we have enough space on RW image ...
std::ostringstream dummy_padding;
diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx
index bd2b6af..c8e2cb8 100644
--- a/Source/cmExportFileGenerator.cxx
+++ b/Source/cmExportFileGenerator.cxx
@@ -669,8 +669,7 @@ void cmExportFileGenerator::ResolveTargetsInGeneratorExpression(
while ((pos = input.find("$<TARGET_PROPERTY:", lastPos)) !=
std::string::npos) {
- std::string::size_type nameStartPos =
- pos + sizeof("$<TARGET_PROPERTY:") - 1;
+ std::string::size_type nameStartPos = pos + cmStrLen("$<TARGET_PROPERTY:");
std::string::size_type closePos = input.find('>', nameStartPos);
std::string::size_type commaPos = input.find(',', nameStartPos);
std::string::size_type nextOpenPos = input.find("$<", nameStartPos);
@@ -696,7 +695,7 @@ void cmExportFileGenerator::ResolveTargetsInGeneratorExpression(
pos = 0;
lastPos = pos;
while ((pos = input.find("$<TARGET_NAME:", lastPos)) != std::string::npos) {
- std::string::size_type nameStartPos = pos + sizeof("$<TARGET_NAME:") - 1;
+ std::string::size_type nameStartPos = pos + cmStrLen("$<TARGET_NAME:");
std::string::size_type endPos = input.find('>', nameStartPos);
if (endPos == std::string::npos) {
errorString = "$<TARGET_NAME:...> expression incomplete";
@@ -721,7 +720,7 @@ void cmExportFileGenerator::ResolveTargetsInGeneratorExpression(
lastPos = pos;
while (errorString.empty() &&
(pos = input.find("$<LINK_ONLY:", lastPos)) != std::string::npos) {
- std::string::size_type nameStartPos = pos + sizeof("$<LINK_ONLY:") - 1;
+ std::string::size_type nameStartPos = pos + cmStrLen("$<LINK_ONLY:");
std::string::size_type endPos = input.find('>', nameStartPos);
if (endPos == std::string::npos) {
errorString = "$<LINK_ONLY:...> expression incomplete";
diff --git a/Source/cmGeneratorExpression.cxx b/Source/cmGeneratorExpression.cxx
index b605350..c5ae31b 100644
--- a/Source/cmGeneratorExpression.cxx
+++ b/Source/cmGeneratorExpression.cxx
@@ -406,7 +406,7 @@ void cmGeneratorExpression::ReplaceInstallPrefix(
while ((pos = input.find("$<INSTALL_PREFIX>", lastPos)) !=
std::string::npos) {
- std::string::size_type endPos = pos + sizeof("$<INSTALL_PREFIX>") - 1;
+ std::string::size_type endPos = pos + cmStrLen("$<INSTALL_PREFIX>");
input.replace(pos, endPos - pos, replacement);
lastPos = endPos;
}
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index 6065285..fae6d54 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -6718,7 +6718,7 @@ bool cmGeneratorTarget::IsLinkLookupScope(std::string const& n,
cmLocalGenerator const*& lg) const
{
if (cmHasLiteralPrefix(n, CMAKE_DIRECTORY_ID_SEP)) {
- cmDirectoryId const dirId = n.substr(sizeof(CMAKE_DIRECTORY_ID_SEP) - 1);
+ cmDirectoryId const dirId = n.substr(cmStrLen(CMAKE_DIRECTORY_ID_SEP));
if (dirId.String.empty()) {
lg = this->LocalGenerator;
return true;
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index 9745142..4d5371f 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -1021,12 +1021,6 @@ void cmLocalGenerator::AddCompileOptions(std::vector<BT<std::string>>& flags,
}
}
- std::string compReqFlag;
- this->AddCompilerRequirementFlag(compReqFlag, target, lang, config);
- if (!compReqFlag.empty()) {
- flags.emplace_back(std::move(compReqFlag));
- }
-
// Add Warning as errors flags
if (!this->GetCMakeInstance()->GetIgnoreWarningAsError()) {
const cmValue wError = target->GetProperty("COMPILE_WARNING_AS_ERROR");
@@ -1932,6 +1926,30 @@ void cmLocalGenerator::AddLanguageFlags(std::string& flags,
this->AddConfigVariableFlags(flags, cmStrCat("CMAKE_", lang, "_FLAGS"),
config);
+ // Add the language standard flag for compiling, and sometimes linking.
+ if (compileOrLink == cmBuildStep::Compile ||
+ (compileOrLink == cmBuildStep::Link &&
+ // Some toolchains require use of the language standard flag
+ // when linking in order to use the matching standard library.
+ // FIXME: If CMake gains an abstraction for standard library
+ // selection, this will have to be reconciled with it.
+ this->Makefile->IsOn(
+ cmStrCat("CMAKE_", lang, "_LINK_WITH_STANDARD_COMPILE_OPTION")))) {
+ cmStandardLevelResolver standardResolver(this->Makefile);
+ std::string const& optionFlagDef =
+ standardResolver.GetCompileOptionDef(target, lang, config);
+ if (!optionFlagDef.empty()) {
+ cmValue opt =
+ target->Target->GetMakefile()->GetDefinition(optionFlagDef);
+ if (opt) {
+ std::vector<std::string> optVec = cmExpandedList(*opt);
+ for (std::string const& i : optVec) {
+ this->AppendFlagEscape(flags, i);
+ }
+ }
+ }
+ }
+
std::string compiler = this->Makefile->GetSafeDefinition(
cmStrCat("CMAKE_", lang, "_COMPILER_ID"));
@@ -2076,15 +2094,6 @@ void cmLocalGenerator::AddLanguageFlagsForLinking(
std::string& flags, cmGeneratorTarget const* target, const std::string& lang,
const std::string& config)
{
- if (this->Makefile->IsOn("CMAKE_" + lang +
- "_LINK_WITH_STANDARD_COMPILE_OPTION")) {
- // This toolchain requires use of the language standard flag
- // when linking in order to use the matching standard library.
- // FIXME: If CMake gains an abstraction for standard library
- // selection, this will have to be reconciled with it.
- this->AddCompilerRequirementFlag(flags, target, lang, config);
- }
-
this->AddLanguageFlags(flags, target, cmBuildStep::Link, lang, config);
if (target->IsIPOEnabled(lang, config)) {
@@ -2224,25 +2233,6 @@ void cmLocalGenerator::AddSharedFlags(std::string& flags,
}
}
-void cmLocalGenerator::AddCompilerRequirementFlag(
- std::string& flags, cmGeneratorTarget const* target, const std::string& lang,
- const std::string& config)
-{
- cmStandardLevelResolver standardResolver(this->Makefile);
-
- std::string const& optionFlagDef =
- standardResolver.GetCompileOptionDef(target, lang, config);
- if (!optionFlagDef.empty()) {
- cmValue opt = target->Target->GetMakefile()->GetDefinition(optionFlagDef);
- if (opt) {
- std::vector<std::string> optVec = cmExpandedList(*opt);
- for (std::string const& i : optVec) {
- this->AppendFlagEscape(flags, i);
- }
- }
- }
-}
-
static void AddVisibilityCompileOption(std::string& flags,
cmGeneratorTarget const* target,
cmLocalGenerator* lg,
diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h
index 765441c..20f23de 100644
--- a/Source/cmLocalGenerator.h
+++ b/Source/cmLocalGenerator.h
@@ -164,10 +164,6 @@ public:
const std::string& lang);
void AddConfigVariableFlags(std::string& flags, const std::string& var,
const std::string& config);
- void AddCompilerRequirementFlag(std::string& flags,
- cmGeneratorTarget const* target,
- const std::string& lang,
- const std::string& config);
void AddColorDiagnosticsFlags(std::string& flags, const std::string& lang);
//! Append flags to a string.
virtual void AppendFlags(std::string& flags,
diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx
index fba0ff9..d39e155 100644
--- a/Source/cmNinjaTargetGenerator.cxx
+++ b/Source/cmNinjaTargetGenerator.cxx
@@ -109,12 +109,13 @@ cmGlobalNinjaGenerator* cmNinjaTargetGenerator::GetGlobalGenerator() const
}
std::string cmNinjaTargetGenerator::LanguageCompilerRule(
- const std::string& lang, const std::string& config) const
+ const std::string& lang, const std::string& config,
+ WithScanning withScanning) const
{
return cmStrCat(
lang, "_COMPILER__",
cmGlobalNinjaGenerator::EncodeRuleName(this->GeneratorTarget->GetName()),
- '_', config);
+ withScanning == WithScanning::Yes ? "_scanned_" : "_unscanned_", config);
}
std::string cmNinjaTargetGenerator::LanguagePreprocessAndScanRule(
@@ -173,6 +174,90 @@ bool cmNinjaTargetGenerator::NeedDyndep(std::string const& lang,
return lang == "Fortran" || this->NeedCxxModuleSupport(lang, config);
}
+void cmNinjaTargetGenerator::BuildFileSetInfoCache(std::string const& config)
+{
+ auto& per_config = this->Configs[config];
+
+ if (per_config.BuiltFileSetCache) {
+ return;
+ }
+
+ auto const* tgt = this->GeneratorTarget->Target;
+
+ for (auto const& name : tgt->GetAllFileSetNames()) {
+ auto const* file_set = tgt->GetFileSet(name);
+ if (!file_set) {
+ this->GetMakefile()->IssueMessage(
+ MessageType::INTERNAL_ERROR,
+ cmStrCat("Target \"", tgt->GetName(),
+ "\" is tracked to have file set \"", name,
+ "\", but it was not found."));
+ continue;
+ }
+
+ auto fileEntries = file_set->CompileFileEntries();
+ auto directoryEntries = file_set->CompileDirectoryEntries();
+ auto directories = file_set->EvaluateDirectoryEntries(
+ directoryEntries, this->LocalGenerator, config, this->GeneratorTarget);
+
+ std::map<std::string, std::vector<std::string>> files;
+ for (auto const& entry : fileEntries) {
+ file_set->EvaluateFileEntry(directories, files, entry,
+ this->LocalGenerator, config,
+ this->GeneratorTarget);
+ }
+
+ for (auto const& it : files) {
+ for (auto const& filename : it.second) {
+ per_config.FileSetCache[filename] = file_set;
+ }
+ }
+ }
+
+ per_config.BuiltFileSetCache = true;
+}
+
+cmFileSet const* cmNinjaTargetGenerator::GetFileSetForSource(
+ std::string const& config, cmSourceFile const* sf)
+{
+ this->BuildFileSetInfoCache(config);
+
+ auto const& path = sf->GetFullPath();
+ auto const& per_config = this->Configs[config];
+
+ auto const fsit = per_config.FileSetCache.find(path);
+ if (fsit == per_config.FileSetCache.end()) {
+ return nullptr;
+ }
+ return fsit->second;
+}
+
+bool cmNinjaTargetGenerator::NeedDyndepForSource(std::string const& lang,
+ std::string const& config,
+ cmSourceFile const* sf)
+{
+ bool const needDyndep = this->NeedDyndep(lang, config);
+ if (!needDyndep) {
+ return false;
+ }
+ auto const* fs = this->GetFileSetForSource(config, sf);
+ if (fs &&
+ (fs->GetType() == "CXX_MODULES"_s ||
+ fs->GetType() == "CXX_MODULE_HEADER_UNITS"_s)) {
+ return true;
+ }
+ auto const sfProp = sf->GetProperty("CXX_SCAN_FOR_MODULES");
+ if (sfProp.IsSet()) {
+ return sfProp.IsOn();
+ }
+ auto const tgtProp =
+ this->GeneratorTarget->GetProperty("CXX_SCAN_FOR_MODULES");
+ if (tgtProp.IsSet()) {
+ return tgtProp.IsOn();
+ }
+ return true;
+}
+
std::string cmNinjaTargetGenerator::OrderDependsTargetForTarget(
const std::string& config)
{
@@ -256,54 +341,17 @@ std::string cmNinjaTargetGenerator::ComputeFlagsForObject(
flags, genexInterpreter.Evaluate(pchOptions, COMPILE_OPTIONS));
}
- auto const& path = source->GetFullPath();
- auto const* tgt = this->GeneratorTarget->Target;
-
- std::string file_set_type;
-
- for (auto const& name : tgt->GetAllFileSetNames()) {
- auto const* file_set = tgt->GetFileSet(name);
- if (!file_set) {
+ auto const* fs = this->GetFileSetForSource(config, source);
+ if (fs &&
+ (fs->GetType() == "CXX_MODULES"_s ||
+ fs->GetType() == "CXX_MODULE_HEADER_UNITS"_s)) {
+ if (source->GetLanguage() != "CXX"_s) {
this->GetMakefile()->IssueMessage(
- MessageType::INTERNAL_ERROR,
- cmStrCat("Target \"", tgt->GetName(),
- "\" is tracked to have file set \"", name,
- "\", but it was not found."));
- continue;
- }
-
- auto fileEntries = file_set->CompileFileEntries();
- auto directoryEntries = file_set->CompileDirectoryEntries();
- auto directories = file_set->EvaluateDirectoryEntries(
- directoryEntries, this->LocalGenerator, config, this->GeneratorTarget);
-
- std::map<std::string, std::vector<std::string>> files;
- for (auto const& entry : fileEntries) {
- file_set->EvaluateFileEntry(directories, files, entry,
- this->LocalGenerator, config,
- this->GeneratorTarget);
- }
-
- for (auto const& it : files) {
- for (auto const& filename : it.second) {
- if (filename == path) {
- file_set_type = file_set->GetType();
- break;
- }
- }
- }
-
- if (file_set_type == "CXX_MODULES"_s ||
- file_set_type == "CXX_MODULE_HEADER_UNITS"_s) {
- if (source->GetLanguage() != "CXX"_s) {
- this->GetMakefile()->IssueMessage(
- MessageType::FATAL_ERROR,
- cmStrCat(
- "Target \"", tgt->GetName(), "\" contains the source\n ", path,
- "\nin a file set of type \"", file_set_type,
- R"(" but the source is not classified as a "CXX" source.)"));
- continue;
- }
+ MessageType::FATAL_ERROR,
+ cmStrCat("Target \"", this->GeneratorTarget->Target->GetName(),
+ "\" contains the source\n ", source->GetFullPath(),
+ "\nin a file set of type \"", fs->GetType(),
+ R"(" but the source is not classified as a "CXX" source.)"));
}
}
@@ -650,6 +698,19 @@ cmNinjaRule GetScanRule(
void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang,
const std::string& config)
{
+ // For some cases we scan to dynamically discover dependencies.
+ bool const needDyndep = this->NeedDyndep(lang, config);
+
+ if (needDyndep) {
+ this->WriteCompileRule(lang, config, WithScanning::Yes);
+ }
+ this->WriteCompileRule(lang, config, WithScanning::No);
+}
+
+void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang,
+ const std::string& config,
+ WithScanning withScanning)
+{
cmRulePlaceholderExpander::RuleVariables vars;
vars.CMTargetName = this->GetGeneratorTarget()->GetName().c_str();
vars.CMTargetType =
@@ -669,7 +730,6 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang,
cmMakefile* mf = this->GetMakefile();
// For some cases we scan to dynamically discover dependencies.
- bool const needDyndep = this->NeedDyndep(lang, config);
bool const compilationPreprocesses = !this->NeedExplicitPreprocessing(lang);
std::string flags = "$FLAGS";
@@ -707,7 +767,7 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang,
this->GetLocalGenerator()->ConvertToOutputFormat(
cmSystemTools::GetCMakeCommand(), cmLocalGenerator::SHELL);
- if (needDyndep) {
+ if (withScanning == WithScanning::Yes) {
const auto& scanDepType = this->GetMakefile()->GetSafeDefinition(
cmStrCat("CMAKE_EXPERIMENTAL_", lang, "_SCANDEP_DEPFILE_FORMAT"));
@@ -813,7 +873,7 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang,
this->GetGlobalGenerator()->AddRule(rule);
}
- cmNinjaRule rule(this->LanguageCompilerRule(lang, config));
+ cmNinjaRule rule(this->LanguageCompilerRule(lang, config, withScanning));
// If using a response file, move defines, includes, and flags into it.
if (!responseFlag.empty()) {
rule.RspFile = "$RSP_FILE";
@@ -867,7 +927,7 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang,
}
}
- if (needDyndep && !modmapFormat.empty()) {
+ if (withScanning == WithScanning::Yes && !modmapFormat.empty()) {
std::string modmapFlags = mf->GetRequiredDefinition(
cmStrCat("CMAKE_EXPERIMENTAL_", lang, "_MODULE_MAP_FLAG"));
cmSystemTools::ReplaceString(modmapFlags, "<MODULE_MAP_FILE>",
@@ -1327,8 +1387,10 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
!(language == "RC" || (language == "CUDA" && !flag));
int const commandLineLengthLimit =
((lang_supports_response && this->ForceResponseFile())) ? -1 : 0;
+ bool const needDyndep = this->NeedDyndepForSource(language, config, source);
- cmNinjaBuild objBuild(this->LanguageCompilerRule(language, config));
+ cmNinjaBuild objBuild(this->LanguageCompilerRule(
+ language, config, needDyndep ? WithScanning::Yes : WithScanning::No));
cmNinjaVars& vars = objBuild.Variables;
vars["FLAGS"] = this->ComputeFlagsForObject(source, language, config);
vars["DEFINES"] = this->ComputeDefines(source, language, config);
@@ -1437,7 +1499,6 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
}
// For some cases we scan to dynamically discover dependencies.
- bool const needDyndep = this->NeedDyndep(language, config);
bool const compilationPreprocesses =
!this->NeedExplicitPreprocessing(language);
diff --git a/Source/cmNinjaTargetGenerator.h b/Source/cmNinjaTargetGenerator.h
index c43b650..d09f04b 100644
--- a/Source/cmNinjaTargetGenerator.h
+++ b/Source/cmNinjaTargetGenerator.h
@@ -19,6 +19,7 @@
#include "cmOSXBundleGenerator.h"
class cmCustomCommand;
+class cmFileSet;
class cmGeneratedFileStream;
class cmGeneratorTarget;
class cmLocalNinjaGenerator;
@@ -63,8 +64,18 @@ protected:
cmMakefile* GetMakefile() const { return this->Makefile; }
+ void BuildFileSetInfoCache(std::string const& config);
+ cmFileSet const* GetFileSetForSource(std::string const& config,
+ cmSourceFile const* sf);
+
+ enum class WithScanning
+ {
+ No,
+ Yes,
+ };
std::string LanguageCompilerRule(const std::string& lang,
- const std::string& config) const;
+ const std::string& config,
+ WithScanning withScanning) const;
std::string LanguagePreprocessAndScanRule(std::string const& lang,
const std::string& config) const;
std::string LanguageScanRule(std::string const& lang,
@@ -72,6 +83,8 @@ protected:
std::string LanguageDyndepRule(std::string const& lang,
const std::string& config) const;
bool NeedDyndep(std::string const& lang, std::string const& config) const;
+ bool NeedDyndepForSource(std::string const& lang, std::string const& config,
+ cmSourceFile const* sf);
bool NeedExplicitPreprocessing(std::string const& lang) const;
bool CompileWithDefines(std::string const& lang) const;
bool NeedCxxModuleSupport(std::string const& lang,
@@ -150,6 +163,8 @@ protected:
const std::string& config);
void WriteCompileRule(const std::string& language,
const std::string& config);
+ void WriteCompileRule(const std::string& language, const std::string& config,
+ WithScanning withScanning);
void WriteObjectBuildStatements(const std::string& config,
const std::string& fileConfig,
bool firstForConfig);
@@ -223,6 +238,8 @@ private:
std::vector<cmCustomCommand const*> CustomCommands;
cmNinjaDeps ExtraFiles;
std::unique_ptr<MacOSXContentGeneratorType> MacOSXContentGenerator;
+ bool BuiltFileSetCache = false;
+ std::map<std::string, cmFileSet const*> FileSetCache;
};
std::map<std::string, ByConfig> Configs;
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 2955d7c..70a624d 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -526,6 +526,7 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
initProp("ANDROID_ANT_ADDITIONAL_OPTIONS");
initProp("BUILD_RPATH");
initProp("BUILD_RPATH_USE_ORIGIN");
+ initProp("CXX_SCAN_FOR_MODULES");
initProp("INSTALL_NAME_DIR");
initProp("INSTALL_REMOVE_ENVIRONMENT_RPATH");
initPropValue("INSTALL_RPATH", "");
diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index 7e43bee..cd73551 100644
--- a/Source/cmVisualStudio10TargetGenerator.cxx
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -3293,6 +3293,8 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions(
this->GeneratorTarget->GetLanguages(languages, configName);
if (languages.count("C")) {
std::string flagsC;
+ this->LocalGenerator->AddLanguageFlags(
+ flagsC, this->GeneratorTarget, cmBuildStep::Compile, "C", configName);
this->LocalGenerator->AddCompileOptions(flagsC, this->GeneratorTarget,
"C", configName);
Options optC(this->LocalGenerator, Options::Compiler,
diff --git a/Tests/CMakeTests/CMakeLists.txt b/Tests/CMakeTests/CMakeLists.txt
index bd2dd7e..16e631b 100644
--- a/Tests/CMakeTests/CMakeLists.txt
+++ b/Tests/CMakeTests/CMakeLists.txt
@@ -32,16 +32,6 @@ AddCMakeTest(ProcessorCount "-DKWSYS_TEST_EXE=$<TARGET_FILE:cmsysTestsCxx>")
AddCMakeTest(PushCheckState "")
AddCMakeTest(While "")
-AddCMakeTest(FileDownload "")
-set_tests_properties(CMake.FileDownload PROPERTIES
- PASS_REGULAR_EXPRESSION "file already exists with expected MD5 sum"
- FAIL_REGULAR_EXPRESSION "Unexpected status|incorrectly interpreted"
- )
-AddCMakeTest(FileDownloadBadHash "")
-set_property(TEST CMake.FileDownloadBadHash PROPERTY
- WILL_FAIL TRUE
- )
-
AddCMakeTest(FileUpload "")
set(EndStuff_PreArgs
diff --git a/Tests/CMakeTests/FileDownloadBadHashTest.cmake.in b/Tests/CMakeTests/FileDownloadBadHashTest.cmake.in
deleted file mode 100644
index 64b45ed..0000000
--- a/Tests/CMakeTests/FileDownloadBadHashTest.cmake.in
+++ /dev/null
@@ -1,13 +0,0 @@
-if(NOT "@CMAKE_CURRENT_SOURCE_DIR@" MATCHES "^/")
- set(slash /)
-endif()
-set(url "file://${slash}@CMAKE_CURRENT_SOURCE_DIR@/FileDownloadInput.png")
-set(dir "@CMAKE_CURRENT_BINARY_DIR@/downloads")
-
-file(DOWNLOAD
- ${url}
- ${dir}/file3.png
- TIMEOUT 2
- STATUS status
- EXPECTED_HASH SHA1=5555555555555555555555555555555555555555
- )
diff --git a/Tests/CMakeTests/FileDownloadTest.cmake.in b/Tests/CMakeTests/FileDownloadTest.cmake.in
deleted file mode 100644
index 255909d..0000000
--- a/Tests/CMakeTests/FileDownloadTest.cmake.in
+++ /dev/null
@@ -1,229 +0,0 @@
-# We do not contact any real URLs, but do try a bogus one.
-# Remove any proxy configuration that may change behavior.
-unset(ENV{http_proxy})
-unset(ENV{https_proxy})
-
-set(timeout 4)
-
-if(NOT "@CMAKE_CURRENT_SOURCE_DIR@" MATCHES "^/")
- set(slash /)
-endif()
-set(url "file://${slash}@CMAKE_CURRENT_SOURCE_DIR@/FileDownloadInput.png")
-set(dir "@CMAKE_CURRENT_BINARY_DIR@/downloads")
-
-# Beware Windows asynchronous file/directory removal, rename and then
-# remove the renamed dir so we can be certain the dir isn't there when
-# we get to the file() commands below
-if(EXISTS "${dir}")
- file(RENAME ${dir} "${dir}_beingRemoved")
- file(REMOVE_RECURSE "${dir}_beingRemoved")
-endif()
-
-function(__reportIfWrongStatus statusPair expectedStatusCode)
- list(GET statusPair 0 statusCode)
- if(NOT statusCode EQUAL expectedStatusCode)
- message(SEND_ERROR
- "Unexpected status: ${statusCode}, expected: ${expectedStatusCode}")
- endif()
-endfunction()
-
-message(STATUS "FileDownload:1")
-file(DOWNLOAD
- ${url}
- ${dir}/file1.png
- TIMEOUT ${timeout}
- STATUS status
- )
-__reportIfWrongStatus("${status}" 0)
-
-message(STATUS "FileDownload:2")
-file(DOWNLOAD
- ${url}
- ${dir}/file2.png
- TIMEOUT ${timeout}
- STATUS status
- SHOW_PROGRESS
- )
-__reportIfWrongStatus("${status}" 0)
-
-# Two calls in a row, exactly the same arguments.
-# Since downloaded file should exist already for 2nd call,
-# the 2nd call will short-circuit and return early...
-#
-if(EXISTS ${dir}/file3.png)
- file(REMOVE ${dir}/file3.png)
-endif()
-
-message(STATUS "FileDownload:3")
-file(DOWNLOAD
- ${url}
- ${dir}/file3.png
- TIMEOUT ${timeout}
- STATUS status
- EXPECTED_MD5 dbd330d52f4dbd60115d4191904ded92
- )
-__reportIfWrongStatus("${status}" 0)
-
-message(STATUS "FileDownload:4")
-file(DOWNLOAD
- ${url}
- ${dir}/file3.png
- TIMEOUT ${timeout}
- STATUS status
- EXPECTED_HASH SHA1=67eee17f79d9ac557284fc0b8ad19f25723fb578
- )
-__reportIfWrongStatus("${status}" 0)
-
-message(STATUS "FileDownload:5")
-file(DOWNLOAD
- ${url}
- ${dir}/file3.png
- TIMEOUT ${timeout}
- STATUS status
- EXPECTED_HASH SHA224=ba283726bbb602776818b463943189afd91836cb7ee5dd6e2c7b5ae4
- )
-__reportIfWrongStatus("${status}" 0)
-
-message(STATUS "FileDownload:6")
-file(DOWNLOAD
- ${url}
- ${dir}/file3.png
- TIMEOUT ${timeout}
- STATUS status
- EXPECTED_HASH SHA256=cf3334b1275071e1da6e8c396ccb72cf1b2388d8c937526f3af26230affb9423
- )
-__reportIfWrongStatus("${status}" 0)
-
-message(STATUS "FileDownload:7")
-file(DOWNLOAD
- ${url}
- ${dir}/file3.png
- TIMEOUT ${timeout}
- STATUS status
- EXPECTED_HASH SHA384=43a5d13978d97c660db44481aee0604cb4ff6ca0775cd5c2cd68cd8000e107e507c4caf6c228941231041e282ffb8950
- )
-__reportIfWrongStatus("${status}" 0)
-
-message(STATUS "FileDownload:8")
-file(DOWNLOAD
- ${url}
- ${dir}/file3.png
- TIMEOUT ${timeout}
- STATUS status
- EXPECTED_HASH SHA512=6984e0909a1018030ccaa418e3be1654223cdccff0fe6adc745f9aea7e377f178be53b9fc7d54a6f81c2b62ef9ddcd38ba1978fedf4c5e7139baaf355eefad5b
- )
-__reportIfWrongStatus("${status}" 0)
-
-message(STATUS "FileDownload:9")
-file(DOWNLOAD
- ${url}
- ${dir}/file3.png
- TIMEOUT ${timeout}
- STATUS status
- EXPECTED_HASH MD5=dbd330d52f4dbd60115d4191904ded92
- )
-__reportIfWrongStatus("${status}" 0)
-
-message(STATUS "FileDownload:10")
-file(DOWNLOAD
- ${url}
- ${dir}/file3.png
- TIMEOUT ${timeout}
- STATUS status
- EXPECTED_MD5 dbd330d52f4dbd60115d4191904ded92
- )
-__reportIfWrongStatus("${status}" 0)
-# Print status because we check its message too
-message(STATUS "${status}")
-
-# do not use proxy for lookup of invalid site (DNS failure by proxy looks
-# different than DNS failure without proxy)
-set(ENV{no_proxy} "$ENV{no_proxy},badhostname.invalid")
-message(STATUS "FileDownload:11")
-file(DOWNLOAD
- badhostname.invalid
- ${dir}/file11.png
- TIMEOUT 30
- STATUS status
- )
-message(STATUS "${status}")
-__reportIfWrongStatus("${status}" 6) # 6 corresponds to an unresolvable host name
-
-message(STATUS "FileDownload:12")
-set(absFile "@CMAKE_CURRENT_BINARY_DIR@/file12.png")
-if(EXISTS "${absFile}")
- file(RENAME ${absFile} "${absFile}_beingRemoved")
- file(REMOVE "${absFile}_beingRemoved")
-endif()
-file(DOWNLOAD
- ${url}
- file12.png
- TIMEOUT ${timeout}
- EXPECTED_MD5 dbd330d52f4dbd60115d4191904ded92
- STATUS status
- )
-__reportIfWrongStatus("${status}" 0)
-if(NOT EXISTS file12.png)
- message(SEND_ERROR "file12.png not downloaded: ${status}")
-endif()
-
-message(STATUS "FileDownload:13")
-file(DOWNLOAD
- ${url}
- TIMEOUT ${timeout}
- STATUS status
- )
-__reportIfWrongStatus("${status}" 0)
-if(EXISTS TIMEOUT)
- file(REMOVE TIMEOUT)
- message(SEND_ERROR "TIMEOUT argument was incorrectly interpreted as a filename")
-endif()
-message(STATUS "${status}")
-
-message(STATUS "FileDownload:14")
-file(DOWNLOAD
- ${url}
- ${dir}/file14.bin
- TIMEOUT ${timeout}
- STATUS status
- RANGE_START 0
- EXPECTED_MD5 dbd330d52f4dbd60115d4191904ded92
- )
-__reportIfWrongStatus("${status}" 0)
-
-message(STATUS "FileDownload:15")
-file(DOWNLOAD
- ${url}
- ${dir}/file15.bin
- TIMEOUT ${timeout}
- STATUS status
- RANGE_END 50
- EXPECTED_MD5 8592e5665b839b5d23825dc84c135b61
- )
-__reportIfWrongStatus("${status}" 0)
-
-message(STATUS "FileDownload:16")
-file(DOWNLOAD
- ${url}
- ${dir}/file16.bin
- TIMEOUT ${timeout}
- STATUS status
- RANGE_START 10
- RANGE_END 50
- EXPECTED_MD5 36cd52681e6c6c8fef85fcd9e86fc30d
- )
-__reportIfWrongStatus("${status}" 0)
-
-message(STATUS "FileDownload:17")
-file(DOWNLOAD
- ${url}
- ${dir}/file17.bin
- TIMEOUT ${timeout}
- STATUS status
- RANGE_START 0
- RANGE_END 50
- RANGE_START 60
- RANGE_END 100
- EXPECTED_MD5 c5c9e74e82d493dd901eecccd659cebc
- )
-__reportIfWrongStatus("${status}" 0)
diff --git a/Tests/CMakeTests/FileDownloadInput.png b/Tests/CMakeTests/FileUploadInput.png
index 9ab565a..9ab565a 100644
--- a/Tests/CMakeTests/FileDownloadInput.png
+++ b/Tests/CMakeTests/FileUploadInput.png
Binary files differ
diff --git a/Tests/CMakeTests/FileUploadTest.cmake.in b/Tests/CMakeTests/FileUploadTest.cmake.in
index 0e6f080..7725041 100644
--- a/Tests/CMakeTests/FileUploadTest.cmake.in
+++ b/Tests/CMakeTests/FileUploadTest.cmake.in
@@ -9,7 +9,7 @@ endif()
file(MAKE_DIRECTORY "@CMAKE_CURRENT_BINARY_DIR@/uploads")
-set(filename "@CMAKE_CURRENT_SOURCE_DIR@/FileDownloadInput.png")
+set(filename "@CMAKE_CURRENT_SOURCE_DIR@/FileUploadInput.png")
if(NOT "@CMAKE_CURRENT_BINARY_DIR@" MATCHES "^/")
set(slash /)
endif()
diff --git a/Tests/CompileFeatures/CMakeLists.txt b/Tests/CompileFeatures/CMakeLists.txt
index f3d3a73..17f4408 100644
--- a/Tests/CompileFeatures/CMakeLists.txt
+++ b/Tests/CompileFeatures/CMakeLists.txt
@@ -374,3 +374,16 @@ else()
target_link_libraries(CompileFeaturesGenex3 PRIVATE std_11_iface)
target_compile_definitions(CompileFeaturesGenex3 PRIVATE ${genex_test_defs} ALLOW_LATER_STANDARDS=1)
endif()
+
+if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC"
+ AND (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 19.30
+ # The MSVC 14.29.30133 toolset supports C++20,
+ # but MSBuild puts the flags in the wrong order.
+ OR (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 19.29.30129 AND NOT CMAKE_GENERATOR MATCHES "Visual Studio")
+ )
+ )
+ add_library(msvc_permissive msvc_permissive.cxx)
+ target_compile_features(msvc_permissive PRIVATE cxx_std_20)
+ # The `-std:c++20` flag implies `-permissive-`. Test passing `-permissive` afterward.
+ target_compile_options(msvc_permissive PRIVATE -permissive)
+endif()
diff --git a/Tests/CompileFeatures/msvc_permissive.cxx b/Tests/CompileFeatures/msvc_permissive.cxx
new file mode 100644
index 0000000..a8f2ff3
--- /dev/null
+++ b/Tests/CompileFeatures/msvc_permissive.cxx
@@ -0,0 +1,9 @@
+#if !defined(_MSVC_LANG) || _MSVC_LANG < 202002L
+# error "This source must be compiled with MSVC as C++20 or later."
+#endif
+// Test a construct that is allowed by MSVC only with 'cl -permissive'.
+enum class X
+{
+ Y = 1
+};
+int array[X::Y];
diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt
index 1174d0d..0fe4919 100644
--- a/Tests/RunCMake/CMakeLists.txt
+++ b/Tests/RunCMake/CMakeLists.txt
@@ -466,6 +466,7 @@ add_RunCMake_test(ctest_fixtures)
add_RunCMake_test(define_property)
add_RunCMake_test(file -DCYGWIN=${CYGWIN} -DMSYS=${MSYS})
add_RunCMake_test(file-CHMOD -DMSYS=${MSYS})
+add_RunCMake_test(file-DOWNLOAD -DCMake_TEST_NO_NETWORK=${CMake_TEST_NO_NETWORK})
add_RunCMake_test(file-RPATH -DCMAKE_SYSTEM_NAME=${CMAKE_SYSTEM_NAME})
add_RunCMake_test(find_file)
add_RunCMake_test(find_library -DCYGWIN=${CYGWIN} -DMSYS=${MSYS})
diff --git a/Tests/RunCMake/CXXModules/RunCMakeTest.cmake b/Tests/RunCMake/CXXModules/RunCMakeTest.cmake
index 921fabd..81a086a 100644
--- a/Tests/RunCMake/CXXModules/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CXXModules/RunCMakeTest.cmake
@@ -138,6 +138,7 @@ if ("named" IN_LIST CMake_TEST_MODULE_COMPILATION)
set(RunCMake_CXXModules_NO_TEST 1)
run_cxx_module_test(circular)
unset(RunCMake_CXXModules_NO_TEST)
+ run_cxx_module_test(scan_properties)
endif ()
# Tests which use named modules in shared libraries.
diff --git a/Tests/RunCMake/CXXModules/examples/scan_properties-stderr.txt b/Tests/RunCMake/CXXModules/examples/scan_properties-stderr.txt
new file mode 100644
index 0000000..7d79bad
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/scan_properties-stderr.txt
@@ -0,0 +1,9 @@
+CMake Warning \(dev\) at CMakeLists.txt:20 \(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/scan_properties/CMakeLists.txt b/Tests/RunCMake/CXXModules/examples/scan_properties/CMakeLists.txt
new file mode 100644
index 0000000..551c55c
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/scan_properties/CMakeLists.txt
@@ -0,0 +1,54 @@
+cmake_minimum_required(VERSION 3.24)
+project(scan_properties CXX)
+
+include("${CMAKE_SOURCE_DIR}/../cxx-modules-rules.cmake")
+
+# To detect that not-to-be scanned sources are not scanned, add a `-D` to the
+# scan flags so that the files can detect whether scanning happened and error
+# if not.
+string(APPEND CMAKE_EXPERIMENTAL_CXX_MODULE_MAP_FLAG
+ " -DCMAKE_SCANNED_THIS_SOURCE")
+string(APPEND CMAKE_EXPERIMENTAL_CXX_SCANDEP_SOURCE
+ " -DCMAKE_SCANNED_THIS_SOURCE")
+
+set_property(SOURCE always_scan.cxx
+ PROPERTY CXX_SCAN_FOR_MODULES 1)
+set_property(SOURCE never_scan.cxx
+ PROPERTY CXX_SCAN_FOR_MODULES 0)
+
+add_executable(scans_everything)
+target_sources(scans_everything
+ PRIVATE
+ main.cxx
+ join.cxx
+ always_scan.cxx
+ never_scan.cxx
+ PRIVATE
+ FILE_SET CXX_MODULES
+ BASE_DIRS
+ "${CMAKE_CURRENT_SOURCE_DIR}"
+ FILES
+ module.cxx)
+target_compile_features(scans_everything PRIVATE cxx_std_20)
+target_compile_definitions(scans_everything PRIVATE SCAN_AT_TARGET_LEVEL=1)
+
+set(CMAKE_CXX_SCAN_FOR_MODULES 0)
+
+add_executable(no_scan_everything)
+target_sources(no_scan_everything
+ PRIVATE
+ main.cxx
+ join.cxx
+ always_scan.cxx
+ never_scan.cxx
+ PRIVATE
+ FILE_SET CXX_MODULES
+ BASE_DIRS
+ "${CMAKE_CURRENT_SOURCE_DIR}"
+ FILES
+ module.cxx)
+target_compile_features(no_scan_everything PRIVATE cxx_std_20)
+target_compile_definitions(no_scan_everything PRIVATE SCAN_AT_TARGET_LEVEL=0)
+
+add_test(NAME scanned COMMAND scans_everything)
+add_test(NAME unscanned COMMAND no_scan_everything)
diff --git a/Tests/RunCMake/CXXModules/examples/scan_properties/always_scan.cxx b/Tests/RunCMake/CXXModules/examples/scan_properties/always_scan.cxx
new file mode 100644
index 0000000..27087d7
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/scan_properties/always_scan.cxx
@@ -0,0 +1,10 @@
+#ifndef CMAKE_SCANNED_THIS_SOURCE
+# error "This file should have been scanned"
+#endif
+
+import M;
+
+int scanned_file()
+{
+ return from_module();
+}
diff --git a/Tests/RunCMake/CXXModules/examples/scan_properties/join.cxx b/Tests/RunCMake/CXXModules/examples/scan_properties/join.cxx
new file mode 100644
index 0000000..8184a40
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/scan_properties/join.cxx
@@ -0,0 +1,17 @@
+#if SCAN_AT_TARGET_LEVEL
+# ifndef CMAKE_SCANNED_THIS_SOURCE
+# error "This file should have been scanned"
+# endif
+#else
+# ifdef CMAKE_SCANNED_THIS_SOURCE
+# error "This file should not have been scanned"
+# endif
+#endif
+
+int scanned_file();
+int never_scan();
+
+int join()
+{
+ return scanned_file() + never_scan();
+}
diff --git a/Tests/RunCMake/CXXModules/examples/scan_properties/main.cxx b/Tests/RunCMake/CXXModules/examples/scan_properties/main.cxx
new file mode 100644
index 0000000..81e93f4
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/scan_properties/main.cxx
@@ -0,0 +1,16 @@
+#if SCAN_AT_TARGET_LEVEL
+# ifndef CMAKE_SCANNED_THIS_SOURCE
+# error "This file should have been scanned"
+# endif
+#else
+# ifdef CMAKE_SCANNED_THIS_SOURCE
+# error "This file should not have been scanned"
+# endif
+#endif
+
+int join();
+
+int main(int argc, char** argv)
+{
+ return join();
+}
diff --git a/Tests/RunCMake/CXXModules/examples/scan_properties/module.cxx b/Tests/RunCMake/CXXModules/examples/scan_properties/module.cxx
new file mode 100644
index 0000000..ad1e04d
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/scan_properties/module.cxx
@@ -0,0 +1,10 @@
+#ifndef CMAKE_SCANNED_THIS_SOURCE
+# error "This file should have been scanned"
+#endif
+
+export module M;
+
+export int from_module()
+{
+ return 0;
+}
diff --git a/Tests/RunCMake/CXXModules/examples/scan_properties/never_scan.cxx b/Tests/RunCMake/CXXModules/examples/scan_properties/never_scan.cxx
new file mode 100644
index 0000000..8374110
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/scan_properties/never_scan.cxx
@@ -0,0 +1,8 @@
+#ifdef CMAKE_SCANNED_THIS_SOURCE
+# error "This file should not have been scanned"
+#endif
+
+int never_scan()
+{
+ return 0;
+}
diff --git a/Tests/RunCMake/file-DOWNLOAD/CMakeLists.txt b/Tests/RunCMake/file-DOWNLOAD/CMakeLists.txt
new file mode 100644
index 0000000..9a66cde
--- /dev/null
+++ b/Tests/RunCMake/file-DOWNLOAD/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.13)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/file-DOWNLOAD/EXPECTED_HASH-stdout.txt b/Tests/RunCMake/file-DOWNLOAD/EXPECTED_HASH-stdout.txt
new file mode 100644
index 0000000..bd1727a
--- /dev/null
+++ b/Tests/RunCMake/file-DOWNLOAD/EXPECTED_HASH-stdout.txt
@@ -0,0 +1,8 @@
+-- status='0;"No error"'
+-- status='0;"skipping download as file already exists with expected MD5 sum"'
+-- status='0;"skipping download as file already exists with expected MD5 hash"'
+-- status='0;"skipping download as file already exists with expected SHA1 hash"'
+-- status='0;"skipping download as file already exists with expected SHA224 hash"'
+-- status='0;"skipping download as file already exists with expected SHA256 hash"'
+-- status='0;"skipping download as file already exists with expected SHA384 hash"'
+-- status='0;"skipping download as file already exists with expected SHA512 hash"'
diff --git a/Tests/RunCMake/file-DOWNLOAD/EXPECTED_HASH.cmake b/Tests/RunCMake/file-DOWNLOAD/EXPECTED_HASH.cmake
new file mode 100644
index 0000000..dc7f8ff
--- /dev/null
+++ b/Tests/RunCMake/file-DOWNLOAD/EXPECTED_HASH.cmake
@@ -0,0 +1,13 @@
+include(common.cmake)
+
+# Actually download the file and verify its hash.
+file_download(EXPECTED_MD5 dbd330d52f4dbd60115d4191904ded92)
+
+# Verify that the local file already exists with expected hash.
+file_download(EXPECTED_MD5 dbd330d52f4dbd60115d4191904ded92)
+file_download(EXPECTED_HASH MD5=dbd330d52f4dbd60115d4191904ded92)
+file_download(EXPECTED_HASH SHA1=67eee17f79d9ac557284fc0b8ad19f25723fb578)
+file_download(EXPECTED_HASH SHA224=ba283726bbb602776818b463943189afd91836cb7ee5dd6e2c7b5ae4)
+file_download(EXPECTED_HASH SHA256=cf3334b1275071e1da6e8c396ccb72cf1b2388d8c937526f3af26230affb9423)
+file_download(EXPECTED_HASH SHA384=43a5d13978d97c660db44481aee0604cb4ff6ca0775cd5c2cd68cd8000e107e507c4caf6c228941231041e282ffb8950)
+file_download(EXPECTED_HASH SHA512=6984e0909a1018030ccaa418e3be1654223cdccff0fe6adc745f9aea7e377f178be53b9fc7d54a6f81c2b62ef9ddcd38ba1978fedf4c5e7139baaf355eefad5b)
diff --git a/Tests/RunCMake/file-DOWNLOAD/RunCMakeTest.cmake b/Tests/RunCMake/file-DOWNLOAD/RunCMakeTest.cmake
new file mode 100644
index 0000000..565f440
--- /dev/null
+++ b/Tests/RunCMake/file-DOWNLOAD/RunCMakeTest.cmake
@@ -0,0 +1,26 @@
+include(RunCMake)
+
+# We do not contact any real URLs, but do try a bogus one.
+# Remove any proxy configuration that may change behavior.
+unset(ENV{http_proxy})
+unset(ENV{https_proxy})
+
+run_cmake(hash-mismatch)
+run_cmake(unused-argument)
+run_cmake(httpheader-not-set)
+run_cmake(netrc-bad)
+run_cmake(tls-cainfo-not-set)
+run_cmake(tls-verify-not-set)
+run_cmake(pass-not-set)
+run_cmake(no-save-hash)
+
+run_cmake(basic)
+run_cmake(EXPECTED_HASH)
+run_cmake(file-without-path)
+run_cmake(no-file)
+run_cmake(range)
+run_cmake(SHOW_PROGRESS)
+
+if(NOT CMake_TEST_NO_NETWORK)
+ run_cmake(bad-hostname)
+endif()
diff --git a/Tests/RunCMake/file-DOWNLOAD/SHOW_PROGRESS-stdout.txt b/Tests/RunCMake/file-DOWNLOAD/SHOW_PROGRESS-stdout.txt
new file mode 100644
index 0000000..e0a4982
--- /dev/null
+++ b/Tests/RunCMake/file-DOWNLOAD/SHOW_PROGRESS-stdout.txt
@@ -0,0 +1,2 @@
+-- \[download 100% complete\]
+-- status='0;"No error"'
diff --git a/Tests/RunCMake/file-DOWNLOAD/SHOW_PROGRESS.cmake b/Tests/RunCMake/file-DOWNLOAD/SHOW_PROGRESS.cmake
new file mode 100644
index 0000000..ccabced
--- /dev/null
+++ b/Tests/RunCMake/file-DOWNLOAD/SHOW_PROGRESS.cmake
@@ -0,0 +1,3 @@
+include(common.cmake)
+
+file_download(SHOW_PROGRESS)
diff --git a/Tests/RunCMake/file-DOWNLOAD/bad-hostname-stdout.txt b/Tests/RunCMake/file-DOWNLOAD/bad-hostname-stdout.txt
new file mode 100644
index 0000000..12278e0
--- /dev/null
+++ b/Tests/RunCMake/file-DOWNLOAD/bad-hostname-stdout.txt
@@ -0,0 +1 @@
+-- status='6;"Couldn't resolve host name"'
diff --git a/Tests/RunCMake/file-DOWNLOAD/bad-hostname.cmake b/Tests/RunCMake/file-DOWNLOAD/bad-hostname.cmake
new file mode 100644
index 0000000..d3b7a28
--- /dev/null
+++ b/Tests/RunCMake/file-DOWNLOAD/bad-hostname.cmake
@@ -0,0 +1,9 @@
+include(common.cmake)
+
+# Do not use any proxy for lookup of an invalid site.
+# DNS failure by proxy looks different than DNS failure without proxy.
+set(ENV{no_proxy} "$ENV{no_proxy},badhostname.invalid")
+
+set(url "badhostname.invalid")
+
+file_download()
diff --git a/Tests/RunCMake/file-DOWNLOAD/basic-stdout.txt b/Tests/RunCMake/file-DOWNLOAD/basic-stdout.txt
new file mode 100644
index 0000000..701e995
--- /dev/null
+++ b/Tests/RunCMake/file-DOWNLOAD/basic-stdout.txt
@@ -0,0 +1 @@
+-- status='0;"No error"'
diff --git a/Tests/RunCMake/file-DOWNLOAD/basic.cmake b/Tests/RunCMake/file-DOWNLOAD/basic.cmake
new file mode 100644
index 0000000..1fd931c
--- /dev/null
+++ b/Tests/RunCMake/file-DOWNLOAD/basic.cmake
@@ -0,0 +1,3 @@
+include(common.cmake)
+
+file_download()
diff --git a/Tests/RunCMake/file-DOWNLOAD/common.cmake b/Tests/RunCMake/file-DOWNLOAD/common.cmake
new file mode 100644
index 0000000..6aa2fe6
--- /dev/null
+++ b/Tests/RunCMake/file-DOWNLOAD/common.cmake
@@ -0,0 +1,15 @@
+if(NOT "${CMAKE_CURRENT_SOURCE_DIR}" MATCHES "^/")
+ set(slash /)
+endif()
+set(url "file://${slash}${CMAKE_CURRENT_SOURCE_DIR}/input.png")
+set(file ${CMAKE_CURRENT_BINARY_DIR}/output.png)
+
+function(file_download)
+ file(DOWNLOAD "${url}"
+ ${file} # leave unquoted
+ TIMEOUT 30
+ STATUS status
+ ${ARGN}
+ )
+ message(STATUS "status='${status}'")
+endfunction()
diff --git a/Tests/RunCMake/file-DOWNLOAD/file-without-path-stdout.txt b/Tests/RunCMake/file-DOWNLOAD/file-without-path-stdout.txt
new file mode 100644
index 0000000..701e995
--- /dev/null
+++ b/Tests/RunCMake/file-DOWNLOAD/file-without-path-stdout.txt
@@ -0,0 +1 @@
+-- status='0;"No error"'
diff --git a/Tests/RunCMake/file-DOWNLOAD/file-without-path.cmake b/Tests/RunCMake/file-DOWNLOAD/file-without-path.cmake
new file mode 100644
index 0000000..a628423
--- /dev/null
+++ b/Tests/RunCMake/file-DOWNLOAD/file-without-path.cmake
@@ -0,0 +1,10 @@
+include(common.cmake)
+
+set(file_orig "${file}")
+cmake_path(GET file_orig FILENAME file)
+
+file_download()
+
+if(NOT EXISTS "${file_orig}")
+ message(FATAL_ERROR "file not downloaded to expected path:\n ${file_orig}")
+endif()
diff --git a/Tests/RunCMake/file/DOWNLOAD-tls-verify-not-set-result.txt b/Tests/RunCMake/file-DOWNLOAD/hash-mismatch-result.txt
index d00491f..d00491f 100644
--- a/Tests/RunCMake/file/DOWNLOAD-tls-verify-not-set-result.txt
+++ b/Tests/RunCMake/file-DOWNLOAD/hash-mismatch-result.txt
diff --git a/Tests/RunCMake/file-DOWNLOAD/hash-mismatch-stderr.txt b/Tests/RunCMake/file-DOWNLOAD/hash-mismatch-stderr.txt
new file mode 100644
index 0000000..6682794
--- /dev/null
+++ b/Tests/RunCMake/file-DOWNLOAD/hash-mismatch-stderr.txt
@@ -0,0 +1,11 @@
+^CMake Error at hash-mismatch.cmake:[0-9]+ \(file\):
+ file DOWNLOAD HASH mismatch
+
+ for file: \[.*/Tests/RunCMake/file-DOWNLOAD/hash-mismatch-build/output.png\]
+ expected hash: \[0123456789abcdef0123456789abcdef01234567\]
+ actual hash: \[67eee17f79d9ac557284fc0b8ad19f25723fb578\]
+
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
++
+status='1;HASH mismatch: expected: 0123456789abcdef0123456789abcdef01234567 actual: 67eee17f79d9ac557284fc0b8ad19f25723fb578'$
diff --git a/Tests/RunCMake/file-DOWNLOAD/hash-mismatch.cmake b/Tests/RunCMake/file-DOWNLOAD/hash-mismatch.cmake
new file mode 100644
index 0000000..e3f91e3
--- /dev/null
+++ b/Tests/RunCMake/file-DOWNLOAD/hash-mismatch.cmake
@@ -0,0 +1,8 @@
+include(common.cmake)
+
+file(DOWNLOAD ${url} ${file}
+ EXPECTED_HASH SHA1=0123456789abcdef0123456789abcdef01234567
+ TIMEOUT 30
+ STATUS status
+ )
+message("status='${status}'")
diff --git a/Tests/RunCMake/file/DOWNLOAD-tls-cainfo-not-set-result.txt b/Tests/RunCMake/file-DOWNLOAD/httpheader-not-set-result.txt
index d00491f..d00491f 100644
--- a/Tests/RunCMake/file/DOWNLOAD-tls-cainfo-not-set-result.txt
+++ b/Tests/RunCMake/file-DOWNLOAD/httpheader-not-set-result.txt
diff --git a/Tests/RunCMake/file/DOWNLOAD-httpheader-not-set-stderr.txt b/Tests/RunCMake/file-DOWNLOAD/httpheader-not-set-stderr.txt
index 247923b..3ac5082 100644
--- a/Tests/RunCMake/file/DOWNLOAD-httpheader-not-set-stderr.txt
+++ b/Tests/RunCMake/file-DOWNLOAD/httpheader-not-set-stderr.txt
@@ -1,4 +1,4 @@
-^CMake Error at DOWNLOAD-httpheader-not-set.cmake:[0-9]+ \(file\):
+^CMake Error at httpheader-not-set.cmake:[0-9]+ \(file\):
file DOWNLOAD missing string for HTTPHEADER.
Call Stack \(most recent call first\):
CMakeLists.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/file/DOWNLOAD-httpheader-not-set.cmake b/Tests/RunCMake/file-DOWNLOAD/httpheader-not-set.cmake
index 6efc958..6efc958 100644
--- a/Tests/RunCMake/file/DOWNLOAD-httpheader-not-set.cmake
+++ b/Tests/RunCMake/file-DOWNLOAD/httpheader-not-set.cmake
diff --git a/Tests/RunCMake/file-DOWNLOAD/input.png b/Tests/RunCMake/file-DOWNLOAD/input.png
new file mode 100644
index 0000000..9ab565a
--- /dev/null
+++ b/Tests/RunCMake/file-DOWNLOAD/input.png
Binary files differ
diff --git a/Tests/RunCMake/file/DOWNLOAD-pass-not-set-result.txt b/Tests/RunCMake/file-DOWNLOAD/netrc-bad-result.txt
index d00491f..d00491f 100644
--- a/Tests/RunCMake/file/DOWNLOAD-pass-not-set-result.txt
+++ b/Tests/RunCMake/file-DOWNLOAD/netrc-bad-result.txt
diff --git a/Tests/RunCMake/file/DOWNLOAD-netrc-bad-stderr.txt b/Tests/RunCMake/file-DOWNLOAD/netrc-bad-stderr.txt
index 96ce62a..61d7c99 100644
--- a/Tests/RunCMake/file/DOWNLOAD-netrc-bad-stderr.txt
+++ b/Tests/RunCMake/file-DOWNLOAD/netrc-bad-stderr.txt
@@ -1,19 +1,19 @@
-^CMake Error at DOWNLOAD-netrc-bad\.cmake:[0-9]+ \(file\):
+^CMake Error at netrc-bad\.cmake:[0-9]+ \(file\):
file DOWNLOAD missing level value for NETRC\.
Call Stack \(most recent call first\):
CMakeLists\.txt:[0-9]+ \(include\)
+
-CMake Error at DOWNLOAD-netrc-bad\.cmake:[0-9]+ \(file\):
+CMake Error at netrc-bad\.cmake:[0-9]+ \(file\):
file DOWNLOAD missing file value for NETRC_FILE\.
Call Stack \(most recent call first\):
CMakeLists\.txt:[0-9]+ \(include\)
+
-CMake Error at DOWNLOAD-netrc-bad\.cmake:[0-9]+ \(file\):
+CMake Error at netrc-bad\.cmake:[0-9]+ \(file\):
file NETRC accepts OPTIONAL, IGNORED or REQUIRED but got: INVALID
Call Stack \(most recent call first\):
CMakeLists\.txt:[0-9]+ \(include\)
+
-CMake Error at DOWNLOAD-netrc-bad\.cmake:[0-9]+ \(file\):
+CMake Error at netrc-bad\.cmake:[0-9]+ \(file\):
file NETRC accepts OPTIONAL, IGNORED or REQUIRED but got: FALSE
Call Stack \(most recent call first\):
CMakeLists\.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/file/DOWNLOAD-netrc-bad.cmake b/Tests/RunCMake/file-DOWNLOAD/netrc-bad.cmake
index 6a62df9..c62238a 100644
--- a/Tests/RunCMake/file/DOWNLOAD-netrc-bad.cmake
+++ b/Tests/RunCMake/file-DOWNLOAD/netrc-bad.cmake
@@ -5,11 +5,11 @@ file(DOWNLOAD "" "" NETRC)
file(DOWNLOAD "" "" NETRC_FILE)
set(CMAKE_NETRC FALSE)
file(DOWNLOAD
- "file://${slash}${CMAKE_CURRENT_SOURCE_DIR}/DOWNLOAD-netrc-bad.txt"
+ "file://${slash}${CMAKE_CURRENT_SOURCE_DIR}/netrc-bad.txt"
"${CMAKE_CURRENT_BINARY_DIR}/netrc-bad.txt"
NETRC INVALID
)
file(DOWNLOAD
- "file://${slash}${CMAKE_CURRENT_SOURCE_DIR}/DOWNLOAD-netrc-bad.txt"
+ "file://${slash}${CMAKE_CURRENT_SOURCE_DIR}/netrc-bad.txt"
"${CMAKE_CURRENT_BINARY_DIR}/netrc-bad.txt"
)
diff --git a/Tests/RunCMake/file/DOWNLOAD-unused-argument.txt b/Tests/RunCMake/file-DOWNLOAD/netrc-bad.txt
index e69de29..e69de29 100644
--- a/Tests/RunCMake/file/DOWNLOAD-unused-argument.txt
+++ b/Tests/RunCMake/file-DOWNLOAD/netrc-bad.txt
diff --git a/Tests/RunCMake/file-DOWNLOAD/no-file-arg.cmake b/Tests/RunCMake/file-DOWNLOAD/no-file-arg.cmake
new file mode 100644
index 0000000..6520940
--- /dev/null
+++ b/Tests/RunCMake/file-DOWNLOAD/no-file-arg.cmake
@@ -0,0 +1,11 @@
+include(common.cmake)
+
+set(file "")
+
+file_download()
+
+set(file "${CMAKE_CURRENT_BINARY_DIR}/input.png")
+
+if(NOT EXISTS "${file}")
+ message(FATAL_ERROR "file not downloaded to expected path:\n ${file}")
+endif()
diff --git a/Tests/RunCMake/file-DOWNLOAD/no-file-stdout.txt b/Tests/RunCMake/file-DOWNLOAD/no-file-stdout.txt
new file mode 100644
index 0000000..701e995
--- /dev/null
+++ b/Tests/RunCMake/file-DOWNLOAD/no-file-stdout.txt
@@ -0,0 +1 @@
+-- status='0;"No error"'
diff --git a/Tests/RunCMake/file-DOWNLOAD/no-file.cmake b/Tests/RunCMake/file-DOWNLOAD/no-file.cmake
new file mode 100644
index 0000000..dc234b2
--- /dev/null
+++ b/Tests/RunCMake/file-DOWNLOAD/no-file.cmake
@@ -0,0 +1,11 @@
+include(common.cmake)
+
+# Test downloading without saving to a file.
+set(file "")
+file_download()
+
+foreach(name input.png output.png TIMEOUT)
+ if(EXISTS "${CMAKE_CURRENT_BINARY_DIR}/${name}")
+ message(FATAL_ERROR "file incorrectly saved to:\n ${CMAKE_CURRENT_BINARY_DIR}/${name}")
+ endif()
+endforeach()
diff --git a/Tests/RunCMake/file/DOWNLOAD-no-save-hash-result.txt b/Tests/RunCMake/file-DOWNLOAD/no-save-hash-result.txt
index d00491f..d00491f 100644
--- a/Tests/RunCMake/file/DOWNLOAD-no-save-hash-result.txt
+++ b/Tests/RunCMake/file-DOWNLOAD/no-save-hash-result.txt
diff --git a/Tests/RunCMake/file/DOWNLOAD-no-save-hash-stderr.txt b/Tests/RunCMake/file-DOWNLOAD/no-save-hash-stderr.txt
index b0f0d19..8f2f885 100644
--- a/Tests/RunCMake/file/DOWNLOAD-no-save-hash-stderr.txt
+++ b/Tests/RunCMake/file-DOWNLOAD/no-save-hash-stderr.txt
@@ -1,4 +1,5 @@
-^CMake Error at DOWNLOAD-no-save-hash\.cmake:[0-9]+ \(file\):
+^CMake Error at common\.cmake:[0-9]+ \(file\):
file DOWNLOAD cannot calculate hash if file is not saved\.
Call Stack \(most recent call first\):
+ no-save-hash.cmake:[0-9]+ \(file_download\)
CMakeLists\.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/file-DOWNLOAD/no-save-hash.cmake b/Tests/RunCMake/file-DOWNLOAD/no-save-hash.cmake
new file mode 100644
index 0000000..7fdc397
--- /dev/null
+++ b/Tests/RunCMake/file-DOWNLOAD/no-save-hash.cmake
@@ -0,0 +1,5 @@
+include(common.cmake)
+
+# Test downloading without saving to a file.
+set(file "")
+file_download(EXPECTED_HASH MD5=55555555555555555555555555555555)
diff --git a/Tests/RunCMake/file/DOWNLOAD-unused-argument-result.txt b/Tests/RunCMake/file-DOWNLOAD/no-save-hash.txt
index e69de29..e69de29 100644
--- a/Tests/RunCMake/file/DOWNLOAD-unused-argument-result.txt
+++ b/Tests/RunCMake/file-DOWNLOAD/no-save-hash.txt
diff --git a/Tests/RunCMake/file/DOWNLOAD-netrc-bad-result.txt b/Tests/RunCMake/file-DOWNLOAD/pass-not-set-result.txt
index d00491f..d00491f 100644
--- a/Tests/RunCMake/file/DOWNLOAD-netrc-bad-result.txt
+++ b/Tests/RunCMake/file-DOWNLOAD/pass-not-set-result.txt
diff --git a/Tests/RunCMake/file/DOWNLOAD-pass-not-set-stderr.txt b/Tests/RunCMake/file-DOWNLOAD/pass-not-set-stderr.txt
index 2fa2731..23997c5 100644
--- a/Tests/RunCMake/file/DOWNLOAD-pass-not-set-stderr.txt
+++ b/Tests/RunCMake/file-DOWNLOAD/pass-not-set-stderr.txt
@@ -1,4 +1,4 @@
-^CMake Error at DOWNLOAD-pass-not-set.cmake:[0-9]+ \(file\):
+^CMake Error at pass-not-set.cmake:[0-9]+ \(file\):
file DOWNLOAD missing string for USERPWD.
Call Stack \(most recent call first\):
CMakeLists.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/file/DOWNLOAD-pass-not-set.cmake b/Tests/RunCMake/file-DOWNLOAD/pass-not-set.cmake
index 61eff6d..61eff6d 100644
--- a/Tests/RunCMake/file/DOWNLOAD-pass-not-set.cmake
+++ b/Tests/RunCMake/file-DOWNLOAD/pass-not-set.cmake
diff --git a/Tests/RunCMake/file-DOWNLOAD/range-stdout.txt b/Tests/RunCMake/file-DOWNLOAD/range-stdout.txt
new file mode 100644
index 0000000..e2ed7aa
--- /dev/null
+++ b/Tests/RunCMake/file-DOWNLOAD/range-stdout.txt
@@ -0,0 +1,4 @@
+-- status='0;"No error"'
+-- status='0;"No error"'
+-- status='0;"No error"'
+-- status='0;"No error"'
diff --git a/Tests/RunCMake/file-DOWNLOAD/range.cmake b/Tests/RunCMake/file-DOWNLOAD/range.cmake
new file mode 100644
index 0000000..f77bb28
--- /dev/null
+++ b/Tests/RunCMake/file-DOWNLOAD/range.cmake
@@ -0,0 +1,15 @@
+include(common.cmake)
+
+set(file ${CMAKE_CURRENT_BINARY_DIR}/output1.png)
+file_download(RANGE_START 0 EXPECTED_MD5 dbd330d52f4dbd60115d4191904ded92)
+
+set(file ${CMAKE_CURRENT_BINARY_DIR}/output2.png)
+file_download(RANGE_END 50 EXPECTED_MD5 8592e5665b839b5d23825dc84c135b61)
+
+set(file ${CMAKE_CURRENT_BINARY_DIR}/output3.png)
+file_download(RANGE_START 10 RANGE_END 50 EXPECTED_MD5 36cd52681e6c6c8fef85fcd9e86fc30d)
+
+set(file ${CMAKE_CURRENT_BINARY_DIR}/output4.png)
+file_download(RANGE_START 0 RANGE_END 50
+ RANGE_START 60 RANGE_END 100
+ EXPECTED_MD5 c5c9e74e82d493dd901eecccd659cebc)
diff --git a/Tests/RunCMake/file/DOWNLOAD-httpheader-not-set-result.txt b/Tests/RunCMake/file-DOWNLOAD/tls-cainfo-not-set-result.txt
index d00491f..d00491f 100644
--- a/Tests/RunCMake/file/DOWNLOAD-httpheader-not-set-result.txt
+++ b/Tests/RunCMake/file-DOWNLOAD/tls-cainfo-not-set-result.txt
diff --git a/Tests/RunCMake/file/DOWNLOAD-tls-cainfo-not-set-stderr.txt b/Tests/RunCMake/file-DOWNLOAD/tls-cainfo-not-set-stderr.txt
index 1552baa..d9fa7b7 100644
--- a/Tests/RunCMake/file/DOWNLOAD-tls-cainfo-not-set-stderr.txt
+++ b/Tests/RunCMake/file-DOWNLOAD/tls-cainfo-not-set-stderr.txt
@@ -1,4 +1,4 @@
-^CMake Error at DOWNLOAD-tls-cainfo-not-set.cmake:[0-9]+ \(file\):
+^CMake Error at tls-cainfo-not-set.cmake:[0-9]+ \(file\):
file DOWNLOAD missing file value for TLS_CAINFO.
Call Stack \(most recent call first\):
CMakeLists.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/file/DOWNLOAD-tls-cainfo-not-set.cmake b/Tests/RunCMake/file-DOWNLOAD/tls-cainfo-not-set.cmake
index b476425..b476425 100644
--- a/Tests/RunCMake/file/DOWNLOAD-tls-cainfo-not-set.cmake
+++ b/Tests/RunCMake/file-DOWNLOAD/tls-cainfo-not-set.cmake
diff --git a/Tests/RunCMake/file/DOWNLOAD-hash-mismatch-result.txt b/Tests/RunCMake/file-DOWNLOAD/tls-verify-not-set-result.txt
index d00491f..d00491f 100644
--- a/Tests/RunCMake/file/DOWNLOAD-hash-mismatch-result.txt
+++ b/Tests/RunCMake/file-DOWNLOAD/tls-verify-not-set-result.txt
diff --git a/Tests/RunCMake/file/DOWNLOAD-tls-verify-not-set-stderr.txt b/Tests/RunCMake/file-DOWNLOAD/tls-verify-not-set-stderr.txt
index 2f46c0c..c048ea9 100644
--- a/Tests/RunCMake/file/DOWNLOAD-tls-verify-not-set-stderr.txt
+++ b/Tests/RunCMake/file-DOWNLOAD/tls-verify-not-set-stderr.txt
@@ -1,4 +1,4 @@
-^CMake Error at DOWNLOAD-tls-verify-not-set.cmake:[0-9]+ \(file\):
+^CMake Error at tls-verify-not-set.cmake:[0-9]+ \(file\):
file DOWNLOAD missing bool value for TLS_VERIFY.
Call Stack \(most recent call first\):
CMakeLists.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/file/DOWNLOAD-tls-verify-not-set.cmake b/Tests/RunCMake/file-DOWNLOAD/tls-verify-not-set.cmake
index 919368c..919368c 100644
--- a/Tests/RunCMake/file/DOWNLOAD-tls-verify-not-set.cmake
+++ b/Tests/RunCMake/file-DOWNLOAD/tls-verify-not-set.cmake
diff --git a/Tests/RunCMake/file/DOWNLOAD-no-save-hash.txt b/Tests/RunCMake/file-DOWNLOAD/unused-argument-result.txt
index e69de29..e69de29 100644
--- a/Tests/RunCMake/file/DOWNLOAD-no-save-hash.txt
+++ b/Tests/RunCMake/file-DOWNLOAD/unused-argument-result.txt
diff --git a/Tests/RunCMake/file/DOWNLOAD-unused-argument-stderr.txt b/Tests/RunCMake/file-DOWNLOAD/unused-argument-stderr.txt
index 82a78c9..f7cfc4f 100644
--- a/Tests/RunCMake/file/DOWNLOAD-unused-argument-stderr.txt
+++ b/Tests/RunCMake/file-DOWNLOAD/unused-argument-stderr.txt
@@ -1,5 +1,6 @@
-^CMake Warning \(dev\) at DOWNLOAD-unused-argument.cmake:[0-9]+ \(file\):
+^CMake Warning \(dev\) at common.cmake:[0-9]+ \(file\):
Unexpected argument: JUNK
Call Stack \(most recent call first\):
+ unused-argument.cmake:[0-9]+ \(file_download\)
CMakeLists.txt:[0-9]+ \(include\)
This warning is for project developers. Use -Wno-dev to suppress it.$
diff --git a/Tests/RunCMake/file-DOWNLOAD/unused-argument.cmake b/Tests/RunCMake/file-DOWNLOAD/unused-argument.cmake
new file mode 100644
index 0000000..6f7f597
--- /dev/null
+++ b/Tests/RunCMake/file-DOWNLOAD/unused-argument.cmake
@@ -0,0 +1,3 @@
+include(common.cmake)
+
+file_download(JUNK)
diff --git a/Tests/RunCMake/file/DOWNLOAD-hash-mismatch-stderr.txt b/Tests/RunCMake/file/DOWNLOAD-hash-mismatch-stderr.txt
deleted file mode 100644
index 7a356c1..0000000
--- a/Tests/RunCMake/file/DOWNLOAD-hash-mismatch-stderr.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-^CMake Error at DOWNLOAD-hash-mismatch.cmake:[0-9]+ \(file\):
- file DOWNLOAD HASH mismatch
-
- for file: \[.*/Tests/RunCMake/file/DOWNLOAD-hash-mismatch-build/hash-mismatch.txt\]
- expected hash: \[0123456789abcdef0123456789abcdef01234567\]
- actual hash: \[da39a3ee5e6b4b0d3255bfef95601890afd80709\]
-
-Call Stack \(most recent call first\):
- CMakeLists.txt:[0-9]+ \(include\)
-+
-status='1;HASH mismatch: expected: 0123456789abcdef0123456789abcdef01234567 actual: da39a3ee5e6b4b0d3255bfef95601890afd80709'$
diff --git a/Tests/RunCMake/file/DOWNLOAD-hash-mismatch.cmake b/Tests/RunCMake/file/DOWNLOAD-hash-mismatch.cmake
deleted file mode 100644
index a91b217..0000000
--- a/Tests/RunCMake/file/DOWNLOAD-hash-mismatch.cmake
+++ /dev/null
@@ -1,10 +0,0 @@
-if(NOT "${CMAKE_CURRENT_SOURCE_DIR}" MATCHES "^/")
- set(slash /)
-endif()
-file(DOWNLOAD
- "file://${slash}${CMAKE_CURRENT_SOURCE_DIR}/DOWNLOAD-hash-mismatch.txt"
- ${CMAKE_CURRENT_BINARY_DIR}/hash-mismatch.txt
- EXPECTED_HASH SHA1=0123456789abcdef0123456789abcdef01234567
- STATUS status
- )
-message("status='${status}'")
diff --git a/Tests/RunCMake/file/DOWNLOAD-hash-mismatch.txt b/Tests/RunCMake/file/DOWNLOAD-hash-mismatch.txt
deleted file mode 100644
index e69de29..0000000
--- a/Tests/RunCMake/file/DOWNLOAD-hash-mismatch.txt
+++ /dev/null
diff --git a/Tests/RunCMake/file/DOWNLOAD-netrc-bad.txt b/Tests/RunCMake/file/DOWNLOAD-netrc-bad.txt
deleted file mode 100644
index e69de29..0000000
--- a/Tests/RunCMake/file/DOWNLOAD-netrc-bad.txt
+++ /dev/null
diff --git a/Tests/RunCMake/file/DOWNLOAD-no-save-hash.cmake b/Tests/RunCMake/file/DOWNLOAD-no-save-hash.cmake
deleted file mode 100644
index ce959a7..0000000
--- a/Tests/RunCMake/file/DOWNLOAD-no-save-hash.cmake
+++ /dev/null
@@ -1,8 +0,0 @@
-if(NOT "${CMAKE_CURRENT_SOURCE_DIR}" MATCHES "^/")
- set(slash /)
-endif()
-file(DOWNLOAD
- "file://${slash}${CMAKE_CURRENT_SOURCE_DIR}/DOWNLOAD-no-save-md5.txt"
- EXPECTED_HASH MD5=55555555555555555555555555555555
- STATUS status
- )
diff --git a/Tests/RunCMake/file/DOWNLOAD-unused-argument.cmake b/Tests/RunCMake/file/DOWNLOAD-unused-argument.cmake
deleted file mode 100644
index 2fa5482..0000000
--- a/Tests/RunCMake/file/DOWNLOAD-unused-argument.cmake
+++ /dev/null
@@ -1,8 +0,0 @@
-if(NOT "${CMAKE_CURRENT_SOURCE_DIR}" MATCHES "^/")
- set(slash /)
-endif()
-file(DOWNLOAD
- "file://${slash}${CMAKE_CURRENT_SOURCE_DIR}/DOWNLOAD-unused-argument.txt"
- "${CMAKE_CURRENT_BINARY_DIR}/unused-argument.txt"
- JUNK
- )
diff --git a/Tests/RunCMake/file/RunCMakeTest.cmake b/Tests/RunCMake/file/RunCMakeTest.cmake
index 0c4c174..752f7a0 100644
--- a/Tests/RunCMake/file/RunCMakeTest.cmake
+++ b/Tests/RunCMake/file/RunCMakeTest.cmake
@@ -4,14 +4,6 @@ run_cmake(CREATE_LINK)
run_cmake(CREATE_LINK-COPY_ON_ERROR)
run_cmake(CREATE_LINK-noarg)
run_cmake(CREATE_LINK-noexist)
-run_cmake(DOWNLOAD-hash-mismatch)
-run_cmake(DOWNLOAD-unused-argument)
-run_cmake(DOWNLOAD-httpheader-not-set)
-run_cmake(DOWNLOAD-netrc-bad)
-run_cmake(DOWNLOAD-tls-cainfo-not-set)
-run_cmake(DOWNLOAD-tls-verify-not-set)
-run_cmake(DOWNLOAD-pass-not-set)
-run_cmake(DOWNLOAD-no-save-hash)
run_cmake(TOUCH)
run_cmake(TOUCH-error-in-source-directory)
run_cmake(TOUCH-error-missing-directory)
diff --git a/Utilities/ClangTidyModule/Tests/cmake-use-cmstrlen-fixit.cxx b/Utilities/ClangTidyModule/Tests/cmake-use-cmstrlen-fixit.cxx
index c93d557..cde0086 100644
--- a/Utilities/ClangTidyModule/Tests/cmake-use-cmstrlen-fixit.cxx
+++ b/Utilities/ClangTidyModule/Tests/cmake-use-cmstrlen-fixit.cxx
@@ -27,11 +27,16 @@ int main()
(void)cmStrLen("Goodbye");
(void)cmStrLen("Hola");
(void)cmStrLen("Bonjour");
+ (void)(cmStrLen("Hallo"));
+ (void)(4 + cmStrLen("Hallo"));
+ (void)(cmStrLen("Hallo"));
+ (void)(4 + cmStrLen("Hallo"));
// No correction needed
(void)ns2::strlen("Salve");
(void)cmStrLen("Konnichiwa");
(void)strlen(s0);
+ (void)(sizeof("Hallo") - 2);
return 0;
}
diff --git a/Utilities/ClangTidyModule/Tests/cmake-use-cmstrlen-stdout.txt b/Utilities/ClangTidyModule/Tests/cmake-use-cmstrlen-stdout.txt
index 6c52ad5..d18822a 100644
--- a/Utilities/ClangTidyModule/Tests/cmake-use-cmstrlen-stdout.txt
+++ b/Utilities/ClangTidyModule/Tests/cmake-use-cmstrlen-stdout.txt
@@ -18,3 +18,35 @@ cmake-use-cmstrlen.cxx:29:9: warning: use cmStrLen() for string literals [cmake-
^~~~~~~~~~~
cmStrLen
cmake-use-cmstrlen.cxx:29:9: note: FIX-IT applied suggested code changes
+cmake-use-cmstrlen.cxx:30:10: warning: use cmStrLen() for string literals [cmake-use-cmstrlen]
+ (void)(sizeof("Hallo") - 1);
+ ^~~~~~ ~~~
+ cmStrLen
+cmake-use-cmstrlen.cxx:30:10: note: FIX-IT applied suggested code changes
+cmake-use-cmstrlen.cxx:30:26: note: FIX-IT applied suggested code changes
+ (void)(sizeof("Hallo") - 1);
+ ^
+cmake-use-cmstrlen.cxx:31:14: warning: use cmStrLen() for string literals [cmake-use-cmstrlen]
+ (void)(4 + sizeof("Hallo") - 1);
+ ^~~~~~ ~~~
+ cmStrLen
+cmake-use-cmstrlen.cxx:31:14: note: FIX-IT applied suggested code changes
+cmake-use-cmstrlen.cxx:31:30: note: FIX-IT applied suggested code changes
+ (void)(4 + sizeof("Hallo") - 1);
+ ^
+cmake-use-cmstrlen.cxx:32:10: warning: use cmStrLen() for string literals [cmake-use-cmstrlen]
+ (void)(sizeof "Hallo" - 1);
+ ^~~~~~ ~~~
+ cmStrLen( )
+cmake-use-cmstrlen.cxx:32:10: note: FIX-IT applied suggested code changes
+cmake-use-cmstrlen.cxx:32:25: note: FIX-IT applied suggested code changes
+ (void)(sizeof "Hallo" - 1);
+ ^
+cmake-use-cmstrlen.cxx:33:14: warning: use cmStrLen() for string literals [cmake-use-cmstrlen]
+ (void)(4 + sizeof "Hallo" - 1);
+ ^~~~~~ ~~~
+ cmStrLen( )
+cmake-use-cmstrlen.cxx:33:14: note: FIX-IT applied suggested code changes
+cmake-use-cmstrlen.cxx:33:29: note: FIX-IT applied suggested code changes
+ (void)(4 + sizeof "Hallo" - 1);
+ ^
diff --git a/Utilities/ClangTidyModule/Tests/cmake-use-cmstrlen.cxx b/Utilities/ClangTidyModule/Tests/cmake-use-cmstrlen.cxx
index f36262b..205bc9c 100644
--- a/Utilities/ClangTidyModule/Tests/cmake-use-cmstrlen.cxx
+++ b/Utilities/ClangTidyModule/Tests/cmake-use-cmstrlen.cxx
@@ -27,11 +27,16 @@ int main()
(void)::strlen("Goodbye");
(void)std::strlen("Hola");
(void)ns1::strlen("Bonjour");
+ (void)(sizeof("Hallo") - 1);
+ (void)(4 + sizeof("Hallo") - 1);
+ (void)(sizeof "Hallo" - 1);
+ (void)(4 + sizeof "Hallo" - 1);
// No correction needed
(void)ns2::strlen("Salve");
(void)cmStrLen("Konnichiwa");
(void)strlen(s0);
+ (void)(sizeof("Hallo") - 2);
return 0;
}
diff --git a/Utilities/ClangTidyModule/UseCmstrlenCheck.cxx b/Utilities/ClangTidyModule/UseCmstrlenCheck.cxx
index 590d260..d4bae1f 100644
--- a/Utilities/ClangTidyModule/UseCmstrlenCheck.cxx
+++ b/Utilities/ClangTidyModule/UseCmstrlenCheck.cxx
@@ -17,17 +17,61 @@ UseCmstrlenCheck::UseCmstrlenCheck(StringRef Name, ClangTidyContext* Context)
void UseCmstrlenCheck::registerMatchers(MatchFinder* Finder)
{
Finder->addMatcher(callExpr(callee(functionDecl(hasName("::strlen"))),
- callee(expr().bind("callee")),
+ callee(expr().bind("strlen")),
hasArgument(0, stringLiteral())),
this);
+
+ auto IsSizeOfStringLiteral =
+ unaryExprOrTypeTraitExpr(
+ ofKind(UETT_SizeOf),
+ anyOf(has(parenExpr(has(stringLiteral())).bind("paren")),
+ has(stringLiteral())))
+ .bind("sizeOf");
+ Finder->addMatcher(
+ binaryOperator(
+ hasOperatorName("-"),
+ hasLHS(anyOf(
+ binaryOperator(hasOperatorName("+"), hasRHS(IsSizeOfStringLiteral)),
+ IsSizeOfStringLiteral)),
+ hasRHS(implicitCastExpr(has(integerLiteral(equals(1)).bind("literal")))))
+ .bind("sizeOfMinus"),
+ this);
}
void UseCmstrlenCheck::check(const MatchFinder::MatchResult& Result)
{
- const Expr* Node = Result.Nodes.getNodeAs<Expr>("callee");
+ const Expr* Strlen = Result.Nodes.getNodeAs<Expr>("strlen");
+ const BinaryOperator* SizeOfMinus =
+ Result.Nodes.getNodeAs<BinaryOperator>("sizeOfMinus");
+
+ if (Strlen) {
+ this->diag(Strlen->getBeginLoc(), "use cmStrLen() for string literals")
+ << FixItHint::CreateReplacement(Strlen->getSourceRange(), "cmStrLen");
+ }
+
+ if (SizeOfMinus) {
+ const ParenExpr* Paren = Result.Nodes.getNodeAs<ParenExpr>("paren");
+ const UnaryExprOrTypeTraitExpr* SizeOf =
+ Result.Nodes.getNodeAs<UnaryExprOrTypeTraitExpr>("sizeOf");
+ const IntegerLiteral* Literal =
+ Result.Nodes.getNodeAs<IntegerLiteral>("literal");
- this->diag(Node->getBeginLoc(), "use cmStrLen() for string literals")
- << FixItHint::CreateReplacement(Node->getSourceRange(), "cmStrLen");
+ std::vector<FixItHint> FixIts;
+ if (Paren) {
+ FixIts.push_back(
+ FixItHint::CreateReplacement(SizeOf->getOperatorLoc(), "cmStrLen"));
+ FixIts.push_back(FixItHint::CreateRemoval(
+ SourceRange(SizeOfMinus->getOperatorLoc(), Literal->getLocation())));
+ } else {
+ FixIts.push_back(
+ FixItHint::CreateReplacement(SizeOf->getOperatorLoc(), "cmStrLen("));
+ FixIts.push_back(FixItHint::CreateReplacement(
+ SourceRange(SizeOfMinus->getOperatorLoc(), Literal->getLocation()),
+ ")"));
+ }
+ this->diag(SizeOf->getOperatorLoc(), "use cmStrLen() for string literals")
+ << FixIts;
+ }
}
}
}