summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Auxiliary/bash-completion/cmake2
-rw-r--r--Auxiliary/vim/syntax/cmake.vim1
-rw-r--r--Help/command/execute_process.rst15
-rw-r--r--Help/command/export.rst9
-rw-r--r--Help/manual/cmake-modules.7.rst1
-rw-r--r--Help/manual/cmake-packages.7.rst17
-rw-r--r--Help/manual/cmake-policies.7.rst2
-rw-r--r--Help/manual/cmake-properties.7.rst1
-rw-r--r--Help/manual/cmake-variables.7.rst1
-rw-r--r--Help/manual/cmake.1.rst57
-rw-r--r--Help/module/FindEnvModules.rst1
-rw-r--r--Help/policy/CMP0082.rst8
-rw-r--r--Help/policy/CMP0090.rst27
-rw-r--r--Help/prop_tgt/XCODE_GENERATE_SCHEME.rst39
-rw-r--r--Help/prop_tgt/XCODE_SCHEME_ADDRESS_SANITIZER.rst2
-rw-r--r--Help/prop_tgt/XCODE_SCHEME_ADDRESS_SANITIZER_USE_AFTER_RETURN.rst2
-rw-r--r--Help/prop_tgt/XCODE_SCHEME_ARGUMENTS.rst2
-rw-r--r--Help/prop_tgt/XCODE_SCHEME_DEBUG_AS_ROOT.rst2
-rw-r--r--Help/prop_tgt/XCODE_SCHEME_DISABLE_MAIN_THREAD_CHECKER.rst2
-rw-r--r--Help/prop_tgt/XCODE_SCHEME_DYNAMIC_LIBRARY_LOADS.rst2
-rw-r--r--Help/prop_tgt/XCODE_SCHEME_DYNAMIC_LINKER_API_USAGE.rst2
-rw-r--r--Help/prop_tgt/XCODE_SCHEME_ENVIRONMENT.rst2
-rw-r--r--Help/prop_tgt/XCODE_SCHEME_EXECUTABLE.rst2
-rw-r--r--Help/prop_tgt/XCODE_SCHEME_GUARD_MALLOC.rst2
-rw-r--r--Help/prop_tgt/XCODE_SCHEME_MAIN_THREAD_CHECKER_STOP.rst2
-rw-r--r--Help/prop_tgt/XCODE_SCHEME_MALLOC_GUARD_EDGES.rst2
-rw-r--r--Help/prop_tgt/XCODE_SCHEME_MALLOC_SCRIBBLE.rst2
-rw-r--r--Help/prop_tgt/XCODE_SCHEME_MALLOC_STACK.rst2
-rw-r--r--Help/prop_tgt/XCODE_SCHEME_THREAD_SANITIZER.rst2
-rw-r--r--Help/prop_tgt/XCODE_SCHEME_THREAD_SANITIZER_STOP.rst2
-rw-r--r--Help/prop_tgt/XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER.rst2
-rw-r--r--Help/prop_tgt/XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER_STOP.rst2
-rw-r--r--Help/prop_tgt/XCODE_SCHEME_ZOMBIE_OBJECTS.rst2
-rw-r--r--Help/release/dev/FindGLEW-updates.rst5
-rw-r--r--Help/release/dev/cmake--install_option.rst6
-rw-r--r--Help/release/dev/cmake-e-tar-creating-archive.rst6
-rw-r--r--Help/release/dev/cmake-e-tar-error-handling.rst8
-rw-r--r--Help/release/dev/cuda-compiler-generator-expressions.rst5
-rw-r--r--Help/release/dev/environment-modules.rst5
-rw-r--r--Help/release/dev/export-package-default-off.rst6
-rw-r--r--Help/release/dev/pkg-config-linker-flags.rst5
-rw-r--r--Help/release/dev/xcode-scheme-per-target.rst6
-rw-r--r--Help/variable/CMAKE_EXPORT_NO_PACKAGE_REGISTRY.rst9
-rw-r--r--Help/variable/CMAKE_EXPORT_PACKAGE_REGISTRY.rst15
-rw-r--r--Help/variable/CMAKE_XCODE_GENERATE_SCHEME.rst31
-rw-r--r--Help/variable/CMAKE_XCODE_SCHEME_ADDRESS_SANITIZER.rst2
-rw-r--r--Help/variable/CMAKE_XCODE_SCHEME_ADDRESS_SANITIZER_USE_AFTER_RETURN.rst2
-rw-r--r--Help/variable/CMAKE_XCODE_SCHEME_DISABLE_MAIN_THREAD_CHECKER.rst2
-rw-r--r--Help/variable/CMAKE_XCODE_SCHEME_DYNAMIC_LIBRARY_LOADS.rst2
-rw-r--r--Help/variable/CMAKE_XCODE_SCHEME_DYNAMIC_LINKER_API_USAGE.rst2
-rw-r--r--Help/variable/CMAKE_XCODE_SCHEME_GUARD_MALLOC.rst2
-rw-r--r--Help/variable/CMAKE_XCODE_SCHEME_MAIN_THREAD_CHECKER_STOP.rst2
-rw-r--r--Help/variable/CMAKE_XCODE_SCHEME_MALLOC_GUARD_EDGES.rst2
-rw-r--r--Help/variable/CMAKE_XCODE_SCHEME_MALLOC_SCRIBBLE.rst2
-rw-r--r--Help/variable/CMAKE_XCODE_SCHEME_MALLOC_STACK.rst2
-rw-r--r--Help/variable/CMAKE_XCODE_SCHEME_THREAD_SANITIZER.rst2
-rw-r--r--Help/variable/CMAKE_XCODE_SCHEME_THREAD_SANITIZER_STOP.rst2
-rw-r--r--Help/variable/CMAKE_XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER.rst2
-rw-r--r--Help/variable/CMAKE_XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER_STOP.rst2
-rw-r--r--Help/variable/CMAKE_XCODE_SCHEME_ZOMBIE_OBJECTS.rst2
-rw-r--r--Modules/CMakeCheckCompilerFlagCommonPatterns.cmake1
-rw-r--r--Modules/CMakeCompilerIdDetection.cmake2
-rw-r--r--Modules/CheckTypeSize.c.in2
-rw-r--r--Modules/ExternalProject.cmake118
-rw-r--r--Modules/FindBLAS.cmake26
-rw-r--r--Modules/FindEnvModules.cmake333
-rw-r--r--Modules/FindGLEW.cmake302
-rw-r--r--Modules/FindGTK2.cmake3
-rw-r--r--Modules/FindLua50.cmake9
-rw-r--r--Modules/FindLua51.cmake6
-rw-r--r--Modules/FindOpenAL.cmake6
-rw-r--r--Modules/FindPhysFS.cmake6
-rw-r--r--Modules/FindPkgConfig.cmake6
-rw-r--r--Modules/FindProducer.cmake12
-rw-r--r--Modules/FindPython.cmake7
-rw-r--r--Modules/FindPython/Support.cmake16
-rw-r--r--Modules/FindPython2.cmake7
-rw-r--r--Modules/FindPython3.cmake7
-rw-r--r--Modules/FindSDL.cmake3
-rw-r--r--Modules/FindSDL_sound.cmake24
-rw-r--r--Modules/Internal/FeatureTesting.cmake14
-rw-r--r--Source/CMakeLists.txt8
-rw-r--r--Source/CMakeVersion.cmake2
-rw-r--r--Source/CPack/cmCPackDebGenerator.cxx2
-rw-r--r--Source/CPack/cmCPackFreeBSDGenerator.cxx3
-rw-r--r--Source/CTest/cmCTestBuildCommand.cxx11
-rw-r--r--Source/CTest/cmCTestBuildHandler.cxx10
-rw-r--r--Source/CTest/cmCTestConfigureCommand.cxx11
-rw-r--r--Source/CTest/cmCTestCoverageCommand.cxx8
-rw-r--r--Source/CTest/cmCTestMemCheckCommand.cxx5
-rw-r--r--Source/CTest/cmCTestRunTest.cxx9
-rw-r--r--Source/CTest/cmCTestSubmitCommand.cxx45
-rw-r--r--Source/CTest/cmCTestSubmitCommand.h2
-rw-r--r--Source/CTest/cmCTestSubmitHandler.cxx8
-rw-r--r--Source/CTest/cmCTestSubmitHandler.h4
-rw-r--r--Source/CTest/cmCTestTestCommand.cxx5
-rw-r--r--Source/CTest/cmCTestUpdateCommand.cxx10
-rw-r--r--Source/CTest/cmCTestUploadCommand.cxx12
-rw-r--r--Source/CTest/cmCTestUploadCommand.h6
-rw-r--r--Source/CTest/cmCTestUploadHandler.cxx3
-rw-r--r--Source/CTest/cmCTestUploadHandler.h9
-rw-r--r--Source/cmArchiveWrite.cxx11
-rw-r--r--Source/cmCTest.cxx1121
-rw-r--r--Source/cmCTest.h258
-rw-r--r--Source/cmDepends.cxx9
-rw-r--r--Source/cmDepends.h9
-rw-r--r--Source/cmDependsC.cxx16
-rw-r--r--Source/cmExportCommand.cxx22
-rw-r--r--Source/cmExtraEclipseCDT4Generator.cxx5
-rw-r--r--Source/cmFileCopier.cxx2
-rw-r--r--Source/cmFileCopier.h4
-rw-r--r--Source/cmFileTime.cxx49
-rw-r--r--Source/cmFileTime.h130
-rw-r--r--Source/cmFileTimeCache.cxx57
-rw-r--r--Source/cmFileTimeCache.h51
-rw-r--r--Source/cmFileTimeComparison.cxx233
-rw-r--r--Source/cmFileTimeComparison.h45
-rw-r--r--Source/cmFindProgramCommand.cxx2
-rw-r--r--Source/cmGhsMultiTargetGenerator.cxx2
-rw-r--r--Source/cmGlobalGenerator.cxx18
-rw-r--r--Source/cmGlobalGhsMultiGenerator.cxx3
-rw-r--r--Source/cmGlobalNinjaGenerator.cxx2
-rw-r--r--Source/cmGlobalVisualStudioVersionedGenerator.cxx15
-rw-r--r--Source/cmGlobalXCodeGenerator.cxx61
-rw-r--r--Source/cmGlobalXCodeGenerator.h11
-rw-r--r--Source/cmLocalUnixMakefileGenerator3.cxx17
-rw-r--r--Source/cmMakefile.cxx3
-rw-r--r--Source/cmNinjaTargetGenerator.cxx2
-rw-r--r--Source/cmPolicies.h3
-rw-r--r--Source/cmQtAutoGen.cxx2
-rw-r--r--Source/cmQtAutoGenerator.cxx6
-rw-r--r--Source/cmQtAutoGenerator.h6
-rw-r--r--Source/cmQtAutoGeneratorMocUic.cxx2
-rw-r--r--Source/cmState.cxx19
-rw-r--r--Source/cmSystemTools.cxx40
-rw-r--r--Source/cmSystemTools.h15
-rw-r--r--Source/cmTarget.cxx92
-rw-r--r--Source/cm_utf8.c29
-rw-r--r--Source/cm_utf8.h4
-rw-r--r--Source/cmake.cxx43
-rw-r--r--Source/cmake.h65
-rw-r--r--Source/cmakemain.cxx125
-rw-r--r--Source/cmcmd.cxx66
-rw-r--r--Source/ctest.cxx3
-rw-r--r--Source/kwsys/SystemTools.cxx354
-rw-r--r--Source/kwsys/SystemTools.hxx.in41
-rw-r--r--Tests/CMakeLib/testRange.cxx2
-rw-r--r--Tests/CMakeLib/testUTF8.cxx104
-rw-r--r--Tests/CMakeLists.txt8
-rw-r--r--Tests/FindEnvModules/CMakeLists.txt3
-rw-r--r--Tests/FindEnvModules/EnvModules.cmake35
-rw-r--r--Tests/FindGLEW/CMakeLists.txt10
-rw-r--r--Tests/FindGLEW/Test/CMakeLists.txt18
-rw-r--r--Tests/FindGLEW/Test/main.cpp8
-rw-r--r--Tests/FindPackageTest/CMakeLists.txt20
-rw-r--r--Tests/RunCMake/CommandLine/RunCMakeTest.cmake8
-rw-r--r--Tests/RunCMake/CommandLine/dir-install-options-to-vars/cmake_install.cmake15
-rw-r--r--Tests/RunCMake/CommandLine/install-bad-dir-result.txt1
-rw-r--r--Tests/RunCMake/CommandLine/install-bad-dir-stderr.txt1
-rw-r--r--Tests/RunCMake/CommandLine/install-no-dir-result.txt1
-rw-r--r--Tests/RunCMake/CommandLine/install-no-dir-stderr.txt1
-rw-r--r--Tests/RunCMake/CommandLine/install-options-to-vars-result.txt1
-rw-r--r--Tests/RunCMake/CommandLine/install-options-to-vars-stderr.txt4
-rw-r--r--Tests/RunCMake/CommandLineTar/RunCMakeTest.cmake30
-rw-r--r--Tests/RunCMake/CommandLineTar/bad-file-result.txt1
-rw-r--r--Tests/RunCMake/CommandLineTar/bad-file-stderr.txt2
-rw-r--r--Tests/RunCMake/CommandLineTar/bad-from4-stderr.txt2
-rw-r--r--Tests/RunCMake/CommandLineTar/bad-from5-stderr.txt2
-rw-r--r--Tests/RunCMake/CommandLineTar/bad-without-action-result.txt1
-rw-r--r--Tests/RunCMake/CommandLineTar/bad-without-action-stderr.txt1
-rw-r--r--Tests/RunCMake/CommandLineTar/bad-wrong-flag-stderr.txt1
-rw-r--r--Tests/RunCMake/CommandLineTar/end-opt1-stderr.txt2
-rw-r--r--Tests/RunCMake/CommandLineTar/end-opt2-stderr.txt1
-rw-r--r--Tests/RunCMake/CommandLineTar/gnutar-gz.cmake4
-rw-r--r--Tests/RunCMake/CommandLineTar/pax.cmake4
-rw-r--r--Tests/RunCMake/CommandLineTar/test-file.txt0
-rw-r--r--Tests/RunCMake/CommandLineTar/without-files-stderr.txt1
-rw-r--r--Tests/RunCMake/FindPkgConfig/FindPkgConfig_IMPORTED_TARGET.cmake21
-rw-r--r--Tests/RunCMake/XcodeProject/XcodeSchemaProperty-check.cmake9
-rw-r--r--Tests/RunCMake/XcodeProject/XcodeSchemaProperty.cmake3
-rw-r--r--Utilities/Scripts/update-third-party.bash24
-rw-r--r--Utilities/cmzstd/CMakeLists.txt3
-rwxr-xr-xbootstrap3
183 files changed, 3025 insertions, 1842 deletions
diff --git a/Auxiliary/bash-completion/cmake b/Auxiliary/bash-completion/cmake
index 5d67b0b..8c0c5e8 100644
--- a/Auxiliary/bash-completion/cmake
+++ b/Auxiliary/bash-completion/cmake
@@ -96,7 +96,7 @@ _cmake()
_filedir
return
;;
- --build|--open)
+ --build|--install|--open)
_filedir -d
return
;;
diff --git a/Auxiliary/vim/syntax/cmake.vim b/Auxiliary/vim/syntax/cmake.vim
index 9610410..7fcdc72 100644
--- a/Auxiliary/vim/syntax/cmake.vim
+++ b/Auxiliary/vim/syntax/cmake.vim
@@ -353,6 +353,7 @@ syn keyword cmakeProperty contained
\ XCODE_EMIT_EFFECTIVE_PLATFORM_NAME
\ XCODE_EXPLICIT_FILE_TYPE
\ XCODE_FILE_ATTRIBUTES
+ \ XCODE_GENERATE_SCHEME
\ XCODE_LAST_KNOWN_FILE_TYPE
\ XCODE_PRODUCT_TYPE
\ XCODE_SCHEME_ADDRESS_SANITIZER
diff --git a/Help/command/execute_process.rst b/Help/command/execute_process.rst
index 3a56dce..2d71352 100644
--- a/Help/command/execute_process.rst
+++ b/Help/command/execute_process.rst
@@ -22,7 +22,9 @@ Execute one or more child processes.
[ERROR_STRIP_TRAILING_WHITESPACE]
[ENCODING <name>])
-Runs the given sequence of one or more commands in parallel with the standard
+Runs the given sequence of one or more commands.
+
+Commands are executed concurrently as a pipeline, with the standard
output of each process piped to the standard input of the next.
A single standard error pipe is used for all processes.
@@ -46,8 +48,9 @@ Options:
the child processes.
``TIMEOUT``
- The child processes will be terminated if they do not finish in the
- specified number of seconds (fractions are allowed).
+ After the specified number of seconds (fractions allowed), all unfinished
+ child processes will be terminated, and the ``RESULT_VARIABLE`` will be
+ set to a string mentioning the "timeout".
``RESULT_VARIABLE``
The variable will be set to contain the result of last child process.
@@ -56,9 +59,9 @@ Options:
``RESULTS_VARIABLE <variable>``
The variable will be set to contain the result of all processes as a
- :ref:`semicolon-separated list <CMake Language Lists>`, in order of the given ``COMMAND``
- arguments. Each entry will be an integer return code from the
- corresponding child or a string describing an error condition.
+ :ref:`semicolon-separated list <CMake Language Lists>`, in order of the
+ given ``COMMAND`` arguments. Each entry will be an integer return code
+ from the corresponding child or a string describing an error condition.
``OUTPUT_VARIABLE``, ``ERROR_VARIABLE``
The variable named will be set with the contents of the standard output
diff --git a/Help/command/export.rst b/Help/command/export.rst
index b255ee8..ffd60e1 100644
--- a/Help/command/export.rst
+++ b/Help/command/export.rst
@@ -62,8 +62,13 @@ registry that this command creates works only in conjunction with a
package configuration file (``<PackageName>Config.cmake``) that works with the
build tree. In some cases, for example for packaging and for system
wide installations, it is not desirable to write the user package
-registry. If the :variable:`CMAKE_EXPORT_NO_PACKAGE_REGISTRY` variable
-is enabled, the ``export(PACKAGE)`` command will do nothing.
+registry.
+
+By default the ``export(PACKAGE)`` command does nothing (see policy
+:policy:`CMP0090`) because populating the user package registry has effects
+outside the source and build trees. Set the
+:variable:`CMAKE_EXPORT_PACKAGE_REGISTRY` variable to add build directories to
+the CMake user package registry.
.. code-block:: cmake
diff --git a/Help/manual/cmake-modules.7.rst b/Help/manual/cmake-modules.7.rst
index d9b939f..fc4bfdc 100644
--- a/Help/manual/cmake-modules.7.rst
+++ b/Help/manual/cmake-modules.7.rst
@@ -125,6 +125,7 @@ They are normally called through the :command:`find_package` command.
/module/FindDCMTK
/module/FindDevIL
/module/FindDoxygen
+ /module/FindEnvModules
/module/FindEXPAT
/module/FindFLEX
/module/FindFLTK2
diff --git a/Help/manual/cmake-packages.7.rst b/Help/manual/cmake-packages.7.rst
index 876ca84..bbe742e 100644
--- a/Help/manual/cmake-packages.7.rst
+++ b/Help/manual/cmake-packages.7.rst
@@ -647,12 +647,17 @@ Disabling the Package Registry
In some cases using the Package Registries is not desirable. CMake
allows one to disable them using the following variables:
- * :variable:`CMAKE_EXPORT_NO_PACKAGE_REGISTRY` disables the
- :command:`export(PACKAGE)` command.
- * :variable:`CMAKE_FIND_PACKAGE_NO_PACKAGE_REGISTRY` disables the
- User Package Registry in all the :command:`find_package` calls.
- * :variable:`CMAKE_FIND_PACKAGE_NO_SYSTEM_PACKAGE_REGISTRY` disables
- the System Package Registry in all the :command:`find_package` calls.
+* The :command:`export(PACKAGE)` command does not populate the user
+ package registry when :policy:`CMP0090` is set to ``NEW`` unless the
+ :variable:`CMAKE_EXPORT_PACKAGE_REGISTRY` variable explicitly enables it.
+ When :policy:`CMP0090` is *not* set to ``NEW`` then
+ :command:`export(PACKAGE)` populates the user package registry unless
+ the :variable:`CMAKE_EXPORT_NO_PACKAGE_REGISTRY` variable explicitly
+ disables it.
+* :variable:`CMAKE_FIND_PACKAGE_NO_PACKAGE_REGISTRY` disables the
+ User Package Registry in all the :command:`find_package` calls.
+* :variable:`CMAKE_FIND_PACKAGE_NO_SYSTEM_PACKAGE_REGISTRY` disables
+ the System Package Registry in all the :command:`find_package` calls.
Package Registry Example
------------------------
diff --git a/Help/manual/cmake-policies.7.rst b/Help/manual/cmake-policies.7.rst
index 9470d6c..e89ea3da 100644
--- a/Help/manual/cmake-policies.7.rst
+++ b/Help/manual/cmake-policies.7.rst
@@ -57,6 +57,7 @@ Policies Introduced by CMake 3.15
.. toctree::
:maxdepth: 1
+ CMP0090: export(PACKAGE) does not populate package registry by default. </policy/CMP0090>
CMP0089: Compiler id for IBM Clang-based XL compilers is now XLClang. </policy/CMP0089>
Policies Introduced by CMake 3.14
@@ -73,6 +74,7 @@ Policies Introduced by CMake 3.14
CMP0083: Add PIE options when linking executable. </policy/CMP0083>
CMP0082: Install rules from add_subdirectory() are interleaved with those in caller. </policy/CMP0082>
+
Policies Introduced by CMake 3.13
=================================
diff --git a/Help/manual/cmake-properties.7.rst b/Help/manual/cmake-properties.7.rst
index fce5584..4d4b9ff 100644
--- a/Help/manual/cmake-properties.7.rst
+++ b/Help/manual/cmake-properties.7.rst
@@ -349,6 +349,7 @@ Properties on Targets
/prop_tgt/WINDOWS_EXPORT_ALL_SYMBOLS
/prop_tgt/XCODE_ATTRIBUTE_an-attribute
/prop_tgt/XCODE_EXPLICIT_FILE_TYPE
+ /prop_tgt/XCODE_GENERATE_SCHEME
/prop_tgt/XCODE_PRODUCT_TYPE
/prop_tgt/XCODE_SCHEME_ADDRESS_SANITIZER
/prop_tgt/XCODE_SCHEME_ADDRESS_SANITIZER_USE_AFTER_RETURN
diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst
index 6bb30cb..48d7550 100644
--- a/Help/manual/cmake-variables.7.rst
+++ b/Help/manual/cmake-variables.7.rst
@@ -159,6 +159,7 @@ Variables that Change Behavior
/variable/CMAKE_ERROR_DEPRECATED
/variable/CMAKE_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION
/variable/CMAKE_EXPORT_COMPILE_COMMANDS
+ /variable/CMAKE_EXPORT_PACKAGE_REGISTRY
/variable/CMAKE_EXPORT_NO_PACKAGE_REGISTRY
/variable/CMAKE_FIND_APPBUNDLE
/variable/CMAKE_FIND_FRAMEWORK
diff --git a/Help/manual/cmake.1.rst b/Help/manual/cmake.1.rst
index a3c7834..b67fa3a 100644
--- a/Help/manual/cmake.1.rst
+++ b/Help/manual/cmake.1.rst
@@ -16,6 +16,9 @@ Synopsis
`Build a Project`_
cmake --build <dir> [<options>] [-- <build-tool-options>]
+ `Install a Project`_
+ cmake --install <dir> [<options>]
+
`Open a Project`_
cmake --open <dir>
@@ -39,8 +42,8 @@ buildsystem generator CMake. The above `Synopsis`_ lists various actions
the tool can perform as described in sections below.
To build a software project with CMake, `Generate a Project Buildsystem`_.
-Optionally use **cmake** to `Build a Project`_ or just run the
-corresponding build tool (e.g. ``make``) directly. **cmake** can also
+Optionally use **cmake** to `Build a Project`_, `Install a Project`_ or just
+run the corresponding build tool (e.g. ``make``) directly. **cmake** can also
be used to `View Help`_.
The other actions are meant for use by software developers writing
@@ -302,6 +305,41 @@ following options:
Run ``cmake --build`` with no options for quick help.
+Install a Project
+=================
+
+CMake provides a command-line signature to install an already-generated
+project binary tree:
+
+.. code-block:: shell
+
+ cmake --install <dir> [<options>]
+
+This may be used after building a project to run installation without
+using the generated build system or the native build tool.
+The options are:
+
+``--install <dir>``
+ Project binary directory to install. This is required and must be first.
+
+``--config <cfg>``
+ For multi-configuration tools, choose configuration ``<cfg>``.
+
+``--component <comp>``
+ Component-based install. Only install component ``<comp>``.
+
+``--prefix <prefix>``
+ The installation prefix CMAKE_INSTALL_PREFIX.
+
+``--strip``
+ Strip before installing by setting CMAKE_INSTALL_DO_STRIP.
+
+``-v, --verbose``
+ Enable verbose output.
+
+ This option can be omitted if :envvar:`VERBOSE` environment variable is set.
+
+Run ``cmake --install`` with no options for quick help.
Open a Project
==============
@@ -483,6 +521,21 @@ Available commands are:
``tar [cxt][vf][zjJ] file.tar [<options>] [--] [<file>...]``
Create or extract a tar or zip archive. Options are:
+ ``c``
+ Create a new archive containing the specified files.
+ If used, the <file> argument is mandatory.
+ ``x``
+ Extract to disk from the archive.
+ ``t``
+ List archive contents to stdout.
+ ``v``
+ Produce verbose output.
+ ``z``
+ Compress the resulting archive with gzip.
+ ``j``
+ Compress the resulting archive with bzip2.
+ ``J``
+ Compress the resulting archive with XZ.
``--``
Stop interpreting options and treat all remaining arguments
as file names even if they start in ``-``.
diff --git a/Help/module/FindEnvModules.rst b/Help/module/FindEnvModules.rst
new file mode 100644
index 0000000..72c120f
--- /dev/null
+++ b/Help/module/FindEnvModules.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindEnvModules.cmake
diff --git a/Help/policy/CMP0082.rst b/Help/policy/CMP0082.rst
index 7b2ef04..8256444 100644
--- a/Help/policy/CMP0082.rst
+++ b/Help/policy/CMP0082.rst
@@ -6,9 +6,11 @@ those in caller.
CMake 3.13 and lower ran the install rules from :command:`add_subdirectory`
after all other install rules, even if :command:`add_subdirectory` was called
-before the other install rules. CMake 3.14 and later interleaves these
-:command:`add_subdirectory` install rules with the others so that they are
-run in the order they are declared.
+before the other install rules. CMake 3.14 and above prefer to interleave
+these :command:`add_subdirectory` install rules with the others so that
+they are run in the order they are declared. This policy provides
+compatibility for projects that have not been updated to expect the
+new behavior.
The ``OLD`` behavior for this policy is to run the install rules from
:command:`add_subdirectory` after the other install rules. The ``NEW``
diff --git a/Help/policy/CMP0090.rst b/Help/policy/CMP0090.rst
new file mode 100644
index 0000000..720c17c
--- /dev/null
+++ b/Help/policy/CMP0090.rst
@@ -0,0 +1,27 @@
+CMP0090
+-------
+
+:command:`export(PACKAGE)` does not populate package registry by default.
+
+In CMake 3.14 and below the :command:`export(PACKAGE)` command populated the
+user package registry by default and users needed to set the
+:variable:`CMAKE_EXPORT_NO_PACKAGE_REGISTRY` to disable it, e.g. in automated
+build and packaging environments. Since the user package registry is stored
+outside the build tree, this side effect should not be enabled by default.
+Therefore CMake 3.15 and above prefer that :command:`export(PACKAGE)` does
+nothing unless an explicit :variable:`CMAKE_EXPORT_PACKAGE_REGISTRY` variable
+is set to enable it. This policy provides compatibility with projects that
+have not been updated.
+
+The ``OLD`` behavior for this policy is for :command:`export(PACKAGE)` command
+to populate the user package registry unless
+:variable:`CMAKE_EXPORT_NO_PACKAGE_REGISTRY` is enabled.
+The ``NEW`` behavior is for :command:`export(PACKAGE)` command to do nothing
+unless the :variable:`CMAKE_EXPORT_PACKAGE_REGISTRY` is enabled.
+
+This policy was introduced in CMake version 3.15. Use the
+:command:`cmake_policy` command to set it to ``OLD`` or ``NEW`` explicitly.
+Unlike most policies, CMake version |release| does *not* warn
+when this policy is not set and simply uses ``OLD`` behavior.
+
+.. include:: DEPRECATED.txt
diff --git a/Help/prop_tgt/XCODE_GENERATE_SCHEME.rst b/Help/prop_tgt/XCODE_GENERATE_SCHEME.rst
new file mode 100644
index 0000000..a56a210
--- /dev/null
+++ b/Help/prop_tgt/XCODE_GENERATE_SCHEME.rst
@@ -0,0 +1,39 @@
+XCODE_GENERATE_SCHEME
+---------------------
+
+If enabled, the Xcode generator will generate schema files. These
+are useful to invoke analyze, archive, build-for-testing and test
+actions from the command line.
+
+This property is initialized by the value of the variable
+:variable:`CMAKE_XCODE_GENERATE_SCHEME` if it is set when a target
+is created.
+
+The following target properties overwrite the default of the
+corresponding settings on the "Diagnostic" tab for each schema file.
+Each of those is initialized by the respective ``CMAKE_`` variable
+at target creation time.
+
+- :prop_tgt:`XCODE_SCHEME_ADDRESS_SANITIZER`
+- :prop_tgt:`XCODE_SCHEME_ADDRESS_SANITIZER_USE_AFTER_RETURN`
+- :prop_tgt:`XCODE_SCHEME_DISABLE_MAIN_THREAD_CHECKER`
+- :prop_tgt:`XCODE_SCHEME_DYNAMIC_LIBRARY_LOADS`
+- :prop_tgt:`XCODE_SCHEME_DYNAMIC_LINKER_API_USAGE`
+- :prop_tgt:`XCODE_SCHEME_GUARD_MALLOC`
+- :prop_tgt:`XCODE_SCHEME_MAIN_THREAD_CHECKER_STOP`
+- :prop_tgt:`XCODE_SCHEME_MALLOC_GUARD_EDGES`
+- :prop_tgt:`XCODE_SCHEME_MALLOC_SCRIBBLE`
+- :prop_tgt:`XCODE_SCHEME_MALLOC_STACK`
+- :prop_tgt:`XCODE_SCHEME_THREAD_SANITIZER`
+- :prop_tgt:`XCODE_SCHEME_THREAD_SANITIZER_STOP`
+- :prop_tgt:`XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER`
+- :prop_tgt:`XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER_STOP`
+- :prop_tgt:`XCODE_SCHEME_ZOMBIE_OBJECTS`
+
+The following target properties will be applied on the
+"Info" and "Arguments" tab:
+
+- :prop_tgt:`XCODE_SCHEME_ARGUMENTS`
+- :prop_tgt:`XCODE_SCHEME_DEBUG_AS_ROOT`
+- :prop_tgt:`XCODE_SCHEME_ENVIRONMENT`
+- :prop_tgt:`XCODE_SCHEME_EXECUTABLE`
diff --git a/Help/prop_tgt/XCODE_SCHEME_ADDRESS_SANITIZER.rst b/Help/prop_tgt/XCODE_SCHEME_ADDRESS_SANITIZER.rst
index 694cd77..cc9bac2 100644
--- a/Help/prop_tgt/XCODE_SCHEME_ADDRESS_SANITIZER.rst
+++ b/Help/prop_tgt/XCODE_SCHEME_ADDRESS_SANITIZER.rst
@@ -8,5 +8,5 @@ This property is initialized by the value of the variable
:variable:`CMAKE_XCODE_SCHEME_ADDRESS_SANITIZER` if it is set
when a target is created.
-Please refer to the :variable:`CMAKE_XCODE_GENERATE_SCHEME` variable
+Please refer to the :prop_tgt:`XCODE_GENERATE_SCHEME` target property
documentation to see all Xcode schema related properties.
diff --git a/Help/prop_tgt/XCODE_SCHEME_ADDRESS_SANITIZER_USE_AFTER_RETURN.rst b/Help/prop_tgt/XCODE_SCHEME_ADDRESS_SANITIZER_USE_AFTER_RETURN.rst
index 2803da0..37a043a 100644
--- a/Help/prop_tgt/XCODE_SCHEME_ADDRESS_SANITIZER_USE_AFTER_RETURN.rst
+++ b/Help/prop_tgt/XCODE_SCHEME_ADDRESS_SANITIZER_USE_AFTER_RETURN.rst
@@ -8,5 +8,5 @@ This property is initialized by the value of the variable
:variable:`CMAKE_XCODE_SCHEME_ADDRESS_SANITIZER_USE_AFTER_RETURN`
if it is set when a target is created.
-Please refer to the :variable:`CMAKE_XCODE_GENERATE_SCHEME` variable
+Please refer to the :prop_tgt:`XCODE_GENERATE_SCHEME` target property
documentation to see all Xcode schema related properties.
diff --git a/Help/prop_tgt/XCODE_SCHEME_ARGUMENTS.rst b/Help/prop_tgt/XCODE_SCHEME_ARGUMENTS.rst
index 2eac4a9..1f228e3 100644
--- a/Help/prop_tgt/XCODE_SCHEME_ARGUMENTS.rst
+++ b/Help/prop_tgt/XCODE_SCHEME_ARGUMENTS.rst
@@ -6,5 +6,5 @@ section of the generated Xcode scheme.
If set to a list of arguments those will be added to the scheme.
-Please refer to the :variable:`CMAKE_XCODE_GENERATE_SCHEME` variable
+Please refer to the :prop_tgt:`XCODE_GENERATE_SCHEME` target property
documentation to see all Xcode schema related properties.
diff --git a/Help/prop_tgt/XCODE_SCHEME_DEBUG_AS_ROOT.rst b/Help/prop_tgt/XCODE_SCHEME_DEBUG_AS_ROOT.rst
index a53f836..5407e80 100644
--- a/Help/prop_tgt/XCODE_SCHEME_DEBUG_AS_ROOT.rst
+++ b/Help/prop_tgt/XCODE_SCHEME_DEBUG_AS_ROOT.rst
@@ -3,5 +3,5 @@ XCODE_SCHEME_DEBUG_AS_ROOT
Whether to debug the target as 'root'.
-Please refer to the :variable:`CMAKE_XCODE_GENERATE_SCHEME` variable
+Please refer to the :prop_tgt:`XCODE_GENERATE_SCHEME` target property
documentation to see all Xcode schema related properties.
diff --git a/Help/prop_tgt/XCODE_SCHEME_DISABLE_MAIN_THREAD_CHECKER.rst b/Help/prop_tgt/XCODE_SCHEME_DISABLE_MAIN_THREAD_CHECKER.rst
index 75fc326..1a6fcfd 100644
--- a/Help/prop_tgt/XCODE_SCHEME_DISABLE_MAIN_THREAD_CHECKER.rst
+++ b/Help/prop_tgt/XCODE_SCHEME_DISABLE_MAIN_THREAD_CHECKER.rst
@@ -8,5 +8,5 @@ This property is initialized by the value of the variable
:variable:`CMAKE_XCODE_SCHEME_DISABLE_MAIN_THREAD_CHECKER`
if it is set when a target is created.
-Please refer to the :variable:`CMAKE_XCODE_GENERATE_SCHEME` variable
+Please refer to the :prop_tgt:`XCODE_GENERATE_SCHEME` target property
documentation to see all Xcode schema related properties.
diff --git a/Help/prop_tgt/XCODE_SCHEME_DYNAMIC_LIBRARY_LOADS.rst b/Help/prop_tgt/XCODE_SCHEME_DYNAMIC_LIBRARY_LOADS.rst
index a7fab66..9224022 100644
--- a/Help/prop_tgt/XCODE_SCHEME_DYNAMIC_LIBRARY_LOADS.rst
+++ b/Help/prop_tgt/XCODE_SCHEME_DYNAMIC_LIBRARY_LOADS.rst
@@ -8,5 +8,5 @@ This property is initialized by the value of the variable
:variable:`CMAKE_XCODE_SCHEME_DYNAMIC_LIBRARY_LOADS` if it is set
when a target is created.
-Please refer to the :variable:`CMAKE_XCODE_GENERATE_SCHEME` variable
+Please refer to the :prop_tgt:`XCODE_GENERATE_SCHEME` target property
documentation to see all Xcode schema related properties.
diff --git a/Help/prop_tgt/XCODE_SCHEME_DYNAMIC_LINKER_API_USAGE.rst b/Help/prop_tgt/XCODE_SCHEME_DYNAMIC_LINKER_API_USAGE.rst
index 162fc45..203c803 100644
--- a/Help/prop_tgt/XCODE_SCHEME_DYNAMIC_LINKER_API_USAGE.rst
+++ b/Help/prop_tgt/XCODE_SCHEME_DYNAMIC_LINKER_API_USAGE.rst
@@ -8,5 +8,5 @@ This property is initialized by the value of the variable
:variable:`CMAKE_XCODE_SCHEME_DYNAMIC_LINKER_API_USAGE` if it is set
when a target is created.
-Please refer to the :variable:`CMAKE_XCODE_GENERATE_SCHEME` variable
+Please refer to the :prop_tgt:`XCODE_GENERATE_SCHEME` target property
documentation to see all Xcode schema related properties.
diff --git a/Help/prop_tgt/XCODE_SCHEME_ENVIRONMENT.rst b/Help/prop_tgt/XCODE_SCHEME_ENVIRONMENT.rst
index 1dbd6c4..c6d875e 100644
--- a/Help/prop_tgt/XCODE_SCHEME_ENVIRONMENT.rst
+++ b/Help/prop_tgt/XCODE_SCHEME_ENVIRONMENT.rst
@@ -8,5 +8,5 @@ If set to a list of environment variables and values of the form
``MYVAR=value`` those environment variables will be added to the
scheme.
-Please refer to the :variable:`CMAKE_XCODE_GENERATE_SCHEME` variable
+Please refer to the :prop_tgt:`XCODE_GENERATE_SCHEME` target property
documentation to see all Xcode schema related properties.
diff --git a/Help/prop_tgt/XCODE_SCHEME_EXECUTABLE.rst b/Help/prop_tgt/XCODE_SCHEME_EXECUTABLE.rst
index d0427e2..104841b 100644
--- a/Help/prop_tgt/XCODE_SCHEME_EXECUTABLE.rst
+++ b/Help/prop_tgt/XCODE_SCHEME_EXECUTABLE.rst
@@ -5,5 +5,5 @@ Specify path to executable in the Info section of the generated
Xcode scheme. If not set the schema generator will select the
current target if it is actually executable.
-Please refer to the :variable:`CMAKE_XCODE_GENERATE_SCHEME` variable
+Please refer to the :prop_tgt:`XCODE_GENERATE_SCHEME` target property
documentation to see all Xcode schema related properties.
diff --git a/Help/prop_tgt/XCODE_SCHEME_GUARD_MALLOC.rst b/Help/prop_tgt/XCODE_SCHEME_GUARD_MALLOC.rst
index 64e1990..c4e83da 100644
--- a/Help/prop_tgt/XCODE_SCHEME_GUARD_MALLOC.rst
+++ b/Help/prop_tgt/XCODE_SCHEME_GUARD_MALLOC.rst
@@ -8,5 +8,5 @@ This property is initialized by the value of the variable
:variable:`CMAKE_XCODE_SCHEME_GUARD_MALLOC` if it is set
when a target is created.
-Please refer to the :variable:`CMAKE_XCODE_GENERATE_SCHEME` variable
+Please refer to the :prop_tgt:`XCODE_GENERATE_SCHEME` target property
documentation to see all Xcode schema related properties.
diff --git a/Help/prop_tgt/XCODE_SCHEME_MAIN_THREAD_CHECKER_STOP.rst b/Help/prop_tgt/XCODE_SCHEME_MAIN_THREAD_CHECKER_STOP.rst
index 99c112f..73992c3 100644
--- a/Help/prop_tgt/XCODE_SCHEME_MAIN_THREAD_CHECKER_STOP.rst
+++ b/Help/prop_tgt/XCODE_SCHEME_MAIN_THREAD_CHECKER_STOP.rst
@@ -9,5 +9,5 @@ This property is initialized by the value of the variable
:variable:`CMAKE_XCODE_SCHEME_MAIN_THREAD_CHECKER_STOP` if it is set
when a target is created.
-Please refer to the :variable:`CMAKE_XCODE_GENERATE_SCHEME` variable
+Please refer to the :prop_tgt:`XCODE_GENERATE_SCHEME` target property
documentation to see all Xcode schema related properties.
diff --git a/Help/prop_tgt/XCODE_SCHEME_MALLOC_GUARD_EDGES.rst b/Help/prop_tgt/XCODE_SCHEME_MALLOC_GUARD_EDGES.rst
index ef3852a..ca761c0 100644
--- a/Help/prop_tgt/XCODE_SCHEME_MALLOC_GUARD_EDGES.rst
+++ b/Help/prop_tgt/XCODE_SCHEME_MALLOC_GUARD_EDGES.rst
@@ -8,5 +8,5 @@ This property is initialized by the value of the variable
:variable:`CMAKE_XCODE_SCHEME_MALLOC_GUARD_EDGES` if it is set
when a target is created.
-Please refer to the :variable:`CMAKE_XCODE_GENERATE_SCHEME` variable
+Please refer to the :prop_tgt:`XCODE_GENERATE_SCHEME` target property
documentation to see all Xcode schema related properties.
diff --git a/Help/prop_tgt/XCODE_SCHEME_MALLOC_SCRIBBLE.rst b/Help/prop_tgt/XCODE_SCHEME_MALLOC_SCRIBBLE.rst
index 75baba2..c5ddb95 100644
--- a/Help/prop_tgt/XCODE_SCHEME_MALLOC_SCRIBBLE.rst
+++ b/Help/prop_tgt/XCODE_SCHEME_MALLOC_SCRIBBLE.rst
@@ -8,5 +8,5 @@ This property is initialized by the value of the variable
:variable:`CMAKE_XCODE_SCHEME_MALLOC_SCRIBBLE` if it is set
when a target is created.
-Please refer to the :variable:`CMAKE_XCODE_GENERATE_SCHEME` variable
+Please refer to the :prop_tgt:`XCODE_GENERATE_SCHEME` target property
documentation to see all Xcode schema related properties.
diff --git a/Help/prop_tgt/XCODE_SCHEME_MALLOC_STACK.rst b/Help/prop_tgt/XCODE_SCHEME_MALLOC_STACK.rst
index 984022c..170f33d 100644
--- a/Help/prop_tgt/XCODE_SCHEME_MALLOC_STACK.rst
+++ b/Help/prop_tgt/XCODE_SCHEME_MALLOC_STACK.rst
@@ -8,5 +8,5 @@ This property is initialized by the value of the variable
:variable:`CMAKE_XCODE_SCHEME_MALLOC_STACK` if it is set
when a target is created.
-Please refer to the :variable:`CMAKE_XCODE_GENERATE_SCHEME` variable
+Please refer to the :prop_tgt:`XCODE_GENERATE_SCHEME` target property
documentation to see all Xcode schema related properties.
diff --git a/Help/prop_tgt/XCODE_SCHEME_THREAD_SANITIZER.rst b/Help/prop_tgt/XCODE_SCHEME_THREAD_SANITIZER.rst
index 825ac5b..bb70141 100644
--- a/Help/prop_tgt/XCODE_SCHEME_THREAD_SANITIZER.rst
+++ b/Help/prop_tgt/XCODE_SCHEME_THREAD_SANITIZER.rst
@@ -8,5 +8,5 @@ This property is initialized by the value of the variable
:variable:`CMAKE_XCODE_SCHEME_THREAD_SANITIZER` if it is set
when a target is created.
-Please refer to the :variable:`CMAKE_XCODE_GENERATE_SCHEME` variable
+Please refer to the :prop_tgt:`XCODE_GENERATE_SCHEME` target property
documentation to see all Xcode schema related properties.
diff --git a/Help/prop_tgt/XCODE_SCHEME_THREAD_SANITIZER_STOP.rst b/Help/prop_tgt/XCODE_SCHEME_THREAD_SANITIZER_STOP.rst
index 86f894e..5deadb1 100644
--- a/Help/prop_tgt/XCODE_SCHEME_THREAD_SANITIZER_STOP.rst
+++ b/Help/prop_tgt/XCODE_SCHEME_THREAD_SANITIZER_STOP.rst
@@ -8,5 +8,5 @@ This property is initialized by the value of the variable
:variable:`CMAKE_XCODE_SCHEME_THREAD_SANITIZER_STOP` if it is set
when a target is created.
-Please refer to the :variable:`CMAKE_XCODE_GENERATE_SCHEME` variable
+Please refer to the :prop_tgt:`XCODE_GENERATE_SCHEME` target property
documentation to see all Xcode schema related properties.
diff --git a/Help/prop_tgt/XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER.rst b/Help/prop_tgt/XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER.rst
index 829a62e..0cd823d 100644
--- a/Help/prop_tgt/XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER.rst
+++ b/Help/prop_tgt/XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER.rst
@@ -8,5 +8,5 @@ This property is initialized by the value of the variable
:variable:`CMAKE_XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER`
if it is set when a target is created.
-Please refer to the :variable:`CMAKE_XCODE_GENERATE_SCHEME` variable
+Please refer to the :prop_tgt:`XCODE_GENERATE_SCHEME` target property
documentation to see all Xcode schema related properties.
diff --git a/Help/prop_tgt/XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER_STOP.rst b/Help/prop_tgt/XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER_STOP.rst
index 5e382ca..d1a9bca 100644
--- a/Help/prop_tgt/XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER_STOP.rst
+++ b/Help/prop_tgt/XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER_STOP.rst
@@ -9,5 +9,5 @@ This property is initialized by the value of the variable
:variable:`CMAKE_XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER_STOP`
if it is set when a target is created.
-Please refer to the :variable:`CMAKE_XCODE_GENERATE_SCHEME` variable
+Please refer to the :prop_tgt:`XCODE_GENERATE_SCHEME` target property
documentation to see all Xcode schema related properties.
diff --git a/Help/prop_tgt/XCODE_SCHEME_ZOMBIE_OBJECTS.rst b/Help/prop_tgt/XCODE_SCHEME_ZOMBIE_OBJECTS.rst
index 80b954a..6e70e8b 100644
--- a/Help/prop_tgt/XCODE_SCHEME_ZOMBIE_OBJECTS.rst
+++ b/Help/prop_tgt/XCODE_SCHEME_ZOMBIE_OBJECTS.rst
@@ -8,5 +8,5 @@ This property is initialized by the value of the variable
:variable:`CMAKE_XCODE_SCHEME_ZOMBIE_OBJECTS` if it is set
when a target is created.
-Please refer to the :variable:`CMAKE_XCODE_GENERATE_SCHEME` variable
+Please refer to the :prop_tgt:`XCODE_GENERATE_SCHEME` target property
documentation to see all Xcode schema related properties.
diff --git a/Help/release/dev/FindGLEW-updates.rst b/Help/release/dev/FindGLEW-updates.rst
new file mode 100644
index 0000000..6487052
--- /dev/null
+++ b/Help/release/dev/FindGLEW-updates.rst
@@ -0,0 +1,5 @@
+FindGLEW-updates
+----------------
+
+* The :module:`FindGLEW` module now provides an interface more consistent
+ with what upstream GLEW provides in its own CMake package files.
diff --git a/Help/release/dev/cmake--install_option.rst b/Help/release/dev/cmake--install_option.rst
new file mode 100644
index 0000000..8e526a0
--- /dev/null
+++ b/Help/release/dev/cmake--install_option.rst
@@ -0,0 +1,6 @@
+cmake--install-option
+---------------------
+
+* A new ``--install`` option was added to :manual:`cmake(1)`.
+ This may be used after building a project to run installation without
+ using the generated build system or the native build tool.
diff --git a/Help/release/dev/cmake-e-tar-creating-archive.rst b/Help/release/dev/cmake-e-tar-creating-archive.rst
new file mode 100644
index 0000000..717855c
--- /dev/null
+++ b/Help/release/dev/cmake-e-tar-creating-archive.rst
@@ -0,0 +1,6 @@
+cmake-e-tar-creating-archive
+----------------------------
+
+* The :manual:`cmake(1)` ``-E tar`` tool now continues adding files to an
+ archive, even if some of the files aren't readable. This behavior is more
+ consistent with the classic ``tar`` tool.
diff --git a/Help/release/dev/cmake-e-tar-error-handling.rst b/Help/release/dev/cmake-e-tar-error-handling.rst
new file mode 100644
index 0000000..d1f2c72
--- /dev/null
+++ b/Help/release/dev/cmake-e-tar-error-handling.rst
@@ -0,0 +1,8 @@
+cmake-e-tar-error-handling
+--------------------------
+
+* The :manual:`cmake(1)` ``-E tar`` tool now parses all flags, and if an
+ invalid flag was provided, a warning is issued.
+* The :manual:`cmake(1)` ``-E tar`` tool now displays an error if no action
+ flag was specified, along with a list of possible actions: ``t`` (list),
+ ``c`` (create) or ``x`` (extract).
diff --git a/Help/release/dev/cuda-compiler-generator-expressions.rst b/Help/release/dev/cuda-compiler-generator-expressions.rst
new file mode 100644
index 0000000..2610a39
--- /dev/null
+++ b/Help/release/dev/cuda-compiler-generator-expressions.rst
@@ -0,0 +1,5 @@
+cuda-compiler-generator-expressions
+-----------------------------------
+
+* The ``$<CUDA_COMPILER_ID:...>`` and ``$<CUDA_COMPILER_VERSION:...>``
+ :manual:`generator expressions <cmake-generator-expressions(7)>` were added.
diff --git a/Help/release/dev/environment-modules.rst b/Help/release/dev/environment-modules.rst
new file mode 100644
index 0000000..eace35d
--- /dev/null
+++ b/Help/release/dev/environment-modules.rst
@@ -0,0 +1,5 @@
+environment-modules
+-------------------
+
+* The :module:`FindEnvModules` module was added to use Lua- and TCL-based
+ environment modules in :ref:`CTest Scripts <CTest Script>`.
diff --git a/Help/release/dev/export-package-default-off.rst b/Help/release/dev/export-package-default-off.rst
new file mode 100644
index 0000000..0868c82
--- /dev/null
+++ b/Help/release/dev/export-package-default-off.rst
@@ -0,0 +1,6 @@
+export-package-default-off
+--------------------------
+
+* The :command:`export(PACKAGE)` command now does nothing unless
+ enabled via :variable:`CMAKE_EXPORT_PACKAGE_REGISTRY`.
+ See policy :policy:`CMP0090`.
diff --git a/Help/release/dev/pkg-config-linker-flags.rst b/Help/release/dev/pkg-config-linker-flags.rst
new file mode 100644
index 0000000..85c13be
--- /dev/null
+++ b/Help/release/dev/pkg-config-linker-flags.rst
@@ -0,0 +1,5 @@
+pkg-config-linker-flags
+-----------------------
+
+* The :module:`FindPkgConfig` now populates :prop_tgt:`INTERFACE_LINK_OPTIONS`
+ property of imported targets with other (non-library) linker flags.
diff --git a/Help/release/dev/xcode-scheme-per-target.rst b/Help/release/dev/xcode-scheme-per-target.rst
new file mode 100644
index 0000000..3febe79
--- /dev/null
+++ b/Help/release/dev/xcode-scheme-per-target.rst
@@ -0,0 +1,6 @@
+xcode-scheme-per-target
+-----------------------
+
+* The :generator:`Xcode` generator now supports per-target schemes.
+ See the :variable:`CMAKE_XCODE_GENERATE_SCHEME` variable and
+ :prop_tgt:`XCODE_GENERATE_SCHEME` target property.
diff --git a/Help/variable/CMAKE_EXPORT_NO_PACKAGE_REGISTRY.rst b/Help/variable/CMAKE_EXPORT_NO_PACKAGE_REGISTRY.rst
index ee109ba..768ed64 100644
--- a/Help/variable/CMAKE_EXPORT_NO_PACKAGE_REGISTRY.rst
+++ b/Help/variable/CMAKE_EXPORT_NO_PACKAGE_REGISTRY.rst
@@ -1,11 +1,16 @@
CMAKE_EXPORT_NO_PACKAGE_REGISTRY
--------------------------------
-Disable the :command:`export(PACKAGE)` command.
+Disable the :command:`export(PACKAGE)` command when :policy:`CMP0090`
+is not set to ``NEW``.
In some cases, for example for packaging and for system wide
installations, it is not desirable to write the user package registry.
-If the :variable:`CMAKE_EXPORT_NO_PACKAGE_REGISTRY` variable is enabled,
+If the ``CMAKE_EXPORT_NO_PACKAGE_REGISTRY`` variable is enabled,
the :command:`export(PACKAGE)` command will do nothing.
+If :policy:`CMP0090` is set to ``NEW`` this variable does nothing, and the
+:variable:`CMAKE_EXPORT_PACKAGE_REGISTRY` variable controls the behavior
+instead.
+
See also :ref:`Disabling the Package Registry`.
diff --git a/Help/variable/CMAKE_EXPORT_PACKAGE_REGISTRY.rst b/Help/variable/CMAKE_EXPORT_PACKAGE_REGISTRY.rst
new file mode 100644
index 0000000..3476a19
--- /dev/null
+++ b/Help/variable/CMAKE_EXPORT_PACKAGE_REGISTRY.rst
@@ -0,0 +1,15 @@
+CMAKE_EXPORT_PACKAGE_REGISTRY
+-----------------------------
+
+Enables the :command:`export(PACKAGE)` command when :policy:`CMP0090`
+is set to ``NEW``.
+
+The :command:`export(PACKAGE)` command does nothing by default. In some cases
+it is desirable to write to the user package registry, so the
+``CMAKE_EXPORT_PACKAGE_REGISTRY`` variable may be set to enable it.
+
+If :policy:`CMP0090` is *not* set to ``NEW`` this variable does nothing, and
+the :variable:`CMAKE_EXPORT_NO_PACKAGE_REGISTRY` variable controls the behavior
+instead.
+
+See also :ref:`Disabling the Package Registry`.
diff --git a/Help/variable/CMAKE_XCODE_GENERATE_SCHEME.rst b/Help/variable/CMAKE_XCODE_GENERATE_SCHEME.rst
index 707c6a0..1fb84d7 100644
--- a/Help/variable/CMAKE_XCODE_GENERATE_SCHEME.rst
+++ b/Help/variable/CMAKE_XCODE_GENERATE_SCHEME.rst
@@ -5,31 +5,6 @@ If enabled, the Xcode generator will generate schema files. These
are useful to invoke analyze, archive, build-for-testing and test
actions from the command line.
-The following target properties overwrite the default of the
-corresponding settings on the "Diagnostic" tab for each schema file.
-Each of those is initialized by the respective ``CMAKE_`` variable
-at target creation time.
-
-- :prop_tgt:`XCODE_SCHEME_ADDRESS_SANITIZER`
-- :prop_tgt:`XCODE_SCHEME_ADDRESS_SANITIZER_USE_AFTER_RETURN`
-- :prop_tgt:`XCODE_SCHEME_DISABLE_MAIN_THREAD_CHECKER`
-- :prop_tgt:`XCODE_SCHEME_DYNAMIC_LIBRARY_LOADS`
-- :prop_tgt:`XCODE_SCHEME_DYNAMIC_LINKER_API_USAGE`
-- :prop_tgt:`XCODE_SCHEME_GUARD_MALLOC`
-- :prop_tgt:`XCODE_SCHEME_MAIN_THREAD_CHECKER_STOP`
-- :prop_tgt:`XCODE_SCHEME_MALLOC_GUARD_EDGES`
-- :prop_tgt:`XCODE_SCHEME_MALLOC_SCRIBBLE`
-- :prop_tgt:`XCODE_SCHEME_MALLOC_STACK`
-- :prop_tgt:`XCODE_SCHEME_THREAD_SANITIZER`
-- :prop_tgt:`XCODE_SCHEME_THREAD_SANITIZER_STOP`
-- :prop_tgt:`XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER`
-- :prop_tgt:`XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER_STOP`
-- :prop_tgt:`XCODE_SCHEME_ZOMBIE_OBJECTS`
-
-The following target properties will be applied on the
-"Info" and "Arguments" tab:
-
-- :prop_tgt:`XCODE_SCHEME_ARGUMENTS`
-- :prop_tgt:`XCODE_SCHEME_DEBUG_AS_ROOT`
-- :prop_tgt:`XCODE_SCHEME_ENVIRONMENT`
-- :prop_tgt:`XCODE_SCHEME_EXECUTABLE`
+This variable initializes the
+:prop_tgt:`XCODE_GENERATE_SCHEME`
+target property on all targets.
diff --git a/Help/variable/CMAKE_XCODE_SCHEME_ADDRESS_SANITIZER.rst b/Help/variable/CMAKE_XCODE_SCHEME_ADDRESS_SANITIZER.rst
index 37dc0ce..b972ba5 100644
--- a/Help/variable/CMAKE_XCODE_SCHEME_ADDRESS_SANITIZER.rst
+++ b/Help/variable/CMAKE_XCODE_SCHEME_ADDRESS_SANITIZER.rst
@@ -8,5 +8,5 @@ This variable initializes the
:prop_tgt:`XCODE_SCHEME_ADDRESS_SANITIZER`
property on all targets.
-Please refer to the :variable:`CMAKE_XCODE_GENERATE_SCHEME` variable
+Please refer to the :prop_tgt:`XCODE_GENERATE_SCHEME` target property
documentation to see all Xcode schema related properties.
diff --git a/Help/variable/CMAKE_XCODE_SCHEME_ADDRESS_SANITIZER_USE_AFTER_RETURN.rst b/Help/variable/CMAKE_XCODE_SCHEME_ADDRESS_SANITIZER_USE_AFTER_RETURN.rst
index 05949c3..59eb32d 100644
--- a/Help/variable/CMAKE_XCODE_SCHEME_ADDRESS_SANITIZER_USE_AFTER_RETURN.rst
+++ b/Help/variable/CMAKE_XCODE_SCHEME_ADDRESS_SANITIZER_USE_AFTER_RETURN.rst
@@ -8,5 +8,5 @@ This variable initializes the
:prop_tgt:`XCODE_SCHEME_ADDRESS_SANITIZER_USE_AFTER_RETURN`
property on all targets.
-Please refer to the :variable:`CMAKE_XCODE_GENERATE_SCHEME` variable
+Please refer to the :prop_tgt:`XCODE_GENERATE_SCHEME` target property
documentation to see all Xcode schema related properties.
diff --git a/Help/variable/CMAKE_XCODE_SCHEME_DISABLE_MAIN_THREAD_CHECKER.rst b/Help/variable/CMAKE_XCODE_SCHEME_DISABLE_MAIN_THREAD_CHECKER.rst
index 81f4974..71bcf42 100644
--- a/Help/variable/CMAKE_XCODE_SCHEME_DISABLE_MAIN_THREAD_CHECKER.rst
+++ b/Help/variable/CMAKE_XCODE_SCHEME_DISABLE_MAIN_THREAD_CHECKER.rst
@@ -8,5 +8,5 @@ This variable initializes the
:prop_tgt:`XCODE_SCHEME_DISABLE_MAIN_THREAD_CHECKER`
property on all targets.
-Please refer to the :variable:`CMAKE_XCODE_GENERATE_SCHEME` variable
+Please refer to the :prop_tgt:`XCODE_GENERATE_SCHEME` target property
documentation to see all Xcode schema related properties.
diff --git a/Help/variable/CMAKE_XCODE_SCHEME_DYNAMIC_LIBRARY_LOADS.rst b/Help/variable/CMAKE_XCODE_SCHEME_DYNAMIC_LIBRARY_LOADS.rst
index 5e133ac..53f55e6 100644
--- a/Help/variable/CMAKE_XCODE_SCHEME_DYNAMIC_LIBRARY_LOADS.rst
+++ b/Help/variable/CMAKE_XCODE_SCHEME_DYNAMIC_LIBRARY_LOADS.rst
@@ -8,5 +8,5 @@ This variable initializes the
:prop_tgt:`XCODE_SCHEME_DYNAMIC_LIBRARY_LOADS`
property on all targets.
-Please refer to the :variable:`CMAKE_XCODE_GENERATE_SCHEME` variable
+Please refer to the :prop_tgt:`XCODE_GENERATE_SCHEME` target property
documentation to see all Xcode schema related properties.
diff --git a/Help/variable/CMAKE_XCODE_SCHEME_DYNAMIC_LINKER_API_USAGE.rst b/Help/variable/CMAKE_XCODE_SCHEME_DYNAMIC_LINKER_API_USAGE.rst
index 33162d9..784ceb6 100644
--- a/Help/variable/CMAKE_XCODE_SCHEME_DYNAMIC_LINKER_API_USAGE.rst
+++ b/Help/variable/CMAKE_XCODE_SCHEME_DYNAMIC_LINKER_API_USAGE.rst
@@ -8,5 +8,5 @@ This variable initializes the
:prop_tgt:`XCODE_SCHEME_DYNAMIC_LINKER_API_USAGE`
property on all targets.
-Please refer to the :variable:`CMAKE_XCODE_GENERATE_SCHEME` variable
+Please refer to the :prop_tgt:`XCODE_GENERATE_SCHEME` target property
documentation to see all Xcode schema related properties.
diff --git a/Help/variable/CMAKE_XCODE_SCHEME_GUARD_MALLOC.rst b/Help/variable/CMAKE_XCODE_SCHEME_GUARD_MALLOC.rst
index 03d88c2..9350244 100644
--- a/Help/variable/CMAKE_XCODE_SCHEME_GUARD_MALLOC.rst
+++ b/Help/variable/CMAKE_XCODE_SCHEME_GUARD_MALLOC.rst
@@ -8,5 +8,5 @@ This variable initializes the
:prop_tgt:`XCODE_SCHEME_GUARD_MALLOC`
property on all targets.
-Please refer to the :variable:`CMAKE_XCODE_GENERATE_SCHEME` variable
+Please refer to the :prop_tgt:`XCODE_GENERATE_SCHEME` target property
documentation to see all Xcode schema related properties.
diff --git a/Help/variable/CMAKE_XCODE_SCHEME_MAIN_THREAD_CHECKER_STOP.rst b/Help/variable/CMAKE_XCODE_SCHEME_MAIN_THREAD_CHECKER_STOP.rst
index fd6135f..45a2dad 100644
--- a/Help/variable/CMAKE_XCODE_SCHEME_MAIN_THREAD_CHECKER_STOP.rst
+++ b/Help/variable/CMAKE_XCODE_SCHEME_MAIN_THREAD_CHECKER_STOP.rst
@@ -9,5 +9,5 @@ This variable initializes the
:prop_tgt:`XCODE_SCHEME_MAIN_THREAD_CHECKER_STOP`
property on all targets.
-Please refer to the :variable:`CMAKE_XCODE_GENERATE_SCHEME` variable
+Please refer to the :prop_tgt:`XCODE_GENERATE_SCHEME` target property
documentation to see all Xcode schema related properties.
diff --git a/Help/variable/CMAKE_XCODE_SCHEME_MALLOC_GUARD_EDGES.rst b/Help/variable/CMAKE_XCODE_SCHEME_MALLOC_GUARD_EDGES.rst
index 8fedc20..94d1c61 100644
--- a/Help/variable/CMAKE_XCODE_SCHEME_MALLOC_GUARD_EDGES.rst
+++ b/Help/variable/CMAKE_XCODE_SCHEME_MALLOC_GUARD_EDGES.rst
@@ -8,5 +8,5 @@ This variable initializes the
:prop_tgt:`XCODE_SCHEME_MALLOC_GUARD_EDGES`
property on all targets.
-Please refer to the :variable:`CMAKE_XCODE_GENERATE_SCHEME` variable
+Please refer to the :prop_tgt:`XCODE_GENERATE_SCHEME` target property
documentation to see all Xcode schema related properties.
diff --git a/Help/variable/CMAKE_XCODE_SCHEME_MALLOC_SCRIBBLE.rst b/Help/variable/CMAKE_XCODE_SCHEME_MALLOC_SCRIBBLE.rst
index cddca7c..9bf0eb4 100644
--- a/Help/variable/CMAKE_XCODE_SCHEME_MALLOC_SCRIBBLE.rst
+++ b/Help/variable/CMAKE_XCODE_SCHEME_MALLOC_SCRIBBLE.rst
@@ -8,5 +8,5 @@ This variable initializes the
:prop_tgt:`XCODE_SCHEME_MALLOC_SCRIBBLE`
property on all targets.
-Please refer to the :variable:`CMAKE_XCODE_GENERATE_SCHEME` variable
+Please refer to the :prop_tgt:`XCODE_GENERATE_SCHEME` target property
documentation to see all Xcode schema related properties.
diff --git a/Help/variable/CMAKE_XCODE_SCHEME_MALLOC_STACK.rst b/Help/variable/CMAKE_XCODE_SCHEME_MALLOC_STACK.rst
index 9c83698..4cc21ee 100644
--- a/Help/variable/CMAKE_XCODE_SCHEME_MALLOC_STACK.rst
+++ b/Help/variable/CMAKE_XCODE_SCHEME_MALLOC_STACK.rst
@@ -8,5 +8,5 @@ This variable initializes the
:prop_tgt:`XCODE_SCHEME_MALLOC_STACK`
property on all targets.
-Please refer to the :variable:`CMAKE_XCODE_GENERATE_SCHEME` variable
+Please refer to the :prop_tgt:`XCODE_GENERATE_SCHEME` target property
documentation to see all Xcode schema related properties.
diff --git a/Help/variable/CMAKE_XCODE_SCHEME_THREAD_SANITIZER.rst b/Help/variable/CMAKE_XCODE_SCHEME_THREAD_SANITIZER.rst
index c937369..6d1b56e 100644
--- a/Help/variable/CMAKE_XCODE_SCHEME_THREAD_SANITIZER.rst
+++ b/Help/variable/CMAKE_XCODE_SCHEME_THREAD_SANITIZER.rst
@@ -8,5 +8,5 @@ This variable initializes the
:prop_tgt:`XCODE_SCHEME_THREAD_SANITIZER`
property on all targets.
-Please refer to the :variable:`CMAKE_XCODE_GENERATE_SCHEME` variable
+Please refer to the :prop_tgt:`XCODE_GENERATE_SCHEME` target property
documentation to see all Xcode schema related properties.
diff --git a/Help/variable/CMAKE_XCODE_SCHEME_THREAD_SANITIZER_STOP.rst b/Help/variable/CMAKE_XCODE_SCHEME_THREAD_SANITIZER_STOP.rst
index eed796c..de40478 100644
--- a/Help/variable/CMAKE_XCODE_SCHEME_THREAD_SANITIZER_STOP.rst
+++ b/Help/variable/CMAKE_XCODE_SCHEME_THREAD_SANITIZER_STOP.rst
@@ -8,5 +8,5 @@ This variable initializes the
:prop_tgt:`XCODE_SCHEME_THREAD_SANITIZER_STOP`
property on all targets.
-Please refer to the :variable:`CMAKE_XCODE_GENERATE_SCHEME` variable
+Please refer to the :prop_tgt:`XCODE_GENERATE_SCHEME` target property
documentation to see all Xcode schema related properties.
diff --git a/Help/variable/CMAKE_XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER.rst b/Help/variable/CMAKE_XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER.rst
index d14ba3f..ec5df66 100644
--- a/Help/variable/CMAKE_XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER.rst
+++ b/Help/variable/CMAKE_XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER.rst
@@ -8,5 +8,5 @@ This variable initializes the
:prop_tgt:`XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER`
property on all targets.
-Please refer to the :variable:`CMAKE_XCODE_GENERATE_SCHEME` variable
+Please refer to the :prop_tgt:`XCODE_GENERATE_SCHEME` target property
documentation to see all Xcode schema related properties.
diff --git a/Help/variable/CMAKE_XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER_STOP.rst b/Help/variable/CMAKE_XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER_STOP.rst
index f8df304..dcec9b0 100644
--- a/Help/variable/CMAKE_XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER_STOP.rst
+++ b/Help/variable/CMAKE_XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER_STOP.rst
@@ -9,5 +9,5 @@ This variable initializes the
:prop_tgt:`XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER_STOP`
property on all targets.
-Please refer to the :variable:`CMAKE_XCODE_GENERATE_SCHEME` variable
+Please refer to the :prop_tgt:`XCODE_GENERATE_SCHEME` target property
documentation to see all Xcode schema related properties.
diff --git a/Help/variable/CMAKE_XCODE_SCHEME_ZOMBIE_OBJECTS.rst b/Help/variable/CMAKE_XCODE_SCHEME_ZOMBIE_OBJECTS.rst
index efc331a..82e9d76 100644
--- a/Help/variable/CMAKE_XCODE_SCHEME_ZOMBIE_OBJECTS.rst
+++ b/Help/variable/CMAKE_XCODE_SCHEME_ZOMBIE_OBJECTS.rst
@@ -8,5 +8,5 @@ This variable initializes the
:prop_tgt:`XCODE_SCHEME_ZOMBIE_OBJECTS`
property on all targets.
-Please refer to the :variable:`CMAKE_XCODE_GENERATE_SCHEME` variable
+Please refer to the :prop_tgt:`XCODE_GENERATE_SCHEME` target property
documentation to see all Xcode schema related properties.
diff --git a/Modules/CMakeCheckCompilerFlagCommonPatterns.cmake b/Modules/CMakeCheckCompilerFlagCommonPatterns.cmake
index e60ffe0..5b9ed34 100644
--- a/Modules/CMakeCheckCompilerFlagCommonPatterns.cmake
+++ b/Modules/CMakeCheckCompilerFlagCommonPatterns.cmake
@@ -30,5 +30,6 @@ macro (CHECK_COMPILER_FLAG_COMMON_PATTERNS _VAR)
FAIL_REGEX "Incorrect command line option:" # Borland
FAIL_REGEX "Warning: illegal option" # SunStudio 12
FAIL_REGEX "[Ww]arning: Invalid suboption" # Fujitsu
+ FAIL_REGEX "An invalid option .* appears on the command line" # Cray
)
endmacro ()
diff --git a/Modules/CMakeCompilerIdDetection.cmake b/Modules/CMakeCompilerIdDetection.cmake
index 7aac846..ed288f5 100644
--- a/Modules/CMakeCompilerIdDetection.cmake
+++ b/Modules/CMakeCompilerIdDetection.cmake
@@ -74,13 +74,13 @@ function(compiler_id_detection outvar lang)
endif()
list(APPEND ordered_compilers
SCO
+ ARMCC
AppleClang
Clang
GNU
MSVC
ADSP
IAR
- ARMCC
)
if (lang STREQUAL C)
list(APPEND ordered_compilers
diff --git a/Modules/CheckTypeSize.c.in b/Modules/CheckTypeSize.c.in
index 2303c4e..82035a3 100644
--- a/Modules/CheckTypeSize.c.in
+++ b/Modules/CheckTypeSize.c.in
@@ -18,7 +18,7 @@
#endif
#define SIZE (sizeof(@type@))
-char info_size[] = {'I', 'N', 'F', 'O', ':', 's','i','z','e','[',
+static char info_size[] = {'I', 'N', 'F', 'O', ':', 's','i','z','e','[',
('0' + ((SIZE / 10000)%10)),
('0' + ((SIZE / 1000)%10)),
('0' + ((SIZE / 100)%10)),
diff --git a/Modules/ExternalProject.cmake b/Modules/ExternalProject.cmake
index 22e0523..948b921 100644
--- a/Modules/ExternalProject.cmake
+++ b/Modules/ExternalProject.cmake
@@ -251,6 +251,9 @@ External Project Definition
The lack of such deterministic behavior makes the main project lose
traceability and repeatability.
+ If ``GIT_SHALLOW`` is enabled then ``GIT_TAG`` works only with
+ branch names and tags. A commit hash is not allowed.
+
``GIT_REMOTE_NAME <name>``
The optional name of the remote. If this option is not specified, it
defaults to ``origin``.
@@ -1053,11 +1056,6 @@ define_property(DIRECTORY PROPERTY "EP_UPDATE_DISCONNECTED" INHERITED
)
function(_ep_write_gitclone_script script_filename source_dir git_EXECUTABLE git_repository git_tag git_remote_name git_submodules git_shallow git_progress git_config src_name work_dir gitclone_infofile gitclone_stampfile tls_verify)
- if(NOT GIT_VERSION_STRING VERSION_LESS 1.7.10)
- set(git_clone_shallow_options "--depth 1 --no-single-branch")
- else()
- set(git_clone_shallow_options "--depth 1")
- endif()
if(NOT GIT_VERSION_STRING VERSION_LESS 1.8.5)
# Use `git checkout <tree-ish> --` to avoid ambiguity with a local path.
set(git_checkout_explicit-- "--")
@@ -1067,18 +1065,41 @@ function(_ep_write_gitclone_script script_filename source_dir git_EXECUTABLE git
# because that will not search for remote branch names, a common use case.
set(git_checkout_explicit-- "")
endif()
- file(WRITE ${script_filename}
-"if(\"${git_tag}\" STREQUAL \"\")
- message(FATAL_ERROR \"Tag for git checkout should not be empty.\")
-endif()
+ if("${git_tag}" STREQUAL "")
+ message(FATAL_ERROR "Tag for git checkout should not be empty.")
+ endif()
+
+ set(git_clone_options)
+ if(git_shallow)
+ if(NOT GIT_VERSION_STRING VERSION_LESS 1.7.10)
+ list(APPEND git_clone_options "--depth 1 --no-single-branch")
+ else()
+ list(APPEND git_clone_options "--depth 1")
+ endif()
+ endif()
+ if(git_progress)
+ list(APPEND git_clone_options --progress)
+ endif()
+ foreach(config IN LISTS git_config)
+ list(APPEND git_clone_options --config ${config})
+ endforeach()
+ if(NOT ${git_remote_name} STREQUAL "origin")
+ list(APPEND git_clone_options --origin \"${git_remote_name}\")
+ endif()
-set(run 0)
+ string (REPLACE ";" " " git_clone_options "${git_clone_options}")
-if(\"${gitclone_infofile}\" IS_NEWER_THAN \"${gitclone_stampfile}\")
- set(run 1)
-endif()
+ set(git_options)
+ # disable cert checking if explicitly told not to do it
+ if(NOT "x${tls_verify}" STREQUAL "x" AND NOT tls_verify)
+ set(git_options
+ -c http.sslVerify=false)
+ endif()
+ string (REPLACE ";" " " git_options "${git_options}")
-if(NOT run)
+ file(WRITE ${script_filename}
+"
+if(NOT \"${gitclone_infofile}\" IS_NEWER_THAN \"${gitclone_stampfile}\")
message(STATUS \"Avoiding repeated git clone, stamp file is up to date: '${gitclone_stampfile}'\")
return()
endif()
@@ -1091,38 +1112,12 @@ if(error_code)
message(FATAL_ERROR \"Failed to remove directory: '${source_dir}'\")
endif()
-set(git_options)
-
-# disable cert checking if explicitly told not to do it
-set(tls_verify \"${tls_verify}\")
-if(NOT \"x${tls_verify}\" STREQUAL \"x\" AND NOT tls_verify)
- list(APPEND git_options
- -c http.sslVerify=false)
-endif()
-
-set(git_clone_options)
-
-set(git_shallow \"${git_shallow}\")
-if(git_shallow)
- list(APPEND git_clone_options ${git_clone_shallow_options})
-endif()
-
-set(git_progress \"${git_progress}\")
-if(git_progress)
- list(APPEND git_clone_options --progress)
-endif()
-
-set(git_config \"${git_config}\")
-foreach(config IN LISTS git_config)
- list(APPEND git_clone_options --config \${config})
-endforeach()
-
# try the clone 3 times in case there is an odd git clone issue
set(error_code 1)
set(number_of_tries 0)
while(error_code AND number_of_tries LESS 3)
execute_process(
- COMMAND \"${git_EXECUTABLE}\" \${git_options} clone \${git_clone_options} --origin \"${git_remote_name}\" \"${git_repository}\" \"${src_name}\"
+ COMMAND \"${git_EXECUTABLE}\" ${git_options} clone ${git_clone_options} \"${git_repository}\" \"${src_name}\"
WORKING_DIRECTORY \"${work_dir}\"
RESULT_VARIABLE error_code
)
@@ -1137,7 +1132,7 @@ if(error_code)
endif()
execute_process(
- COMMAND \"${git_EXECUTABLE}\" \${git_options} checkout ${git_tag} ${git_checkout_explicit--}
+ COMMAND \"${git_EXECUTABLE}\" ${git_options} checkout ${git_tag} ${git_checkout_explicit--}
WORKING_DIRECTORY \"${work_dir}/${src_name}\"
RESULT_VARIABLE error_code
)
@@ -1146,16 +1141,7 @@ if(error_code)
endif()
execute_process(
- COMMAND \"${git_EXECUTABLE}\" \${git_options} submodule init ${git_submodules}
- WORKING_DIRECTORY \"${work_dir}/${src_name}\"
- RESULT_VARIABLE error_code
- )
-if(error_code)
- message(FATAL_ERROR \"Failed to init submodules in: '${work_dir}/${src_name}'\")
-endif()
-
-execute_process(
- COMMAND \"${git_EXECUTABLE}\" \${git_options} submodule update --recursive --init ${git_submodules}
+ COMMAND \"${git_EXECUTABLE}\" ${git_options} submodule update --recursive --init ${git_submodules}
WORKING_DIRECTORY \"${work_dir}/${src_name}\"
RESULT_VARIABLE error_code
)
@@ -1169,7 +1155,6 @@ execute_process(
COMMAND \${CMAKE_COMMAND} -E copy
\"${gitclone_infofile}\"
\"${gitclone_stampfile}\"
- WORKING_DIRECTORY \"${work_dir}/${src_name}\"
RESULT_VARIABLE error_code
)
if(error_code)
@@ -1182,18 +1167,12 @@ endif()
endfunction()
function(_ep_write_hgclone_script script_filename source_dir hg_EXECUTABLE hg_repository hg_tag src_name work_dir hgclone_infofile hgclone_stampfile)
+ if("${hg_tag}" STREQUAL "")
+ message(FATAL_ERROR "Tag for hg checkout should not be empty.")
+ endif()
file(WRITE ${script_filename}
-"if(\"${hg_tag}\" STREQUAL \"\")
- message(FATAL_ERROR \"Tag for hg checkout should not be empty.\")
-endif()
-
-set(run 0)
-
-if(\"${hgclone_infofile}\" IS_NEWER_THAN \"${hgclone_stampfile}\")
- set(run 1)
-endif()
-
-if(NOT run)
+"
+if(NOT \"${hgclone_infofile}\" IS_NEWER_THAN \"${hgclone_stampfile}\")
message(STATUS \"Avoiding repeated hg clone, stamp file is up to date: '${hgclone_stampfile}'\")
return()
endif()
@@ -1230,7 +1209,6 @@ execute_process(
COMMAND \${CMAKE_COMMAND} -E copy
\"${hgclone_infofile}\"
\"${hgclone_stampfile}\"
- WORKING_DIRECTORY \"${work_dir}/${src_name}\"
RESULT_VARIABLE error_code
)
if(error_code)
@@ -1244,16 +1222,16 @@ endfunction()
function(_ep_write_gitupdate_script script_filename git_EXECUTABLE git_tag git_remote_name git_submodules git_repository work_dir)
+ if("${git_tag}" STREQUAL "")
+ message(FATAL_ERROR "Tag for git checkout should not be empty.")
+ endif()
if(NOT GIT_VERSION_STRING VERSION_LESS 1.7.6)
set(git_stash_save_options --all --quiet)
else()
set(git_stash_save_options --quiet)
endif()
file(WRITE ${script_filename}
-"if(\"${git_tag}\" STREQUAL \"\")
- message(FATAL_ERROR \"Tag for git checkout should not be empty.\")
-endif()
-
+"
execute_process(
COMMAND \"${git_EXECUTABLE}\" rev-list --max-count=1 HEAD
WORKING_DIRECTORY \"${work_dir}\"
@@ -2460,7 +2438,7 @@ function(_ep_add_download_command name)
#
set(repository ${git_repository})
set(module)
- set(tag)
+ set(tag ${git_remote_name})
configure_file(
"${CMAKE_ROOT}/Modules/RepositoryInfo.txt.in"
"${stamp_dir}/${name}-gitinfo.txt"
diff --git a/Modules/FindBLAS.cmake b/Modules/FindBLAS.cmake
index 0aa4f50..bfa449f 100644
--- a/Modules/FindBLAS.cmake
+++ b/Modules/FindBLAS.cmake
@@ -83,6 +83,13 @@ This module defines the following variables:
set(BLA_VENDOR Intel10_64lp)
find_package(BLAS)
+
+Hints
+^^^^^
+
+Set ``MKLROOT`` environment variable to a directory that contains an MKL
+installation.
+
#]=======================================================================]
include(${CMAKE_CURRENT_LIST_DIR}/CheckFunctionExists.cmake)
@@ -394,6 +401,24 @@ if (BLA_VENDOR MATCHES "Intel" OR BLA_VENDOR STREQUAL "All")
endif ()
endif ()
+ if (DEFINED ENV{MKLROOT})
+ set(_BLAS_MKLROOT_LIB_DIR "$ENV{MKLROOT}")
+ endif ()
+ if (_BLAS_MKLROOT_LIB_DIR)
+ if( SIZEOF_INTEGER EQUAL 8 )
+ set( _BLAS_MKL_PATH_PREFIX "intel64" )
+ else()
+ set( _BLAS_MKL_PATH_PREFIX "ia32" )
+ endif()
+ if (WIN32)
+ string(APPEND _BLAS_MKLROOT_LIB_DIR "/lib/${_BLAS_MKL_PATH_PREFIX}_win")
+ elseif (APPLE)
+ string(APPEND _BLAS_MKLROOT_LIB_DIR "/lib/${_BLAS_MKL_PATH_PREFIX}_mac")
+ else ()
+ string(APPEND _BLAS_MKLROOT_LIB_DIR "/lib/${_BLAS_MKL_PATH_PREFIX}_lin")
+ endif ()
+ endif ()
+
foreach (IT ${BLAS_SEARCH_LIBS})
string(REPLACE " " ";" SEARCH_LIBS ${IT})
if (NOT ${_LIBRARIES})
@@ -404,6 +429,7 @@ if (BLA_VENDOR MATCHES "Intel" OR BLA_VENDOR STREQUAL "All")
""
"${SEARCH_LIBS}"
"${CMAKE_THREAD_LIBS_INIT};${BLAS_mkl_LM};${BLAS_mkl_LDL}"
+ "${_BLAS_MKLROOT_LIB_DIR}"
)
endif ()
endforeach ()
diff --git a/Modules/FindEnvModules.cmake b/Modules/FindEnvModules.cmake
new file mode 100644
index 0000000..5d3452d
--- /dev/null
+++ b/Modules/FindEnvModules.cmake
@@ -0,0 +1,333 @@
+# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+# file Copyright.txt or https://cmake.org/licensing for details.
+
+#[=======================================================================[.rst:
+FindEnvModules
+--------------
+
+Locate an environment module implementation and make commands available to
+CMake scripts to use them. This is compatible with both Lua-based Lmod
+and TCL-based EnvironmentModules.
+
+This module is intended for the use case of setting up the compiler and library
+environment within a :ref:`CTest Script <CTest Script>` (``ctest -S``). It can
+also be used in a :ref:`CMake Script <Script Processing Mode>` (``cmake -P``).
+
+.. note::
+
+ The loaded environment will not survive past the end of the calling process.
+ Do not use this module in project code (``CMakeLists.txt`` files) to load
+ a compiler environment; it will not be available during the build. Instead
+ load the environment manually before running CMake or using the generated
+ build system.
+
+Example Usage
+^^^^^^^^^^^^^
+
+.. code-block:: cmake
+
+ set(CTEST_BUILD_NAME "CrayLinux-CrayPE-Cray-dynamic")
+ set(CTEST_BUILD_CONFIGURATION Release)
+ set(CTEST_BUILD_FLAGS "-k -j8")
+ set(CTEST_CMAKE_GENERATOR "Unix Makefiles")
+
+ ...
+
+ find_package(EnvModules REQUIRED)
+
+ env_module(purge)
+ env_module(load modules)
+ env_module(load craype)
+ env_module(load PrgEnv-cray)
+ env_module(load craype-knl)
+ env_module(load cray-mpich)
+ env_module(load cray-libsci)
+
+ set(ENV{CRAYPE_LINK_TYPE} dynamic)
+
+ ...
+
+Result Variables
+^^^^^^^^^^^^^^^^
+
+This module will set the following variables in your project:
+
+``EnvModules_FOUND``
+ Found the a compatible environment modules framework
+
+Cache Variables
+^^^^^^^^^^^^^^^
+
+The following cache variable will be set:
+
+``EnvModules_COMMAND``
+ The low level module command to use. Currently supported are
+ implementations are the Lua based Lmod and TCL based EnvironmentModules.
+
+Environment Variables
+^^^^^^^^^^^^^^^^^^^^^
+
+``ENV{MODULESHOME}``
+ Usually set by the module environment implementation, used as a hint to
+ locate the module command to execute.
+
+Provided Functions
+^^^^^^^^^^^^^^^^^^
+
+This defines the following cmake functions for interacting with environment
+modules:
+
+.. command:: env_module
+
+ Execute an aribitrary module command:
+
+ .. code-block:: cmake
+
+ env_module(cmd arg1 ... argN)
+ env_module(
+ COMMAND cmd arg1 ... argN
+ [OUTPUT_VARIABLE <out-var>]
+ [RESULT_VARIABLE <ret-var>]
+ )
+
+ The options are:
+
+ ``cmd arg1 ... argN``
+ The module sub-command and arguments to execute as if they were
+ passed directly to the module command in your shell environment.
+
+ ``OUTPUT_VARIABLE <out-var>``
+ The standard output from executing the module command.
+
+ ``RESULT_VARIABLE <ret-var>``
+ The return code from executing the module command.
+
+.. command:: env_module_swap
+
+ Swap one module for another:
+
+ .. code-block:: cmake
+
+ env_module_swap(out_mod in_mod
+ [OUTPUT_VARIABLE <out-var>]
+ [RESULT_VARIABLE <ret-var>]
+ )
+
+ This is functionally equivalent to the ``module swap out_mod in_mod`` shell
+ command. The options are:
+
+ ``OUTPUT_VARIABLE <out-var>``
+ The standard output from executing the module command.
+
+ ``RESULT_VARIABLE <ret-var>``
+ The return code from executing the module command.
+
+.. command:: env_module_list
+
+ Retrieve the list of currently loaded modules:
+
+ .. code-block:: cmake
+
+ env_module_list(<out-var>)
+
+ This is functionally equivalent to the ``module list`` shell command.
+ The result is stored in ``<out-var>`` as a properly formatted CMake
+ :ref:`semicolon-separated list <CMake Language Lists>` variable.
+
+.. command:: env_module_avail
+
+ Retrieve the list of available modules:
+
+ .. code-block:: cmake
+
+ env_module_avail([<mod-prefix>] <out-var>)
+
+ This is functionally equivalent to the ``module avail <mod-prefix>`` shell
+ command. The result is stored in ``<out-var>`` as a properly formatted
+ CMake :ref:`semicolon-separated list <CMake Language Lists>` variable.
+
+#]=======================================================================]
+
+function(env_module)
+ if(NOT EnvModules_COMMAND)
+ message(FATAL_ERROR "Failed to process module command. EnvModules_COMMAND not found")
+ return()
+ endif()
+
+ set(options)
+ set(oneValueArgs OUTPUT_VARIABLE RESULT_VARIABLE)
+ set(multiValueArgs COMMAND)
+ cmake_parse_arguments(MOD_ARGS
+ "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGV}
+ )
+ if(NOT MOD_ARGS_COMMAND)
+ # If no explicit command argument was given, then treat the calling syntax
+ # as: module(cmd args...)
+ set(exec_cmd ${ARGV})
+ else()
+ set(exec_cmd ${MOD_ARGS_COMMAND})
+ endif()
+
+ if(MOD_ARGS_OUTPUT_VARIABLE)
+ set(err_var_args ERROR_VARIABLE err_var)
+ endif()
+
+ execute_process(
+ COMMAND mktemp -t module.cmake.XXXXXXXXXXXX
+ OUTPUT_VARIABLE tempfile_name
+ )
+ string(STRIP "${tempfile_name}" tempfile_name)
+
+ # If the $MODULESHOME/init/cmake file exists then assume that the CMake
+ # "shell" functionality exits
+ if(EXISTS "$ENV{MODULESHOME}/init/cmake")
+ execute_process(
+ COMMAND ${EnvModules_COMMAND} cmake ${exec_cmd}
+ OUTPUT_FILE ${tempfile_name}
+ ${err_var_args}
+ RESULT_VARIABLE ret_var
+ )
+
+ else() # fallback to the sh shell and manually convert to CMake
+ execute_process(
+ COMMAND ${EnvModules_COMMAND} sh ${exec_cmd}
+ OUTPUT_VARIABLE out_var
+ ${err_var_args}
+ RESULT_VARIABLE ret_var
+ )
+ endif()
+
+ # If we executed successfully then process and cleanup the temp file
+ if(ret_var EQUAL 0)
+ # No CMake shell so we need to process the sh output into CMake code
+ if(NOT EXISTS "$ENV{MODULESHOME}/init/cmake")
+ file(WRITE ${tempfile_name} "")
+ string(REPLACE "\n" ";" out_var "${out_var}")
+ foreach(sh_cmd IN LISTS out_var)
+ if(sh_cmd MATCHES "^ *unset *([^ ]*)")
+ set(cmake_cmd "unset(ENV{${CMAKE_MATCH_1}})")
+ elseif(sh_cmd MATCHES "^ *export *([^ ]*)")
+ set(cmake_cmd "set(ENV{${CMAKE_MATCH_1}} \"\${${CMAKE_MATCH_1}}\")")
+ elseif(sh_cmd MATCHES " *([^ =]*) *= *(.*)")
+ set(var_name "${CMAKE_MATCH_1}")
+ set(var_value "${CMAKE_MATCH_2}")
+ if(var_value MATCHES "^\"(.*[^\\])\"")
+ # If it's in quotes, take the value as is
+ set(var_value "${CMAKE_MATCH_1}")
+ else()
+ # Otherwise, strip trailing spaces
+ string(REGEX REPLACE "([^\\])? +$" "\\1" var_value "${var_value}")
+ endif()
+ string(REPLACE "\\ " " " var_value "${var_value}")
+ set(cmake_cmd "set(${var_name} \"${var_value}\")")
+ else()
+ continue()
+ endif()
+ file(APPEND ${tempfile_name} "${cmake_cmd}\n")
+ endforeach()
+ endif()
+
+ # Process the change in environment variables
+ include(${tempfile_name})
+ file(REMOVE ${tempfile_name})
+ endif()
+
+ # Push the output back out to the calling scope
+ if(MOD_ARGS_OUTPUT_VARIABLE)
+ set(${MOD_ARGS_OUTPUT_VARIABLE} "${err_var}" PARENT_SCOPE)
+ endif()
+ if(MOD_ARGS_RESULT_VARIABLE)
+ set(${MOD_ARGS_RESULT_VARIABLE} ${ret_var} PARENT_SCOPE)
+ endif()
+endfunction(env_module)
+
+#------------------------------------------------------------------------------
+function(env_module_swap out_mod in_mod)
+ set(options)
+ set(oneValueArgs OUTPUT_VARIABLE RESULT_VARIABLE)
+ set(multiValueArgs)
+
+ cmake_parse_arguments(MOD_ARGS
+ "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGV}
+ )
+
+ env_module(COMMAND -t swap ${out_mod} ${in_mod}
+ OUTPUT_VARIABLE tmp_out
+ RETURN_VARIABLE tmp_ret
+ )
+
+ if(MOD_ARGS_OUTPUT_VARIABLE)
+ set(${MOD_ARGS_OUTPUT_VARIABLE} "${err_var}" PARENT_SCOPE)
+ endif()
+ if(MOD_ARGS_RESULT_VARIABLE)
+ set(${MOD_ARGS_RESULT_VARIABLE} ${tmp_ret} PARENT_SCOPE)
+ endif()
+endfunction()
+
+#------------------------------------------------------------------------------
+function(env_module_list out_var)
+ cmake_policy(SET CMP0007 NEW)
+ env_module(COMMAND -t list OUTPUT_VARIABLE tmp_out)
+
+ # Convert output into a CMake list
+ string(REPLACE "\n" ";" ${out_var} "${tmp_out}")
+
+ # Remove title headers and empty entries
+ list(REMOVE_ITEM ${out_var} "No modules loaded")
+ if(${out_var})
+ list(FILTER ${out_var} EXCLUDE REGEX "^(.*:)?$")
+ endif()
+ list(FILTER ${out_var} EXCLUDE REGEX "^(.*:)?$")
+
+ set(${out_var} ${${out_var}} PARENT_SCOPE)
+endfunction()
+
+#------------------------------------------------------------------------------
+function(env_module_avail)
+ cmake_policy(SET CMP0007 NEW)
+
+ if(ARGC EQUAL 1)
+ set(mod_prefix)
+ set(out_var ${ARGV0})
+ elseif(ARGC EQUAL 2)
+ set(mod_prefix ${ARGV0})
+ set(out_var ${ARGV1})
+ else()
+ message(FATAL_ERROR "Usage: env_module_avail([mod_prefix] out_var)")
+ endif()
+ env_module(COMMAND -t avail ${mod_prefix} OUTPUT_VARIABLE tmp_out)
+
+ # Convert output into a CMake list
+ string(REPLACE "\n" ";" tmp_out "${tmp_out}")
+
+ set(${out_var})
+ foreach(MOD IN LISTS tmp_out)
+ # Remove directory entries and empty values
+ if(MOD MATCHES "^(.*:)?$")
+ continue()
+ endif()
+
+ # Convert default modules
+ if(MOD MATCHES "^(.*)/$" ) # "foo/"
+ list(APPEND ${out_var} ${CMAKE_MATCH_1})
+ elseif(MOD MATCHES "^((.*)/.*)\\(default\\)$") # "foo/1.2.3(default)"
+ list(APPEND ${out_var} ${CMAKE_MATCH_2})
+ list(APPEND ${out_var} ${CMAKE_MATCH_1})
+ else()
+ list(APPEND ${out_var} ${MOD})
+ endif()
+ endforeach()
+
+ set(${out_var} ${${out_var}} PARENT_SCOPE)
+endfunction()
+
+#------------------------------------------------------------------------------
+# Make sure we know where the underlying module command is
+find_program(EnvModules_COMMAND
+ NAMES lmod modulecmd
+ HINTS ENV MODULESHOME
+ PATH_SUFFIXES libexec
+)
+
+include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+find_package_handle_standard_args(EnvModules DEFAULT_MSG EnvModules_COMMAND)
diff --git a/Modules/FindGLEW.cmake b/Modules/FindGLEW.cmake
index ad8a810..34ee873 100644
--- a/Modules/FindGLEW.cmake
+++ b/Modules/FindGLEW.cmake
@@ -7,64 +7,300 @@ FindGLEW
Find the OpenGL Extension Wrangler Library (GLEW)
-IMPORTED Targets
+Input Variables
+^^^^^^^^^^^^^^^
+
+The following variables may be set to influence this module’s behavior:
+
+``GLEW_USE_STATIC_LIBS``
+ to find and create :prop_tgt:`IMPORTED` target for static linkage.
+
+``GLEW_VERBOSE``
+ to output a detailed log of this module.
+
+Imported Targets
^^^^^^^^^^^^^^^^
-This module defines the :prop_tgt:`IMPORTED` target ``GLEW::GLEW``,
-if GLEW has been found.
+This module defines the following :ref:`Imported Targets <Imported Targets>`:
+
+
+``GLEW::glew``
+ The GLEW shared library.
+``GLEW::glew_s``
+ The GLEW static library, if ``GLEW_USE_STATIC_LIBS`` is set to ``TRUE``.
+``GLEW::GLEW``
+ Duplicates either ``GLEW::glew`` or ``GLEW::glew_s`` based on availability.
Result Variables
^^^^^^^^^^^^^^^^
This module defines the following variables:
-::
+``GLEW_INCLUDE_DIRS``
+ include directories for GLEW
+``GLEW_LIBRARIES``
+ libraries to link against GLEW
+``GLEW_SHARED_LIBRARIES``
+ libraries to link against shared GLEW
+``GLEW_STATIC_LIBRARIES``
+ libraries to link against static GLEW
+``GLEW_FOUND``
+ true if GLEW has been found and can be used
+``GLEW_VERSION``
+ GLEW version
+``GLEW_VERSION_MAJOR``
+ GLEW major version
+``GLEW_VERSION_MINOR``
+ GLEW minor version
+``GLEW_VERSION_MICRO``
+ GLEW micro version
- GLEW_INCLUDE_DIRS - include directories for GLEW
- GLEW_LIBRARIES - libraries to link against GLEW
- GLEW_FOUND - true if GLEW has been found and can be used
#]=======================================================================]
+include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+
+find_package(GLEW CONFIG QUIET)
+
+if(GLEW_FOUND)
+ find_package_handle_standard_args(GLEW DEFAULT_MSG GLEW_CONFIG)
+ return()
+endif()
+
+if(GLEW_VERBOSE)
+ message(STATUS "FindGLEW: did not find GLEW CMake config file. Searching for libraries.")
+endif()
+
+
+function(__glew_set_find_library_suffix shared_or_static)
+ if(UNIX AND "${shared_or_static}" MATCHES "SHARED")
+ set(CMAKE_FIND_LIBRARY_SUFFIXES ".so" PARENT_SCOPE)
+ elseif(UNIX AND "${shared_or_static}" MATCHES "STATIC")
+ set(CMAKE_FIND_LIBRARY_SUFFIXES ".a" PARENT_SCOPE)
+ elseif(APPLE AND "${shared_or_static}" MATCHES "SHARED")
+ set(CMAKE_FIND_LIBRARY_SUFFIXES ".dylib;.so" PARENT_SCOPE)
+ elseif(APPLE AND "${shared_or_static}" MATCHES "STATIC")
+ set(CMAKE_FIND_LIBRARY_SUFFIXES ".a" PARENT_SCOPE)
+ elseif(WIN32 AND "${shared_or_static}" MATCHES "SHARED")
+ set(CMAKE_FIND_LIBRARY_SUFFIXES ".lib" PARENT_SCOPE)
+ elseif(WIN32 AND "${shared_or_static}" MATCHES "STATIC")
+ set(CMAKE_FIND_LIBRARY_SUFFIXES ".lib;.dll.a" PARENT_SCOPE)
+ endif()
+
+ if(GLEW_VERBOSE)
+ message(STATUS "FindGLEW: CMAKE_FIND_LIBRARY_SUFFIXES for ${shared_or_static}: ${CMAKE_FIND_LIBRARY_SUFFIXES}")
+ endif()
+endfunction()
+
+
+if(GLEW_VERBOSE)
+ if(DEFINED GLEW_USE_STATIC_LIBS)
+ message(STATUS "FindGLEW: GLEW_USE_STATIC_LIBS: ${GLEW_USE_STATIC_LIBS}.")
+ else()
+ message(STATUS "FindGLEW: GLEW_USE_STATIC_LIBS is undefined. Treated as FALSE.")
+ endif()
+endif()
+
find_path(GLEW_INCLUDE_DIR GL/glew.h)
+mark_as_advanced(GLEW_INCLUDE_DIR)
-if(NOT GLEW_LIBRARY)
- find_library(GLEW_LIBRARY_RELEASE NAMES GLEW glew32 glew glew32s PATH_SUFFIXES lib64 libx32)
- find_library(GLEW_LIBRARY_DEBUG NAMES GLEWd glew32d glewd PATH_SUFFIXES lib64)
+set(GLEW_INCLUDE_DIRS ${GLEW_INCLUDE_DIR})
- include(${CMAKE_CURRENT_LIST_DIR}/SelectLibraryConfigurations.cmake)
- select_library_configurations(GLEW)
-endif ()
+if(GLEW_VERBOSE)
+ message(STATUS "FindGLEW: GLEW_INCLUDE_DIR: ${GLEW_INCLUDE_DIR}")
+ message(STATUS "FindGLEW: GLEW_INCLUDE_DIRS: ${GLEW_INCLUDE_DIRS}")
+endif()
+
+if("${CMAKE_GENERATOR_PLATFORM}" MATCHES "x64" OR "${CMAKE_GENERATOR}" MATCHES "Win64")
+ set(_arch "x64")
+else()
+ set(_arch "Win32")
+endif()
+
+
+__glew_set_find_library_suffix(SHARED)
+
+find_library(GLEW_SHARED_LIBRARY_RELEASE
+ NAMES GLEW glew glew32
+ PATH_SUFFIXES lib lib64 libx32 lib/Release/${_arch}
+ PATHS ENV GLEW_ROOT)
+
+find_library(GLEW_SHARED_LIBRARY_DEBUG
+ NAMES GLEWd glewd glew32d
+ PATH_SUFFIXES lib lib64
+ PATHS ENV GLEW_ROOT)
+
+
+__glew_set_find_library_suffix(STATIC)
+
+find_library(GLEW_STATIC_LIBRARY_RELEASE
+ NAMES GLEW glew glew32s
+ PATH_SUFFIXES lib lib64 libx32 lib/Release/${_arch}
+ PATHS ENV GLEW_ROOT)
+
+find_library(GLEW_STATIC_LIBRARY_DEBUG
+ NAMES GLEWds glewds glew32ds
+ PATH_SUFFIXES lib lib64
+ PATHS ENV GLEW_ROOT)
+
+include(${CMAKE_CURRENT_LIST_DIR}/SelectLibraryConfigurations.cmake)
+
+select_library_configurations(GLEW_SHARED)
+select_library_configurations(GLEW_STATIC)
+
+if(NOT GLEW_USE_STATIC_LIBS)
+ set(GLEW_LIBRARIES ${GLEW_SHARED_LIBRARY})
+else()
+ set(GLEW_LIBRARIES ${GLEW_STATIC_LIBRARY})
+endif()
+
+
+if(GLEW_VERBOSE)
+ message(STATUS "FindGLEW: GLEW_SHARED_LIBRARY_RELEASE: ${GLEW_SHARED_LIBRARY_RELEASE}")
+ message(STATUS "FindGLEW: GLEW_STATIC_LIBRARY_RELEASE: ${GLEW_STATIC_LIBRARY_RELEASE}")
+ message(STATUS "FindGLEW: GLEW_SHARED_LIBRARY_DEBUG: ${GLEW_SHARED_LIBRARY_DEBUG}")
+ message(STATUS "FindGLEW: GLEW_STATIC_LIBRARY_DEBUG: ${GLEW_STATIC_LIBRARY_DEBUG}")
+ message(STATUS "FindGLEW: GLEW_SHARED_LIBRARY: ${GLEW_SHARED_LIBRARY}")
+ message(STATUS "FindGLEW: GLEW_STATIC_LIBRARY: ${GLEW_STATIC_LIBRARY}")
+ message(STATUS "FindGLEW: GLEW_LIBRARIES: ${GLEW_LIBRARIES}")
+endif()
+
+
+# Read version from GL/glew.h file
+if(EXISTS "${GLEW_INCLUDE_DIR}/GL/glew.h")
+ file(STRINGS "${GLEW_INCLUDE_DIR}/GL/glew.h" _contents REGEX "^VERSION_.+ [0-9]+")
+ if(_contents)
+ string(REGEX REPLACE ".*VERSION_MAJOR[ \t]+([0-9]+).*" "\\1" GLEW_VERSION_MAJOR "${_contents}")
+ string(REGEX REPLACE ".*VERSION_MINOR[ \t]+([0-9]+).*" "\\1" GLEW_VERSION_MINOR "${_contents}")
+ string(REGEX REPLACE ".*VERSION_MICRO[ \t]+([0-9]+).*" "\\1" GLEW_VERSION_MICRO "${_contents}")
+ set(GLEW_VERSION "${GLEW_VERSION_MAJOR}.${GLEW_VERSION_MINOR}.${GLEW_VERSION_MICRO}")
+ endif()
+endif()
+
+if(GLEW_VERBOSE)
+ message(STATUS "FindGLEW: GLEW_VERSION_MAJOR: ${GLEW_VERSION_MAJOR}")
+ message(STATUS "FindGLEW: GLEW_VERSION_MINOR: ${GLEW_VERSION_MINOR}")
+ message(STATUS "FindGLEW: GLEW_VERSION_MICRO: ${GLEW_VERSION_MICRO}")
+ message(STATUS "FindGLEW: GLEW_VERSION: ${GLEW_VERSION}")
+endif()
-include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
find_package_handle_standard_args(GLEW
- REQUIRED_VARS GLEW_INCLUDE_DIR GLEW_LIBRARY)
+ REQUIRED_VARS GLEW_INCLUDE_DIRS GLEW_LIBRARIES
+ VERSION_VAR GLEW_VERSION)
-if(GLEW_FOUND)
- set(GLEW_INCLUDE_DIRS ${GLEW_INCLUDE_DIR})
+if(NOT GLEW_FOUND)
+ if(GLEW_VERBOSE)
+ message(STATUS "FindGLEW: could not found GLEW library.")
+ endif()
+ return()
+endif()
+
+
+if(NOT TARGET GLEW::glew AND NOT GLEW_USE_STATIC_LIBS)
+ if(GLEW_VERBOSE)
+ message(STATUS "FindGLEW: Creating GLEW::glew imported target.")
+ endif()
+
+ add_library(GLEW::glew UNKNOWN IMPORTED)
+
+ set_target_properties(GLEW::glew
+ PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${GLEW_INCLUDE_DIRS}")
+
+ if(GLEW_SHARED_LIBRARY_RELEASE)
+ set_property(TARGET GLEW::glew
+ APPEND
+ PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
+
+ set_target_properties(GLEW::glew
+ PROPERTIES IMPORTED_LOCATION_RELEASE "${GLEW_SHARED_LIBRARY_RELEASE}")
+ endif()
+
+ if(GLEW_SHARED_LIBRARY_DEBUG)
+ set_property(TARGET GLEW::glew
+ APPEND
+ PROPERTY IMPORTED_CONFIGURATIONS DEBUG)
+
+ set_target_properties(GLEW::glew
+ PROPERTIES IMPORTED_LOCATION_DEBUG "${GLEW_SHARED_LIBRARY_DEBUG}")
+ endif()
- if(NOT GLEW_LIBRARIES)
- set(GLEW_LIBRARIES ${GLEW_LIBRARY})
+elseif(NOT TARGET GLEW::glew_s AND GLEW_USE_STATIC_LIBS)
+ if(GLEW_VERBOSE)
+ message(STATUS "FindGLEW: Creating GLEW::glew_s imported target.")
endif()
- if (NOT TARGET GLEW::GLEW)
- add_library(GLEW::GLEW UNKNOWN IMPORTED)
- set_target_properties(GLEW::GLEW PROPERTIES
- INTERFACE_INCLUDE_DIRECTORIES "${GLEW_INCLUDE_DIRS}")
+ add_library(GLEW::glew_s UNKNOWN IMPORTED)
- if(GLEW_LIBRARY_RELEASE)
- set_property(TARGET GLEW::GLEW APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
- set_target_properties(GLEW::GLEW PROPERTIES IMPORTED_LOCATION_RELEASE "${GLEW_LIBRARY_RELEASE}")
+ set_target_properties(GLEW::glew_s
+ PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${GLEW_INCLUDE_DIRS}")
+
+ if(GLEW_STATIC_LIBRARY_RELEASE)
+ set_property(TARGET GLEW::glew_s
+ APPEND
+ PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
+
+ set_target_properties(GLEW::glew_s
+ PROPERTIES IMPORTED_LOCATION_RELEASE "${GLEW_STATIC_LIBRARY_RELEASE}")
+ endif()
+
+ if(GLEW_STATIC_LIBRARY_DEBUG)
+ set_property(TARGET GLEW::glew_s
+ APPEND
+ PROPERTY IMPORTED_CONFIGURATIONS DEBUG)
+
+ set_target_properties(GLEW::glew_s
+ PROPERTIES IMPORTED_LOCATION_DEBUG "${GLEW_STATIC_LIBRARY_DEBUG}")
+ endif()
+endif()
+
+if(NOT TARGET GLEW::GLEW)
+ if(GLEW_VERBOSE)
+ message(STATUS "FindGLEW: Creating GLEW::GLEW imported target.")
+ endif()
+
+ add_library(GLEW::GLEW UNKNOWN IMPORTED)
+
+ set_target_properties(GLEW::GLEW
+ PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${GLEW_INCLUDE_DIRS}")
+
+ if(TARGET GLEW::glew)
+ if(GLEW_SHARED_LIBRARY_RELEASE)
+ set_property(TARGET GLEW::GLEW
+ APPEND
+ PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
+
+ set_target_properties(GLEW::GLEW
+ PROPERTIES IMPORTED_LOCATION_RELEASE "${GLEW_SHARED_LIBRARY_RELEASE}")
+ endif()
+
+ if(GLEW_SHARED_LIBRARY_DEBUG)
+ set_property(TARGET GLEW::GLEW
+ APPEND
+ PROPERTY IMPORTED_CONFIGURATIONS DEBUG)
+
+ set_target_properties(GLEW::GLEW
+ PROPERTIES IMPORTED_LOCATION_DEBUG "${GLEW_SHARED_LIBRARY_DEBUG}")
endif()
- if(GLEW_LIBRARY_DEBUG)
- set_property(TARGET GLEW::GLEW APPEND PROPERTY IMPORTED_CONFIGURATIONS DEBUG)
- set_target_properties(GLEW::GLEW PROPERTIES IMPORTED_LOCATION_DEBUG "${GLEW_LIBRARY_DEBUG}")
+ elseif(TARGET GLEW::glew_s)
+ if(GLEW_STATIC_LIBRARY_RELEASE)
+ set_property(TARGET GLEW::GLEW
+ APPEND
+ PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
+
+ set_target_properties(GLEW::GLEW
+ PROPERTIES IMPORTED_LOCATION_RELEASE "${GLEW_STATIC_LIBRARY_RELEASE}")
endif()
- if(NOT GLEW_LIBRARY_RELEASE AND NOT GLEW_LIBRARY_DEBUG)
- set_property(TARGET GLEW::GLEW APPEND PROPERTY IMPORTED_LOCATION "${GLEW_LIBRARY}")
+ if(GLEW_STATIC_LIBRARY_DEBUG AND GLEW_USE_STATIC_LIBS)
+ set_property(TARGET GLEW::GLEW
+ APPEND
+ PROPERTY IMPORTED_CONFIGURATIONS DEBUG)
+
+ set_target_properties(GLEW::GLEW
+ PROPERTIES IMPORTED_LOCATION_DEBUG "${GLEW_STATIC_LIBRARY_DEBUG}")
endif()
+
+ elseif(GLEW_VERBOSE)
+ message(WARNING "FindGLEW: no `GLEW::glew` or `GLEW::glew_s` target was created. Something went wrong in FindGLEW target creation.")
endif()
endif()
-
-mark_as_advanced(GLEW_INCLUDE_DIR)
diff --git a/Modules/FindGTK2.cmake b/Modules/FindGTK2.cmake
index 6c1897c..3bd61a9 100644
--- a/Modules/FindGTK2.cmake
+++ b/Modules/FindGTK2.cmake
@@ -303,9 +303,7 @@ function(_GTK2_FIND_INCLUDE_DIR _var _hdr)
/opt/gnome/lib
/opt/openwin/include
/usr/openwin/lib
- /sw/include
/sw/lib
- /opt/local/include
/opt/local/lib
/usr/pkg/lib
/usr/pkg/include/glib
@@ -415,7 +413,6 @@ function(_GTK2_FIND_LIBRARY _var _lib _expand_vc _append_version)
PATHS
/opt/gnome/lib
/usr/openwin/lib
- /sw/lib
$ENV{GTKMM_BASEPATH}/lib
[HKEY_CURRENT_USER\\SOFTWARE\\gtkmm\\2.4;Path]/lib
[HKEY_LOCAL_MACHINE\\SOFTWARE\\gtkmm\\2.4;Path]/lib
diff --git a/Modules/FindLua50.cmake b/Modules/FindLua50.cmake
index aafc056..52a54e7 100644
--- a/Modules/FindLua50.cmake
+++ b/Modules/FindLua50.cmake
@@ -40,9 +40,6 @@ find_path(LUA_INCLUDE_DIR lua.h
PATHS
~/Library/Frameworks
/Library/Frameworks
- /sw # Fink
- /opt/local # DarwinPorts
- /opt/csw # Blastwave
/opt
)
@@ -54,9 +51,6 @@ find_library(LUA_LIBRARY_lua
PATHS
~/Library/Frameworks
/Library/Frameworks
- /sw
- /opt/local
- /opt/csw
/opt
)
@@ -72,9 +66,6 @@ else()
ENV LUA_DIR
PATH_SUFFIXES lib
PATHS
- /sw
- /opt/local
- /opt/csw
/opt
)
if(LUA_LIBRARY_lualib AND LUA_LIBRARY_lua)
diff --git a/Modules/FindLua51.cmake b/Modules/FindLua51.cmake
index 31eaf87..1c9029b 100644
--- a/Modules/FindLua51.cmake
+++ b/Modules/FindLua51.cmake
@@ -41,9 +41,6 @@ find_path(LUA_INCLUDE_DIR lua.h
PATHS
~/Library/Frameworks
/Library/Frameworks
- /sw # Fink
- /opt/local # DarwinPorts
- /opt/csw # Blastwave
/opt
)
@@ -55,9 +52,6 @@ find_library(LUA_LIBRARY
PATHS
~/Library/Frameworks
/Library/Frameworks
- /sw
- /opt/local
- /opt/csw
/opt
)
diff --git a/Modules/FindOpenAL.cmake b/Modules/FindOpenAL.cmake
index dbd7961..18f3ff6 100644
--- a/Modules/FindOpenAL.cmake
+++ b/Modules/FindOpenAL.cmake
@@ -63,9 +63,6 @@ find_path(OPENAL_INCLUDE_DIR al.h
PATHS
~/Library/Frameworks
/Library/Frameworks
- /sw # Fink
- /opt/local # DarwinPorts
- /opt/csw # Blastwave
/opt
[HKEY_LOCAL_MACHINE\\SOFTWARE\\Creative\ Labs\\OpenAL\ 1.1\ Software\ Development\ Kit\\1.00.0000;InstallDir]
)
@@ -84,9 +81,6 @@ find_library(OPENAL_LIBRARY
PATHS
~/Library/Frameworks
/Library/Frameworks
- /sw
- /opt/local
- /opt/csw
/opt
[HKEY_LOCAL_MACHINE\\SOFTWARE\\Creative\ Labs\\OpenAL\ 1.1\ Software\ Development\ Kit\\1.00.0000;InstallDir]
)
diff --git a/Modules/FindPhysFS.cmake b/Modules/FindPhysFS.cmake
index 0366f77..a32f83a 100644
--- a/Modules/FindPhysFS.cmake
+++ b/Modules/FindPhysFS.cmake
@@ -24,9 +24,6 @@ find_path(PHYSFS_INCLUDE_DIR physfs.h
PATHS
~/Library/Frameworks
/Library/Frameworks
- /sw # Fink
- /opt/local # DarwinPorts
- /opt/csw # Blastwave
/opt
)
@@ -38,9 +35,6 @@ find_library(PHYSFS_LIBRARY
PATHS
~/Library/Frameworks
/Library/Frameworks
- /sw
- /opt/local
- /opt/csw
/opt
)
diff --git a/Modules/FindPkgConfig.cmake b/Modules/FindPkgConfig.cmake
index e192426..cf0ae09 100644
--- a/Modules/FindPkgConfig.cmake
+++ b/Modules/FindPkgConfig.cmake
@@ -242,7 +242,7 @@ endfunction()
function(_pkg_create_imp_target _prefix _imp_target_global)
# only create the target if it is linkable, i.e. no executables
if (NOT TARGET PkgConfig::${_prefix}
- AND ( ${_prefix}_INCLUDE_DIRS OR ${_prefix}_LINK_LIBRARIES OR ${_prefix}_CFLAGS_OTHER ))
+ AND ( ${_prefix}_INCLUDE_DIRS OR ${_prefix}_LINK_LIBRARIES OR ${_prefix}_LDFLAGS_OTHER OR ${_prefix}_CFLAGS_OTHER ))
if(${_imp_target_global})
set(_global_opt "GLOBAL")
else()
@@ -258,6 +258,10 @@ function(_pkg_create_imp_target _prefix _imp_target_global)
set_property(TARGET PkgConfig::${_prefix} PROPERTY
INTERFACE_LINK_LIBRARIES "${${_prefix}_LINK_LIBRARIES}")
endif()
+ if(${_prefix}_LDFLAGS_OTHER)
+ set_property(TARGET PkgConfig::${_prefix} PROPERTY
+ INTERFACE_LINK_OPTIONS "${${_prefix}_LDFLAGS_OTHER}")
+ endif()
if(${_prefix}_CFLAGS_OTHER)
set_property(TARGET PkgConfig::${_prefix} PROPERTY
INTERFACE_COMPILE_OPTIONS "${${_prefix}_CFLAGS_OTHER}")
diff --git a/Modules/FindProducer.cmake b/Modules/FindProducer.cmake
index fba0494..65495b5 100644
--- a/Modules/FindProducer.cmake
+++ b/Modules/FindProducer.cmake
@@ -45,12 +45,9 @@ find_path(PRODUCER_INCLUDE_DIR Producer/CameraGroup
PATHS
~/Library/Frameworks
/Library/Frameworks
- /sw/include # Fink
- /opt/local/include # DarwinPorts
- /opt/csw/include # Blastwave
- /opt/include
- [HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Session\ Manager\\Environment;OpenThreads_ROOT]/include
- [HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Session\ Manager\\Environment;OSG_ROOT]/include
+ /opt
+ [HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Session\ Manager\\Environment;OpenThreads_ROOT]
+ [HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Session\ Manager\\Environment;OSG_ROOT]
)
find_library(PRODUCER_LIBRARY
@@ -61,9 +58,6 @@ find_library(PRODUCER_LIBRARY
ENV OSGDIR
PATH_SUFFIXES lib
PATHS
- /sw
- /opt/local
- /opt/csw
/opt
)
diff --git a/Modules/FindPython.cmake b/Modules/FindPython.cmake
index f014916..1c134e2 100644
--- a/Modules/FindPython.cmake
+++ b/Modules/FindPython.cmake
@@ -28,6 +28,13 @@ is searched.
To manage concurrent versions 3 and 2 of Python, use :module:`FindPython3` and
:module:`FindPython2` modules rather than this one.
+.. note::
+
+ If components ``Interpreter`` and ``Development`` are both specified, this
+ module search only for interpreter with same platform architecture as the one
+ defined by ``CMake`` configuration. This contraint does not apply if only
+ ``Interpreter`` component is specified.
+
Imported Targets
^^^^^^^^^^^^^^^^
diff --git a/Modules/FindPython/Support.cmake b/Modules/FindPython/Support.cmake
index ef8272c..1236bf8 100644
--- a/Modules/FindPython/Support.cmake
+++ b/Modules/FindPython/Support.cmake
@@ -341,14 +341,14 @@ if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES}
NAMES_PER_DIR
HINTS ${_${_PYTHON_PREFIX}_HINTS}
- PATHS [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath]
- [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath]
+ PATHS [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath]
[HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}-${_${_PYTHON_PREFIX}_ARCH2}\\InstallPath]
+ [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath]
[HKEY_CURRENT_USER\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath]
[HKEY_CURRENT_USER\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH2}\\InstallPath]
- [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath]
[HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath]
[HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}-${_${_PYTHON_PREFIX}_ARCH2}\\InstallPath]
+ [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath]
[HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath]
[HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH2}\\InstallPath]
[HKEY_LOCAL_MACHINE\\SOFTWARE\\IronPython\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath]
@@ -402,14 +402,14 @@ if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
python
${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES}
NAMES_PER_DIR
- PATHS [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath]
- [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath]
+ PATHS [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath]
[HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}-${_${_PYTHON_PREFIX}_ARCH2}\\InstallPath]
+ [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath]
[HKEY_CURRENT_USER\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath]
[HKEY_CURRENT_USER\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH2}\\InstallPath]
- [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath]
[HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath]
[HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}-${_${_PYTHON_PREFIX}_ARCH2}\\InstallPath]
+ [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath]
[HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath]
[HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH2}\\InstallPath]
[HKEY_LOCAL_MACHINE\\SOFTWARE\\IronPython\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath]
@@ -816,14 +816,14 @@ if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS
_python_get_frameworks (_${_PYTHON_PREFIX}_FRAMEWORK_PATHS ${_${_PYTHON_PREFIX}_VERSION})
set (_${_PYTHON_PREFIX}_REGISTRY_PATHS
- [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath]
[HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath]
[HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}-${_${_PYTHON_PREFIX}_ARCH2}\\InstallPath]
+ [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath]
[HKEY_CURRENT_USER\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath]
[HKEY_CURRENT_USER\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH2}\\InstallPath]
- [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath]
[HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath]
[HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}-${_${_PYTHON_PREFIX}_ARCH2}\\InstallPath]
+ [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath]
[HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath]
[HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH2}\\InstallPath])
diff --git a/Modules/FindPython2.cmake b/Modules/FindPython2.cmake
index 0bb7b28..b9c0b6b 100644
--- a/Modules/FindPython2.cmake
+++ b/Modules/FindPython2.cmake
@@ -29,6 +29,13 @@ concurrently with :module:`FindPython3` module to use both Python versions.
The :module:`FindPython` module can be used if Python version does not matter
for you.
+.. note::
+
+ If components ``Interpreter`` and ``Development`` are both specified, this
+ module search only for interpreter with same platform architecture as the one
+ defined by ``CMake`` configuration. This contraint does not apply if only
+ ``Interpreter`` component is specified.
+
Imported Targets
^^^^^^^^^^^^^^^^
diff --git a/Modules/FindPython3.cmake b/Modules/FindPython3.cmake
index b3dfff3..c2f3384 100644
--- a/Modules/FindPython3.cmake
+++ b/Modules/FindPython3.cmake
@@ -29,6 +29,13 @@ concurrently with :module:`FindPython2` module to use both Python versions.
The :module:`FindPython` module can be used if Python version does not matter
for you.
+.. note::
+
+ If components ``Interpreter`` and ``Development`` are both specified, this
+ module search only for interpreter with same platform architecture as the one
+ defined by ``CMake`` configuration. This contraint does not apply if only
+ ``Interpreter`` component is specified.
+
Imported Targets
^^^^^^^^^^^^^^^^
diff --git a/Modules/FindSDL.cmake b/Modules/FindSDL.cmake
index 2813831..8d793a9 100644
--- a/Modules/FindSDL.cmake
+++ b/Modules/FindSDL.cmake
@@ -112,9 +112,6 @@ if(NOT SDL_BUILDING_LIBRARY)
ENV SDLDIR
PATH_SUFFIXES lib ${VC_LIB_PATH_SUFFIX}
PATHS
- /sw
- /opt/local
- /opt/csw
/opt
)
endif()
diff --git a/Modules/FindSDL_sound.cmake b/Modules/FindSDL_sound.cmake
index e217981..c986574 100644
--- a/Modules/FindSDL_sound.cmake
+++ b/Modules/FindSDL_sound.cmake
@@ -208,9 +208,6 @@ if(SDL_FOUND AND SDL_SOUND_INCLUDE_DIR AND SDL_SOUND_LIBRARY)
ENV MIKMODDIR
ENV SDLSOUNDDIR
ENV SDLDIR
- /sw
- /opt/local
- /opt/csw
/opt
PATH_SUFFIXES
lib
@@ -228,9 +225,6 @@ if(SDL_FOUND AND SDL_SOUND_INCLUDE_DIR AND SDL_SOUND_LIBRARY)
ENV MODPLUGDIR
ENV SDLSOUNDDIR
ENV SDLDIR
- /sw
- /opt/local
- /opt/csw
/opt
PATH_SUFFIXES
lib
@@ -250,9 +244,6 @@ if(SDL_FOUND AND SDL_SOUND_INCLUDE_DIR AND SDL_SOUND_LIBRARY)
ENV OGGDIR
ENV SDLSOUNDDIR
ENV SDLDIR
- /sw
- /opt/local
- /opt/csw
/opt
PATH_SUFFIXES
lib
@@ -268,9 +259,6 @@ if(SDL_FOUND AND SDL_SOUND_INCLUDE_DIR AND SDL_SOUND_LIBRARY)
ENV VORBISDIR
ENV SDLSOUNDDIR
ENV SDLDIR
- /sw
- /opt/local
- /opt/csw
/opt
PATH_SUFFIXES
lib
@@ -289,9 +277,6 @@ if(SDL_FOUND AND SDL_SOUND_INCLUDE_DIR AND SDL_SOUND_LIBRARY)
ENV SMPEGDIR
ENV SDLSOUNDDIR
ENV SDLDIR
- /sw
- /opt/local
- /opt/csw
/opt
PATH_SUFFIXES
lib
@@ -310,9 +295,6 @@ if(SDL_FOUND AND SDL_SOUND_INCLUDE_DIR AND SDL_SOUND_LIBRARY)
ENV FLACDIR
ENV SDLSOUNDDIR
ENV SDLDIR
- /sw
- /opt/local
- /opt/csw
/opt
PATH_SUFFIXES
lib
@@ -334,9 +316,6 @@ if(SDL_FOUND AND SDL_SOUND_INCLUDE_DIR AND SDL_SOUND_LIBRARY)
ENV SPEEXDIR
ENV SDLSOUNDDIR
ENV SDLDIR
- /sw
- /opt/local
- /opt/csw
/opt
PATH_SUFFIXES
lib
@@ -356,9 +335,6 @@ if(SDL_FOUND AND SDL_SOUND_INCLUDE_DIR AND SDL_SOUND_LIBRARY)
ENV SPEEXDIR
ENV SDLSOUNDDIR
ENV SDLDIR
- /sw
- /opt/local
- /opt/csw
/opt
PATH_SUFFIXES lib
)
diff --git a/Modules/Internal/FeatureTesting.cmake b/Modules/Internal/FeatureTesting.cmake
index de336e7..b9c20ec 100644
--- a/Modules/Internal/FeatureTesting.cmake
+++ b/Modules/Internal/FeatureTesting.cmake
@@ -71,10 +71,20 @@ endmacro()
macro(_record_compiler_features_c std)
list(APPEND CMAKE_C${std}_COMPILE_FEATURES c_std_${std})
- _record_compiler_features(C "${CMAKE_C${std}_STANDARD_COMPILE_OPTION}" CMAKE_C${std}_COMPILE_FEATURES)
+
+ get_property(lang_level_has_features GLOBAL PROPERTY CMAKE_C${std}_KNOWN_FEATURES)
+ if(lang_level_has_features)
+ _record_compiler_features(C "${CMAKE_C${std}_STANDARD_COMPILE_OPTION}" CMAKE_C${std}_COMPILE_FEATURES)
+ endif()
+ unset(lang_level_has_features)
endmacro()
macro(_record_compiler_features_cxx std)
list(APPEND CMAKE_CXX${std}_COMPILE_FEATURES cxx_std_${std})
- _record_compiler_features(CXX "${CMAKE_CXX${std}_STANDARD_COMPILE_OPTION}" CMAKE_CXX${std}_COMPILE_FEATURES)
+
+ get_property(lang_level_has_features GLOBAL PROPERTY CMAKE_CXX${std}_KNOWN_FEATURES)
+ if(lang_level_has_features)
+ _record_compiler_features(CXX "${CMAKE_CXX${std}_STANDARD_COMPILE_OPTION}" CMAKE_CXX${std}_COMPILE_FEATURES)
+ endif()
+ unset(lang_level_has_features)
endmacro()
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt
index f65e78f..52f6742 100644
--- a/Source/CMakeLists.txt
+++ b/Source/CMakeLists.txt
@@ -236,8 +236,10 @@ set(SRCS
cmFileLockResult.h
cmFilePathChecksum.cxx
cmFilePathChecksum.h
- cmFileTimeComparison.cxx
- cmFileTimeComparison.h
+ cmFileTime.cxx
+ cmFileTime.h
+ cmFileTimeCache.cxx
+ cmFileTimeCache.h
cmFortranParserImpl.cxx
cmFSPermissions.cxx
cmFSPermissions.h
@@ -804,7 +806,7 @@ foreach(check
else()
set(CMake_${check} 0)
endif()
- set_property(SOURCE cmFileTimeComparison.cxx APPEND PROPERTY
+ set_property(SOURCE cmFileTime.cxx APPEND PROPERTY
COMPILE_DEFINITIONS CMake_${check}=${CMake_${check}})
endforeach()
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index 9340c35..672ceae 100644
--- a/Source/CMakeVersion.cmake
+++ b/Source/CMakeVersion.cmake
@@ -1,5 +1,5 @@
# CMake version number components.
set(CMake_VERSION_MAJOR 3)
set(CMake_VERSION_MINOR 14)
-set(CMake_VERSION_PATCH 20190315)
+set(CMake_VERSION_PATCH 20190322)
#set(CMake_VERSION_RC 1)
diff --git a/Source/CPack/cmCPackDebGenerator.cxx b/Source/CPack/cmCPackDebGenerator.cxx
index 635de49..cfb5efd 100644
--- a/Source/CPack/cmCPackDebGenerator.cxx
+++ b/Source/CPack/cmCPackDebGenerator.cxx
@@ -195,7 +195,7 @@ bool DebGenerator::generateDataTar() const
// XXX/application/usr/bin/myprogram with GEN_WDIR=XXX/application
// should not add XXX/application
orderedFiles.insert(currentPath);
- currentPath = cmSystemTools::CollapseCombinedPath(currentPath, "..");
+ currentPath = cmSystemTools::CollapseFullPath("..", currentPath);
}
}
diff --git a/Source/CPack/cmCPackFreeBSDGenerator.cxx b/Source/CPack/cmCPackFreeBSDGenerator.cxx
index fcf8af1..dd8127d 100644
--- a/Source/CPack/cmCPackFreeBSDGenerator.cxx
+++ b/Source/CPack/cmCPackFreeBSDGenerator.cxx
@@ -325,8 +325,7 @@ int cmCPackFreeBSDGenerator::PackageFiles()
ONE_PACKAGE_PER_COMPONENT);
}
- std::string output_dir =
- cmSystemTools::CollapseCombinedPath(toplevel, "../");
+ std::string output_dir = cmSystemTools::CollapseFullPath("../", toplevel);
pkg_create_from_manifest(output_dir.c_str(), ::TXZ, toplevel.c_str(),
manifestname.c_str(), nullptr);
diff --git a/Source/CTest/cmCTestBuildCommand.cxx b/Source/CTest/cmCTestBuildCommand.cxx
index 32f7496..2eacaf1 100644
--- a/Source/CTest/cmCTestBuildCommand.cxx
+++ b/Source/CTest/cmCTestBuildCommand.cxx
@@ -4,7 +4,6 @@
#include "cmCTest.h"
#include "cmCTestBuildHandler.h"
-#include "cmCTestGenericHandler.h"
#include "cmGlobalGenerator.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
@@ -39,12 +38,10 @@ cmCTestBuildCommand::~cmCTestBuildCommand()
cmCTestGenericHandler* cmCTestBuildCommand::InitializeHandler()
{
- cmCTestGenericHandler* handler = this->CTest->GetInitializedHandler("build");
- if (!handler) {
- this->SetError("internal CTest error. Cannot instantiate build handler");
- return nullptr;
- }
- this->Handler = static_cast<cmCTestBuildHandler*>(handler);
+ cmCTestBuildHandler* handler = this->CTest->GetBuildHandler();
+ handler->Initialize();
+
+ this->Handler = handler;
const char* ctestBuildCommand =
this->Makefile->GetDefinition("CTEST_BUILD_COMMAND");
diff --git a/Source/CTest/cmCTestBuildHandler.cxx b/Source/CTest/cmCTestBuildHandler.cxx
index 07bc7e7..8ea9a83 100644
--- a/Source/CTest/cmCTestBuildHandler.cxx
+++ b/Source/CTest/cmCTestBuildHandler.cxx
@@ -5,7 +5,7 @@
#include "cmAlgorithms.h"
#include "cmCTest.h"
#include "cmDuration.h"
-#include "cmFileTimeComparison.h"
+#include "cmFileTimeCache.h"
#include "cmGeneratedFileStream.h"
#include "cmMakefile.h"
#include "cmProcessOutput.h"
@@ -503,7 +503,7 @@ void cmCTestBuildHandler::GenerateXMLHeader(cmXMLWriter& xml)
class cmCTestBuildHandler::FragmentCompare
{
public:
- FragmentCompare(cmFileTimeComparison* ftc)
+ FragmentCompare(cmFileTimeCache* ftc)
: FTC(ftc)
{
}
@@ -513,14 +513,14 @@ public:
// Order files by modification time. Use lexicographic order
// among files with the same time.
int result;
- if (this->FTC->FileTimeCompare(l, r, &result) && result != 0) {
+ if (this->FTC->Compare(l, r, &result) && result != 0) {
return result < 0;
}
return l < r;
}
private:
- cmFileTimeComparison* FTC = nullptr;
+ cmFileTimeCache* FTC = nullptr;
};
void cmCTestBuildHandler::GenerateXMLLaunched(cmXMLWriter& xml)
@@ -530,7 +530,7 @@ void cmCTestBuildHandler::GenerateXMLLaunched(cmXMLWriter& xml)
}
// Sort XML fragments in chronological order.
- cmFileTimeComparison ftc;
+ cmFileTimeCache ftc;
FragmentCompare fragmentCompare(&ftc);
typedef std::set<std::string, FragmentCompare> Fragments;
Fragments fragments(fragmentCompare);
diff --git a/Source/CTest/cmCTestConfigureCommand.cxx b/Source/CTest/cmCTestConfigureCommand.cxx
index 7b5c3bc..74a932a 100644
--- a/Source/CTest/cmCTestConfigureCommand.cxx
+++ b/Source/CTest/cmCTestConfigureCommand.cxx
@@ -3,7 +3,7 @@
#include "cmCTestConfigureCommand.h"
#include "cmCTest.h"
-#include "cmCTestGenericHandler.h"
+#include "cmCTestConfigureHandler.h"
#include "cmGlobalGenerator.h"
#include "cmMakefile.h"
#include "cmSystemTools.h"
@@ -142,13 +142,8 @@ cmCTestGenericHandler* cmCTestConfigureCommand::InitializeHandler()
labelsForSubprojects, this->Quiet);
}
- cmCTestGenericHandler* handler =
- this->CTest->GetInitializedHandler("configure");
- if (!handler) {
- this->SetError(
- "internal CTest error. Cannot instantiate configure handler");
- return nullptr;
- }
+ cmCTestConfigureHandler* handler = this->CTest->GetConfigureHandler();
+ handler->Initialize();
handler->SetQuiet(this->Quiet);
return handler;
}
diff --git a/Source/CTest/cmCTestCoverageCommand.cxx b/Source/CTest/cmCTestCoverageCommand.cxx
index d2003ba..07aae76 100644
--- a/Source/CTest/cmCTestCoverageCommand.cxx
+++ b/Source/CTest/cmCTestCoverageCommand.cxx
@@ -19,12 +19,8 @@ cmCTestGenericHandler* cmCTestCoverageCommand::InitializeHandler()
this->CTest->SetCTestConfigurationFromCMakeVariable(
this->Makefile, "CoverageExtraFlags", "CTEST_COVERAGE_EXTRA_FLAGS",
this->Quiet);
- cmCTestCoverageHandler* handler = static_cast<cmCTestCoverageHandler*>(
- this->CTest->GetInitializedHandler("coverage"));
- if (!handler) {
- this->SetError("internal CTest error. Cannot instantiate test handler");
- return nullptr;
- }
+ cmCTestCoverageHandler* handler = this->CTest->GetCoverageHandler();
+ handler->Initialize();
// If a LABELS option was given, select only files with the labels.
if (this->LabelsMentioned) {
diff --git a/Source/CTest/cmCTestMemCheckCommand.cxx b/Source/CTest/cmCTestMemCheckCommand.cxx
index a5d5995..7dad1ce 100644
--- a/Source/CTest/cmCTestMemCheckCommand.cxx
+++ b/Source/CTest/cmCTestMemCheckCommand.cxx
@@ -7,7 +7,6 @@
#include <vector>
#include "cmCTest.h"
-#include "cmCTestGenericHandler.h"
#include "cmCTestMemCheckHandler.h"
#include "cmMakefile.h"
@@ -20,8 +19,8 @@ cmCTestMemCheckCommand::cmCTestMemCheckCommand()
cmCTestGenericHandler* cmCTestMemCheckCommand::InitializeActualHandler()
{
- cmCTestGenericHandler* handler =
- this->CTest->GetInitializedHandler("memcheck");
+ cmCTestMemCheckHandler* handler = this->CTest->GetMemCheckHandler();
+ handler->Initialize();
this->CTest->SetCTestConfigurationFromCMakeVariable(
this->Makefile, "MemoryCheckType", "CTEST_MEMORYCHECK_TYPE", this->Quiet);
diff --git a/Source/CTest/cmCTestRunTest.cxx b/Source/CTest/cmCTestRunTest.cxx
index 3bf2087..31976b9 100644
--- a/Source/CTest/cmCTestRunTest.cxx
+++ b/Source/CTest/cmCTestRunTest.cxx
@@ -132,14 +132,17 @@ bool cmCTestRunTest::EndTest(size_t completed, size_t total, bool started)
} else {
this->TestResult.Status = cmCTestTestHandler::FAILED;
outputStream << "***Failed " << reason;
- outputTestErrorsToConsole = this->CTest->OutputTestOutputOnTestFailure;
+ outputTestErrorsToConsole =
+ this->CTest->GetOutputTestOutputOnTestFailure();
}
} else if (res == cmProcess::State::Expired) {
outputStream << "***Timeout ";
this->TestResult.Status = cmCTestTestHandler::TIMEOUT;
- outputTestErrorsToConsole = this->CTest->OutputTestOutputOnTestFailure;
+ outputTestErrorsToConsole =
+ this->CTest->GetOutputTestOutputOnTestFailure();
} else if (res == cmProcess::State::Exception) {
- outputTestErrorsToConsole = this->CTest->OutputTestOutputOnTestFailure;
+ outputTestErrorsToConsole =
+ this->CTest->GetOutputTestOutputOnTestFailure();
outputStream << "***Exception: ";
this->TestResult.ExceptionStatus =
this->TestProcess->GetExitExceptionString();
diff --git a/Source/CTest/cmCTestSubmitCommand.cxx b/Source/CTest/cmCTestSubmitCommand.cxx
index 00c0610..e31d982 100644
--- a/Source/CTest/cmCTestSubmitCommand.cxx
+++ b/Source/CTest/cmCTestSubmitCommand.cxx
@@ -3,7 +3,6 @@
#include "cmCTestSubmitCommand.h"
#include "cmCTest.h"
-#include "cmCTestGenericHandler.h"
#include "cmCTestSubmitHandler.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
@@ -42,33 +41,23 @@ cmCTestGenericHandler* cmCTestSubmitCommand::InitializeHandler()
this->Makefile->GetDefinition("CTEST_NOTES_FILES");
if (notesFilesVariable) {
std::vector<std::string> notesFiles;
- cmCTest::VectorOfStrings newNotesFiles;
cmSystemTools::ExpandListArgument(notesFilesVariable, notesFiles);
- newNotesFiles.insert(newNotesFiles.end(), notesFiles.begin(),
- notesFiles.end());
- this->CTest->GenerateNotesFile(newNotesFiles);
+ this->CTest->GenerateNotesFile(notesFiles);
}
const char* extraFilesVariable =
this->Makefile->GetDefinition("CTEST_EXTRA_SUBMIT_FILES");
if (extraFilesVariable) {
std::vector<std::string> extraFiles;
- cmCTest::VectorOfStrings newExtraFiles;
cmSystemTools::ExpandListArgument(extraFilesVariable, extraFiles);
- newExtraFiles.insert(newExtraFiles.end(), extraFiles.begin(),
- extraFiles.end());
- if (!this->CTest->SubmitExtraFiles(newExtraFiles)) {
+ if (!this->CTest->SubmitExtraFiles(extraFiles)) {
this->SetError("problem submitting extra files.");
return nullptr;
}
}
- cmCTestGenericHandler* handler =
- this->CTest->GetInitializedHandler("submit");
- if (!handler) {
- this->SetError("internal CTest error. Cannot instantiate submit handler");
- return nullptr;
- }
+ cmCTestSubmitHandler* handler = this->CTest->GetSubmitHandler();
+ handler->Initialize();
// If no FILES or PARTS given, *all* PARTS are submitted by default.
//
@@ -90,38 +79,30 @@ cmCTestGenericHandler* cmCTestSubmitCommand::InitializeHandler()
// But FILES with no PARTS mentioned should just submit the FILES
// without any of the default parts.
//
- std::set<cmCTest::Part> noParts;
- static_cast<cmCTestSubmitHandler*>(handler)->SelectParts(noParts);
-
- static_cast<cmCTestSubmitHandler*>(handler)->SelectFiles(this->Files);
+ handler->SelectParts(std::set<cmCTest::Part>());
+ handler->SelectFiles(this->Files);
}
// If a PARTS option was given, select only the named parts for submission.
//
if (this->PartsMentioned) {
- static_cast<cmCTestSubmitHandler*>(handler)->SelectParts(this->Parts);
+ handler->SelectParts(this->Parts);
}
// Pass along any HTTPHEADER to the handler if this option was given.
if (!this->HttpHeaders.empty()) {
- static_cast<cmCTestSubmitHandler*>(handler)->SetHttpHeaders(
- this->HttpHeaders);
+ handler->SetHttpHeaders(this->HttpHeaders);
}
- static_cast<cmCTestSubmitHandler*>(handler)->SetOption(
- "RetryDelay", this->RetryDelay.c_str());
- static_cast<cmCTestSubmitHandler*>(handler)->SetOption(
- "RetryCount", this->RetryCount.c_str());
- static_cast<cmCTestSubmitHandler*>(handler)->SetOption(
- "InternalTest", this->InternalTest ? "ON" : "OFF");
+ handler->SetOption("RetryDelay", this->RetryDelay.c_str());
+ handler->SetOption("RetryCount", this->RetryCount.c_str());
+ handler->SetOption("InternalTest", this->InternalTest ? "ON" : "OFF");
handler->SetQuiet(this->Quiet);
if (this->CDashUpload) {
- static_cast<cmCTestSubmitHandler*>(handler)->SetOption(
- "CDashUploadFile", this->CDashUploadFile.c_str());
- static_cast<cmCTestSubmitHandler*>(handler)->SetOption(
- "CDashUploadType", this->CDashUploadType.c_str());
+ handler->SetOption("CDashUploadFile", this->CDashUploadFile.c_str());
+ handler->SetOption("CDashUploadType", this->CDashUploadType.c_str());
}
return handler;
}
diff --git a/Source/CTest/cmCTestSubmitCommand.h b/Source/CTest/cmCTestSubmitCommand.h
index 0caccd6..4b1bb26 100644
--- a/Source/CTest/cmCTestSubmitCommand.h
+++ b/Source/CTest/cmCTestSubmitCommand.h
@@ -79,7 +79,7 @@ protected:
std::set<cmCTest::Part> Parts;
bool FilesMentioned;
bool InternalTest;
- cmCTest::SetOfStrings Files;
+ std::set<std::string> Files;
std::string RetryCount;
std::string RetryDelay;
bool CDashUpload;
diff --git a/Source/CTest/cmCTestSubmitHandler.cxx b/Source/CTest/cmCTestSubmitHandler.cxx
index 1539635..2b54365 100644
--- a/Source/CTest/cmCTestSubmitHandler.cxx
+++ b/Source/CTest/cmCTestSubmitHandler.cxx
@@ -259,8 +259,7 @@ bool cmCTestSubmitHandler::SubmitUsingHTTP(
upload_as += ctest_curl.Escape(this->CTest->GetCurrentTag());
upload_as += "-";
upload_as += ctest_curl.Escape(this->CTest->GetTestModelString());
- cmCTestScriptHandler* ch = static_cast<cmCTestScriptHandler*>(
- this->CTest->GetHandler("script"));
+ cmCTestScriptHandler* ch = this->CTest->GetScriptHandler();
cmake* cm = ch->GetCMake();
if (cm) {
const char* subproject =
@@ -558,8 +557,7 @@ int cmCTestSubmitHandler::HandleCDashUploadFile(std::string const& file,
// has already been uploaded
// TODO I added support for subproject. You would need to add
// a "&subproject=subprojectname" to the first POST.
- cmCTestScriptHandler* ch =
- static_cast<cmCTestScriptHandler*>(this->CTest->GetHandler("script"));
+ cmCTestScriptHandler* ch = this->CTest->GetScriptHandler();
cmake* cm = ch->GetCMake();
const char* subproject = cm->GetState()->GetGlobalProperty("SubProject");
// TODO: Encode values for a URL instead of trusting caller.
@@ -902,7 +900,7 @@ void cmCTestSubmitHandler::SelectParts(std::set<cmCTest::Part> const& parts)
}
}
-void cmCTestSubmitHandler::SelectFiles(cmCTest::SetOfStrings const& files)
+void cmCTestSubmitHandler::SelectFiles(std::set<std::string> const& files)
{
this->Files.insert(files.begin(), files.end());
}
diff --git a/Source/CTest/cmCTestSubmitHandler.h b/Source/CTest/cmCTestSubmitHandler.h
index 58f4f97..e0fed10 100644
--- a/Source/CTest/cmCTestSubmitHandler.h
+++ b/Source/CTest/cmCTestSubmitHandler.h
@@ -38,7 +38,7 @@ public:
void SelectParts(std::set<cmCTest::Part> const& parts);
/** Specify a set of files to submit. */
- void SelectFiles(cmCTest::SetOfStrings const& files);
+ void SelectFiles(std::set<std::string> const& files);
// handle the cdash file upload protocol
int HandleCDashUploadFile(std::string const& file, std::string const& type);
@@ -74,7 +74,7 @@ private:
bool SubmitPart[cmCTest::PartCount];
bool HasWarnings;
bool HasErrors;
- cmCTest::SetOfStrings Files;
+ std::set<std::string> Files;
std::vector<std::string> HttpHeaders;
};
diff --git a/Source/CTest/cmCTestTestCommand.cxx b/Source/CTest/cmCTestTestCommand.cxx
index 895ca12..cfd5e3d 100644
--- a/Source/CTest/cmCTestTestCommand.cxx
+++ b/Source/CTest/cmCTestTestCommand.cxx
@@ -4,6 +4,7 @@
#include "cmCTest.h"
#include "cmCTestGenericHandler.h"
+#include "cmCTestTestHandler.h"
#include "cmDuration.h"
#include "cmMakefile.h"
#include "cmSystemTools.h"
@@ -140,5 +141,7 @@ cmCTestGenericHandler* cmCTestTestCommand::InitializeHandler()
cmCTestGenericHandler* cmCTestTestCommand::InitializeActualHandler()
{
- return this->CTest->GetInitializedHandler("test");
+ cmCTestTestHandler* handler = this->CTest->GetTestHandler();
+ handler->Initialize();
+ return handler;
}
diff --git a/Source/CTest/cmCTestUpdateCommand.cxx b/Source/CTest/cmCTestUpdateCommand.cxx
index 3d800f8..a2f1462 100644
--- a/Source/CTest/cmCTestUpdateCommand.cxx
+++ b/Source/CTest/cmCTestUpdateCommand.cxx
@@ -3,7 +3,7 @@
#include "cmCTestUpdateCommand.h"
#include "cmCTest.h"
-#include "cmCTestGenericHandler.h"
+#include "cmCTestUpdateHandler.h"
#include "cmMakefile.h"
#include "cmSystemTools.h"
@@ -74,12 +74,8 @@ cmCTestGenericHandler* cmCTestUpdateCommand::InitializeHandler()
this->CTest->SetCTestConfigurationFromCMakeVariable(
this->Makefile, "P4Options", "CTEST_P4_OPTIONS", this->Quiet);
- cmCTestGenericHandler* handler =
- this->CTest->GetInitializedHandler("update");
- if (!handler) {
- this->SetError("internal CTest error. Cannot instantiate update handler");
- return nullptr;
- }
+ cmCTestUpdateHandler* handler = this->CTest->GetUpdateHandler();
+ handler->Initialize();
handler->SetCommand(this);
if (source_dir.empty()) {
this->SetError("source directory not specified. Please use SOURCE tag");
diff --git a/Source/CTest/cmCTestUploadCommand.cxx b/Source/CTest/cmCTestUploadCommand.cxx
index 2fe2cd3..59fbf37 100644
--- a/Source/CTest/cmCTestUploadCommand.cxx
+++ b/Source/CTest/cmCTestUploadCommand.cxx
@@ -6,7 +6,6 @@
#include <vector>
#include "cmCTest.h"
-#include "cmCTestGenericHandler.h"
#include "cmCTestUploadHandler.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
@@ -14,14 +13,9 @@
cmCTestGenericHandler* cmCTestUploadCommand::InitializeHandler()
{
- cmCTestGenericHandler* handler =
- this->CTest->GetInitializedHandler("upload");
- if (!handler) {
- this->SetError("internal CTest error. Cannot instantiate upload handler");
- return nullptr;
- }
- static_cast<cmCTestUploadHandler*>(handler)->SetFiles(this->Files);
-
+ cmCTestUploadHandler* handler = this->CTest->GetUploadHandler();
+ handler->Initialize();
+ handler->SetFiles(this->Files);
handler->SetQuiet(this->Quiet);
return handler;
}
diff --git a/Source/CTest/cmCTestUploadCommand.h b/Source/CTest/cmCTestUploadCommand.h
index 61bf1cc..0d3b06e 100644
--- a/Source/CTest/cmCTestUploadCommand.h
+++ b/Source/CTest/cmCTestUploadCommand.h
@@ -5,9 +5,9 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmCTest.h"
#include "cmCTestHandlerCommand.h"
+#include <set>
#include <string>
class cmCTestGenericHandler;
@@ -22,8 +22,6 @@ class cmCommand;
class cmCTestUploadCommand : public cmCTestHandlerCommand
{
public:
- cmCTestUploadCommand() {}
-
/**
* This is a virtual constructor for the command.
*/
@@ -55,7 +53,7 @@ protected:
ArgumentDoingLast2
};
- cmCTest::SetOfStrings Files;
+ std::set<std::string> Files;
};
#endif
diff --git a/Source/CTest/cmCTestUploadHandler.cxx b/Source/CTest/cmCTestUploadHandler.cxx
index 261ecab..ee9ee91 100644
--- a/Source/CTest/cmCTestUploadHandler.cxx
+++ b/Source/CTest/cmCTestUploadHandler.cxx
@@ -2,6 +2,7 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCTestUploadHandler.h"
+#include "cmCTest.h"
#include "cmGeneratedFileStream.h"
#include "cmVersion.h"
#include "cmXMLWriter.h"
@@ -20,7 +21,7 @@ void cmCTestUploadHandler::Initialize()
this->Files.clear();
}
-void cmCTestUploadHandler::SetFiles(const cmCTest::SetOfStrings& files)
+void cmCTestUploadHandler::SetFiles(std::set<std::string> const& files)
{
this->Files = files;
}
diff --git a/Source/CTest/cmCTestUploadHandler.h b/Source/CTest/cmCTestUploadHandler.h
index ff50574..4d8fab4 100644
--- a/Source/CTest/cmCTestUploadHandler.h
+++ b/Source/CTest/cmCTestUploadHandler.h
@@ -5,9 +5,11 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmCTest.h"
#include "cmCTestGenericHandler.h"
+#include <set>
+#include <string>
+
/** \class cmCTestUploadHandler
* \brief Helper class for CTest
*
@@ -20,7 +22,6 @@ public:
typedef cmCTestGenericHandler Superclass;
cmCTestUploadHandler();
- ~cmCTestUploadHandler() override {}
/*
* The main entry point for this class
@@ -30,10 +31,10 @@ public:
void Initialize() override;
/** Specify a set of files to submit. */
- void SetFiles(cmCTest::SetOfStrings const& files);
+ void SetFiles(std::set<std::string> const& files);
private:
- cmCTest::SetOfStrings Files;
+ std::set<std::string> Files;
};
#endif
diff --git a/Source/cmArchiveWrite.cxx b/Source/cmArchiveWrite.cxx
index 23be603..177ba02 100644
--- a/Source/cmArchiveWrite.cxx
+++ b/Source/cmArchiveWrite.cxx
@@ -179,12 +179,10 @@ cmArchiveWrite::~cmArchiveWrite()
bool cmArchiveWrite::Add(std::string path, size_t skip, const char* prefix,
bool recursive)
{
- if (this->Okay()) {
- if (!path.empty() && path.back() == '/') {
- path.erase(path.size() - 1);
- }
- this->AddPath(path.c_str(), skip, prefix, recursive);
+ if (!path.empty() && path.back() == '/') {
+ path.erase(path.size() - 1);
}
+ this->AddPath(path.c_str(), skip, prefix, recursive);
return this->Okay();
}
@@ -220,6 +218,7 @@ bool cmArchiveWrite::AddPath(const char* path, size_t skip, const char* prefix,
bool cmArchiveWrite::AddFile(const char* file, size_t skip, const char* prefix)
{
+ this->Error = "";
// Skip the file if we have no name for it. This may happen on a
// top-level directory, which does not need to be included anyway.
if (skip >= strlen(file)) {
@@ -241,7 +240,7 @@ bool cmArchiveWrite::AddFile(const char* file, size_t skip, const char* prefix)
cm_archive_entry_copy_pathname(e, dest);
if (archive_read_disk_entry_from_file(this->Disk, e, -1, nullptr) !=
ARCHIVE_OK) {
- this->Error = "archive_read_disk_entry_from_file '";
+ this->Error = "Unable to read from file '";
this->Error += file;
this->Error += "': ";
this->Error += cm_archive_error_string(this->Disk);
diff --git a/Source/cmCTest.cxx b/Source/cmCTest.cxx
index c77bb97..709feac 100644
--- a/Source/cmCTest.cxx
+++ b/Source/cmCTest.cxx
@@ -43,7 +43,6 @@
#include "cmCTestTestHandler.h"
#include "cmCTestUpdateHandler.h"
#include "cmCTestUploadHandler.h"
-#include "cmCurl.h"
#include "cmDynamicLoader.h"
#include "cmGeneratedFileStream.h"
#include "cmGlobalGenerator.h"
@@ -62,12 +61,149 @@
# include <be/kernel/OS.h> /* disable_debugger() API. */
#endif
-#define DEBUGOUT \
- std::cout << __LINE__ << " "; \
- std::cout
-#define DEBUGERR \
- std::cerr << __LINE__ << " "; \
- std::cerr
+struct cmCTest::Private
+{
+ /** Representation of one part. */
+ struct PartInfo
+ {
+ void SetName(const std::string& name) { this->Name = name; }
+ const std::string& GetName() const { return this->Name; }
+
+ void Enable() { this->Enabled = true; }
+ explicit operator bool() const { return this->Enabled; }
+
+ std::vector<std::string> SubmitFiles;
+
+ private:
+ bool Enabled = false;
+ std::string Name;
+ };
+
+ int RepeatTests = 1; // default to run each test once
+ bool RepeatUntilFail = false;
+ std::string ConfigType;
+ std::string ScheduleType;
+ std::chrono::system_clock::time_point StopTime;
+ bool TestProgressOutput = false;
+ bool Verbose = false;
+ bool ExtraVerbose = false;
+ bool ProduceXML = false;
+ bool LabelSummary = true;
+ bool SubprojectSummary = true;
+ bool UseHTTP10 = false;
+ bool PrintLabels = false;
+ bool Failover = false;
+
+ bool FlushTestProgressLine = false;
+
+ bool ForceNewCTestProcess = false;
+
+ bool RunConfigurationScript = false;
+
+ // these are helper classes
+ cmCTestBuildHandler BuildHandler;
+ cmCTestBuildAndTestHandler BuildAndTestHandler;
+ cmCTestCoverageHandler CoverageHandler;
+ cmCTestScriptHandler ScriptHandler;
+ cmCTestTestHandler TestHandler;
+ cmCTestUpdateHandler UpdateHandler;
+ cmCTestConfigureHandler ConfigureHandler;
+ cmCTestMemCheckHandler MemCheckHandler;
+ cmCTestSubmitHandler SubmitHandler;
+ cmCTestUploadHandler UploadHandler;
+
+ std::vector<cmCTestGenericHandler*> GetTestingHandlers()
+ {
+ return { &this->BuildHandler, &this->BuildAndTestHandler,
+ &this->CoverageHandler, &this->ScriptHandler,
+ &this->TestHandler, &this->UpdateHandler,
+ &this->ConfigureHandler, &this->MemCheckHandler,
+ &this->SubmitHandler, &this->UploadHandler };
+ }
+
+ std::map<std::string, cmCTestGenericHandler*> GetNamedTestingHandlers()
+ {
+ return { { "build", &this->BuildHandler },
+ { "buildtest", &this->BuildAndTestHandler },
+ { "coverage", &this->CoverageHandler },
+ { "script", &this->ScriptHandler },
+ { "test", &this->TestHandler },
+ { "update", &this->UpdateHandler },
+ { "configure", &this->ConfigureHandler },
+ { "memcheck", &this->MemCheckHandler },
+ { "submit", &this->SubmitHandler },
+ { "upload", &this->UploadHandler } };
+ }
+
+ bool ShowOnly = false;
+ bool OutputAsJson = false;
+ int OutputAsJsonVersion = 1;
+
+ // TODO: The ctest configuration should be a hierarchy of
+ // configuration option sources: command-line, script, ini file.
+ // Then the ini file can get re-loaded whenever it changes without
+ // affecting any higher-precedence settings.
+ std::map<std::string, std::string> CTestConfiguration;
+ std::map<std::string, std::string> CTestConfigurationOverwrites;
+
+ PartInfo Parts[PartCount];
+ std::map<std::string, Part> PartMap;
+
+ std::string CurrentTag;
+ bool TomorrowTag = false;
+
+ int TestModel = cmCTest::EXPERIMENTAL;
+ std::string SpecificTrack;
+
+ cmDuration TimeOut = cmDuration::zero();
+
+ cmDuration GlobalTimeout = cmDuration::zero();
+
+ int MaxTestNameWidth = 30;
+
+ int ParallelLevel = 1;
+ bool ParallelLevelSetInCli = false;
+
+ unsigned long TestLoad = 0;
+
+ int CompatibilityMode;
+
+ // information for the --build-and-test options
+ std::string BinaryDir;
+
+ std::string NotesFiles;
+
+ bool InteractiveDebugMode = true;
+
+ bool ShortDateFormat = true;
+
+ bool CompressXMLFiles = false;
+ bool CompressTestOutput = true;
+
+ // By default we write output to the process output streams.
+ std::ostream* StreamOut = &std::cout;
+ std::ostream* StreamErr = &std::cerr;
+
+ bool SuppressUpdatingCTestConfiguration = false;
+
+ bool Debug = false;
+ bool ShowLineNumbers = false;
+ bool Quiet = false;
+
+ std::string BuildID;
+
+ std::vector<std::string> InitialCommandLineArguments;
+
+ int SubmitIndex = 0;
+
+ cmGeneratedFileStream* OutputLogFile = nullptr;
+ int OutputLogFileLastTag = -1;
+
+ bool OutputTestOutputOnTestFailure = false;
+ bool OutputColorCode = cmCTest::ColoredOutputSupportedByConsole();
+
+ std::map<std::string, std::string> Definitions;
+};
struct tm* cmCTest::GetNightlyTime(std::string const& str, bool tomorrowtag)
{
@@ -123,6 +259,11 @@ struct tm* cmCTest::GetNightlyTime(std::string const& str, bool tomorrowtag)
return lctime;
}
+bool cmCTest::GetTomorrowTag() const
+{
+ return this->Impl->TomorrowTag;
+}
+
std::string cmCTest::CleanString(const std::string& str)
{
std::string::size_type spos = str.find_first_not_of(" \n\t\r\f\v");
@@ -142,7 +283,7 @@ std::string cmCTest::CurrentTime()
struct tm* t = localtime(&currenttime);
// return ::CleanString(ctime(&currenttime));
char current_time[1024];
- if (this->ShortDateFormat) {
+ if (this->Impl->ShortDateFormat) {
strftime(current_time, 1000, "%b %d %H:%M %Z", t);
} else {
strftime(current_time, 1000, "%a %b %d %H:%M:%S %Z %Y", t);
@@ -160,88 +301,6 @@ std::string cmCTest::GetCostDataFile()
return fname;
}
-#ifdef CMAKE_BUILD_WITH_CMAKE
-static size_t HTTPResponseCallback(void* ptr, size_t size, size_t nmemb,
- void* data)
-{
- int realsize = static_cast<int>(size * nmemb);
-
- std::string* response = static_cast<std::string*>(data);
- const char* chPtr = static_cast<char*>(ptr);
- *response += chPtr;
-
- return realsize;
-}
-
-int cmCTest::HTTPRequest(std::string url, HTTPMethod method,
- std::string& response, std::string const& fields,
- std::string const& putFile, int timeout)
-{
- CURL* curl;
- FILE* file;
- ::curl_global_init(CURL_GLOBAL_ALL);
- curl = ::curl_easy_init();
- cmCurlSetCAInfo(curl);
-
- // set request options based on method
- switch (method) {
- case cmCTest::HTTP_POST:
- ::curl_easy_setopt(curl, CURLOPT_POST, 1);
- ::curl_easy_setopt(curl, CURLOPT_POSTFIELDS, fields.c_str());
- break;
- case cmCTest::HTTP_PUT:
- if (!cmSystemTools::FileExists(putFile)) {
- response = "Error: File ";
- response += putFile + " does not exist.\n";
- return -1;
- }
- ::curl_easy_setopt(curl, CURLOPT_PUT, 1);
- file = cmsys::SystemTools::Fopen(putFile, "rb");
- ::curl_easy_setopt(curl, CURLOPT_INFILE, file);
- // fall through to append GET fields
- CM_FALLTHROUGH;
- case cmCTest::HTTP_GET:
- if (!fields.empty()) {
- url += "?" + fields;
- }
- break;
- }
-
- ::curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
- ::curl_easy_setopt(curl, CURLOPT_TIMEOUT, timeout);
- ::curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1);
-
- // set response options
- ::curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, HTTPResponseCallback);
- ::curl_easy_setopt(curl, CURLOPT_FILE, &response);
- ::curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1);
-
- CURLcode res = ::curl_easy_perform(curl);
-
- ::curl_easy_cleanup(curl);
- ::curl_global_cleanup();
-
- return static_cast<int>(res);
-}
-#endif
-
-std::string cmCTest::MakeURLSafe(const std::string& str)
-{
- std::ostringstream ost;
- char buffer[10];
- for (unsigned char ch : str) {
- if ((ch > 126 || ch < 32 || ch == '&' || ch == '%' || ch == '+' ||
- ch == '=' || ch == '@') &&
- ch != 9) {
- sprintf(buffer, "%02x;", static_cast<unsigned int>(ch));
- ost << buffer;
- } else {
- ost << ch;
- }
- }
- return ost.str();
-}
-
std::string cmCTest::DecodeURL(const std::string& in)
{
std::string out;
@@ -258,92 +317,39 @@ std::string cmCTest::DecodeURL(const std::string& in)
}
cmCTest::cmCTest()
+ : Impl(new Private)
{
- this->LabelSummary = true;
- this->SubprojectSummary = true;
- this->ParallelLevel = 1;
- this->ParallelLevelSetInCli = false;
- this->TestLoad = 0;
- this->SubmitIndex = 0;
- this->Failover = false;
- this->ForceNewCTestProcess = false;
- this->TomorrowTag = false;
- this->TestProgressOutput = false;
- this->FlushTestProgressLine = false;
- this->Verbose = false;
-
- this->Debug = false;
- this->ShowLineNumbers = false;
- this->Quiet = false;
- this->ExtraVerbose = false;
- this->ProduceXML = false;
- this->ShowOnly = false;
- this->OutputAsJson = false;
- this->OutputAsJsonVersion = 1;
- this->RunConfigurationScript = false;
- this->UseHTTP10 = false;
- this->PrintLabels = false;
- this->CompressTestOutput = true;
- this->TestModel = cmCTest::EXPERIMENTAL;
- this->MaxTestNameWidth = 30;
- this->InteractiveDebugMode = true;
- this->TimeOut = cmDuration::zero();
- this->GlobalTimeout = cmDuration::zero();
- this->CompressXMLFiles = false;
- this->ScheduleType.clear();
- this->OutputLogFile = nullptr;
- this->OutputLogFileLastTag = -1;
- this->SuppressUpdatingCTestConfiguration = false;
- this->BuildID = "";
- this->OutputTestOutputOnTestFailure = false;
- this->OutputColorCode = cmCTest::ColoredOutputSupportedByConsole();
- this->RepeatTests = 1; // default to run each test once
- this->RepeatUntilFail = false;
-
std::string envValue;
if (cmSystemTools::GetEnv("CTEST_OUTPUT_ON_FAILURE", envValue)) {
- this->OutputTestOutputOnTestFailure = !cmSystemTools::IsOff(envValue);
+ this->Impl->OutputTestOutputOnTestFailure =
+ !cmSystemTools::IsOff(envValue);
}
envValue.clear();
if (cmSystemTools::GetEnv("CTEST_PROGRESS_OUTPUT", envValue)) {
- this->TestProgressOutput = !cmSystemTools::IsOff(envValue);
- }
-
- this->InitStreams();
-
- this->Parts[PartStart].SetName("Start");
- this->Parts[PartUpdate].SetName("Update");
- this->Parts[PartConfigure].SetName("Configure");
- this->Parts[PartBuild].SetName("Build");
- this->Parts[PartTest].SetName("Test");
- this->Parts[PartCoverage].SetName("Coverage");
- this->Parts[PartMemCheck].SetName("MemCheck");
- this->Parts[PartSubmit].SetName("Submit");
- this->Parts[PartNotes].SetName("Notes");
- this->Parts[PartExtraFiles].SetName("ExtraFiles");
- this->Parts[PartUpload].SetName("Upload");
- this->Parts[PartDone].SetName("Done");
+ this->Impl->TestProgressOutput = !cmSystemTools::IsOff(envValue);
+ }
+
+ this->Impl->Parts[PartStart].SetName("Start");
+ this->Impl->Parts[PartUpdate].SetName("Update");
+ this->Impl->Parts[PartConfigure].SetName("Configure");
+ this->Impl->Parts[PartBuild].SetName("Build");
+ this->Impl->Parts[PartTest].SetName("Test");
+ this->Impl->Parts[PartCoverage].SetName("Coverage");
+ this->Impl->Parts[PartMemCheck].SetName("MemCheck");
+ this->Impl->Parts[PartSubmit].SetName("Submit");
+ this->Impl->Parts[PartNotes].SetName("Notes");
+ this->Impl->Parts[PartExtraFiles].SetName("ExtraFiles");
+ this->Impl->Parts[PartUpload].SetName("Upload");
+ this->Impl->Parts[PartDone].SetName("Done");
// Fill the part name-to-id map.
for (Part p = PartStart; p != PartCount; p = Part(p + 1)) {
- this->PartMap[cmSystemTools::LowerCase(this->Parts[p].GetName())] = p;
+ this->Impl
+ ->PartMap[cmSystemTools::LowerCase(this->Impl->Parts[p].GetName())] = p;
}
- this->ShortDateFormat = true;
-
- this->TestingHandlers["build"] = new cmCTestBuildHandler;
- this->TestingHandlers["buildtest"] = new cmCTestBuildAndTestHandler;
- this->TestingHandlers["coverage"] = new cmCTestCoverageHandler;
- this->TestingHandlers["script"] = new cmCTestScriptHandler;
- this->TestingHandlers["test"] = new cmCTestTestHandler;
- this->TestingHandlers["update"] = new cmCTestUpdateHandler;
- this->TestingHandlers["configure"] = new cmCTestConfigureHandler;
- this->TestingHandlers["memcheck"] = new cmCTestMemCheckHandler;
- this->TestingHandlers["submit"] = new cmCTestSubmitHandler;
- this->TestingHandlers["upload"] = new cmCTestUploadHandler;
-
- for (auto& handler : this->TestingHandlers) {
- handler.second->SetCTestInstance(this);
+ for (auto& handler : this->Impl->GetTestingHandlers()) {
+ handler->SetCTestInstance(this);
}
// Make sure we can capture the build tool output.
@@ -352,31 +358,40 @@ cmCTest::cmCTest()
cmCTest::~cmCTest()
{
- cmDeleteAll(this->TestingHandlers);
- this->SetOutputLogFileName(nullptr);
+ delete this->Impl->OutputLogFile;
+}
+
+int cmCTest::GetParallelLevel() const
+{
+ return this->Impl->ParallelLevel;
}
void cmCTest::SetParallelLevel(int level)
{
- this->ParallelLevel = level < 1 ? 1 : level;
+ this->Impl->ParallelLevel = level < 1 ? 1 : level;
+}
+
+unsigned long cmCTest::GetTestLoad() const
+{
+ return this->Impl->TestLoad;
}
void cmCTest::SetTestLoad(unsigned long load)
{
- this->TestLoad = load;
+ this->Impl->TestLoad = load;
}
bool cmCTest::ShouldCompressTestOutput()
{
- return this->CompressTestOutput;
+ return this->Impl->CompressTestOutput;
}
cmCTest::Part cmCTest::GetPartFromName(const char* name)
{
// Look up by lower-case to make names case-insensitive.
std::string lower_name = cmSystemTools::LowerCase(name);
- PartMapType::const_iterator i = this->PartMap.find(lower_name);
- if (i != this->PartMap.end()) {
+ auto const i = this->Impl->PartMap.find(lower_name);
+ if (i != this->Impl->PartMap.end()) {
return i->second;
}
@@ -392,19 +407,19 @@ int cmCTest::Initialize(const char* binary_dir, cmCTestStartCommand* command)
}
cmCTestOptionalLog(this, DEBUG, "Here: " << __LINE__ << std::endl, quiet);
- if (!this->InteractiveDebugMode) {
+ if (!this->Impl->InteractiveDebugMode) {
this->BlockTestErrorDiagnostics();
} else {
cmSystemTools::PutEnv("CTEST_INTERACTIVE_DEBUG_MODE=1");
}
- this->BinaryDir = binary_dir;
- cmSystemTools::ConvertToUnixSlashes(this->BinaryDir);
+ this->Impl->BinaryDir = binary_dir;
+ cmSystemTools::ConvertToUnixSlashes(this->Impl->BinaryDir);
this->UpdateCTestConfiguration();
cmCTestOptionalLog(this, DEBUG, "Here: " << __LINE__ << std::endl, quiet);
- if (this->ProduceXML) {
+ if (this->Impl->ProduceXML) {
cmCTestOptionalLog(this, DEBUG, "Here: " << __LINE__ << std::endl, quiet);
cmCTestOptionalLog(this, OUTPUT,
" Site: "
@@ -415,7 +430,7 @@ int cmCTest::Initialize(const char* binary_dir, cmCTestStartCommand* command)
<< std::endl,
quiet);
cmCTestOptionalLog(this, DEBUG, "Produce XML is on" << std::endl, quiet);
- if (this->TestModel == cmCTest::NIGHTLY &&
+ if (this->Impl->TestModel == cmCTest::NIGHTLY &&
this->GetCTestConfiguration("NightlyStartTime").empty()) {
cmCTestOptionalLog(
this, WARNING,
@@ -435,17 +450,18 @@ int cmCTest::Initialize(const char* binary_dir, cmCTestStartCommand* command)
cm.GetCurrentSnapshot().SetDefaultDefinitions();
cmGlobalGenerator gg(&cm);
cmMakefile mf(&gg, cm.GetCurrentSnapshot());
- if (!this->ReadCustomConfigurationFileTree(this->BinaryDir.c_str(), &mf)) {
+ if (!this->ReadCustomConfigurationFileTree(this->Impl->BinaryDir.c_str(),
+ &mf)) {
cmCTestOptionalLog(
this, DEBUG, "Cannot find custom configuration file tree" << std::endl,
quiet);
return 0;
}
- if (this->ProduceXML) {
+ if (this->Impl->ProduceXML) {
// Verify "Testing" directory exists:
//
- std::string testingDir = this->BinaryDir + "/Testing";
+ std::string testingDir = this->Impl->BinaryDir + "/Testing";
if (cmSystemTools::FileExists(testingDir)) {
if (!cmSystemTools::FileIsDirectory(testingDir)) {
cmCTestLog(this, ERROR_MESSAGE,
@@ -475,7 +491,7 @@ int cmCTest::Initialize(const char* binary_dir, cmCTestStartCommand* command)
if (createNewTag) {
time_t tctime = time(nullptr);
- if (this->TomorrowTag) {
+ if (this->Impl->TomorrowTag) {
tctime += (24 * 60 * 60);
}
struct tm* lctime = gmtime(&tctime);
@@ -493,26 +509,28 @@ int cmCTest::Initialize(const char* binary_dir, cmCTestStartCommand* command)
}
std::string track;
if (cmSystemTools::GetLineFromStream(tfin, track) &&
- !this->Parts[PartStart] && !command) {
- this->SpecificTrack = track;
+ !this->Impl->Parts[PartStart] && !command) {
+ this->Impl->SpecificTrack = track;
}
std::string model;
if (cmSystemTools::GetLineFromStream(tfin, model) &&
- !this->Parts[PartStart] && !command) {
- this->TestModel = GetTestModelFromString(model.c_str());
+ !this->Impl->Parts[PartStart] && !command) {
+ this->Impl->TestModel = GetTestModelFromString(model.c_str());
}
tfin.close();
}
- if (tag.empty() || (nullptr != command) || this->Parts[PartStart]) {
+ if (tag.empty() || (nullptr != command) ||
+ this->Impl->Parts[PartStart]) {
cmCTestOptionalLog(
this, DEBUG,
"TestModel: " << this->GetTestModelString() << std::endl, quiet);
- cmCTestOptionalLog(
- this, DEBUG, "TestModel: " << this->TestModel << std::endl, quiet);
- if (this->TestModel == cmCTest::NIGHTLY) {
+ cmCTestOptionalLog(this, DEBUG,
+ "TestModel: " << this->Impl->TestModel << std::endl,
+ quiet);
+ if (this->Impl->TestModel == cmCTest::NIGHTLY) {
lctime = this->GetNightlyTime(
this->GetCTestConfiguration("NightlyStartTime"),
- this->TomorrowTag);
+ this->Impl->TomorrowTag);
}
char datestring[100];
sprintf(datestring, "%04d%02d%02d-%02d%02d", lctime->tm_year + 1900,
@@ -523,7 +541,7 @@ int cmCTest::Initialize(const char* binary_dir, cmCTestStartCommand* command)
if (ofs) {
ofs << tag << std::endl;
ofs << this->GetTestModelString() << std::endl;
- switch (this->TestModel) {
+ switch (this->Impl->TestModel) {
case cmCTest::EXPERIMENTAL:
ofs << "Experimental" << std::endl;
break;
@@ -565,7 +583,7 @@ int cmCTest::Initialize(const char* binary_dir, cmCTestStartCommand* command)
return 0;
}
- if (this->TestModel == cmCTest::UNKNOWN) {
+ if (this->Impl->TestModel == cmCTest::UNKNOWN) {
if (model == cmCTest::UNKNOWN) {
cmCTestLog(this, ERROR_MESSAGE,
"TAG file does not contain model and "
@@ -577,8 +595,8 @@ int cmCTest::Initialize(const char* binary_dir, cmCTestStartCommand* command)
this->SetTestModel(model);
}
- if (model != this->TestModel && model != cmCTest::UNKNOWN &&
- this->TestModel != cmCTest::UNKNOWN) {
+ if (model != this->Impl->TestModel && model != cmCTest::UNKNOWN &&
+ this->Impl->TestModel != cmCTest::UNKNOWN) {
cmCTestOptionalLog(this, WARNING,
"Model given in TAG does not match "
"model given in ctest_start()"
@@ -586,14 +604,15 @@ int cmCTest::Initialize(const char* binary_dir, cmCTestStartCommand* command)
quiet);
}
- if (!this->SpecificTrack.empty() && track != this->SpecificTrack) {
+ if (!this->Impl->SpecificTrack.empty() &&
+ track != this->Impl->SpecificTrack) {
cmCTestOptionalLog(this, WARNING,
"Track given in TAG does not match "
"track given in ctest_start()"
<< std::endl,
quiet);
} else {
- this->SpecificTrack = track;
+ this->Impl->SpecificTrack = track;
}
cmCTestOptionalLog(this, OUTPUT,
@@ -603,7 +622,7 @@ int cmCTest::Initialize(const char* binary_dir, cmCTestStartCommand* command)
quiet);
}
- this->CurrentTag = tag;
+ this->Impl->CurrentTag = tag;
}
return 1;
@@ -613,9 +632,9 @@ bool cmCTest::InitializeFromCommand(cmCTestStartCommand* command)
{
std::string src_dir = this->GetCTestConfiguration("SourceDirectory");
std::string bld_dir = this->GetCTestConfiguration("BuildDirectory");
- this->BuildID = "";
+ this->Impl->BuildID = "";
for (Part p = PartStart; p != PartCount; p = Part(p + 1)) {
- this->Parts[p].SubmitFiles.clear();
+ this->Impl->Parts[p].SubmitFiles.clear();
}
cmMakefile* mf = command->GetMakefile();
@@ -669,18 +688,18 @@ bool cmCTest::InitializeFromCommand(cmCTestStartCommand* command)
bool cmCTest::UpdateCTestConfiguration()
{
- if (this->SuppressUpdatingCTestConfiguration) {
+ if (this->Impl->SuppressUpdatingCTestConfiguration) {
return true;
}
- std::string fileName = this->BinaryDir + "/CTestConfiguration.ini";
+ std::string fileName = this->Impl->BinaryDir + "/CTestConfiguration.ini";
if (!cmSystemTools::FileExists(fileName)) {
- fileName = this->BinaryDir + "/DartConfiguration.tcl";
+ fileName = this->Impl->BinaryDir + "/DartConfiguration.tcl";
}
cmCTestLog(this, HANDLER_VERBOSE_OUTPUT,
"UpdateCTestConfiguration from :" << fileName << "\n");
if (!cmSystemTools::FileExists(fileName)) {
// No need to exit if we are not producing XML
- if (this->ProduceXML) {
+ if (this->Impl->ProduceXML) {
cmCTestLog(this, ERROR_MESSAGE,
"Cannot find file: " << fileName << std::endl);
return false;
@@ -720,15 +739,15 @@ bool cmCTest::UpdateCTestConfiguration()
}
std::string key = line.substr(0, cpos);
std::string value = cmCTest::CleanString(line.substr(cpos + 1));
- this->CTestConfiguration[key] = value;
+ this->Impl->CTestConfiguration[key] = value;
}
fin.close();
}
if (!this->GetCTestConfiguration("BuildDirectory").empty()) {
- this->BinaryDir = this->GetCTestConfiguration("BuildDirectory");
- cmSystemTools::ChangeDirectory(this->BinaryDir);
+ this->Impl->BinaryDir = this->GetCTestConfiguration("BuildDirectory");
+ cmSystemTools::ChangeDirectory(this->Impl->BinaryDir);
}
- this->TimeOut =
+ this->Impl->TimeOut =
std::chrono::seconds(atoi(this->GetCTestConfiguration("TimeOut").c_str()));
std::string const& testLoad = this->GetCTestConfiguration("TestLoad");
if (!testLoad.empty()) {
@@ -740,8 +759,8 @@ bool cmCTest::UpdateCTestConfiguration()
"Invalid value for 'Test Load' : " << testLoad << std::endl);
}
}
- if (this->ProduceXML) {
- this->CompressXMLFiles =
+ if (this->Impl->ProduceXML) {
+ this->Impl->CompressXMLFiles =
cmSystemTools::IsOn(this->GetCTestConfiguration("CompressSubmission"));
}
return true;
@@ -760,21 +779,26 @@ void cmCTest::BlockTestErrorDiagnostics()
void cmCTest::SetTestModel(int mode)
{
- this->InteractiveDebugMode = false;
- this->TestModel = mode;
+ this->Impl->InteractiveDebugMode = false;
+ this->Impl->TestModel = mode;
+}
+
+int cmCTest::GetTestModel() const
+{
+ return this->Impl->TestModel;
}
bool cmCTest::SetTest(const char* ttype, bool report)
{
if (cmSystemTools::LowerCase(ttype) == "all") {
for (Part p = PartStart; p != PartCount; p = Part(p + 1)) {
- this->Parts[p].Enable();
+ this->Impl->Parts[p].Enable();
}
return true;
}
Part p = this->GetPartFromName(ttype);
if (p != PartCount) {
- this->Parts[p].Enable();
+ this->Impl->Parts[p].Enable();
return true;
}
if (report) {
@@ -792,7 +816,7 @@ void cmCTest::Finalize()
bool cmCTest::OpenOutputFile(const std::string& path, const std::string& name,
cmGeneratedFileStream& stream, bool compress)
{
- std::string testingDir = this->BinaryDir + "/Testing";
+ std::string testingDir = this->Impl->BinaryDir + "/Testing";
if (!path.empty()) {
testingDir += "/" + path;
}
@@ -819,7 +843,7 @@ bool cmCTest::OpenOutputFile(const std::string& path, const std::string& name,
return false;
}
if (compress) {
- if (this->CompressXMLFiles) {
+ if (this->Impl->CompressXMLFiles) {
stream.SetCompression(true);
}
}
@@ -844,40 +868,59 @@ bool cmCTest::AddIfExists(Part part, const char* file)
bool cmCTest::CTestFileExists(const std::string& filename)
{
- std::string testingDir =
- this->BinaryDir + "/Testing/" + this->CurrentTag + "/" + filename;
+ std::string testingDir = this->Impl->BinaryDir + "/Testing/" +
+ this->Impl->CurrentTag + "/" + filename;
return cmSystemTools::FileExists(testingDir);
}
-cmCTestGenericHandler* cmCTest::GetInitializedHandler(const char* handler)
+cmCTestBuildHandler* cmCTest::GetBuildHandler()
{
- cmCTest::t_TestingHandlers::iterator it =
- this->TestingHandlers.find(handler);
- if (it == this->TestingHandlers.end()) {
- return nullptr;
- }
- it->second->Initialize();
- return it->second;
+ return &this->Impl->BuildHandler;
}
-cmCTestGenericHandler* cmCTest::GetHandler(const char* handler)
+cmCTestBuildAndTestHandler* cmCTest::GetBuildAndTestHandler()
{
- cmCTest::t_TestingHandlers::iterator it =
- this->TestingHandlers.find(handler);
- if (it == this->TestingHandlers.end()) {
- return nullptr;
- }
- return it->second;
+ return &this->Impl->BuildAndTestHandler;
}
-int cmCTest::ExecuteHandler(const char* shandler)
+cmCTestCoverageHandler* cmCTest::GetCoverageHandler()
{
- cmCTestGenericHandler* handler = this->GetHandler(shandler);
- if (!handler) {
- return -1;
- }
- handler->Initialize();
- return handler->ProcessHandler();
+ return &this->Impl->CoverageHandler;
+}
+
+cmCTestScriptHandler* cmCTest::GetScriptHandler()
+{
+ return &this->Impl->ScriptHandler;
+}
+
+cmCTestTestHandler* cmCTest::GetTestHandler()
+{
+ return &this->Impl->TestHandler;
+}
+
+cmCTestUpdateHandler* cmCTest::GetUpdateHandler()
+{
+ return &this->Impl->UpdateHandler;
+}
+
+cmCTestConfigureHandler* cmCTest::GetConfigureHandler()
+{
+ return &this->Impl->ConfigureHandler;
+}
+
+cmCTestMemCheckHandler* cmCTest::GetMemCheckHandler()
+{
+ return &this->Impl->MemCheckHandler;
+}
+
+cmCTestSubmitHandler* cmCTest::GetSubmitHandler()
+{
+ return &this->Impl->SubmitHandler;
+}
+
+cmCTestUploadHandler* cmCTest::GetUploadHandler()
+{
+ return &this->Impl->UploadHandler;
}
int cmCTest::ProcessSteps()
@@ -887,11 +930,11 @@ int cmCTest::ProcessSteps()
int update_count = 0;
for (Part p = PartStart; notest && p != PartCount; p = Part(p + 1)) {
- notest = !this->Parts[p];
+ notest = !this->Impl->Parts[p];
}
- if (this->Parts[PartUpdate] &&
+ if (this->Impl->Parts[PartUpdate] &&
(this->GetRemainingTimeAllowed() > std::chrono::minutes(2))) {
- cmCTestGenericHandler* uphandler = this->GetHandler("update");
+ cmCTestUpdateHandler* uphandler = this->GetUpdateHandler();
uphandler->SetPersistentOption(
"SourceDirectory",
this->GetCTestConfiguration("SourceDirectory").c_str());
@@ -900,45 +943,45 @@ int cmCTest::ProcessSteps()
res |= cmCTest::UPDATE_ERRORS;
}
}
- if (this->TestModel == cmCTest::CONTINUOUS && !update_count) {
+ if (this->Impl->TestModel == cmCTest::CONTINUOUS && !update_count) {
return 0;
}
- if (this->Parts[PartConfigure] &&
+ if (this->Impl->Parts[PartConfigure] &&
(this->GetRemainingTimeAllowed() > std::chrono::minutes(2))) {
- if (this->GetHandler("configure")->ProcessHandler() < 0) {
+ if (this->GetConfigureHandler()->ProcessHandler() < 0) {
res |= cmCTest::CONFIGURE_ERRORS;
}
}
- if (this->Parts[PartBuild] &&
+ if (this->Impl->Parts[PartBuild] &&
(this->GetRemainingTimeAllowed() > std::chrono::minutes(2))) {
this->UpdateCTestConfiguration();
- if (this->GetHandler("build")->ProcessHandler() < 0) {
+ if (this->GetBuildHandler()->ProcessHandler() < 0) {
res |= cmCTest::BUILD_ERRORS;
}
}
- if ((this->Parts[PartTest] || notest) &&
+ if ((this->Impl->Parts[PartTest] || notest) &&
(this->GetRemainingTimeAllowed() > std::chrono::minutes(2))) {
this->UpdateCTestConfiguration();
- if (this->GetHandler("test")->ProcessHandler() < 0) {
+ if (this->GetTestHandler()->ProcessHandler() < 0) {
res |= cmCTest::TEST_ERRORS;
}
}
- if (this->Parts[PartCoverage] &&
+ if (this->Impl->Parts[PartCoverage] &&
(this->GetRemainingTimeAllowed() > std::chrono::minutes(2))) {
this->UpdateCTestConfiguration();
- if (this->GetHandler("coverage")->ProcessHandler() < 0) {
+ if (this->GetCoverageHandler()->ProcessHandler() < 0) {
res |= cmCTest::COVERAGE_ERRORS;
}
}
- if (this->Parts[PartMemCheck] &&
+ if (this->Impl->Parts[PartMemCheck] &&
(this->GetRemainingTimeAllowed() > std::chrono::minutes(2))) {
this->UpdateCTestConfiguration();
- if (this->GetHandler("memcheck")->ProcessHandler() < 0) {
+ if (this->GetMemCheckHandler()->ProcessHandler() < 0) {
res |= cmCTest::MEMORY_ERRORS;
}
}
if (!notest) {
- std::string notes_dir = this->BinaryDir + "/Testing/Notes";
+ std::string notes_dir = this->Impl->BinaryDir + "/Testing/Notes";
if (cmSystemTools::FileIsDirectory(notes_dir)) {
cmsys::Directory d;
d.Load(notes_dir);
@@ -948,24 +991,24 @@ int cmCTest::ProcessSteps()
std::string fullname = notes_dir + "/" + file;
if (cmSystemTools::FileExists(fullname) &&
!cmSystemTools::FileIsDirectory(fullname)) {
- if (!this->NotesFiles.empty()) {
- this->NotesFiles += ";";
+ if (!this->Impl->NotesFiles.empty()) {
+ this->Impl->NotesFiles += ";";
}
- this->NotesFiles += fullname;
- this->Parts[PartNotes].Enable();
+ this->Impl->NotesFiles += fullname;
+ this->Impl->Parts[PartNotes].Enable();
}
}
}
}
- if (this->Parts[PartNotes]) {
+ if (this->Impl->Parts[PartNotes]) {
this->UpdateCTestConfiguration();
- if (!this->NotesFiles.empty()) {
- this->GenerateNotesFile(this->NotesFiles.c_str());
+ if (!this->Impl->NotesFiles.empty()) {
+ this->GenerateNotesFile(this->Impl->NotesFiles.c_str());
}
}
- if (this->Parts[PartSubmit]) {
+ if (this->Impl->Parts[PartSubmit]) {
this->UpdateCTestConfiguration();
- if (this->GetHandler("submit")->ProcessHandler() < 0) {
+ if (this->GetSubmitHandler()->ProcessHandler() < 0) {
res |= cmCTest::SUBMIT_ERRORS;
}
}
@@ -977,10 +1020,10 @@ int cmCTest::ProcessSteps()
std::string cmCTest::GetTestModelString()
{
- if (!this->SpecificTrack.empty()) {
- return this->SpecificTrack;
+ if (!this->Impl->SpecificTrack.empty()) {
+ return this->Impl->SpecificTrack;
}
- switch (this->TestModel) {
+ switch (this->Impl->TestModel) {
case cmCTest::NIGHTLY:
return "Nightly";
case cmCTest::CONTINUOUS:
@@ -1139,8 +1182,9 @@ int cmCTest::RunTest(std::vector<const char*> argv, std::string* output,
if (timeout != cmCTest::MaxDuration()) {
timeout -= std::chrono::minutes(2);
}
- if (this->TimeOut > cmDuration::zero() && this->TimeOut < timeout) {
- timeout = this->TimeOut;
+ if (this->Impl->TimeOut > cmDuration::zero() &&
+ this->Impl->TimeOut < timeout) {
+ timeout = this->Impl->TimeOut;
}
if (testTimeOut > cmDuration::zero() &&
testTimeOut < this->GetRemainingTimeAllowed()) {
@@ -1158,10 +1202,10 @@ int cmCTest::RunTest(std::vector<const char*> argv, std::string* output,
: std::to_string(cmDurationTo<unsigned int>(timeout)))
<< "\n");
if (cmSystemTools::SameFile(argv[0], cmSystemTools::GetCTestCommand()) &&
- !this->ForceNewCTestProcess) {
+ !this->Impl->ForceNewCTestProcess) {
cmCTest inst;
- inst.ConfigType = this->ConfigType;
- inst.TimeOut = timeout;
+ inst.Impl->ConfigType = this->Impl->ConfigType;
+ inst.Impl->TimeOut = timeout;
// Capture output of the child ctest.
std::ostringstream oss;
@@ -1267,11 +1311,11 @@ int cmCTest::RunTest(std::vector<const char*> argv, std::string* output,
if (result == cmsysProcess_State_Exited) {
*retVal = cmsysProcess_GetExitValue(cp);
- if (*retVal != 0 && this->OutputTestOutputOnTestFailure) {
+ if (*retVal != 0 && this->Impl->OutputTestOutputOnTestFailure) {
OutputTestErrors(tempOutput);
}
} else if (result == cmsysProcess_State_Exception) {
- if (this->OutputTestOutputOnTestFailure) {
+ if (this->Impl->OutputTestOutputOnTestFailure) {
OutputTestErrors(tempOutput);
}
*retVal = cmsysProcess_GetExitException(cp);
@@ -1330,7 +1374,7 @@ std::string cmCTest::SafeBuildIdField(const std::string& value)
void cmCTest::StartXML(cmXMLWriter& xml, bool append)
{
- if (this->CurrentTag.empty()) {
+ if (this->Impl->CurrentTag.empty()) {
cmCTestLog(this, ERROR_MESSAGE,
"Current Tag empty, this may mean"
" NightlStartTime was not set correctly."
@@ -1346,7 +1390,7 @@ void cmCTest::StartXML(cmXMLWriter& xml, bool append)
std::string buildname =
cmCTest::SafeBuildIdField(this->GetCTestConfiguration("BuildName"));
- std::string stamp = cmCTest::SafeBuildIdField(this->CurrentTag + "-" +
+ std::string stamp = cmCTest::SafeBuildIdField(this->Impl->CurrentTag + "-" +
this->GetTestModelString());
std::string site =
cmCTest::SafeBuildIdField(this->GetCTestConfiguration("Site"));
@@ -1394,8 +1438,7 @@ void cmCTest::StartXML(cmXMLWriter& xml, bool append)
void cmCTest::AddSiteProperties(cmXMLWriter& xml)
{
- cmCTestScriptHandler* ch =
- static_cast<cmCTestScriptHandler*>(this->GetHandler("script"));
+ cmCTestScriptHandler* ch = this->GetScriptHandler();
cmake* cm = ch->GetCMake();
// if no CMake then this is the old style script and props like
// this will not work anyway.
@@ -1465,7 +1508,7 @@ void cmCTest::EndXML(cmXMLWriter& xml)
}
int cmCTest::GenerateCTestNotesOutput(cmXMLWriter& xml,
- const cmCTest::VectorOfStrings& files)
+ std::vector<std::string> const& files)
{
std::string buildname =
cmCTest::SafeBuildIdField(this->GetCTestConfiguration("BuildName"));
@@ -1477,7 +1520,7 @@ int cmCTest::GenerateCTestNotesOutput(cmXMLWriter& xml,
xml.StartElement("Site");
xml.Attribute("BuildName", buildname);
xml.Attribute("BuildStamp",
- this->CurrentTag + "-" + this->GetTestModelString());
+ this->Impl->CurrentTag + "-" + this->GetTestModelString());
xml.Attribute("Name", this->GetCTestConfiguration("Site"));
xml.Attribute("Generator",
std::string("ctest") + cmVersion::GetCMakeVersion());
@@ -1515,10 +1558,10 @@ int cmCTest::GenerateCTestNotesOutput(cmXMLWriter& xml,
return 1;
}
-int cmCTest::GenerateNotesFile(const VectorOfStrings& files)
+int cmCTest::GenerateNotesFile(std::vector<std::string> const& files)
{
cmGeneratedFileStream ofs;
- if (!this->OpenOutputFile(this->CurrentTag, "Notes.xml", ofs)) {
+ if (!this->OpenOutputFile(this->Impl->CurrentTag, "Notes.xml", ofs)) {
cmCTestLog(this, ERROR_MESSAGE, "Cannot open notes file" << std::endl);
return 1;
}
@@ -1533,11 +1576,10 @@ int cmCTest::GenerateNotesFile(const char* cfiles)
return 1;
}
- VectorOfStrings files;
-
cmCTestLog(this, OUTPUT, "Create notes file" << std::endl);
- files = cmSystemTools::SplitString(cfiles, ';');
+ std::vector<std::string> const files =
+ cmSystemTools::SplitString(cfiles, ';');
if (files.empty()) {
return 1;
}
@@ -1548,14 +1590,14 @@ int cmCTest::GenerateNotesFile(const char* cfiles)
int cmCTest::GenerateDoneFile()
{
cmGeneratedFileStream ofs;
- if (!this->OpenOutputFile(this->CurrentTag, "Done.xml", ofs)) {
+ if (!this->OpenOutputFile(this->Impl->CurrentTag, "Done.xml", ofs)) {
cmCTestLog(this, ERROR_MESSAGE, "Cannot open done file" << std::endl);
return 1;
}
cmXMLWriter xml(ofs);
xml.StartDocument();
xml.StartElement("Done");
- xml.Element("buildId", this->BuildID);
+ xml.Element("buildId", this->Impl->BuildID);
xml.Element("time", std::chrono::system_clock::now());
xml.EndElement(); // Done
xml.EndDocument();
@@ -1604,7 +1646,7 @@ std::string cmCTest::Base64EncodeFile(std::string const& file)
return std::string(&encoded_buffer[0], rlen);
}
-bool cmCTest::SubmitExtraFiles(const VectorOfStrings& files)
+bool cmCTest::SubmitExtraFiles(std::vector<std::string> const& files)
{
for (std::string const& file : files) {
if (!cmSystemTools::FileExists(file)) {
@@ -1624,11 +1666,10 @@ bool cmCTest::SubmitExtraFiles(const char* cfiles)
return true;
}
- VectorOfStrings files;
-
cmCTestLog(this, OUTPUT, "Submit extra files" << std::endl);
- files = cmSystemTools::SplitString(cfiles, ';');
+ std::vector<std::string> const files =
+ cmSystemTools::SplitString(cfiles, ';');
if (files.empty()) {
return true;
}
@@ -1796,17 +1837,17 @@ bool cmCTest::HandleCommandLineArguments(size_t& i,
{
std::string arg = args[i];
if (this->CheckArgument(arg, "-F")) {
- this->Failover = true;
+ this->Impl->Failover = true;
}
if (this->CheckArgument(arg, "-j", "--parallel") && i < args.size() - 1) {
i++;
int plevel = atoi(args[i].c_str());
this->SetParallelLevel(plevel);
- this->ParallelLevelSetInCli = true;
+ this->Impl->ParallelLevelSetInCli = true;
} else if (arg.find("-j") == 0) {
int plevel = atoi(arg.substr(2).c_str());
this->SetParallelLevel(plevel);
- this->ParallelLevelSetInCli = true;
+ this->Impl->ParallelLevelSetInCli = true;
}
if (this->CheckArgument(arg, "--repeat-until-fail")) {
if (i >= args.size() - 1) {
@@ -1820,9 +1861,9 @@ bool cmCTest::HandleCommandLineArguments(size_t& i,
"'--repeat-until-fail' given non-integer value '" + args[i] + "'";
return false;
}
- this->RepeatTests = static_cast<int>(repeat);
+ this->Impl->RepeatTests = static_cast<int>(repeat);
if (repeat > 1) {
- this->RepeatUntilFail = true;
+ this->Impl->RepeatUntilFail = true;
}
}
@@ -1838,21 +1879,21 @@ bool cmCTest::HandleCommandLineArguments(size_t& i,
}
if (this->CheckArgument(arg, "--no-compress-output")) {
- this->CompressTestOutput = false;
+ this->Impl->CompressTestOutput = false;
}
if (this->CheckArgument(arg, "--print-labels")) {
- this->PrintLabels = true;
+ this->Impl->PrintLabels = true;
}
if (this->CheckArgument(arg, "--http1.0")) {
- this->UseHTTP10 = true;
+ this->Impl->UseHTTP10 = true;
}
if (this->CheckArgument(arg, "--timeout") && i < args.size() - 1) {
i++;
auto timeout = cmDuration(atof(args[i].c_str()));
- this->GlobalTimeout = timeout;
+ this->Impl->GlobalTimeout = timeout;
}
if (this->CheckArgument(arg, "--stop-time") && i < args.size() - 1) {
@@ -1867,47 +1908,44 @@ bool cmCTest::HandleCommandLineArguments(size_t& i,
}
if (this->CheckArgument(arg, "--debug")) {
- this->Debug = true;
- this->ShowLineNumbers = true;
+ this->Impl->Debug = true;
+ this->Impl->ShowLineNumbers = true;
}
if (this->CheckArgument(arg, "--track") && i < args.size() - 1) {
i++;
- this->SpecificTrack = args[i];
+ this->Impl->SpecificTrack = args[i];
}
if (this->CheckArgument(arg, "--show-line-numbers")) {
- this->ShowLineNumbers = true;
+ this->Impl->ShowLineNumbers = true;
}
if (this->CheckArgument(arg, "--no-label-summary")) {
- this->LabelSummary = false;
+ this->Impl->LabelSummary = false;
}
if (this->CheckArgument(arg, "--no-subproject-summary")) {
- this->SubprojectSummary = false;
+ this->Impl->SubprojectSummary = false;
}
if (this->CheckArgument(arg, "-Q", "--quiet")) {
- this->Quiet = true;
+ this->Impl->Quiet = true;
}
if (this->CheckArgument(arg, "--progress")) {
- this->TestProgressOutput = true;
+ this->Impl->TestProgressOutput = true;
}
if (this->CheckArgument(arg, "-V", "--verbose")) {
- this->Verbose = true;
+ this->Impl->Verbose = true;
}
if (this->CheckArgument(arg, "-VV", "--extra-verbose")) {
- this->ExtraVerbose = true;
- this->Verbose = true;
+ this->Impl->ExtraVerbose = true;
+ this->Impl->Verbose = true;
}
if (this->CheckArgument(arg, "--output-on-failure")) {
- this->OutputTestOutputOnTestFailure = true;
+ this->Impl->OutputTestOutputOnTestFailure = true;
}
if (this->CheckArgument(arg, "--test-output-size-passed") &&
i < args.size() - 1) {
i++;
long outputSize;
if (cmSystemTools::StringToLong(args[i].c_str(), &outputSize)) {
- if (cmCTestTestHandler* pCTestTestHandler =
- static_cast<cmCTestTestHandler*>(this->TestingHandlers["test"])) {
- pCTestTestHandler->SetTestOutputSizePassed(int(outputSize));
- }
+ this->Impl->TestHandler.SetTestOutputSizePassed(int(outputSize));
} else {
cmCTestLog(this, WARNING,
"Invalid value for '--test-output-size-passed': " << args[i]
@@ -1919,10 +1957,7 @@ bool cmCTest::HandleCommandLineArguments(size_t& i,
i++;
long outputSize;
if (cmSystemTools::StringToLong(args[i].c_str(), &outputSize)) {
- if (cmCTestTestHandler* pCTestTestHandler =
- static_cast<cmCTestTestHandler*>(this->TestingHandlers["test"])) {
- pCTestTestHandler->SetTestOutputSizeFailed(int(outputSize));
- }
+ this->Impl->TestHandler.SetTestOutputSizeFailed(int(outputSize));
} else {
cmCTestLog(this, WARNING,
"Invalid value for '--test-output-size-failed': " << args[i]
@@ -1930,10 +1965,10 @@ bool cmCTest::HandleCommandLineArguments(size_t& i,
}
}
if (this->CheckArgument(arg, "-N", "--show-only")) {
- this->ShowOnly = true;
+ this->Impl->ShowOnly = true;
}
if (cmSystemTools::StringStartsWith(arg.c_str(), "--show-only=")) {
- this->ShowOnly = true;
+ this->Impl->ShowOnly = true;
// Check if a specific format is requested. Defaults to human readable
// text.
@@ -1941,9 +1976,9 @@ bool cmCTest::HandleCommandLineArguments(size_t& i,
std::string format = arg.substr(argWithFormat.length());
if (format == "json-v1") {
// Force quiet mode so the only output is the json object model.
- this->Quiet = true;
- this->OutputAsJson = true;
- this->OutputAsJsonVersion = 1;
+ this->Impl->Quiet = true;
+ this->Impl->OutputAsJson = true;
+ this->Impl->OutputAsJsonVersion = 1;
} else if (format != "human") {
errormsg = "'--show-only=' given unknown value '" + format + "'";
return false;
@@ -1956,25 +1991,25 @@ bool cmCTest::HandleCommandLineArguments(size_t& i,
}
if (this->CheckArgument(arg, "--tomorrow-tag")) {
- this->TomorrowTag = true;
+ this->Impl->TomorrowTag = true;
}
if (this->CheckArgument(arg, "--force-new-ctest-process")) {
- this->ForceNewCTestProcess = true;
+ this->Impl->ForceNewCTestProcess = true;
}
if (this->CheckArgument(arg, "-W", "--max-width") && i < args.size() - 1) {
i++;
- this->MaxTestNameWidth = atoi(args[i].c_str());
+ this->Impl->MaxTestNameWidth = atoi(args[i].c_str());
}
if (this->CheckArgument(arg, "--interactive-debug-mode") &&
i < args.size() - 1) {
i++;
- this->InteractiveDebugMode = cmSystemTools::IsOn(args[i]);
+ this->Impl->InteractiveDebugMode = cmSystemTools::IsOn(args[i]);
}
if (this->CheckArgument(arg, "--submit-index") && i < args.size() - 1) {
i++;
- this->SubmitIndex = atoi(args[i].c_str());
- if (this->SubmitIndex < 0) {
- this->SubmitIndex = 0;
+ this->Impl->SubmitIndex = atoi(args[i].c_str());
+ if (this->Impl->SubmitIndex < 0) {
+ this->Impl->SubmitIndex = 0;
}
}
@@ -1983,7 +2018,7 @@ bool cmCTest::HandleCommandLineArguments(size_t& i,
this->AddCTestConfigurationOverwrite(args[i]);
}
if (this->CheckArgument(arg, "-A", "--add-notes") && i < args.size() - 1) {
- this->ProduceXML = true;
+ this->Impl->ProduceXML = true;
this->SetTest("Notes");
i++;
this->SetNotesFiles(args[i].c_str());
@@ -1993,78 +2028,75 @@ bool cmCTest::HandleCommandLineArguments(size_t& i,
if (this->CheckArgument(arg, "-I", "--tests-information") &&
i < args.size() - 1) {
i++;
- this->GetHandler("test")->SetPersistentOption("TestsToRunInformation",
- args[i].c_str());
- this->GetHandler("memcheck")
- ->SetPersistentOption("TestsToRunInformation", args[i].c_str());
+ this->GetTestHandler()->SetPersistentOption("TestsToRunInformation",
+ args[i].c_str());
+ this->GetMemCheckHandler()->SetPersistentOption("TestsToRunInformation",
+ args[i].c_str());
}
if (this->CheckArgument(arg, "-U", "--union")) {
- this->GetHandler("test")->SetPersistentOption("UseUnion", "true");
- this->GetHandler("memcheck")->SetPersistentOption("UseUnion", "true");
+ this->GetTestHandler()->SetPersistentOption("UseUnion", "true");
+ this->GetMemCheckHandler()->SetPersistentOption("UseUnion", "true");
}
if (this->CheckArgument(arg, "-R", "--tests-regex") && i < args.size() - 1) {
i++;
- this->GetHandler("test")->SetPersistentOption("IncludeRegularExpression",
- args[i].c_str());
- this->GetHandler("memcheck")
- ->SetPersistentOption("IncludeRegularExpression", args[i].c_str());
+ this->GetTestHandler()->SetPersistentOption("IncludeRegularExpression",
+ args[i].c_str());
+ this->GetMemCheckHandler()->SetPersistentOption("IncludeRegularExpression",
+ args[i].c_str());
}
if (this->CheckArgument(arg, "-L", "--label-regex") && i < args.size() - 1) {
i++;
- this->GetHandler("test")->SetPersistentOption("LabelRegularExpression",
- args[i].c_str());
- this->GetHandler("memcheck")
- ->SetPersistentOption("LabelRegularExpression", args[i].c_str());
+ this->GetTestHandler()->SetPersistentOption("LabelRegularExpression",
+ args[i].c_str());
+ this->GetMemCheckHandler()->SetPersistentOption("LabelRegularExpression",
+ args[i].c_str());
}
if (this->CheckArgument(arg, "-LE", "--label-exclude") &&
i < args.size() - 1) {
i++;
- this->GetHandler("test")->SetPersistentOption(
+ this->GetTestHandler()->SetPersistentOption(
+ "ExcludeLabelRegularExpression", args[i].c_str());
+ this->GetMemCheckHandler()->SetPersistentOption(
"ExcludeLabelRegularExpression", args[i].c_str());
- this->GetHandler("memcheck")
- ->SetPersistentOption("ExcludeLabelRegularExpression", args[i].c_str());
}
if (this->CheckArgument(arg, "-E", "--exclude-regex") &&
i < args.size() - 1) {
i++;
- this->GetHandler("test")->SetPersistentOption("ExcludeRegularExpression",
- args[i].c_str());
- this->GetHandler("memcheck")
- ->SetPersistentOption("ExcludeRegularExpression", args[i].c_str());
+ this->GetTestHandler()->SetPersistentOption("ExcludeRegularExpression",
+ args[i].c_str());
+ this->GetMemCheckHandler()->SetPersistentOption("ExcludeRegularExpression",
+ args[i].c_str());
}
if (this->CheckArgument(arg, "-FA", "--fixture-exclude-any") &&
i < args.size() - 1) {
i++;
- this->GetHandler("test")->SetPersistentOption(
+ this->GetTestHandler()->SetPersistentOption(
+ "ExcludeFixtureRegularExpression", args[i].c_str());
+ this->GetMemCheckHandler()->SetPersistentOption(
"ExcludeFixtureRegularExpression", args[i].c_str());
- this->GetHandler("memcheck")
- ->SetPersistentOption("ExcludeFixtureRegularExpression",
- args[i].c_str());
}
if (this->CheckArgument(arg, "-FS", "--fixture-exclude-setup") &&
i < args.size() - 1) {
i++;
- this->GetHandler("test")->SetPersistentOption(
+ this->GetTestHandler()->SetPersistentOption(
+ "ExcludeFixtureSetupRegularExpression", args[i].c_str());
+ this->GetMemCheckHandler()->SetPersistentOption(
"ExcludeFixtureSetupRegularExpression", args[i].c_str());
- this->GetHandler("memcheck")
- ->SetPersistentOption("ExcludeFixtureSetupRegularExpression",
- args[i].c_str());
}
if (this->CheckArgument(arg, "-FC", "--fixture-exclude-cleanup") &&
i < args.size() - 1) {
i++;
- this->GetHandler("test")->SetPersistentOption(
+ this->GetTestHandler()->SetPersistentOption(
+ "ExcludeFixtureCleanupRegularExpression", args[i].c_str());
+ this->GetMemCheckHandler()->SetPersistentOption(
"ExcludeFixtureCleanupRegularExpression", args[i].c_str());
- this->GetHandler("memcheck")
- ->SetPersistentOption("ExcludeFixtureCleanupRegularExpression",
- args[i].c_str());
}
if (this->CheckArgument(arg, "--rerun-failed")) {
- this->GetHandler("test")->SetPersistentOption("RerunFailed", "true");
- this->GetHandler("memcheck")->SetPersistentOption("RerunFailed", "true");
+ this->GetTestHandler()->SetPersistentOption("RerunFailed", "true");
+ this->GetMemCheckHandler()->SetPersistentOption("RerunFailed", "true");
}
return true;
}
@@ -2111,10 +2143,9 @@ void cmCTest::HandleScriptArguments(size_t& i, std::vector<std::string>& args,
std::string arg = args[i];
if (this->CheckArgument(arg, "-SP", "--script-new-process") &&
i < args.size() - 1) {
- this->RunConfigurationScript = true;
+ this->Impl->RunConfigurationScript = true;
i++;
- cmCTestScriptHandler* ch =
- static_cast<cmCTestScriptHandler*>(this->GetHandler("script"));
+ cmCTestScriptHandler* ch = this->GetScriptHandler();
// -SR is an internal argument, -SP should be ignored when it is passed
if (!SRArgumentSpecified) {
ch->AddConfigurationScript(args[i].c_str(), false);
@@ -2123,18 +2154,16 @@ void cmCTest::HandleScriptArguments(size_t& i, std::vector<std::string>& args,
if (this->CheckArgument(arg, "-SR", "--script-run") && i < args.size() - 1) {
SRArgumentSpecified = true;
- this->RunConfigurationScript = true;
+ this->Impl->RunConfigurationScript = true;
i++;
- cmCTestScriptHandler* ch =
- static_cast<cmCTestScriptHandler*>(this->GetHandler("script"));
+ cmCTestScriptHandler* ch = this->GetScriptHandler();
ch->AddConfigurationScript(args[i].c_str(), true);
}
if (this->CheckArgument(arg, "-S", "--script") && i < args.size() - 1) {
- this->RunConfigurationScript = true;
+ this->Impl->RunConfigurationScript = true;
i++;
- cmCTestScriptHandler* ch =
- static_cast<cmCTestScriptHandler*>(this->GetHandler("script"));
+ cmCTestScriptHandler* ch = this->GetScriptHandler();
// -SR is an internal argument, -S should be ignored when it is passed
if (!SRArgumentSpecified) {
ch->AddConfigurationScript(args[i].c_str(), true);
@@ -2149,7 +2178,7 @@ bool cmCTest::AddVariableDefinition(const std::string& arg)
cmStateEnums::CacheEntryType type = cmStateEnums::UNINITIALIZED;
if (cmake::ParseCacheEntry(arg, name, value, type)) {
- this->Definitions[name] = value;
+ this->Impl->Definitions[name] = value;
return true;
}
@@ -2165,8 +2194,8 @@ int cmCTest::Run(std::vector<std::string>& args, std::string* output)
bool SRArgumentSpecified = false;
// copy the command line
- this->InitialCommandLineArguments.insert(
- this->InitialCommandLineArguments.end(), args.begin(), args.end());
+ this->Impl->InitialCommandLineArguments.insert(
+ this->Impl->InitialCommandLineArguments.end(), args.begin(), args.end());
// process the command line arguments
for (size_t i = 1; i < args.size(); ++i) {
@@ -2183,7 +2212,7 @@ int cmCTest::Run(std::vector<std::string>& args, std::string* output)
// --dashboard: handle a request for a dashboard
std::string arg = args[i];
if (this->CheckArgument(arg, "-D", "--dashboard") && i < args.size() - 1) {
- this->ProduceXML = true;
+ this->Impl->ProduceXML = true;
i++;
std::string targ = args[i];
// AddTestsForDashboard parses the dashboard type and converts it
@@ -2219,7 +2248,7 @@ int cmCTest::Run(std::vector<std::string>& args, std::string* output)
// --extra-submit
if (this->CheckArgument(arg, "--extra-submit") && i < args.size() - 1) {
- this->ProduceXML = true;
+ this->Impl->ProduceXML = true;
this->SetTest("Submit");
i++;
if (!this->SubmitExtraFiles(args[i].c_str())) {
@@ -2234,14 +2263,14 @@ int cmCTest::Run(std::vector<std::string>& args, std::string* output)
// --schedule-random
if (this->CheckArgument(arg, "--schedule-random")) {
- this->ScheduleType = "Random";
+ this->Impl->ScheduleType = "Random";
}
// pass the argument to all the handlers as well, but i may no longer be
// set to what it was originally so I'm not sure this is working as
// intended
- for (auto& handler : this->TestingHandlers) {
- if (!handler.second->ProcessCommandLineArguments(arg, i, args)) {
+ for (auto& handler : this->Impl->GetTestingHandlers()) {
+ if (!handler->ProcessCommandLineArguments(arg, i, args)) {
cmCTestLog(this, ERROR_MESSAGE,
"Problem parsing command line arguments within a handler");
return 0;
@@ -2250,7 +2279,7 @@ int cmCTest::Run(std::vector<std::string>& args, std::string* output)
} // the close of the for argument loop
// handle CTEST_PARALLEL_LEVEL environment variable
- if (!this->ParallelLevelSetInCli) {
+ if (!this->Impl->ParallelLevelSetInCli) {
std::string parallel;
if (cmSystemTools::GetEnv("CTEST_PARALLEL_LEVEL", parallel)) {
int plevel = atoi(parallel.c_str());
@@ -2260,10 +2289,10 @@ int cmCTest::Run(std::vector<std::string>& args, std::string* output)
// TestProgressOutput only supported if console supports it and not logging
// to a file
- this->TestProgressOutput = this->TestProgressOutput &&
- !this->OutputLogFile && this->ProgressOutputSupportedByConsole();
+ this->Impl->TestProgressOutput = this->Impl->TestProgressOutput &&
+ !this->Impl->OutputLogFile && this->ProgressOutputSupportedByConsole();
#ifdef _WIN32
- if (this->TestProgressOutput) {
+ if (this->Impl->TestProgressOutput) {
// Disable output line buffering so we can print content without
// a newline.
std::setvbuf(stdout, nullptr, _IONBF, 0);
@@ -2290,7 +2319,7 @@ bool cmCTest::HandleTestActionArgument(const char* ctestExec, size_t& i,
std::string arg = args[i];
if (this->CheckArgument(arg, "-T", "--test-action") &&
(i < args.size() - 1)) {
- this->ProduceXML = true;
+ this->Impl->ProduceXML = true;
i++;
if (!this->SetTest(args[i].c_str(), false)) {
success = false;
@@ -2350,16 +2379,16 @@ int cmCTest::ExecuteTests()
{
int res;
// call process directory
- if (this->RunConfigurationScript) {
- if (this->ExtraVerbose) {
+ if (this->Impl->RunConfigurationScript) {
+ if (this->Impl->ExtraVerbose) {
cmCTestLog(this, OUTPUT, "* Extra verbosity turned on" << std::endl);
}
- for (auto& handler : this->TestingHandlers) {
- handler.second->SetVerbose(this->ExtraVerbose);
- handler.second->SetSubmitIndex(this->SubmitIndex);
+ for (auto& handler : this->Impl->GetTestingHandlers()) {
+ handler->SetVerbose(this->Impl->ExtraVerbose);
+ handler->SetSubmitIndex(this->Impl->SubmitIndex);
}
- this->GetHandler("script")->SetVerbose(this->Verbose);
- res = this->GetHandler("script")->ProcessHandler();
+ this->GetScriptHandler()->SetVerbose(this->Impl->Verbose);
+ res = this->GetScriptHandler()->ProcessHandler();
if (res != 0) {
cmCTestLog(this, DEBUG,
"running script failing returning: " << res << std::endl);
@@ -2368,11 +2397,11 @@ int cmCTest::ExecuteTests()
} else {
// What is this? -V seems to be the same as -VV,
// and Verbose is always on in this case
- this->ExtraVerbose = this->Verbose;
- this->Verbose = true;
- for (auto& handler : this->TestingHandlers) {
- handler.second->SetVerbose(this->Verbose);
- handler.second->SetSubmitIndex(this->SubmitIndex);
+ this->Impl->ExtraVerbose = this->Impl->Verbose;
+ this->Impl->Verbose = true;
+ for (auto& handler : this->Impl->GetTestingHandlers()) {
+ handler->SetVerbose(this->Impl->Verbose);
+ handler->SetSubmitIndex(this->Impl->SubmitIndex);
}
std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
if (!this->Initialize(cwd.c_str(), nullptr)) {
@@ -2393,9 +2422,8 @@ int cmCTest::ExecuteTests()
int cmCTest::RunCMakeAndTest(std::string* output)
{
- this->Verbose = true;
- cmCTestBuildAndTestHandler* handler =
- static_cast<cmCTestBuildAndTestHandler*>(this->GetHandler("buildtest"));
+ this->Impl->Verbose = true;
+ cmCTestBuildAndTestHandler* handler = this->GetBuildAndTestHandler();
int retv = handler->ProcessHandler();
*output = handler->GetOutput();
#ifdef CMAKE_BUILD_WITH_CMAKE
@@ -2413,7 +2441,12 @@ void cmCTest::SetNotesFiles(const char* notes)
if (!notes) {
return;
}
- this->NotesFiles = notes;
+ this->Impl->NotesFiles = notes;
+}
+
+std::chrono::system_clock::time_point cmCTest::GetStopTime() const
+{
+ return this->Impl->StopTime;
}
void cmCTest::SetStopTime(std::string const& time_str)
@@ -2443,21 +2476,29 @@ void cmCTest::SetStopTime(std::string const& time_str)
time_t stop_time = curl_getdate(buf, &current_time);
if (stop_time == -1) {
- this->StopTime = std::chrono::system_clock::time_point();
+ this->Impl->StopTime = std::chrono::system_clock::time_point();
return;
}
- this->StopTime = std::chrono::system_clock::from_time_t(stop_time);
+ this->Impl->StopTime = std::chrono::system_clock::from_time_t(stop_time);
if (stop_time < current_time) {
- this->StopTime += std::chrono::hours(24);
+ this->Impl->StopTime += std::chrono::hours(24);
}
}
+std::string cmCTest::GetScheduleType() const
+{
+ return this->Impl->ScheduleType;
+}
+
+void cmCTest::SetScheduleType(std::string const& type)
+{
+ this->Impl->ScheduleType = type;
+}
+
int cmCTest::ReadCustomConfigurationFileTree(const char* dir, cmMakefile* mf)
{
bool found = false;
- VectorOfStrings dirs;
- VectorOfStrings ndirs;
cmCTestLog(this, DEBUG,
"* Read custom CTest configuration directory: " << dir
<< std::endl);
@@ -2505,7 +2546,7 @@ int cmCTest::ReadCustomConfigurationFileTree(const char* dir, cmMakefile* mf)
}
if (found) {
- for (auto& handler : this->TestingHandlers) {
+ for (auto& handler : this->Impl->GetNamedTestingHandlers()) {
cmCTestLog(this, DEBUG,
"* Read custom CTest configuration vectors for handler: "
<< handler.first << " (" << handler.second << ")"
@@ -2596,16 +2637,16 @@ std::string cmCTest::GetShortPathToFile(const char* cfname)
std::string cmCTest::GetCTestConfiguration(const std::string& name)
{
- if (this->CTestConfigurationOverwrites.find(name) !=
- this->CTestConfigurationOverwrites.end()) {
- return this->CTestConfigurationOverwrites[name];
+ if (this->Impl->CTestConfigurationOverwrites.find(name) !=
+ this->Impl->CTestConfigurationOverwrites.end()) {
+ return this->Impl->CTestConfigurationOverwrites[name];
}
- return this->CTestConfiguration[name];
+ return this->Impl->CTestConfiguration[name];
}
void cmCTest::EmptyCTestConfiguration()
{
- this->CTestConfiguration.clear();
+ this->Impl->CTestConfiguration.clear();
}
void cmCTest::SetCTestConfiguration(const char* name, const char* value,
@@ -2620,10 +2661,10 @@ void cmCTest::SetCTestConfiguration(const char* name, const char* value,
return;
}
if (!value) {
- this->CTestConfiguration.erase(name);
+ this->Impl->CTestConfiguration.erase(name);
return;
}
- this->CTestConfiguration[name] = value;
+ this->Impl->CTestConfiguration[name] = value;
}
std::string cmCTest::GetSubmitURL()
@@ -2654,69 +2695,190 @@ std::string cmCTest::GetSubmitURL()
std::string cmCTest::GetCurrentTag()
{
- return this->CurrentTag;
+ return this->Impl->CurrentTag;
}
std::string cmCTest::GetBinaryDir()
{
- return this->BinaryDir;
+ return this->Impl->BinaryDir;
}
std::string const& cmCTest::GetConfigType()
{
- return this->ConfigType;
+ return this->Impl->ConfigType;
+}
+
+cmDuration cmCTest::GetTimeOut() const
+{
+ return this->Impl->TimeOut;
+}
+
+void cmCTest::SetTimeOut(cmDuration t)
+{
+ this->Impl->TimeOut = t;
+}
+
+cmDuration cmCTest::GetGlobalTimeout() const
+{
+ return this->Impl->GlobalTimeout;
}
bool cmCTest::GetShowOnly()
{
- return this->ShowOnly;
+ return this->Impl->ShowOnly;
}
bool cmCTest::GetOutputAsJson()
{
- return this->OutputAsJson;
+ return this->Impl->OutputAsJson;
}
int cmCTest::GetOutputAsJsonVersion()
{
- return this->OutputAsJsonVersion;
+ return this->Impl->OutputAsJsonVersion;
+}
+
+bool cmCTest::ShouldUseHTTP10() const
+{
+ return this->Impl->UseHTTP10;
+}
+
+bool cmCTest::ShouldPrintLabels() const
+{
+ return this->Impl->PrintLabels;
}
int cmCTest::GetMaxTestNameWidth() const
{
- return this->MaxTestNameWidth;
+ return this->Impl->MaxTestNameWidth;
+}
+
+void cmCTest::SetMaxTestNameWidth(int w)
+{
+ this->Impl->MaxTestNameWidth = w;
}
void cmCTest::SetProduceXML(bool v)
{
- this->ProduceXML = v;
+ this->Impl->ProduceXML = v;
}
bool cmCTest::GetProduceXML()
{
- return this->ProduceXML;
+ return this->Impl->ProduceXML;
+}
+
+std::vector<std::string>& cmCTest::GetInitialCommandLineArguments()
+{
+ return this->Impl->InitialCommandLineArguments;
}
const char* cmCTest::GetSpecificTrack()
{
- if (this->SpecificTrack.empty()) {
+ if (this->Impl->SpecificTrack.empty()) {
return nullptr;
}
- return this->SpecificTrack.c_str();
+ return this->Impl->SpecificTrack.c_str();
}
void cmCTest::SetSpecificTrack(const char* track)
{
if (!track) {
- this->SpecificTrack.clear();
+ this->Impl->SpecificTrack.clear();
return;
}
- this->SpecificTrack = track;
+ this->Impl->SpecificTrack = track;
+}
+
+void cmCTest::SetFailover(bool failover)
+{
+ this->Impl->Failover = failover;
+}
+
+bool cmCTest::GetFailover() const
+{
+ return this->Impl->Failover;
+}
+
+bool cmCTest::GetTestProgressOutput() const
+{
+ return this->Impl->TestProgressOutput;
+}
+
+bool cmCTest::GetVerbose() const
+{
+ return this->Impl->Verbose;
+}
+
+bool cmCTest::GetExtraVerbose() const
+{
+ return this->Impl->ExtraVerbose;
+}
+
+void cmCTest::SetStreams(std::ostream* out, std::ostream* err)
+{
+ this->Impl->StreamOut = out;
+ this->Impl->StreamErr = err;
+}
+
+bool cmCTest::GetLabelSummary() const
+{
+ return this->Impl->LabelSummary;
+}
+
+bool cmCTest::GetSubprojectSummary() const
+{
+ return this->Impl->SubprojectSummary;
+}
+
+bool cmCTest::GetOutputTestOutputOnTestFailure() const
+{
+ return this->Impl->OutputTestOutputOnTestFailure;
+}
+
+const std::map<std::string, std::string>& cmCTest::GetDefinitions() const
+{
+ return this->Impl->Definitions;
+}
+
+int cmCTest::GetTestRepeat() const
+{
+ return this->Impl->RepeatTests;
+}
+
+bool cmCTest::GetRepeatUntilFail() const
+{
+ return this->Impl->RepeatUntilFail;
+}
+
+void cmCTest::SetBuildID(const std::string& id)
+{
+ this->Impl->BuildID = id;
+}
+
+std::string cmCTest::GetBuildID() const
+{
+ return this->Impl->BuildID;
}
void cmCTest::AddSubmitFile(Part part, const char* name)
{
- this->Parts[part].SubmitFiles.emplace_back(name);
+ this->Impl->Parts[part].SubmitFiles.emplace_back(name);
+}
+
+std::vector<std::string> const& cmCTest::GetSubmitFiles(Part part) const
+{
+ return this->Impl->Parts[part].SubmitFiles;
+}
+
+void cmCTest::ClearSubmitFiles(Part part)
+{
+ this->Impl->Parts[part].SubmitFiles.clear();
+}
+
+void cmCTest::SetSuppressUpdatingCTestConfiguration(bool val)
+{
+ this->Impl->SuppressUpdatingCTestConfiguration = val;
}
void cmCTest::AddCTestConfigurationOverwrite(const std::string& overStr)
@@ -2732,14 +2894,14 @@ void cmCTest::AddCTestConfigurationOverwrite(const std::string& overStr)
}
std::string key = overStr.substr(0, epos);
std::string value = overStr.substr(epos + 1);
- this->CTestConfigurationOverwrites[key] = value;
+ this->Impl->CTestConfigurationOverwrites[key] = value;
}
void cmCTest::SetConfigType(const char* ct)
{
- this->ConfigType = ct ? ct : "";
- cmSystemTools::ReplaceString(this->ConfigType, ".\\", "");
- std::string confTypeEnv = "CMAKE_CONFIG_TYPE=" + this->ConfigType;
+ this->Impl->ConfigType = ct ? ct : "";
+ cmSystemTools::ReplaceString(this->Impl->ConfigType, ".\\", "");
+ std::string confTypeEnv = "CMAKE_CONFIG_TYPE=" + this->Impl->ConfigType;
cmSystemTools::PutEnv(confTypeEnv);
}
@@ -2805,12 +2967,12 @@ bool cmCTest::RunCommand(std::vector<std::string> const& args,
done = true;
}
if ((res == cmsysProcess_Pipe_STDOUT || res == cmsysProcess_Pipe_STDERR) &&
- this->ExtraVerbose) {
+ this->Impl->ExtraVerbose) {
processOutput.DecodeText(data, length, strdata);
cmSystemTools::Stdout(strdata);
}
}
- if (this->ExtraVerbose) {
+ if (this->Impl->ExtraVerbose) {
processOutput.DecodeText(std::string(), strdata);
if (!strdata.empty()) {
cmSystemTools::Stdout(strdata);
@@ -2859,12 +3021,12 @@ bool cmCTest::RunCommand(std::vector<std::string> const& args,
void cmCTest::SetOutputLogFileName(const char* name)
{
- if (this->OutputLogFile) {
- delete this->OutputLogFile;
- this->OutputLogFile = nullptr;
+ if (this->Impl->OutputLogFile) {
+ delete this->Impl->OutputLogFile;
+ this->Impl->OutputLogFile = nullptr;
}
if (name) {
- this->OutputLogFile = new cmGeneratedFileStream(name);
+ this->Impl->OutputLogFile = new cmGeneratedFileStream(name);
}
}
@@ -2880,18 +3042,11 @@ static const char* cmCTestStringLogType[] = { "DEBUG",
#define cmCTestLogOutputFileLine(stream) \
do { \
- if (this->ShowLineNumbers) { \
+ if (this->Impl->ShowLineNumbers) { \
(stream) << std::endl << file << ":" << line << " "; \
} \
} while (false)
-void cmCTest::InitStreams()
-{
- // By default we write output to the process output streams.
- this->StreamOut = &std::cout;
- this->StreamErr = &std::cerr;
-}
-
void cmCTest::Log(int logType, const char* file, int line, const char* msg,
bool suppress)
{
@@ -2902,53 +3057,53 @@ void cmCTest::Log(int logType, const char* file, int line, const char* msg,
return;
}
if (logType == cmCTest::HANDLER_PROGRESS_OUTPUT &&
- (this->Debug || this->ExtraVerbose)) {
+ (this->Impl->Debug || this->Impl->ExtraVerbose)) {
return;
}
- if (this->OutputLogFile) {
+ if (this->Impl->OutputLogFile) {
bool display = true;
- if (logType == cmCTest::DEBUG && !this->Debug) {
+ if (logType == cmCTest::DEBUG && !this->Impl->Debug) {
display = false;
}
- if (logType == cmCTest::HANDLER_VERBOSE_OUTPUT && !this->Debug &&
- !this->ExtraVerbose) {
+ if (logType == cmCTest::HANDLER_VERBOSE_OUTPUT && !this->Impl->Debug &&
+ !this->Impl->ExtraVerbose) {
display = false;
}
if (display) {
- cmCTestLogOutputFileLine(*this->OutputLogFile);
- if (logType != this->OutputLogFileLastTag) {
- *this->OutputLogFile << "[";
+ cmCTestLogOutputFileLine(*this->Impl->OutputLogFile);
+ if (logType != this->Impl->OutputLogFileLastTag) {
+ *this->Impl->OutputLogFile << "[";
if (logType >= OTHER || logType < 0) {
- *this->OutputLogFile << "OTHER";
+ *this->Impl->OutputLogFile << "OTHER";
} else {
- *this->OutputLogFile << cmCTestStringLogType[logType];
+ *this->Impl->OutputLogFile << cmCTestStringLogType[logType];
}
- *this->OutputLogFile << "] " << std::endl << std::flush;
+ *this->Impl->OutputLogFile << "] " << std::endl << std::flush;
}
- *this->OutputLogFile << msg << std::flush;
- if (logType != this->OutputLogFileLastTag) {
- *this->OutputLogFile << std::endl << std::flush;
- this->OutputLogFileLastTag = logType;
+ *this->Impl->OutputLogFile << msg << std::flush;
+ if (logType != this->Impl->OutputLogFileLastTag) {
+ *this->Impl->OutputLogFile << std::endl << std::flush;
+ this->Impl->OutputLogFileLastTag = logType;
}
}
}
- if (!this->Quiet) {
- std::ostream& out = *this->StreamOut;
- std::ostream& err = *this->StreamErr;
+ if (!this->Impl->Quiet) {
+ std::ostream& out = *this->Impl->StreamOut;
+ std::ostream& err = *this->Impl->StreamErr;
if (logType == HANDLER_TEST_PROGRESS_OUTPUT) {
- if (this->TestProgressOutput) {
+ if (this->Impl->TestProgressOutput) {
cmCTestLogOutputFileLine(out);
- if (this->FlushTestProgressLine) {
+ if (this->Impl->FlushTestProgressLine) {
printf("\r");
- this->FlushTestProgressLine = false;
+ this->Impl->FlushTestProgressLine = false;
out.flush();
}
std::string msg_str{ msg };
auto const lineBreakIt = msg_str.find('\n');
if (lineBreakIt != std::string::npos) {
- this->FlushTestProgressLine = true;
+ this->Impl->FlushTestProgressLine = true;
msg_str.erase(std::remove(msg_str.begin(), msg_str.end(), '\n'),
msg_str.end());
}
@@ -2965,7 +3120,7 @@ void cmCTest::Log(int logType, const char* file, int line, const char* msg,
switch (logType) {
case DEBUG:
- if (this->Debug) {
+ if (this->Impl->Debug) {
cmCTestLogOutputFileLine(out);
out << msg;
out.flush();
@@ -2973,14 +3128,14 @@ void cmCTest::Log(int logType, const char* file, int line, const char* msg,
break;
case OUTPUT:
case HANDLER_OUTPUT:
- if (this->Debug || this->Verbose) {
+ if (this->Impl->Debug || this->Impl->Verbose) {
cmCTestLogOutputFileLine(out);
out << msg;
out.flush();
}
break;
case HANDLER_VERBOSE_OUTPUT:
- if (this->Debug || this->ExtraVerbose) {
+ if (this->Impl->Debug || this->Impl->ExtraVerbose) {
cmCTestLogOutputFileLine(out);
out << msg;
out.flush();
@@ -3007,7 +3162,7 @@ void cmCTest::Log(int logType, const char* file, int line, const char* msg,
std::string cmCTest::GetColorCode(Color color) const
{
- if (this->OutputColorCode) {
+ if (this->Impl->OutputColorCode) {
#if defined(_WIN32)
// Not supported on Windows
static_cast<void>(color);
@@ -3021,14 +3176,7 @@ std::string cmCTest::GetColorCode(Color color) const
cmDuration cmCTest::GetRemainingTimeAllowed()
{
- if (!this->GetHandler("script")) {
- return cmCTest::MaxDuration();
- }
-
- cmCTestScriptHandler* ch =
- static_cast<cmCTestScriptHandler*>(this->GetHandler("script"));
-
- return ch->GetRemainingTimeAllowed();
+ return this->GetScriptHandler()->GetRemainingTimeAllowed();
}
cmDuration cmCTest::MaxDuration()
@@ -3038,10 +3186,7 @@ cmDuration cmCTest::MaxDuration()
void cmCTest::SetRunCurrentScript(bool value)
{
- cmCTestScriptHandler* ch =
- static_cast<cmCTestScriptHandler*>(this->GetHandler("script"));
-
- ch->SetRunCurrentScript(value);
+ this->GetScriptHandler()->SetRunCurrentScript(value);
}
void cmCTest::OutputTestErrors(std::vector<char> const& process_output)
diff --git a/Source/cmCTest.h b/Source/cmCTest.h
index a765fed..d300c33 100644
--- a/Source/cmCTest.h
+++ b/Source/cmCTest.h
@@ -10,13 +10,22 @@
#include <chrono>
#include <map>
-#include <set>
+#include <memory> // IWYU pragma: keep
#include <sstream>
#include <string>
#include <time.h>
#include <vector>
-class cmCTestGenericHandler;
+class cmCTestBuildHandler;
+class cmCTestBuildAndTestHandler;
+class cmCTestCoverageHandler;
+class cmCTestScriptHandler;
+class cmCTestTestHandler;
+class cmCTestUpdateHandler;
+class cmCTestConfigureHandler;
+class cmCTestMemCheckHandler;
+class cmCTestSubmitHandler;
+class cmCTestUploadHandler;
class cmCTestStartCommand;
class cmGeneratedFileStream;
class cmMakefile;
@@ -31,9 +40,6 @@ class cmXMLWriter;
*/
class cmCTest
{
- friend class cmCTestRunTest;
- friend class cmCTestMultiProcessHandler;
-
public:
typedef cmProcessOutput::Encoding Encoding;
/** Enumerate parts of the testing and submission process. */
@@ -54,44 +60,10 @@ public:
PartCount // Update names in constructor when adding a part
};
- /** Representation of one part. */
- struct PartInfo
- {
- void SetName(const std::string& name) { this->Name = name; }
- const std::string& GetName() const { return this->Name; }
-
- void Enable() { this->Enabled = true; }
- explicit operator bool() const { return this->Enabled; }
-
- std::vector<std::string> SubmitFiles;
-
- private:
- bool Enabled = false;
- std::string Name;
- };
-#ifdef CMAKE_BUILD_WITH_CMAKE
- enum HTTPMethod
- {
- HTTP_GET,
- HTTP_POST,
- HTTP_PUT
- };
-
- /**
- * Perform an HTTP request.
- */
- static int HTTPRequest(std::string url, HTTPMethod method,
- std::string& response, std::string const& fields = "",
- std::string const& putFile = "", int timeout = 0);
-#endif
-
/** Get a testing part id from its string name. Returns PartCount
if the string does not name a valid part. */
Part GetPartFromName(const char* name);
- typedef std::vector<std::string> VectorOfStrings;
- typedef std::set<std::string> SetOfStrings;
-
/** Process Command line arguments */
int Run(std::vector<std::string>&, std::string* output = nullptr);
@@ -128,7 +100,7 @@ public:
/**
* Is the tomorrow tag set?
*/
- bool GetTomorrowTag() { return this->TomorrowTag; }
+ bool GetTomorrowTag() const;
/**
* Try to run tests of the project
@@ -137,16 +109,16 @@ public:
/** what is the configuration type, e.g. Debug, Release etc. */
std::string const& GetConfigType();
- cmDuration GetTimeOut() { return this->TimeOut; }
- void SetTimeOut(cmDuration t) { this->TimeOut = t; }
+ cmDuration GetTimeOut() const;
+ void SetTimeOut(cmDuration t);
- cmDuration GetGlobalTimeout() { return this->GlobalTimeout; }
+ cmDuration GetGlobalTimeout() const;
/** how many test to run at the same time */
- int GetParallelLevel() { return this->ParallelLevel; }
+ int GetParallelLevel() const;
void SetParallelLevel(int);
- unsigned long GetTestLoad() { return this->TestLoad; }
+ unsigned long GetTestLoad() const;
void SetTestLoad(unsigned long);
/**
@@ -164,7 +136,7 @@ public:
* Set the cmake test mode (experimental, nightly, continuous).
*/
void SetTestModel(int mode);
- int GetTestModel() { return this->TestModel; }
+ int GetTestModel() const;
std::string GetTestModelString();
static int GetTestModelFromString(const char* str);
@@ -222,26 +194,23 @@ public:
int GetOutputAsJsonVersion();
- bool ShouldUseHTTP10() { return this->UseHTTP10; }
+ bool ShouldUseHTTP10() const;
- bool ShouldPrintLabels() { return this->PrintLabels; }
+ bool ShouldPrintLabels() const;
bool ShouldCompressTestOutput();
bool CompressString(std::string& str);
- std::chrono::system_clock::time_point GetStopTime()
- {
- return this->StopTime;
- }
+ std::chrono::system_clock::time_point GetStopTime() const;
void SetStopTime(std::string const& time);
/** Used for parallel ctest job scheduling */
- std::string GetScheduleType() { return this->ScheduleType; }
- void SetScheduleType(std::string const& type) { this->ScheduleType = type; }
+ std::string GetScheduleType() const;
+ void SetScheduleType(std::string const& type);
/** The max output width */
int GetMaxTestNameWidth() const;
- void SetMaxTestNameWidth(int w) { this->MaxTestNameWidth = w; }
+ void SetMaxTestNameWidth(int w);
/**
* Run a single executable command and put the stdout and stderr
@@ -335,16 +304,18 @@ public:
Encoding encoding = cmProcessOutput::Auto);
/**
- * Execute handler and return its result. If the handler fails, it returns
- * negative value.
- */
- int ExecuteHandler(const char* handler);
-
- /**
* Get the handler object
*/
- cmCTestGenericHandler* GetHandler(const char* handler);
- cmCTestGenericHandler* GetInitializedHandler(const char* handler);
+ cmCTestBuildHandler* GetBuildHandler();
+ cmCTestBuildAndTestHandler* GetBuildAndTestHandler();
+ cmCTestCoverageHandler* GetCoverageHandler();
+ cmCTestScriptHandler* GetScriptHandler();
+ cmCTestTestHandler* GetTestHandler();
+ cmCTestUpdateHandler* GetUpdateHandler();
+ cmCTestConfigureHandler* GetConfigureHandler();
+ cmCTestMemCheckHandler* GetMemCheckHandler();
+ cmCTestSubmitHandler* GetSubmitHandler();
+ cmCTestUploadHandler* GetUploadHandler();
/**
* Set the CTest variable from CMake variable
@@ -354,9 +325,6 @@ public:
const std::string& cmake_var,
bool suppress = false);
- /** Make string safe to be sent as a URL */
- static std::string MakeURLSafe(const std::string&);
-
/** Decode a URL to the original string. */
static std::string DecodeURL(const std::string&);
@@ -364,10 +332,7 @@ public:
* Should ctect configuration be updated. When using new style ctest
* script, this should be true.
*/
- void SetSuppressUpdatingCTestConfiguration(bool val)
- {
- this->SuppressUpdatingCTestConfiguration = val;
- }
+ void SetSuppressUpdatingCTestConfiguration(bool val);
/**
* Add overwrite to ctest configuration.
@@ -377,14 +342,14 @@ public:
void AddCTestConfigurationOverwrite(const std::string& encstr);
/** Create XML file that contains all the notes specified */
- int GenerateNotesFile(const VectorOfStrings& files);
+ int GenerateNotesFile(std::vector<std::string> const& files);
/** Create XML file to indicate that build is complete */
int GenerateDoneFile();
/** Submit extra files to the server */
bool SubmitExtraFiles(const char* files);
- bool SubmitExtraFiles(const VectorOfStrings& files);
+ bool SubmitExtraFiles(std::vector<std::string> const& files);
/** Set the output log file name */
void SetOutputLogFileName(const char* name);
@@ -424,62 +389,52 @@ public:
std::string GetColorCode(Color color) const;
/** The Build ID is assigned by CDash */
- void SetBuildID(const std::string& id) { this->BuildID = id; }
- std::string GetBuildID() { return this->BuildID; }
+ void SetBuildID(const std::string& id);
+ std::string GetBuildID() const;
/** Add file to be submitted */
void AddSubmitFile(Part part, const char* name);
- std::vector<std::string> const& GetSubmitFiles(Part part)
- {
- return this->Parts[part].SubmitFiles;
- }
- void ClearSubmitFiles(Part part) { this->Parts[part].SubmitFiles.clear(); }
+ std::vector<std::string> const& GetSubmitFiles(Part part) const;
+ void ClearSubmitFiles(Part part);
/**
* Read the custom configuration files and apply them to the current ctest
*/
int ReadCustomConfigurationFileTree(const char* dir, cmMakefile* mf);
- std::vector<std::string>& GetInitialCommandLineArguments()
- {
- return this->InitialCommandLineArguments;
- }
+ std::vector<std::string>& GetInitialCommandLineArguments();
/** Set the track to submit to */
void SetSpecificTrack(const char* track);
const char* GetSpecificTrack();
- void SetFailover(bool failover) { this->Failover = failover; }
- bool GetFailover() { return this->Failover; }
+ void SetFailover(bool failover);
+ bool GetFailover() const;
- bool GetTestProgressOutput() const { return this->TestProgressOutput; }
+ bool GetTestProgressOutput() const;
- bool GetVerbose() { return this->Verbose; }
- bool GetExtraVerbose() { return this->ExtraVerbose; }
+ bool GetVerbose() const;
+ bool GetExtraVerbose() const;
/** Direct process output to given streams. */
- void SetStreams(std::ostream* out, std::ostream* err)
- {
- this->StreamOut = out;
- this->StreamErr = err;
- }
+ void SetStreams(std::ostream* out, std::ostream* err);
+
void AddSiteProperties(cmXMLWriter& xml);
- bool GetLabelSummary() { return this->LabelSummary; }
- bool GetSubprojectSummary() { return this->SubprojectSummary; }
+ bool GetLabelSummary() const;
+ bool GetSubprojectSummary() const;
std::string GetCostDataFile();
- const std::map<std::string, std::string>& GetDefinitions()
- {
- return this->Definitions;
- }
+ bool GetOutputTestOutputOnTestFailure() const;
+
+ const std::map<std::string, std::string>& GetDefinitions() const;
/** Return the number of times a test should be run */
- int GetTestRepeat() { return this->RepeatTests; }
+ int GetTestRepeat() const;
/** Return true if test should run until fail */
- bool GetRepeatUntilFail() { return this->RepeatUntilFail; }
+ bool GetRepeatUntilFail() const;
void GenerateSubprojectsOutput(cmXMLWriter& xml);
std::vector<std::string> GetLabelsForSubprojects();
@@ -487,85 +442,8 @@ public:
void SetRunCurrentScript(bool value);
private:
- int RepeatTests;
- bool RepeatUntilFail;
- std::string ConfigType;
- std::string ScheduleType;
- std::chrono::system_clock::time_point StopTime;
- bool TestProgressOutput;
- bool Verbose;
- bool ExtraVerbose;
- bool ProduceXML;
- bool LabelSummary;
- bool SubprojectSummary;
- bool UseHTTP10;
- bool PrintLabels;
- bool Failover;
-
- bool FlushTestProgressLine;
-
- bool ForceNewCTestProcess;
-
- bool RunConfigurationScript;
-
int GenerateNotesFile(const char* files);
- // these are helper classes
- typedef std::map<std::string, cmCTestGenericHandler*> t_TestingHandlers;
- t_TestingHandlers TestingHandlers;
-
- bool ShowOnly;
- bool OutputAsJson;
- int OutputAsJsonVersion;
-
- /** Map of configuration properties */
- typedef std::map<std::string, std::string> CTestConfigurationMap;
-
- // TODO: The ctest configuration should be a hierarchy of
- // configuration option sources: command-line, script, ini file.
- // Then the ini file can get re-loaded whenever it changes without
- // affecting any higher-precedence settings.
- CTestConfigurationMap CTestConfiguration;
- CTestConfigurationMap CTestConfigurationOverwrites;
- PartInfo Parts[PartCount];
- typedef std::map<std::string, Part> PartMapType;
- PartMapType PartMap;
-
- std::string CurrentTag;
- bool TomorrowTag;
-
- int TestModel;
- std::string SpecificTrack;
-
- cmDuration TimeOut;
-
- cmDuration GlobalTimeout;
-
- int MaxTestNameWidth;
-
- int ParallelLevel;
- bool ParallelLevelSetInCli;
-
- unsigned long TestLoad;
-
- int CompatibilityMode;
-
- // information for the --build-and-test options
- std::string BinaryDir;
-
- std::string NotesFiles;
-
- bool InteractiveDebugMode;
-
- bool ShortDateFormat;
-
- bool CompressXMLFiles;
- bool CompressTestOutput;
-
- void InitStreams();
- std::ostream* StreamOut;
- std::ostream* StreamErr;
-
void BlockTestErrorDiagnostics();
/**
@@ -610,7 +488,8 @@ private:
bool UpdateCTestConfiguration();
/** Create note from files. */
- int GenerateCTestNotesOutput(cmXMLWriter& xml, const VectorOfStrings& files);
+ int GenerateCTestNotesOutput(cmXMLWriter& xml,
+ std::vector<std::string> const& files);
/** Check if the argument is the one specified */
bool CheckArgument(const std::string& arg, const char* varg1,
@@ -630,25 +509,8 @@ private:
int RunCMakeAndTest(std::string* output);
int ExecuteTests();
- bool SuppressUpdatingCTestConfiguration;
-
- bool Debug;
- bool ShowLineNumbers;
- bool Quiet;
-
- std::string BuildID;
-
- std::vector<std::string> InitialCommandLineArguments;
-
- int SubmitIndex;
-
- cmGeneratedFileStream* OutputLogFile;
- int OutputLogFileLastTag;
-
- bool OutputTestOutputOnTestFailure;
- bool OutputColorCode;
-
- std::map<std::string, std::string> Definitions;
+ struct Private;
+ std::unique_ptr<Private> Impl;
};
class cmCTestLogWrite
diff --git a/Source/cmDepends.cxx b/Source/cmDepends.cxx
index c128b02..efadaf1 100644
--- a/Source/cmDepends.cxx
+++ b/Source/cmDepends.cxx
@@ -2,7 +2,7 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmDepends.h"
-#include "cmFileTimeComparison.h"
+#include "cmFileTimeCache.h"
#include "cmGeneratedFileStream.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
@@ -177,8 +177,7 @@ bool cmDepends::CheckDependencies(
if (dependerExists) {
// The dependee and depender both exist. Compare file times.
int result = 0;
- if ((!this->FileComparison->FileTimeCompare(depender, dependee,
- &result) ||
+ if ((!this->FileTimeCache->Compare(depender, dependee, &result) ||
result < 0)) {
// The depender is older than the dependee.
regenerate = true;
@@ -195,8 +194,8 @@ bool cmDepends::CheckDependencies(
// The dependee exists, but the depender doesn't. Regenerate if the
// internalDepends file is older than the dependee.
int result = 0;
- if ((!this->FileComparison->FileTimeCompare(internalDependsFileName,
- dependee, &result) ||
+ if ((!this->FileTimeCache->Compare(internalDependsFileName, dependee,
+ &result) ||
result < 0)) {
// The depends-file is older than the dependee.
regenerate = true;
diff --git a/Source/cmDepends.h b/Source/cmDepends.h
index 20c91ca..fc6571d 100644
--- a/Source/cmDepends.h
+++ b/Source/cmDepends.h
@@ -12,7 +12,7 @@
#include <string>
#include <vector>
-class cmFileTimeComparison;
+class cmFileTimeCache;
class cmLocalGenerator;
/** \class cmDepends
@@ -72,10 +72,7 @@ public:
void Clear(const std::string& file);
/** Set the file comparison object */
- void SetFileComparison(cmFileTimeComparison* fc)
- {
- this->FileComparison = fc;
- }
+ void SetFileTimeCache(cmFileTimeCache* fc) { this->FileTimeCache = fc; }
protected:
// Write dependencies for the target file to the given stream.
@@ -101,7 +98,7 @@ protected:
// Flag for verbose output.
bool Verbose = false;
- cmFileTimeComparison* FileComparison = nullptr;
+ cmFileTimeCache* FileTimeCache = nullptr;
std::string Language;
diff --git a/Source/cmDependsC.cxx b/Source/cmDependsC.cxx
index a85f5ee..7b78767 100644
--- a/Source/cmDependsC.cxx
+++ b/Source/cmDependsC.cxx
@@ -6,6 +6,7 @@
#include <utility>
#include "cmAlgorithms.h"
+#include "cmFileTime.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
#include "cmSystemTools.h"
@@ -149,7 +150,7 @@ bool cmDependsC::WriteDependencies(const std::set<std::string>& sources,
// Construct the name of the file as if it were in the current
// include directory. Avoid using a leading "./".
std::string tmpPath =
- cmSystemTools::CollapseCombinedPath(iPath, current.FileName);
+ cmSystemTools::CollapseFullPath(current.FileName, iPath);
// Look for the file in this location.
if (cmSystemTools::FileExists(tmpPath, true)) {
@@ -247,6 +248,8 @@ void cmDependsC::ReadCacheFile()
cmIncludeLines* cacheEntry = nullptr;
bool haveFileName = false;
+ cmFileTime cacheFileTime;
+ bool const cacheFileTimeGood = cacheFileTime.Load(this->CacheFileName);
while (cmSystemTools::GetLineFromStream(fin, line)) {
if (line.empty()) {
cacheEntry = nullptr;
@@ -256,11 +259,12 @@ void cmDependsC::ReadCacheFile()
// the first line after an empty line is the name of the parsed file
if (!haveFileName) {
haveFileName = true;
- int newer = 0;
- bool res =
- cmSystemTools::FileTimeCompare(this->CacheFileName, line, &newer);
- if (res && newer == 1) // cache is newer than the parsed file
+ cmFileTime fileTime;
+ bool const res = cacheFileTimeGood && fileTime.Load(line);
+ bool const newer = res && cacheFileTime.Newer(fileTime);
+
+ if (res && newer) // cache is newer than the parsed file
{
cacheEntry = new cmIncludeLines;
this->FileCache[line] = cacheEntry;
@@ -358,7 +362,7 @@ void cmDependsC::Scan(std::istream& is, const std::string& directory,
// must check for the file in the directory containing the
// file we are scanning.
entry.QuotedLocation =
- cmSystemTools::CollapseCombinedPath(directory, entry.FileName);
+ cmSystemTools::CollapseFullPath(entry.FileName, directory);
}
// Queue the file if it has not yet been encountered and it
diff --git a/Source/cmExportCommand.cxx b/Source/cmExportCommand.cxx
index 722831a..c25e1f4 100644
--- a/Source/cmExportCommand.cxx
+++ b/Source/cmExportCommand.cxx
@@ -13,6 +13,7 @@
#include "cmGlobalGenerator.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
+#include "cmPolicies.h"
#include "cmStateTypes.h"
#include "cmSystemTools.h"
#include "cmTarget.h"
@@ -243,10 +244,23 @@ bool cmExportCommand::HandlePackage(std::vector<std::string> const& args)
return false;
}
- // If the CMAKE_EXPORT_NO_PACKAGE_REGISTRY variable is set the command
- // export(PACKAGE) does nothing.
- if (this->Makefile->IsOn("CMAKE_EXPORT_NO_PACKAGE_REGISTRY")) {
- return true;
+ // CMP0090 decides both the default and what variable changes it.
+ switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0090)) {
+ case cmPolicies::WARN:
+ case cmPolicies::OLD:
+ // Default is to export, but can be disabled.
+ if (this->Makefile->IsOn("CMAKE_EXPORT_NO_PACKAGE_REGISTRY")) {
+ return true;
+ }
+ break;
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::REQUIRED_ALWAYS:
+ case cmPolicies::NEW:
+ // Default is to not export, but can be enabled.
+ if (!this->Makefile->IsOn("CMAKE_EXPORT_PACKAGE_REGISTRY")) {
+ return true;
+ }
+ break;
}
// We store the current build directory in the registry as a value
diff --git a/Source/cmExtraEclipseCDT4Generator.cxx b/Source/cmExtraEclipseCDT4Generator.cxx
index a6ce8b7..aece3bc 100644
--- a/Source/cmExtraEclipseCDT4Generator.cxx
+++ b/Source/cmExtraEclipseCDT4Generator.cxx
@@ -845,6 +845,9 @@ void cmExtraEclipseCDT4Generator::CreateCProjectFile() const
const std::vector<cmGeneratorTarget*>& targets =
lgen->GetGeneratorTargets();
for (cmGeneratorTarget* target : targets) {
+ if (target->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
+ continue;
+ }
std::vector<std::string> includeDirs;
std::string config = mf->GetSafeDefinition("CMAKE_BUILD_TYPE");
lgen->GetIncludeDirectories(includeDirs, target, "C", config);
@@ -971,6 +974,8 @@ void cmExtraEclipseCDT4Generator::CreateCProjectFile() const
virtDir, "", "");
}
} break;
+ case cmStateEnums::INTERFACE_LIBRARY:
+ break;
default:
break;
}
diff --git a/Source/cmFileCopier.cxx b/Source/cmFileCopier.cxx
index 560d893..8913e6d 100644
--- a/Source/cmFileCopier.cxx
+++ b/Source/cmFileCopier.cxx
@@ -532,7 +532,7 @@ bool cmFileCopier::InstallFile(const std::string& fromFile,
bool copy = true;
if (!this->Always) {
// If both files exist with the same time do not copy.
- if (!this->FileTimes.FileTimesDiffer(fromFile, toFile)) {
+ if (!this->FileTimes.DifferS(fromFile, toFile)) {
copy = false;
}
}
diff --git a/Source/cmFileCopier.h b/Source/cmFileCopier.h
index a11c371..003b8f6 100644
--- a/Source/cmFileCopier.h
+++ b/Source/cmFileCopier.h
@@ -5,7 +5,7 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmFileTimeComparison.h"
+#include "cmFileTimeCache.h"
#include "cm_sys_stat.h"
#include "cmsys/RegularExpression.hxx"
@@ -28,7 +28,7 @@ protected:
cmMakefile* Makefile;
const char* Name;
bool Always;
- cmFileTimeComparison FileTimes;
+ cmFileTimeCache FileTimes;
// Whether to install a file not matching any expression.
bool MatchlessFiles;
diff --git a/Source/cmFileTime.cxx b/Source/cmFileTime.cxx
new file mode 100644
index 0000000..253457f
--- /dev/null
+++ b/Source/cmFileTime.cxx
@@ -0,0 +1,49 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#include "cmFileTime.h"
+
+#include <string>
+#include <time.h>
+
+// Use a platform-specific API to get file times efficiently.
+#if !defined(_WIN32) || defined(__CYGWIN__)
+# include "cm_sys_stat.h"
+#else
+# include "cmsys/Encoding.hxx"
+# include <windows.h>
+#endif
+
+bool cmFileTime::Load(std::string const& fileName)
+{
+#if !defined(_WIN32) || defined(__CYGWIN__)
+ // POSIX version. Use the stat function.
+ struct stat fst;
+ if (::stat(fileName.c_str(), &fst) != 0) {
+ return false;
+ }
+# if CMake_STAT_HAS_ST_MTIM
+ // Nanosecond resolution
+ this->NS = fst.st_mtim.tv_sec * NsPerS + fst.st_mtim.tv_nsec;
+# elif CMake_STAT_HAS_ST_MTIMESPEC
+ // Nanosecond resolution
+ this->NS = fst.st_mtimespec.tv_sec * NsPerS + fst.st_mtimespec.tv_nsec;
+# else
+ // Second resolution
+ this->NS = fst.st_mtime * NsPerS;
+# endif
+#else
+ // Windows version. Get the modification time from extended file attributes.
+ WIN32_FILE_ATTRIBUTE_DATA fdata;
+ if (!GetFileAttributesExW(cmsys::Encoding::ToWide(fileName).c_str(),
+ GetFileExInfoStandard, &fdata)) {
+ return false;
+ }
+
+ // Copy the file time to the output location.
+ this->NS = (static_cast<NSC>(fdata.ftLastWriteTime.dwHighDateTime) << 32) |
+ static_cast<NSC>(fdata.ftLastWriteTime.dwLowDateTime);
+ // The file time resolution is 100 ns.
+ this->NS *= 100;
+#endif
+ return true;
+}
diff --git a/Source/cmFileTime.h b/Source/cmFileTime.h
new file mode 100644
index 0000000..4c8e556
--- /dev/null
+++ b/Source/cmFileTime.h
@@ -0,0 +1,130 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#ifndef cmFileTime_h
+#define cmFileTime_h
+
+#include "cmConfigure.h" // IWYU pragma: keep
+
+#include <string>
+
+/** \class cmFileTime
+ * \brief Abstract file modification time with support for comparison with
+ * other file modification times.
+ */
+class cmFileTime
+{
+public:
+ typedef long long NSC;
+ static constexpr NSC NsPerS = 1000000000;
+
+ cmFileTime() = default;
+ ~cmFileTime() = default;
+
+ /**
+ * @brief Loads the file time of fileName from the file system
+ * @return true on success
+ */
+ bool Load(std::string const& fileName);
+
+ /**
+ * @brief Return true if this is older than ftm
+ */
+ bool Older(cmFileTime const& ftm) const { return (this->NS - ftm.NS) < 0; }
+
+ /**
+ * @brief Return true if this is newer than ftm
+ */
+ bool Newer(cmFileTime const& ftm) const { return (ftm.NS - this->NS) < 0; }
+
+ /**
+ * @brief Return true if this is the same as ftm
+ */
+ bool Equal(cmFileTime const& ftm) const { return this->NS == ftm.NS; }
+
+ /**
+ * @brief Return true if this is not the same as ftm
+ */
+ bool Differ(cmFileTime const& ftm) const { return this->NS != ftm.NS; }
+
+ /**
+ * @brief Compare file modification times.
+ * @return -1, 0, +1 for this older, same, or newer than ftm.
+ */
+ int Compare(cmFileTime const& ftm)
+ {
+ NSC const diff = this->NS - ftm.NS;
+ if (diff == 0) {
+ return 0;
+ }
+ return (diff < 0) ? -1 : 1;
+ }
+
+ // -- Comparison in second resolution
+
+ /**
+ * @brief Return true if this is at least a second older than ftm
+ */
+ bool OlderS(cmFileTime const& ftm) const
+ {
+ return (ftm.NS - this->NS) >= cmFileTime::NsPerS;
+ }
+
+ /**
+ * @brief Return true if this is at least a second newer than ftm
+ */
+ bool NewerS(cmFileTime const& ftm) const
+ {
+ return (this->NS - ftm.NS) >= cmFileTime::NsPerS;
+ }
+
+ /**
+ * @brief Return true if this is within the same second as ftm
+ */
+ bool EqualS(cmFileTime const& ftm) const
+ {
+ NSC diff = this->NS - ftm.NS;
+ if (diff < 0) {
+ diff = -diff;
+ }
+ return (diff < cmFileTime::NsPerS);
+ }
+
+ /**
+ * @brief Return true if this is older or newer than ftm by at least a second
+ */
+ bool DifferS(cmFileTime const& ftm) const
+ {
+ NSC diff = this->NS - ftm.NS;
+ if (diff < 0) {
+ diff = -diff;
+ }
+ return (diff >= cmFileTime::NsPerS);
+ }
+
+ /**
+ * @brief Compare file modification times.
+ * @return -1: this at least a second older, 0: this within the same second
+ * as ftm, +1: this at least a second newer than ftm.
+ */
+ int CompareS(cmFileTime const& ftm) const
+ {
+ NSC const diff = this->NS - ftm.NS;
+ if (diff <= -cmFileTime::NsPerS) {
+ return -1;
+ }
+ if (diff >= cmFileTime::NsPerS) {
+ return 1;
+ }
+ return 0;
+ }
+
+ /**
+ * @brief The file modification time in nanoseconds
+ */
+ NSC GetNS() const { return this->NS; }
+
+private:
+ NSC NS = 0;
+};
+
+#endif
diff --git a/Source/cmFileTimeCache.cxx b/Source/cmFileTimeCache.cxx
new file mode 100644
index 0000000..1fff6a9
--- /dev/null
+++ b/Source/cmFileTimeCache.cxx
@@ -0,0 +1,57 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#include "cmFileTimeCache.h"
+
+#include <string>
+#include <unordered_map>
+#include <utility>
+
+cmFileTimeCache::cmFileTimeCache() = default;
+
+cmFileTimeCache::~cmFileTimeCache() = default;
+
+bool cmFileTimeCache::Load(std::string const& fileName, cmFileTime& fileTime)
+{
+ // Use the stored time if available.
+ {
+ auto fit = this->FileTimes.find(fileName);
+ if (fit != this->FileTimes.end()) {
+ fileTime = fit->second;
+ return true;
+ }
+ }
+ // Read file time from OS
+ if (!fileTime.Load(fileName)) {
+ return false;
+ }
+ // Store file time in cache
+ this->FileTimes[fileName] = fileTime;
+ return true;
+}
+
+bool cmFileTimeCache::Compare(std::string const& f1, std::string const& f2,
+ int* result)
+{
+ // Get the modification time for each file.
+ cmFileTime ft1, ft2;
+ if (this->Load(f1, ft1) && this->Load(f2, ft2)) {
+ // Compare the two modification times.
+ *result = ft1.Compare(ft2);
+ return true;
+ }
+ // No comparison available. Default to the same time.
+ *result = 0;
+ return false;
+}
+
+bool cmFileTimeCache::DifferS(std::string const& f1, std::string const& f2)
+{
+ // Get the modification time for each file.
+ cmFileTime ft1, ft2;
+ if (this->Load(f1, ft1) && this->Load(f2, ft2)) {
+ // Compare the two modification times.
+ return ft1.DifferS(ft2);
+ }
+ // No comparison available. Default to different times.
+ return true;
+}
diff --git a/Source/cmFileTimeCache.h b/Source/cmFileTimeCache.h
new file mode 100644
index 0000000..a47904c
--- /dev/null
+++ b/Source/cmFileTimeCache.h
@@ -0,0 +1,51 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#ifndef cmFileTimeCache_h
+#define cmFileTimeCache_h
+
+#include "cmConfigure.h" // IWYU pragma: keep
+
+#include "cmFileTime.h"
+#include <string>
+#include <unordered_map>
+
+/** \class cmFileTimeCache
+ * \brief Caches file modification times in an internal map for fast lookups.
+ */
+class cmFileTimeCache
+{
+public:
+ cmFileTimeCache();
+ ~cmFileTimeCache();
+
+ cmFileTimeCache(const cmFileTimeCache&) = delete;
+ cmFileTimeCache& operator=(const cmFileTimeCache&) = delete;
+
+ /**
+ * @brief Loads the file time from the cache or the file system.
+ * @return true on success
+ */
+ bool Load(std::string const& fileName, cmFileTime& fileTime);
+
+ /**
+ * @brief Compare file modification times.
+ * @return true for successful comparison and false for error.
+ *
+ * When true is returned, result has -1, 0, +1 for
+ * f1 older, same, or newer than f2.
+ */
+ bool Compare(std::string const& f1, std::string const& f2, int* result);
+
+ /**
+ * @brief Compare file modification times.
+ * @return true unless both files exist and have modification times less
+ * than 1 second apart.
+ */
+ bool DifferS(std::string const& f1, std::string const& f2);
+
+private:
+ typedef std::unordered_map<std::string, cmFileTime> FileTimeMap;
+ FileTimeMap FileTimes;
+};
+
+#endif
diff --git a/Source/cmFileTimeComparison.cxx b/Source/cmFileTimeComparison.cxx
deleted file mode 100644
index 8b3911e..0000000
--- a/Source/cmFileTimeComparison.cxx
+++ /dev/null
@@ -1,233 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing for details. */
-#include "cmFileTimeComparison.h"
-
-#include <string>
-#include <time.h>
-#include <unordered_map>
-#include <utility>
-
-// Use a platform-specific API to get file times efficiently.
-#if !defined(_WIN32) || defined(__CYGWIN__)
-# include "cm_sys_stat.h"
-# define cmFileTimeComparison_Type struct stat
-#else
-# include "cmsys/Encoding.hxx"
-# include <windows.h>
-# define cmFileTimeComparison_Type FILETIME
-#endif
-
-class cmFileTimeComparisonInternal
-{
-public:
- // Internal comparison method.
- inline bool FileTimeCompare(const std::string& f1, const std::string& f2,
- int* result);
-
- bool FileTimesDiffer(const std::string& f1, const std::string& f2);
-
-private:
- typedef std::unordered_map<std::string, cmFileTimeComparison_Type>
- FileStatsMap;
- FileStatsMap Files;
-
- // Internal methods to lookup and compare modification times.
- inline bool Stat(const std::string& fname, cmFileTimeComparison_Type* st);
- inline int Compare(cmFileTimeComparison_Type* st1,
- cmFileTimeComparison_Type* st2);
- inline bool TimesDiffer(cmFileTimeComparison_Type* st1,
- cmFileTimeComparison_Type* st2);
-};
-
-bool cmFileTimeComparisonInternal::Stat(const std::string& fname,
- cmFileTimeComparison_Type* st)
-{
- // Use the stored time if available.
- cmFileTimeComparisonInternal::FileStatsMap::iterator fit =
- this->Files.find(fname);
- if (fit != this->Files.end()) {
- *st = fit->second;
- return true;
- }
-
-#if !defined(_WIN32) || defined(__CYGWIN__)
- // POSIX version. Use the stat function.
- int res = ::stat(fname.c_str(), st);
- if (res != 0) {
- return false;
- }
-#else
- // Windows version. Get the modification time from extended file
- // attributes.
- WIN32_FILE_ATTRIBUTE_DATA fdata;
- if (!GetFileAttributesExW(cmsys::Encoding::ToWide(fname).c_str(),
- GetFileExInfoStandard, &fdata)) {
- return false;
- }
-
- // Copy the file time to the output location.
- *st = fdata.ftLastWriteTime;
-#endif
-
- // Store the time for future use.
- this->Files[fname] = *st;
- return true;
-}
-
-cmFileTimeComparison::cmFileTimeComparison()
-{
- this->Internals = new cmFileTimeComparisonInternal;
-}
-
-cmFileTimeComparison::~cmFileTimeComparison()
-{
- delete this->Internals;
-}
-
-bool cmFileTimeComparison::FileTimeCompare(const std::string& f1,
- const std::string& f2, int* result)
-{
- return this->Internals->FileTimeCompare(f1, f2, result);
-}
-
-bool cmFileTimeComparison::FileTimesDiffer(const std::string& f1,
- const std::string& f2)
-{
- return this->Internals->FileTimesDiffer(f1, f2);
-}
-
-int cmFileTimeComparisonInternal::Compare(cmFileTimeComparison_Type* s1,
- cmFileTimeComparison_Type* s2)
-{
-#if !defined(_WIN32) || defined(__CYGWIN__)
-# if CMake_STAT_HAS_ST_MTIM
- // Compare using nanosecond resolution.
- if (s1->st_mtim.tv_sec < s2->st_mtim.tv_sec) {
- return -1;
- }
- if (s1->st_mtim.tv_sec > s2->st_mtim.tv_sec) {
- return 1;
- }
- if (s1->st_mtim.tv_nsec < s2->st_mtim.tv_nsec) {
- return -1;
- }
- if (s1->st_mtim.tv_nsec > s2->st_mtim.tv_nsec) {
- return 1;
- }
-# elif CMake_STAT_HAS_ST_MTIMESPEC
- // Compare using nanosecond resolution.
- if (s1->st_mtimespec.tv_sec < s2->st_mtimespec.tv_sec) {
- return -1;
- }
- if (s1->st_mtimespec.tv_sec > s2->st_mtimespec.tv_sec) {
- return 1;
- }
- if (s1->st_mtimespec.tv_nsec < s2->st_mtimespec.tv_nsec) {
- return -1;
- }
- if (s1->st_mtimespec.tv_nsec > s2->st_mtimespec.tv_nsec) {
- return 1;
- }
-# else
- // Compare using 1 second resolution.
- if (s1->st_mtime < s2->st_mtime) {
- return -1;
- }
- if (s1->st_mtime > s2->st_mtime) {
- return 1;
- }
-# endif
- // Files have the same time.
- return 0;
-#else
- // Compare using system-provided function.
- return (int)CompareFileTime(s1, s2);
-#endif
-}
-
-bool cmFileTimeComparisonInternal::TimesDiffer(cmFileTimeComparison_Type* s1,
- cmFileTimeComparison_Type* s2)
-{
-#if !defined(_WIN32) || defined(__CYGWIN__)
-# if CMake_STAT_HAS_ST_MTIM
- // Times are integers in units of 1ns.
- long long bil = 1000000000;
- long long t1 = s1->st_mtim.tv_sec * bil + s1->st_mtim.tv_nsec;
- long long t2 = s2->st_mtim.tv_sec * bil + s2->st_mtim.tv_nsec;
- if (t1 < t2) {
- return (t2 - t1) >= bil;
- }
- if (t2 < t1) {
- return (t1 - t2) >= bil;
- }
- return false;
-# elif CMake_STAT_HAS_ST_MTIMESPEC
- // Times are integers in units of 1ns.
- long long bil = 1000000000;
- long long t1 = s1->st_mtimespec.tv_sec * bil + s1->st_mtimespec.tv_nsec;
- long long t2 = s2->st_mtimespec.tv_sec * bil + s2->st_mtimespec.tv_nsec;
- if (t1 < t2) {
- return (t2 - t1) >= bil;
- }
- if (t2 < t1) {
- return (t1 - t2) >= bil;
- }
- return false;
-# else
- // Times are integers in units of 1s.
- if (s1->st_mtime < s2->st_mtime) {
- return (s2->st_mtime - s1->st_mtime) >= 1;
- }
- if (s1->st_mtime > s2->st_mtime) {
- return (s1->st_mtime - s2->st_mtime) >= 1;
- }
- return false;
-# endif
-#else
- // Times are integers in units of 100ns.
- LARGE_INTEGER t1;
- LARGE_INTEGER t2;
- t1.LowPart = s1->dwLowDateTime;
- t1.HighPart = s1->dwHighDateTime;
- t2.LowPart = s2->dwLowDateTime;
- t2.HighPart = s2->dwHighDateTime;
- if (t1.QuadPart < t2.QuadPart) {
- return (t2.QuadPart - t1.QuadPart) >= static_cast<LONGLONG>(10000000);
- } else if (t2.QuadPart < t1.QuadPart) {
- return (t1.QuadPart - t2.QuadPart) >= static_cast<LONGLONG>(10000000);
- } else {
- return false;
- }
-#endif
-}
-
-bool cmFileTimeComparisonInternal::FileTimeCompare(const std::string& f1,
- const std::string& f2,
- int* result)
-{
- // Get the modification time for each file.
- cmFileTimeComparison_Type s1;
- cmFileTimeComparison_Type s2;
- if (this->Stat(f1, &s1) && this->Stat(f2, &s2)) {
- // Compare the two modification times.
- *result = this->Compare(&s1, &s2);
- return true;
- }
- // No comparison available. Default to the same time.
- *result = 0;
- return false;
-}
-
-bool cmFileTimeComparisonInternal::FileTimesDiffer(const std::string& f1,
- const std::string& f2)
-{
- // Get the modification time for each file.
- cmFileTimeComparison_Type s1;
- cmFileTimeComparison_Type s2;
- if (this->Stat(f1, &s1) && this->Stat(f2, &s2)) {
- // Compare the two modification times.
- return this->TimesDiffer(&s1, &s2);
- }
- // No comparison available. Default to different times.
- return true;
-}
diff --git a/Source/cmFileTimeComparison.h b/Source/cmFileTimeComparison.h
deleted file mode 100644
index b4e4eb3..0000000
--- a/Source/cmFileTimeComparison.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing for details. */
-#ifndef cmFileTimeComparison_h
-#define cmFileTimeComparison_h
-
-#include "cmConfigure.h" // IWYU pragma: keep
-
-#include <string>
-
-class cmFileTimeComparisonInternal;
-
-/** \class cmFileTimeComparison
- * \brief Helper class for comparing file modification times.
- *
- * Compare file modification times or test if file modification times differ.
- */
-class cmFileTimeComparison
-{
-public:
- cmFileTimeComparison();
- ~cmFileTimeComparison();
-
- cmFileTimeComparison(const cmFileTimeComparison&) = delete;
- cmFileTimeComparison& operator=(const cmFileTimeComparison&) = delete;
-
- /**
- * Compare file modification times.
- * Return true for successful comparison and false for error.
- * When true is returned, result has -1, 0, +1 for
- * f1 older, same, or newer than f2.
- */
- bool FileTimeCompare(const std::string& f1, const std::string& f2,
- int* result);
-
- /**
- * Compare file modification times. Return true unless both files
- * exist and have modification times less than 1 second apart.
- */
- bool FileTimesDiffer(const std::string& f1, const std::string& f2);
-
-protected:
- cmFileTimeComparisonInternal* Internals;
-};
-
-#endif
diff --git a/Source/cmFindProgramCommand.cxx b/Source/cmFindProgramCommand.cxx
index db34077..782f746 100644
--- a/Source/cmFindProgramCommand.cxx
+++ b/Source/cmFindProgramCommand.cxx
@@ -77,7 +77,7 @@ struct cmFindProgramHelper
this->TestNameExt = name;
this->TestNameExt += ext;
this->TestPath =
- cmSystemTools::CollapseCombinedPath(path, this->TestNameExt);
+ cmSystemTools::CollapseFullPath(this->TestNameExt, path);
if (cmSystemTools::FileExists(this->TestPath, true)) {
this->BestPath = this->TestPath;
diff --git a/Source/cmGhsMultiTargetGenerator.cxx b/Source/cmGhsMultiTargetGenerator.cxx
index bbe7f23..668bcbd 100644
--- a/Source/cmGhsMultiTargetGenerator.cxx
+++ b/Source/cmGhsMultiTargetGenerator.cxx
@@ -298,7 +298,7 @@ void cmGhsMultiTargetGenerator::WriteTargetLinkLine(std::ostream& fout,
if (l.compare(0, 2, "-l") == 0) {
fout << " \"" << l << "\"" << std::endl;
} else {
- std::string rl = cmSystemTools::CollapseCombinedPath(cbd, l);
+ std::string rl = cmSystemTools::CollapseFullPath(l, cbd);
fout << " -l\"" << rl << "\"" << std::endl;
}
}
diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx
index 6964b62..00781c3 100644
--- a/Source/cmGlobalGenerator.cxx
+++ b/Source/cmGlobalGenerator.cxx
@@ -1214,14 +1214,16 @@ void cmGlobalGenerator::Configure()
this->ConfigureDoneCMP0026AndCMP0024 = true;
// Put a copy of each global target in every directory.
- std::vector<GlobalTargetInfo> globalTargets;
- this->CreateDefaultGlobalTargets(globalTargets);
-
- for (cmMakefile* mf : this->Makefiles) {
- cmTargets* targets = &(mf->GetTargets());
- for (GlobalTargetInfo const& globalTarget : globalTargets) {
- targets->insert(cmTargets::value_type(
- globalTarget.Name, this->CreateGlobalTarget(globalTarget, mf)));
+ {
+ std::vector<GlobalTargetInfo> globalTargets;
+ this->CreateDefaultGlobalTargets(globalTargets);
+
+ for (cmMakefile* mf : this->Makefiles) {
+ auto& targets = mf->GetTargets();
+ for (GlobalTargetInfo const& globalTarget : globalTargets) {
+ targets.emplace(globalTarget.Name,
+ this->CreateGlobalTarget(globalTarget, mf));
+ }
}
}
diff --git a/Source/cmGlobalGhsMultiGenerator.cxx b/Source/cmGlobalGhsMultiGenerator.cxx
index 690398f..e6a1d78 100644
--- a/Source/cmGlobalGhsMultiGenerator.cxx
+++ b/Source/cmGlobalGhsMultiGenerator.cxx
@@ -194,8 +194,7 @@ void cmGlobalGhsMultiGenerator::GetToolset(cmMakefile* mf, std::string& tsd,
}
} else {
std::string tryPath;
- /* CollapseCombinedPath will check if ts is an absolute path */
- tryPath = cmSystemTools::CollapseCombinedPath(tsd, ts);
+ tryPath = cmSystemTools::CollapseFullPath(ts, tsd);
if (!cmSystemTools::FileExists(tryPath)) {
std::string msg = "GHS toolset \"" + tryPath + "\" not found.";
cmSystemTools::Error(msg);
diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx
index 841587c..e443678 100644
--- a/Source/cmGlobalNinjaGenerator.cxx
+++ b/Source/cmGlobalNinjaGenerator.cxx
@@ -1997,7 +1997,7 @@ int cmcmd_cmake_ninja_dyndep(std::vector<std::string>::const_iterator argBeg,
std::string const dir_top_bld = tdi["dir-top-bld"].asString();
std::string const dir_top_src = tdi["dir-top-src"].asString();
std::string module_dir = tdi["module-dir"].asString();
- if (!module_dir.empty()) {
+ if (!module_dir.empty() && !cmHasLiteralSuffix(module_dir, "/")) {
module_dir += "/";
}
std::vector<std::string> linked_target_dirs;
diff --git a/Source/cmGlobalVisualStudioVersionedGenerator.cxx b/Source/cmGlobalVisualStudioVersionedGenerator.cxx
index 391fe69..2ba1aff 100644
--- a/Source/cmGlobalVisualStudioVersionedGenerator.cxx
+++ b/Source/cmGlobalVisualStudioVersionedGenerator.cxx
@@ -18,8 +18,15 @@
#elif defined(_M_IA64)
# define HOST_PLATFORM_NAME "Itanium"
# define HOST_TOOLS_ARCH ""
+#elif defined(_WIN64)
+# define HOST_PLATFORM_NAME "x64"
+# define HOST_TOOLS_ARCH "x64"
#else
-# include "cmsys/SystemInformation.hxx"
+static bool VSIsWow64()
+{
+ BOOL isWow64 = false;
+ return IsWow64Process(GetCurrentProcess(), &isWow64) && isWow64;
+}
#endif
static std::string VSHostPlatformName()
@@ -27,8 +34,7 @@ static std::string VSHostPlatformName()
#ifdef HOST_PLATFORM_NAME
return HOST_PLATFORM_NAME;
#else
- cmsys::SystemInformation info;
- if (info.Is64Bits()) {
+ if (VSIsWow64()) {
return "x64";
} else {
return "Win32";
@@ -41,8 +47,7 @@ static std::string VSHostArchitecture()
#ifdef HOST_TOOLS_ARCH
return HOST_TOOLS_ARCH;
#else
- cmsys::SystemInformation info;
- if (info.Is64Bits()) {
+ if (VSIsWow64()) {
return "x64";
} else {
return "x86";
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index 53baed5..4025073 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -1022,7 +1022,7 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateXCodeFileReferenceFromPath(
this->CreateString(fileType));
// Store the file path relative to the top of the source tree.
- std::string path = this->RelativeToSource(fullpath.c_str());
+ std::string path = this->RelativeToSource(fullpath);
std::string name = cmSystemTools::GetFilenameName(path);
const char* sourceTree =
(cmSystemTools::FileIsFullPath(path.c_str()) ? "<absolute>"
@@ -3063,7 +3063,7 @@ bool cmGlobalXCodeGenerator::CreateXCodeObjects(
// Point Xcode at the top of the source tree.
{
std::string pdir =
- this->RelativeToBinary(root->GetCurrentSourceDirectory().c_str());
+ this->RelativeToBinary(root->GetCurrentSourceDirectory());
this->RootObject->AddAttribute("projectDirPath", this->CreateString(pdir));
this->RootObject->AddAttribute("projectRoot", this->CreateString(""));
}
@@ -3402,10 +3402,8 @@ void cmGlobalXCodeGenerator::OutputXCodeProject(
}
this->WriteXCodePBXProj(fout, root, generators);
- if (this->IsGeneratingScheme(root)) {
- this->OutputXCodeSharedSchemes(xcodeDir);
- }
- this->OutputXCodeWorkspaceSettings(xcodeDir, root);
+ bool hasGeneratedSchemes = this->OutputXCodeSharedSchemes(xcodeDir, root);
+ this->OutputXCodeWorkspaceSettings(xcodeDir, hasGeneratedSchemes);
this->ClearXCodeObjects();
@@ -3415,17 +3413,8 @@ void cmGlobalXCodeGenerator::OutputXCodeProject(
root->GetBinaryDirectory());
}
-bool cmGlobalXCodeGenerator::IsGeneratingScheme(cmLocalGenerator* root) const
-{
- // Since the lowest available Xcode version for testing was 6.4,
- // I'm setting this as a limit then
- return this->XcodeVersion >= 64 &&
- (root->GetMakefile()->GetCMakeInstance()->GetIsInTryCompile() ||
- root->GetMakefile()->IsOn("CMAKE_XCODE_GENERATE_SCHEME"));
-}
-
-void cmGlobalXCodeGenerator::OutputXCodeSharedSchemes(
- const std::string& xcProjDir)
+bool cmGlobalXCodeGenerator::OutputXCodeSharedSchemes(
+ const std::string& xcProjDir, cmLocalGenerator* root)
{
// collect all tests for the targets
std::map<std::string, cmXCodeScheme::TestObjects> testables;
@@ -3449,21 +3438,33 @@ void cmGlobalXCodeGenerator::OutputXCodeSharedSchemes(
}
// generate scheme
- for (auto obj : this->XCodeObjects) {
- if (obj->GetType() == cmXCodeObject::OBJECT &&
- (obj->GetIsA() == cmXCodeObject::PBXNativeTarget ||
- obj->GetIsA() == cmXCodeObject::PBXAggregateTarget)) {
- const std::string& targetName = obj->GetTarget()->GetName();
- cmXCodeScheme schm(obj, testables[targetName],
- this->CurrentConfigurationTypes, this->XcodeVersion);
- schm.WriteXCodeSharedScheme(xcProjDir,
- this->RelativeToSource(xcProjDir.c_str()));
+ bool ret = false;
+
+ // Since the lowest available Xcode version for testing was 6.4,
+ // I'm setting this as a limit then
+ if (this->XcodeVersion >= 64) {
+ for (auto obj : this->XCodeObjects) {
+ if (obj->GetType() == cmXCodeObject::OBJECT &&
+ (obj->GetIsA() == cmXCodeObject::PBXNativeTarget ||
+ obj->GetIsA() == cmXCodeObject::PBXAggregateTarget) &&
+ (root->GetMakefile()->GetCMakeInstance()->GetIsInTryCompile() ||
+ obj->GetTarget()->GetPropertyAsBool("XCODE_GENERATE_SCHEME"))) {
+ const std::string& targetName = obj->GetTarget()->GetName();
+ cmXCodeScheme schm(obj, testables[targetName],
+ this->CurrentConfigurationTypes,
+ this->XcodeVersion);
+ schm.WriteXCodeSharedScheme(xcProjDir,
+ this->RelativeToSource(xcProjDir));
+ ret = true;
+ }
}
}
+
+ return ret;
}
void cmGlobalXCodeGenerator::OutputXCodeWorkspaceSettings(
- const std::string& xcProjDir, cmLocalGenerator* root)
+ const std::string& xcProjDir, bool hasGeneratedSchemes)
{
std::string xcodeSharedDataDir = xcProjDir;
xcodeSharedDataDir += "/project.xcworkspace/xcshareddata";
@@ -3489,7 +3490,7 @@ void cmGlobalXCodeGenerator::OutputXCodeWorkspaceSettings(
xout.Element("key", "BuildSystemType");
xout.Element("string", "Original");
}
- if (this->IsGeneratingScheme(root)) {
+ if (hasGeneratedSchemes) {
xout.Element("key",
"IDEWorkspaceSharedSettings_AutocreateContextsIfNeeded");
xout.Element("false");
@@ -3559,7 +3560,7 @@ std::string cmGlobalXCodeGenerator::ConvertToRelativeForMake(
return cmSystemTools::ConvertToOutputPath(p);
}
-std::string cmGlobalXCodeGenerator::RelativeToSource(const char* p)
+std::string cmGlobalXCodeGenerator::RelativeToSource(const std::string& p)
{
// We force conversion because Xcode breakpoints do not work unless
// they are in a file named relative to the source tree.
@@ -3567,7 +3568,7 @@ std::string cmGlobalXCodeGenerator::RelativeToSource(const char* p)
cmSystemTools::JoinPath(this->ProjectSourceDirectoryComponents), p);
}
-std::string cmGlobalXCodeGenerator::RelativeToBinary(const char* p)
+std::string cmGlobalXCodeGenerator::RelativeToBinary(const std::string& p)
{
return this->CurrentLocalGenerator->MaybeConvertToRelativePath(
cmSystemTools::JoinPath(this->ProjectOutputDirectoryComponents), p);
diff --git a/Source/cmGlobalXCodeGenerator.h b/Source/cmGlobalXCodeGenerator.h
index 95db852..8daa95b 100644
--- a/Source/cmGlobalXCodeGenerator.h
+++ b/Source/cmGlobalXCodeGenerator.h
@@ -119,8 +119,8 @@ private:
const std::string& name);
bool CreateGroups(std::vector<cmLocalGenerator*>& generators);
std::string XCodeEscapePath(const std::string& p);
- std::string RelativeToSource(const char* p);
- std::string RelativeToBinary(const char* p);
+ std::string RelativeToSource(const std::string& p);
+ std::string RelativeToBinary(const std::string& p);
std::string ConvertToRelativeForMake(std::string const& p);
void CreateCustomCommands(cmXCodeObject* buildPhases,
cmXCodeObject* sourceBuildPhase,
@@ -186,11 +186,12 @@ private:
std::vector<cmLocalGenerator*>& generators);
void OutputXCodeProject(cmLocalGenerator* root,
std::vector<cmLocalGenerator*>& generators);
- bool IsGeneratingScheme(cmLocalGenerator* root) const;
// Write shared scheme files for all the native targets
- void OutputXCodeSharedSchemes(const std::string& xcProjDir);
+ // return true if any were written
+ bool OutputXCodeSharedSchemes(const std::string& xcProjDir,
+ cmLocalGenerator* root);
void OutputXCodeWorkspaceSettings(const std::string& xcProjDir,
- cmLocalGenerator* root);
+ bool hasGeneratedSchemes);
void WriteXCodePBXProj(std::ostream& fout, cmLocalGenerator* root,
std::vector<cmLocalGenerator*>& generators);
cmXCodeObject* CreateXCodeFileReferenceFromPath(const std::string& fullpath,
diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx
index d1093be..f3d5a94 100644
--- a/Source/cmLocalUnixMakefileGenerator3.cxx
+++ b/Source/cmLocalUnixMakefileGenerator3.cxx
@@ -12,7 +12,7 @@
#include "cmAlgorithms.h"
#include "cmCustomCommandGenerator.h"
-#include "cmFileTimeComparison.h"
+#include "cmFileTimeCache.h"
#include "cmGeneratedFileStream.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h"
@@ -1273,12 +1273,11 @@ bool cmLocalUnixMakefileGenerator3::UpdateDependencies(
// happen when a new source file is added and CMake regenerates the
// project but no other sources were touched.
bool needRescanDependInfo = false;
- cmFileTimeComparison* ftc =
- this->GlobalGenerator->GetCMakeInstance()->GetFileComparison();
+ cmFileTimeCache* ftc =
+ this->GlobalGenerator->GetCMakeInstance()->GetFileTimeCache();
{
int result;
- if (!ftc->FileTimeCompare(internalDependFile, tgtInfo, &result) ||
- result < 0) {
+ if (!ftc->Compare(internalDependFile, tgtInfo, &result) || result < 0) {
if (verbose) {
std::ostringstream msg;
msg << "Dependee \"" << tgtInfo << "\" is newer than depender \""
@@ -1297,7 +1296,7 @@ bool cmLocalUnixMakefileGenerator3::UpdateDependencies(
dirInfoFile += "/CMakeFiles";
dirInfoFile += "/CMakeDirectoryInformation.cmake";
int result;
- if (!ftc->FileTimeCompare(internalDependFile, dirInfoFile, &result) ||
+ if (!ftc->Compare(internalDependFile, dirInfoFile, &result) ||
result < 0) {
if (verbose) {
std::ostringstream msg;
@@ -1318,7 +1317,7 @@ bool cmLocalUnixMakefileGenerator3::UpdateDependencies(
if (!needRescanDirInfo) {
cmDependsC checker;
checker.SetVerbose(verbose);
- checker.SetFileComparison(ftc);
+ checker.SetFileTimeCache(ftc);
// cmDependsC::Check() fills the vector validDependencies() with the
// dependencies for those files where they are still valid, i.e. neither
// the files themselves nor any files they depend on have changed.
@@ -1439,8 +1438,8 @@ bool cmLocalUnixMakefileGenerator3::ScanDependencies(
if (scanner) {
scanner->SetLocalGenerator(this);
- scanner->SetFileComparison(
- this->GlobalGenerator->GetCMakeInstance()->GetFileComparison());
+ scanner->SetFileTimeCache(
+ this->GlobalGenerator->GetCMakeInstance()->GetFileTimeCache());
scanner->SetLanguage(lang);
scanner->SetTargetDirectory(targetDir);
scanner->Write(ruleFileStream, internalRuleFileStream);
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index ab37774..3832427 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -2023,8 +2023,7 @@ cmTarget* cmMakefile::AddNewTarget(cmStateEnums::TargetType type,
{
cmTargets::iterator it =
this->Targets
- .insert(cmTargets::value_type(
- name, cmTarget(name, type, cmTarget::VisibilityNormal, this)))
+ .emplace(name, cmTarget(name, type, cmTarget::VisibilityNormal, this))
.first;
this->GetGlobalGenerator()->IndexTarget(&it->second);
this->GetStateSnapshot().GetDirectory().AddNormalTargetName(name);
diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx
index 8d11408..1ad26dd 100644
--- a/Source/cmNinjaTargetGenerator.cxx
+++ b/Source/cmNinjaTargetGenerator.cxx
@@ -1113,7 +1113,7 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
// Explicit preprocessing always uses a depfile.
ppVars["DEP_FILE"] = this->GetLocalGenerator()->ConvertToOutputFormat(
- objectFileName + ".d", cmOutputConverter::SHELL);
+ objectFileName + ".pp.d", cmOutputConverter::SHELL);
if (compilePP) {
// The actual compilation does not need a depfile because it
// depends on the already-preprocessed source.
diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h
index 8b21166..7677186 100644
--- a/Source/cmPolicies.h
+++ b/Source/cmPolicies.h
@@ -264,6 +264,9 @@ class cmMakefile;
3, 14, 0, cmPolicies::WARN) \
SELECT(POLICY, CMP0089, \
"Compiler id for IBM Clang-based XL compilers is now XLClang.", 3, \
+ 15, 0, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0090, \
+ "export(PACKAGE) does not populate package registry by default.", 3, \
15, 0, cmPolicies::WARN)
#define CM_SELECT_ID(F, A1, A2, A3, A4, A5, A6) F(A1)
diff --git a/Source/cmQtAutoGen.cxx b/Source/cmQtAutoGen.cxx
index 022947f..87ef112 100644
--- a/Source/cmQtAutoGen.cxx
+++ b/Source/cmQtAutoGen.cxx
@@ -309,7 +309,7 @@ void cmQtAutoGen::RccListConvertFullPath(std::string const& qrcFileDir,
std::vector<std::string>& files)
{
for (std::string& entry : files) {
- std::string tmp = cmSystemTools::CollapseCombinedPath(qrcFileDir, entry);
+ std::string tmp = cmSystemTools::CollapseFullPath(entry, qrcFileDir);
entry = std::move(tmp);
}
}
diff --git a/Source/cmQtAutoGenerator.cxx b/Source/cmQtAutoGenerator.cxx
index af50c1d..a1abd3f 100644
--- a/Source/cmQtAutoGenerator.cxx
+++ b/Source/cmQtAutoGenerator.cxx
@@ -158,11 +158,11 @@ std::string cmQtAutoGenerator::FileSystem::GetRealPath(
return cmSystemTools::GetRealPath(filename);
}
-std::string cmQtAutoGenerator::FileSystem::CollapseCombinedPath(
- std::string const& dir, std::string const& file)
+std::string cmQtAutoGenerator::FileSystem::CollapseFullPath(
+ std::string const& file, std::string const& dir)
{
std::lock_guard<std::mutex> lock(Mutex_);
- return cmSystemTools::CollapseCombinedPath(dir, file);
+ return cmSystemTools::CollapseFullPath(file, dir);
}
void cmQtAutoGenerator::FileSystem::SplitPath(
diff --git a/Source/cmQtAutoGenerator.h b/Source/cmQtAutoGenerator.h
index 6771dd8..b55bebc 100644
--- a/Source/cmQtAutoGenerator.h
+++ b/Source/cmQtAutoGenerator.h
@@ -77,9 +77,9 @@ public:
// -- Paths
/// @brief Wrapper for cmSystemTools::GetRealPath
std::string GetRealPath(std::string const& filename);
- /// @brief Wrapper for cmSystemTools::CollapseCombinedPath
- std::string CollapseCombinedPath(std::string const& dir,
- std::string const& file);
+ /// @brief Wrapper for cmSystemTools::CollapseFullPath
+ std::string CollapseFullPath(std::string const& file,
+ std::string const& dir);
/// @brief Wrapper for cmSystemTools::SplitPath
void SplitPath(const std::string& p, std::vector<std::string>& components,
bool expand_home_dir = true);
diff --git a/Source/cmQtAutoGeneratorMocUic.cxx b/Source/cmQtAutoGeneratorMocUic.cxx
index b02cd44..cb6f7ea 100644
--- a/Source/cmQtAutoGeneratorMocUic.cxx
+++ b/Source/cmQtAutoGeneratorMocUic.cxx
@@ -27,7 +27,7 @@
std::string cmQtAutoGeneratorMocUic::BaseSettingsT::AbsoluteBuildPath(
std::string const& relativePath) const
{
- return FileSys->CollapseCombinedPath(AutogenBuildDir, relativePath);
+ return FileSys->CollapseFullPath(relativePath, AutogenBuildDir);
}
/**
diff --git a/Source/cmState.cxx b/Source/cmState.cxx
index a08e9b8..fa7df0b 100644
--- a/Source/cmState.cxx
+++ b/Source/cmState.cxx
@@ -556,9 +556,28 @@ const char* cmState::GetGlobalProperty(const std::string& prop)
if (prop == "CMAKE_C_KNOWN_FEATURES") {
return &FOR_EACH_C_FEATURE(STRING_LIST_ELEMENT)[1];
}
+ if (prop == "CMAKE_C90_KNOWN_FEATURES") {
+ return &FOR_EACH_C90_FEATURE(STRING_LIST_ELEMENT)[1];
+ }
+ if (prop == "CMAKE_C99_KNOWN_FEATURES") {
+ return &FOR_EACH_C99_FEATURE(STRING_LIST_ELEMENT)[1];
+ }
+ if (prop == "CMAKE_C11_KNOWN_FEATURES") {
+ return &FOR_EACH_C11_FEATURE(STRING_LIST_ELEMENT)[1];
+ }
if (prop == "CMAKE_CXX_KNOWN_FEATURES") {
return &FOR_EACH_CXX_FEATURE(STRING_LIST_ELEMENT)[1];
}
+ if (prop == "CMAKE_CXX98_KNOWN_FEATURES") {
+ return &FOR_EACH_CXX98_FEATURE(STRING_LIST_ELEMENT)[1];
+ }
+ if (prop == "CMAKE_CXX11_KNOWN_FEATURES") {
+ return &FOR_EACH_CXX11_FEATURE(STRING_LIST_ELEMENT)[1];
+ }
+ if (prop == "CMAKE_CXX14_KNOWN_FEATURES") {
+ return &FOR_EACH_CXX14_FEATURE(STRING_LIST_ELEMENT)[1];
+ }
+
#undef STRING_LIST_ELEMENT
return this->GlobalProperties.GetPropertyValue(prop);
}
diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx
index d762106..d201061 100644
--- a/Source/cmSystemTools.cxx
+++ b/Source/cmSystemTools.cxx
@@ -1510,36 +1510,6 @@ std::string cmSystemTools::ForceToRelativePath(std::string const& local_path,
return relative;
}
-std::string cmSystemTools::CollapseCombinedPath(std::string const& dir,
- std::string const& file)
-{
- if (dir.empty() || dir == ".") {
- return file;
- }
-
- std::vector<std::string> dirComponents;
- std::vector<std::string> fileComponents;
- cmSystemTools::SplitPath(dir, dirComponents);
- cmSystemTools::SplitPath(file, fileComponents);
-
- if (fileComponents.empty()) {
- return dir;
- }
- if (!fileComponents[0].empty()) {
- // File is not a relative path.
- return file;
- }
-
- std::vector<std::string>::iterator i = fileComponents.begin() + 1;
- while (i != fileComponents.end() && *i == ".." && dirComponents.size() > 1) {
- ++i; // Remove ".." file component.
- dirComponents.pop_back(); // Remove last dir component.
- }
-
- dirComponents.insert(dirComponents.end(), i, fileComponents.end());
- return cmSystemTools::JoinPath(dirComponents);
-}
-
#ifdef CMAKE_BUILD_WITH_CMAKE
bool cmSystemTools::UnsetEnv(const char* value)
{
@@ -1658,20 +1628,18 @@ bool cmSystemTools::CreateTar(const char* outFileName,
a.SetMTime(mtime);
a.SetVerbose(verbose);
+ bool tarCreatedSuccessfully = true;
for (auto path : files) {
if (cmSystemTools::FileIsFullPath(path)) {
// Get the relative path to the file.
path = cmSystemTools::RelativePath(cwd, path);
}
if (!a.Add(path)) {
- break;
+ cmSystemTools::Error(a.GetError());
+ tarCreatedSuccessfully = false;
}
}
- if (!a) {
- cmSystemTools::Error(a.GetError());
- return false;
- }
- return true;
+ return tarCreatedSuccessfully;
#else
(void)outFileName;
(void)files;
diff --git a/Source/cmSystemTools.h b/Source/cmSystemTools.h
index 60e8c18..0b75025 100644
--- a/Source/cmSystemTools.h
+++ b/Source/cmSystemTools.h
@@ -374,12 +374,6 @@ public:
static std::string ForceToRelativePath(std::string const& local_path,
std::string const& remote_path);
- /** Joins two paths while collapsing x/../ parts
- * For example CollapseCombinedPath("a/b/c", "../../d") results in "a/d"
- */
- static std::string CollapseCombinedPath(std::string const& dir,
- std::string const& file);
-
#ifdef CMAKE_BUILD_WITH_CMAKE
/** Remove an environment variable */
static bool UnsetEnv(const char* value);
@@ -412,6 +406,14 @@ public:
/** Setup the environment to enable VS 8 IDE output. */
static void EnableVSConsoleOutput();
+ enum cmTarAction
+ {
+ TarActionCreate,
+ TarActionList,
+ TarActionExtract,
+ TarActionNone
+ };
+
/** Create tar */
enum cmTarCompression
{
@@ -420,6 +422,7 @@ public:
TarCompressXZ,
TarCompressNone
};
+
static bool ListTar(const char* outFileName, bool verbose);
static bool CreateTar(const char* outFileName,
const std::vector<std::string>& files,
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 46f930a..c6a69be 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -32,6 +32,13 @@
#include "cmTargetPropertyComputer.h"
#include "cmake.h"
+///! Append all elements from the second container to the first container
+template <class C, class R>
+static inline void CApp(C& container, R const& range)
+{
+ container.insert(container.end(), range.begin(), range.end());
+}
+
template <>
const char* cmTargetPropertyComputer::ComputeLocationForBuild<cmTarget>(
cmTarget const* tgt)
@@ -283,6 +290,7 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
this->SetPropertyDefault("FOLDER", nullptr);
#ifdef __APPLE__
if (this->GetGlobalGenerator()->IsXcode()) {
+ this->SetPropertyDefault("XCODE_GENERATE_SCHEME", nullptr);
this->SetPropertyDefault("XCODE_SCHEME_ADDRESS_SANITIZER", nullptr);
this->SetPropertyDefault(
"XCODE_SCHEME_ADDRESS_SANITIZER_USE_AFTER_RETURN", nullptr);
@@ -308,10 +316,6 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
#endif
}
- // Collect the set of configuration types.
- std::vector<std::string> configNames;
- mf->GetConfigurations(configNames);
-
// Setup per-configuration property default values.
if (this->GetType() != cmStateEnums::UTILITY) {
static const auto configProps = {
@@ -321,6 +325,9 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
"COMPILE_PDB_OUTPUT_DIRECTORY_", "MAP_IMPORTED_CONFIG_",
"INTERPROCEDURAL_OPTIMIZATION_"
};
+ // Collect the set of configuration types.
+ std::vector<std::string> configNames;
+ mf->GetConfigurations(configNames);
for (std::string const& configName : configNames) {
std::string configUpper = cmSystemTools::UpperCase(configName);
for (auto const& prop : configProps) {
@@ -355,59 +362,30 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
if (!this->IsImported()) {
// Initialize the INCLUDE_DIRECTORIES property based on the current value
// of the same directory property:
- const cmStringRange parentIncludes =
- this->Makefile->GetIncludeDirectoriesEntries();
- const cmBacktraceRange parentIncludesBts =
- this->Makefile->GetIncludeDirectoriesBacktraces();
-
- this->Internal->IncludeDirectoriesEntries.insert(
- this->Internal->IncludeDirectoriesEntries.end(), parentIncludes.begin(),
- parentIncludes.end());
- this->Internal->IncludeDirectoriesBacktraces.insert(
- this->Internal->IncludeDirectoriesBacktraces.end(),
- parentIncludesBts.begin(), parentIncludesBts.end());
-
- const std::set<std::string> parentSystemIncludes =
- this->Makefile->GetSystemIncludeDirectories();
-
- this->SystemIncludeDirectories.insert(parentSystemIncludes.begin(),
- parentSystemIncludes.end());
-
- const cmStringRange parentCompileOptions =
- this->Makefile->GetCompileOptionsEntries();
- const cmBacktraceRange parentCompileOptionsBts =
- this->Makefile->GetCompileOptionsBacktraces();
-
- this->Internal->CompileOptionsEntries.insert(
- this->Internal->CompileOptionsEntries.end(),
- parentCompileOptions.begin(), parentCompileOptions.end());
- this->Internal->CompileOptionsBacktraces.insert(
- this->Internal->CompileOptionsBacktraces.end(),
- parentCompileOptionsBts.begin(), parentCompileOptionsBts.end());
-
- const cmStringRange parentLinkOptions =
- this->Makefile->GetLinkOptionsEntries();
- const cmBacktraceRange parentLinkOptionsBts =
- this->Makefile->GetLinkOptionsBacktraces();
-
- this->Internal->LinkOptionsEntries.insert(
- this->Internal->LinkOptionsEntries.end(), parentLinkOptions.begin(),
- parentLinkOptions.end());
- this->Internal->LinkOptionsBacktraces.insert(
- this->Internal->LinkOptionsBacktraces.end(),
- parentLinkOptionsBts.begin(), parentLinkOptionsBts.end());
-
- const cmStringRange parentLinkDirectories =
- this->Makefile->GetLinkDirectoriesEntries();
- const cmBacktraceRange parentLinkDirectoriesBts =
- this->Makefile->GetLinkDirectoriesBacktraces();
-
- this->Internal->LinkDirectoriesEntries.insert(
- this->Internal->LinkDirectoriesEntries.end(),
- parentLinkDirectories.begin(), parentLinkDirectories.end());
- this->Internal->LinkDirectoriesBacktraces.insert(
- this->Internal->LinkDirectoriesBacktraces.end(),
- parentLinkDirectoriesBts.begin(), parentLinkDirectoriesBts.end());
+ CApp(this->Internal->IncludeDirectoriesEntries,
+ this->Makefile->GetIncludeDirectoriesEntries());
+ CApp(this->Internal->IncludeDirectoriesBacktraces,
+ this->Makefile->GetIncludeDirectoriesBacktraces());
+
+ {
+ auto const& sysInc = this->Makefile->GetSystemIncludeDirectories();
+ this->SystemIncludeDirectories.insert(sysInc.begin(), sysInc.end());
+ }
+
+ CApp(this->Internal->CompileOptionsEntries,
+ this->Makefile->GetCompileOptionsEntries());
+ CApp(this->Internal->CompileOptionsBacktraces,
+ this->Makefile->GetCompileOptionsBacktraces());
+
+ CApp(this->Internal->LinkOptionsEntries,
+ this->Makefile->GetLinkOptionsEntries());
+ CApp(this->Internal->LinkOptionsBacktraces,
+ this->Makefile->GetLinkOptionsBacktraces());
+
+ CApp(this->Internal->LinkDirectoriesEntries,
+ this->Makefile->GetLinkDirectoriesEntries());
+ CApp(this->Internal->LinkDirectoriesBacktraces,
+ this->Makefile->GetLinkDirectoriesBacktraces());
}
if (this->GetType() != cmStateEnums::INTERFACE_LIBRARY &&
diff --git a/Source/cm_utf8.c b/Source/cm_utf8.c
index 52af4a6..62e7e8c 100644
--- a/Source/cm_utf8.c
+++ b/Source/cm_utf8.c
@@ -2,6 +2,8 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cm_utf8.h"
+#include <string.h>
+
/*
RFC 3629
07-bit: 0xxxxxxx
@@ -71,7 +73,34 @@ const char* cm_utf8_decode_character(const char* first, const char* last,
return 0;
}
+ /* UTF-16 surrogate halves. */
+ if (0xD800 <= uc && uc <= 0xDFFF) {
+ return 0;
+ }
+
+ /* Invalid codepoints. */
+ if (0x10FFFF < uc) {
+ return 0;
+ }
+
*pc = uc;
return first;
}
}
+
+int cm_utf8_is_valid(const char* s)
+{
+ if (!s) {
+ return 0;
+ }
+
+ const char* last = s + strlen(s);
+ const char* pos = s;
+ unsigned int pc;
+
+ while (pos != last && (pos = cm_utf8_decode_character(pos, last, &pc))) {
+ /* Nothing to do. */
+ }
+
+ return pos == last;
+}
diff --git a/Source/cm_utf8.h b/Source/cm_utf8.h
index fcb43e0..27dc559 100644
--- a/Source/cm_utf8.h
+++ b/Source/cm_utf8.h
@@ -13,6 +13,10 @@ extern "C" {
const char* cm_utf8_decode_character(const char* first, const char* last,
unsigned int* pc);
+/** Returns whether a C string is a sequence of valid UTF-8 encoded Unicode
+ codepoints. Returns non-zero on success. */
+int cm_utf8_is_valid(const char* s);
+
#ifdef __cplusplus
} /* extern "C" */
#endif
diff --git a/Source/cmake.cxx b/Source/cmake.cxx
index 69dc26b..8c1a359 100644
--- a/Source/cmake.cxx
+++ b/Source/cmake.cxx
@@ -9,7 +9,7 @@
#include "cmDocumentationFormatter.h"
#include "cmDuration.h"
#include "cmExternalMakefileProjectGenerator.h"
-#include "cmFileTimeComparison.h"
+#include "cmFileTimeCache.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h"
#include "cmGlobalGeneratorFactory.h"
@@ -141,7 +141,7 @@ cmake::cmake(Role role, cmState::Mode mode)
this->DebugOutput = false;
this->DebugTryCompile = false;
this->ClearBuildSystem = false;
- this->FileComparison = new cmFileTimeComparison;
+ this->FileTimeCache = new cmFileTimeCache;
this->State = new cmState;
this->State->SetMode(mode);
@@ -225,7 +225,7 @@ cmake::~cmake()
#ifdef CMAKE_BUILD_WITH_CMAKE
delete this->VariableWatch;
#endif
- delete this->FileComparison;
+ delete this->FileTimeCache;
}
#if defined(CMAKE_BUILD_WITH_CMAKE)
@@ -2144,7 +2144,7 @@ int cmake::CheckBuildSystem()
std::string dep_newest = *dep++;
for (; dep != depends.end(); ++dep) {
int result = 0;
- if (this->FileComparison->FileTimeCompare(dep_newest, *dep, &result)) {
+ if (this->FileTimeCache->Compare(dep_newest, *dep, &result)) {
if (result < 0) {
dep_newest = *dep;
}
@@ -2163,7 +2163,7 @@ int cmake::CheckBuildSystem()
std::string out_oldest = *out++;
for (; out != outputs.end(); ++out) {
int result = 0;
- if (this->FileComparison->FileTimeCompare(out_oldest, *out, &result)) {
+ if (this->FileTimeCache->Compare(out_oldest, *out, &result)) {
if (result > 0) {
out_oldest = *out;
}
@@ -2180,8 +2180,7 @@ int cmake::CheckBuildSystem()
// If any output is older than any dependency then rerun.
{
int result = 0;
- if (!this->FileComparison->FileTimeCompare(out_oldest, dep_newest,
- &result) ||
+ if (!this->FileTimeCache->Compare(out_oldest, dep_newest, &result) ||
result < 0) {
if (verbose) {
std::ostringstream msg;
@@ -2436,20 +2435,22 @@ static bool cmakeCheckStampFile(const std::string& stampName)
}
// Compare the stamp dependencies against the dependency file itself.
- cmFileTimeComparison ftc;
- std::string dep;
- while (cmSystemTools::GetLineFromStream(fin, dep)) {
- int result;
- if (!dep.empty() && dep[0] != '#' &&
- (!ftc.FileTimeCompare(stampDepends, dep, &result) || result < 0)) {
- // The stamp depends file is older than this dependency. The
- // build system is really out of date.
- std::cout << "CMake is re-running because " << stampName
- << " is out-of-date.\n";
- std::cout << " the file '" << dep << "'\n";
- std::cout << " is newer than '" << stampDepends << "'\n";
- std::cout << " result='" << result << "'\n";
- return false;
+ {
+ cmFileTimeCache ftc;
+ std::string dep;
+ while (cmSystemTools::GetLineFromStream(fin, dep)) {
+ int result;
+ if (!dep.empty() && dep[0] != '#' &&
+ (!ftc.Compare(stampDepends, dep, &result) || result < 0)) {
+ // The stamp depends file is older than this dependency. The
+ // build system is really out of date.
+ std::cout << "CMake is re-running because " << stampName
+ << " is out-of-date.\n";
+ std::cout << " the file '" << dep << "'\n";
+ std::cout << " is newer than '" << stampDepends << "'\n";
+ std::cout << " result='" << result << "'\n";
+ return false;
+ }
}
}
diff --git a/Source/cmake.h b/Source/cmake.h
index 1ffeabc..8d22f34 100644
--- a/Source/cmake.h
+++ b/Source/cmake.h
@@ -26,7 +26,7 @@
class cmExternalMakefileProjectGeneratorFactory;
class cmFileAPI;
-class cmFileTimeComparison;
+class cmFileTimeCache;
class cmGlobalGenerator;
class cmGlobalGeneratorFactory;
class cmMakefile;
@@ -329,7 +329,7 @@ public:
/**
* Get the file comparison class
*/
- cmFileTimeComparison* GetFileComparison() { return this->FileComparison; }
+ cmFileTimeCache* GetFileTimeCache() { return this->FileTimeCache; }
// Do we want debug output during the cmake run.
bool GetDebugOutput() { return this->DebugOutput; }
@@ -509,7 +509,7 @@ private:
std::unordered_set<std::string> HeaderFileExtensionsSet;
bool ClearBuildSystem;
bool DebugTryCompile;
- cmFileTimeComparison* FileComparison;
+ cmFileTimeCache* FileTimeCache;
std::string GraphVizFile;
InstalledFilesMap InstalledFiles;
@@ -562,40 +562,38 @@ private:
"not errors." \
}
+#define FOR_EACH_C90_FEATURE(F) F(c_function_prototypes)
+
+#define FOR_EACH_C99_FEATURE(F) \
+ F(c_restrict) \
+ F(c_variadic_macros)
+
+#define FOR_EACH_C11_FEATURE(F) F(c_static_assert)
+
#define FOR_EACH_C_FEATURE(F) \
F(c_std_90) \
F(c_std_99) \
F(c_std_11) \
- F(c_function_prototypes) \
- F(c_restrict) \
- F(c_static_assert) \
- F(c_variadic_macros)
+ FOR_EACH_C90_FEATURE(F) \
+ FOR_EACH_C99_FEATURE(F) \
+ FOR_EACH_C11_FEATURE(F)
-#define FOR_EACH_CXX_FEATURE(F) \
- F(cxx_std_98) \
- F(cxx_std_11) \
- F(cxx_std_14) \
- F(cxx_std_17) \
- F(cxx_std_20) \
- F(cxx_aggregate_default_initializers) \
+#define FOR_EACH_CXX98_FEATURE(F) F(cxx_template_template_parameters)
+
+#define FOR_EACH_CXX11_FEATURE(F) \
F(cxx_alias_templates) \
F(cxx_alignas) \
F(cxx_alignof) \
F(cxx_attributes) \
- F(cxx_attribute_deprecated) \
F(cxx_auto_type) \
- F(cxx_binary_literals) \
F(cxx_constexpr) \
- F(cxx_contextual_conversions) \
F(cxx_decltype) \
- F(cxx_decltype_auto) \
F(cxx_decltype_incomplete_return_types) \
F(cxx_default_function_template_args) \
F(cxx_defaulted_functions) \
F(cxx_defaulted_move_initializers) \
F(cxx_delegating_constructors) \
F(cxx_deleted_functions) \
- F(cxx_digit_separators) \
F(cxx_enum_forward_declarations) \
F(cxx_explicit_conversions) \
F(cxx_extended_friend_declarations) \
@@ -603,11 +601,9 @@ private:
F(cxx_final) \
F(cxx_func_identifier) \
F(cxx_generalized_initializers) \
- F(cxx_generic_lambdas) \
F(cxx_inheriting_constructors) \
F(cxx_inline_namespaces) \
F(cxx_lambdas) \
- F(cxx_lambda_init_captures) \
F(cxx_local_type_template_args) \
F(cxx_long_long_type) \
F(cxx_noexcept) \
@@ -617,22 +613,41 @@ private:
F(cxx_range_for) \
F(cxx_raw_string_literals) \
F(cxx_reference_qualified_functions) \
- F(cxx_relaxed_constexpr) \
- F(cxx_return_type_deduction) \
F(cxx_right_angle_brackets) \
F(cxx_rvalue_references) \
F(cxx_sizeof_member) \
F(cxx_static_assert) \
F(cxx_strong_enums) \
- F(cxx_template_template_parameters) \
F(cxx_thread_local) \
F(cxx_trailing_return_types) \
F(cxx_unicode_literals) \
F(cxx_uniform_initialization) \
F(cxx_unrestricted_unions) \
F(cxx_user_literals) \
- F(cxx_variable_templates) \
F(cxx_variadic_macros) \
F(cxx_variadic_templates)
+#define FOR_EACH_CXX14_FEATURE(F) \
+ F(cxx_aggregate_default_initializers) \
+ F(cxx_attribute_deprecated) \
+ F(cxx_binary_literals) \
+ F(cxx_contextual_conversions) \
+ F(cxx_decltype_auto) \
+ F(cxx_digit_separators) \
+ F(cxx_generic_lambdas) \
+ F(cxx_lambda_init_captures) \
+ F(cxx_relaxed_constexpr) \
+ F(cxx_return_type_deduction) \
+ F(cxx_variable_templates)
+
+#define FOR_EACH_CXX_FEATURE(F) \
+ F(cxx_std_98) \
+ F(cxx_std_11) \
+ F(cxx_std_14) \
+ F(cxx_std_17) \
+ F(cxx_std_20) \
+ FOR_EACH_CXX98_FEATURE(F) \
+ FOR_EACH_CXX11_FEATURE(F) \
+ FOR_EACH_CXX14_FEATURE(F)
+
#endif
diff --git a/Source/cmakemain.cxx b/Source/cmakemain.cxx
index b83c744..d70c9d9 100644
--- a/Source/cmakemain.cxx
+++ b/Source/cmakemain.cxx
@@ -23,6 +23,7 @@
# include "cmsys/ConsoleBuf.hxx"
#endif
+#include <cassert>
#include <ctype.h>
#include <iostream>
#include <string.h>
@@ -72,11 +73,20 @@ static const char* cmDocumentationUsageNote[][2] = {
" the build commands to be executed. \n" \
" -- = Pass remaining options to the native tool.\n"
+# define CMAKE_INSTALL_OPTIONS \
+ " <dir> = Project binary directory to install.\n" \
+ " --config <cfg> = For multi-configuration tools, choose <cfg>.\n" \
+ " --component <comp> = Component-based install. Only install <comp>.\n" \
+ " --prefix <prefix> = The installation prefix CMAKE_INSTALL_PREFIX.\n" \
+ " --strip = Performing install/strip.\n" \
+ " -v --verbose = Enable verbose output.\n"
+
static const char* cmDocumentationOptions[][2] = {
CMAKE_STANDARD_OPTIONS_TABLE,
{ "-E", "CMake command mode." },
{ "-L[A][H]", "List non-advanced cached variables." },
{ "--build <dir>", "Build a CMake-generated project binary tree." },
+ { "--install <dir>", "Install a CMake-generated project binary tree." },
{ "--open <dir>", "Open generated project in the associated application." },
{ "-N", "View mode only." },
{ "-P <file>", "Process script mode." },
@@ -115,6 +125,7 @@ static int do_command(int ac, char const* const* av)
int do_cmake(int ac, char const* const* av);
static int do_build(int ac, char const* const* av);
+static int do_install(int ac, char const* const* av);
static int do_open(int ac, char const* const* av);
static cmMakefile* cmakemainGetMakefile(cmake* cm)
@@ -189,6 +200,9 @@ int main(int ac, char const* const* av)
if (strcmp(av[1], "--build") == 0) {
return do_build(ac, av);
}
+ if (strcmp(av[1], "--install") == 0) {
+ return do_install(ac, av);
+ }
if (strcmp(av[1], "--open") == 0) {
return do_open(ac, av);
}
@@ -525,6 +539,117 @@ static int do_build(int ac, char const* const* av)
#endif
}
+static int do_install(int ac, char const* const* av)
+{
+#ifndef CMAKE_BUILD_WITH_CMAKE
+ std::cerr << "This cmake does not support --install\n";
+ return -1;
+#else
+ assert(1 < ac);
+
+ std::string config;
+ std::string component;
+ std::string prefix;
+ std::string dir;
+ bool strip = false;
+ bool verbose = cmSystemTools::HasEnv("VERBOSE");
+
+ enum Doing
+ {
+ DoingNone,
+ DoingDir,
+ DoingConfig,
+ DoingComponent,
+ DoingPrefix,
+ };
+
+ Doing doing = DoingDir;
+
+ for (int i = 2; i < ac; ++i) {
+ if (strcmp(av[i], "--config") == 0) {
+ doing = DoingConfig;
+ } else if (strcmp(av[i], "--component") == 0) {
+ doing = DoingComponent;
+ } else if (strcmp(av[i], "--prefix") == 0) {
+ doing = DoingPrefix;
+ } else if (strcmp(av[i], "--strip") == 0) {
+ strip = true;
+ doing = DoingNone;
+ } else if ((strcmp(av[i], "--verbose") == 0) ||
+ (strcmp(av[i], "-v") == 0)) {
+ verbose = true;
+ doing = DoingNone;
+ } else {
+ switch (doing) {
+ case DoingDir:
+ dir = cmSystemTools::CollapseFullPath(av[i]);
+ doing = DoingNone;
+ break;
+ case DoingConfig:
+ config = av[i];
+ doing = DoingNone;
+ break;
+ case DoingComponent:
+ component = av[i];
+ doing = DoingNone;
+ break;
+ case DoingPrefix:
+ prefix = av[i];
+ doing = DoingNone;
+ break;
+ default:
+ std::cerr << "Unknown argument " << av[i] << std::endl;
+ dir.clear();
+ break;
+ }
+ }
+ }
+
+ if (dir.empty()) {
+ std::cerr << "Usage: cmake --install <dir> "
+ "[options]\nOptions:\n" CMAKE_INSTALL_OPTIONS;
+ return 1;
+ }
+
+ cmake cm(cmake::RoleScript, cmState::Script);
+
+ cmSystemTools::SetMessageCallback(
+ [&cm](const std::string& msg, const char* title) {
+ cmakemainMessageCallback(msg, title, &cm);
+ });
+ cm.SetProgressCallback([&cm](const std::string& msg, float prog) {
+ cmakemainProgressCallback(msg, prog, &cm);
+ });
+ cm.SetHomeDirectory("");
+ cm.SetHomeOutputDirectory("");
+ cm.SetDebugOutputOn(verbose);
+ cm.SetWorkingMode(cmake::SCRIPT_MODE);
+
+ std::vector<std::string> args{ av[0] };
+
+ if (!prefix.empty()) {
+ args.emplace_back("-DCMAKE_INSTALL_PREFIX=" + prefix);
+ }
+
+ if (!component.empty()) {
+ args.emplace_back("-DCMAKE_INSTALL_COMPONENT=" + component);
+ }
+
+ if (strip) {
+ args.emplace_back("-DCMAKE_INSTALL_DO_STRIP=1");
+ }
+
+ if (!config.empty()) {
+ args.emplace_back("-DCMAKE_INSTALL_CONFIG_NAME=" + config);
+ }
+
+ args.emplace_back("-P");
+ args.emplace_back(dir + "/cmake_install.cmake");
+
+ return cm.Run(args) ? 1 : 0;
+#endif
+}
+
static int do_open(int ac, char const* const* av)
{
#ifndef CMAKE_BUILD_WITH_CMAKE
diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx
index f996a3e..8d63971 100644
--- a/Source/cmcmd.cxx
+++ b/Source/cmcmd.cxx
@@ -1078,21 +1078,47 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string>& args)
files.push_back(arg);
}
}
+ cmSystemTools::cmTarAction action = cmSystemTools::TarActionNone;
cmSystemTools::cmTarCompression compress =
cmSystemTools::TarCompressNone;
bool verbose = false;
int nCompress = 0;
- if (flags.find_first_of('j') != std::string::npos) {
- compress = cmSystemTools::TarCompressBZip2;
- ++nCompress;
- }
- if (flags.find_first_of('J') != std::string::npos) {
- compress = cmSystemTools::TarCompressXZ;
- ++nCompress;
- }
- if (flags.find_first_of('z') != std::string::npos) {
- compress = cmSystemTools::TarCompressGZip;
- ++nCompress;
+
+ for (auto flag : flags) {
+ switch (flag) {
+ case '-':
+ case 'f': {
+ // Keep for backward compatibility. Ignored
+ } break;
+ case 'j': {
+ compress = cmSystemTools::TarCompressBZip2;
+ ++nCompress;
+ } break;
+ case 'J': {
+ compress = cmSystemTools::TarCompressXZ;
+ ++nCompress;
+ } break;
+ case 'z': {
+ compress = cmSystemTools::TarCompressGZip;
+ ++nCompress;
+ } break;
+ case 'v': {
+ verbose = true;
+ } break;
+ case 't': {
+ action = cmSystemTools::TarActionList;
+ } break;
+ case 'c': {
+ action = cmSystemTools::TarActionCreate;
+ } break;
+ case 'x': {
+ action = cmSystemTools::TarActionExtract;
+ } break;
+ default: {
+ cmSystemTools::Message(
+ std::string("tar: Unknown argument: ") + flag, "Warning");
+ }
+ }
}
if ((format == "7zip" || format == "zip") && nCompress > 0) {
cmSystemTools::Error("Can not use compression flags with format: " +
@@ -1104,22 +1130,22 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string>& args)
"at most one flag of z, j, or J may be used");
return 1;
}
- if (flags.find_first_of('v') != std::string::npos) {
- verbose = true;
- }
-
- if (flags.find_first_of('t') != std::string::npos) {
+ if (action == cmSystemTools::TarActionList) {
if (!cmSystemTools::ListTar(outFile.c_str(), verbose)) {
cmSystemTools::Error("Problem listing tar: " + outFile);
return 1;
}
- } else if (flags.find_first_of('c') != std::string::npos) {
+ } else if (action == cmSystemTools::TarActionCreate) {
+ if (files.empty()) {
+ cmSystemTools::Message("tar: No files or directories specified",
+ "Warning");
+ }
if (!cmSystemTools::CreateTar(outFile.c_str(), files, compress,
verbose, mtime, format)) {
cmSystemTools::Error("Problem creating tar: " + outFile);
return 1;
}
- } else if (flags.find_first_of('x') != std::string::npos) {
+ } else if (action == cmSystemTools::TarActionExtract) {
if (!cmSystemTools::ExtractTar(outFile.c_str(), verbose)) {
cmSystemTools::Error("Problem extracting tar: " + outFile);
return 1;
@@ -1140,6 +1166,10 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string>& args)
cmSystemTools::Delay(delay);
}
#endif
+ } else {
+ cmSystemTools::Error("tar: No action specified. Please choose: 't' "
+ "(list), 'c' (create) or 'x' (extract)");
+ return 1;
}
return 0;
}
diff --git a/Source/ctest.cxx b/Source/ctest.cxx
index 4a2531a..461021b 100644
--- a/Source/ctest.cxx
+++ b/Source/ctest.cxx
@@ -191,8 +191,7 @@ int main(int argc, char const* const* argv)
doc.addCTestStandardDocSections();
if (doc.CheckOptions(argc, argv)) {
// Construct and print requested documentation.
- cmCTestScriptHandler* ch =
- static_cast<cmCTestScriptHandler*>(inst.GetHandler("script"));
+ cmCTestScriptHandler* ch = inst.GetScriptHandler();
ch->CreateCMake();
doc.SetShowGenerators(false);
diff --git a/Source/kwsys/SystemTools.cxx b/Source/kwsys/SystemTools.cxx
index 33a92e4..b736ed4 100644
--- a/Source/kwsys/SystemTools.cxx
+++ b/Source/kwsys/SystemTools.cxx
@@ -28,6 +28,7 @@
#include <iostream>
#include <set>
#include <sstream>
+#include <utility>
#include <vector>
// Work-around CMake dependency scanning limitation. This must
@@ -363,10 +364,6 @@ double SystemTools::GetTime(void)
#endif
}
-class SystemToolsTranslationMap : public std::map<std::string, std::string>
-{
-};
-
/* Type of character storing the environment. */
#if defined(_WIN32)
typedef wchar_t envchar;
@@ -447,15 +444,139 @@ struct SystemToolsPathCaseCmp
# endif
}
};
+#endif
-class SystemToolsPathCaseMap
- : public std::map<std::string, std::string, SystemToolsPathCaseCmp>
+/**
+ * SystemTools static variables singleton class.
+ */
+class SystemToolsStatic
{
+public:
+ typedef std::map<std::string, std::string> StringMap;
+ /**
+ * Path translation table from dir to refdir
+ * Each time 'dir' will be found it will be replace by 'refdir'
+ */
+ StringMap TranslationMap;
+#ifdef _WIN32
+ static std::string GetCasePathName(std::string const& pathIn);
+ static std::string GetActualCaseForPathCached(std::string const& path);
+ static const char* GetEnvBuffered(const char* key);
+ std::map<std::string, std::string, SystemToolsPathCaseCmp> PathCaseMap;
+ std::map<std::string, std::string> EnvMap;
+#endif
+#ifdef __CYGWIN__
+ StringMap Cyg2Win32Map;
+#endif
+
+ /**
+ * Actual implementation of ReplaceString.
+ */
+ static void ReplaceString(std::string& source, const char* replace,
+ size_t replaceSize, const std::string& with);
+
+ /**
+ * Actual implementation of FileIsFullPath.
+ */
+ static bool FileIsFullPath(const char*, size_t);
+
+ /**
+ * Find a filename (file or directory) in the system PATH, with
+ * optional extra paths.
+ */
+ static std::string FindName(
+ const std::string& name,
+ const std::vector<std::string>& path = std::vector<std::string>(),
+ bool no_system_path = false);
};
-class SystemToolsEnvMap : public std::map<std::string, std::string>
+#ifdef _WIN32
+std::string SystemToolsStatic::GetCasePathName(std::string const& pathIn)
{
-};
+ std::string casePath;
+
+ // First check if the file is relative. We don't fix relative paths since the
+ // real case depends on the root directory and the given path fragment may
+ // have meaning elsewhere in the project.
+ if (!SystemTools::FileIsFullPath(pathIn)) {
+ // This looks unnecessary, but it allows for the return value optimization
+ // since all return paths return the same local variable.
+ casePath = pathIn;
+ return casePath;
+ }
+
+ std::vector<std::string> path_components;
+ SystemTools::SplitPath(pathIn, path_components);
+
+ // Start with root component.
+ std::vector<std::string>::size_type idx = 0;
+ casePath = path_components[idx++];
+ // make sure drive letter is always upper case
+ if (casePath.size() > 1 && casePath[1] == ':') {
+ casePath[0] = toupper(casePath[0]);
+ }
+ const char* sep = "";
+
+ // If network path, fill casePath with server/share so FindFirstFile
+ // will work after that. Maybe someday call other APIs to get
+ // actual case of servers and shares.
+ if (path_components.size() > 2 && path_components[0] == "//") {
+ casePath += path_components[idx++];
+ casePath += "/";
+ casePath += path_components[idx++];
+ sep = "/";
+ }
+
+ // Convert case of all components that exist.
+ bool converting = true;
+ for (; idx < path_components.size(); idx++) {
+ casePath += sep;
+ sep = "/";
+
+ if (converting) {
+ // If path component contains wildcards, we skip matching
+ // because these filenames are not allowed on windows,
+ // and we do not want to match a different file.
+ if (path_components[idx].find('*') != std::string::npos ||
+ path_components[idx].find('?') != std::string::npos) {
+ converting = false;
+ } else {
+ std::string test_str = casePath;
+ test_str += path_components[idx];
+ WIN32_FIND_DATAW findData;
+ HANDLE hFind =
+ ::FindFirstFileW(Encoding::ToWide(test_str).c_str(), &findData);
+ if (INVALID_HANDLE_VALUE != hFind) {
+ path_components[idx] = Encoding::ToNarrow(findData.cFileName);
+ ::FindClose(hFind);
+ } else {
+ converting = false;
+ }
+ }
+ }
+
+ casePath += path_components[idx];
+ }
+ return casePath;
+}
+
+std::string SystemToolsStatic::GetActualCaseForPathCached(std::string const& p)
+{
+ // Check to see if actual case has already been called
+ // for this path, and the result is stored in the PathCaseMap
+ auto& pcm = SystemTools::Statics->PathCaseMap;
+ {
+ auto itr = pcm.find(p);
+ if (itr != pcm.end()) {
+ return itr->second;
+ }
+ }
+ std::string casePath = SystemToolsStatic::GetCasePathName(p);
+ if (casePath.size() <= MAX_PATH) {
+ pcm[p] = casePath;
+ }
+ return casePath;
+}
#endif
// adds the elements of the env variable path to the arg passed in
@@ -496,30 +617,35 @@ void SystemTools::GetPath(std::vector<std::string>& path, const char* env)
}
}
-const char* SystemTools::GetEnvImpl(const char* key)
-{
- const char* v = KWSYS_NULLPTR;
#if defined(_WIN32)
+const char* SystemToolsStatic::GetEnvBuffered(const char* key)
+{
std::string env;
if (SystemTools::GetEnv(key, env)) {
- std::string& menv = (*SystemTools::EnvMap)[key];
- menv = env;
- v = menv.c_str();
+ std::string& menv = SystemTools::Statics->EnvMap[key];
+ menv = std::move(env);
+ return menv.c_str();
}
-#else
- v = getenv(key);
-#endif
- return v;
+ return KWSYS_NULLPTR;
}
+#endif
const char* SystemTools::GetEnv(const char* key)
{
- return SystemTools::GetEnvImpl(key);
+#if defined(_WIN32)
+ return SystemToolsStatic::GetEnvBuffered(key);
+#else
+ return getenv(key);
+#endif
}
const char* SystemTools::GetEnv(const std::string& key)
{
- return SystemTools::GetEnvImpl(key.c_str());
+#if defined(_WIN32)
+ return SystemToolsStatic::GetEnvBuffered(key.c_str());
+#else
+ return getenv(key.c_str());
+#endif
}
bool SystemTools::GetEnv(const char* key, std::string& result)
@@ -822,7 +948,8 @@ void SystemTools::ReplaceString(std::string& source,
return;
}
- SystemTools::ReplaceString(source, replace.c_str(), replace.size(), with);
+ SystemToolsStatic::ReplaceString(source, replace.c_str(), replace.size(),
+ with);
}
void SystemTools::ReplaceString(std::string& source, const char* replace,
@@ -833,12 +960,13 @@ void SystemTools::ReplaceString(std::string& source, const char* replace,
return;
}
- SystemTools::ReplaceString(source, replace, strlen(replace),
- with ? with : "");
+ SystemToolsStatic::ReplaceString(source, replace, strlen(replace),
+ with ? with : "");
}
-void SystemTools::ReplaceString(std::string& source, const char* replace,
- size_t replaceSize, const std::string& with)
+void SystemToolsStatic::ReplaceString(std::string& source, const char* replace,
+ size_t replaceSize,
+ const std::string& with)
{
const char* src = source.c_str();
char* searchPos = const_cast<char*>(strstr(src, replace));
@@ -1316,18 +1444,16 @@ int SystemTools::Stat(const std::string& path, SystemTools::Stat_t* buf)
#ifdef __CYGWIN__
bool SystemTools::PathCygwinToWin32(const char* path, char* win32_path)
{
- SystemToolsTranslationMap::iterator i =
- SystemTools::Cyg2Win32Map->find(path);
-
- if (i != SystemTools::Cyg2Win32Map->end()) {
- strncpy(win32_path, i->second.c_str(), MAX_PATH);
+ auto itr = SystemTools::Statics->Cyg2Win32Map.find(path);
+ if (itr != SystemTools::Statics->Cyg2Win32Map.end()) {
+ strncpy(win32_path, itr->second.c_str(), MAX_PATH);
} else {
if (cygwin_conv_path(CCP_POSIX_TO_WIN_A, path, win32_path, MAX_PATH) !=
0) {
win32_path[0] = 0;
}
- SystemToolsTranslationMap::value_type entry(path, win32_path);
- SystemTools::Cyg2Win32Map->insert(entry);
+ SystemTools::Statics->Cyg2Win32Map.insert(
+ SystemToolsStatic::StringMap::value_type(path, win32_path));
}
return win32_path[0] != 0;
}
@@ -2673,9 +2799,9 @@ size_t SystemTools::GetMaximumFilePathLength()
* the system search path. Returns the full path to the file if it is
* found. Otherwise, the empty string is returned.
*/
-std::string SystemTools::FindName(const std::string& name,
- const std::vector<std::string>& userPaths,
- bool no_system_path)
+std::string SystemToolsStatic::FindName(
+ const std::string& name, const std::vector<std::string>& userPaths,
+ bool no_system_path)
{
// Add the system search path to our path first
std::vector<std::string> path;
@@ -2723,7 +2849,8 @@ std::string SystemTools::FindFile(const std::string& name,
const std::vector<std::string>& userPaths,
bool no_system_path)
{
- std::string tryPath = SystemTools::FindName(name, userPaths, no_system_path);
+ std::string tryPath =
+ SystemToolsStatic::FindName(name, userPaths, no_system_path);
if (!tryPath.empty() && !SystemTools::FileIsDirectory(tryPath)) {
return SystemTools::CollapseFullPath(tryPath);
}
@@ -2740,7 +2867,8 @@ std::string SystemTools::FindDirectory(
const std::string& name, const std::vector<std::string>& userPaths,
bool no_system_path)
{
- std::string tryPath = SystemTools::FindName(name, userPaths, no_system_path);
+ std::string tryPath =
+ SystemToolsStatic::FindName(name, userPaths, no_system_path);
if (!tryPath.empty() && SystemTools::FileIsDirectory(tryPath)) {
return SystemTools::CollapseFullPath(tryPath);
}
@@ -3244,8 +3372,9 @@ void SystemTools::AddTranslationPath(const std::string& a,
path_b += '/';
}
if (!(path_a == path_b)) {
- SystemTools::TranslationMap->insert(
- SystemToolsTranslationMap::value_type(path_a, path_b));
+ SystemTools::Statics->TranslationMap.insert(
+ SystemToolsStatic::StringMap::value_type(std::move(path_a),
+ std::move(path_b)));
}
}
}
@@ -3269,21 +3398,19 @@ void SystemTools::CheckTranslationPath(std::string& path)
// Always add a trailing slash before translation. It does not
// matter if this adds an extra slash, but we do not want to
// translate part of a directory (like the foo part of foo-dir).
- path += "/";
+ path += '/';
// In case a file was specified we still have to go through this:
// Now convert any path found in the table back to the one desired:
- std::map<std::string, std::string>::const_iterator it;
- for (it = SystemTools::TranslationMap->begin();
- it != SystemTools::TranslationMap->end(); ++it) {
+ for (auto const& pair : SystemTools::Statics->TranslationMap) {
// We need to check of the path is a substring of the other path
- if (path.find(it->first) == 0) {
- path = path.replace(0, it->first.size(), it->second);
+ if (path.find(pair.first) == 0) {
+ path = path.replace(0, pair.first.size(), pair.second);
}
}
// Remove the trailing slash we added before.
- path.erase(path.end() - 1, path.end());
+ path.pop_back();
}
static void SystemToolsAppendComponents(
@@ -3371,7 +3498,7 @@ std::string SystemTools::CollapseFullPath(const std::string& in_path,
SystemTools::CheckTranslationPath(newPath);
#ifdef _WIN32
- newPath = SystemTools::GetActualCaseForPathCached(newPath);
+ newPath = SystemTools::Statics->GetActualCaseForPathCached(newPath);
SystemTools::ConvertToUnixSlashes(newPath);
#endif
// Return the reconstructed path.
@@ -3457,104 +3584,15 @@ std::string SystemTools::RelativePath(const std::string& local,
return relativePath;
}
-#ifdef _WIN32
-static std::string GetCasePathName(std::string const& pathIn)
-{
- std::string casePath;
-
- // First check if the file is relative. We don't fix relative paths since the
- // real case depends on the root directory and the given path fragment may
- // have meaning elsewhere in the project.
- if (!SystemTools::FileIsFullPath(pathIn)) {
- // This looks unnecessary, but it allows for the return value optimization
- // since all return paths return the same local variable.
- casePath = pathIn;
- return casePath;
- }
-
- std::vector<std::string> path_components;
- SystemTools::SplitPath(pathIn, path_components);
-
- // Start with root component.
- std::vector<std::string>::size_type idx = 0;
- casePath = path_components[idx++];
- // make sure drive letter is always upper case
- if (casePath.size() > 1 && casePath[1] == ':') {
- casePath[0] = toupper(casePath[0]);
- }
- const char* sep = "";
-
- // If network path, fill casePath with server/share so FindFirstFile
- // will work after that. Maybe someday call other APIs to get
- // actual case of servers and shares.
- if (path_components.size() > 2 && path_components[0] == "//") {
- casePath += path_components[idx++];
- casePath += "/";
- casePath += path_components[idx++];
- sep = "/";
- }
-
- // Convert case of all components that exist.
- bool converting = true;
- for (; idx < path_components.size(); idx++) {
- casePath += sep;
- sep = "/";
-
- if (converting) {
- // If path component contains wildcards, we skip matching
- // because these filenames are not allowed on windows,
- // and we do not want to match a different file.
- if (path_components[idx].find('*') != std::string::npos ||
- path_components[idx].find('?') != std::string::npos) {
- converting = false;
- } else {
- std::string test_str = casePath;
- test_str += path_components[idx];
- WIN32_FIND_DATAW findData;
- HANDLE hFind =
- ::FindFirstFileW(Encoding::ToWide(test_str).c_str(), &findData);
- if (INVALID_HANDLE_VALUE != hFind) {
- path_components[idx] = Encoding::ToNarrow(findData.cFileName);
- ::FindClose(hFind);
- } else {
- converting = false;
- }
- }
- }
-
- casePath += path_components[idx];
- }
- return casePath;
-}
-#endif
-
std::string SystemTools::GetActualCaseForPath(const std::string& p)
{
-#ifndef _WIN32
- return p;
+#ifdef _WIN32
+ return SystemToolsStatic::GetCasePathName(p);
#else
- return GetCasePathName(p);
+ return p;
#endif
}
-#ifdef _WIN32
-std::string SystemTools::GetActualCaseForPathCached(std::string const& p)
-{
- // Check to see if actual case has already been called
- // for this path, and the result is stored in the PathCaseMap
- SystemToolsPathCaseMap::iterator i = SystemTools::PathCaseMap->find(p);
- if (i != SystemTools::PathCaseMap->end()) {
- return i->second;
- }
- std::string casePath = GetCasePathName(p);
- if (casePath.size() > MAX_PATH) {
- return casePath;
- }
- (*SystemTools::PathCaseMap)[p] = casePath;
- return casePath;
-}
-#endif
-
const char* SystemTools::SplitPathRootComponent(const std::string& p,
std::string* root)
{
@@ -4047,16 +4085,16 @@ bool SystemTools::LocateFileInDir(const char* filename, const char* dir,
bool SystemTools::FileIsFullPath(const std::string& in_name)
{
- return SystemTools::FileIsFullPath(in_name.c_str(), in_name.size());
+ return SystemToolsStatic::FileIsFullPath(in_name.c_str(), in_name.size());
}
bool SystemTools::FileIsFullPath(const char* in_name)
{
- return SystemTools::FileIsFullPath(in_name,
- in_name[0] ? (in_name[1] ? 2 : 1) : 0);
+ return SystemToolsStatic::FileIsFullPath(
+ in_name, in_name[0] ? (in_name[1] ? 2 : 1) : 0);
}
-bool SystemTools::FileIsFullPath(const char* in_name, size_t len)
+bool SystemToolsStatic::FileIsFullPath(const char* in_name, size_t len)
{
#if defined(_WIN32) || defined(__CYGWIN__)
// On Windows, the name must be at least two characters long.
@@ -4654,14 +4692,7 @@ bool SystemTools::ParseURL(const std::string& URL, std::string& protocol,
// These must NOT be initialized. Default initialization to zero is
// necessary.
static unsigned int SystemToolsManagerCount;
-SystemToolsTranslationMap* SystemTools::TranslationMap;
-#ifdef _WIN32
-SystemToolsPathCaseMap* SystemTools::PathCaseMap;
-SystemToolsEnvMap* SystemTools::EnvMap;
-#endif
-#ifdef __CYGWIN__
-SystemToolsTranslationMap* SystemTools::Cyg2Win32Map;
-#endif
+SystemToolsStatic* SystemTools::Statics;
// SystemToolsManager manages the SystemTools singleton.
// SystemToolsManager should be included in any translation unit
@@ -4702,15 +4733,9 @@ void SystemTools::ClassInitialize()
#ifdef __VMS
SetVMSFeature("DECC$FILENAME_UNIX_ONLY", 1);
#endif
- // Allocate the translation map first.
- SystemTools::TranslationMap = new SystemToolsTranslationMap;
-#ifdef _WIN32
- SystemTools::PathCaseMap = new SystemToolsPathCaseMap;
- SystemTools::EnvMap = new SystemToolsEnvMap;
-#endif
-#ifdef __CYGWIN__
- SystemTools::Cyg2Win32Map = new SystemToolsTranslationMap;
-#endif
+
+ // Create statics singleton instance
+ SystemTools::Statics = new SystemToolsStatic;
// Add some special translation paths for unix. These are not added
// for windows because drive letters need to be maintained. Also,
@@ -4758,14 +4783,7 @@ void SystemTools::ClassInitialize()
void SystemTools::ClassFinalize()
{
- delete SystemTools::TranslationMap;
-#ifdef _WIN32
- delete SystemTools::PathCaseMap;
- delete SystemTools::EnvMap;
-#endif
-#ifdef __CYGWIN__
- delete SystemTools::Cyg2Win32Map;
-#endif
+ delete SystemTools::Statics;
}
} // namespace KWSYS_NAMESPACE
diff --git a/Source/kwsys/SystemTools.hxx.in b/Source/kwsys/SystemTools.hxx.in
index 33b579f..cdc9483 100644
--- a/Source/kwsys/SystemTools.hxx.in
+++ b/Source/kwsys/SystemTools.hxx.in
@@ -41,9 +41,7 @@ typedef @KWSYS_NAMESPACE@_VA_LIST::hack_va_list va_list;
namespace @KWSYS_NAMESPACE@ {
-class SystemToolsTranslationMap;
-class SystemToolsPathCaseMap;
-class SystemToolsEnvMap;
+class SystemToolsStatic;
/** \class SystemToolsManager
* \brief Use to make sure SystemTools is initialized before it is used
@@ -967,41 +965,8 @@ private:
return &SystemToolsManagerInstance;
}
- /**
- * Actual implementation of ReplaceString.
- */
- static void ReplaceString(std::string& source, const char* replace,
- size_t replaceSize, const std::string& with);
-
- /**
- * Actual implementation of FileIsFullPath.
- */
- static bool FileIsFullPath(const char*, size_t);
-
- /**
- * Find a filename (file or directory) in the system PATH, with
- * optional extra paths.
- */
- static std::string FindName(
- const std::string& name,
- const std::vector<std::string>& path = std::vector<std::string>(),
- bool no_system_path = false);
-
- static const char* GetEnvImpl(const char* key);
-
- /**
- * Path translation table from dir to refdir
- * Each time 'dir' will be found it will be replace by 'refdir'
- */
- static SystemToolsTranslationMap* TranslationMap;
-#ifdef _WIN32
- static std::string GetActualCaseForPathCached(std::string const& path);
- static SystemToolsPathCaseMap* PathCaseMap;
- static SystemToolsEnvMap* EnvMap;
-#endif
-#ifdef __CYGWIN__
- static SystemToolsTranslationMap* Cyg2Win32Map;
-#endif
+ static SystemToolsStatic* Statics;
+ friend class SystemToolsStatic;
friend class SystemToolsManager;
};
diff --git a/Tests/CMakeLib/testRange.cxx b/Tests/CMakeLib/testRange.cxx
index 5ae805f..b26b07b 100644
--- a/Tests/CMakeLib/testRange.cxx
+++ b/Tests/CMakeLib/testRange.cxx
@@ -11,7 +11,7 @@
do { \
if (!(x)) { \
std::cout << "ASSERT_TRUE(" #x ") failed on line " << __LINE__ << "\n"; \
- return false; \
+ return -1; \
} \
} while (false)
diff --git a/Tests/CMakeLib/testUTF8.cxx b/Tests/CMakeLib/testUTF8.cxx
index c99c46d..a0bb5cd 100644
--- a/Tests/CMakeLib/testUTF8.cxx
+++ b/Tests/CMakeLib/testUTF8.cxx
@@ -13,6 +13,21 @@ static void test_utf8_char_print(test_utf8_char const c)
static_cast<int>(d[3]));
}
+static void byte_array_print(char const* s)
+{
+ unsigned char const* d = reinterpret_cast<unsigned char const*>(s);
+ bool started = false;
+ printf("[");
+ for (; *d; ++d) {
+ if (started) {
+ printf(",");
+ }
+ started = true;
+ printf("0x%02X", static_cast<int>(*d));
+ }
+ printf("]");
+}
+
struct test_utf8_entry
{
int n;
@@ -21,17 +36,36 @@ struct test_utf8_entry
};
static test_utf8_entry const good_entry[] = {
- { 1, "\x20\x00\x00\x00", 0x0020 }, /* Space. */
- { 2, "\xC2\xA9\x00\x00", 0x00A9 }, /* Copyright. */
- { 3, "\xE2\x80\x98\x00", 0x2018 }, /* Open-single-quote. */
- { 3, "\xE2\x80\x99\x00", 0x2019 }, /* Close-single-quote. */
- { 4, "\xF0\xA3\x8E\xB4", 0x233B4 }, /* Example from RFC 3629. */
+ { 1, "\x20\x00\x00\x00", 0x0020 }, /* Space. */
+ { 2, "\xC2\xA9\x00\x00", 0x00A9 }, /* Copyright. */
+ { 3, "\xE2\x80\x98\x00", 0x2018 }, /* Open-single-quote. */
+ { 3, "\xE2\x80\x99\x00", 0x2019 }, /* Close-single-quote. */
+ { 4, "\xF0\xA3\x8E\xB4", 0x233B4 }, /* Example from RFC 3629. */
+ { 3, "\xED\x80\x80\x00", 0xD000 }, /* Valid 0xED prefixed codepoint. */
+ { 4, "\xF4\x8F\xBF\xBF", 0x10FFFF }, /* Highest valid RFC codepoint. */
{ 0, { 0, 0, 0, 0, 0 }, 0 }
};
static test_utf8_char const bad_chars[] = {
- "\x80\x00\x00\x00", "\xC0\x00\x00\x00", "\xE0\x00\x00\x00",
- "\xE0\x80\x80\x00", "\xF0\x80\x80\x80", { 0, 0, 0, 0, 0 }
+ "\x80\x00\x00\x00", /* Leading continuation byte. */
+ "\xC0\x80\x00\x00", /* Overlong encoding. */
+ "\xC1\x80\x00\x00", /* Overlong encoding. */
+ "\xC2\x00\x00\x00", /* Missing continuation byte. */
+ "\xE0\x00\x00\x00", /* Missing continuation bytes. */
+ "\xE0\x80\x80\x00", /* Overlong encoding. */
+ "\xF0\x80\x80\x80", /* Overlong encoding. */
+ "\xED\xA0\x80\x00", /* UTF-16 surrogate half. */
+ "\xED\xBF\xBF\x00", /* UTF-16 surrogate half. */
+ "\xF4\x90\x80\x80", /* Lowest out-of-range codepoint. */
+ "\xF5\x80\x80\x80", /* Prefix forces out-of-range codepoints. */
+ { 0, 0, 0, 0, 0 }
+};
+
+static char const* good_strings[] = { "", "ASCII", "\xC2\xA9 Kitware", 0 };
+
+static char const* bad_strings[] = {
+ "\xC0\x80", /* Modified UTF-8 for embedded 0-byte. */
+ 0
};
static void report_good(bool passed, test_utf8_char const c)
@@ -87,6 +121,46 @@ static bool decode_bad(test_utf8_char const s)
return true;
}
+static void report_valid(bool passed, char const* s)
+{
+ printf("%s: validity good ", passed ? "pass" : "FAIL");
+ byte_array_print(s);
+ printf(" (%s) ", s);
+}
+
+static void report_invalid(bool passed, char const* s)
+{
+ printf("%s: validity bad ", passed ? "pass" : "FAIL");
+ byte_array_print(s);
+ printf(" ");
+}
+
+static bool is_valid(const char* s)
+{
+ bool valid = cm_utf8_is_valid(s) != 0;
+ if (!valid) {
+ report_valid(false, s);
+ printf("expected valid, reported as invalid\n");
+ return false;
+ }
+ report_valid(true, s);
+ printf("valid as expected\n");
+ return true;
+}
+
+static bool is_invalid(const char* s)
+{
+ bool valid = cm_utf8_is_valid(s) != 0;
+ if (valid) {
+ report_invalid(false, s);
+ printf("expected invalid, reported as valid\n");
+ return false;
+ }
+ report_invalid(true, s);
+ printf("invalid as expected\n");
+ return true;
+}
+
int testUTF8(int /*unused*/, char* /*unused*/ [])
{
int result = 0;
@@ -94,11 +168,27 @@ int testUTF8(int /*unused*/, char* /*unused*/ [])
if (!decode_good(*e)) {
result = 1;
}
+ if (!is_valid(e->str)) {
+ result = 1;
+ }
}
for (test_utf8_char const* c = bad_chars; (*c)[0]; ++c) {
if (!decode_bad(*c)) {
result = 1;
}
+ if (!is_invalid(*c)) {
+ result = 1;
+ }
+ }
+ for (char const** s = good_strings; *s; ++s) {
+ if (!is_valid(*s)) {
+ result = 1;
+ }
+ }
+ for (char const** s = bad_strings; *s; ++s) {
+ if (!is_invalid(*s)) {
+ result = 1;
+ }
}
return result;
}
diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt
index a59b6eb..3746965 100644
--- a/Tests/CMakeLists.txt
+++ b/Tests/CMakeLists.txt
@@ -1421,6 +1421,10 @@ ${CMake_BINARY_DIR}/bin/cmake -DDIR=dev -P ${CMake_SOURCE_DIR}/Utilities/Release
add_subdirectory(FindDoxygen)
endif()
+ if(CMake_TEST_FindEnvModules)
+ add_subdirectory(FindEnvModules)
+ endif()
+
if(CMake_TEST_FindEXPAT)
add_subdirectory(FindEXPAT)
endif()
@@ -1445,6 +1449,10 @@ ${CMake_BINARY_DIR}/bin/cmake -DDIR=dev -P ${CMake_SOURCE_DIR}/Utilities/Release
add_subdirectory(FindGit)
endif()
+ if(CMake_TEST_FindGLEW)
+ add_subdirectory(FindGLEW)
+ endif()
+
if(CMake_TEST_FindGSL)
add_subdirectory(FindGSL)
endif()
diff --git a/Tests/FindEnvModules/CMakeLists.txt b/Tests/FindEnvModules/CMakeLists.txt
new file mode 100644
index 0000000..95b7d1d
--- /dev/null
+++ b/Tests/FindEnvModules/CMakeLists.txt
@@ -0,0 +1,3 @@
+add_test(FindEnvModules.Test ${CMAKE_CMAKE_COMMAND}
+ -P ${CMAKE_CURRENT_LIST_DIR}/EnvModules.cmake
+)
diff --git a/Tests/FindEnvModules/EnvModules.cmake b/Tests/FindEnvModules/EnvModules.cmake
new file mode 100644
index 0000000..0c81bf2
--- /dev/null
+++ b/Tests/FindEnvModules/EnvModules.cmake
@@ -0,0 +1,35 @@
+find_package(EnvModules REQUIRED)
+message("module purge")
+env_module(COMMAND purge RESULT_VARIABLE ret_var)
+if(NOT ret_var EQUAL 0)
+ message(FATAL_ERROR "module(purge) returned ${ret_var}")
+endif()
+
+message("module avail")
+env_module_avail(avail_mods)
+foreach(mod IN LISTS avail_mods)
+ message(" ${mod}")
+endforeach()
+
+if(avail_mods)
+ list(GET avail_mods 0 mod0)
+ message("module load ${mod0}")
+ env_module(load ${mod0})
+
+ message("module list")
+ env_module_list(loaded_mods)
+ foreach(mod IN LISTS loaded_mods)
+ message(" ${mod}")
+ endforeach()
+
+ list(LENGTH loaded_mods num_loaded_mods)
+ message("Number of modules loaded: ${num_loaded_mods}")
+ if(NOT num_loaded_mods EQUAL 1)
+ message(FATAL_ERROR "Exactly 1 module should be loaded. Found ${num_loaded_mods}")
+ endif()
+
+ list(GET loaded_mods 0 mod0_actual)
+ if(NOT (mod0_actual MATCHES "^${mod0}"))
+ message(FATAL_ERROR "Loaded module does not match ${mod0}. Actual: ${mod0_actual}")
+ endif()
+endif()
diff --git a/Tests/FindGLEW/CMakeLists.txt b/Tests/FindGLEW/CMakeLists.txt
new file mode 100644
index 0000000..ff42bce
--- /dev/null
+++ b/Tests/FindGLEW/CMakeLists.txt
@@ -0,0 +1,10 @@
+add_test(NAME FindGLEW.Test COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindGLEW/Test"
+ "${CMake_BINARY_DIR}/Tests/FindGLEW/Test"
+ ${build_generator_args}
+ --build-project TestFindGLEW
+ --build-options ${build_options}
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+ )
diff --git a/Tests/FindGLEW/Test/CMakeLists.txt b/Tests/FindGLEW/Test/CMakeLists.txt
new file mode 100644
index 0000000..954ee10
--- /dev/null
+++ b/Tests/FindGLEW/Test/CMakeLists.txt
@@ -0,0 +1,18 @@
+cmake_minimum_required(VERSION 3.1)
+project(TestFindGLEW LANGUAGES CXX)
+include(CTest)
+
+find_package(GLEW REQUIRED)
+
+add_executable(test_glew_shared_tgt main.cpp)
+target_link_libraries(test_glew_shared_tgt GLEW::GLEW)
+add_test(NAME test_glew_shared_tgt COMMAND test_glew_shared_tgt)
+
+add_executable(test_glew_generic_tgt main.cpp)
+target_link_libraries(test_glew_generic_tgt GLEW::glew)
+add_test(NAME test_glew_generic_tgt COMMAND test_glew_generic_tgt)
+
+add_executable(test_glew_var main.cpp)
+target_include_directories(test_glew_var PRIVATE ${GLEW_INCLUDE_DIRS})
+target_link_libraries(test_glew_var PRIVATE ${GLEW_LIBRARIES})
+add_test(NAME test_glew_var COMMAND test_glew_var)
diff --git a/Tests/FindGLEW/Test/main.cpp b/Tests/FindGLEW/Test/main.cpp
new file mode 100644
index 0000000..4a108ad
--- /dev/null
+++ b/Tests/FindGLEW/Test/main.cpp
@@ -0,0 +1,8 @@
+#include <GL/glew.h>
+
+int main()
+{
+ GLenum init_return = glewInit();
+
+ return (init_return == GLEW_OK);
+}
diff --git a/Tests/FindPackageTest/CMakeLists.txt b/Tests/FindPackageTest/CMakeLists.txt
index f8b36c5..972580c 100644
--- a/Tests/FindPackageTest/CMakeLists.txt
+++ b/Tests/FindPackageTest/CMakeLists.txt
@@ -380,6 +380,7 @@ try_compile(EXPORTER_COMPILED
${FindPackageTest_SOURCE_DIR}/Exporter
CMakeTestExportPackage dummy
CMAKE_FLAGS "-UCMAKE_EXPORT_NO_PACKAGE_REGISTRY"
+ "-DCMAKE_POLICY_DEFAULT_CMP0090:STRING=OLD"
-Dversion=${version}
OUTPUT_VARIABLE output)
message(STATUS "Searching for export(PACKAGE) test project")
@@ -417,6 +418,25 @@ if(CMakeTestExportPackage_FOUND)
message(SEND_ERROR "CMakeTestExportPackage should not be FOUND!")
endif()
+message(STATUS "Remove export(PACKAGE) test project")
+file(REMOVE_RECURSE ${FindPackageTest_BINARY_DIR}/Exporter-build)
+
+message(STATUS "Preparing export(PACKAGE) test project with POLICY CMP0090=NEW")
+try_compile(EXPORTER_COMPILED
+ ${FindPackageTest_BINARY_DIR}/Exporter-build
+ ${FindPackageTest_SOURCE_DIR}/Exporter
+ CMakeTestExportPackage dummy
+ CMAKE_FLAGS
+ "-DCMAKE_POLICY_DEFAULT_CMP0090:STRING=NEW"
+ -Dversion=${version}
+ OUTPUT_VARIABLE output)
+message(STATUS "Searching for export(PACKAGE) test project")
+find_package(CMakeTestExportPackage 1.${version} EXACT QUIET)
+if(CMakeTestExportPackage_FOUND)
+ message(SEND_ERROR "CMakeTestExportPackage should not be FOUND!")
+endif()
+
+
#-----------------------------------------------------------------------------
# Test configure_package_config_file().
diff --git a/Tests/RunCMake/CommandLine/RunCMakeTest.cmake b/Tests/RunCMake/CommandLine/RunCMakeTest.cmake
index 5b5c5a5..3deabd0 100644
--- a/Tests/RunCMake/CommandLine/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CommandLine/RunCMakeTest.cmake
@@ -54,6 +54,14 @@ run_cmake_command(build-bad-dir
run_cmake_command(build-bad-generator
${CMAKE_COMMAND} --build ${RunCMake_SOURCE_DIR}/cache-bad-generator)
+run_cmake_command(install-no-dir
+ ${CMAKE_COMMAND} --install)
+run_cmake_command(install-bad-dir
+ ${CMAKE_COMMAND} --install dir-does-not-exist)
+run_cmake_command(install-options-to-vars
+ ${CMAKE_COMMAND} --install ${RunCMake_SOURCE_DIR}/dir-install-options-to-vars
+ --strip --prefix /var/test --config sample --component pack)
+
run_cmake_command(cache-bad-entry
${CMAKE_COMMAND} --build ${RunCMake_SOURCE_DIR}/cache-bad-entry/)
run_cmake_command(cache-empty-entry
diff --git a/Tests/RunCMake/CommandLine/dir-install-options-to-vars/cmake_install.cmake b/Tests/RunCMake/CommandLine/dir-install-options-to-vars/cmake_install.cmake
new file mode 100644
index 0000000..fd4e67d
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/dir-install-options-to-vars/cmake_install.cmake
@@ -0,0 +1,15 @@
+if(CMAKE_INSTALL_PREFIX)
+ message("CMAKE_INSTALL_PREFIX is ${CMAKE_INSTALL_PREFIX}")
+endif()
+
+if(CMAKE_INSTALL_COMPONENT)
+ message("CMAKE_INSTALL_COMPONENT is ${CMAKE_INSTALL_COMPONENT}")
+endif()
+
+if(CMAKE_INSTALL_CONFIG_NAME)
+ message("CMAKE_INSTALL_CONFIG_NAME is ${CMAKE_INSTALL_CONFIG_NAME}")
+endif()
+
+if(CMAKE_INSTALL_DO_STRIP)
+ message("CMAKE_INSTALL_DO_STRIP is ${CMAKE_INSTALL_DO_STRIP}")
+endif()
diff --git a/Tests/RunCMake/CommandLine/install-bad-dir-result.txt b/Tests/RunCMake/CommandLine/install-bad-dir-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/install-bad-dir-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CommandLine/install-bad-dir-stderr.txt b/Tests/RunCMake/CommandLine/install-bad-dir-stderr.txt
new file mode 100644
index 0000000..320aecc
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/install-bad-dir-stderr.txt
@@ -0,0 +1 @@
+^CMake Error: Error processing file:
diff --git a/Tests/RunCMake/CommandLine/install-no-dir-result.txt b/Tests/RunCMake/CommandLine/install-no-dir-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/install-no-dir-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CommandLine/install-no-dir-stderr.txt b/Tests/RunCMake/CommandLine/install-no-dir-stderr.txt
new file mode 100644
index 0000000..d64f638
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/install-no-dir-stderr.txt
@@ -0,0 +1 @@
+^Usage: cmake --install <dir> \[options\]
diff --git a/Tests/RunCMake/CommandLine/install-options-to-vars-result.txt b/Tests/RunCMake/CommandLine/install-options-to-vars-result.txt
new file mode 100644
index 0000000..573541a
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/install-options-to-vars-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/CommandLine/install-options-to-vars-stderr.txt b/Tests/RunCMake/CommandLine/install-options-to-vars-stderr.txt
new file mode 100644
index 0000000..f7b1583
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/install-options-to-vars-stderr.txt
@@ -0,0 +1,4 @@
+CMAKE_INSTALL_PREFIX is /var/test
+CMAKE_INSTALL_COMPONENT is pack
+CMAKE_INSTALL_CONFIG_NAME is sample
+CMAKE_INSTALL_DO_STRIP is 1
diff --git a/Tests/RunCMake/CommandLineTar/RunCMakeTest.cmake b/Tests/RunCMake/CommandLineTar/RunCMakeTest.cmake
index 12635db..5deb110 100644
--- a/Tests/RunCMake/CommandLineTar/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CommandLineTar/RunCMakeTest.cmake
@@ -4,19 +4,23 @@ function(external_command_test NAME)
run_cmake_command(${NAME} ${CMAKE_COMMAND} -E ${ARGN})
endfunction()
-external_command_test(bad-opt1 tar cvf bad.tar --bad)
-external_command_test(bad-mtime1 tar cvf bad.tar --mtime=bad .)
-external_command_test(bad-from1 tar cvf bad.tar --files-from=bad)
-external_command_test(bad-from2 tar cvf bad.tar --files-from=.)
-external_command_test(bad-from3 tar cvf bad.tar --files-from=${CMAKE_CURRENT_LIST_DIR}/bad-from3.txt)
-external_command_test(bad-from4 tar cvf bad.tar --files-from=${CMAKE_CURRENT_LIST_DIR}/bad-from4.txt)
-external_command_test(bad-from5 tar cvf bad.tar --files-from=${CMAKE_CURRENT_LIST_DIR}/bad-from5.txt)
-external_command_test(end-opt1 tar cvf bad.tar -- --bad)
-external_command_test(end-opt2 tar cvf bad.tar --)
-external_command_test(mtime tar cvf bad.tar "--mtime=1970-01-01 00:00:00 UTC")
-external_command_test(bad-format tar cvf bad.tar "--format=bad-format")
-external_command_test(zip-bz2 tar cvjf bad.tar "--format=zip")
-external_command_test(7zip-gz tar cvzf bad.tar "--format=7zip")
+external_command_test(without-files tar cvf bad.tar)
+external_command_test(bad-opt1 tar cvf bad.tar --bad)
+external_command_test(bad-mtime1 tar cvf bad.tar --mtime=bad .)
+external_command_test(bad-from1 tar cvf bad.tar --files-from=bad)
+external_command_test(bad-from2 tar cvf bad.tar --files-from=.)
+external_command_test(bad-from3 tar cvf bad.tar --files-from=${CMAKE_CURRENT_LIST_DIR}/bad-from3.txt)
+external_command_test(bad-from4 tar cvf bad.tar --files-from=${CMAKE_CURRENT_LIST_DIR}/bad-from4.txt)
+external_command_test(bad-from5 tar cvf bad.tar --files-from=${CMAKE_CURRENT_LIST_DIR}/bad-from5.txt)
+external_command_test(bad-file tar cf bad.tar badfile.txt ${CMAKE_CURRENT_LIST_DIR}/test-file.txt)
+external_command_test(bad-without-action tar f bad.tar ${CMAKE_CURRENT_LIST_DIR}/test-file.txt)
+external_command_test(bad-wrong-flag tar cvfq bad.tar ${CMAKE_CURRENT_LIST_DIR}/test-file.txt)
+external_command_test(end-opt1 tar cvf bad.tar -- --bad)
+external_command_test(end-opt2 tar cvf bad.tar --)
+external_command_test(mtime tar cvf bad.tar "--mtime=1970-01-01 00:00:00 UTC" ${CMAKE_CURRENT_LIST_DIR}/test-file.txt)
+external_command_test(bad-format tar cvf bad.tar "--format=bad-format" ${CMAKE_CURRENT_LIST_DIR}/test-file.txt)
+external_command_test(zip-bz2 tar cvjf bad.tar "--format=zip" ${CMAKE_CURRENT_LIST_DIR}/test-file.txt)
+external_command_test(7zip-gz tar cvzf bad.tar "--format=7zip" ${CMAKE_CURRENT_LIST_DIR}/test-file.txt)
run_cmake(7zip)
run_cmake(gnutar)
diff --git a/Tests/RunCMake/CommandLineTar/bad-file-result.txt b/Tests/RunCMake/CommandLineTar/bad-file-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/CommandLineTar/bad-file-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CommandLineTar/bad-file-stderr.txt b/Tests/RunCMake/CommandLineTar/bad-file-stderr.txt
new file mode 100644
index 0000000..1f9f748
--- /dev/null
+++ b/Tests/RunCMake/CommandLineTar/bad-file-stderr.txt
@@ -0,0 +1,2 @@
+^CMake Error: Unable to read from file 'badfile.txt': .*
+CMake Error: Problem creating tar: bad.tar$
diff --git a/Tests/RunCMake/CommandLineTar/bad-from4-stderr.txt b/Tests/RunCMake/CommandLineTar/bad-from4-stderr.txt
index 1417d4d..fb0702a 100644
--- a/Tests/RunCMake/CommandLineTar/bad-from4-stderr.txt
+++ b/Tests/RunCMake/CommandLineTar/bad-from4-stderr.txt
@@ -1,2 +1,2 @@
-^CMake Error: archive_read_disk_entry_from_file 'does-not-exist':.*
+^CMake Error: Unable to read from file 'does-not-exist':.*
CMake Error: Problem creating tar: bad.tar$
diff --git a/Tests/RunCMake/CommandLineTar/bad-from5-stderr.txt b/Tests/RunCMake/CommandLineTar/bad-from5-stderr.txt
index 1417d4d..fb0702a 100644
--- a/Tests/RunCMake/CommandLineTar/bad-from5-stderr.txt
+++ b/Tests/RunCMake/CommandLineTar/bad-from5-stderr.txt
@@ -1,2 +1,2 @@
-^CMake Error: archive_read_disk_entry_from_file 'does-not-exist':.*
+^CMake Error: Unable to read from file 'does-not-exist':.*
CMake Error: Problem creating tar: bad.tar$
diff --git a/Tests/RunCMake/CommandLineTar/bad-without-action-result.txt b/Tests/RunCMake/CommandLineTar/bad-without-action-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/CommandLineTar/bad-without-action-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CommandLineTar/bad-without-action-stderr.txt b/Tests/RunCMake/CommandLineTar/bad-without-action-stderr.txt
new file mode 100644
index 0000000..2fec254
--- /dev/null
+++ b/Tests/RunCMake/CommandLineTar/bad-without-action-stderr.txt
@@ -0,0 +1 @@
+^CMake Error: tar: No action specified. Please choose: 't' \(list\), 'c' \(create\) or 'x' \(extract\)$
diff --git a/Tests/RunCMake/CommandLineTar/bad-wrong-flag-stderr.txt b/Tests/RunCMake/CommandLineTar/bad-wrong-flag-stderr.txt
new file mode 100644
index 0000000..d5c1e01
--- /dev/null
+++ b/Tests/RunCMake/CommandLineTar/bad-wrong-flag-stderr.txt
@@ -0,0 +1 @@
+^tar: Unknown argument: q
diff --git a/Tests/RunCMake/CommandLineTar/end-opt1-stderr.txt b/Tests/RunCMake/CommandLineTar/end-opt1-stderr.txt
index 1fddf6d..1342dc8 100644
--- a/Tests/RunCMake/CommandLineTar/end-opt1-stderr.txt
+++ b/Tests/RunCMake/CommandLineTar/end-opt1-stderr.txt
@@ -1,2 +1,2 @@
-^CMake Error: archive_read_disk_entry_from_file '--bad':.*
+^CMake Error: Unable to read from file '--bad':.*
CMake Error: Problem creating tar: bad.tar$
diff --git a/Tests/RunCMake/CommandLineTar/end-opt2-stderr.txt b/Tests/RunCMake/CommandLineTar/end-opt2-stderr.txt
new file mode 100644
index 0000000..70166f5
--- /dev/null
+++ b/Tests/RunCMake/CommandLineTar/end-opt2-stderr.txt
@@ -0,0 +1 @@
+^tar: No files or directories specified
diff --git a/Tests/RunCMake/CommandLineTar/gnutar-gz.cmake b/Tests/RunCMake/CommandLineTar/gnutar-gz.cmake
index 5f2674a..53ee961 100644
--- a/Tests/RunCMake/CommandLineTar/gnutar-gz.cmake
+++ b/Tests/RunCMake/CommandLineTar/gnutar-gz.cmake
@@ -1,9 +1,9 @@
set(OUTPUT_NAME "test.tar.gz")
-set(COMPRESSION_FLAGS cvzf)
+set(COMPRESSION_FLAGS -cvzf)
set(COMPRESSION_OPTIONS --format=gnutar)
-set(DECOMPRESSION_FLAGS xvzf)
+set(DECOMPRESSION_FLAGS -xvzf)
include(${CMAKE_CURRENT_LIST_DIR}/roundtrip.cmake)
diff --git a/Tests/RunCMake/CommandLineTar/pax.cmake b/Tests/RunCMake/CommandLineTar/pax.cmake
index 60ed238..77f74d1 100644
--- a/Tests/RunCMake/CommandLineTar/pax.cmake
+++ b/Tests/RunCMake/CommandLineTar/pax.cmake
@@ -1,9 +1,9 @@
set(OUTPUT_NAME "test.tar")
-set(COMPRESSION_FLAGS cvf)
+set(COMPRESSION_FLAGS -cvf)
set(COMPRESSION_OPTIONS --format=pax)
-set(DECOMPRESSION_FLAGS xvf)
+set(DECOMPRESSION_FLAGS -xvf)
include(${CMAKE_CURRENT_LIST_DIR}/roundtrip.cmake)
diff --git a/Tests/RunCMake/CommandLineTar/test-file.txt b/Tests/RunCMake/CommandLineTar/test-file.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/RunCMake/CommandLineTar/test-file.txt
diff --git a/Tests/RunCMake/CommandLineTar/without-files-stderr.txt b/Tests/RunCMake/CommandLineTar/without-files-stderr.txt
new file mode 100644
index 0000000..70166f5
--- /dev/null
+++ b/Tests/RunCMake/CommandLineTar/without-files-stderr.txt
@@ -0,0 +1 @@
+^tar: No files or directories specified
diff --git a/Tests/RunCMake/FindPkgConfig/FindPkgConfig_IMPORTED_TARGET.cmake b/Tests/RunCMake/FindPkgConfig/FindPkgConfig_IMPORTED_TARGET.cmake
index 24e7202..e82b05f 100644
--- a/Tests/RunCMake/FindPkgConfig/FindPkgConfig_IMPORTED_TARGET.cmake
+++ b/Tests/RunCMake/FindPkgConfig/FindPkgConfig_IMPORTED_TARGET.cmake
@@ -109,3 +109,24 @@ pkg_check_modules(FakePackage2 REQUIRED QUIET IMPORTED_TARGET cmakeinternalfakep
if (NOT FakePackage2_LINK_LIBRARIES STREQUAL "${fakePkgDir}/lib/libcmakeinternalfakepackage2.a")
message(FATAL_ERROR "FakePackage2_LINK_LIBRARIES has bad content on second run: ${FakePackage2_LINK_LIBRARIES}")
endif()
+
+set(pname fakelinkoptionspackage)
+file(WRITE ${fakePkgDir}/lib/pkgconfig/${pname}.pc
+"Name: FakeLinkOptionsPackage
+Description: Dummy package for FindPkgConfig IMPORTED_TARGET INTERFACE_LINK_OPTIONS test
+Version: 1.2.3
+Libs: -e dummy_main
+")
+
+set(expected_link_options -e dummy_main)
+pkg_check_modules(FakeLinkOptionsPackage REQUIRED QUIET IMPORTED_TARGET fakelinkoptionspackage)
+if (NOT TARGET PkgConfig::FakeLinkOptionsPackage)
+ message(FATAL_ERROR "No import target for fake link options package")
+endif()
+get_target_property(link_options PkgConfig::FakeLinkOptionsPackage INTERFACE_LINK_OPTIONS)
+if (NOT link_options STREQUAL expected_link_options)
+ message(FATAL_ERROR
+ "Additional link options not present in INTERFACE_LINK_OPTIONS property"
+ "expected: \"${expected_link_options}\", but got \"${link_options}\""
+ )
+endif()
diff --git a/Tests/RunCMake/XcodeProject/XcodeSchemaProperty-check.cmake b/Tests/RunCMake/XcodeProject/XcodeSchemaProperty-check.cmake
index f675d81..88077b3 100644
--- a/Tests/RunCMake/XcodeProject/XcodeSchemaProperty-check.cmake
+++ b/Tests/RunCMake/XcodeProject/XcodeSchemaProperty-check.cmake
@@ -7,6 +7,13 @@ function(check_property property matcher)
endif()
endfunction()
+function(expect_no_schema target)
+ set(schema "${RunCMake_TEST_BINARY_DIR}/XcodeSchemaProperty.xcodeproj/xcshareddata/xcschemes/${target}.xcscheme")
+ if(EXISTS ${schema})
+ message(SEND_ERROR "Found unexpected schema ${schema}")
+ endif()
+endfunction()
+
check_property("ADDRESS_SANITIZER" "enableAddressSanitizer")
check_property("ADDRESS_SANITIZER_USE_AFTER_RETURN" "enableASanStackUseAfterReturn")
check_property("THREAD_SANITIZER" "enableThreadSanitizer")
@@ -31,3 +38,5 @@ check_property("ENVIRONMENT" [=[key="FOO"]=])
check_property("ENVIRONMENT" [=[value="foo"]=])
check_property("ENVIRONMENT" [=[key="BAR"]=])
check_property("ENVIRONMENT" [=[value="bar"]=])
+
+expect_no_schema("NoSchema")
diff --git a/Tests/RunCMake/XcodeProject/XcodeSchemaProperty.cmake b/Tests/RunCMake/XcodeProject/XcodeSchemaProperty.cmake
index 2b72a64..73ef5ca 100644
--- a/Tests/RunCMake/XcodeProject/XcodeSchemaProperty.cmake
+++ b/Tests/RunCMake/XcodeProject/XcodeSchemaProperty.cmake
@@ -35,3 +35,6 @@ endfunction()
create_scheme_for_property(EXECUTABLE myExecutable)
create_scheme_for_property(ARGUMENTS "--foo;--bar=baz")
create_scheme_for_property(ENVIRONMENT "FOO=foo;BAR=bar")
+
+add_executable(NoSchema main.cpp)
+set_target_properties(NoSchema PROPERTIES XCODE_GENERATE_SCHEME OFF)
diff --git a/Utilities/Scripts/update-third-party.bash b/Utilities/Scripts/update-third-party.bash
index 670946e..fcab871 100644
--- a/Utilities/Scripts/update-third-party.bash
+++ b/Utilities/Scripts/update-third-party.bash
@@ -71,8 +71,6 @@ warn () {
readonly regex_date='20[0-9][0-9]-[0-9][0-9]-[0-9][0-9]'
readonly basehash_regex="$name $regex_date ([0-9a-f]*)"
-readonly basehash="$( git rev-list --author="$ownership" --grep="$basehash_regex" -n 1 HEAD )"
-readonly upstream_old_short="$( git cat-file commit "$basehash" | sed -n '/'"$basehash_regex"'/ {s/.*(//;s/)//;p}' | egrep '^[0-9a-f]+$' )"
########################################################################
# Sanity checking
@@ -87,6 +85,18 @@ readonly upstream_old_short="$( git cat-file commit "$basehash" | sed -n '/'"$ba
die "'repo' is empty"
[ -n "$tag" ] || \
die "'tag' is empty"
+
+# Check for an empty destination directory on disk. By checking on disk and
+# not in the repo it allows a library to be freshly re-inialized in a single
+# commit rather than first deleting the old copy in one commit and adding the
+# new copy in a seperate commit.
+if [ ! -d "$(git rev-parse --show-toplevel)/$subtree" ]; then
+ readonly basehash=""
+else
+ readonly basehash="$( git rev-list --author="$ownership" --grep="$basehash_regex" -n 1 HEAD )"
+fi
+readonly upstream_old_short="$( git cat-file commit "$basehash" | sed -n '/'"$basehash_regex"'/ {s/.*(//;s/)//;p}' | egrep '^[0-9a-f]+$' )"
+
[ -n "$basehash" ] || \
warn "'basehash' is empty; performing initial import"
readonly do_shortlog="${shortlog-false}"
@@ -104,6 +114,8 @@ trap "rm -rf '$workdir'" EXIT
git clone "$repo" "$upstreamdir"
if [ -n "$basehash" ]; then
+ # Remove old worktrees
+ git worktree prune
# Use the existing package's history
git worktree add "$extractdir" "$basehash"
# Clear out the working tree
@@ -163,13 +175,17 @@ popd
if [ -n "$basehash" ]; then
git merge --log -s recursive "-Xsubtree=$subtree/" --no-commit "upstream-$name"
else
+ # Note: on Windows 'git merge --help' will open a browser, and the check
+ # will fail, so use the flag by default.
unrelated_histories_flag=""
- if git merge --help | grep -q -e allow-unrelated-histories; then
+ if git --version | grep -q windows; then
+ unrelated_histories_flag="--allow-unrelated-histories "
+ elif git merge --help | grep -q -e allow-unrelated-histories; then
unrelated_histories_flag="--allow-unrelated-histories "
fi
readonly unrelated_histories_flag
- git fetch "$extractdir" "upstream-$name:upstream-$name"
+ git fetch "$extractdir" "+upstream-$name:upstream-$name"
git merge --log -s ours --no-commit $unrelated_histories_flag "upstream-$name"
git read-tree -u --prefix="$subtree/" "upstream-$name"
fi
diff --git a/Utilities/cmzstd/CMakeLists.txt b/Utilities/cmzstd/CMakeLists.txt
index b1399bd..8ed04d8 100644
--- a/Utilities/cmzstd/CMakeLists.txt
+++ b/Utilities/cmzstd/CMakeLists.txt
@@ -41,4 +41,7 @@ add_library(cmzstd STATIC
lib/dictBuilder/zdict.c
)
+# BMI2 instructions are not supported in older environments.
+set_property(TARGET cmzstd PROPERTY COMPILE_DEFINITIONS DYNAMIC_BMI2=0)
+
install(FILES LICENSE DESTINATION ${CMAKE_DOC_DIR}/cmzstd)
diff --git a/bootstrap b/bootstrap
index af05024..537b43b 100755
--- a/bootstrap
+++ b/bootstrap
@@ -304,7 +304,8 @@ CMAKE_CXX_SOURCES="\
cmFileCommand \
cmFileCopier \
cmFileInstaller \
- cmFileTimeComparison \
+ cmFileTime \
+ cmFileTimeCache \
cmFindBase \
cmFindCommon \
cmFindFileCommand \