summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.clang-tidy1
-rw-r--r--Help/command/project.rst3
-rw-r--r--Help/manual/cmake.1.rst14
-rw-r--r--Help/release/dev/cmake-E-copy-t-arg.rst4
-rw-r--r--Help/release/dev/top-level-command-order.rst6
-rw-r--r--Modules/CMakeDetermineSystem.cmake52
-rw-r--r--Source/CMakeVersion.cmake2
-rw-r--r--Source/cmCommandLineArgument.h11
-rw-r--r--Source/cmProjectCommand.cxx9
-rw-r--r--Source/cmakemain.cxx26
-rw-r--r--Source/cmcmd.cxx57
-rw-r--r--Tests/CheckSourceTree/check.cmake1
-rw-r--r--Tests/RunCMake/CMakePresetsTest/RunCMakeTest.cmake4
-rw-r--r--Tests/RunCMake/CTestCommandLine/RunCMakeTest.cmake3
-rw-r--r--Tests/RunCMake/CommandLine/C_buildsrcdir/initial-cache.txt2
-rw-r--r--Tests/RunCMake/CommandLine/E_copy-t-argument-target-is-file-result.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E_copy-t-argument-target-is-file-stderr.txt1
-rw-r--r--Tests/RunCMake/CommandLine/RunCMakeTest.cmake8
-rw-r--r--Tests/RunCMake/CommandLine/build-no-dir2-result.txt1
-rw-r--r--Tests/RunCMake/CommandLine/build-no-dir2-stderr.txt1
-rw-r--r--Tests/RunCMake/GoogleTest/RunCMakeTest.cmake4
-rw-r--r--Tests/RunCMake/RunCTest.cmake4
-rw-r--r--Tests/RunCMake/ctest_environment/RunCMakeTest.cmake4
-rw-r--r--Tests/RunCMake/ctest_fixtures/RunCMakeTest.cmake4
-rw-r--r--Tests/RunCMake/ctest_memcheck/RunCMakeTest.cmake2
-rw-r--r--Tests/RunCMake/ctest_test/RunCMakeTest.cmake3
-rw-r--r--Tests/RunCMake/project/CMP0048-OLD-VERSION-stderr.txt2
-rw-r--r--Tests/RunCMake/project/CMP0048-OLD-stderr.txt2
-rw-r--r--Tests/RunCMake/project/CMP0048-WARN-stderr.txt2
-rw-r--r--Tests/RunCMake/project/CMakeLists.txt4
-rw-r--r--Tests/RunCMake/project/LanguagesTwice-stderr.txt2
-rw-r--r--Tests/RunCMake/project/NoMinimumRequired-stderr.txt5
-rw-r--r--Tests/RunCMake/project/NoMinimumRequired.cmake0
-rw-r--r--Tests/RunCMake/project/RunCMakeTest.cmake2
-rw-r--r--Tests/RunCMake/project/VersionInvalid-stderr.txt2
-rw-r--r--Tests/RunCMake/project/VersionMissingLanguages-stderr.txt2
-rw-r--r--Tests/RunCMake/project/VersionTwice-stderr.txt2
-rw-r--r--Tests/RunCMake/project_injected/RunCMakeTest.cmake1
-rw-r--r--Tests/RunCMake/test_include_dirs/RunCMakeTest.cmake4
-rw-r--r--Utilities/ClangTidyModule/CMakeLists.txt2
-rw-r--r--Utilities/ClangTidyModule/Module.cxx3
-rw-r--r--Utilities/ClangTidyModule/OstringstreamUseCmstrcatCheck.cxx52
-rw-r--r--Utilities/ClangTidyModule/OstringstreamUseCmstrcatCheck.h21
-rw-r--r--Utilities/ClangTidyModule/Tests/CMakeLists.txt1
-rw-r--r--Utilities/ClangTidyModule/Tests/cmake-ostringstream-use-cmstrcat-stdout.txt6
-rw-r--r--Utilities/ClangTidyModule/Tests/cmake-ostringstream-use-cmstrcat.cxx10
46 files changed, 282 insertions, 71 deletions
diff --git a/.clang-tidy b/.clang-tidy
index 18aa86e..7ee8bf0 100644
--- a/.clang-tidy
+++ b/.clang-tidy
@@ -34,6 +34,7 @@ readability-*,\
-readability-suspicious-call-argument,\
-readability-uppercase-literal-suffix,\
cmake-*,\
+-cmake-ostringstream-use-cmstrcat,\
-cmake-use-bespoke-enum-class,\
"
HeaderFilterRegex: 'Source/cm[^/]*\.(h|hxx|cxx)$'
diff --git a/Help/command/project.rst b/Help/command/project.rst
index 8f32fa3..4e57d09 100644
--- a/Help/command/project.rst
+++ b/Help/command/project.rst
@@ -188,5 +188,6 @@ call exists, CMake will issue a warning and pretend there is a
Call the ``project()`` command near the top of the top-level
``CMakeLists.txt``, but *after* calling :command:`cmake_minimum_required`.
It is important to establish version and policy settings before invoking
- other commands whose behavior they may affect.
+ other commands whose behavior they may affect and for this reason the
+ ``project()`` command will issue a warning if this order is not kept.
See also policy :policy:`CMP0000`.
diff --git a/Help/manual/cmake.1.rst b/Help/manual/cmake.1.rst
index daa2e58..dc51383 100644
--- a/Help/manual/cmake.1.rst
+++ b/Help/manual/cmake.1.rst
@@ -848,17 +848,21 @@ Available commands are:
.. program:: cmake-E
-.. option:: copy <file>... <destination>
+.. option:: copy <file>... <destination>, copy -t <destination> <file>...
Copy files to ``<destination>`` (either file or directory).
- If multiple files are specified, the ``<destination>`` must be
- directory and it must exist. Wildcards are not supported.
- ``copy`` does follow symlinks. That means it does not copy symlinks,
- but the files or directories it point to.
+ If multiple files are specified, or if ``-t`` is specified, the
+ ``<destination>`` must be directory and it must exist. If ``-t`` is not
+ specified, the last argument is assumed to be the ``<destination>``.
+ Wildcards are not supported. ``copy`` does follow symlinks. That means it
+ does not copy symlinks, but the files or directories it point to.
.. versionadded:: 3.5
Support for multiple input files.
+ .. versionadded:: 3.26
+ Support for ``-t`` argument.
+
.. option:: copy_directory <dir>... <destination>
Copy content of ``<dir>...`` directories to ``<destination>`` directory.
diff --git a/Help/release/dev/cmake-E-copy-t-arg.rst b/Help/release/dev/cmake-E-copy-t-arg.rst
new file mode 100644
index 0000000..ca897d3
--- /dev/null
+++ b/Help/release/dev/cmake-E-copy-t-arg.rst
@@ -0,0 +1,4 @@
+cmake-E-copy-t-arg
+------------------
+
+* The :option:`cmake -E copy <cmake-E copy>` argument now supports a ``-t`` argument.
diff --git a/Help/release/dev/top-level-command-order.rst b/Help/release/dev/top-level-command-order.rst
new file mode 100644
index 0000000..07f87fb
--- /dev/null
+++ b/Help/release/dev/top-level-command-order.rst
@@ -0,0 +1,6 @@
+top-level-command-order
+-----------------------
+
+* The top-level :command:`project` call will now emit an author warning if the
+ documented command order in relation to :command:`cmake_minimum_required` is
+ not respected.
diff --git a/Modules/CMakeDetermineSystem.cmake b/Modules/CMakeDetermineSystem.cmake
index 2c2c2ac..94e92e8 100644
--- a/Modules/CMakeDetermineSystem.cmake
+++ b/Modules/CMakeDetermineSystem.cmake
@@ -33,20 +33,32 @@
# find out on which system cmake runs
if(CMAKE_HOST_UNIX)
- find_program(CMAKE_UNAME uname /bin /usr/bin /usr/local/bin )
+ find_program(CMAKE_UNAME NAMES uname PATHS /bin /usr/bin /usr/local/bin)
if(CMAKE_UNAME)
if(CMAKE_HOST_SYSTEM_NAME STREQUAL "AIX")
- exec_program(${CMAKE_UNAME} ARGS -v OUTPUT_VARIABLE _CMAKE_HOST_SYSTEM_MAJOR_VERSION)
- exec_program(${CMAKE_UNAME} ARGS -r OUTPUT_VARIABLE _CMAKE_HOST_SYSTEM_MINOR_VERSION)
+ execute_process(COMMAND ${CMAKE_UNAME} -v
+ OUTPUT_VARIABLE _CMAKE_HOST_SYSTEM_MAJOR_VERSION
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ ERROR_QUIET)
+ execute_process(COMMAND ${CMAKE_UNAME} -r
+ OUTPUT_VARIABLE _CMAKE_HOST_SYSTEM_MINOR_VERSION
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ ERROR_QUIET)
set(CMAKE_HOST_SYSTEM_VERSION "${_CMAKE_HOST_SYSTEM_MAJOR_VERSION}.${_CMAKE_HOST_SYSTEM_MINOR_VERSION}")
unset(_CMAKE_HOST_SYSTEM_MAJOR_VERSION)
unset(_CMAKE_HOST_SYSTEM_MINOR_VERSION)
else()
- exec_program(${CMAKE_UNAME} ARGS -r OUTPUT_VARIABLE CMAKE_HOST_SYSTEM_VERSION)
+ execute_process(COMMAND ${CMAKE_UNAME} -r
+ OUTPUT_VARIABLE CMAKE_HOST_SYSTEM_VERSION
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ ERROR_QUIET)
endif()
if(CMAKE_HOST_SYSTEM_NAME MATCHES "Linux|CYGWIN.*|MSYS.*|^GNU$|Android")
- exec_program(${CMAKE_UNAME} ARGS -m OUTPUT_VARIABLE CMAKE_HOST_SYSTEM_PROCESSOR
- RETURN_VALUE val)
+ execute_process(COMMAND ${CMAKE_UNAME} -m
+ OUTPUT_VARIABLE CMAKE_HOST_SYSTEM_PROCESSOR
+ RESULT_VARIABLE val
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ ERROR_QUIET)
elseif(CMAKE_HOST_SYSTEM_NAME MATCHES "Darwin")
# If we are running on Apple Silicon, honor CMAKE_APPLE_SILICON_PROCESSOR.
if(DEFINED CMAKE_APPLE_SILICON_PROCESSOR)
@@ -74,8 +86,11 @@ if(CMAKE_HOST_UNIX)
if(_CMAKE_APPLE_SILICON_PROCESSOR)
set(CMAKE_HOST_SYSTEM_PROCESSOR "${_CMAKE_APPLE_SILICON_PROCESSOR}")
else()
- exec_program(${CMAKE_UNAME} ARGS -m OUTPUT_VARIABLE CMAKE_HOST_SYSTEM_PROCESSOR
- RETURN_VALUE val)
+ execute_process(COMMAND ${CMAKE_UNAME} -m
+ OUTPUT_VARIABLE CMAKE_HOST_SYSTEM_PROCESSOR
+ RESULT_VARIABLE val
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ ERROR_QUIET)
endif()
unset(_CMAKE_APPLE_SILICON_PROCESSOR)
if(CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL "Power Macintosh")
@@ -83,14 +98,23 @@ if(CMAKE_HOST_UNIX)
set(CMAKE_HOST_SYSTEM_PROCESSOR "powerpc")
endif()
elseif(CMAKE_HOST_SYSTEM_NAME MATCHES "OpenBSD")
- exec_program(arch ARGS -s OUTPUT_VARIABLE CMAKE_HOST_SYSTEM_PROCESSOR
- RETURN_VALUE val)
+ execute_process(COMMAND arch -s
+ OUTPUT_VARIABLE CMAKE_HOST_SYSTEM_PROCESSOR
+ RESULT_VARIABLE val
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ ERROR_QUIET)
else()
- exec_program(${CMAKE_UNAME} ARGS -p OUTPUT_VARIABLE CMAKE_HOST_SYSTEM_PROCESSOR
- RETURN_VALUE val)
+ execute_process(COMMAND ${CMAKE_UNAME} -p
+ OUTPUT_VARIABLE CMAKE_HOST_SYSTEM_PROCESSOR
+ RESULT_VARIABLE val
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ ERROR_QUIET)
if("${val}" GREATER 0)
- exec_program(${CMAKE_UNAME} ARGS -m OUTPUT_VARIABLE CMAKE_HOST_SYSTEM_PROCESSOR
- RETURN_VALUE val)
+ execute_process(COMMAND ${CMAKE_UNAME} -m
+ OUTPUT_VARIABLE CMAKE_HOST_SYSTEM_PROCESSOR
+ RESULT_VARIABLE val
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ ERROR_QUIET)
endif()
endif()
# check the return of the last uname -m or -p
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index fbd5c69..359576c 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 20221114)
+set(CMake_VERSION_PATCH 20221115)
#set(CMake_VERSION_RC 0)
set(CMake_VERSION_IS_DIRTY 0)
diff --git a/Source/cmCommandLineArgument.h b/Source/cmCommandLineArgument.h
index 33c91bc..003e972 100644
--- a/Source/cmCommandLineArgument.h
+++ b/Source/cmCommandLineArgument.h
@@ -2,6 +2,8 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#pragma once
+#include <cm/optional>
+
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
@@ -250,6 +252,15 @@ private:
return true;
};
}
+
+ static std::function<bool(const std::string&, CallState...)>
+ generateSetToValue(cm::optional<std::string>& value1)
+ {
+ return [&value1](const std::string& arg, CallState&&...) -> bool {
+ value1 = arg;
+ return true;
+ };
+ }
};
std::string extract_single_value(std::string const& input,
diff --git a/Source/cmProjectCommand.cxx b/Source/cmProjectCommand.cxx
index 249fe2d..4d1ccfe 100644
--- a/Source/cmProjectCommand.cxx
+++ b/Source/cmProjectCommand.cxx
@@ -34,6 +34,15 @@ bool cmProjectCommand(std::vector<std::string> const& args,
}
cmMakefile& mf = status.GetMakefile();
+ if (mf.IsRootMakefile() &&
+ !mf.GetDefinition("CMAKE_MINIMUM_REQUIRED_VERSION")) {
+ mf.IssueMessage(
+ MessageType::AUTHOR_WARNING,
+ "cmake_minimum_required() should be called prior to this top-level "
+ "project() call. Please see the cmake-commands(7) manual for usage "
+ "documentation of both commands.");
+ }
+
if (!IncludeByVariable(status, "CMAKE_PROJECT_INCLUDE_BEFORE")) {
return false;
}
diff --git a/Source/cmakemain.cxx b/Source/cmakemain.cxx
index 43bebc1..9f23667 100644
--- a/Source/cmakemain.cxx
+++ b/Source/cmakemain.cxx
@@ -522,25 +522,8 @@ int do_build(int ac, char const* const* av)
if (ac >= 3) {
std::vector<std::string> inputArgs;
- bool hasPreset = false;
- for (int i = 2; i < ac; ++i) {
- if (strcmp(av[i], "--list-presets") == 0 ||
- cmHasLiteralPrefix(av[i], "--preset=") ||
- strcmp(av[i], "--preset") == 0) {
- hasPreset = true;
- break;
- }
- }
-
- if (hasPreset) {
- inputArgs.reserve(ac - 2);
- cm::append(inputArgs, av + 2, av + ac);
- } else {
- dir = cmSystemTools::CollapseFullPath(av[2]);
-
- inputArgs.reserve(ac - 3);
- cm::append(inputArgs, av + 3, av + ac);
- }
+ inputArgs.reserve(ac - 2);
+ cm::append(inputArgs, av + 2, av + ac);
decltype(inputArgs.size()) i = 0;
for (; i < inputArgs.size() && !nativeOptionsPassed; ++i) {
@@ -555,6 +538,11 @@ int do_build(int ac, char const* const* av)
break;
}
}
+ if (!matched && i == 0) {
+ dir = cmSystemTools::CollapseFullPath(arg);
+ matched = true;
+ parsed = true;
+ }
if (!(matched && parsed)) {
dir.clear();
if (!matched) {
diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx
index 67394f9..06bceb4 100644
--- a/Source/cmcmd.cxx
+++ b/Source/cmcmd.cxx
@@ -2,11 +2,15 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmcmd.h"
+#include <functional>
+
+#include <cm/optional>
#include <cmext/algorithm>
#include <cm3p/uv.h>
#include <fcntl.h>
+#include "cmCommandLineArgument.h"
#include "cmConsoleBuf.h"
#include "cmDuration.h"
#include "cmGlobalGenerator.h"
@@ -640,20 +644,59 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args,
if (args.size() > 1) {
// Copy file
if (args[1] == "copy" && args.size() > 3) {
+ using CommandArgument =
+ cmCommandLineArgument<bool(const std::string& value)>;
+
+ cm::optional<std::string> targetArg;
+ std::vector<CommandArgument> argParsers{
+ { "-t", CommandArgument::Values::One,
+ CommandArgument::setToValue(targetArg) },
+ };
+
+ std::vector<std::string> files;
+ for (decltype(args.size()) i = 2; i < args.size(); i++) {
+ const std::string& arg = args[i];
+ bool matched = false;
+ for (auto const& m : argParsers) {
+ if (m.matches(arg)) {
+ matched = true;
+ if (m.parse(arg, i, args)) {
+ break;
+ }
+ return 1; // failed to parse
+ }
+ }
+ if (!matched) {
+ files.push_back(arg);
+ }
+ }
+
// If multiple source files specified,
// then destination must be directory
- if ((args.size() > 4) &&
- (!cmSystemTools::FileIsDirectory(args.back()))) {
- std::cerr << "Error: Target (for copy command) \"" << args.back()
+ if (files.size() > 2 && !targetArg) {
+ targetArg = files.back();
+ files.pop_back();
+ }
+ if (targetArg && (!cmSystemTools::FileIsDirectory(*targetArg))) {
+ std::cerr << "Error: Target (for copy command) \"" << *targetArg
<< "\" is not a directory.\n";
return 1;
}
+ if (!targetArg) {
+ if (files.size() < 2) {
+ std::cerr
+ << "Error: No files or target specified (for copy command).\n";
+ return 1;
+ }
+ targetArg = files.back();
+ files.pop_back();
+ }
// If error occurs we want to continue copying next files.
bool return_value = false;
- for (auto const& arg : cmMakeRange(args).advance(2).retreat(1)) {
- if (!cmsys::SystemTools::CopyFileAlways(arg, args.back())) {
- std::cerr << "Error copying file \"" << arg << "\" to \""
- << args.back() << "\".\n";
+ for (auto const& file : files) {
+ if (!cmsys::SystemTools::CopyFileAlways(file, *targetArg)) {
+ std::cerr << "Error copying file \"" << file << "\" to \""
+ << *targetArg << "\".\n";
return_value = true;
}
}
diff --git a/Tests/CheckSourceTree/check.cmake b/Tests/CheckSourceTree/check.cmake
index 6341bd6..655e419 100644
--- a/Tests/CheckSourceTree/check.cmake
+++ b/Tests/CheckSourceTree/check.cmake
@@ -4,6 +4,7 @@ if(DEFINED ENV{CTEST_REAL_HOME})
endif()
file(GLOB known_files
+ "${CMake_SOURCE_DIR}/Tests/Java/hs_err_pid*.log"
"${CMake_SOURCE_DIR}/Tests/JavaExportImport/InstallExport/hs_err_pid*.log"
"${CMake_SOURCE_DIR}/Tests/JavaNativeHeaders/hs_err_pid*.log"
)
diff --git a/Tests/RunCMake/CMakePresetsTest/RunCMakeTest.cmake b/Tests/RunCMake/CMakePresetsTest/RunCMakeTest.cmake
index 1c7b836..5bd0158 100644
--- a/Tests/RunCMake/CMakePresetsTest/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CMakePresetsTest/RunCMakeTest.cmake
@@ -1,5 +1,9 @@
include(RunCMake)
+# Isolate our ctest runs from external environment.
+unset(ENV{CTEST_PARALLEL_LEVEL})
+unset(ENV{CTEST_OUTPUT_ON_FAILURE})
+
# Presets do not support legacy VS generator name architecture suffix.
if(RunCMake_GENERATOR MATCHES "^(Visual Studio [0-9]+ [0-9]+) ")
set(RunCMake_GENERATOR "${CMAKE_MATCH_1}")
diff --git a/Tests/RunCMake/CTestCommandLine/RunCMakeTest.cmake b/Tests/RunCMake/CTestCommandLine/RunCMakeTest.cmake
index df3e82a..8c35fe5 100644
--- a/Tests/RunCMake/CTestCommandLine/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CTestCommandLine/RunCMakeTest.cmake
@@ -3,9 +3,6 @@ include(RunCTest)
set(RunCMake_TEST_TIMEOUT 60)
-unset(ENV{CTEST_PARALLEL_LEVEL})
-unset(ENV{CTEST_OUTPUT_ON_FAILURE})
-
run_cmake_command(repeat-opt-bad1
${CMAKE_CTEST_COMMAND} --repeat until-pass
)
diff --git a/Tests/RunCMake/CommandLine/C_buildsrcdir/initial-cache.txt b/Tests/RunCMake/CommandLine/C_buildsrcdir/initial-cache.txt
index adc125b..ce1cce3 100644
--- a/Tests/RunCMake/CommandLine/C_buildsrcdir/initial-cache.txt
+++ b/Tests/RunCMake/CommandLine/C_buildsrcdir/initial-cache.txt
@@ -1,3 +1,5 @@
+set(CMAKE_MINIMUM_REQUIRED_VERSION "" CACHE STRING "")
+
# Used to verify that the values match what is passed via -S and -B, and are retained in cache.
set(INITIAL_SOURCE_DIR "${CMAKE_SOURCE_DIR}" CACHE PATH "defined in initial.cmake")
set(INITIAL_BINARY_DIR "${CMAKE_BINARY_DIR}" CACHE PATH "defined in initial.cmake")
diff --git a/Tests/RunCMake/CommandLine/E_copy-t-argument-target-is-file-result.txt b/Tests/RunCMake/CommandLine/E_copy-t-argument-target-is-file-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_copy-t-argument-target-is-file-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CommandLine/E_copy-t-argument-target-is-file-stderr.txt b/Tests/RunCMake/CommandLine/E_copy-t-argument-target-is-file-stderr.txt
new file mode 100644
index 0000000..9504216
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_copy-t-argument-target-is-file-stderr.txt
@@ -0,0 +1 @@
+^Error: Target \(for copy command\).* is not a directory.$
diff --git a/Tests/RunCMake/CommandLine/RunCMakeTest.cmake b/Tests/RunCMake/CommandLine/RunCMakeTest.cmake
index 327b772..08c5a49 100644
--- a/Tests/RunCMake/CommandLine/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CommandLine/RunCMakeTest.cmake
@@ -58,6 +58,8 @@ run_cmake_command(P_fresh ${CMAKE_COMMAND} -P "${RunCMake_SOURCE_DIR}/P_fresh.cm
run_cmake_command(build-no-dir
${CMAKE_COMMAND} --build)
+run_cmake_command(build-no-dir2
+ ${CMAKE_COMMAND} --build --target=invalid)
run_cmake_command(build-no-cache
${CMAKE_COMMAND} --build ${RunCMake_SOURCE_DIR})
run_cmake_command(build-unknown-command-short
@@ -574,6 +576,12 @@ run_cmake_command(E_copy-three-source-files-target-is-file
${CMAKE_COMMAND} -E copy ${in}/f1.txt ${in}/f2.txt ${in}/f3.txt ${out}/f1.txt)
run_cmake_command(E_copy-two-good-and-one-bad-source-files-target-is-directory
${CMAKE_COMMAND} -E copy ${in}/f1.txt ${in}/not_existing_file.bad ${in}/f3.txt ${out})
+run_cmake_command(E_copy-t-argument
+ ${CMAKE_COMMAND} -E copy ${in}/f1.txt -t ${out} ${in}/f3.txt)
+run_cmake_command(E_copy-t-argument-target-is-file
+ ${CMAKE_COMMAND} -E copy ${in}/f1.txt -t ${out}/f1.txt ${in}/f3.txt)
+run_cmake_command(E_copy-t-argument-no-source-files
+ ${CMAKE_COMMAND} -E copy -t ${out})
run_cmake_command(E_copy_if_different-one-source-directory-target-is-directory
${CMAKE_COMMAND} -E copy_if_different ${in}/f1.txt ${out})
run_cmake_command(E_copy_if_different-three-source-files-target-is-directory
diff --git a/Tests/RunCMake/CommandLine/build-no-dir2-result.txt b/Tests/RunCMake/CommandLine/build-no-dir2-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/build-no-dir2-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CommandLine/build-no-dir2-stderr.txt b/Tests/RunCMake/CommandLine/build-no-dir2-stderr.txt
new file mode 100644
index 0000000..4811bea
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/build-no-dir2-stderr.txt
@@ -0,0 +1 @@
+^Usage: cmake --build <dir> +\[options\] \[-- \[native-options\]\]
diff --git a/Tests/RunCMake/GoogleTest/RunCMakeTest.cmake b/Tests/RunCMake/GoogleTest/RunCMakeTest.cmake
index 695f562..b494cef 100644
--- a/Tests/RunCMake/GoogleTest/RunCMakeTest.cmake
+++ b/Tests/RunCMake/GoogleTest/RunCMakeTest.cmake
@@ -1,5 +1,9 @@
include(RunCMake)
+# Isolate our ctest runs from external environment.
+unset(ENV{CTEST_PARALLEL_LEVEL})
+unset(ENV{CTEST_OUTPUT_ON_FAILURE})
+
if(RunCMake_GENERATOR STREQUAL "Borland Makefiles" OR
RunCMake_GENERATOR STREQUAL "Watcom WMake")
set(fs_delay 3)
diff --git a/Tests/RunCMake/RunCTest.cmake b/Tests/RunCMake/RunCTest.cmake
index 59db395..86f5b3a 100644
--- a/Tests/RunCMake/RunCTest.cmake
+++ b/Tests/RunCMake/RunCTest.cmake
@@ -1,5 +1,9 @@
include(RunCMake)
+# Isolate our ctest runs from external environment.
+unset(ENV{CTEST_PARALLEL_LEVEL})
+unset(ENV{CTEST_OUTPUT_ON_FAILURE})
+
function(run_ctest CASE_NAME)
configure_file(${RunCMake_SOURCE_DIR}/test.cmake.in
${RunCMake_BINARY_DIR}/${CASE_NAME}/test.cmake @ONLY)
diff --git a/Tests/RunCMake/ctest_environment/RunCMakeTest.cmake b/Tests/RunCMake/ctest_environment/RunCMakeTest.cmake
index 365c9e8..4716c41 100644
--- a/Tests/RunCMake/ctest_environment/RunCMakeTest.cmake
+++ b/Tests/RunCMake/ctest_environment/RunCMakeTest.cmake
@@ -1,9 +1,5 @@
include(RunCTest)
-# Isolate our ctest runs from external environment.
-unset(ENV{CTEST_PARALLEL_LEVEL})
-unset(ENV{CTEST_OUTPUT_ON_FAILURE})
-
set(CASE_SOURCE_DIR "${RunCMake_SOURCE_DIR}")
set(RunCTest_VERBOSE_FLAG "-VV")
diff --git a/Tests/RunCMake/ctest_fixtures/RunCMakeTest.cmake b/Tests/RunCMake/ctest_fixtures/RunCMakeTest.cmake
index 1754203..1c2ad89 100644
--- a/Tests/RunCMake/ctest_fixtures/RunCMakeTest.cmake
+++ b/Tests/RunCMake/ctest_fixtures/RunCMakeTest.cmake
@@ -1,9 +1,5 @@
include(RunCTest)
-# Isolate our ctest runs from external environment.
-unset(ENV{CTEST_PARALLEL_LEVEL})
-unset(ENV{CTEST_OUTPUT_ON_FAILURE})
-
function(run_ctest_test CASE_NAME)
set(CASE_CTEST_FIXTURES_ARGS "${ARGN}")
run_ctest(${CASE_NAME})
diff --git a/Tests/RunCMake/ctest_memcheck/RunCMakeTest.cmake b/Tests/RunCMake/ctest_memcheck/RunCMakeTest.cmake
index cb8f696..3f6501e 100644
--- a/Tests/RunCMake/ctest_memcheck/RunCMakeTest.cmake
+++ b/Tests/RunCMake/ctest_memcheck/RunCMakeTest.cmake
@@ -4,8 +4,6 @@ set(SITE test-site)
set(BUILDNAME test-build)
set(COVERAGE_COMMAND "")
-unset(ENV{CTEST_PARALLEL_LEVEL})
-
function(run_mc_test CASE_NAME CHECKER_COMMAND)
run_ctest(${CASE_NAME} ${ARGN})
endfunction()
diff --git a/Tests/RunCMake/ctest_test/RunCMakeTest.cmake b/Tests/RunCMake/ctest_test/RunCMakeTest.cmake
index 74ae99c..242a059 100644
--- a/Tests/RunCMake/ctest_test/RunCMakeTest.cmake
+++ b/Tests/RunCMake/ctest_test/RunCMakeTest.cmake
@@ -1,9 +1,6 @@
include(RunCTest)
set(RunCMake_TEST_TIMEOUT 60)
-unset(ENV{CTEST_PARALLEL_LEVEL})
-unset(ENV{CTEST_OUTPUT_ON_FAILURE})
-
set(CASE_CTEST_TEST_ARGS "")
set(CASE_CTEST_TEST_LOAD "")
diff --git a/Tests/RunCMake/project/CMP0048-OLD-VERSION-stderr.txt b/Tests/RunCMake/project/CMP0048-OLD-VERSION-stderr.txt
index 3a13d32..c11215a 100644
--- a/Tests/RunCMake/project/CMP0048-OLD-VERSION-stderr.txt
+++ b/Tests/RunCMake/project/CMP0048-OLD-VERSION-stderr.txt
@@ -1,4 +1,4 @@
CMake Error at CMP0048-OLD-VERSION.cmake:1 \(project\):
VERSION not allowed unless CMP0048 is set to NEW
Call Stack \(most recent call first\):
- CMakeLists.txt:3 \(include\)$
+ CMakeLists.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/project/CMP0048-OLD-stderr.txt b/Tests/RunCMake/project/CMP0048-OLD-stderr.txt
index 1fa70f8..695fb70 100644
--- a/Tests/RunCMake/project/CMP0048-OLD-stderr.txt
+++ b/Tests/RunCMake/project/CMP0048-OLD-stderr.txt
@@ -7,4 +7,4 @@
specific short-term circumstances. Projects should be ported to the NEW
behavior and not rely on setting a policy to OLD.
Call Stack \(most recent call first\):
- CMakeLists.txt:3 \(include\)$
+ CMakeLists.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/project/CMP0048-WARN-stderr.txt b/Tests/RunCMake/project/CMP0048-WARN-stderr.txt
index 6d29ad2..d9be5d3 100644
--- a/Tests/RunCMake/project/CMP0048-WARN-stderr.txt
+++ b/Tests/RunCMake/project/CMP0048-WARN-stderr.txt
@@ -8,5 +8,5 @@ CMake Warning \(dev\) at CMP0048-WARN.cmake:3 \(project\):
PROJECT_VERSION
MyProject_VERSION_TWEAK
Call Stack \(most recent call first\):
- CMakeLists.txt:3 \(include\)
+ CMakeLists.txt:[0-9]+ \(include\)
This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/project/CMakeLists.txt b/Tests/RunCMake/project/CMakeLists.txt
index 4b3de84..fdcaee9 100644
--- a/Tests/RunCMake/project/CMakeLists.txt
+++ b/Tests/RunCMake/project/CMakeLists.txt
@@ -1,3 +1,5 @@
-cmake_minimum_required(VERSION 2.8.12)
+if(NOT "x${RunCMake_TEST}" STREQUAL "xNoMinimumRequired")
+ cmake_minimum_required(VERSION 2.8.12)
+endif()
project(${RunCMake_TEST} NONE)
include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/project/LanguagesTwice-stderr.txt b/Tests/RunCMake/project/LanguagesTwice-stderr.txt
index 9c69dd0..6edca2f 100644
--- a/Tests/RunCMake/project/LanguagesTwice-stderr.txt
+++ b/Tests/RunCMake/project/LanguagesTwice-stderr.txt
@@ -1,4 +1,4 @@
CMake Error at LanguagesTwice.cmake:1 \(project\):
LANGUAGES may be specified at most once.
Call Stack \(most recent call first\):
- CMakeLists.txt:3 \(include\)$
+ CMakeLists.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/project/NoMinimumRequired-stderr.txt b/Tests/RunCMake/project/NoMinimumRequired-stderr.txt
new file mode 100644
index 0000000..83e2ac9
--- /dev/null
+++ b/Tests/RunCMake/project/NoMinimumRequired-stderr.txt
@@ -0,0 +1,5 @@
+CMake Warning \(dev\) at CMakeLists\.txt:[0-9]+ \(project\):
+ cmake_minimum_required\(\) should be called prior to this top-level project\(\)
+ call\. Please see the cmake-commands\(7\) manual for usage documentation of
+ both commands\.
+This warning is for project developers\. Use -Wno-dev to suppress it\.$
diff --git a/Tests/RunCMake/project/NoMinimumRequired.cmake b/Tests/RunCMake/project/NoMinimumRequired.cmake
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/RunCMake/project/NoMinimumRequired.cmake
diff --git a/Tests/RunCMake/project/RunCMakeTest.cmake b/Tests/RunCMake/project/RunCMakeTest.cmake
index 6d9f52f..0f3716f 100644
--- a/Tests/RunCMake/project/RunCMakeTest.cmake
+++ b/Tests/RunCMake/project/RunCMakeTest.cmake
@@ -52,3 +52,5 @@ run_cmake(CMP0048-NEW)
run_cmake(CMP0096-WARN)
run_cmake(CMP0096-OLD)
run_cmake(CMP0096-NEW)
+
+run_cmake(NoMinimumRequired)
diff --git a/Tests/RunCMake/project/VersionInvalid-stderr.txt b/Tests/RunCMake/project/VersionInvalid-stderr.txt
index 48358d1..e13a382 100644
--- a/Tests/RunCMake/project/VersionInvalid-stderr.txt
+++ b/Tests/RunCMake/project/VersionInvalid-stderr.txt
@@ -1,4 +1,4 @@
CMake Error at VersionInvalid.cmake:2 \(project\):
VERSION "NONE" format invalid.
Call Stack \(most recent call first\):
- CMakeLists.txt:3 \(include\)$
+ CMakeLists.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/project/VersionMissingLanguages-stderr.txt b/Tests/RunCMake/project/VersionMissingLanguages-stderr.txt
index 576ac69..63cbf63 100644
--- a/Tests/RunCMake/project/VersionMissingLanguages-stderr.txt
+++ b/Tests/RunCMake/project/VersionMissingLanguages-stderr.txt
@@ -2,4 +2,4 @@ CMake Error at VersionMissingLanguages.cmake:2 \(project\):
project with VERSION, DESCRIPTION or HOMEPAGE_URL must use LANGUAGES before
language names.
Call Stack \(most recent call first\):
- CMakeLists.txt:3 \(include\)$
+ CMakeLists.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/project/VersionTwice-stderr.txt b/Tests/RunCMake/project/VersionTwice-stderr.txt
index ec07ead..dc05533 100644
--- a/Tests/RunCMake/project/VersionTwice-stderr.txt
+++ b/Tests/RunCMake/project/VersionTwice-stderr.txt
@@ -1,4 +1,4 @@
CMake Error at VersionTwice.cmake:2 \(project\):
VERSION may be specified at most once.
Call Stack \(most recent call first\):
- CMakeLists.txt:3 \(include\)$
+ CMakeLists.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/project_injected/RunCMakeTest.cmake b/Tests/RunCMake/project_injected/RunCMakeTest.cmake
index ba1a003..cf63e12 100644
--- a/Tests/RunCMake/project_injected/RunCMakeTest.cmake
+++ b/Tests/RunCMake/project_injected/RunCMakeTest.cmake
@@ -1,6 +1,7 @@
include(RunCMake)
set(RunCMake_TEST_OPTIONS
+ -DCMAKE_MINIMUM_REQUIRED_VERSION:STATIC=
# Simulate a previous CMake run that used `project(... VERSION ...)`
# in a non-injected call site.
-DCMAKE_PROJECT_VERSION:STATIC=1.2.3
diff --git a/Tests/RunCMake/test_include_dirs/RunCMakeTest.cmake b/Tests/RunCMake/test_include_dirs/RunCMakeTest.cmake
index 72056ae..74795c2 100644
--- a/Tests/RunCMake/test_include_dirs/RunCMakeTest.cmake
+++ b/Tests/RunCMake/test_include_dirs/RunCMakeTest.cmake
@@ -1,5 +1,9 @@
include(RunCMake)
+# Isolate our ctest runs from external environment.
+unset(ENV{CTEST_PARALLEL_LEVEL})
+unset(ENV{CTEST_OUTPUT_ON_FAILURE})
+
function(run_TID)
# Use a single build tree for a few tests without cleaning.
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/TID-build)
diff --git a/Utilities/ClangTidyModule/CMakeLists.txt b/Utilities/ClangTidyModule/CMakeLists.txt
index 8e7b2bc..c51f43a 100644
--- a/Utilities/ClangTidyModule/CMakeLists.txt
+++ b/Utilities/ClangTidyModule/CMakeLists.txt
@@ -14,6 +14,8 @@ find_package(Clang REQUIRED)
add_library(cmake-clang-tidy-module MODULE
Module.cxx
+ OstringstreamUseCmstrcatCheck.cxx
+ OstringstreamUseCmstrcatCheck.h
UseBespokeEnumClassCheck.cxx
UseBespokeEnumClassCheck.h
UseCmstrlenCheck.cxx
diff --git a/Utilities/ClangTidyModule/Module.cxx b/Utilities/ClangTidyModule/Module.cxx
index ca9a812..7ef8e7d 100644
--- a/Utilities/ClangTidyModule/Module.cxx
+++ b/Utilities/ClangTidyModule/Module.cxx
@@ -3,6 +3,7 @@
#include <clang-tidy/ClangTidyModule.h>
#include <clang-tidy/ClangTidyModuleRegistry.h>
+#include "OstringstreamUseCmstrcatCheck.h"
#include "UseBespokeEnumClassCheck.h"
#include "UseCmstrlenCheck.h"
#include "UseCmsysFstreamCheck.h"
@@ -20,6 +21,8 @@ public:
"cmake-use-cmsys-fstream");
CheckFactories.registerCheck<UseBespokeEnumClassCheck>(
"cmake-use-bespoke-enum-class");
+ CheckFactories.registerCheck<OstringstreamUseCmstrcatCheck>(
+ "cmake-ostringstream-use-cmstrcat");
}
};
diff --git a/Utilities/ClangTidyModule/OstringstreamUseCmstrcatCheck.cxx b/Utilities/ClangTidyModule/OstringstreamUseCmstrcatCheck.cxx
new file mode 100644
index 0000000..920fdf3
--- /dev/null
+++ b/Utilities/ClangTidyModule/OstringstreamUseCmstrcatCheck.cxx
@@ -0,0 +1,52 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#include "OstringstreamUseCmstrcatCheck.h"
+
+#include <clang/AST/Type.h>
+#include <clang/ASTMatchers/ASTMatchFinder.h>
+
+namespace clang {
+namespace tidy {
+namespace cmake {
+using namespace ast_matchers;
+
+OstringstreamUseCmstrcatCheck::OstringstreamUseCmstrcatCheck(
+ StringRef Name, ClangTidyContext* Context)
+ : ClangTidyCheck(Name, Context)
+{
+}
+
+void OstringstreamUseCmstrcatCheck::registerMatchers(MatchFinder* Finder)
+{
+ Finder->addMatcher(
+ typeLoc(unless(elaboratedTypeLoc()),
+ optionally(hasParent(elaboratedTypeLoc().bind("parentType"))),
+ loc(qualType(
+ hasDeclaration(namedDecl(hasName("::std::ostringstream"))))))
+ .bind("ostringstream"),
+ this);
+}
+
+void OstringstreamUseCmstrcatCheck::check(
+ const MatchFinder::MatchResult& Result)
+{
+ const TypeLoc* ParentTypeNode =
+ Result.Nodes.getNodeAs<TypeLoc>("parentType");
+ const TypeLoc* RootNode = Result.Nodes.getNodeAs<TypeLoc>("ostringstream");
+
+ if (ParentTypeNode != nullptr) {
+ if (ParentTypeNode->getBeginLoc().isValid()) {
+ this->diag(ParentTypeNode->getBeginLoc(),
+ "use strings and cmStrCat() instead of std::ostringstream");
+ }
+
+ } else if (RootNode != nullptr) {
+ if (RootNode->getBeginLoc().isValid()) {
+ this->diag(RootNode->getBeginLoc(),
+ "use strings and cmStrCat() instead of std::ostringstream");
+ }
+ }
+}
+}
+}
+}
diff --git a/Utilities/ClangTidyModule/OstringstreamUseCmstrcatCheck.h b/Utilities/ClangTidyModule/OstringstreamUseCmstrcatCheck.h
new file mode 100644
index 0000000..ecb5616
--- /dev/null
+++ b/Utilities/ClangTidyModule/OstringstreamUseCmstrcatCheck.h
@@ -0,0 +1,21 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#pragma once
+
+#include <clang-tidy/ClangTidyCheck.h>
+#include <clang/ASTMatchers/ASTMatchFinder.h>
+
+namespace clang {
+namespace tidy {
+namespace cmake {
+class OstringstreamUseCmstrcatCheck : public ClangTidyCheck
+{
+public:
+ OstringstreamUseCmstrcatCheck(StringRef Name, ClangTidyContext* Context);
+ void registerMatchers(ast_matchers::MatchFinder* Finder) override;
+
+ void check(const ast_matchers::MatchFinder::MatchResult& Result) override;
+};
+}
+}
+}
diff --git a/Utilities/ClangTidyModule/Tests/CMakeLists.txt b/Utilities/ClangTidyModule/Tests/CMakeLists.txt
index 2fedfa1..5bf0e89 100644
--- a/Utilities/ClangTidyModule/Tests/CMakeLists.txt
+++ b/Utilities/ClangTidyModule/Tests/CMakeLists.txt
@@ -13,3 +13,4 @@ endfunction()
add_run_clang_tidy_test(cmake-use-cmstrlen)
add_run_clang_tidy_test(cmake-use-cmsys-fstream)
add_run_clang_tidy_test(cmake-use-bespoke-enum-class)
+add_run_clang_tidy_test(cmake-ostringstream-use-cmstrcat)
diff --git a/Utilities/ClangTidyModule/Tests/cmake-ostringstream-use-cmstrcat-stdout.txt b/Utilities/ClangTidyModule/Tests/cmake-ostringstream-use-cmstrcat-stdout.txt
new file mode 100644
index 0000000..1b2d6e7
--- /dev/null
+++ b/Utilities/ClangTidyModule/Tests/cmake-ostringstream-use-cmstrcat-stdout.txt
@@ -0,0 +1,6 @@
+cmake-ostringstream-use-cmstrcat.cxx:5:3: warning: use strings and cmStrCat() instead of std::ostringstream [cmake-ostringstream-use-cmstrcat]
+ std::ostringstream test;
+ ^
+cmake-ostringstream-use-cmstrcat.cxx:8:13: warning: use strings and cmStrCat() instead of std::ostringstream [cmake-ostringstream-use-cmstrcat]
+void check2(std::ostringstream& test2)
+ ^
diff --git a/Utilities/ClangTidyModule/Tests/cmake-ostringstream-use-cmstrcat.cxx b/Utilities/ClangTidyModule/Tests/cmake-ostringstream-use-cmstrcat.cxx
new file mode 100644
index 0000000..ab749a6
--- /dev/null
+++ b/Utilities/ClangTidyModule/Tests/cmake-ostringstream-use-cmstrcat.cxx
@@ -0,0 +1,10 @@
+#include <sstream>
+
+void check()
+{
+ std::ostringstream test;
+}
+
+void check2(std::ostringstream& test2)
+{
+}