summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Auxiliary/vim/syntax/cmake.vim1
-rw-r--r--Help/command/add_compile_options.rst39
-rw-r--r--Help/command/install.rst5
-rw-r--r--Help/command/target_compile_options.rst30
-rw-r--r--Help/command/try_compile.rst5
-rw-r--r--Help/manual/cmake-modules.7.rst1
-rw-r--r--Help/manual/cmake-policies.7.rst1
-rw-r--r--Help/manual/cmake-properties.7.rst3
-rw-r--r--Help/manual/ctest.1.rst71
-rw-r--r--Help/module/CheckPIESupported.rst1
-rw-r--r--Help/policy/CMP0083.rst38
-rw-r--r--Help/policy/CMP0087.rst29
-rw-r--r--Help/prop_tgt/AUTOMOC.rst3
-rw-r--r--Help/prop_tgt/AUTOMOC_EXECUTABLE.rst15
-rw-r--r--Help/prop_tgt/AUTORCC.rst3
-rw-r--r--Help/prop_tgt/AUTORCC_EXECUTABLE.rst15
-rw-r--r--Help/prop_tgt/AUTOUIC.rst3
-rw-r--r--Help/prop_tgt/AUTOUIC_EXECUTABLE.rst15
-rw-r--r--Help/prop_tgt/POSITION_INDEPENDENT_CODE.rst5
-rw-r--r--Help/release/dev/UseSWIG-source-file-ext.rst5
-rw-r--r--Help/release/dev/autogen_executables.rst9
-rw-r--r--Help/release/dev/ctest-show-only-json-v1.rst6
-rw-r--r--Help/release/dev/install-code-script-genex.rst5
-rw-r--r--Help/release/dev/link-option-PIE.rst7
-rw-r--r--Modules/BundleUtilities.cmake11
-rw-r--r--Modules/CheckIPOSupported.cmake2
-rw-r--r--Modules/CheckPIESupported.cmake134
-rw-r--r--Modules/Compiler/AppleClang-C.cmake3
-rw-r--r--Modules/Compiler/AppleClang-CXX.cmake3
-rw-r--r--Modules/Compiler/Clang.cmake20
-rw-r--r--Modules/Compiler/GNU.cmake19
-rw-r--r--Modules/Compiler/SunPro-C.cmake1
-rw-r--r--Modules/Compiler/SunPro-CXX.cmake1
-rw-r--r--Modules/Compiler/SunPro-Fortran.cmake1
-rw-r--r--Modules/ExternalProject.cmake51
-rw-r--r--Modules/FeatureSummary.cmake2
-rw-r--r--Modules/FindLibLZMA.cmake40
-rw-r--r--Modules/FindProtobuf.cmake2
-rw-r--r--Modules/FindThreads.cmake5
-rw-r--r--Modules/GetPrerequisites.cmake38
-rw-r--r--Modules/GoogleTestAddTests.cmake1
-rw-r--r--Modules/Internal/CMakeCheckCompilerFlag.cmake26
-rw-r--r--Modules/Platform/CYGWIN-GNU.cmake1
-rw-r--r--Modules/Platform/Fuchsia.cmake1
-rw-r--r--Modules/Platform/Linux-Intel.cmake2
-rw-r--r--Modules/Platform/Linux-PGI.cmake1
-rw-r--r--Modules/Platform/SINIX.cmake1
-rw-r--r--Modules/Platform/UNIX_SV.cmake1
-rw-r--r--Modules/Platform/UnixWare.cmake1
-rw-r--r--Modules/Platform/Windows-GNU.cmake1
-rw-r--r--Modules/UseSWIG.cmake26
-rw-r--r--Source/CMakeVersion.cmake2
-rw-r--r--Source/CPack/WiX/cmCPackWIXGenerator.h12
-rw-r--r--Source/CTest/cmCTestMultiProcessHandler.cxx331
-rw-r--r--Source/CTest/cmCTestMultiProcessHandler.h1
-rw-r--r--Source/CTest/cmCTestRunTest.h4
-rw-r--r--Source/CTest/cmCTestTestHandler.cxx26
-rw-r--r--Source/CTest/cmCTestTestHandler.h3
-rw-r--r--Source/cmAlgorithms.h6
-rw-r--r--Source/cmCPluginAPI.cxx2
-rw-r--r--Source/cmCTest.cxx26
-rw-r--r--Source/cmCTest.h6
-rw-r--r--Source/cmCommandArgumentParserHelper.cxx25
-rw-r--r--Source/cmCommandArgumentParserHelper.h2
-rw-r--r--Source/cmCoreTryCompile.cxx18
-rw-r--r--Source/cmExtraCodeLiteGenerator.cxx15
-rw-r--r--Source/cmFileCommand.cxx2
-rw-r--r--Source/cmGeneratorExpression.cxx13
-rw-r--r--Source/cmGhsMultiTargetGenerator.cxx23
-rw-r--r--Source/cmGhsMultiTargetGenerator.h2
-rw-r--r--Source/cmGlobalGenerator.cxx18
-rw-r--r--Source/cmGlobalGhsMultiGenerator.h29
-rw-r--r--Source/cmGlobalVisualStudio10Generator.cxx31
-rw-r--r--Source/cmGlobalVisualStudio10Generator.h7
-rw-r--r--Source/cmGlobalVisualStudio11Generator.cxx12
-rw-r--r--Source/cmGlobalVisualStudio11Generator.h5
-rw-r--r--Source/cmGlobalVisualStudio12Generator.cxx10
-rw-r--r--Source/cmGlobalVisualStudio12Generator.h8
-rw-r--r--Source/cmGlobalVisualStudio14Generator.cxx11
-rw-r--r--Source/cmGlobalVisualStudio14Generator.h5
-rw-r--r--Source/cmGlobalVisualStudio15Generator.cxx19
-rw-r--r--Source/cmGlobalVisualStudio15Generator.h6
-rw-r--r--Source/cmGlobalVisualStudio71Generator.cxx6
-rw-r--r--Source/cmGlobalVisualStudio71Generator.h3
-rw-r--r--Source/cmGlobalVisualStudio7Generator.h2
-rw-r--r--Source/cmGlobalVisualStudio8Generator.cxx2
-rw-r--r--Source/cmGlobalVisualStudio8Generator.h7
-rw-r--r--Source/cmGlobalVisualStudio9Generator.cxx6
-rw-r--r--Source/cmGlobalVisualStudio9Generator.h9
-rw-r--r--Source/cmGlobalVisualStudioGenerator.cxx71
-rw-r--r--Source/cmGlobalVisualStudioGenerator.h12
-rw-r--r--Source/cmInstallScriptGenerator.cxx70
-rw-r--r--Source/cmInstallScriptGenerator.h14
-rw-r--r--Source/cmLinkedTree.h3
-rw-r--r--Source/cmLocalGenerator.cxx10
-rw-r--r--Source/cmMakefile.cxx71
-rw-r--r--Source/cmMakefile.h5
-rw-r--r--Source/cmMakefileTargetGenerator.cxx11
-rw-r--r--Source/cmMessenger.cxx34
-rw-r--r--Source/cmMessenger.h40
-rw-r--r--Source/cmPolicies.h6
-rw-r--r--Source/cmQtAutoGenGlobalInitializer.cxx21
-rw-r--r--Source/cmQtAutoGenInitializer.cxx78
-rw-r--r--Source/cmTestGenerator.cxx59
-rw-r--r--Source/cmTestGenerator.h3
-rw-r--r--Source/cmVSSetupHelper.cxx9
-rw-r--r--Source/cmVisualStudioGeneratorOptions.cxx2
-rw-r--r--Source/cmWriteFileCommand.cxx2
-rw-r--r--Source/cmake.cxx32
-rwxr-xr-xSource/cmparseMSBuildXML.py341
-rw-r--r--Source/ctest.cxx5
-rw-r--r--Tests/CMakeOnly/CMakeLists.txt2
-rw-r--r--Tests/RunCMake/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/CTestCommandLine/RunCMakeTest.cmake29
-rw-r--r--Tests/RunCMake/CTestCommandLine/ShowAsJson1-check.py106
-rw-r--r--Tests/RunCMake/CTestCommandLine/ShowAsJson_check.py24
-rw-r--r--Tests/RunCMake/CommandLine/RunCMakeTest.cmake2
-rw-r--r--Tests/RunCMake/CommandLine/warn-uninitialized-stderr.txt52
-rw-r--r--Tests/RunCMake/CommandLine/warn-uninitialized.cmake19
-rw-r--r--Tests/RunCMake/ExternalProject/LogOutputOnFailure-build-result.txt1
-rw-r--r--Tests/RunCMake/ExternalProject/LogOutputOnFailure-build-stderr.txt1
-rw-r--r--Tests/RunCMake/ExternalProject/LogOutputOnFailure-build-stdout.txt8
-rw-r--r--Tests/RunCMake/ExternalProject/LogOutputOnFailure.cmake20
-rw-r--r--Tests/RunCMake/ExternalProject/LogOutputOnFailureMerged-build-result.txt1
-rw-r--r--Tests/RunCMake/ExternalProject/LogOutputOnFailureMerged-build-stderr.txt1
-rw-r--r--Tests/RunCMake/ExternalProject/LogOutputOnFailureMerged-build-stdout.txt7
-rw-r--r--Tests/RunCMake/ExternalProject/LogOutputOnFailureMerged.cmake21
-rw-r--r--Tests/RunCMake/ExternalProject/RunCMakeTest.cmake7
-rw-r--r--Tests/RunCMake/GetPrerequisites/ExecutableScripts-stdout.txt3
-rw-r--r--Tests/RunCMake/GetPrerequisites/ExecutableScripts.cmake19
-rw-r--r--Tests/RunCMake/GetPrerequisites/RunCMakeTest.cmake1
-rwxr-xr-xTests/RunCMake/GetPrerequisites/script3
-rwxr-xr-xTests/RunCMake/GetPrerequisites/script.bat3
-rwxr-xr-xTests/RunCMake/GetPrerequisites/script.sh3
-rw-r--r--Tests/RunCMake/PositionIndependentCode/CMP0083.cmake2
-rw-r--r--Tests/RunCMake/PositionIndependentCode/CheckPIESupported.cmake10
-rw-r--r--Tests/RunCMake/PositionIndependentCode/PIE.cmake3
-rw-r--r--Tests/RunCMake/README.rst11
-rw-r--r--Tests/RunCMake/RunCMake.cmake4
-rw-r--r--Tests/RunCMake/install/CMP0087-NEW-check.cmake7
-rw-r--r--Tests/RunCMake/install/CMP0087-NEW.cmake3
-rw-r--r--Tests/RunCMake/install/CMP0087-NEW/CMakeLists.txt7
-rw-r--r--Tests/RunCMake/install/CMP0087-OLD-check.cmake8
-rw-r--r--Tests/RunCMake/install/CMP0087-OLD.cmake3
-rw-r--r--Tests/RunCMake/install/CMP0087-OLD/CMakeLists.txt6
-rw-r--r--Tests/RunCMake/install/CMP0087-WARN-stderr.txt5
-rw-r--r--Tests/RunCMake/install/CMP0087-WARN.cmake2
-rw-r--r--Tests/RunCMake/install/RunCMakeTest.cmake3
-rw-r--r--Tests/RunCMake/install/TARGETS-Defaults-Cache-all-check.cmake2
-rw-r--r--Tests/RunCMake/install/TARGETS-Defaults-all-check.cmake2
-rw-r--r--Tests/UseSWIG/CMakeLists.txt12
-rw-r--r--Tests/UseSWIG/SwigSrcFileExtension/CMakeLists.txt28
-rw-r--r--Tests/UseSWIG/SwigSrcFileExtension/my_add.i9
-rw-r--r--Tests/UseSWIG/SwigSrcFileExtension/my_sub.swg9
-rwxr-xr-xTests/UseSWIG/SwigSrcFileExtension/runme.py24
-rw-r--r--Utilities/Sphinx/colors.py10
156 files changed, 2030 insertions, 800 deletions
diff --git a/Auxiliary/vim/syntax/cmake.vim b/Auxiliary/vim/syntax/cmake.vim
index d4d0edf..b67ef06 100644
--- a/Auxiliary/vim/syntax/cmake.vim
+++ b/Auxiliary/vim/syntax/cmake.vim
@@ -877,6 +877,7 @@ syn keyword cmakeKWExternalProject contained
\ LOG_DOWNLOAD
\ LOG_INSTALL
\ LOG_MERGED_STDOUTERR
+ \ LOG_OUTPUT_ON_FAILURE
\ LOG_PATCH
\ LOG_TEST
\ LOG_UPDATE
diff --git a/Help/command/add_compile_options.rst b/Help/command/add_compile_options.rst
index fcdcfd4..43805c3 100644
--- a/Help/command/add_compile_options.rst
+++ b/Help/command/add_compile_options.rst
@@ -7,15 +7,12 @@ Add options to the compilation of source files.
add_compile_options(<option> ...)
-Adds options to the compiler command line for targets in the current
-directory and below that are added after this command is invoked.
-See documentation of the :prop_dir:`directory <COMPILE_OPTIONS>` and
-:prop_tgt:`target <COMPILE_OPTIONS>` ``COMPILE_OPTIONS`` properties.
+Adds options to the :prop_dir:`COMPILE_OPTIONS` directory property.
+These options are used when compiling targets from the current
+directory and below.
-This command can be used to add any options, but alternative commands
-exist to add preprocessor definitions (:command:`target_compile_definitions`
-and :command:`add_compile_definitions`) or include directories
-(:command:`target_include_directories` and :command:`include_directories`).
+Arguments
+^^^^^^^^^
Arguments to ``add_compile_options`` may use "generator expressions" with
the syntax ``$<...>``. See the :manual:`cmake-generator-expressions(7)`
@@ -23,3 +20,29 @@ manual for available expressions. See the :manual:`cmake-buildsystem(7)`
manual for more on defining buildsystem properties.
.. include:: OPTIONS_SHELL.txt
+
+Example
+^^^^^^^
+
+Since different compilers support different options, a typical use of
+this command is in a compiler-specific conditional clause:
+
+.. code-block:: cmake
+
+ if (MSVC)
+ # warning level 4 and all warnings as errors
+ add_compile_options(/W4 /WX)
+ else()
+ # lots of warnings and all warnings as errors
+ add_compile_options(-Wall -Wextra -pedantic -Werror)
+ endif()
+
+See Also
+^^^^^^^^
+
+This command can be used to add any options. However, for
+adding preprocessor definitions and include directories it is recommended
+to use the more specific commands :command:`add_compile_definitions`
+and :command:`include_directories`.
+
+The command :command:`target_compile_options` adds target-specific options.
diff --git a/Help/command/install.rst b/Help/command/install.rst
index 55c8485..a0e8c37 100644
--- a/Help/command/install.rst
+++ b/Help/command/install.rst
@@ -547,6 +547,11 @@ example, the code
will print a message during installation.
+``<file>`` or ``<code>`` may use "generator expressions" with the syntax
+``$<...>`` (in the case of ``<file>``, this refers to their use in the file
+name, not the file's contents). See the
+:manual:`cmake-generator-expressions(7)` manual for available expressions.
+
Installing Exports
^^^^^^^^^^^^^^^^^^
diff --git a/Help/command/target_compile_options.rst b/Help/command/target_compile_options.rst
index c26c926..47e7d86 100644
--- a/Help/command/target_compile_options.rst
+++ b/Help/command/target_compile_options.rst
@@ -9,22 +9,18 @@ Add compile options to a target.
<INTERFACE|PUBLIC|PRIVATE> [items1...]
[<INTERFACE|PUBLIC|PRIVATE> [items2...] ...])
-Specifies compile options to use when compiling a given target. The
-named ``<target>`` must have been created by a command such as
-:command:`add_executable` or :command:`add_library` and must not be an
-:ref:`ALIAS target <Alias Targets>`.
+Adds options to the :prop_tgt:`COMPILE_OPTIONS` or
+:prop_tgt:`INTERFACE_COMPILE_OPTIONS` target properties. These options
+are used when compiling the given ``<target>``, which must have been
+created by a command such as :command:`add_executable` or
+:command:`add_library` and must not be an :ref:`ALIAS target <Alias Targets>`.
+
+Arguments
+^^^^^^^^^
If ``BEFORE`` is specified, the content will be prepended to the property
instead of being appended.
-This command can be used to add any options, but
-alternative commands exist to add preprocessor definitions
-(:command:`target_compile_definitions` and :command:`add_compile_definitions`)
-or include directories (:command:`target_include_directories` and
-:command:`include_directories`). See documentation of the
-:prop_dir:`directory <COMPILE_OPTIONS>` and
-:prop_tgt:`target <COMPILE_OPTIONS>` ``COMPILE_OPTIONS`` properties.
-
The ``INTERFACE``, ``PUBLIC`` and ``PRIVATE`` keywords are required to
specify the scope of the following arguments. ``PRIVATE`` and ``PUBLIC``
items will populate the :prop_tgt:`COMPILE_OPTIONS` property of
@@ -40,3 +36,13 @@ manual for available expressions. See the :manual:`cmake-buildsystem(7)`
manual for more on defining buildsystem properties.
.. include:: OPTIONS_SHELL.txt
+
+See Also
+^^^^^^^^
+
+This command can be used to add any options. However, for adding
+preprocessor definitions and include directories it is recommended
+to use the more specific commands :command:`target_compile_definitions`
+and :command:`target_include_directories`.
+
+For directory-wide settings, there is the command :command:`add_compile_options`.
diff --git a/Help/command/try_compile.rst b/Help/command/try_compile.rst
index f50fcb6..cf9e06f 100644
--- a/Help/command/try_compile.rst
+++ b/Help/command/try_compile.rst
@@ -134,6 +134,11 @@ default values:
If :policy:`CMP0056` is set to ``NEW``, then
:variable:`CMAKE_EXE_LINKER_FLAGS` is passed in as well.
+If :policy:`CMP0083` is set to ``NEW``, then in order to obtain correct
+behavior at link time, the ``check_pie_supported()`` command from the
+:module:`CheckPIESupported` module must be called before using the
+:command:`try_compile` command.
+
The current settings of :policy:`CMP0065` and :policy:`CMP0083` are set in the
generated project.
diff --git a/Help/manual/cmake-modules.7.rst b/Help/manual/cmake-modules.7.rst
index 2f08a04..940186a 100644
--- a/Help/manual/cmake-modules.7.rst
+++ b/Help/manual/cmake-modules.7.rst
@@ -35,6 +35,7 @@ These modules are loaded using the :command:`include` command.
/module/CheckIncludeFiles
/module/CheckLanguage
/module/CheckLibraryExists
+ /module/CheckPIESupported
/module/CheckPrototypeDefinition
/module/CheckStructHasMember
/module/CheckSymbolExists
diff --git a/Help/manual/cmake-policies.7.rst b/Help/manual/cmake-policies.7.rst
index ed61ae0..40ec1ef 100644
--- a/Help/manual/cmake-policies.7.rst
+++ b/Help/manual/cmake-policies.7.rst
@@ -57,6 +57,7 @@ Policies Introduced by CMake 3.14
.. toctree::
:maxdepth: 1
+ CMP0087: install(SCRIPT | CODE) supports generator expressions. </policy/CMP0087>
CMP0086: UseSWIG honors SWIG_MODULE_NAME via -module flag. </policy/CMP0086>
CMP0085: IN_LIST generator expression handles empty list items. </policy/CMP0085>
CMP0084: The FindQt module does not exist for find_package(). </policy/CMP0084>
diff --git a/Help/manual/cmake-properties.7.rst b/Help/manual/cmake-properties.7.rst
index 047859d..df8f12c 100644
--- a/Help/manual/cmake-properties.7.rst
+++ b/Help/manual/cmake-properties.7.rst
@@ -129,13 +129,16 @@ Properties on Targets
/prop_tgt/AUTOGEN_TARGET_DEPENDS
/prop_tgt/AUTOMOC_COMPILER_PREDEFINES
/prop_tgt/AUTOMOC_DEPEND_FILTERS
+ /prop_tgt/AUTOMOC_EXECUTABLE
/prop_tgt/AUTOMOC_MACRO_NAMES
/prop_tgt/AUTOMOC_MOC_OPTIONS
/prop_tgt/AUTOMOC
/prop_tgt/AUTOUIC
+ /prop_tgt/AUTOUIC_EXECUTABLE
/prop_tgt/AUTOUIC_OPTIONS
/prop_tgt/AUTOUIC_SEARCH_PATHS
/prop_tgt/AUTORCC
+ /prop_tgt/AUTORCC_EXECUTABLE
/prop_tgt/AUTORCC_OPTIONS
/prop_tgt/BINARY_DIR
/prop_tgt/BUILD_RPATH
diff --git a/Help/manual/ctest.1.rst b/Help/manual/ctest.1.rst
index 1ef20ab..8490e3d 100644
--- a/Help/manual/ctest.1.rst
+++ b/Help/manual/ctest.1.rst
@@ -109,13 +109,23 @@ Options
This option tells CTest to write all its output to a log file.
-``-N,--show-only``
+``-N,--show-only[=<format>]``
Disable actual execution of tests.
This option tells CTest to list the tests that would be run but not
actually run them. Useful in conjunction with the ``-R`` and ``-E``
options.
+ ``<format>`` can be one of the following values.
+
+ ``human``
+ Human-friendly output. This is not guaranteed to be stable.
+ This is the default.
+
+ ``json-v1``
+ Dump the test information in JSON format.
+ See `Show as JSON Object Model`_.
+
``-L <regex>, --label-regex <regex>``
Run tests with labels matching regular expression.
@@ -1163,6 +1173,65 @@ Configuration settings include:
* :module:`CTest` module variable: ``TRIGGER_SITE`` if set,
else ``CTEST_TRIGGER_SITE``
+.. _`Show as JSON Object Model`:
+
+Show as JSON Object Model
+=========================
+
+When the ``--show-only=json-v1`` command line option is given, the test
+information is output in JSON format. Version 1.0 of the JSON object
+model is defined as follows:
+
+``kind``
+ The string "ctestInfo".
+
+``version``
+ A JSON object specifying the version components. Its members are
+
+ ``major``
+ A non-negative integer specifying the major version component.
+ ``minor``
+ A non-negative integer specifying the minor version component.
+
+``backtraceGraph``
+ JSON object representing backtrace information with the
+ following members:
+
+ ``commands``
+ List of command names.
+ ``files``
+ List of file names.
+ ``nodes``
+ List of node JSON objects with members:
+
+ ``command``
+ Index into the ``commands`` member of the ``backtraceGraph``.
+ ``file``
+ Index into the ``files`` member of the ``backtraceGraph``.
+ ``line``
+ Line number in the file where the backtrace was added.
+ ``parent``
+ Index into the ``nodes`` member of the ``backtraceGraph``
+ representing the parent in the graph.
+
+``tests``
+ A JSON array listing information about each test. Each entry
+ is a JSON object with members:
+
+ ``name``
+ Test name.
+ ``config``
+ Configuration that the test can run on.
+ Empty string means any config.
+ ``command``
+ List where the first element is the test command and the
+ remaining elements are the command arguments.
+ ``backtrace``
+ Index into the ``nodes`` member of the ``backtraceGraph``.
+ ``properties``
+ Test properties.
+ Can contain keys for each of the supported test properties.
+
See Also
========
diff --git a/Help/module/CheckPIESupported.rst b/Help/module/CheckPIESupported.rst
new file mode 100644
index 0000000..02e7b43
--- /dev/null
+++ b/Help/module/CheckPIESupported.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/CheckPIESupported.cmake
diff --git a/Help/policy/CMP0083.rst b/Help/policy/CMP0083.rst
index 7b467b0..b26d6c8 100644
--- a/Help/policy/CMP0083.rst
+++ b/Help/policy/CMP0083.rst
@@ -17,8 +17,46 @@ is set:
passed to the linker step. For example ``-no-pie`` for ``GCC``.
* Not set: no flags are passed to the linker step.
+Since a given linker may not support ``PIE`` flags in all environments in
+which it is used, it is the project's responsibility to use the
+:module:`CheckPIESupported` module to check for support to ensure that the
+:prop_tgt:`POSITION_INDEPENDENT_CODE` target property for executables will be
+honored at link time.
+
This policy was introduced in CMake version 3.14. CMake version
|release| warns when the policy is not set and uses ``OLD`` behavior. Use
the :command:`cmake_policy` command to set it to ``OLD`` or ``NEW`` explicitly.
.. include:: DEPRECATED.txt
+
+Examples
+^^^^^^^^
+
+Behave like CMake 3.13 and do not apply any ``PIE`` flags at link stage.
+
+.. code-block:: cmake
+
+ cmake_minimum_required(VERSION 3.13)
+ project(foo)
+
+ # ...
+
+ add_executable(foo ...)
+ set_property(TARGET foo PROPERTY POSITION_INDEPENDENT_CODE TRUE)
+
+Use the :module:`CheckPIESupported` module to detect whether ``PIE`` is
+supported by the current linker and environment. Apply ``PIE`` flags only
+if the linker supports them.
+
+.. code-block:: cmake
+
+ cmake_minimum_required(VERSION 3.14) # CMP0083 NEW
+ project(foo)
+
+ include(CheckPIESupported)
+ check_pie_supported()
+
+ # ...
+
+ add_executable(foo ...)
+ set_property(TARGET foo PROPERTY POSITION_INDEPENDENT_CODE TRUE)
diff --git a/Help/policy/CMP0087.rst b/Help/policy/CMP0087.rst
new file mode 100644
index 0000000..4c45b99
--- /dev/null
+++ b/Help/policy/CMP0087.rst
@@ -0,0 +1,29 @@
+CMP0087
+-------
+
+:command:`install(CODE)` and :command:`install(SCRIPT)` support generator
+expressions.
+
+In CMake 3.13 and earlier, :command:`install(CODE)` and
+:command:`install(SCRIPT)` did not evaluate generator expressions. CMake 3.14
+and later will evaluate generator expressions for :command:`install(CODE)` and
+:command:`install(SCRIPT)`.
+
+The ``OLD`` behavior of this policy is for :command:`install(CODE)` and
+:command:`install(SCRIPT)` to not evaluate generator expressions. The ``NEW``
+behavior is to evaluate generator expressions for :command:`install(CODE)` and
+:command:`install(SCRIPT)`.
+
+Note that it is the value of this policy setting at the end of the directory
+scope that is important, not its setting at the time of the call to
+:command:`install(CODE)` or :command:`install(SCRIPT)`. This has implications
+for calling these commands from places that have their own policy scope but not
+their own directory scope (e.g. from files brought in via :command:`include()`
+rather than :command:`add_subdirectory()`).
+
+This policy was introduced in CMake version 3.14. CMake version
+|release| warns when the policy is not set and uses ``OLD`` behavior.
+Use the :command:`cmake_policy` command to set it to ``OLD`` or ``NEW``
+explicitly.
+
+.. include:: DEPRECATED.txt
diff --git a/Help/prop_tgt/AUTOMOC.rst b/Help/prop_tgt/AUTOMOC.rst
index 7a3fd48..3e6d560 100644
--- a/Help/prop_tgt/AUTOMOC.rst
+++ b/Help/prop_tgt/AUTOMOC.rst
@@ -58,6 +58,9 @@ source files at build time and invoke moc accordingly.
This property is initialized by the value of the :variable:`CMAKE_AUTOMOC`
variable if it is set when a target is created.
+The ``moc`` executable will be detected automatically, but can be forced to
+a certain binary using the :prop_tgt:`AUTOMOC_EXECUTABLE` property.
+
Additional command line options for ``moc`` can be set via the
:prop_tgt:`AUTOMOC_MOC_OPTIONS` property.
diff --git a/Help/prop_tgt/AUTOMOC_EXECUTABLE.rst b/Help/prop_tgt/AUTOMOC_EXECUTABLE.rst
new file mode 100644
index 0000000..6b66ce8
--- /dev/null
+++ b/Help/prop_tgt/AUTOMOC_EXECUTABLE.rst
@@ -0,0 +1,15 @@
+AUTOMOC_EXECUTABLE
+------------------
+
+:prop_tgt:`AUTOMOC_EXECUTABLE` is file path pointing to the ``moc``
+executable to use for :prop_tgt:`AUTOMOC` enabled files. Setting
+this property will make CMake skip the automatic detection of the
+``moc`` binary as well as the sanity-tests normally run to ensure
+that the binary is available and working as expected.
+
+Usually this property does not need to be set. Only consider this
+property if auto-detection of ``moc`` can not work -- e.g. because
+you are building the ``moc`` binary as part of your project.
+
+See the :manual:`cmake-qt(7)` manual for more information on using CMake
+with Qt.
diff --git a/Help/prop_tgt/AUTORCC.rst b/Help/prop_tgt/AUTORCC.rst
index 27fb149..5db6ed0 100644
--- a/Help/prop_tgt/AUTORCC.rst
+++ b/Help/prop_tgt/AUTORCC.rst
@@ -21,6 +21,9 @@ If the ``.qrc`` file is :prop_sf:`GENERATED` though, a
Additional command line options for rcc can be set via the
:prop_sf:`AUTORCC_OPTIONS` source file property on the ``.qrc`` file.
+The ``rcc`` executable will be detected automatically, but can be forced to
+a certain binary using the :prop_tgt:`AUTORCC_EXECUTABLE` property.
+
The global property :prop_gbl:`AUTOGEN_TARGETS_FOLDER` can be used to group
the autorcc targets together in an IDE, e.g. in MSVS.
diff --git a/Help/prop_tgt/AUTORCC_EXECUTABLE.rst b/Help/prop_tgt/AUTORCC_EXECUTABLE.rst
new file mode 100644
index 0000000..ca0fbd7
--- /dev/null
+++ b/Help/prop_tgt/AUTORCC_EXECUTABLE.rst
@@ -0,0 +1,15 @@
+AUTORCC_EXECUTABLE
+------------------
+
+:prop_tgt:`AUTORCC_EXECUTABLE` is file path pointing to the ``rcc``
+executable to use for :prop_tgt:`AUTORCC` enabled files. Setting
+this property will make CMake skip the automatic detection of the
+``rcc`` binary as well as the sanity-tests normally run to ensure
+that the binary is available and working as expected.
+
+Usually this property does not need to be set. Only consider this
+property if auto-detection of ``rcc`` can not work -- e.g. because
+you are building the ``rcc`` binary as part of your project.
+
+See the :manual:`cmake-qt(7)` manual for more information on using CMake
+with Qt.
diff --git a/Help/prop_tgt/AUTOUIC.rst b/Help/prop_tgt/AUTOUIC.rst
index 4f58b35..85226c1 100644
--- a/Help/prop_tgt/AUTOUIC.rst
+++ b/Help/prop_tgt/AUTOUIC.rst
@@ -30,6 +30,9 @@ Additional command line options for ``uic`` can be set via the
The global property :prop_gbl:`AUTOGEN_TARGETS_FOLDER` can be used to group the
autouic targets together in an IDE, e.g. in MSVS.
+The ``uic`` executable will be detected automatically, but can be forced to
+a certain binary using the :prop_tgt:`AUTOUIC_EXECUTABLE` property.
+
Source files can be excluded from :prop_tgt:`AUTOUIC` processing by
enabling :prop_sf:`SKIP_AUTOUIC` or the broader :prop_sf:`SKIP_AUTOGEN`.
diff --git a/Help/prop_tgt/AUTOUIC_EXECUTABLE.rst b/Help/prop_tgt/AUTOUIC_EXECUTABLE.rst
new file mode 100644
index 0000000..03bd554
--- /dev/null
+++ b/Help/prop_tgt/AUTOUIC_EXECUTABLE.rst
@@ -0,0 +1,15 @@
+AUTOUIC_EXECUTABLE
+------------------
+
+:prop_tgt:`AUTOUIC_EXECUTABLE` is file path pointing to the ``uic``
+executable to use for :prop_tgt:`AUTOUIC` enabled files. Setting
+this property will make CMake skip the automatic detection of the
+``uic`` binary as well as the sanity-tests normally run to ensure
+that the binary is available and working as expected.
+
+Usually this property does not need to be set. Only consider this
+property if auto-detection of ``uic`` can not work -- e.g. because
+you are building the ``uic`` binary as part of your project.
+
+See the :manual:`cmake-qt(7)` manual for more information on using CMake
+with Qt.
diff --git a/Help/prop_tgt/POSITION_INDEPENDENT_CODE.rst b/Help/prop_tgt/POSITION_INDEPENDENT_CODE.rst
index 54af8c6..0aaf66b 100644
--- a/Help/prop_tgt/POSITION_INDEPENDENT_CODE.rst
+++ b/Help/prop_tgt/POSITION_INDEPENDENT_CODE.rst
@@ -9,3 +9,8 @@ property is ``True`` by default for ``SHARED`` and ``MODULE`` library
targets and ``False`` otherwise. This property is initialized by the value
of the :variable:`CMAKE_POSITION_INDEPENDENT_CODE` variable if it is set
when a target is created.
+
+.. note::
+
+ For executable targets, the link step is controlled by the :policy:`CMP0083`
+ policy and the :module:`CheckPIESupported` module.
diff --git a/Help/release/dev/UseSWIG-source-file-ext.rst b/Help/release/dev/UseSWIG-source-file-ext.rst
new file mode 100644
index 0000000..5d11dc6
--- /dev/null
+++ b/Help/release/dev/UseSWIG-source-file-ext.rst
@@ -0,0 +1,5 @@
+UseSWIG-source-file-ext
+-----------------------
+
+* The :module:`UseSWIG` module gains capability to specify
+ ``SWIG`` source file extensions.
diff --git a/Help/release/dev/autogen_executables.rst b/Help/release/dev/autogen_executables.rst
new file mode 100644
index 0000000..5e967ea
--- /dev/null
+++ b/Help/release/dev/autogen_executables.rst
@@ -0,0 +1,9 @@
+AUTO*_EXECUTABLE
+----------------
+
+* The :prop_tgt:`AUTOMOC_EXECUTABLE`, :prop_tgt:`AUTORCC_EXECUTABLE` and
+ :prop_tgt:`AUTOUIC_EXECUTABLE` target properties all take a path to an
+ executable and force automoc/autorcc/autouic to use this executable.
+
+ Setting these will also prevent the configure time testing for these
+ executables. This is mainly useful when you build these tools yourself.
diff --git a/Help/release/dev/ctest-show-only-json-v1.rst b/Help/release/dev/ctest-show-only-json-v1.rst
new file mode 100644
index 0000000..f593e7e
--- /dev/null
+++ b/Help/release/dev/ctest-show-only-json-v1.rst
@@ -0,0 +1,6 @@
+ctest-show-only-json-v1
+-----------------------
+
+* :manual:`ctest(1)` gained a ``--show-only=json-v1`` option to show the
+ list of tests in a machine-readable JSON format.
+ See the :ref:`Show as JSON Object Model` section of the manual.
diff --git a/Help/release/dev/install-code-script-genex.rst b/Help/release/dev/install-code-script-genex.rst
new file mode 100644
index 0000000..a28a466
--- /dev/null
+++ b/Help/release/dev/install-code-script-genex.rst
@@ -0,0 +1,5 @@
+install-code-script-genex
+-------------------------
+
+* The :command:`install(CODE)` and :command:`install(SCRIPT)` commands
+ learned to support generator expressions. See policy :policy:`CMP0087`.
diff --git a/Help/release/dev/link-option-PIE.rst b/Help/release/dev/link-option-PIE.rst
index 824ab2c..872343c 100644
--- a/Help/release/dev/link-option-PIE.rst
+++ b/Help/release/dev/link-option-PIE.rst
@@ -2,5 +2,8 @@ link-option-PIE
---------------
* Required link options to manage Position Independent Executable are now
- added when :prop_tgt:`POSITION_INDEPENDENT_CODE` is set. These flags are
- controlled by policy :policy:`CMP0083`.
+ added when :prop_tgt:`POSITION_INDEPENDENT_CODE` is set. The project is
+ responsible for using the :module:`CheckPIESupported` module to check for
+ ``PIE`` support to ensure that the :prop_tgt:`POSITION_INDEPENDENT_CODE`
+ target property will be honored at link time for executables. This behavior
+ is controlled by policy :policy:`CMP0083`.
diff --git a/Modules/BundleUtilities.cmake b/Modules/BundleUtilities.cmake
index 10e5510..8c7646e 100644
--- a/Modules/BundleUtilities.cmake
+++ b/Modules/BundleUtilities.cmake
@@ -717,6 +717,9 @@ function(link_resolved_item_into_bundle resolved_item resolved_embedded_item)
else()
get_filename_component(target_dir "${resolved_embedded_item}" DIRECTORY)
file(RELATIVE_PATH symlink_target "${target_dir}" "${resolved_item}")
+ if (NOT EXISTS "${target_dir}")
+ file(MAKE_DIRECTORY "${target_dir}")
+ endif()
execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink "${symlink_target}" "${resolved_embedded_item}")
endif()
endfunction()
@@ -877,9 +880,13 @@ function(fixup_bundle_item resolved_embedded_item exepath dirs)
execute_process(COMMAND chmod u+w "${resolved_embedded_item}")
endif()
+ # CMAKE_INSTALL_NAME_TOOL may not be set if executed in script mode
+ # Duplicated from CMakeFindBinUtils.cmake
+ find_program(CMAKE_INSTALL_NAME_TOOL NAMES install_name_tool HINTS ${_CMAKE_TOOLCHAIN_LOCATION})
+
# Only if install_name_tool supports -delete_rpath:
#
- execute_process(COMMAND install_name_tool
+ execute_process(COMMAND ${CMAKE_INSTALL_NAME_TOOL}
OUTPUT_VARIABLE install_name_tool_usage
ERROR_VARIABLE install_name_tool_usage
)
@@ -897,7 +904,7 @@ function(fixup_bundle_item resolved_embedded_item exepath dirs)
# to install_name_tool:
#
if(changes)
- set(cmd install_name_tool ${changes} "${resolved_embedded_item}")
+ set(cmd ${CMAKE_INSTALL_NAME_TOOL} ${changes} "${resolved_embedded_item}")
execute_process(COMMAND ${cmd} RESULT_VARIABLE install_name_tool_result)
if(NOT install_name_tool_result EQUAL 0)
string(REPLACE ";" "' '" msg "'${cmd}'")
diff --git a/Modules/CheckIPOSupported.cmake b/Modules/CheckIPOSupported.cmake
index ad8852c..0d6ad20 100644
--- a/Modules/CheckIPOSupported.cmake
+++ b/Modules/CheckIPOSupported.cmake
@@ -51,8 +51,6 @@ Examples
#]=======================================================================]
-include(CMakeParseArguments) # cmake_parse_arguments
-
# X_RESULT - name of the final result variable
# X_OUTPUT - name of the variable with information about error
macro(_ipo_not_supported output)
diff --git a/Modules/CheckPIESupported.cmake b/Modules/CheckPIESupported.cmake
new file mode 100644
index 0000000..720217d
--- /dev/null
+++ b/Modules/CheckPIESupported.cmake
@@ -0,0 +1,134 @@
+# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+# file Copyright.txt or https://cmake.org/licensing for details.
+
+#[=======================================================================[.rst:
+CheckPIESupported
+-----------------
+
+Check whether the linker supports position independent code (PIE) or no
+position independent code (NO_PIE) for executables.
+Use this to ensure that the :prop_tgt:`POSITION_INDEPENDENT_CODE` target
+property for executables will be honored at link time.
+
+.. command:: check_pie_supported
+
+ ::
+
+ check_pie_supported([OUTPUT_VARIABLE <output>]
+ [LANGUAGES <lang>...])
+
+ Options are:
+
+ ``OUTPUT_VARIABLE <output>``
+ Set ``<output>`` variable with details about any error.
+ ``LANGUAGES <lang>...``
+ Check the linkers used for each of the specified languages.
+ Supported languages are ``C``, ``CXX``, and ``Fortran``.
+
+It makes no sense to use this module when :policy:`CMP0083` is set to ``OLD``,
+so the command will return an error in this case. See policy :policy:`CMP0083`
+for details.
+
+Variables
+^^^^^^^^^
+
+For each language checked, two boolean cache variables are defined.
+
+ ``CMAKE_<lang>_LINK_PIE_SUPPORTED``
+ Set to ``YES`` if ``PIE`` is supported by the linker and ``NO`` otherwise.
+ ``CMAKE_<lang>_LINK_NO_PIE_SUPPORTED``
+ Set to ``YES`` if ``NO_PIE`` is supported by the linker and ``NO`` otherwise.
+
+Examples
+^^^^^^^^
+
+.. code-block:: cmake
+
+ check_pie_supported()
+ set_property(TARGET foo PROPERTY POSITION_INDEPENDENT_CODE TRUE)
+
+.. code-block:: cmake
+
+ # Retrieve any error message.
+ check_pie_supported(OUTPUT_VARIABLE output LANGUAGES C)
+ set_property(TARGET foo PROPERTY POSITION_INDEPENDENT_CODE TRUE)
+ if(NOT CMAKE_C_LINK_PIE_SUPPORTED)
+ message(WARNING "PIE is not supported at link time: ${output}.\n"
+ "PIE link options will not be passed to linker.")
+ endif()
+
+#]=======================================================================]
+
+
+include (Internal/CMakeCheckCompilerFlag)
+
+function (check_pie_supported)
+ cmake_policy(GET CMP0083 cmp0083)
+
+ if (NOT cmp0083)
+ message(FATAL_ERROR "check_pie_supported: Policy CMP0083 is not set")
+ endif()
+
+ if(cmp0083 STREQUAL "OLD")
+ message(FATAL_ERROR "check_pie_supported: Policy CMP0083 set to OLD")
+ endif()
+
+ set(optional)
+ set(one OUTPUT_VARIABLE)
+ set(multiple LANGUAGES)
+
+ cmake_parse_arguments(CHECK_PIE "${optional}" "${one}" "${multiple}" "${ARGN}")
+ if(CHECK_PIE_UNPARSED_ARGUMENTS)
+ message(FATAL_ERROR "check_pie_supported: Unparsed arguments: ${CHECK_PIE_UNPARSED_ARGUMENTS}")
+ endif()
+
+ if (CHECK_PIE_LANGUAGES)
+ set (unsupported_languages "${CHECK_PIE_LANGUAGES}")
+ list (REMOVE_ITEM unsupported_languages "C" "CXX" "Fortran")
+ if(unsupported_languages)
+ message(FATAL_ERROR "check_pie_supported: language(s) '${unsupported_languages}' not supported")
+ endif()
+ else()
+ # User did not set any languages, use defaults
+ get_property (enabled_languages GLOBAL PROPERTY ENABLED_LANGUAGES)
+ if (NOT enabled_languages)
+ return()
+ endif()
+
+ list (FILTER enabled_languages INCLUDE REGEX "^(C|CXX|Fortran)$")
+ if (NOT enabled_languages)
+ return()
+ endif()
+
+ set (CHECK_PIE_LANGUAGES ${enabled_languages})
+ endif()
+
+ set (outputs)
+
+ foreach(lang IN LISTS CHECK_PIE_LANGUAGES)
+ if(_CMAKE_${lang}_PIE_MAY_BE_SUPPORTED_BY_LINKER)
+ cmake_check_compiler_flag(${lang} "${CMAKE_${lang}_LINK_OPTIONS_PIE}"
+ CMAKE_${lang}_LINK_PIE_SUPPORTED
+ OUTPUT_VARIABLE output)
+ if (NOT CMAKE_${lang}_LINK_PIE_SUPPORTED)
+ string (APPEND outputs "PIE (${lang}): ${output}\n")
+ endif()
+
+ cmake_check_compiler_flag(${lang} "${CMAKE_${lang}_LINK_OPTIONS_NO_PIE}"
+ CMAKE_${lang}_LINK_NO_PIE_SUPPORTED
+ OUTPUT_VARIABLE output)
+ if (NOT CMAKE_${lang}_LINK_NO_PIE_SUPPORTED)
+ string (APPEND outputs "NO_PIE (${lang}): ${output}\n")
+ endif()
+ else()
+ # no support at link time. Set cache variables to NO
+ set(CMAKE_${lang}_LINK_PIE_SUPPORTED NO CACHE INTERNAL "PIE (${lang})")
+ set(CMAKE_${lang}_LINK_NO_PIE_SUPPORTED NO CACHE INTERNAL "NO_PIE (${lang})")
+ string (APPEND outputs "PIE and NO_PIE are not supported by linker for ${lang}")
+ endif()
+ endforeach()
+
+ if (CHECK_PIE_OUTPUT_VARIABLE)
+ set (${CHECK_PIE_OUTPUT_VARIABLE} "${outputs}" PARENT_SCOPE)
+ endif()
+endfunction()
diff --git a/Modules/Compiler/AppleClang-C.cmake b/Modules/Compiler/AppleClang-C.cmake
index 8754951..a48adec 100644
--- a/Modules/Compiler/AppleClang-C.cmake
+++ b/Modules/Compiler/AppleClang-C.cmake
@@ -1,9 +1,6 @@
include(Compiler/Clang)
__compiler_clang(C)
-set(CMAKE_C_LINK_OPTIONS_PIE ${CMAKE_C_COMPILE_OPTIONS_PIE} -Xlinker -pie)
-set(CMAKE_C_LINK_OPTIONS_NO_PIE -Xlinker -no_pie)
-
if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.0)
set(CMAKE_C90_STANDARD_COMPILE_OPTION "-std=c90")
set(CMAKE_C90_EXTENSION_COMPILE_OPTION "-std=gnu90")
diff --git a/Modules/Compiler/AppleClang-CXX.cmake b/Modules/Compiler/AppleClang-CXX.cmake
index 54c1388..e5fd647 100644
--- a/Modules/Compiler/AppleClang-CXX.cmake
+++ b/Modules/Compiler/AppleClang-CXX.cmake
@@ -1,9 +1,6 @@
include(Compiler/Clang)
__compiler_clang(CXX)
-set(CMAKE_CXX_LINK_OPTIONS_PIE ${CMAKE_CXX_COMPILE_OPTIONS_PIE} -Xlinker -pie)
-set(CMAKE_CXX_LINK_OPTIONS_NO_PIE -Xlinker -no_pie)
-
if(NOT "x${CMAKE_CXX_SIMULATE_ID}" STREQUAL "xMSVC")
set(CMAKE_CXX_COMPILE_OPTIONS_VISIBILITY_INLINES_HIDDEN "-fvisibility-inlines-hidden")
endif()
diff --git a/Modules/Compiler/Clang.cmake b/Modules/Compiler/Clang.cmake
index 7cee9c7..c3f13f3 100644
--- a/Modules/Compiler/Clang.cmake
+++ b/Modules/Compiler/Clang.cmake
@@ -23,23 +23,9 @@ else()
set(CMAKE_${lang}_COMPILE_OPTIONS_PIE "-fPIE")
# Link options for PIE are already set in 'Compiler/GNU.cmake'
# but clang may require alternate syntax on some platforms
- if (NOT CMAKE_${lang}_FLAG_PIE)
- cmake_check_compiler_flag(${lang} "${CMAKE_${lang}_COMPILE_OPTIONS_PIE};-Xlinker;-pie"
- CMAKE_${lang}_FLAG_XLINKER_PIE)
- if (CMAKE_${lang}_FLAG_XLINKER_PIE)
- set(CMAKE_${lang}_LINK_OPTIONS_PIE ${CMAKE_${lang}_COMPILE_OPTIONS_PIE} "-Xlinker" "-pie")
- else()
- set(CMAKE_${lang}_LINK_OPTIONS_PIE "")
- endif()
- endif()
- if (NOT CMAKE_${lang}_FLAG_NO_PIE)
- cmake_check_compiler_flag(${lang} "-Xlinker;-no_pie"
- CMAKE_${lang}_FLAG_XLINKER_NO_PIE)
- if (CMAKE_${lang}_FLAG_XLINKER_NO_PIE)
- set(CMAKE_${lang}_LINK_OPTIONS_NO_PIE "-Xlinker" "-no_pie")
- else()
- set(CMAKE_${lang}_LINK_OPTIONS_NO_PIE "")
- endif()
+ if (APPLE)
+ set(CMAKE_${lang}_LINK_OPTIONS_PIE ${CMAKE_${lang}_COMPILE_OPTIONS_PIE} -Xlinker -pie)
+ set(CMAKE_${lang}_LINK_OPTIONS_NO_PIE -Xlinker -no_pie)
endif()
set(CMAKE_INCLUDE_SYSTEM_FLAG_${lang} "-isystem ")
set(CMAKE_${lang}_COMPILE_OPTIONS_VISIBILITY "-fvisibility=")
diff --git a/Modules/Compiler/GNU.cmake b/Modules/Compiler/GNU.cmake
index 688a1b5..6b1bd3a 100644
--- a/Modules/Compiler/GNU.cmake
+++ b/Modules/Compiler/GNU.cmake
@@ -15,23 +15,14 @@ macro(__compiler_gnu lang)
# Feature flags.
set(CMAKE_${lang}_VERBOSE_FLAG "-v")
set(CMAKE_${lang}_COMPILE_OPTIONS_PIC "-fPIC")
+ set (_CMAKE_${lang}_PIE_MAY_BE_SUPPORTED_BY_LINKER NO)
if(NOT CMAKE_${lang}_COMPILER_VERSION VERSION_LESS 3.4)
set(CMAKE_${lang}_COMPILE_OPTIONS_PIE "-fPIE")
# Support of PIE at link stage depends on various elements : platform, compiler, linker
- # so the easiest way is to check if compiler supports these flags
- cmake_check_compiler_flag(${lang} "${CMAKE_${lang}_COMPILE_OPTIONS_PIE};-pie"
- CMAKE_${lang}_FLAG_PIE)
- if (CMAKE_${lang}_FLAG_PIE)
- set(CMAKE_${lang}_LINK_OPTIONS_PIE ${CMAKE_${lang}_COMPILE_OPTIONS_PIE} "-pie")
- else()
- set(CMAKE_${lang}_LINK_OPTIONS_PIE "")
- endif()
- cmake_check_compiler_flag(${lang} "-no-pie" CMAKE_${lang}_FLAG_NO_PIE)
- if (CMAKE_${lang}_FLAG_NO_PIE)
- set(CMAKE_${lang}_LINK_OPTIONS_NO_PIE "-no-pie")
- else()
- set(CMAKE_${lang}_LINK_OPTIONS_NO_PIE "")
- endif()
+ # so to activate it, module CheckPIESupported must be used.
+ set (_CMAKE_${lang}_PIE_MAY_BE_SUPPORTED_BY_LINKER YES)
+ set(CMAKE_${lang}_LINK_OPTIONS_PIE ${CMAKE_${lang}_COMPILE_OPTIONS_PIE} "-pie")
+ set(CMAKE_${lang}_LINK_OPTIONS_NO_PIE "-no-pie")
endif()
if(NOT CMAKE_${lang}_COMPILER_VERSION VERSION_LESS 4.0)
set(CMAKE_${lang}_COMPILE_OPTIONS_VISIBILITY "-fvisibility=")
diff --git a/Modules/Compiler/SunPro-C.cmake b/Modules/Compiler/SunPro-C.cmake
index 75b8fe6..c4aba8e 100644
--- a/Modules/Compiler/SunPro-C.cmake
+++ b/Modules/Compiler/SunPro-C.cmake
@@ -7,6 +7,7 @@ set(CMAKE_C_VERBOSE_FLAG "-#")
set(CMAKE_C_COMPILE_OPTIONS_PIC -KPIC)
set(CMAKE_C_COMPILE_OPTIONS_PIE "")
+set(_CMAKE_C_PIE_MAY_BE_SUPPORTED_BY_LINKER NO)
set(CMAKE_C_LINK_OPTIONS_PIE "")
set(CMAKE_C_LINK_OPTIONS_NO_PIE "")
set(CMAKE_SHARED_LIBRARY_C_FLAGS "-KPIC")
diff --git a/Modules/Compiler/SunPro-CXX.cmake b/Modules/Compiler/SunPro-CXX.cmake
index 662ac30..5ce58b2 100644
--- a/Modules/Compiler/SunPro-CXX.cmake
+++ b/Modules/Compiler/SunPro-CXX.cmake
@@ -7,6 +7,7 @@ set(CMAKE_CXX_VERBOSE_FLAG "-v")
set(CMAKE_CXX_COMPILE_OPTIONS_PIC -KPIC)
set(CMAKE_CXX_COMPILE_OPTIONS_PIE "")
+set(_CMAKE_CXX_PIE_MAY_BE_SUPPORTED_BY_LINKER NO)
set(CMAKE_CXX_LINK_OPTIONS_PIE "")
set(CMAKE_CXX_LINK_OPTIONS_NO_PIE "")
set(CMAKE_SHARED_LIBRARY_CXX_FLAGS "-KPIC")
diff --git a/Modules/Compiler/SunPro-Fortran.cmake b/Modules/Compiler/SunPro-Fortran.cmake
index e110253..0c93c94 100644
--- a/Modules/Compiler/SunPro-Fortran.cmake
+++ b/Modules/Compiler/SunPro-Fortran.cmake
@@ -4,6 +4,7 @@ set(CMAKE_Fortran_FORMAT_FREE_FLAG "-free")
set(CMAKE_Fortran_COMPILE_OPTIONS_PIC "-KPIC")
set(CMAKE_Fortran_COMPILE_OPTIONS_PIE "")
+set(_CMAKE_Fortran_PIE_MAY_BE_SUPPORTED_BY_LINKER NO)
set(CMAKE_Fortran_LINK_OPTIONS_PIE "")
set(CMAKE_Fortran_LINK_OPTIONS_NO_PIE "")
set(CMAKE_SHARED_LIBRARY_Fortran_FLAGS "-KPIC")
diff --git a/Modules/ExternalProject.cmake b/Modules/ExternalProject.cmake
index 93cd74a..e763bab 100644
--- a/Modules/ExternalProject.cmake
+++ b/Modules/ExternalProject.cmake
@@ -550,6 +550,14 @@ External Project Definition
``LOG_MERGED_STDOUTERR <bool>``
When enabled, the output the step is not split by stdout and stderr.
+ ``LOG_OUTPUT_ON_FAILURE <bool>``
+ This option only has an effect if at least one of the other ``LOG_<step>``
+ options is enabled. If an error occurs for a step which has logging to
+ file enabled, that step's output will be printed to the console if
+ ``LOG_OUTPUT_ON_FAILURE`` is set to true. For cases where a large amount
+ of output is recorded, just the end of that output may be printed to the
+ console.
+
**Terminal Access Options:**
Steps can be given direct access to the terminal in some cases. Giving a
step access to the terminal may allow it to receive terminal input if
@@ -1953,6 +1961,7 @@ endif()
set(script ${stamp_dir}/${name}-${step}-$<CONFIG>.cmake)
set(logbase ${log_dir}/${name}-${step})
get_property(log_merged TARGET ${name} PROPERTY _EP_LOG_MERGED_STDOUTERR)
+ get_property(log_output_on_failure TARGET ${name} PROPERTY _EP_LOG_OUTPUT_ON_FAILURE)
if (log_merged)
set(stdout_log "${logbase}.log")
set(stderr_log "${logbase}.log")
@@ -1961,21 +1970,55 @@ endif()
set(stderr_log "${logbase}-err.log")
endif()
set(code "
+cmake_minimum_required(VERSION 3.13)
${code_cygpath_make}
set(command \"${command}\")
+set(log_merged \"${log_merged}\")
+set(log_output_on_failure \"${log_output_on_failure}\")
+set(stdout_log \"${stdout_log}\")
+set(stderr_log \"${stderr_log}\")
execute_process(
COMMAND \${command}
RESULT_VARIABLE result
- OUTPUT_FILE \"${stdout_log}\"
- ERROR_FILE \"${stderr_log}\"
+ OUTPUT_FILE \"\${stdout_log}\"
+ ERROR_FILE \"\${stderr_log}\"
)
+macro(read_up_to_max_size log_file output_var)
+ file(SIZE \${log_file} determined_size)
+ set(max_size 10240)
+ if (determined_size GREATER max_size)
+ math(EXPR seek_position \"\${determined_size} - \${max_size}\")
+ file(READ \${log_file} \${output_var} OFFSET \${seek_position})
+ set(\${output_var} \"...skipping to end...\\n\${\${output_var}}\")
+ else()
+ file(READ \${log_file} \${output_var})
+ endif()
+endmacro()
if(result)
set(msg \"Command failed: \${result}\\n\")
foreach(arg IN LISTS command)
set(msg \"\${msg} '\${arg}'\")
endforeach()
- set(msg \"\${msg}\\nSee also\\n ${stderr_log}\")
- message(FATAL_ERROR \"\${msg}\")
+ if (\${log_merged})
+ set(msg \"\${msg}\\nSee also\\n \${stderr_log}\")
+ else()
+ set(msg \"\${msg}\\nSee also\\n ${logbase}-*.log\")
+ endif()
+ if (\${log_output_on_failure})
+ message(SEND_ERROR \"\${msg}\")
+ if (\${log_merged})
+ read_up_to_max_size(\"\${stderr_log}\" error_log_contents)
+ message(STATUS \"Log output is:\\n\${error_log_contents}\")
+ else()
+ read_up_to_max_size(\"\${stdout_log}\" out_log_contents)
+ read_up_to_max_size(\"\${stderr_log}\" err_log_contents)
+ message(STATUS \"stdout output is:\\n\${out_log_contents}\")
+ message(STATUS \"stderr output is:\\n\${err_log_contents}\")
+ endif()
+ message(FATAL_ERROR \"Stopping after outputting logs.\")
+ else()
+ message(FATAL_ERROR \"\${msg}\")
+ endif()
else()
set(msg \"${name} ${step} command succeeded. See also ${logbase}-*.log\")
message(STATUS \"\${msg}\")
diff --git a/Modules/FeatureSummary.cmake b/Modules/FeatureSummary.cmake
index fbce235..4a3e83a 100644
--- a/Modules/FeatureSummary.cmake
+++ b/Modules/FeatureSummary.cmake
@@ -97,8 +97,6 @@ Functions
#]=======================================================================]
-include(CMakeParseArguments)
-
function(_FS_GET_FEATURE_SUMMARY _property _var _includeQuiet)
get_property(_fsPkgTypes GLOBAL PROPERTY FeatureSummary_PKG_TYPES)
diff --git a/Modules/FindLibLZMA.cmake b/Modules/FindLibLZMA.cmake
index b7e5815..6225744 100644
--- a/Modules/FindLibLZMA.cmake
+++ b/Modules/FindLibLZMA.cmake
@@ -5,34 +5,40 @@
FindLibLZMA
-----------
-Find LibLZMA
+Find LZMA compression algorithm headers and library.
-Find LibLZMA headers and library
-
-IMPORTED Targets
+Imported Targets
^^^^^^^^^^^^^^^^
This module defines :prop_tgt:`IMPORTED` target ``LibLZMA::LibLZMA``, if
-LibLZMA has been found.
+liblzma has been found.
Result variables
^^^^^^^^^^^^^^^^
This module will set the following variables in your project:
-::
-
- LIBLZMA_FOUND - True if liblzma is found.
- LIBLZMA_INCLUDE_DIRS - Directory where liblzma headers are located.
- LIBLZMA_LIBRARIES - Lzma libraries to link against.
- LIBLZMA_HAS_AUTO_DECODER - True if lzma_auto_decoder() is found (required).
- LIBLZMA_HAS_EASY_ENCODER - True if lzma_easy_encoder() is found (required).
- LIBLZMA_HAS_LZMA_PRESET - True if lzma_lzma_preset() is found (required).
- LIBLZMA_VERSION_MAJOR - The major version of lzma
- LIBLZMA_VERSION_MINOR - The minor version of lzma
- LIBLZMA_VERSION_PATCH - The patch version of lzma
- LIBLZMA_VERSION_STRING - version number as a string (ex: "5.0.3")
+``LIBLZMA_FOUND``
+ True if liblzma headers and library were found.
+``LIBLZMA_INCLUDE_DIRS``
+ Directory where liblzma headers are located.
+``LIBLZMA_LIBRARIES``
+ Lzma libraries to link against.
+``LIBLZMA_HAS_AUTO_DECODER``
+ True if lzma_auto_decoder() is found (required).
+``LIBLZMA_HAS_EASY_ENCODER``
+ True if lzma_easy_encoder() is found (required).
+``LIBLZMA_HAS_LZMA_PRESET``
+ True if lzma_lzma_preset() is found (required).
+``LIBLZMA_VERSION_MAJOR``
+ The major version of lzma
+``LIBLZMA_VERSION_MINOR``
+ The minor version of lzma
+``LIBLZMA_VERSION_PATCH``
+ The patch version of lzma
+``LIBLZMA_VERSION_STRING``
+ version number as a string (ex: "5.0.3")
#]=======================================================================]
find_path(LIBLZMA_INCLUDE_DIR lzma.h )
diff --git a/Modules/FindProtobuf.cmake b/Modules/FindProtobuf.cmake
index 593fff6..1758fb3 100644
--- a/Modules/FindProtobuf.cmake
+++ b/Modules/FindProtobuf.cmake
@@ -121,8 +121,6 @@ Example:
#]=======================================================================]
function(protobuf_generate)
- include(CMakeParseArguments)
-
set(_options APPEND_PATH DESCRIPTORS)
set(_singleargs LANGUAGE OUT_VAR EXPORT_MACRO PROTOC_OUT_DIR)
if(COMMAND target_sources)
diff --git a/Modules/FindThreads.cmake b/Modules/FindThreads.cmake
index 9c96a1b..5d894c8 100644
--- a/Modules/FindThreads.cmake
+++ b/Modules/FindThreads.cmake
@@ -29,9 +29,12 @@ caller can set
THREADS_PREFER_PTHREAD_FLAG
-Please note that the compiler flag can only be used with the imported
+The compiler flag can only be used with the imported
target. Use of both the imported target as well as this switch is highly
recommended for new code.
+
+This module is not needed for C++11 and later if threading is done using
+``std::thread`` from the standard library.
#]=======================================================================]
include (CheckLibraryExists)
diff --git a/Modules/GetPrerequisites.cmake b/Modules/GetPrerequisites.cmake
index 5b32f7c..fa6d75a 100644
--- a/Modules/GetPrerequisites.cmake
+++ b/Modules/GetPrerequisites.cmake
@@ -63,6 +63,9 @@ searched first when a target without any path info is given. Then
standard system locations are also searched: PATH, Framework
locations, /usr/lib...
+The variable GET_PREREQUISITES_VERBOSE can be set to true to enable verbose
+output.
+
::
LIST_PREREQUISITES(<target> [<recurse> [<exclude_system> [<verbose>]]])
@@ -644,6 +647,10 @@ function(get_prerequisites target prerequisites_var exclude_system recurse exepa
set(rpaths "")
endif()
+ if(GET_PREREQUISITES_VERBOSE)
+ set(verbose 1)
+ endif()
+
if(NOT IS_ABSOLUTE "${target}")
message("warning: target '${target}' is not absolute...")
endif()
@@ -653,6 +660,15 @@ function(get_prerequisites target prerequisites_var exclude_system recurse exepa
return()
endif()
+ # Check for a script by extension (.bat,.sh,...) or if the file starts with "#!" (shebang)
+ file(READ ${target} file_contents LIMIT 5)
+ if(target MATCHES "\\.(bat|c?sh|bash|ksh|cmd)$" OR file_contents MATCHES "^#!")
+ message(STATUS "GetPrequisites(${target}) : ignoring script file")
+ # Clear var
+ set(${prerequisites_var} "" PARENT_SCOPE)
+ return()
+ endif()
+
set(gp_cmd_paths ${gp_cmd_paths}
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\14.0;InstallDir]/../../VC/bin"
"$ENV{VS140COMNTOOLS}/../../VC/bin"
@@ -711,25 +727,25 @@ function(get_prerequisites target prerequisites_var exclude_system recurse exepa
set(gp_cmd_maybe_filter) # optional command to pre-filter gp_tool results
- if(gp_tool STREQUAL "ldd")
+ if(gp_tool MATCHES "ldd$")
set(gp_cmd_args "")
set(gp_regex "^[\t ]*[^\t ]+ => ([^\t\(]+) .*${eol_char}$")
set(gp_regex_error "not found${eol_char}$")
set(gp_regex_fallback "^[\t ]*([^\t ]+) => ([^\t ]+).*${eol_char}$")
set(gp_regex_cmp_count 1)
- elseif(gp_tool STREQUAL "otool")
+ elseif(gp_tool MATCHES "otool$")
set(gp_cmd_args "-L")
set(gp_regex "^\t([^\t]+) \\(compatibility version ([0-9]+.[0-9]+.[0-9]+), current version ([0-9]+.[0-9]+.[0-9]+)\\)${eol_char}$")
set(gp_regex_error "")
set(gp_regex_fallback "")
set(gp_regex_cmp_count 3)
- elseif(gp_tool STREQUAL "dumpbin")
+ elseif(gp_tool MATCHES "dumpbin$")
set(gp_cmd_args "/dependents")
set(gp_regex "^ ([^ ].*[Dd][Ll][Ll])${eol_char}$")
set(gp_regex_error "")
set(gp_regex_fallback "")
set(gp_regex_cmp_count 1)
- elseif(gp_tool STREQUAL "objdump")
+ elseif(gp_tool MATCHES "objdump$")
set(gp_cmd_args "-p")
set(gp_regex "^\t*DLL Name: (.*\\.[Dd][Ll][Ll])${eol_char}$")
set(gp_regex_error "")
@@ -752,7 +768,7 @@ function(get_prerequisites target prerequisites_var exclude_system recurse exepa
endif()
- if(gp_tool STREQUAL "dumpbin")
+ if(gp_tool MATCHES "dumpbin$")
# When running dumpbin, it also needs the "Common7/IDE" directory in the
# PATH. It will already be in the PATH if being run from a Visual Studio
# command prompt. Add it to the PATH here in case we are running from a
@@ -781,7 +797,7 @@ function(get_prerequisites target prerequisites_var exclude_system recurse exepa
#
# </setup-gp_tool-vars>
- if(gp_tool STREQUAL "ldd")
+ if(gp_tool MATCHES "ldd$")
set(old_ld_env "$ENV{LD_LIBRARY_PATH}")
set(new_ld_env "${exepath}")
foreach(dir ${dirs})
@@ -806,7 +822,7 @@ function(get_prerequisites target prerequisites_var exclude_system recurse exepa
ERROR_VARIABLE gp_ev
)
- if(gp_tool STREQUAL "dumpbin")
+ if(gp_tool MATCHES "dumpbin$")
# Exclude delay load dependencies under windows (they are listed in dumpbin output after the message below)
string(FIND "${gp_cmd_ov}" "Image has the following delay load dependencies" gp_delayload_pos)
if (${gp_delayload_pos} GREATER -1)
@@ -820,7 +836,7 @@ function(get_prerequisites target prerequisites_var exclude_system recurse exepa
endif()
if(NOT gp_rv STREQUAL "0")
- if(gp_tool STREQUAL "dumpbin")
+ if(gp_tool MATCHES "dumpbin$")
# dumpbin error messages seem to go to stdout
message(FATAL_ERROR "${gp_cmd} failed: ${gp_rv}\n${gp_ev}\n${gp_cmd_ov}")
else()
@@ -828,7 +844,7 @@ function(get_prerequisites target prerequisites_var exclude_system recurse exepa
endif()
endif()
- if(gp_tool STREQUAL "ldd")
+ if(gp_tool MATCHES "ldd$")
set(ENV{LD_LIBRARY_PATH} "${old_ld_env}")
endif()
@@ -848,9 +864,9 @@ function(get_prerequisites target prerequisites_var exclude_system recurse exepa
# check for install id and remove it from list, since otool -L can include a
# reference to itself
set(gp_install_id)
- if(gp_tool STREQUAL "otool")
+ if(gp_tool MATCHES "otool$")
execute_process(
- COMMAND otool -D ${target}
+ COMMAND ${gp_cmd} -D ${target}
RESULT_VARIABLE otool_rv
OUTPUT_VARIABLE gp_install_id_ov
ERROR_VARIABLE otool_ev
diff --git a/Modules/GoogleTestAddTests.cmake b/Modules/GoogleTestAddTests.cmake
index 5a4bdca..4abbbec 100644
--- a/Modules/GoogleTestAddTests.cmake
+++ b/Modules/GoogleTestAddTests.cmake
@@ -30,6 +30,7 @@ if(NOT EXISTS "${TEST_EXECUTABLE}")
endif()
execute_process(
COMMAND ${TEST_EXECUTOR} "${TEST_EXECUTABLE}" --gtest_list_tests
+ WORKING_DIRECTORY "${TEST_WORKING_DIR}"
TIMEOUT ${TEST_DISCOVERY_TIMEOUT}
OUTPUT_VARIABLE output
RESULT_VARIABLE result
diff --git a/Modules/Internal/CMakeCheckCompilerFlag.cmake b/Modules/Internal/CMakeCheckCompilerFlag.cmake
index ca9b356..9c8dfb6 100644
--- a/Modules/Internal/CMakeCheckCompilerFlag.cmake
+++ b/Modules/Internal/CMakeCheckCompilerFlag.cmake
@@ -12,12 +12,17 @@ The function does not use the try_compile() command so as to avoid infinite
recursion. It may not work for all platforms or toolchains, the caller is
responsible for ensuring it is only called in valid situations.
+ cmake_check_compiler_flag(<lang> <flag> <result>
+ [SRC_EXT <ext>] [COMMAND_PATTERN <pattern>]
+ [FAIL_REGEX <regex> ...]
+ [OUTPUT_VARIABLE <output>])
+
Parameters:
- lang - Language to check.
- flag - The flag to add to the compile/link command line.
- result - Boolean output variable. It will be stored in the cache as an
- internal variable and if true, will cause future tests that assign
- to that variable to be bypassed.
+ <lang> - Language to check.
+ <flag> - The flag to add to the compile/link command line.
+ <result> - Boolean output variable. It will be stored in the cache as an
+ internal variable and if true, will cause future tests that assign
+ to that variable to be bypassed.
Optional parameters:
SRC_EXT - Overrides the extension of the source file used for the
@@ -28,7 +33,7 @@ Optional parameters:
the output, give a failed result for the check. A common
set of regular expressions will be included in addition to
those given by FAIL_REGEX.
-
+ OUTPUT_VARIABLE - Set <output> variable with details about any error.
#]=]
include_guard(GLOBAL)
@@ -58,7 +63,7 @@ function(CMAKE_CHECK_COMPILER_FLAG lang flag result)
set(check_lang ${lang})
endif()
- cmake_parse_arguments(CCCF "" "SRC_EXT;COMMAND_PATTERN" "FAIL_REGEX" ${ARGN})
+ cmake_parse_arguments(CCCF "" "SRC_EXT;COMMAND_PATTERN;OUTPUT_VARIABLE" "FAIL_REGEX" ${ARGN})
if (NOT CCCF_COMMAND_PATTERN)
set (CCCF_COMMAND_PATTERN "<FLAG> -o <OUTPUT> <SOURCE>")
@@ -95,6 +100,10 @@ function(CMAKE_CHECK_COMPILER_FLAG lang flag result)
endif()
endif()
+ if (CCCF_OUTPUT_VARIABLE)
+ unset(${CCCF_OUTPUT_VARIABLE} PARENT_SCOPE)
+ endif()
+
# Compute the directory in which to run the test.
set(COMPILER_FLAG_DIR "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp")
# Compute source and output files.
@@ -139,6 +148,9 @@ function(CMAKE_CHECK_COMPILER_FLAG lang flag result)
"Determining if the ${flag} option "
"is supported for ${lang} language failed with the following output:\n"
"${COMPILER_FLAG_OUTPUT}\n")
+ if (CCCF_OUTPUT_VARIABLE)
+ set(${CCCF_OUTPUT_VARIABLE} "${COMPILER_FLAG_OUTPUT}" PARENT_SCOPE)
+ endif()
return()
endif()
diff --git a/Modules/Platform/CYGWIN-GNU.cmake b/Modules/Platform/CYGWIN-GNU.cmake
index f55b80d..ca90712 100644
--- a/Modules/Platform/CYGWIN-GNU.cmake
+++ b/Modules/Platform/CYGWIN-GNU.cmake
@@ -27,6 +27,7 @@ macro(__cygwin_compiler_gnu lang)
# No -fPIC on cygwin
set(CMAKE_${lang}_COMPILE_OPTIONS_PIC "")
set(CMAKE_${lang}_COMPILE_OPTIONS_PIE "")
+ set(_CMAKE_${lang}_PIE_MAY_BE_SUPPORTED_BY_LINKER NO)
set(CMAKE_${lang}_LINK_OPTIONS_PIE "")
set(CMAKE_${lang}_LINK_OPTIONS_NO_PIE "")
set(CMAKE_SHARED_LIBRARY_${lang}_FLAGS "")
diff --git a/Modules/Platform/Fuchsia.cmake b/Modules/Platform/Fuchsia.cmake
index 7b33434..4b13805 100644
--- a/Modules/Platform/Fuchsia.cmake
+++ b/Modules/Platform/Fuchsia.cmake
@@ -3,6 +3,7 @@ set(FUCHSIA 1)
set(CMAKE_DL_LIBS "")
set(CMAKE_C_COMPILE_OPTIONS_PIC "-fPIC")
set(CMAKE_C_COMPILE_OPTIONS_PIE "-fPIE")
+set(_CMAKE_C_PIE_MAY_BE_SUPPORTED_BY_LINKER YES)
set(CMAKE_C_LINK_OPTIONS_PIE ${CMAKE_C_COMPILE_OPTIONS_PIE} "-pie")
set(CMAKE_C_LINK_OPTIONS_NO_PIE "-no-pie")
set(CMAKE_SHARED_LIBRARY_C_FLAGS "-fPIC")
diff --git a/Modules/Platform/Linux-Intel.cmake b/Modules/Platform/Linux-Intel.cmake
index ab22b1d..3b5ca59 100644
--- a/Modules/Platform/Linux-Intel.cmake
+++ b/Modules/Platform/Linux-Intel.cmake
@@ -23,7 +23,9 @@ endif()
macro(__linux_compiler_intel lang)
set(CMAKE_${lang}_COMPILE_OPTIONS_PIC "-fPIC")
set(CMAKE_${lang}_COMPILE_OPTIONS_PIE "-fPIE")
+ set(_CMAKE_${lang}_PIE_MAY_BE_SUPPORTED_BY_LINKER NO)
if (NOT CMAKE_${lang}_COMPILER_VERSION VERSION_LESS 13.0)
+ set(_CMAKE_${lang}_PIE_MAY_BE_SUPPORTED_BY_LINKER YES)
set(CMAKE_${lang}_LINK_OPTIONS_PIE ${CMAKE_${lang}_COMPILE_OPTIONS_PIE} "-pie")
set(CMAKE_${lang}_LINK_OPTIONS_NO_PIE "-no-pie")
endif()
diff --git a/Modules/Platform/Linux-PGI.cmake b/Modules/Platform/Linux-PGI.cmake
index 3e7e391..0341654 100644
--- a/Modules/Platform/Linux-PGI.cmake
+++ b/Modules/Platform/Linux-PGI.cmake
@@ -12,6 +12,7 @@ macro(__linux_compiler_pgi lang)
# Shared library compile and link flags.
set(CMAKE_${lang}_COMPILE_OPTIONS_PIC "-fPIC")
set(CMAKE_${lang}_COMPILE_OPTIONS_PIE "")
+ set(_CMAKE_${lang}_PIE_MAY_BE_SUPPORTED_BY_LINKER NO)
set(CMAKE_${lang}_LINK_OPTIONS_PIE "")
set(CMAKE_${lang}_LINK_OPTIONS_NO_PIE "")
set(CMAKE_SHARED_LIBRARY_${lang}_FLAGS "-fPIC")
diff --git a/Modules/Platform/SINIX.cmake b/Modules/Platform/SINIX.cmake
index e44ceef..e3b0a05 100644
--- a/Modules/Platform/SINIX.cmake
+++ b/Modules/Platform/SINIX.cmake
@@ -1,5 +1,6 @@
set(CMAKE_C_COMPILE_OPTIONS_PIC -K PIC)
set(CMAKE_C_COMPILE_OPTIONS_PIE "")
+set(_CMAKE_C_PIE_MAY_BE_SUPPORTED_BY_LINKER NO)
set(CMAKE_C_LINK_OPTIONS_PIE "")
set(CMAKE_C_LINK_OPTIONS_NO_PIE "")
set(CMAKE_SHARED_LIBRARY_C_FLAGS "-K PIC")
diff --git a/Modules/Platform/UNIX_SV.cmake b/Modules/Platform/UNIX_SV.cmake
index 433daf3..bd1ffce 100644
--- a/Modules/Platform/UNIX_SV.cmake
+++ b/Modules/Platform/UNIX_SV.cmake
@@ -1,5 +1,6 @@
set(CMAKE_C_COMPILE_OPTIONS_PIC -K PIC)
set(CMAKE_C_COMPILE_OPTIONS_PIE "")
+set(_CMAKE_C_PIE_MAY_BE_SUPPORTED_BY_LINKER NO)
set(CMAKE_C_LINK_OPTIONS_PIE "")
set(CMAKE_C_LINK_OPTIONS_NO_PIE "")
set(CMAKE_SHARED_LIBRARY_C_FLAGS "-K PIC")
diff --git a/Modules/Platform/UnixWare.cmake b/Modules/Platform/UnixWare.cmake
index 8c9d430..94888d9 100644
--- a/Modules/Platform/UnixWare.cmake
+++ b/Modules/Platform/UnixWare.cmake
@@ -1,5 +1,6 @@
set(CMAKE_C_COMPILE_OPTIONS_PIC -K PIC)
set(CMAKE_C_COMPILE_OPTIONS_PIE "")
+set(_CMAKE_C_PIE_MAY_BE_SUPPORTED_BY_LINKER NO)
set(CMAKE_C_LINK_OPTIONS_PIE "")
set(CMAKE_C_LINK_OPTIONS_NO_PIE "")
set(CMAKE_SHARED_LIBRARY_C_FLAGS "-K PIC")
diff --git a/Modules/Platform/Windows-GNU.cmake b/Modules/Platform/Windows-GNU.cmake
index 2e854e5..71189b1 100644
--- a/Modules/Platform/Windows-GNU.cmake
+++ b/Modules/Platform/Windows-GNU.cmake
@@ -72,6 +72,7 @@ macro(__windows_compiler_gnu lang)
# No -fPIC on Windows
set(CMAKE_${lang}_COMPILE_OPTIONS_PIC "")
set(CMAKE_${lang}_COMPILE_OPTIONS_PIE "")
+ set(_CMAKE_${lang}_PIE_MAY_BE_SUPPORTED_BY_LINKER NO)
set(CMAKE_${lang}_LINK_OPTIONS_PIE "")
set(CMAKE_${lang}_LINK_OPTIONS_NO_PIE "")
set(CMAKE_SHARED_LIBRARY_${lang}_FLAGS "")
diff --git a/Modules/UseSWIG.cmake b/Modules/UseSWIG.cmake
index a3d6d9e..18ea55c 100644
--- a/Modules/UseSWIG.cmake
+++ b/Modules/UseSWIG.cmake
@@ -75,7 +75,8 @@ Defines the following command for use with ``SWIG``:
``SOURCES``
List of sources for the library. Files with extension ``.i`` will be
identified as sources for the ``SWIG`` tool. Other files will be handled in
- the standard way.
+ the standard way. This behavior can be overriden by specifying the variable
+ ``SWIG_SOURCE_FILE_EXTENSIONS``.
.. note::
@@ -222,6 +223,15 @@ as well as ``SWIG``:
``SWIG_MODULE_<name>_EXTRA_DEPS``
Specify extra dependencies for the generated module for ``<name>``.
+
+``SWIG_SOURCE_FILE_EXTENSIONS``
+ Specify a list of source file extensions to override the default
+ behavior of considering only ``.i`` files as sources for the ``SWIG``
+ tool. For example:
+
+ .. code-block:: cmake
+
+ set(SWIG_SOURCE_FILE_EXTENSIONS ".i" ".swg")
#]=======================================================================]
cmake_policy(GET CMP0078 target_name_policy)
@@ -659,8 +669,20 @@ function(SWIG_ADD_LIBRARY name)
set(CMAKE_SWIG_OUTDIR "${outputdir}")
set(SWIG_OUTFILE_DIR "${outfiledir}")
+ # See if the user has specified source extensions for swig files?
+ if (NOT DEFINED SWIG_SOURCE_FILE_EXTENSIONS)
+ # Assume the default (*.i) file extension for Swig source files
+ set(SWIG_SOURCE_FILE_EXTENSIONS ".i")
+ endif()
+
+ # Generate a regex out of file extensions.
+ string(REGEX REPLACE "([$^.*+?|()-])" "\\\\\\1" swig_source_ext_regex "${SWIG_SOURCE_FILE_EXTENSIONS}")
+ list (JOIN swig_source_ext_regex "|" swig_source_ext_regex)
+ string (PREPEND swig_source_ext_regex "(")
+ string (APPEND swig_source_ext_regex ")$")
+
set(swig_dot_i_sources ${_SAM_SOURCES})
- list(FILTER swig_dot_i_sources INCLUDE REGEX "\\.i$")
+ list(FILTER swig_dot_i_sources INCLUDE REGEX ${swig_source_ext_regex})
if (NOT swig_dot_i_sources)
message(FATAL_ERROR "SWIG_ADD_LIBRARY: no SWIG interface files specified")
endif()
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index 3c4c065..2c83140 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 13)
-set(CMake_VERSION_PATCH 20181220)
+set(CMake_VERSION_PATCH 20190111)
#set(CMake_VERSION_RC 1)
diff --git a/Source/CPack/WiX/cmCPackWIXGenerator.h b/Source/CPack/WiX/cmCPackWIXGenerator.h
index 128a04d..f8c7644 100644
--- a/Source/CPack/WiX/cmCPackWIXGenerator.h
+++ b/Source/CPack/WiX/cmCPackWIXGenerator.h
@@ -28,20 +28,20 @@ public:
~cmCPackWIXGenerator();
protected:
- virtual int InitializeInternal();
+ int InitializeInternal() override;
- virtual int PackageFiles();
+ int PackageFiles() override;
- virtual const char* GetOutputExtension() { return ".msi"; }
+ const char* GetOutputExtension() override { return ".msi"; }
- virtual enum CPackSetDestdirSupport SupportsSetDestdir() const
+ enum CPackSetDestdirSupport SupportsSetDestdir() const override
{
return SETDESTDIR_UNSUPPORTED;
}
- virtual bool SupportsAbsoluteDestination() const { return false; }
+ bool SupportsAbsoluteDestination() const override { return false; }
- virtual bool SupportsComponentInstallation() const { return true; }
+ bool SupportsComponentInstallation() const override { return true; }
private:
typedef std::map<std::string, std::string> id_map_t;
diff --git a/Source/CTest/cmCTestMultiProcessHandler.cxx b/Source/CTest/cmCTestMultiProcessHandler.cxx
index f026001..8867323 100644
--- a/Source/CTest/cmCTestMultiProcessHandler.cxx
+++ b/Source/CTest/cmCTestMultiProcessHandler.cxx
@@ -6,9 +6,13 @@
#include "cmCTest.h"
#include "cmCTestRunTest.h"
#include "cmCTestTestHandler.h"
+#include "cmDuration.h"
+#include "cmListFileCache.h"
#include "cmSystemTools.h"
#include "cmWorkingDirectory.h"
+#include "cm_jsoncpp_value.h"
+#include "cm_jsoncpp_writer.h"
#include "cm_uv.h"
#include "cmUVSignalHackRAII.h" // IWYU pragma: keep
@@ -20,13 +24,19 @@
#include <chrono>
#include <cstring>
#include <iomanip>
+#include <iostream>
#include <list>
#include <math.h>
#include <sstream>
#include <stack>
#include <stdlib.h>
+#include <unordered_map>
#include <utility>
+namespace cmsys {
+class RegularExpression;
+}
+
class TestComparator
{
public:
@@ -725,9 +735,330 @@ void cmCTestMultiProcessHandler::MarkFinished()
cmSystemTools::RemoveFile(fname);
}
+static Json::Value DumpToJsonArray(const std::set<std::string>& values)
+{
+ Json::Value jsonArray = Json::arrayValue;
+ for (auto& it : values) {
+ jsonArray.append(it);
+ }
+ return jsonArray;
+}
+
+static Json::Value DumpToJsonArray(const std::vector<std::string>& values)
+{
+ Json::Value jsonArray = Json::arrayValue;
+ for (auto& it : values) {
+ jsonArray.append(it);
+ }
+ return jsonArray;
+}
+
+static Json::Value DumpRegExToJsonArray(
+ const std::vector<std::pair<cmsys::RegularExpression, std::string>>& values)
+{
+ Json::Value jsonArray = Json::arrayValue;
+ for (auto& it : values) {
+ jsonArray.append(it.second);
+ }
+ return jsonArray;
+}
+
+static Json::Value DumpMeasurementToJsonArray(
+ const std::map<std::string, std::string>& values)
+{
+ Json::Value jsonArray = Json::arrayValue;
+ for (auto& it : values) {
+ Json::Value measurement = Json::objectValue;
+ measurement["measurement"] = it.first;
+ measurement["value"] = it.second;
+ jsonArray.append(measurement);
+ }
+ return jsonArray;
+}
+
+static Json::Value DumpTimeoutAfterMatch(
+ cmCTestTestHandler::cmCTestTestProperties& testProperties)
+{
+ Json::Value timeoutAfterMatch = Json::objectValue;
+ timeoutAfterMatch["timeout"] = testProperties.AlternateTimeout.count();
+ timeoutAfterMatch["regex"] =
+ DumpRegExToJsonArray(testProperties.TimeoutRegularExpressions);
+ return timeoutAfterMatch;
+}
+
+static Json::Value DumpCTestProperty(std::string const& name,
+ Json::Value value)
+{
+ Json::Value property = Json::objectValue;
+ property["name"] = name;
+ property["value"] = std::move(value);
+ return property;
+}
+
+static Json::Value DumpCTestProperties(
+ cmCTestTestHandler::cmCTestTestProperties& testProperties)
+{
+ Json::Value properties = Json::arrayValue;
+ if (!testProperties.AttachOnFail.empty()) {
+ properties.append(DumpCTestProperty(
+ "ATTACHED_FILES_ON_FAIL", DumpToJsonArray(testProperties.AttachOnFail)));
+ }
+ if (!testProperties.AttachedFiles.empty()) {
+ properties.append(DumpCTestProperty(
+ "ATTACHED_FILES", DumpToJsonArray(testProperties.AttachedFiles)));
+ }
+ if (testProperties.Cost != 0.0f) {
+ properties.append(
+ DumpCTestProperty("COST", static_cast<double>(testProperties.Cost)));
+ }
+ if (!testProperties.Depends.empty()) {
+ properties.append(
+ DumpCTestProperty("DEPENDS", DumpToJsonArray(testProperties.Depends)));
+ }
+ if (testProperties.Disabled) {
+ properties.append(DumpCTestProperty("DISABLED", testProperties.Disabled));
+ }
+ if (!testProperties.Environment.empty()) {
+ properties.append(DumpCTestProperty(
+ "ENVIRONMENT", DumpToJsonArray(testProperties.Environment)));
+ }
+ if (!testProperties.ErrorRegularExpressions.empty()) {
+ properties.append(DumpCTestProperty(
+ "FAIL_REGULAR_EXPRESSION",
+ DumpRegExToJsonArray(testProperties.ErrorRegularExpressions)));
+ }
+ if (!testProperties.FixturesCleanup.empty()) {
+ properties.append(DumpCTestProperty(
+ "FIXTURES_CLEANUP", DumpToJsonArray(testProperties.FixturesCleanup)));
+ }
+ if (!testProperties.FixturesRequired.empty()) {
+ properties.append(DumpCTestProperty(
+ "FIXTURES_REQUIRED", DumpToJsonArray(testProperties.FixturesRequired)));
+ }
+ if (!testProperties.FixturesSetup.empty()) {
+ properties.append(DumpCTestProperty(
+ "FIXTURES_SETUP", DumpToJsonArray(testProperties.FixturesSetup)));
+ }
+ if (!testProperties.Labels.empty()) {
+ properties.append(
+ DumpCTestProperty("LABELS", DumpToJsonArray(testProperties.Labels)));
+ }
+ if (!testProperties.Measurements.empty()) {
+ properties.append(DumpCTestProperty(
+ "MEASUREMENT", DumpMeasurementToJsonArray(testProperties.Measurements)));
+ }
+ if (!testProperties.RequiredRegularExpressions.empty()) {
+ properties.append(DumpCTestProperty(
+ "PASS_REGULAR_EXPRESSION",
+ DumpRegExToJsonArray(testProperties.RequiredRegularExpressions)));
+ }
+ if (testProperties.WantAffinity) {
+ properties.append(
+ DumpCTestProperty("PROCESSOR_AFFINITY", testProperties.WantAffinity));
+ }
+ if (testProperties.Processors != 1) {
+ properties.append(
+ DumpCTestProperty("PROCESSORS", testProperties.Processors));
+ }
+ if (!testProperties.RequiredFiles.empty()) {
+ properties["REQUIRED_FILES"] =
+ DumpToJsonArray(testProperties.RequiredFiles);
+ }
+ if (!testProperties.LockedResources.empty()) {
+ properties.append(DumpCTestProperty(
+ "RESOURCE_LOCK", DumpToJsonArray(testProperties.LockedResources)));
+ }
+ if (testProperties.RunSerial) {
+ properties.append(
+ DumpCTestProperty("RUN_SERIAL", testProperties.RunSerial));
+ }
+ if (testProperties.SkipReturnCode != -1) {
+ properties.append(
+ DumpCTestProperty("SKIP_RETURN_CODE", testProperties.SkipReturnCode));
+ }
+ if (testProperties.ExplicitTimeout) {
+ properties.append(
+ DumpCTestProperty("TIMEOUT", testProperties.Timeout.count()));
+ }
+ if (!testProperties.TimeoutRegularExpressions.empty()) {
+ properties.append(DumpCTestProperty(
+ "TIMEOUT_AFTER_MATCH", DumpTimeoutAfterMatch(testProperties)));
+ }
+ if (testProperties.WillFail) {
+ properties.append(DumpCTestProperty("WILL_FAIL", testProperties.WillFail));
+ }
+ if (!testProperties.Directory.empty()) {
+ properties.append(
+ DumpCTestProperty("WORKING_DIRECTORY", testProperties.Directory));
+ }
+ return properties;
+}
+
+class BacktraceData
+{
+ std::unordered_map<std::string, Json::ArrayIndex> CommandMap;
+ std::unordered_map<std::string, Json::ArrayIndex> FileMap;
+ std::unordered_map<cmListFileContext const*, Json::ArrayIndex> NodeMap;
+ Json::Value Commands = Json::arrayValue;
+ Json::Value Files = Json::arrayValue;
+ Json::Value Nodes = Json::arrayValue;
+
+ Json::ArrayIndex AddCommand(std::string const& command)
+ {
+ auto i = this->CommandMap.find(command);
+ if (i == this->CommandMap.end()) {
+ i = this->CommandMap.emplace(command, this->Commands.size()).first;
+ this->Commands.append(command);
+ }
+ return i->second;
+ }
+
+ Json::ArrayIndex AddFile(std::string const& file)
+ {
+ auto i = this->FileMap.find(file);
+ if (i == this->FileMap.end()) {
+ i = this->FileMap.emplace(file, this->Files.size()).first;
+ this->Files.append(file);
+ }
+ return i->second;
+ }
+
+public:
+ bool Add(cmListFileBacktrace const& bt, Json::ArrayIndex& index);
+ Json::Value Dump();
+};
+
+bool BacktraceData::Add(cmListFileBacktrace const& bt, Json::ArrayIndex& index)
+{
+ if (bt.Empty()) {
+ return false;
+ }
+ cmListFileContext const* top = &bt.Top();
+ auto found = this->NodeMap.find(top);
+ if (found != this->NodeMap.end()) {
+ index = found->second;
+ return true;
+ }
+ Json::Value entry = Json::objectValue;
+ entry["file"] = this->AddFile(top->FilePath);
+ if (top->Line) {
+ entry["line"] = static_cast<int>(top->Line);
+ }
+ if (!top->Name.empty()) {
+ entry["command"] = this->AddCommand(top->Name);
+ }
+ Json::ArrayIndex parent;
+ if (this->Add(bt.Pop(), parent)) {
+ entry["parent"] = parent;
+ }
+ index = this->NodeMap[top] = this->Nodes.size();
+ this->Nodes.append(std::move(entry)); // NOLINT(*)
+ return true;
+}
+
+Json::Value BacktraceData::Dump()
+{
+ Json::Value backtraceGraph;
+ this->CommandMap.clear();
+ this->FileMap.clear();
+ this->NodeMap.clear();
+ backtraceGraph["commands"] = std::move(this->Commands);
+ backtraceGraph["files"] = std::move(this->Files);
+ backtraceGraph["nodes"] = std::move(this->Nodes);
+ return backtraceGraph;
+}
+
+static void AddBacktrace(BacktraceData& backtraceGraph, Json::Value& object,
+ cmListFileBacktrace const& bt)
+{
+ Json::ArrayIndex backtrace;
+ if (backtraceGraph.Add(bt, backtrace)) {
+ object["backtrace"] = backtrace;
+ }
+}
+
+static Json::Value DumpCTestInfo(
+ cmCTestRunTest& testRun,
+ cmCTestTestHandler::cmCTestTestProperties& testProperties,
+ BacktraceData& backtraceGraph)
+{
+ Json::Value testInfo = Json::objectValue;
+ // test name should always be present
+ testInfo["name"] = testProperties.Name;
+ std::string const& config = testRun.GetCTest()->GetConfigType();
+ if (!config.empty()) {
+ testInfo["config"] = config;
+ }
+ std::string const& command = testRun.GetActualCommand();
+ if (!command.empty()) {
+ std::vector<std::string> commandAndArgs;
+ commandAndArgs.push_back(command);
+ const std::vector<std::string>& args = testRun.GetArguments();
+ if (!args.empty()) {
+ commandAndArgs.reserve(args.size() + 1);
+ commandAndArgs.insert(commandAndArgs.end(), args.begin(), args.end());
+ }
+ testInfo["command"] = DumpToJsonArray(commandAndArgs);
+ }
+ Json::Value properties = DumpCTestProperties(testProperties);
+ if (!properties.empty()) {
+ testInfo["properties"] = properties;
+ }
+ if (!testProperties.Backtrace.Empty()) {
+ AddBacktrace(backtraceGraph, testInfo, testProperties.Backtrace);
+ }
+ return testInfo;
+}
+
+static Json::Value DumpVersion(int major, int minor)
+{
+ Json::Value version = Json::objectValue;
+ version["major"] = major;
+ version["minor"] = minor;
+ return version;
+}
+
+void cmCTestMultiProcessHandler::PrintOutputAsJson()
+{
+ this->TestHandler->SetMaxIndex(this->FindMaxIndex());
+
+ Json::Value result = Json::objectValue;
+ result["kind"] = "ctestInfo";
+ result["version"] = DumpVersion(1, 0);
+
+ BacktraceData backtraceGraph;
+ Json::Value tests = Json::arrayValue;
+ for (auto& it : this->Properties) {
+ cmCTestTestHandler::cmCTestTestProperties& p = *it.second;
+
+ // Don't worry if this fails, we are only showing the test list, not
+ // running the tests
+ cmWorkingDirectory workdir(p.Directory);
+ cmCTestRunTest testRun(*this);
+ testRun.SetIndex(p.Index);
+ testRun.SetTestProperties(&p);
+ testRun.ComputeArguments();
+
+ Json::Value testInfo = DumpCTestInfo(testRun, p, backtraceGraph);
+ tests.append(testInfo);
+ }
+ result["backtraceGraph"] = backtraceGraph.Dump();
+ result["tests"] = std::move(tests);
+
+ Json::StreamWriterBuilder builder;
+ builder["indentation"] = " ";
+ std::unique_ptr<Json::StreamWriter> jout(builder.newStreamWriter());
+ jout->write(result, &std::cout);
+}
+
// For ShowOnly mode
void cmCTestMultiProcessHandler::PrintTestList()
{
+ if (this->CTest->GetOutputAsJson()) {
+ PrintOutputAsJson();
+ return;
+ }
+
this->TestHandler->SetMaxIndex(this->FindMaxIndex());
int count = 0;
diff --git a/Source/CTest/cmCTestMultiProcessHandler.h b/Source/CTest/cmCTestMultiProcessHandler.h
index 3927a8a..93bb880 100644
--- a/Source/CTest/cmCTestMultiProcessHandler.h
+++ b/Source/CTest/cmCTestMultiProcessHandler.h
@@ -51,6 +51,7 @@ public:
void SetParallelLevel(size_t);
void SetTestLoad(unsigned long load);
virtual void RunTests();
+ void PrintOutputAsJson();
void PrintTestList();
void PrintLabels();
diff --git a/Source/CTest/cmCTestRunTest.h b/Source/CTest/cmCTestRunTest.h
index 10dceca..c786413 100644
--- a/Source/CTest/cmCTestRunTest.h
+++ b/Source/CTest/cmCTestRunTest.h
@@ -78,6 +78,10 @@ public:
cmCTest* GetCTest() const { return this->CTest; }
+ std::string& GetActualCommand() { return this->ActualCommand; }
+
+ const std::vector<std::string>& GetArguments() { return this->Arguments; }
+
void FinalizeTest();
bool TimedOutForStopTime() const { return this->TimeoutIsForStopTime; }
diff --git a/Source/CTest/cmCTestTestHandler.cxx b/Source/CTest/cmCTestTestHandler.cxx
index 2e1bb0a..9fd2299 100644
--- a/Source/CTest/cmCTestTestHandler.cxx
+++ b/Source/CTest/cmCTestTestHandler.cxx
@@ -2147,6 +2147,32 @@ bool cmCTestTestHandler::SetTestsProperties(
for (std::string const& t : tests) {
for (cmCTestTestProperties& rt : this->TestList) {
if (t == rt.Name) {
+ if (key == "_BACKTRACE_TRIPLES") {
+ std::vector<std::string> triples;
+ // allow empty args in the triples
+ cmSystemTools::ExpandListArgument(val, triples, true);
+
+ // Ensure we have complete triples otherwise the data is corrupt.
+ if (triples.size() % 3 == 0) {
+ cmState state;
+ rt.Backtrace = cmListFileBacktrace(state.CreateBaseSnapshot());
+
+ // the first entry represents the top of the trace so we need to
+ // reconstruct the backtrace in reverse
+ for (size_t i = triples.size(); i >= 3; i -= 3) {
+ cmListFileContext fc;
+ fc.FilePath = triples[i - 3];
+ long line = 0;
+ if (!cmSystemTools::StringToLong(triples[i - 2].c_str(),
+ &line)) {
+ line = 0;
+ }
+ fc.Line = line;
+ fc.Name = triples[i - 1];
+ rt.Backtrace = rt.Backtrace.Push(fc);
+ }
+ }
+ }
if (key == "WILL_FAIL") {
rt.WillFail = cmSystemTools::IsOn(val);
}
diff --git a/Source/CTest/cmCTestTestHandler.h b/Source/CTest/cmCTestTestHandler.h
index bcacf23..0b557db 100644
--- a/Source/CTest/cmCTestTestHandler.h
+++ b/Source/CTest/cmCTestTestHandler.h
@@ -7,6 +7,7 @@
#include "cmCTestGenericHandler.h"
#include "cmDuration.h"
+#include "cmListFileCache.h"
#include "cmsys/RegularExpression.hxx"
#include <chrono>
@@ -141,6 +142,8 @@ public:
std::set<std::string> FixturesCleanup;
std::set<std::string> FixturesRequired;
std::set<std::string> RequireSuccessDepends;
+ // Private test generator properties used to track backtraces
+ cmListFileBacktrace Backtrace;
};
struct cmCTestTestResult
diff --git a/Source/cmAlgorithms.h b/Source/cmAlgorithms.h
index bbd3e8e..2f8e675 100644
--- a/Source/cmAlgorithms.h
+++ b/Source/cmAlgorithms.h
@@ -396,6 +396,12 @@ constexpr
#endif
+template <typename T>
+int isize(const T& t)
+{
+ return static_cast<int>(cm::size(t));
+}
+
#if __cplusplus >= 201402L || defined(_MSVC_LANG) && _MSVC_LANG >= 201402L
using std::cbegin;
diff --git a/Source/cmCPluginAPI.cxx b/Source/cmCPluginAPI.cxx
index 065a184..1d9621c 100644
--- a/Source/cmCPluginAPI.cxx
+++ b/Source/cmCPluginAPI.cxx
@@ -407,7 +407,7 @@ char CCONV* cmExpandVariablesInString(void* arg, const char* source,
cmMakefile* mf = static_cast<cmMakefile*>(arg);
std::string barf = source;
std::string const& result =
- mf->ExpandVariablesInString(barf, escapeQuotes, atOnly);
+ mf->ExpandVariablesInString(barf, escapeQuotes != 0, atOnly != 0);
return strdup(result.c_str());
}
diff --git a/Source/cmCTest.cxx b/Source/cmCTest.cxx
index 7c19864..225c99f 100644
--- a/Source/cmCTest.cxx
+++ b/Source/cmCTest.cxx
@@ -278,6 +278,8 @@ cmCTest::cmCTest()
this->ExtraVerbose = false;
this->ProduceXML = false;
this->ShowOnly = false;
+ this->OutputAsJson = false;
+ this->OutputAsJsonVersion = 1;
this->RunConfigurationScript = false;
this->UseHTTP10 = false;
this->PrintLabels = false;
@@ -1930,6 +1932,20 @@ bool cmCTest::HandleCommandLineArguments(size_t& i,
if (this->CheckArgument(arg, "-N", "--show-only")) {
this->ShowOnly = true;
}
+ if (cmSystemTools::StringStartsWith(arg.c_str(), "--show-only=")) {
+ this->ShowOnly = true;
+
+ // Check if a specific format is requested. Defaults to human readable
+ // text.
+ std::string argWithFormat = "--show-only=";
+ 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;
+ }
+ }
if (this->CheckArgument(arg, "-O", "--output-log") && i < args.size() - 1) {
i++;
@@ -2630,6 +2646,16 @@ bool cmCTest::GetShowOnly()
return this->ShowOnly;
}
+bool cmCTest::GetOutputAsJson()
+{
+ return this->OutputAsJson;
+}
+
+int cmCTest::GetOutputAsJsonVersion()
+{
+ return this->OutputAsJsonVersion;
+}
+
int cmCTest::GetMaxTestNameWidth() const
{
return this->MaxTestNameWidth;
diff --git a/Source/cmCTest.h b/Source/cmCTest.h
index 480204a..2b40ca3 100644
--- a/Source/cmCTest.h
+++ b/Source/cmCTest.h
@@ -215,6 +215,10 @@ public:
/** Should we only show what we would do? */
bool GetShowOnly();
+ bool GetOutputAsJson();
+
+ int GetOutputAsJsonVersion();
+
bool ShouldUseHTTP10() { return this->UseHTTP10; }
bool ShouldPrintLabels() { return this->PrintLabels; }
@@ -507,6 +511,8 @@ private:
t_TestingHandlers TestingHandlers;
bool ShowOnly;
+ bool OutputAsJson;
+ int OutputAsJsonVersion;
/** Map of configuration properties */
typedef std::map<std::string, std::string> CTestConfigurationMap;
diff --git a/Source/cmCommandArgumentParserHelper.cxx b/Source/cmCommandArgumentParserHelper.cxx
index 2b4ceaa..ca29967 100644
--- a/Source/cmCommandArgumentParserHelper.cxx
+++ b/Source/cmCommandArgumentParserHelper.cxx
@@ -6,7 +6,6 @@
#include "cmMakefile.h"
#include "cmState.h"
#include "cmSystemTools.h"
-#include "cmake.h"
#include <iostream>
#include <sstream>
@@ -16,8 +15,6 @@ int cmCommandArgument_yyparse(yyscan_t yyscanner);
//
cmCommandArgumentParserHelper::cmCommandArgumentParserHelper()
{
- this->WarnUninitialized = false;
- this->CheckSystemVars = false;
this->FileLine = -1;
this->FileName = nullptr;
this->RemoveEmpty = true;
@@ -95,23 +92,11 @@ const char* cmCommandArgumentParserHelper::ExpandVariable(const char* var)
return this->AddString(ostr.str());
}
const char* value = this->Makefile->GetDefinition(var);
- if (!value && !this->RemoveEmpty) {
- // check to see if we need to print a warning
- // if strict mode is on and the variable has
- // not been "cleared"/initialized with a set(foo ) call
- if (this->WarnUninitialized && !this->Makefile->VariableInitialized(var)) {
- if (this->CheckSystemVars ||
- (this->FileName &&
- (cmSystemTools::IsSubDirectory(
- this->FileName, this->Makefile->GetHomeDirectory()) ||
- cmSystemTools::IsSubDirectory(
- this->FileName, this->Makefile->GetHomeOutputDirectory())))) {
- std::ostringstream msg;
- msg << "uninitialized variable \'" << var << "\'";
- this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, msg.str());
- }
+ if (!value) {
+ this->Makefile->MaybeWarnUninitialized(var, this->FileName);
+ if (!this->RemoveEmpty) {
+ return nullptr;
}
- return nullptr;
}
if (this->EscapeQuotes && value) {
return this->AddString(cmSystemTools::EscapeQuotes(value));
@@ -286,8 +271,6 @@ void cmCommandArgumentParserHelper::Error(const char* str)
void cmCommandArgumentParserHelper::SetMakefile(const cmMakefile* mf)
{
this->Makefile = mf;
- this->WarnUninitialized = mf->GetCMakeInstance()->GetWarnUninitialized();
- this->CheckSystemVars = mf->GetCMakeInstance()->GetCheckSystemVars();
}
void cmCommandArgumentParserHelper::SetResult(const char* value)
diff --git a/Source/cmCommandArgumentParserHelper.h b/Source/cmCommandArgumentParserHelper.h
index 098c000..4dc238e 100644
--- a/Source/cmCommandArgumentParserHelper.h
+++ b/Source/cmCommandArgumentParserHelper.h
@@ -75,8 +75,6 @@ private:
long FileLine;
int CurrentLine;
int Verbose;
- bool WarnUninitialized;
- bool CheckSystemVars;
bool EscapeQuotes;
bool NoEscapeMode;
bool ReplaceAtSyntax;
diff --git a/Source/cmCoreTryCompile.cxx b/Source/cmCoreTryCompile.cxx
index 541ae76..f9b494e 100644
--- a/Source/cmCoreTryCompile.cxx
+++ b/Source/cmCoreTryCompile.cxx
@@ -24,10 +24,18 @@
static std::string const kCMAKE_C_COMPILER_EXTERNAL_TOOLCHAIN =
"CMAKE_C_COMPILER_EXTERNAL_TOOLCHAIN";
static std::string const kCMAKE_C_COMPILER_TARGET = "CMAKE_C_COMPILER_TARGET";
+static std::string const kCMAKE_C_LINK_NO_PIE_SUPPORTED =
+ "CMAKE_C_LINK_NO_PIE_SUPPORTED";
+static std::string const kCMAKE_C_LINK_PIE_SUPPORTED =
+ "CMAKE_C_LINK_PIE_SUPPORTED";
static std::string const kCMAKE_CXX_COMPILER_EXTERNAL_TOOLCHAIN =
"CMAKE_CXX_COMPILER_EXTERNAL_TOOLCHAIN";
static std::string const kCMAKE_CXX_COMPILER_TARGET =
"CMAKE_CXX_COMPILER_TARGET";
+static std::string const kCMAKE_CXX_LINK_NO_PIE_SUPPORTED =
+ "CMAKE_CXX_LINK_NO_PIE_SUPPORTED";
+static std::string const kCMAKE_CXX_LINK_PIE_SUPPORTED =
+ "CMAKE_CXX_LINK_PIE_SUPPORTED";
static std::string const kCMAKE_ENABLE_EXPORTS = "CMAKE_ENABLE_EXPORTS";
static std::string const kCMAKE_LINK_SEARCH_END_STATIC =
"CMAKE_LINK_SEARCH_END_STATIC";
@@ -633,6 +641,16 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
vars.insert(varList.begin(), varList.end());
}
+ if (this->Makefile->GetPolicyStatus(cmPolicies::CMP0083) ==
+ cmPolicies::NEW) {
+ // To ensure full support of PIE, propagate cache variables
+ // driving the link options
+ vars.insert(kCMAKE_C_LINK_PIE_SUPPORTED);
+ vars.insert(kCMAKE_C_LINK_NO_PIE_SUPPORTED);
+ vars.insert(kCMAKE_CXX_LINK_PIE_SUPPORTED);
+ vars.insert(kCMAKE_CXX_LINK_NO_PIE_SUPPORTED);
+ }
+
/* for the TRY_COMPILEs we want to be able to specify the architecture.
So the user can set CMAKE_OSX_ARCHITECTURES to i386;ppc and then set
CMAKE_TRY_COMPILE_OSX_ARCHITECTURES first to i386 and then to ppc to
diff --git a/Source/cmExtraCodeLiteGenerator.cxx b/Source/cmExtraCodeLiteGenerator.cxx
index bbc90a2..2fa593c 100644
--- a/Source/cmExtraCodeLiteGenerator.cxx
+++ b/Source/cmExtraCodeLiteGenerator.cxx
@@ -59,18 +59,17 @@ void cmExtraCodeLiteGenerator::Generate()
// and extract the information for creating the worspace
// root makefile
for (auto const& it : projectMap) {
- const cmMakefile* mf = it.second[0]->GetMakefile();
+ cmLocalGenerator* lg = it.second[0];
+ const cmMakefile* mf = lg->GetMakefile();
this->ConfigName = GetConfigurationName(mf);
- if (it.second[0]->GetCurrentBinaryDirectory() ==
- it.second[0]->GetBinaryDirectory()) {
- workspaceOutputDir = it.second[0]->GetCurrentBinaryDirectory();
- workspaceProjectName = it.second[0]->GetProjectName();
- workspaceSourcePath = it.second[0]->GetSourceDirectory();
+ if (lg->GetCurrentBinaryDirectory() == lg->GetBinaryDirectory()) {
+ workspaceOutputDir = lg->GetCurrentBinaryDirectory();
+ workspaceProjectName = lg->GetProjectName();
+ workspaceSourcePath = lg->GetSourceDirectory();
workspaceFileName = workspaceOutputDir + "/";
workspaceFileName += workspaceProjectName + ".workspace";
- this->WorkspacePath = it.second[0]->GetCurrentBinaryDirectory();
- ;
+ this->WorkspacePath = lg->GetCurrentBinaryDirectory();
break;
}
}
diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx
index 594cb67..fc9c1d2 100644
--- a/Source/cmFileCommand.cxx
+++ b/Source/cmFileCommand.cxx
@@ -220,7 +220,7 @@ bool cmFileCommand::HandleWriteCommand(std::vector<std::string> const& args,
// Set permissions to writable
if (cmSystemTools::GetPermissions(fileName.c_str(), mode)) {
#if defined(_MSC_VER) || defined(__MINGW32__)
- writable = mode & S_IWRITE;
+ writable = (mode & S_IWRITE) != 0;
mode_t newMode = mode | S_IWRITE;
#else
writable = mode & S_IWUSR;
diff --git a/Source/cmGeneratorExpression.cxx b/Source/cmGeneratorExpression.cxx
index 2727d9a..96d4ad6 100644
--- a/Source/cmGeneratorExpression.cxx
+++ b/Source/cmGeneratorExpression.cxx
@@ -71,16 +71,11 @@ const std::string& cmCompiledGeneratorExpression::EvaluateWithContext(
this->Output.clear();
- std::vector<cmGeneratorExpressionEvaluator*>::const_iterator it =
- this->Evaluators.begin();
- const std::vector<cmGeneratorExpressionEvaluator*>::const_iterator end =
- this->Evaluators.end();
+ for (const cmGeneratorExpressionEvaluator* it : this->Evaluators) {
+ this->Output += it->Evaluate(&context, dagChecker);
- for (; it != end; ++it) {
- this->Output += (*it)->Evaluate(&context, dagChecker);
-
- this->SeenTargetProperties.insert(context.SeenTargetProperties.begin(),
- context.SeenTargetProperties.end());
+ this->SeenTargetProperties.insert(context.SeenTargetProperties.cbegin(),
+ context.SeenTargetProperties.cend());
if (context.HadError) {
this->Output.clear();
break;
diff --git a/Source/cmGhsMultiTargetGenerator.cxx b/Source/cmGhsMultiTargetGenerator.cxx
index 4d98d55..1a25633 100644
--- a/Source/cmGhsMultiTargetGenerator.cxx
+++ b/Source/cmGhsMultiTargetGenerator.cxx
@@ -196,7 +196,7 @@ void cmGhsMultiTargetGenerator::WriteTypeSpecifics(const std::string& config,
std::string outputFilename(this->GetOutputFilename(config));
if (this->GeneratorTarget->GetType() == cmStateEnums::STATIC_LIBRARY) {
- std::string const static_library_suffix =
+ std::string const& static_library_suffix =
this->Makefile->GetSafeDefinition("CMAKE_STATIC_LIBRARY_SUFFIX");
*this->GetFolderBuildStreams()
<< " -o \"" << outputDir << outputFilename << static_library_suffix
@@ -478,10 +478,9 @@ void cmGhsMultiTargetGenerator::WriteSources(
std::vector<cmSourceFile*> const& objectSources,
std::map<const cmSourceFile*, std::string> const& objectNames)
{
- for (std::vector<cmSourceFile*>::const_iterator si = objectSources.begin();
- si != objectSources.end(); ++si) {
+ for (const cmSourceFile* sf : objectSources) {
std::vector<cmSourceGroup> sourceGroups(this->Makefile->GetSourceGroups());
- std::string const& sourceFullPath = (*si)->GetFullPath();
+ std::string const& sourceFullPath = sf->GetFullPath();
cmSourceGroup* sourceGroup =
this->Makefile->FindSourceGroup(sourceFullPath, sourceGroups);
std::string sgPath = sourceGroup->GetFullName();
@@ -491,8 +490,8 @@ void cmGhsMultiTargetGenerator::WriteSources(
this->LocalGenerator->GetBinaryDirectory().c_str(), sgPath,
GhsMultiGpj::SUBPROJECT, this->RelBuildFilePath);
- std::string fullSourcePath((*si)->GetFullPath());
- if ((*si)->GetExtension() == "int" || (*si)->GetExtension() == "bsp") {
+ std::string fullSourcePath(sf->GetFullPath());
+ if (sf->GetExtension() == "int" || sf->GetExtension() == "bsp") {
*this->FolderBuildStreams[sgPath] << fullSourcePath << std::endl;
} else {
// WORKAROUND: GHS MULTI needs the path to use backslashes without quotes
@@ -501,12 +500,12 @@ void cmGhsMultiTargetGenerator::WriteSources(
*this->FolderBuildStreams[sgPath] << fullSourcePath << std::endl;
}
- if ("ld" != (*si)->GetExtension() && "int" != (*si)->GetExtension() &&
- "bsp" != (*si)->GetExtension()) {
- this->WriteObjectLangOverride(this->FolderBuildStreams[sgPath], (*si));
- if (objectNames.end() != objectNames.find(*si)) {
+ if ("ld" != sf->GetExtension() && "int" != sf->GetExtension() &&
+ "bsp" != sf->GetExtension()) {
+ this->WriteObjectLangOverride(this->FolderBuildStreams[sgPath], sf);
+ if (objectNames.end() != objectNames.find(sf)) {
*this->FolderBuildStreams[sgPath]
- << " -o \"" << objectNames.find(*si)->second << "\"" << std::endl;
+ << " -o \"" << objectNames.find(sf)->second << "\"" << std::endl;
}
this->WriteObjectDir(this->FolderBuildStreams[sgPath],
@@ -516,7 +515,7 @@ void cmGhsMultiTargetGenerator::WriteSources(
}
void cmGhsMultiTargetGenerator::WriteObjectLangOverride(
- cmGeneratedFileStream* fileStream, cmSourceFile* sourceFile)
+ cmGeneratedFileStream* fileStream, const cmSourceFile* sourceFile)
{
const char* rawLangProp = sourceFile->GetProperty("LANGUAGE");
if (NULL != rawLangProp) {
diff --git a/Source/cmGhsMultiTargetGenerator.h b/Source/cmGhsMultiTargetGenerator.h
index 2cdf68e..e936b08 100644
--- a/Source/cmGhsMultiTargetGenerator.h
+++ b/Source/cmGhsMultiTargetGenerator.h
@@ -86,7 +86,7 @@ private:
cmLocalGhsMultiGenerator* localGhsMultiGenerator,
cmGeneratorTarget* generatorTarget);
static void WriteObjectLangOverride(cmGeneratedFileStream* fileStream,
- cmSourceFile* sourceFile);
+ const cmSourceFile* sourceFile);
static void WriteObjectDir(cmGeneratedFileStream* fileStream,
std::string const& dir);
std::string GetOutputDirectory(const std::string& config) const;
diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx
index 35d716c..47c53e7 100644
--- a/Source/cmGlobalGenerator.cxx
+++ b/Source/cmGlobalGenerator.cxx
@@ -3023,11 +3023,23 @@ void cmGlobalGenerator::WriteSummary(cmGeneratorTarget* target)
std::string cmGlobalGenerator::EscapeJSON(const std::string& s)
{
std::string result;
+ result.reserve(s.size());
for (char i : s) {
- if (i == '"' || i == '\\') {
- result += '\\';
+ switch (i) {
+ case '"':
+ case '\\':
+ result += '\\';
+ result += i;
+ break;
+ case '\n':
+ result += "\\n";
+ break;
+ case '\t':
+ result += "\\t";
+ break;
+ default:
+ result += i;
}
- result += i;
}
return result;
}
diff --git a/Source/cmGlobalGhsMultiGenerator.h b/Source/cmGlobalGhsMultiGenerator.h
index 13c5113..a5aff73 100644
--- a/Source/cmGlobalGhsMultiGenerator.h
+++ b/Source/cmGlobalGhsMultiGenerator.h
@@ -25,13 +25,13 @@ public:
}
///! create the correct local generator
- virtual cmLocalGenerator* CreateLocalGenerator(cmMakefile* mf);
+ cmLocalGenerator* CreateLocalGenerator(cmMakefile* mf) override;
/// @return the name of this generator.
static std::string GetActualName() { return "Green Hills MULTI"; }
///! Get the name for this generator
- virtual std::string GetName() const { return this->GetActualName(); }
+ std::string GetName() const override { return this->GetActualName(); }
/// Overloaded methods. @see cmGlobalGenerator::GetDocumentation()
static void GetDocumentation(cmDocumentationEntry& entry);
@@ -49,15 +49,15 @@ public:
static bool SupportsPlatform() { return true; }
// Toolset / Platform Support
- virtual bool SetGeneratorToolset(std::string const& ts, cmMakefile* mf);
- virtual bool SetGeneratorPlatform(std::string const& p, cmMakefile* mf);
+ bool SetGeneratorToolset(std::string const& ts, cmMakefile* mf) override;
+ bool SetGeneratorPlatform(std::string const& p, cmMakefile* mf) override;
/**
* Try to determine system information such as shared library
* extension, pthreads, byte order etc.
*/
- virtual void EnableLanguage(std::vector<std::string> const& languages,
- cmMakefile*, bool optional);
+ void EnableLanguage(std::vector<std::string> const& languages, cmMakefile*,
+ bool optional) override;
/*
* Determine what program to use for building the project.
*/
@@ -88,13 +88,16 @@ public:
inline bool IsOSDirRelative() { return this->OSDirRelative; }
protected:
- virtual void Generate();
- virtual void GenerateBuildCommand(
- std::vector<std::string>& makeCommand, const std::string& makeProgram,
- const std::string& projectName, const std::string& projectDir,
- const std::string& targetName, const std::string& config, bool fast,
- int jobs, bool verbose,
- std::vector<std::string> const& makeOptions = std::vector<std::string>());
+ void Generate() override;
+ void GenerateBuildCommand(std::vector<std::string>& makeCommand,
+ const std::string& makeProgram,
+ const std::string& projectName,
+ const std::string& projectDir,
+ const std::string& targetName,
+ const std::string& config, bool fast, int jobs,
+ bool verbose,
+ std::vector<std::string> const& makeOptions =
+ std::vector<std::string>()) override;
private:
void GetToolset(cmMakefile* mf, std::string& tsd, std::string& ts);
diff --git a/Source/cmGlobalVisualStudio10Generator.cxx b/Source/cmGlobalVisualStudio10Generator.cxx
index c9c6938..4709194 100644
--- a/Source/cmGlobalVisualStudio10Generator.cxx
+++ b/Source/cmGlobalVisualStudio10Generator.cxx
@@ -488,16 +488,6 @@ std::string cmGlobalVisualStudio10Generator::SelectWindowsCEToolset() const
return "";
}
-void cmGlobalVisualStudio10Generator::WriteSLNHeader(std::ostream& fout)
-{
- fout << "Microsoft Visual Studio Solution File, Format Version 11.00\n";
- if (this->ExpressEdition) {
- fout << "# Visual C++ Express 2010\n";
- } else {
- fout << "# Visual Studio 2010\n";
- }
-}
-
///! Create a local generator appropriate to this Global Generator
cmLocalGenerator* cmGlobalVisualStudio10Generator::CreateLocalGenerator(
cmMakefile* mf)
@@ -1024,6 +1014,27 @@ std::string cmGlobalVisualStudio10Generator::Encoding()
return "utf-8";
}
+const char* cmGlobalVisualStudio10Generator::GetToolsVersion() const
+{
+ switch (this->Version) {
+ case cmGlobalVisualStudioGenerator::VS9:
+ case cmGlobalVisualStudioGenerator::VS10:
+ case cmGlobalVisualStudioGenerator::VS11:
+ return "4.0";
+
+ // in Visual Studio 2013 they detached the MSBuild tools version
+ // from the .Net Framework version and instead made it have it's own
+ // version number
+ case cmGlobalVisualStudioGenerator::VS12:
+ return "12.0";
+ case cmGlobalVisualStudioGenerator::VS14:
+ return "14.0";
+ case cmGlobalVisualStudioGenerator::VS15:
+ return "15.0";
+ }
+ return "";
+}
+
bool cmGlobalVisualStudio10Generator::IsNsightTegra() const
{
return !this->NsightTegraVersion.empty();
diff --git a/Source/cmGlobalVisualStudio10Generator.h b/Source/cmGlobalVisualStudio10Generator.h
index 6c4a9e6..1e72959 100644
--- a/Source/cmGlobalVisualStudio10Generator.h
+++ b/Source/cmGlobalVisualStudio10Generator.h
@@ -43,7 +43,6 @@ public:
*/
void EnableLanguage(std::vector<std::string> const& languages, cmMakefile*,
bool optional) override;
- void WriteSLNHeader(std::ostream& fout) override;
bool IsCudaEnabled() const { return this->CudaEnabled; }
@@ -86,7 +85,7 @@ public:
}
/** Return true if building for WindowsCE */
- bool TargetsWindowsCE() const { return this->SystemIsWindowsCE; }
+ bool TargetsWindowsCE() const override { return this->SystemIsWindowsCE; }
/** Return true if building for WindowsPhone */
bool TargetsWindowsPhone() const { return this->SystemIsWindowsPhone; }
@@ -104,7 +103,7 @@ public:
std::string const& sfRel);
std::string Encoding() override;
- virtual const char* GetToolsVersion() { return "4.0"; }
+ const char* GetToolsVersion() const;
virtual bool IsDefaultToolset(const std::string& version) const;
virtual std::string GetAuxiliaryToolset() const;
@@ -140,8 +139,6 @@ protected:
virtual bool SelectWindowsPhoneToolset(std::string& toolset) const;
virtual bool SelectWindowsStoreToolset(std::string& toolset) const;
- const char* GetIDEVersion() override { return "10.0"; }
-
std::string const& GetMSBuildCommand();
cmIDEFlagTable const* LoadFlagTable(std::string const& flagTableName,
diff --git a/Source/cmGlobalVisualStudio11Generator.cxx b/Source/cmGlobalVisualStudio11Generator.cxx
index e40023d..499ae32 100644
--- a/Source/cmGlobalVisualStudio11Generator.cxx
+++ b/Source/cmGlobalVisualStudio11Generator.cxx
@@ -188,17 +188,7 @@ bool cmGlobalVisualStudio11Generator::SelectWindowsStoreToolset(
toolset);
}
-void cmGlobalVisualStudio11Generator::WriteSLNHeader(std::ostream& fout)
-{
- fout << "Microsoft Visual Studio Solution File, Format Version 12.00\n";
- if (this->ExpressEdition) {
- fout << "# Visual Studio Express 2012 for Windows Desktop\n";
- } else {
- fout << "# Visual Studio 2012\n";
- }
-}
-
-bool cmGlobalVisualStudio11Generator::UseFolderProperty()
+bool cmGlobalVisualStudio11Generator::UseFolderProperty() const
{
// Intentionally skip up to the top-level class implementation.
// Folders are not supported by the Express editions in VS10 and earlier,
diff --git a/Source/cmGlobalVisualStudio11Generator.h b/Source/cmGlobalVisualStudio11Generator.h
index 40f02fb..6346da2 100644
--- a/Source/cmGlobalVisualStudio11Generator.h
+++ b/Source/cmGlobalVisualStudio11Generator.h
@@ -26,8 +26,6 @@ public:
bool MatchesGeneratorName(const std::string& name) const override;
- void WriteSLNHeader(std::ostream& fout) override;
-
protected:
bool InitializeWindowsPhone(cmMakefile* mf) override;
bool InitializeWindowsStore(cmMakefile* mf) override;
@@ -43,8 +41,7 @@ protected:
bool IsWindowsPhoneToolsetInstalled() const;
bool IsWindowsStoreToolsetInstalled() const;
- const char* GetIDEVersion() override { return "11.0"; }
- bool UseFolderProperty();
+ bool UseFolderProperty() const override;
static std::set<std::string> GetInstalledWindowsCESDKs();
/** Return true if the configuration needs to be deployed */
diff --git a/Source/cmGlobalVisualStudio12Generator.cxx b/Source/cmGlobalVisualStudio12Generator.cxx
index 3be7d24..2cec48c 100644
--- a/Source/cmGlobalVisualStudio12Generator.cxx
+++ b/Source/cmGlobalVisualStudio12Generator.cxx
@@ -186,16 +186,6 @@ bool cmGlobalVisualStudio12Generator::SelectWindowsStoreToolset(
toolset);
}
-void cmGlobalVisualStudio12Generator::WriteSLNHeader(std::ostream& fout)
-{
- fout << "Microsoft Visual Studio Solution File, Format Version 12.00\n";
- if (this->ExpressEdition) {
- fout << "# Visual Studio Express 2013 for Windows Desktop\n";
- } else {
- fout << "# Visual Studio 2013\n";
- }
-}
-
bool cmGlobalVisualStudio12Generator::IsWindowsDesktopToolsetInstalled() const
{
const char desktop81Key[] = "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\"
diff --git a/Source/cmGlobalVisualStudio12Generator.h b/Source/cmGlobalVisualStudio12Generator.h
index 9d6554a..1b7bbc9 100644
--- a/Source/cmGlobalVisualStudio12Generator.h
+++ b/Source/cmGlobalVisualStudio12Generator.h
@@ -24,13 +24,6 @@ public:
bool MatchesGeneratorName(const std::string& name) const override;
- void WriteSLNHeader(std::ostream& fout) override;
-
- // in Visual Studio 2013 they detached the MSBuild tools version
- // from the .Net Framework version and instead made it have it's own
- // version number
- const char* GetToolsVersion() override { return "12.0"; }
-
protected:
bool ProcessGeneratorToolsetField(std::string const& key,
std::string const& value) override;
@@ -48,7 +41,6 @@ protected:
// of the toolset is installed
bool IsWindowsPhoneToolsetInstalled() const;
bool IsWindowsStoreToolsetInstalled() const;
- const char* GetIDEVersion() override { return "12.0"; }
private:
class Factory;
diff --git a/Source/cmGlobalVisualStudio14Generator.cxx b/Source/cmGlobalVisualStudio14Generator.cxx
index ac969e8..a6dbc23 100644
--- a/Source/cmGlobalVisualStudio14Generator.cxx
+++ b/Source/cmGlobalVisualStudio14Generator.cxx
@@ -174,17 +174,6 @@ bool cmGlobalVisualStudio14Generator::SelectWindowsStoreToolset(
toolset);
}
-void cmGlobalVisualStudio14Generator::WriteSLNHeader(std::ostream& fout)
-{
- // Visual Studio 14 writes .sln format 12.00
- fout << "Microsoft Visual Studio Solution File, Format Version 12.00\n";
- if (this->ExpressEdition) {
- fout << "# Visual Studio Express 14 for Windows Desktop\n";
- } else {
- fout << "# Visual Studio 14\n";
- }
-}
-
bool cmGlobalVisualStudio14Generator::IsWindowsDesktopToolsetInstalled() const
{
const char desktop10Key[] = "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\"
diff --git a/Source/cmGlobalVisualStudio14Generator.h b/Source/cmGlobalVisualStudio14Generator.h
index 9f5bb4e..4be21e0 100644
--- a/Source/cmGlobalVisualStudio14Generator.h
+++ b/Source/cmGlobalVisualStudio14Generator.h
@@ -24,10 +24,6 @@ public:
bool MatchesGeneratorName(const std::string& name) const override;
- void WriteSLNHeader(std::ostream& fout) override;
-
- const char* GetToolsVersion() override { return "14.0"; }
-
protected:
bool InitializeWindows(cmMakefile* mf) override;
bool InitializeWindowsStore(cmMakefile* mf) override;
@@ -41,7 +37,6 @@ protected:
// version of the toolset.
virtual std::string GetWindows10SDKMaxVersion() const;
- const char* GetIDEVersion() override { return "14.0"; }
virtual bool SelectWindows10SDK(cmMakefile* mf, bool required);
// Used to verify that the Desktop toolset for the current generator is
diff --git a/Source/cmGlobalVisualStudio15Generator.cxx b/Source/cmGlobalVisualStudio15Generator.cxx
index 2853283..2af17e8 100644
--- a/Source/cmGlobalVisualStudio15Generator.cxx
+++ b/Source/cmGlobalVisualStudio15Generator.cxx
@@ -29,8 +29,8 @@ class cmGlobalVisualStudio15Generator::Factory
: public cmGlobalGeneratorFactory
{
public:
- virtual cmGlobalGenerator* CreateGlobalGenerator(const std::string& name,
- cmake* cm) const
+ cmGlobalGenerator* CreateGlobalGenerator(const std::string& name,
+ cmake* cm) const override
{
std::string genName;
const char* p = cmVS15GenName(name, genName);
@@ -52,14 +52,14 @@ public:
return 0;
}
- virtual void GetDocumentation(cmDocumentationEntry& entry) const
+ void GetDocumentation(cmDocumentationEntry& entry) const override
{
entry.Name = std::string(vs15generatorName) + " [arch]";
entry.Brief = "Generates Visual Studio 2017 project files. "
"Optional [arch] can be \"Win64\" or \"ARM\".";
}
- virtual void GetGenerators(std::vector<std::string>& names) const
+ void GetGenerators(std::vector<std::string>& names) const override
{
names.push_back(vs15generatorName);
names.push_back(vs15generatorName + std::string(" ARM"));
@@ -97,17 +97,6 @@ bool cmGlobalVisualStudio15Generator::MatchesGeneratorName(
return false;
}
-void cmGlobalVisualStudio15Generator::WriteSLNHeader(std::ostream& fout)
-{
- // Visual Studio 15 writes .sln format 12.00
- fout << "Microsoft Visual Studio Solution File, Format Version 12.00\n";
- if (this->ExpressEdition) {
- fout << "# Visual Studio Express 15 for Windows Desktop\n";
- } else {
- fout << "# Visual Studio 15\n";
- }
-}
-
bool cmGlobalVisualStudio15Generator::SetGeneratorInstance(
std::string const& i, cmMakefile* mf)
{
diff --git a/Source/cmGlobalVisualStudio15Generator.h b/Source/cmGlobalVisualStudio15Generator.h
index 8ab63f1..233f3bc 100644
--- a/Source/cmGlobalVisualStudio15Generator.h
+++ b/Source/cmGlobalVisualStudio15Generator.h
@@ -24,10 +24,6 @@ public:
bool MatchesGeneratorName(const std::string& name) const override;
- void WriteSLNHeader(std::ostream& fout) override;
-
- const char* GetToolsVersion() override { return "15.0"; }
-
bool SetGeneratorInstance(std::string const& i, cmMakefile* mf) override;
bool GetVSInstance(std::string& dir) const;
@@ -39,8 +35,6 @@ protected:
bool InitializeWindows(cmMakefile* mf) override;
bool SelectWindowsStoreToolset(std::string& toolset) const override;
- const char* GetIDEVersion() override { return "15.0"; }
-
// Used to verify that the Desktop toolset for the current generator is
// installed on the machine.
bool IsWindowsDesktopToolsetInstalled() const override;
diff --git a/Source/cmGlobalVisualStudio71Generator.cxx b/Source/cmGlobalVisualStudio71Generator.cxx
index 3be09b0..8694df2 100644
--- a/Source/cmGlobalVisualStudio71Generator.cxx
+++ b/Source/cmGlobalVisualStudio71Generator.cxx
@@ -217,9 +217,3 @@ void cmGlobalVisualStudio71Generator::WriteProjectConfigurations(
}
}
}
-
-// output standard header for dsw file
-void cmGlobalVisualStudio71Generator::WriteSLNHeader(std::ostream& fout)
-{
- fout << "Microsoft Visual Studio Solution File, Format Version 8.00\n";
-}
diff --git a/Source/cmGlobalVisualStudio71Generator.h b/Source/cmGlobalVisualStudio71Generator.h
index b6e3131..85755af 100644
--- a/Source/cmGlobalVisualStudio71Generator.h
+++ b/Source/cmGlobalVisualStudio71Generator.h
@@ -34,10 +34,9 @@ protected:
void WriteExternalProject(std::ostream& fout, const std::string& name,
const char* path, const char* typeGuid,
const std::set<BT<std::string>>& depends) override;
- void WriteSLNHeader(std::ostream& fout) override;
// Folders are not supported by VS 7.1.
- virtual bool UseFolderProperty() { return false; }
+ bool UseFolderProperty() const override { return false; }
std::string ProjectConfigurationSectionName;
};
diff --git a/Source/cmGlobalVisualStudio7Generator.h b/Source/cmGlobalVisualStudio7Generator.h
index 59e7a98..f092b56 100644
--- a/Source/cmGlobalVisualStudio7Generator.h
+++ b/Source/cmGlobalVisualStudio7Generator.h
@@ -111,7 +111,6 @@ public:
protected:
void Generate() override;
- virtual const char* GetIDEVersion() = 0;
std::string const& GetDevEnvCommand();
virtual std::string FindDevEnvCommand();
@@ -135,7 +134,6 @@ protected:
virtual void WriteSLNGlobalSections(std::ostream& fout,
cmLocalGenerator* root);
virtual void WriteSLNFooter(std::ostream& fout);
- virtual void WriteSLNHeader(std::ostream& fout) = 0;
std::string WriteUtilityDepend(const cmGeneratorTarget* target) override;
virtual void WriteTargetsToSolution(
diff --git a/Source/cmGlobalVisualStudio8Generator.cxx b/Source/cmGlobalVisualStudio8Generator.cxx
index 097d7e2..ee118f1 100644
--- a/Source/cmGlobalVisualStudio8Generator.cxx
+++ b/Source/cmGlobalVisualStudio8Generator.cxx
@@ -78,7 +78,7 @@ void cmGlobalVisualStudio8Generator::Configure()
this->cmGlobalVisualStudio7Generator::Configure();
}
-bool cmGlobalVisualStudio8Generator::UseFolderProperty()
+bool cmGlobalVisualStudio8Generator::UseFolderProperty() const
{
return IsExpressEdition() ? false : cmGlobalGenerator::UseFolderProperty();
}
diff --git a/Source/cmGlobalVisualStudio8Generator.h b/Source/cmGlobalVisualStudio8Generator.h
index 6f64b9c..cacfa68 100644
--- a/Source/cmGlobalVisualStudio8Generator.h
+++ b/Source/cmGlobalVisualStudio8Generator.h
@@ -44,12 +44,8 @@ public:
return !this->WindowsCEVersion.empty();
}
- /** Is the installed VS an Express edition? */
- bool IsExpressEdition() const { return this->ExpressEdition; }
-
protected:
void AddExtraIDETargets() override;
- const char* GetIDEVersion() override { return "8.0"; }
std::string FindDevEnvCommand() override;
@@ -73,10 +69,9 @@ protected:
const char* path,
const cmGeneratorTarget* t) override;
- bool UseFolderProperty();
+ bool UseFolderProperty() const override;
std::string Name;
std::string WindowsCEVersion;
- bool ExpressEdition;
};
#endif
diff --git a/Source/cmGlobalVisualStudio9Generator.cxx b/Source/cmGlobalVisualStudio9Generator.cxx
index 7ac3a6f..760cce4 100644
--- a/Source/cmGlobalVisualStudio9Generator.cxx
+++ b/Source/cmGlobalVisualStudio9Generator.cxx
@@ -94,12 +94,6 @@ cmGlobalVisualStudio9Generator::cmGlobalVisualStudio9Generator(
vc9Express, cmSystemTools::KeyWOW64_32);
}
-void cmGlobalVisualStudio9Generator::WriteSLNHeader(std::ostream& fout)
-{
- fout << "Microsoft Visual Studio Solution File, Format Version 10.00\n";
- fout << "# Visual Studio 2008\n";
-}
-
std::string cmGlobalVisualStudio9Generator::GetUserMacrosDirectory()
{
std::string base;
diff --git a/Source/cmGlobalVisualStudio9Generator.h b/Source/cmGlobalVisualStudio9Generator.h
index 2aa6a91..e537a3d 100644
--- a/Source/cmGlobalVisualStudio9Generator.h
+++ b/Source/cmGlobalVisualStudio9Generator.h
@@ -18,12 +18,6 @@ public:
static cmGlobalGeneratorFactory* NewFactory();
/**
- * Try to determine system information such as shared library
- * extension, pthreads, byte order etc.
- */
- void WriteSLNHeader(std::ostream& fout) override;
-
- /**
* Where does this version of Visual Studio look for macros for the
* current user? Returns the empty string if this version of Visual
* Studio does not implement support for VB macros.
@@ -36,9 +30,6 @@ public:
*/
std::string GetUserMacrosRegKeyBase() override;
-protected:
- const char* GetIDEVersion() override { return "9.0"; }
-
private:
class Factory;
friend class Factory;
diff --git a/Source/cmGlobalVisualStudioGenerator.cxx b/Source/cmGlobalVisualStudioGenerator.cxx
index da3daf8..adf0a81 100644
--- a/Source/cmGlobalVisualStudioGenerator.cxx
+++ b/Source/cmGlobalVisualStudioGenerator.cxx
@@ -43,6 +43,77 @@ void cmGlobalVisualStudioGenerator::SetVersion(VSVersion v)
this->Version = v;
}
+const char* cmGlobalVisualStudioGenerator::GetIDEVersion() const
+{
+ switch (this->Version) {
+ case cmGlobalVisualStudioGenerator::VS9:
+ return "9.0";
+ case cmGlobalVisualStudioGenerator::VS10:
+ return "10.0";
+ case cmGlobalVisualStudioGenerator::VS11:
+ return "11.0";
+ case cmGlobalVisualStudioGenerator::VS12:
+ return "12.0";
+ case cmGlobalVisualStudioGenerator::VS14:
+ return "14.0";
+ case cmGlobalVisualStudioGenerator::VS15:
+ return "15.0";
+ }
+ return "";
+}
+
+void cmGlobalVisualStudioGenerator::WriteSLNHeader(std::ostream& fout)
+{
+ switch (this->Version) {
+ case cmGlobalVisualStudioGenerator::VS9:
+ fout << "Microsoft Visual Studio Solution File, Format Version 10.00\n";
+ fout << "# Visual Studio 2008\n";
+ break;
+ case cmGlobalVisualStudioGenerator::VS10:
+ fout << "Microsoft Visual Studio Solution File, Format Version 11.00\n";
+ if (this->ExpressEdition) {
+ fout << "# Visual C++ Express 2010\n";
+ } else {
+ fout << "# Visual Studio 2010\n";
+ }
+ break;
+ case cmGlobalVisualStudioGenerator::VS11:
+ fout << "Microsoft Visual Studio Solution File, Format Version 12.00\n";
+ if (this->ExpressEdition) {
+ fout << "# Visual Studio Express 2012 for Windows Desktop\n";
+ } else {
+ fout << "# Visual Studio 2012\n";
+ }
+ break;
+ case cmGlobalVisualStudioGenerator::VS12:
+ fout << "Microsoft Visual Studio Solution File, Format Version 12.00\n";
+ if (this->ExpressEdition) {
+ fout << "# Visual Studio Express 2013 for Windows Desktop\n";
+ } else {
+ fout << "# Visual Studio 2013\n";
+ }
+ break;
+ case cmGlobalVisualStudioGenerator::VS14:
+ // Visual Studio 14 writes .sln format 12.00
+ fout << "Microsoft Visual Studio Solution File, Format Version 12.00\n";
+ if (this->ExpressEdition) {
+ fout << "# Visual Studio Express 14 for Windows Desktop\n";
+ } else {
+ fout << "# Visual Studio 14\n";
+ }
+ break;
+ case cmGlobalVisualStudioGenerator::VS15:
+ // Visual Studio 15 writes .sln format 12.00
+ fout << "Microsoft Visual Studio Solution File, Format Version 12.00\n";
+ if (this->ExpressEdition) {
+ fout << "# Visual Studio Express 15 for Windows Desktop\n";
+ } else {
+ fout << "# Visual Studio 15\n";
+ }
+ break;
+ }
+}
+
std::string cmGlobalVisualStudioGenerator::GetRegistryBase()
{
return cmGlobalVisualStudioGenerator::GetRegistryBase(this->GetIDEVersion());
diff --git a/Source/cmGlobalVisualStudioGenerator.h b/Source/cmGlobalVisualStudioGenerator.h
index 07bc9a3..0d4491d 100644
--- a/Source/cmGlobalVisualStudioGenerator.h
+++ b/Source/cmGlobalVisualStudioGenerator.h
@@ -47,6 +47,9 @@ public:
VSVersion GetVersion() const;
void SetVersion(VSVersion v);
+ /** Is the installed VS an Express edition? */
+ bool IsExpressEdition() const { return this->ExpressEdition; }
+
/**
* Configure CMake's Visual Studio macros file into the user's Visual
* Studio macros directory.
@@ -118,7 +121,7 @@ public:
std::string ExpandCFGIntDir(const std::string& str,
const std::string& config) const override;
- void ComputeTargetObjectDirectory(cmGeneratorTarget* gt) const;
+ void ComputeTargetObjectDirectory(cmGeneratorTarget* gt) const override;
std::string GetStartupProjectName(cmLocalGenerator const* root) const;
@@ -137,7 +140,9 @@ protected:
// below 8.
virtual bool VSLinksDependencies() const { return true; }
- virtual const char* GetIDEVersion() = 0;
+ const char* GetIDEVersion() const;
+
+ void WriteSLNHeader(std::ostream& fout);
bool ComputeTargetDepends() override;
class VSDependSet : public std::set<std::string>
@@ -159,11 +164,12 @@ protected:
protected:
VSVersion Version;
+ bool ExpressEdition;
private:
virtual std::string GetVSMakeProgram() = 0;
void PrintCompilerAdvice(std::ostream&, std::string const&,
- const char*) const
+ const char*) const override
{
}
diff --git a/Source/cmInstallScriptGenerator.cxx b/Source/cmInstallScriptGenerator.cxx
index 7d77b7c..b93debb 100644
--- a/Source/cmInstallScriptGenerator.cxx
+++ b/Source/cmInstallScriptGenerator.cxx
@@ -2,11 +2,15 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmInstallScriptGenerator.h"
-#include "cmScriptGenerator.h"
-
#include <ostream>
#include <vector>
+#include "cmGeneratorExpression.h"
+#include "cmLocalGenerator.h"
+#include "cmPolicies.h"
+#include "cmScriptGenerator.h"
+#include "cmake.h"
+
cmInstallScriptGenerator::cmInstallScriptGenerator(const char* script,
bool code,
const char* component,
@@ -15,25 +19,71 @@ cmInstallScriptGenerator::cmInstallScriptGenerator(const char* script,
MessageDefault, exclude_from_all)
, Script(script)
, Code(code)
+ , AllowGenex(false)
{
+ // We need per-config actions if the script has generator expressions.
+ if (cmGeneratorExpression::Find(Script) != std::string::npos) {
+ this->ActionsPerConfig = true;
+ }
}
cmInstallScriptGenerator::~cmInstallScriptGenerator()
{
}
-void cmInstallScriptGenerator::GenerateScript(std::ostream& os)
+void cmInstallScriptGenerator::Compute(cmLocalGenerator* lg)
{
- Indent indent;
- std::string component_test =
- this->CreateComponentTest(this->Component.c_str(), this->ExcludeFromAll);
- os << indent << "if(" << component_test << ")\n";
+ this->LocalGenerator = lg;
+ if (this->ActionsPerConfig) {
+ switch (this->LocalGenerator->GetPolicyStatus(cmPolicies::CMP0087)) {
+ case cmPolicies::WARN:
+ this->LocalGenerator->IssueMessage(
+ cmake::AUTHOR_WARNING,
+ cmPolicies::GetPolicyWarning(cmPolicies::CMP0087));
+ CM_FALLTHROUGH;
+ case cmPolicies::OLD:
+ break;
+ case cmPolicies::NEW:
+ case cmPolicies::REQUIRED_ALWAYS:
+ case cmPolicies::REQUIRED_IF_USED:
+ this->AllowGenex = true;
+ break;
+ }
+ }
+}
+
+void cmInstallScriptGenerator::AddScriptInstallRule(std::ostream& os,
+ Indent indent,
+ std::string const& script)
+{
if (this->Code) {
- os << indent << this->Script << "\n";
+ os << indent << script << "\n";
} else {
- os << indent << "include(\"" << this->Script << "\")\n";
+ os << indent << "include(\"" << script << "\")\n";
}
+}
- os << indent << "endif()\n\n";
+void cmInstallScriptGenerator::GenerateScriptActions(std::ostream& os,
+ Indent indent)
+{
+ if (this->AllowGenex && this->ActionsPerConfig) {
+ this->cmInstallGenerator::GenerateScriptActions(os, indent);
+ } else {
+ this->AddScriptInstallRule(os, indent, this->Script);
+ }
+}
+
+void cmInstallScriptGenerator::GenerateScriptForConfig(
+ std::ostream& os, const std::string& config, Indent indent)
+{
+ if (this->AllowGenex) {
+ cmGeneratorExpression ge;
+ std::unique_ptr<cmCompiledGeneratorExpression> cge =
+ ge.Parse(this->Script);
+ this->AddScriptInstallRule(os, indent,
+ cge->Evaluate(this->LocalGenerator, config));
+ } else {
+ this->AddScriptInstallRule(os, indent, this->Script);
+ }
}
diff --git a/Source/cmInstallScriptGenerator.h b/Source/cmInstallScriptGenerator.h
index fe0f7c6..05199d7 100644
--- a/Source/cmInstallScriptGenerator.h
+++ b/Source/cmInstallScriptGenerator.h
@@ -6,10 +6,13 @@
#include "cmConfigure.h" // IWYU pragma: keep
#include "cmInstallGenerator.h"
+#include "cmScriptGenerator.h"
#include <iosfwd>
#include <string>
+class cmLocalGenerator;
+
/** \class cmInstallScriptGenerator
* \brief Generate target installation rules.
*/
@@ -20,10 +23,19 @@ public:
const char* component, bool exclude_from_all);
~cmInstallScriptGenerator() override;
+ void Compute(cmLocalGenerator* lg) override;
+
protected:
- void GenerateScript(std::ostream& os) override;
+ void GenerateScriptActions(std::ostream& os, Indent indent) override;
+ void GenerateScriptForConfig(std::ostream& os, const std::string& config,
+ Indent indent) override;
+ void AddScriptInstallRule(std::ostream& os, Indent indent,
+ std::string const& script);
+
std::string Script;
bool Code;
+ cmLocalGenerator* LocalGenerator;
+ bool AllowGenex;
};
#endif
diff --git a/Source/cmLinkedTree.h b/Source/cmLinkedTree.h
index 975f052..099fb6d 100644
--- a/Source/cmLinkedTree.h
+++ b/Source/cmLinkedTree.h
@@ -6,7 +6,6 @@
#include "cmConfigure.h" // IWYU pragma: keep
#include <assert.h>
-#include <iterator>
#include <vector>
/**
@@ -33,7 +32,7 @@ class cmLinkedTree
typedef T& ReferenceType;
public:
- class iterator : public std::iterator<std::forward_iterator_tag, T>
+ class iterator
{
friend class cmLinkedTree;
cmLinkedTree* Tree;
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index da48950..8fac039 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -2044,8 +2044,14 @@ void cmLocalGenerator::AppendPositionIndependentLinkerFlags(
return;
}
- std::string name = "CMAKE_" + lang + "_LINK_OPTIONS_";
- name += cmSystemTools::IsOn(PICValue) ? "PIE" : "NO_PIE";
+ const std::string mode = cmSystemTools::IsOn(PICValue) ? "PIE" : "NO_PIE";
+
+ std::string supported = "CMAKE_" + lang + "_LINK_" + mode + "_SUPPORTED";
+ if (cmSystemTools::IsOff(this->Makefile->GetDefinition(supported))) {
+ return;
+ }
+
+ std::string name = "CMAKE_" + lang + "_LINK_OPTIONS_" + mode;
auto pieFlags = this->Makefile->GetSafeDefinition(name);
if (pieFlags.empty()) {
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index d7c4f22..68a5101 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -1837,6 +1837,23 @@ bool cmMakefile::VariableInitialized(const std::string& var) const
return this->StateSnapshot.IsInitialized(var);
}
+void cmMakefile::MaybeWarnUninitialized(std::string const& variable,
+ const char* sourceFilename) const
+{
+ // check to see if we need to print a warning
+ // if strict mode is on and the variable has
+ // not been "cleared"/initialized with a set(foo ) call
+ if (this->GetCMakeInstance()->GetWarnUninitialized() &&
+ !this->VariableInitialized(variable)) {
+ if (this->CheckSystemVars ||
+ (sourceFilename && this->IsProjectFile(sourceFilename))) {
+ std::ostringstream msg;
+ msg << "uninitialized variable \'" << variable << "\'";
+ this->IssueMessage(cmake::AUTHOR_WARNING, msg.str());
+ }
+ }
+}
+
void cmMakefile::LogUnused(const char* reason, const std::string& name) const
{
if (this->WarnUnused) {
@@ -1848,11 +1865,7 @@ void cmMakefile::LogUnused(const char* reason, const std::string& name) const
path += "/CMakeLists.txt";
}
- if (this->CheckSystemVars ||
- cmSystemTools::IsSubDirectory(path, this->GetHomeDirectory()) ||
- (cmSystemTools::IsSubDirectory(path, this->GetHomeOutputDirectory()) &&
- !cmSystemTools::IsSubDirectory(path,
- cmake::GetCMakeFilesDirectory()))) {
+ if (this->CheckSystemVars || this->IsProjectFile(path.c_str())) {
std::ostringstream msg;
msg << "unused variable (" << reason << ") \'" << name << "\'";
this->IssueMessage(cmake::AUTHOR_WARNING, msg.str());
@@ -2509,9 +2522,9 @@ const std::string& cmMakefile::ExpandVariablesInString(
// Suppress variable watches to avoid calling hooks twice. Suppress new
// dereferences since the OLD behavior is still what is actually used.
this->SuppressSideEffects = true;
- newError = ExpandVariablesInStringNew(
- newErrorstr, newResult, escapeQuotes, noEscapes, atOnly, filename,
- line, removeEmpty, replaceAt);
+ newError = ExpandVariablesInStringNew(newErrorstr, newResult,
+ escapeQuotes, noEscapes, atOnly,
+ filename, line, replaceAt);
this->SuppressSideEffects = false;
CM_FALLTHROUGH;
}
@@ -2524,9 +2537,9 @@ const std::string& cmMakefile::ExpandVariablesInString(
case cmPolicies::REQUIRED_ALWAYS:
// Messaging here would be *very* verbose.
case cmPolicies::NEW:
- mtype = ExpandVariablesInStringNew(errorstr, source, escapeQuotes,
- noEscapes, atOnly, filename, line,
- removeEmpty, replaceAt);
+ mtype =
+ ExpandVariablesInStringNew(errorstr, source, escapeQuotes, noEscapes,
+ atOnly, filename, line, replaceAt);
break;
}
@@ -2702,10 +2715,18 @@ struct t_lookup
size_t loc = 0;
};
+bool cmMakefile::IsProjectFile(const char* filename) const
+{
+ return cmSystemTools::IsSubDirectory(filename, this->GetHomeDirectory()) ||
+ (cmSystemTools::IsSubDirectory(filename, this->GetHomeOutputDirectory()) &&
+ !cmSystemTools::IsSubDirectory(filename,
+ cmake::GetCMakeFilesDirectory()));
+}
+
cmake::MessageType cmMakefile::ExpandVariablesInStringNew(
std::string& errorstr, std::string& source, bool escapeQuotes,
bool noEscapes, bool atOnly, const char* filename, long line,
- bool removeEmpty, bool replaceAt) const
+ bool replaceAt) const
{
// This method replaces ${VAR} and @VAR@ where VAR is looked up
// with GetDefinition(), if not found in the map, nothing is expanded.
@@ -2762,23 +2783,8 @@ cmake::MessageType cmMakefile::ExpandVariablesInStringNew(
} else {
varresult = value;
}
- } else if (!removeEmpty && !this->SuppressSideEffects) {
- // check to see if we need to print a warning
- // if strict mode is on and the variable has
- // not been "cleared"/initialized with a set(foo ) call
- if (this->GetCMakeInstance()->GetWarnUninitialized() &&
- !this->VariableInitialized(lookup)) {
- if (this->CheckSystemVars ||
- (filename &&
- (cmSystemTools::IsSubDirectory(filename,
- this->GetHomeDirectory()) ||
- cmSystemTools::IsSubDirectory(
- filename, this->GetHomeOutputDirectory())))) {
- std::ostringstream msg;
- msg << "uninitialized variable \'" << lookup << "\'";
- this->IssueMessage(cmake::AUTHOR_WARNING, msg.str());
- }
- }
+ } else if (!this->SuppressSideEffects) {
+ this->MaybeWarnUninitialized(lookup, filename);
}
result.replace(var.loc, result.size() - var.loc, varresult);
// Start looking from here on out.
@@ -2890,7 +2896,12 @@ cmake::MessageType cmMakefile::ExpandVariablesInStringNew(
if (filename && variable == lineVar) {
varresult = std::to_string(line);
} else {
- varresult = this->GetSafeDefinition(variable);
+ const std::string* def = this->GetDef(variable);
+ if (def) {
+ varresult = *def;
+ } else if (!this->SuppressSideEffects) {
+ this->MaybeWarnUninitialized(variable, filename);
+ }
}
if (escapeQuotes) {
diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h
index aa94054..1607735 100644
--- a/Source/cmMakefile.h
+++ b/Source/cmMakefile.h
@@ -866,6 +866,9 @@ public:
std::deque<std::vector<std::string>> FindPackageRootPathStack;
void MaybeWarnCMP0074(std::string const& pkg);
+ void MaybeWarnUninitialized(std::string const& variable,
+ const char* sourceFilename) const;
+ bool IsProjectFile(const char* filename) const;
protected:
// add link libraries and directories to the target
@@ -987,7 +990,7 @@ private:
cmake::MessageType ExpandVariablesInStringNew(
std::string& errorstr, std::string& source, bool escapeQuotes,
bool noEscapes, bool atOnly, const char* filename, long line,
- bool removeEmpty, bool replaceAt) const;
+ bool replaceAt) const;
/**
* Old version of GetSourceFileWithOutput(const std::string&) kept for
* backward-compatibility. It implements a linear search and support
diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx
index cb41c28..d1dcd81 100644
--- a/Source/cmMakefileTargetGenerator.cxx
+++ b/Source/cmMakefileTargetGenerator.cxx
@@ -687,6 +687,17 @@ void cmMakefileTargetGenerator::WriteObjectBuildFile(
std::string langIncludes = std::string("$(") + lang + "_INCLUDES)";
compileCommand.replace(compileCommand.find(langIncludes),
langIncludes.size(), this->GetIncludes(lang));
+
+ const char* eliminate[] = {
+ this->Makefile->GetDefinition("CMAKE_START_TEMP_FILE"),
+ this->Makefile->GetDefinition("CMAKE_END_TEMP_FILE")
+ };
+ for (const char* el : eliminate) {
+ if (el) {
+ cmSystemTools::ReplaceString(compileCommand, el, "");
+ }
+ }
+
this->GlobalGenerator->AddCXXCompileCommand(
source.GetFullPath(), workingDirectory, compileCommand);
}
diff --git a/Source/cmMessenger.cxx b/Source/cmMessenger.cxx
index a81428a..880cf4b 100644
--- a/Source/cmMessenger.cxx
+++ b/Source/cmMessenger.cxx
@@ -4,7 +4,6 @@
#include "cmAlgorithms.h"
#include "cmDocumentationFormatter.h"
-#include "cmState.h"
#include "cmSystemTools.h"
#if defined(CMAKE_BUILD_WITH_CMAKE)
@@ -131,11 +130,6 @@ void displayMessage(cmake::MessageType t, std::ostringstream& msg)
}
}
-cmMessenger::cmMessenger(cmState* state)
- : State(state)
-{
-}
-
void cmMessenger::IssueMessage(cmake::MessageType t, const std::string& text,
const cmListFileBacktrace& backtrace) const
{
@@ -173,31 +167,3 @@ void cmMessenger::DisplayMessage(cmake::MessageType t, const std::string& text,
displayMessage(t, msg);
}
-
-bool cmMessenger::GetSuppressDevWarnings() const
-{
- const char* cacheEntryValue =
- this->State->GetCacheEntryValue("CMAKE_SUPPRESS_DEVELOPER_WARNINGS");
- return cmSystemTools::IsOn(cacheEntryValue);
-}
-
-bool cmMessenger::GetSuppressDeprecatedWarnings() const
-{
- const char* cacheEntryValue =
- this->State->GetCacheEntryValue("CMAKE_WARN_DEPRECATED");
- return cacheEntryValue && cmSystemTools::IsOff(cacheEntryValue);
-}
-
-bool cmMessenger::GetDevWarningsAsErrors() const
-{
- const char* cacheEntryValue =
- this->State->GetCacheEntryValue("CMAKE_SUPPRESS_DEVELOPER_ERRORS");
- return cacheEntryValue && cmSystemTools::IsOff(cacheEntryValue);
-}
-
-bool cmMessenger::GetDeprecatedWarningsAsErrors() const
-{
- const char* cacheEntryValue =
- this->State->GetCacheEntryValue("CMAKE_ERROR_DEPRECATED");
- return cmSystemTools::IsOn(cacheEntryValue);
-}
diff --git a/Source/cmMessenger.h b/Source/cmMessenger.h
index 4aafbd4..e947eaa 100644
--- a/Source/cmMessenger.h
+++ b/Source/cmMessenger.h
@@ -10,13 +10,9 @@
#include <string>
-class cmState;
-
class cmMessenger
{
public:
- cmMessenger(cmState* state);
-
void IssueMessage(
cmake::MessageType t, std::string const& text,
cmListFileBacktrace const& backtrace = cmListFileBacktrace()) const;
@@ -24,16 +20,42 @@ public:
void DisplayMessage(cmake::MessageType t, std::string const& text,
cmListFileBacktrace const& backtrace) const;
- bool GetSuppressDevWarnings() const;
- bool GetSuppressDeprecatedWarnings() const;
- bool GetDevWarningsAsErrors() const;
- bool GetDeprecatedWarningsAsErrors() const;
+ void SetSuppressDevWarnings(bool suppress)
+ {
+ this->SuppressDevWarnings = suppress;
+ }
+ void SetSuppressDeprecatedWarnings(bool suppress)
+ {
+ this->SuppressDeprecatedWarnings = suppress;
+ }
+ void SetDevWarningsAsErrors(bool error)
+ {
+ this->DevWarningsAsErrors = error;
+ }
+ void SetDeprecatedWarningsAsErrors(bool error)
+ {
+ this->DeprecatedWarningsAsErrors = error;
+ }
+
+ bool GetSuppressDevWarnings() const { return this->SuppressDevWarnings; }
+ bool GetSuppressDeprecatedWarnings() const
+ {
+ return this->SuppressDeprecatedWarnings;
+ }
+ bool GetDevWarningsAsErrors() const { return this->DevWarningsAsErrors; }
+ bool GetDeprecatedWarningsAsErrors() const
+ {
+ return this->DeprecatedWarningsAsErrors;
+ }
private:
bool IsMessageTypeVisible(cmake::MessageType t) const;
cmake::MessageType ConvertMessageType(cmake::MessageType t) const;
- cmState* State;
+ bool SuppressDevWarnings = false;
+ bool SuppressDeprecatedWarnings = false;
+ bool DevWarningsAsErrors = false;
+ bool DeprecatedWarningsAsErrors = false;
};
#endif
diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h
index 7674877..206dd3d 100644
--- a/Source/cmPolicies.h
+++ b/Source/cmPolicies.h
@@ -254,7 +254,11 @@ class cmMakefile;
0, cmPolicies::WARN) \
SELECT(POLICY, CMP0086, \
"UseSWIG honors SWIG_MODULE_NAME via -module flag.", 3, 14, 0, \
- cmPolicies::WARN)
+ cmPolicies::WARN) \
+ SELECT(POLICY, CMP0087, \
+ "Install CODE|SCRIPT allow the use of generator " \
+ "expressions.", \
+ 3, 14, 0, cmPolicies::WARN)
#define CM_SELECT_ID(F, A1, A2, A3, A4, A5, A6) F(A1)
#define CM_FOR_EACH_POLICY_ID(POLICY) \
diff --git a/Source/cmQtAutoGenGlobalInitializer.cxx b/Source/cmQtAutoGenGlobalInitializer.cxx
index 5470ec3..678ff14 100644
--- a/Source/cmQtAutoGenGlobalInitializer.cxx
+++ b/Source/cmQtAutoGenGlobalInitializer.cxx
@@ -75,13 +75,26 @@ cmQtAutoGenGlobalInitializer::cmQtAutoGenGlobalInitializer(
bool const uic = target->GetPropertyAsBool("AUTOUIC");
bool const rcc = target->GetPropertyAsBool("AUTORCC");
if (moc || uic || rcc) {
- // We support Qt4 and Qt5
+ std::string const mocExec =
+ target->GetSafeProperty("AUTOMOC_EXECUTABLE");
+ std::string const uicExec =
+ target->GetSafeProperty("AUTOUIC_EXECUTABLE");
+ std::string const rccExec =
+ target->GetSafeProperty("AUTORCC_EXECUTABLE");
+
+ // We support Qt4, Qt5 and Qt6
auto qtVersion = cmQtAutoGenInitializer::GetQtVersion(target);
- if ((qtVersion.Major == 4) || (qtVersion.Major == 5)) {
+ bool const validQt = (qtVersion.Major == 4) ||
+ (qtVersion.Major == 5) || (qtVersion.Major == 6);
+ bool const mocIsValid = moc && (validQt || !mocExec.empty());
+ bool const uicIsValid = uic && (validQt || !uicExec.empty());
+ bool const rccIsValid = rcc && (validQt || !rccExec.empty());
+
+ if (mocIsValid || uicIsValid || rccIsValid) {
// Create autogen target initializer
Initializers_.emplace_back(cm::make_unique<cmQtAutoGenInitializer>(
- this, target, qtVersion, moc, uic, rcc, globalAutoGenTarget,
- globalAutoRccTarget));
+ this, target, qtVersion, mocIsValid, uicIsValid, rccIsValid,
+ globalAutoGenTarget, globalAutoRccTarget));
}
}
}
diff --git a/Source/cmQtAutoGenInitializer.cxx b/Source/cmQtAutoGenInitializer.cxx
index 6a2a951..e4d2c82 100644
--- a/Source/cmQtAutoGenInitializer.cxx
+++ b/Source/cmQtAutoGenInitializer.cxx
@@ -9,6 +9,7 @@
#include "cmCustomCommandLines.h"
#include "cmDuration.h"
#include "cmFilePathChecksum.h"
+#include "cmGeneratorExpression.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h"
#include "cmLinkItem.h"
@@ -42,6 +43,9 @@
std::string GetQtExecutableTargetName(
const cmQtAutoGen::IntegerVersion& qtVersion, std::string const& executable)
{
+ if (qtVersion.Major == 6) {
+ return ("Qt6::" + executable);
+ }
if (qtVersion.Major == 5) {
return ("Qt5::" + executable);
}
@@ -395,8 +399,16 @@ bool cmQtAutoGenInitializer::InitCustomTargets()
}
// Init uic specific settings
- if (this->Uic.Enabled && !InitUic()) {
- return false;
+ if (this->Uic.Enabled) {
+ if (InitUic()) {
+ auto* uicTarget = makefile->FindTargetToUse(
+ GetQtExecutableTargetName(this->QtVersion, "uic"));
+ if (uicTarget != nullptr) {
+ this->AutogenTarget.DependTargets.insert(uicTarget);
+ }
+ } else {
+ return false;
+ }
}
// Autogen target name
@@ -437,6 +449,12 @@ bool cmQtAutoGenInitializer::InitCustomTargets()
this->AutogenTarget.DependOrigin =
this->Target->GetPropertyAsBool("AUTOGEN_ORIGIN_DEPENDS");
+ auto* mocTarget = makefile->FindTargetToUse(
+ GetQtExecutableTargetName(this->QtVersion, "moc"));
+ if (mocTarget != nullptr) {
+ this->AutogenTarget.DependTargets.insert(mocTarget);
+ }
+
std::string const deps =
this->Target->GetSafeProperty("AUTOGEN_TARGET_DEPENDS");
if (!deps.empty()) {
@@ -504,7 +522,7 @@ bool cmQtAutoGenInitializer::InitMoc()
{
// We need to disable this until we have all implicit includes available.
// See issue #18669.
- // bool const appendImplicit = (this->QtVersion.Major == 5);
+ // bool const appendImplicit = (this->QtVersion.Major >= 5);
auto GetIncludeDirs =
[this, localGen](std::string const& cfg) -> std::vector<std::string> {
@@ -839,7 +857,7 @@ bool cmQtAutoGenInitializer::InitScanFiles()
// Process qrc files
if (!this->Rcc.Qrcs.empty()) {
- const bool QtV5 = (this->QtVersion.Major == 5);
+ const bool modernQt = (this->QtVersion.Major >= 5);
// Target rcc options
std::vector<std::string> optionsTarget;
cmSystemTools::ExpandListArgument(
@@ -911,10 +929,10 @@ bool cmQtAutoGenInitializer::InitScanFiles()
std::vector<std::string> nameOpts;
nameOpts.emplace_back("-name");
nameOpts.emplace_back(std::move(name));
- RccMergeOptions(opts, nameOpts, QtV5);
+ RccMergeOptions(opts, nameOpts, modernQt);
}
// Merge file option
- RccMergeOptions(opts, qrc.Options, QtV5);
+ RccMergeOptions(opts, qrc.Options, modernQt);
qrc.Options = std::move(opts);
}
// RCC resources
@@ -1092,6 +1110,7 @@ bool cmQtAutoGenInitializer::InitRccTargets()
{
cmMakefile* makefile = this->Target->Target->GetMakefile();
cmLocalGenerator* localGen = this->Target->GetLocalGenerator();
+ auto rccTargetName = GetQtExecutableTargetName(this->QtVersion, "rcc");
for (Qrc const& qrc : this->Rcc.Qrcs) {
// Register info file as generated by CMake
@@ -1102,6 +1121,11 @@ bool cmQtAutoGenInitializer::InitRccTargets()
std::vector<std::string> ccOutput;
ccOutput.push_back(qrc.RccFile);
+ std::vector<std::string> ccDepends;
+ // Add the .qrc and info file to the custom command dependencies
+ ccDepends.push_back(qrc.QrcFile);
+ ccDepends.push_back(qrc.InfoFile);
+
cmCustomCommandLines commandLines;
if (this->MultiConfig) {
// Build for all configurations
@@ -1137,15 +1161,12 @@ bool cmQtAutoGenInitializer::InitRccTargets()
ccName += "_";
ccName += qrc.PathChecksum;
}
- std::vector<std::string> ccDepends;
- // Add the .qrc and info file to the custom target dependencies
- ccDepends.push_back(qrc.QrcFile);
- ccDepends.push_back(qrc.InfoFile);
cmTarget* autoRccTarget = makefile->AddUtilityCommand(
ccName, cmMakefile::TargetOrigin::Generator, true,
this->Dir.Work.c_str(), ccOutput, ccDepends, commandLines, false,
ccComment.c_str());
+
// Create autogen generator target
localGen->AddGeneratorTarget(
new cmGeneratorTarget(autoRccTarget, localGen));
@@ -1154,6 +1175,9 @@ bool cmQtAutoGenInitializer::InitRccTargets()
if (!this->TargetsFolder.empty()) {
autoRccTarget->SetProperty("FOLDER", this->TargetsFolder.c_str());
}
+ if (!rccTargetName.empty()) {
+ autoRccTarget->AddUtility(rccTargetName, makefile);
+ }
}
// Add autogen target to the origin target dependencies
this->Target->Target->AddUtility(ccName, makefile);
@@ -1166,16 +1190,15 @@ bool cmQtAutoGenInitializer::InitRccTargets()
// Create custom rcc command
{
std::vector<std::string> ccByproducts;
- std::vector<std::string> ccDepends;
- // Add the .qrc and info file to the custom command dependencies
- ccDepends.push_back(qrc.QrcFile);
- ccDepends.push_back(qrc.InfoFile);
// Add the resource files to the dependencies
for (std::string const& fileName : qrc.Resources) {
// Add resource file to the custom command dependencies
ccDepends.push_back(fileName);
}
+ if (!rccTargetName.empty()) {
+ ccDepends.push_back(rccTargetName);
+ }
makefile->AddCustomCommandToOutput(ccOutput, ccByproducts, ccDepends,
/*main_dependency*/ std::string(),
commandLines, ccComment.c_str(),
@@ -1374,7 +1397,7 @@ static std::vector<cmQtAutoGenInitializer::IntegerVersion> GetKnownQtVersions(
std::vector<cmQtAutoGenInitializer::IntegerVersion> result;
for (const std::string& prefix :
- std::vector<std::string>({ "Qt5Core", "QT" })) {
+ std::vector<std::string>({ "Qt6Core", "Qt5Core", "QT" })) {
auto tmp = cmQtAutoGenInitializer::IntegerVersion(
StringToInt(makefile->GetSafeDefinition(prefix + "_VERSION_MAJOR")),
StringToInt(makefile->GetSafeDefinition(prefix + "_VERSION_MINOR")));
@@ -1418,21 +1441,36 @@ std::pair<bool, std::string> GetQtExecutable(
const cmQtAutoGen::IntegerVersion& qtVersion, cmGeneratorTarget* target,
const std::string& executable, bool ignoreMissingTarget, std::string* output)
{
+ const std::string upperExecutable = cmSystemTools::UpperCase(executable);
+ std::string result =
+ target->Target->GetSafeProperty("AUTO" + upperExecutable + "_EXECUTABLE");
+ if (!result.empty()) {
+ cmListFileBacktrace lfbt = target->Target->GetMakefile()->GetBacktrace();
+ cmGeneratorExpression ge(lfbt);
+ std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(result);
+ result = cge->Evaluate(target->GetLocalGenerator(), "");
+
+ return std::make_pair(true, result);
+ }
+
std::string err;
- std::string result;
// Find executable
{
const std::string targetName =
GetQtExecutableTargetName(qtVersion, executable);
if (targetName.empty()) {
- err = "The AUTOMOC, AUTOUIC and AUTORCC feature ";
- err += "supports only Qt 4 and Qt 5";
+ err = "The AUTO" + upperExecutable + " feature ";
+ err += "supports only Qt 4, Qt 5 and Qt 6.";
} else {
cmLocalGenerator* localGen = target->GetLocalGenerator();
cmGeneratorTarget* tgt = localGen->FindGeneratorTargetToUse(targetName);
if (tgt != nullptr) {
- result = tgt->ImportedGetLocation("");
+ if (tgt->IsImported()) {
+ result = tgt->ImportedGetLocation("");
+ } else {
+ result = tgt->GetLocation("");
+ }
} else {
if (ignoreMissingTarget) {
return std::make_pair(true, "");
@@ -1510,7 +1548,7 @@ bool cmQtAutoGenInitializer::GetRccExecutable()
return false;
}
- if (this->QtVersion.Major == 5) {
+ if (this->QtVersion.Major == 5 || this->QtVersion.Major == 6) {
if (stdOut.find("--list") != std::string::npos) {
this->Rcc.ListOptions.push_back("--list");
} else {
diff --git a/Source/cmTestGenerator.cxx b/Source/cmTestGenerator.cxx
index 796d2df..e4ced6e 100644
--- a/Source/cmTestGenerator.cxx
+++ b/Source/cmTestGenerator.cxx
@@ -7,14 +7,16 @@
#include "cmGeneratorExpression.h"
#include "cmGeneratorTarget.h"
+#include "cmListFileCache.h"
#include "cmLocalGenerator.h"
#include "cmOutputConverter.h"
#include "cmProperty.h"
-#include "cmPropertyMap.h"
#include "cmStateTypes.h"
#include "cmSystemTools.h"
#include "cmTest.h"
+class cmPropertyMap;
+
cmTestGenerator::cmTestGenerator(
cmTest* test, std::vector<std::string> const& configurations)
: cmScriptGenerator("CTEST_CONFIGURATION_TYPE", configurations)
@@ -121,16 +123,15 @@ void cmTestGenerator::GenerateScriptForConfig(std::ostream& os,
// Output properties for the test.
cmPropertyMap& pm = this->Test->GetProperties();
- if (!pm.empty()) {
- os << indent << "set_tests_properties(" << this->Test->GetName()
- << " PROPERTIES ";
- for (auto const& i : pm) {
- os << " " << i.first << " "
- << cmOutputConverter::EscapeForCMake(
- ge.Parse(i.second.GetValue())->Evaluate(this->LG, config));
- }
- os << ")" << std::endl;
+ os << indent << "set_tests_properties(" << this->Test->GetName()
+ << " PROPERTIES ";
+ for (auto const& i : pm) {
+ os << " " << i.first << " "
+ << cmOutputConverter::EscapeForCMake(
+ ge.Parse(i.second.GetValue())->Evaluate(this->LG, config));
}
+ this->GenerateInternalProperties(os);
+ os << ")" << std::endl;
}
void cmTestGenerator::GenerateScriptNoConfig(std::ostream& os, Indent indent)
@@ -179,13 +180,37 @@ void cmTestGenerator::GenerateOldStyle(std::ostream& fout, Indent indent)
// Output properties for the test.
cmPropertyMap& pm = this->Test->GetProperties();
- if (!pm.empty()) {
- fout << indent << "set_tests_properties(" << this->Test->GetName()
- << " PROPERTIES ";
- for (auto const& i : pm) {
- fout << " " << i.first << " "
- << cmOutputConverter::EscapeForCMake(i.second.GetValue());
+ fout << indent << "set_tests_properties(" << this->Test->GetName()
+ << " PROPERTIES ";
+ for (auto const& i : pm) {
+ fout << " " << i.first << " "
+ << cmOutputConverter::EscapeForCMake(i.second.GetValue());
+ }
+ this->GenerateInternalProperties(fout);
+ fout << ")" << std::endl;
+}
+
+void cmTestGenerator::GenerateInternalProperties(std::ostream& os)
+{
+ cmListFileBacktrace bt = this->Test->GetBacktrace();
+ if (bt.Empty()) {
+ return;
+ }
+
+ os << " "
+ << "_BACKTRACE_TRIPLES"
+ << " \"";
+
+ bool prependTripleSeparator = false;
+ while (!bt.Empty()) {
+ const auto& entry = bt.Top();
+ if (prependTripleSeparator) {
+ os << ";";
}
- fout << ")" << std::endl;
+ os << entry.FilePath << ";" << entry.Line << ";" << entry.Name;
+ bt = bt.Pop();
+ prependTripleSeparator = true;
}
+
+ os << "\"";
}
diff --git a/Source/cmTestGenerator.h b/Source/cmTestGenerator.h
index 73d05a3..f26d2ff 100644
--- a/Source/cmTestGenerator.h
+++ b/Source/cmTestGenerator.h
@@ -35,6 +35,9 @@ public:
cmTest* GetTest() const;
+private:
+ void GenerateInternalProperties(std::ostream& os);
+
protected:
void GenerateScriptConfigs(std::ostream& os, Indent indent) override;
void GenerateScriptActions(std::ostream& os, Indent indent) override;
diff --git a/Source/cmVSSetupHelper.cxx b/Source/cmVSSetupHelper.cxx
index 7a54e12..d80b5a2 100644
--- a/Source/cmVSSetupHelper.cxx
+++ b/Source/cmVSSetupHelper.cxx
@@ -328,6 +328,9 @@ bool cmVSSetupAPIHelper::EnumerateAndChooseVSInstance()
return false;
}
+ // FIXME: Add a way for caller to specify other versions.
+ std::wstring wantVersion = std::to_wstring(15) + L'.';
+
SmartCOMPtr<ISetupInstance> instance;
while (SUCCEEDED(enumInstances->Next(1, &instance, NULL)) && instance) {
SmartCOMPtr<ISetupInstance2> instance2 = NULL;
@@ -343,6 +346,12 @@ bool cmVSSetupAPIHelper::EnumerateAndChooseVSInstance()
instance = instance2 = NULL;
if (isInstalled) {
+ // We are looking for a specific major version.
+ if (instanceInfo.Version.size() < wantVersion.size() ||
+ instanceInfo.Version.substr(0, wantVersion.size()) != wantVersion) {
+ continue;
+ }
+
if (!this->SpecifiedVSInstallLocation.empty()) {
// We are looking for a specific instance.
std::string currentVSLocation = instanceInfo.GetInstallLocation();
diff --git a/Source/cmVisualStudioGeneratorOptions.cxx b/Source/cmVisualStudioGeneratorOptions.cxx
index 5d67dcf..afe9230 100644
--- a/Source/cmVisualStudioGeneratorOptions.cxx
+++ b/Source/cmVisualStudioGeneratorOptions.cxx
@@ -269,7 +269,7 @@ void cmVisualStudioGeneratorOptions::FixManifestUACFlags()
if (keyValue[1].front() == '\'' && keyValue[1].back() == '\'') {
keyValue[1] =
- keyValue[1].substr(1, std::max<int>(0, keyValue[1].size() - 2));
+ keyValue[1].substr(1, std::max(0, cm::isize(keyValue[1]) - 2));
}
if (keyValue[0] == "level") {
diff --git a/Source/cmWriteFileCommand.cxx b/Source/cmWriteFileCommand.cxx
index c504ef4..49dbf1a 100644
--- a/Source/cmWriteFileCommand.cxx
+++ b/Source/cmWriteFileCommand.cxx
@@ -50,7 +50,7 @@ bool cmWriteFileCommand::InitialPass(std::vector<std::string> const& args,
// Set permissions to writable
if (cmSystemTools::GetPermissions(fileName.c_str(), mode)) {
#if defined(_MSC_VER) || defined(__MINGW32__)
- writable = mode & S_IWRITE;
+ writable = (mode & S_IWRITE) != 0;
mode_t newMode = mode | S_IWRITE;
#else
writable = mode & S_IWUSR;
diff --git a/Source/cmake.cxx b/Source/cmake.cxx
index e81d14b..e1bae34 100644
--- a/Source/cmake.cxx
+++ b/Source/cmake.cxx
@@ -141,7 +141,7 @@ cmake::cmake(Role role)
this->State = new cmState;
this->CurrentSnapshot = this->State->CreateBaseSnapshot();
- this->Messenger = new cmMessenger(this->State);
+ this->Messenger = new cmMessenger;
#ifdef __APPLE__
struct rlimit rlp;
@@ -1300,6 +1300,23 @@ int cmake::Configure()
}
}
+ // Cache variables may have already been set by a previous invocation,
+ // so we cannot rely on command line options alone. Always ensure our
+ // messenger is in sync with the cache.
+ const char* value = this->State->GetCacheEntryValue("CMAKE_WARN_DEPRECATED");
+ this->Messenger->SetSuppressDeprecatedWarnings(value &&
+ cmSystemTools::IsOff(value));
+
+ value = this->State->GetCacheEntryValue("CMAKE_ERROR_DEPRECATED");
+ this->Messenger->SetDeprecatedWarningsAsErrors(cmSystemTools::IsOn(value));
+
+ value = this->State->GetCacheEntryValue("CMAKE_SUPPRESS_DEVELOPER_WARNINGS");
+ this->Messenger->SetSuppressDevWarnings(cmSystemTools::IsOn(value));
+
+ value = this->State->GetCacheEntryValue("CMAKE_SUPPRESS_DEVELOPER_ERRORS");
+ this->Messenger->SetDevWarningsAsErrors(value &&
+ cmSystemTools::IsOff(value));
+
int ret = this->ActualConfigure();
const char* delCacheVars =
this->State->GetGlobalProperty("__CMAKE_DELETE_CACHE_CHANGE_VARS_");
@@ -1511,7 +1528,6 @@ void cmake::CreateDefaultGlobalGenerator()
const char* GeneratorName;
};
static VSVersionedGenerator const vsGenerators[] = {
- { "15.0", "Visual Studio 15 2017" }, //
{ "14.0", "Visual Studio 14 2015" }, //
{ "12.0", "Visual Studio 12 2013" }, //
{ "11.0", "Visual Studio 11 2012" }, //
@@ -1701,6 +1717,18 @@ void cmake::AddCacheEntry(const std::string& key, const char* value,
this->State->AddCacheEntry(key, value, helpString,
cmStateEnums::CacheEntryType(type));
this->UnwatchUnusedCli(key);
+
+ if (key == "CMAKE_WARN_DEPRECATED") {
+ this->Messenger->SetSuppressDeprecatedWarnings(
+ value && cmSystemTools::IsOff(value));
+ } else if (key == "CMAKE_ERROR_DEPRECATED") {
+ this->Messenger->SetDeprecatedWarningsAsErrors(cmSystemTools::IsOn(value));
+ } else if (key == "CMAKE_SUPPRESS_DEVELOPER_WARNINGS") {
+ this->Messenger->SetSuppressDevWarnings(cmSystemTools::IsOn(value));
+ } else if (key == "CMAKE_SUPPRESS_DEVELOPER_ERRORS") {
+ this->Messenger->SetDevWarningsAsErrors(value &&
+ cmSystemTools::IsOff(value));
+ }
}
bool cmake::DoWriteGlobVerifyTarget() const
diff --git a/Source/cmparseMSBuildXML.py b/Source/cmparseMSBuildXML.py
deleted file mode 100755
index 1b38d15..0000000
--- a/Source/cmparseMSBuildXML.py
+++ /dev/null
@@ -1,341 +0,0 @@
-# This python script parses the spec files from MSBuild to create
-# mappings from compiler options to IDE XML specifications. For
-# more information see here:
-
-# http://blogs.msdn.com/vcblog/archive/2008/12/16/msbuild-task.aspx
-# "${PROGRAMFILES}/MSBuild/Microsoft.Cpp/v4.0/1033/cl.xml"
-# "${PROGRAMFILES}/MSBuild/Microsoft.Cpp/v4.0/1033/lib.xml"
-# "${PROGRAMFILES}/MSBuild/Microsoft.Cpp/v4.0/1033/link.xml"
-# "${PROGRAMFILES}/MSBuild/Microsoft.Cpp/v4.0/V110/1033/cl.xml"
-# "${PROGRAMFILES}/MSBuild/Microsoft.Cpp/v4.0/V110/1033/lib.xml"
-# "${PROGRAMFILES}/MSBuild/Microsoft.Cpp/v4.0/V110/1033/link.xml"
-# "${PROGRAMFILES}/MSBuild/Microsoft.Cpp/v4.0/v120/1033/cl.xml"
-# "${PROGRAMFILES}/MSBuild/Microsoft.Cpp/v4.0/v120/1033/lib.xml"
-# "${PROGRAMFILES}/MSBuild/Microsoft.Cpp/v4.0/v120/1033/link.xml"
-# "${PROGRAMFILES}/MSBuild/Microsoft.Cpp/v4.0/V140/1033/cl.xml"
-# "${PROGRAMFILES}/MSBuild/Microsoft.Cpp/v4.0/V140/1033/lib.xml"
-# "${PROGRAMFILES}/MSBuild/Microsoft.Cpp/v4.0/V140/1033/link.xml"
-# "${PROGRAMFILES}/Microsoft Visual Studio/VS15Preview/Common7/IDE/VC/VCTargets/1033/cl.xml"
-# "${PROGRAMFILES}/Microsoft Visual Studio/VS15Preview/Common7/IDE/VC/VCTargets/1033/lib.xml"
-# "${PROGRAMFILES}/Microsoft Visual Studio/VS15Preview/Common7/IDE/VC/VCTargets/1033/link.xml"
-#
-# BoolProperty <Name>true|false</Name>
-# simple example:
-# <BoolProperty ReverseSwitch="Oy-" Name="OmitFramePointers"
-# Category="Optimization" Switch="Oy">
-# <BoolProperty.DisplayName> <BoolProperty.Description>
-# <CLCompile>
-# <OmitFramePointers>true</OmitFramePointers>
-# </ClCompile>
-#
-# argument means it might be this: /MP3
-# example with argument:
-# <BoolProperty Name="MultiProcessorCompilation" Category="General" Switch="MP">
-# <BoolProperty.DisplayName>
-# <sys:String>Multi-processor Compilation</sys:String>
-# </BoolProperty.DisplayName>
-# <BoolProperty.Description>
-# <sys:String>Multi-processor Compilation</sys:String>
-# </BoolProperty.Description>
-# <Argument Property="ProcessorNumber" IsRequired="false" />
-# </BoolProperty>
-# <CLCompile>
-# <MultiProcessorCompilation>true</MultiProcessorCompilation>
-# <ProcessorNumber>4</ProcessorNumber>
-# </ClCompile>
-# IntProperty
-# not used AFIT
-# <IntProperty Name="ProcessorNumber" Category="General" Visible="false">
-
-
-# per config options example
-# <EnableFiberSafeOptimizations Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</EnableFiberSafeOptimizations>
-#
-# EnumProperty
-# <EnumProperty Name="Optimization" Category="Optimization">
-# <EnumProperty.DisplayName>
-# <sys:String>Optimization</sys:String>
-# </EnumProperty.DisplayName>
-# <EnumProperty.Description>
-# <sys:String>Select option for code optimization; choose Custom to use specific optimization options. (/Od, /O1, /O2, /Ox)</sys:String>
-# </EnumProperty.Description>
-# <EnumValue Name="MaxSpeed" Switch="O2">
-# <EnumValue.DisplayName>
-# <sys:String>Maximize Speed</sys:String>
-# </EnumValue.DisplayName>
-# <EnumValue.Description>
-# <sys:String>Equivalent to /Og /Oi /Ot /Oy /Ob2 /Gs /GF /Gy</sys:String>
-# </EnumValue.Description>
-# </EnumValue>
-# <EnumValue Name="MinSpace" Switch="O1">
-# <EnumValue.DisplayName>
-# <sys:String>Minimize Size</sys:String>
-# </EnumValue.DisplayName>
-# <EnumValue.Description>
-# <sys:String>Equivalent to /Og /Os /Oy /Ob2 /Gs /GF /Gy</sys:String>
-# </EnumValue.Description>
-# </EnumValue>
-# example for O2 would be this:
-# <Optimization>MaxSpeed</Optimization>
-# example for O1 would be this:
-# <Optimization>MinSpace</Optimization>
-#
-# StringListProperty
-# <StringListProperty Name="PreprocessorDefinitions" Category="Preprocessor" Switch="D ">
-# <StringListProperty.DisplayName>
-# <sys:String>Preprocessor Definitions</sys:String>
-# </StringListProperty.DisplayName>
-# <StringListProperty.Description>
-# <sys:String>Defines a preprocessing symbols for your source file.</sys:String>
-# </StringListProperty.Description>
-# </StringListProperty>
-
-# <StringListProperty Subtype="folder" Name="AdditionalIncludeDirectories" Category="General" Switch="I">
-# <StringListProperty.DisplayName>
-# <sys:String>Additional Include Directories</sys:String>
-# </StringListProperty.DisplayName>
-# <StringListProperty.Description>
-# <sys:String>Specifies one or more directories to add to the include path; separate with semi-colons if more than one. (/I[path])</sys:String>
-# </StringListProperty.Description>
-# </StringListProperty>
-# StringProperty
-
-# Example add bill include:
-
-# <AdditionalIncludeDirectories>..\..\..\..\..\..\bill;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-
-
-import sys
-from xml.dom.minidom import parse, parseString
-
-def getText(node):
- nodelist = node.childNodes
- rc = ""
- for child in nodelist:
- if child.nodeType == child.TEXT_NODE:
- rc = rc + child.data
- return rc
-
-def print_tree(document, spaces=""):
- for i in range(len(document.childNodes)):
- if document.childNodes[i].nodeType == document.childNodes[i].ELEMENT_NODE:
- print spaces+str(document.childNodes[i].nodeName )
- print_tree(document.childNodes[i],spaces+"----")
- pass
-
-###########################################################################################
-#Data structure that stores a property of MSBuild
-class Property:
- #type = type of MSBuild property (ex. if the property is EnumProperty type should be "Enum")
- #attributeNames = a list of any attributes that this property could have (ex. if this was a EnumProperty it should be ["Name","Category"])
- #document = the dom file that's root node is the Property node (ex. if you were parsing a BoolProperty the root node should be something like <BoolProperty Name="RegisterOutput" Category="General" IncludeInCommandLine="false">
- def __init__(self,type,attributeNames,document=None):
- self.suffix_type = "Property"
- self.prefix_type = type
- self.attributeNames = attributeNames
- self.attributes = {}
- self.DisplayName = ""
- self.Description = ""
- self.argumentProperty = ""
- self.argumentIsRequired = ""
- self.values = []
- if document is not None:
- self.populate(document)
- pass
-
- #document = the dom file that's root node is the Property node (ex. if you were parsing a BoolProperty the root node should be something like <BoolProperty Name="RegisterOutput" Category="General" IncludeInCommandLine="false">
- #spaces = do not use
- def populate(self,document, spaces = ""):
- if document.nodeName == self.prefix_type+self.suffix_type:
- for i in self.attributeNames:
- self.attributes[i] = document.getAttribute(i)
- for i in range(len(document.childNodes)):
- child = document.childNodes[i]
- if child.nodeType == child.ELEMENT_NODE:
- if child.nodeName == self.prefix_type+self.suffix_type+".DisplayName":
- self.DisplayName = getText(child.childNodes[1])
- if child.nodeName == self.prefix_type+self.suffix_type+".Description":
- self.Description = getText(child.childNodes[1])
- if child.nodeName == "Argument":
- self.argumentProperty = child.getAttribute("Property")
- self.argumentIsRequired = child.getAttribute("IsRequired")
- if child.nodeName == self.prefix_type+"Value":
- va = Property(self.prefix_type,["Name","DisplayName","Switch"])
- va.suffix_type = "Value"
- va.populate(child)
- self.values.append(va)
- self.populate(child,spaces+"----")
- pass
-
- #toString function
- def __str__(self):
- toReturn = self.prefix_type+self.suffix_type+":"
- for i in self.attributeNames:
- toReturn += "\n "+i+": "+self.attributes[i]
- if self.argumentProperty != "":
- toReturn += "\n Argument:\n Property: "+self.argumentProperty+"\n IsRequired: "+self.argumentIsRequired
- for i in self.values:
- toReturn+="\n "+str(i).replace("\n","\n ")
- return toReturn
-###########################################################################################
-
-###########################################################################################
-#Class that populates itself from an MSBuild file and outputs it in CMake
-#format
-
-class MSBuildToCMake:
- #document = the entire MSBuild xml file
- def __init__(self,document=None):
- self.enumProperties = []
- self.stringProperties = []
- self.stringListProperties = []
- self.boolProperties = []
- self.intProperties = []
- if document!=None :
- self.populate(document)
- pass
-
- #document = the entire MSBuild xml file
- #spaces = don't use
- #To add a new property (if they exist) copy and paste this code and fill in appropriate places
- #
- #if child.nodeName == "<Name>Property":
- # self.<Name>Properties.append(Property("<Name>",[<List of attributes>],child))
- #
- #Replace <Name> with the name of the new property (ex. if property is StringProperty replace <Name> with String)
- #Replace <List of attributes> with a list of attributes in your property's root node
- #in the __init__ function add the line self.<Name>Properties = []
- #
- #That is all that is required to add new properties
- #
- def populate(self,document, spaces=""):
- for i in range(len(document.childNodes)):
- child = document.childNodes[i]
- if child.nodeType == child.ELEMENT_NODE:
- if child.nodeName == "EnumProperty":
- self.enumProperties.append(Property("Enum",["Name","Category"],child))
- if child.nodeName == "StringProperty":
- self.stringProperties.append(Property("String",["Name","Subtype","Separator","Category","Visible","IncludeInCommandLine","Switch","DisplayName","ReadOnly"],child))
- if child.nodeName == "StringListProperty":
- self.stringListProperties.append(Property("StringList",["Name","Category","Switch","DisplayName","Subtype"],child))
- if child.nodeName == "BoolProperty":
- self.boolProperties.append(Property("Bool",["ReverseSwitch","Name","Category","Switch","DisplayName","SwitchPrefix","IncludeInCommandLine"],child))
- if child.nodeName == "IntProperty":
- self.intProperties.append(Property("Int",["Name","Category","Visible"],child))
- self.populate(child,spaces+"----")
- pass
-
- #outputs information that CMake needs to know about MSBuild xml files
- def toCMake(self):
- toReturn = "static cmVS7FlagTable cmVS10CxxTable[] =\n{\n"
- toReturn += "\n //Enum Properties\n"
- lastProp = {}
- for i in self.enumProperties:
- if i.attributes["Name"] == "CompileAsManaged":
- #write these out after the rest of the enumProperties
- lastProp = i
- continue
- for j in i.values:
- #hardcore Brad King's manual fixes for cmVS10CLFlagTable.h
- if i.attributes["Name"] == "PrecompiledHeader" and j.attributes["Switch"] != "":
- toReturn+=" {\""+i.attributes["Name"]+"\", \""+j.attributes["Switch"]+"\",\n \""+j.attributes["DisplayName"]+"\", \""+j.attributes["Name"]+"\",\n cmVS7FlagTable::UserValueIgnored | cmVS7FlagTable::Continue},\n"
- else:
- #default (normal, non-hardcoded) case
- toReturn+=" {\""+i.attributes["Name"]+"\", \""+j.attributes["Switch"]+"\",\n \""+j.attributes["DisplayName"]+"\", \""+j.attributes["Name"]+"\", 0},\n"
- toReturn += "\n"
-
- if lastProp != {}:
- for j in lastProp.values:
- toReturn+=" {\""+lastProp.attributes["Name"]+"\", \""+j.attributes["Switch"]+"\",\n \""+j.attributes["DisplayName"]+"\", \""+j.attributes["Name"]+"\", 0},\n"
- toReturn += "\n"
-
- toReturn += "\n //Bool Properties\n"
- for i in self.boolProperties:
- if i.argumentProperty == "":
- if i.attributes["ReverseSwitch"] != "":
- toReturn += " {\""+i.attributes["Name"]+"\", \""+i.attributes["ReverseSwitch"]+"\", \"\", \"false\", 0},\n"
- if i.attributes["Switch"] != "":
- toReturn += " {\""+i.attributes["Name"]+"\", \""+i.attributes["Switch"]+"\", \"\", \"true\", 0},\n"
-
- toReturn += "\n //Bool Properties With Argument\n"
- for i in self.boolProperties:
- if i.argumentProperty != "":
- if i.attributes["ReverseSwitch"] != "":
- toReturn += " {\""+i.attributes["Name"]+"\", \""+i.attributes["ReverseSwitch"]+"\", \"\", \"false\",\n cmVS7FlagTable::UserValueIgnored | cmVS7FlagTable::Continue},\n"
- toReturn += " {\""+i.attributes["Name"]+"\", \""+i.attributes["ReverseSwitch"]+"\", \""+i.attributes["DisplayName"]+"\", \"\",\n cmVS7FlagTable::UserValueRequired},\n"
- if i.attributes["Switch"] != "":
- toReturn += " {\""+i.attributes["Name"]+"\", \""+i.attributes["Switch"]+"\", \"\", \"true\",\n cmVS7FlagTable::UserValueIgnored | cmVS7FlagTable::Continue},\n"
- toReturn += " {\""+i.argumentProperty+"\", \""+i.attributes["Switch"]+"\", \""+i.attributes["DisplayName"]+"\", \"\",\n cmVS7FlagTable::UserValueRequired},\n"
-
- toReturn += "\n //String List Properties\n"
- for i in self.stringListProperties:
- if i.attributes["Switch"] == "":
- toReturn += " // Skip [" + i.attributes["Name"] + "] - no command line Switch.\n";
- else:
- toReturn +=" {\""+i.attributes["Name"]+"\", \""+i.attributes["Switch"]+"\",\n \""+i.attributes["DisplayName"]+"\",\n \"\", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable},\n"
-
- toReturn += "\n //String Properties\n"
- for i in self.stringProperties:
- if i.attributes["Switch"] == "":
- if i.attributes["Name"] == "PrecompiledHeaderFile":
- #more hardcoding
- toReturn += " {\"PrecompiledHeaderFile\", \"Yc\",\n"
- toReturn += " \"Precompiled Header Name\",\n"
- toReturn += " \"\", cmVS7FlagTable::UserValueRequired},\n"
- toReturn += " {\"PrecompiledHeaderFile\", \"Yu\",\n"
- toReturn += " \"Precompiled Header Name\",\n"
- toReturn += " \"\", cmVS7FlagTable::UserValueRequired},\n"
- else:
- toReturn += " // Skip [" + i.attributes["Name"] + "] - no command line Switch.\n";
- else:
- toReturn +=" {\""+i.attributes["Name"]+"\", \""+i.attributes["Switch"]+i.attributes["Separator"]+"\",\n \""+i.attributes["DisplayName"]+"\",\n \"\", cmVS7FlagTable::UserValue},\n"
-
- toReturn += " {0,0,0,0,0}\n};"
- return toReturn
- pass
-
- #toString function
- def __str__(self):
- toReturn = ""
- allList = [self.enumProperties,self.stringProperties,self.stringListProperties,self.boolProperties,self.intProperties]
- for p in allList:
- for i in p:
- toReturn += "==================================================\n"+str(i).replace("\n","\n ")+"\n==================================================\n"
-
- return toReturn
-###########################################################################################
-
-###########################################################################################
-# main function
-def main(argv):
- xml_file = None
- help = """
- Please specify an input xml file with -x
-
- Exiting...
- Have a nice day :)"""
- for i in range(0,len(argv)):
- if argv[i] == "-x":
- xml_file = argv[i+1]
- if argv[i] == "-h":
- print help
- sys.exit(0)
- pass
- if xml_file == None:
- print help
- sys.exit(1)
-
- f = open(xml_file,"r")
- xml_str = f.read()
- xml_dom = parseString(xml_str)
-
- convertor = MSBuildToCMake(xml_dom)
- print convertor.toCMake()
-
- xml_dom.unlink()
-###########################################################################################
-# main entry point
-if __name__ == "__main__":
- main(sys.argv)
-
-sys.exit(0)
diff --git a/Source/ctest.cxx b/Source/ctest.cxx
index ca412ae..8ba126f 100644
--- a/Source/ctest.cxx
+++ b/Source/ctest.cxx
@@ -46,7 +46,10 @@ static const char* cmDocumentationOptions[][2] = {
"given number of jobs." },
{ "-Q,--quiet", "Make ctest quiet." },
{ "-O <file>, --output-log <file>", "Output to log file" },
- { "-N,--show-only", "Disable actual execution of tests." },
+ { "-N,--show-only[=format]",
+ "Disable actual execution of tests. The optional 'format' defines the "
+ "format of the test information and can be 'human' for the current text "
+ "format or 'json-v1' for json format. Defaults to 'human'." },
{ "-L <regex>, --label-regex <regex>",
"Run tests with labels matching "
"regular expression." },
diff --git a/Tests/CMakeOnly/CMakeLists.txt b/Tests/CMakeOnly/CMakeLists.txt
index 204d54c..f40524f 100644
--- a/Tests/CMakeOnly/CMakeLists.txt
+++ b/Tests/CMakeOnly/CMakeLists.txt
@@ -56,7 +56,7 @@ add_test(CMakeOnly.ProjectInclude ${CMAKE_CMAKE_COMMAND}
-P ${CMAKE_CURRENT_BINARY_DIR}/Test.cmake
)
-include(${CMAKE_SOURCE_DIR}/Modules/CMakeParseArguments.cmake)
+include(CMakeParseArguments)
function(add_major_test module)
cmake_parse_arguments(MAJOR_TEST "NOLANG" "VERSION_VAR" "VERSIONS" ${ARGN})
diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt
index 67fd65a..e222376 100644
--- a/Tests/RunCMake/CMakeLists.txt
+++ b/Tests/RunCMake/CMakeLists.txt
@@ -385,8 +385,9 @@ add_RunCMake_test(CPackConfig)
add_RunCMake_test(CPackInstallProperties)
add_RunCMake_test(ExternalProject)
add_RunCMake_test(FetchContent)
+set(CTestCommandLine_ARGS -DPYTHON_EXECUTABLE=${PYTHON_EXECUTABLE})
if(NOT CMake_TEST_EXTERNAL_CMAKE)
- set(CTestCommandLine_ARGS -DTEST_AFFINITY=$<TARGET_FILE:testAffinity>)
+ list(APPEND CTestCommandLine_ARGS -DTEST_AFFINITY=$<TARGET_FILE:testAffinity>)
endif()
add_executable(print_stdin print_stdin.c)
add_RunCMake_test(CTestCommandLine -DTEST_PRINT_STDIN=$<TARGET_FILE:print_stdin>)
diff --git a/Tests/RunCMake/CTestCommandLine/RunCMakeTest.cmake b/Tests/RunCMake/CTestCommandLine/RunCMakeTest.cmake
index 750ae50..cae14b1 100644
--- a/Tests/RunCMake/CTestCommandLine/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CTestCommandLine/RunCMakeTest.cmake
@@ -173,3 +173,32 @@ function(run_TestStdin)
run_cmake_command(TestStdin ${CMAKE_CTEST_COMMAND} -V)
endfunction()
run_TestStdin()
+
+function(ShowAsJson_check_python v)
+ set(json_file "${RunCMake_TEST_BINARY_DIR}/ctest.json")
+ file(WRITE "${json_file}" "${actual_stdout}")
+ set(actual_stdout "" PARENT_SCOPE)
+ execute_process(
+ COMMAND ${PYTHON_EXECUTABLE} "${RunCMake_SOURCE_DIR}/ShowAsJson${v}-check.py" "${json_file}"
+ RESULT_VARIABLE result
+ OUTPUT_VARIABLE output
+ ERROR_VARIABLE output
+ )
+ if(NOT result EQUAL 0)
+ string(REPLACE "\n" "\n " output " ${output}")
+ set(RunCMake_TEST_FAILED "Unexpected output:\n${output}" PARENT_SCOPE)
+ endif()
+endfunction()
+
+function(run_ShowAsJson)
+ set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/ShowAsJson)
+ set(RunCMake_TEST_NO_CLEAN 1)
+ file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+ file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+ file(WRITE "${RunCMake_TEST_BINARY_DIR}/CTestTestfile.cmake" "
+ add_test(ShowAsJson \"${CMAKE_COMMAND}\" -E echo)
+ set_tests_properties(ShowAsJson PROPERTIES WILL_FAIL true _BACKTRACE_TRIPLES \"file1;1;add_test;file0;;\")
+")
+ run_cmake_command(ShowAsJsonVersionOne ${CMAKE_CTEST_COMMAND} --show-only=json-v1)
+endfunction()
+run_ShowAsJson()
diff --git a/Tests/RunCMake/CTestCommandLine/ShowAsJson1-check.py b/Tests/RunCMake/CTestCommandLine/ShowAsJson1-check.py
new file mode 100644
index 0000000..d794e7d
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/ShowAsJson1-check.py
@@ -0,0 +1,106 @@
+from ShowAsJson_check import *
+
+def check_kind(k):
+ assert is_string(k)
+ assert k == "ctestInfo"
+
+def check_version(v):
+ assert is_dict(v)
+ assert sorted(v.keys()) == ["major", "minor"]
+ assert is_int(v["major"])
+ assert is_int(v["minor"])
+ assert v["major"] == 1
+ assert v["minor"] == 0
+
+def check_backtracegraph(b):
+ assert is_dict(b)
+ assert sorted(b.keys()) == ["commands", "files", "nodes"]
+ check_backtracegraph_commands(b["commands"])
+ check_backtracegraph_files(b["files"])
+ check_backtracegraph_nodes(b["nodes"])
+
+def check_backtracegraph_commands(c):
+ assert is_list(c)
+ assert len(c) == 1
+ assert is_string(c[0])
+ assert c[0] == "add_test"
+
+def check_backtracegraph_files(f):
+ assert is_list(f)
+ assert len(f) == 2
+ assert is_string(f[0])
+ assert is_string(f[1])
+ assert f[0] == "file1"
+ assert f[1] == "file0"
+
+def check_backtracegraph_nodes(n):
+ assert is_list(n)
+ assert len(n) == 2
+ node = n[0]
+ assert is_dict(node)
+ assert sorted(node.keys()) == ["file"]
+ assert is_int(node["file"])
+ assert node["file"] == 1
+ node = n[1]
+ assert is_dict(node)
+ assert sorted(node.keys()) == ["command", "file", "line", "parent"]
+ assert is_int(node["command"])
+ assert is_int(node["file"])
+ assert is_int(node["line"])
+ assert is_int(node["parent"])
+ assert node["command"] == 0
+ assert node["file"] == 0
+ assert node["line"] == 1
+ assert node["parent"] == 0
+
+def check_command(c):
+ assert is_list(c)
+ assert len(c) == 3
+ assert is_string(c[0])
+ check_re(c[0], "/cmake(\.exe)?$")
+ assert is_string(c[1])
+ assert c[1] == "-E"
+ assert is_string(c[2])
+ assert c[2] == "echo"
+
+def check_willfail_property(p):
+ assert is_dict(p)
+ assert sorted(p.keys()) == ["name", "value"]
+ assert is_string(p["name"])
+ assert is_bool(p["value"])
+ assert p["name"] == "WILL_FAIL"
+ assert p["value"] == True
+
+def check_workingdir_property(p):
+ assert is_dict(p)
+ assert sorted(p.keys()) == ["name", "value"]
+ assert is_string(p["name"])
+ assert is_string(p["value"])
+ assert p["name"] == "WORKING_DIRECTORY"
+ assert p["value"].endswith("Tests/RunCMake/CTestCommandLine/ShowAsJson")
+
+def check_properties(p):
+ assert is_list(p)
+ assert len(p) == 2
+ check_willfail_property(p[0])
+ check_workingdir_property(p[1])
+
+def check_tests(t):
+ assert is_list(t)
+ assert len(t) == 1
+ test = t[0]
+ assert is_dict(test)
+ assert sorted(test.keys()) == ["backtrace", "command", "name", "properties"]
+ assert is_int(test["backtrace"])
+ assert test["backtrace"] == 1
+ check_command(test["command"])
+ assert is_string(test["name"])
+ assert test["name"] == "ShowAsJson"
+ check_properties(test["properties"])
+
+assert is_dict(ctest_json)
+assert sorted(ctest_json.keys()) == ["backtraceGraph", "kind", "tests", "version"]
+check_backtracegraph(ctest_json["backtraceGraph"])
+check_kind(ctest_json["kind"])
+check_version(ctest_json["version"])
+check_tests(ctest_json["tests"])
diff --git a/Tests/RunCMake/CTestCommandLine/ShowAsJson_check.py b/Tests/RunCMake/CTestCommandLine/ShowAsJson_check.py
new file mode 100644
index 0000000..493c9e5
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/ShowAsJson_check.py
@@ -0,0 +1,24 @@
+import sys
+import json
+import re
+
+def is_bool(x):
+ return isinstance(x, bool)
+
+def is_dict(x):
+ return isinstance(x, dict)
+
+def is_list(x):
+ return isinstance(x, list)
+
+def is_int(x):
+ return isinstance(x, int) or isinstance(x, long)
+
+def is_string(x):
+ return isinstance(x, str) or isinstance(x, unicode)
+
+def check_re(x, regex):
+ assert re.search(regex, x)
+
+with open(sys.argv[1]) as f:
+ ctest_json = json.load(f)
diff --git a/Tests/RunCMake/CommandLine/RunCMakeTest.cmake b/Tests/RunCMake/CommandLine/RunCMakeTest.cmake
index a37b7f1..4cd34de 100644
--- a/Tests/RunCMake/CommandLine/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CommandLine/RunCMakeTest.cmake
@@ -350,7 +350,7 @@ set(RunCMake_TEST_OPTIONS --trace-expand --warn-uninitialized)
run_cmake(trace-expand-warn-uninitialized)
unset(RunCMake_TEST_OPTIONS)
-set(RunCMake_TEST_OPTIONS --warn-uninitialized)
+set(RunCMake_TEST_OPTIONS -Wno-deprecated --warn-uninitialized)
run_cmake(warn-uninitialized)
unset(RunCMake_TEST_OPTIONS)
diff --git a/Tests/RunCMake/CommandLine/warn-uninitialized-stderr.txt b/Tests/RunCMake/CommandLine/warn-uninitialized-stderr.txt
index a13402a..41ba098 100644
--- a/Tests/RunCMake/CommandLine/warn-uninitialized-stderr.txt
+++ b/Tests/RunCMake/CommandLine/warn-uninitialized-stderr.txt
@@ -1,5 +1,53 @@
-^CMake Warning \(dev\) at warn-uninitialized.cmake:1 \(set\):
- uninitialized variable 'WARN_FROM_NORMAL_CMAKE_FILE'
+^CMake Warning \(dev\) at warn-uninitialized.cmake:3 \(set\):
+ uninitialized variable 'OLD_WARN_FROM_NORMAL_CMAKE_FILE_INSIDE_BRACES'
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
+
+CMake Warning \(dev\) at warn-uninitialized.cmake:4 \(set\):
+ uninitialized variable 'OLD_WARN_FROM_NORMAL_CMAKE_FILE_IN_ATS'
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
+
+CMake Warning \(dev\) at warn-uninitialized.cmake:5 \(string\):
+ uninitialized variable 'OLD_WARN_FROM_STRING_CONFIGURE_INSIDE_BRACES'
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
+
+CMake Warning \(dev\) at warn-uninitialized.cmake:7 \(configure_file\):
+ uninitialized variable 'OLD_WARN_FROM_CONFIGURE_FILE_INSIDE_AT'
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
+
+CMake Warning \(dev\) at warn-uninitialized.cmake:8 \(string\):
+ uninitialized variable 'OLD_WARN_FROM_STRING_CONFIGURE_INSIDE_AT'
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
+
+CMake Warning \(dev\) at warn-uninitialized.cmake:13 \(set\):
+ uninitialized variable 'NEW_WARN_FROM_NORMAL_CMAKE_FILE_INSIDE_BRACES'
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
+
+CMake Warning \(dev\) at warn-uninitialized.cmake:14 \(string\):
+ uninitialized variable 'NEW_WARN_FROM_STRING_CONFIGURE_INSIDE_BRACES'
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
+
+CMake Warning \(dev\) at warn-uninitialized.cmake:16 \(configure_file\):
+ uninitialized variable 'NEW_WARN_FROM_CONFIGURE_FILE_INSIDE_AT'
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
+
+CMake Warning \(dev\) at warn-uninitialized.cmake:17 \(string\):
+ uninitialized variable 'NEW_WARN_FROM_STRING_CONFIGURE_INSIDE_AT'
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)
This warning is for project developers. Use -Wno-dev to suppress it.$
diff --git a/Tests/RunCMake/CommandLine/warn-uninitialized.cmake b/Tests/RunCMake/CommandLine/warn-uninitialized.cmake
index f1a75c9..ff65c16 100644
--- a/Tests/RunCMake/CommandLine/warn-uninitialized.cmake
+++ b/Tests/RunCMake/CommandLine/warn-uninitialized.cmake
@@ -1 +1,18 @@
-set(FOO "${WARN_FROM_NORMAL_CMAKE_FILE}")
+cmake_policy(PUSH)
+cmake_policy(SET CMP0053 OLD)
+set(FOO "${OLD_WARN_FROM_NORMAL_CMAKE_FILE_INSIDE_BRACES}")
+set(FOO "@OLD_WARN_FROM_NORMAL_CMAKE_FILE_IN_ATS@")
+string(CONFIGURE "\${OLD_WARN_FROM_STRING_CONFIGURE_INSIDE_BRACES}" OUT1)
+file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/file1.in "\@OLD_WARN_FROM_CONFIGURE_FILE_INSIDE_AT\@")
+configure_file(${CMAKE_CURRENT_BINARY_DIR}/file1.in file1.out)
+string(CONFIGURE "\@OLD_WARN_FROM_STRING_CONFIGURE_INSIDE_AT\@" OUT2)
+cmake_policy(POP)
+
+cmake_policy(PUSH)
+cmake_policy(SET CMP0053 NEW)
+set(FOO "${NEW_WARN_FROM_NORMAL_CMAKE_FILE_INSIDE_BRACES}")
+string(CONFIGURE "\${NEW_WARN_FROM_STRING_CONFIGURE_INSIDE_BRACES}" OUT3)
+file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/file2.in "\@NEW_WARN_FROM_CONFIGURE_FILE_INSIDE_AT\@")
+configure_file(${CMAKE_CURRENT_BINARY_DIR}/file2.in file2.out)
+string(CONFIGURE "@NEW_WARN_FROM_STRING_CONFIGURE_INSIDE_AT@" OUT4)
+cmake_policy(POP)
diff --git a/Tests/RunCMake/ExternalProject/LogOutputOnFailure-build-result.txt b/Tests/RunCMake/ExternalProject/LogOutputOnFailure-build-result.txt
new file mode 100644
index 0000000..c20fd86
--- /dev/null
+++ b/Tests/RunCMake/ExternalProject/LogOutputOnFailure-build-result.txt
@@ -0,0 +1 @@
+^[^0]
diff --git a/Tests/RunCMake/ExternalProject/LogOutputOnFailure-build-stderr.txt b/Tests/RunCMake/ExternalProject/LogOutputOnFailure-build-stderr.txt
new file mode 100644
index 0000000..8d98f9d
--- /dev/null
+++ b/Tests/RunCMake/ExternalProject/LogOutputOnFailure-build-stderr.txt
@@ -0,0 +1 @@
+.*
diff --git a/Tests/RunCMake/ExternalProject/LogOutputOnFailure-build-stdout.txt b/Tests/RunCMake/ExternalProject/LogOutputOnFailure-build-stdout.txt
new file mode 100644
index 0000000..87e5384
--- /dev/null
+++ b/Tests/RunCMake/ExternalProject/LogOutputOnFailure-build-stdout.txt
@@ -0,0 +1,8 @@
+( )?-- stdout output is:
+( )?This is some dummy output with some long lines to ensure formatting is preserved
+( )? Including lines with leading spaces
+( )?
+( )?And also blank lines[
+ ]+
+( )?-- stderr output is:
+( )?cmake -E env: no command given
diff --git a/Tests/RunCMake/ExternalProject/LogOutputOnFailure.cmake b/Tests/RunCMake/ExternalProject/LogOutputOnFailure.cmake
new file mode 100644
index 0000000..863bbef
--- /dev/null
+++ b/Tests/RunCMake/ExternalProject/LogOutputOnFailure.cmake
@@ -0,0 +1,20 @@
+include(ExternalProject)
+
+set(dummyOutput [[
+This is some dummy output with some long lines to ensure formatting is preserved
+ Including lines with leading spaces
+
+And also blank lines
+]])
+
+ExternalProject_Add(FailsWithOutput
+ SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}
+ CONFIGURE_COMMAND ""
+ BUILD_COMMAND ${CMAKE_COMMAND} -E echo ${dummyOutput}
+ COMMAND ${CMAKE_COMMAND} -E env # missing command, forces fail
+ TEST_COMMAND ""
+ INSTALL_COMMAND ""
+ LOG_BUILD YES
+ LOG_OUTPUT_ON_FAILURE YES
+ USES_TERMINAL_BUILD YES
+)
diff --git a/Tests/RunCMake/ExternalProject/LogOutputOnFailureMerged-build-result.txt b/Tests/RunCMake/ExternalProject/LogOutputOnFailureMerged-build-result.txt
new file mode 100644
index 0000000..c20fd86
--- /dev/null
+++ b/Tests/RunCMake/ExternalProject/LogOutputOnFailureMerged-build-result.txt
@@ -0,0 +1 @@
+^[^0]
diff --git a/Tests/RunCMake/ExternalProject/LogOutputOnFailureMerged-build-stderr.txt b/Tests/RunCMake/ExternalProject/LogOutputOnFailureMerged-build-stderr.txt
new file mode 100644
index 0000000..8d98f9d
--- /dev/null
+++ b/Tests/RunCMake/ExternalProject/LogOutputOnFailureMerged-build-stderr.txt
@@ -0,0 +1 @@
+.*
diff --git a/Tests/RunCMake/ExternalProject/LogOutputOnFailureMerged-build-stdout.txt b/Tests/RunCMake/ExternalProject/LogOutputOnFailureMerged-build-stdout.txt
new file mode 100644
index 0000000..11c7317
--- /dev/null
+++ b/Tests/RunCMake/ExternalProject/LogOutputOnFailureMerged-build-stdout.txt
@@ -0,0 +1,7 @@
+( )?-- Log output is:
+( )?This is some dummy output with some long lines to ensure formatting is preserved
+( )? Including lines with leading spaces
+( )?
+( )?And also blank lines[
+ ]+
+( )?cmake -E env: no command given
diff --git a/Tests/RunCMake/ExternalProject/LogOutputOnFailureMerged.cmake b/Tests/RunCMake/ExternalProject/LogOutputOnFailureMerged.cmake
new file mode 100644
index 0000000..116448b
--- /dev/null
+++ b/Tests/RunCMake/ExternalProject/LogOutputOnFailureMerged.cmake
@@ -0,0 +1,21 @@
+include(ExternalProject)
+
+set(dummyOutput [[
+This is some dummy output with some long lines to ensure formatting is preserved
+ Including lines with leading spaces
+
+And also blank lines
+]])
+
+ExternalProject_Add(FailsWithOutput
+ SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}
+ CONFIGURE_COMMAND ""
+ BUILD_COMMAND ${CMAKE_COMMAND} -E echo ${dummyOutput}
+ COMMAND ${CMAKE_COMMAND} -E env # missing command, forces fail
+ TEST_COMMAND ""
+ INSTALL_COMMAND ""
+ LOG_BUILD YES
+ LOG_OUTPUT_ON_FAILURE YES
+ LOG_MERGED_STDOUTERR YES
+ USES_TERMINAL_BUILD YES
+)
diff --git a/Tests/RunCMake/ExternalProject/RunCMakeTest.cmake b/Tests/RunCMake/ExternalProject/RunCMakeTest.cmake
index bf11381..caaf0d2 100644
--- a/Tests/RunCMake/ExternalProject/RunCMakeTest.cmake
+++ b/Tests/RunCMake/ExternalProject/RunCMakeTest.cmake
@@ -29,6 +29,13 @@ endfunction()
__ep_test_with_build(MultiCommand)
+# Output is not predictable enough to be able to verify it reliably
+# when using the various different Visual Studio generators
+if(NOT RunCMake_GENERATOR MATCHES "Visual Studio")
+ __ep_test_with_build(LogOutputOnFailure)
+ __ep_test_with_build(LogOutputOnFailureMerged)
+endif()
+
# We can't test the substitution when using the old MSYS due to
# make/sh mangling the paths (substitution is performed correctly,
# but the mangling means we can't reliably test the output).
diff --git a/Tests/RunCMake/GetPrerequisites/ExecutableScripts-stdout.txt b/Tests/RunCMake/GetPrerequisites/ExecutableScripts-stdout.txt
new file mode 100644
index 0000000..5a353d8
--- /dev/null
+++ b/Tests/RunCMake/GetPrerequisites/ExecutableScripts-stdout.txt
@@ -0,0 +1,3 @@
+-- GetPrequisites\(.*script.sh\) : ignoring script file
+-- GetPrequisites\(.*script.bat\) : ignoring script file
+-- GetPrequisites\(.*script\) : ignoring script file
diff --git a/Tests/RunCMake/GetPrerequisites/ExecutableScripts.cmake b/Tests/RunCMake/GetPrerequisites/ExecutableScripts.cmake
new file mode 100644
index 0000000..d1bc9b1
--- /dev/null
+++ b/Tests/RunCMake/GetPrerequisites/ExecutableScripts.cmake
@@ -0,0 +1,19 @@
+include(GetPrerequisites)
+
+function(check_script script)
+ set(prereqs "")
+ get_prerequisites(${script} prereqs 1 1 "" "")
+ if(NOT "${prereqs}" STREQUAL "")
+ message(FATAL_ERROR "Prerequisites for ${script} not empty")
+ endif()
+endfunction()
+
+# Should not throw any errors
+# Regular executable
+get_prerequisites(${CMAKE_COMMAND} cmake_prereqs 1 1 "" "")
+# Shell script
+check_script(${CMAKE_CURRENT_LIST_DIR}/script.sh)
+# Batch script
+check_script(${CMAKE_CURRENT_LIST_DIR}/script.bat)
+# Shell script without extension
+check_script(${CMAKE_CURRENT_LIST_DIR}/script)
diff --git a/Tests/RunCMake/GetPrerequisites/RunCMakeTest.cmake b/Tests/RunCMake/GetPrerequisites/RunCMakeTest.cmake
index 3856c54..a635e38 100644
--- a/Tests/RunCMake/GetPrerequisites/RunCMakeTest.cmake
+++ b/Tests/RunCMake/GetPrerequisites/RunCMakeTest.cmake
@@ -1,3 +1,4 @@
include(RunCMake)
run_cmake_command(TargetMissing ${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR}/TargetMissing.cmake)
+run_cmake_command(ExecutableScripts ${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR}/ExecutableScripts.cmake)
diff --git a/Tests/RunCMake/GetPrerequisites/script b/Tests/RunCMake/GetPrerequisites/script
new file mode 100755
index 0000000..23bf47c
--- /dev/null
+++ b/Tests/RunCMake/GetPrerequisites/script
@@ -0,0 +1,3 @@
+#!/bin/bash
+
+echo "Hello World"
diff --git a/Tests/RunCMake/GetPrerequisites/script.bat b/Tests/RunCMake/GetPrerequisites/script.bat
new file mode 100755
index 0000000..dbb0ec2
--- /dev/null
+++ b/Tests/RunCMake/GetPrerequisites/script.bat
@@ -0,0 +1,3 @@
+@echo off
+
+echo "Hello world"
diff --git a/Tests/RunCMake/GetPrerequisites/script.sh b/Tests/RunCMake/GetPrerequisites/script.sh
new file mode 100755
index 0000000..23bf47c
--- /dev/null
+++ b/Tests/RunCMake/GetPrerequisites/script.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+
+echo "Hello World"
diff --git a/Tests/RunCMake/PositionIndependentCode/CMP0083.cmake b/Tests/RunCMake/PositionIndependentCode/CMP0083.cmake
index 9713ea4..749ac79 100644
--- a/Tests/RunCMake/PositionIndependentCode/CMP0083.cmake
+++ b/Tests/RunCMake/PositionIndependentCode/CMP0083.cmake
@@ -6,6 +6,8 @@ add_executable (cmp0083_ref main.cpp)
set (CMAKE_POSITION_INDEPENDENT_CODE ON)
cmake_policy(SET CMP0083 NEW)
+include(CheckPIESupported)
+check_pie_supported()
add_executable (cmp0083_new_pie main.cpp)
diff --git a/Tests/RunCMake/PositionIndependentCode/CheckPIESupported.cmake b/Tests/RunCMake/PositionIndependentCode/CheckPIESupported.cmake
index 1e0a2c9..61e1b6d 100644
--- a/Tests/RunCMake/PositionIndependentCode/CheckPIESupported.cmake
+++ b/Tests/RunCMake/PositionIndependentCode/CheckPIESupported.cmake
@@ -1,11 +1,17 @@
-if (CMAKE_CXX_LINK_OPTIONS_PIE)
+cmake_policy(SET CMP0083 NEW)
+
+include (CheckPIESupported)
+
+check_pie_supported()
+
+if (CMAKE_CXX_LINK_PIE_SUPPORTED)
file(WRITE "${PIE_SUPPORTED}" "\nset(PIE_SUPPORTED TRUE)\n")
else()
file(WRITE "${PIE_SUPPORTED}" "\nset(PIE_SUPPORTED FALSE)\n")
endif()
-if (CMAKE_CXX_LINK_OPTIONS_NO_PIE)
+if (CMAKE_CXX_LINK_NO_PIE_SUPPORTED)
file(APPEND "${PIE_SUPPORTED}" "\nset(NO_PIE_SUPPORTED TRUE)\n")
else()
file(APPEND "${PIE_SUPPORTED}" "\nset(NO_PIE_SUPPORTED FALSE)\n")
diff --git a/Tests/RunCMake/PositionIndependentCode/PIE.cmake b/Tests/RunCMake/PositionIndependentCode/PIE.cmake
index a9d579d..16ed89c 100644
--- a/Tests/RunCMake/PositionIndependentCode/PIE.cmake
+++ b/Tests/RunCMake/PositionIndependentCode/PIE.cmake
@@ -1,6 +1,9 @@
cmake_policy(SET CMP0083 NEW)
+include(CheckPIESupported)
+check_pie_supported()
+
add_executable (pie_on main.cpp)
set_property(TARGET pie_on PROPERTY POSITION_INDEPENDENT_CODE ON)
diff --git a/Tests/RunCMake/README.rst b/Tests/RunCMake/README.rst
index 08b51d9..d8b43fe 100644
--- a/Tests/RunCMake/README.rst
+++ b/Tests/RunCMake/README.rst
@@ -65,3 +65,14 @@ but do not actually build anything. To add a test:
Top of test binary tree
and an failure must store a message in ``RunCMake_TEST_FAILED``.
+
+To speed up local testing, you can choose to run only a subset of
+``run_cmake()`` tests in a ``RunCMakeTest.cmake`` script by using the
+``RunCMake_TEST_FILTER`` environment variable. If this variable is set,
+it is treated as a regular expression, and any tests whose names don't
+match the regular expression are not run. For example::
+
+ $ RunCMake_TEST_FILTER="^example" ctest -R '^RunCMake\.Example$'
+
+This will only run subtests in ``RunCMake.Example`` that start with
+``example``.
diff --git a/Tests/RunCMake/RunCMake.cmake b/Tests/RunCMake/RunCMake.cmake
index 4bacd96..ce71677 100644
--- a/Tests/RunCMake/RunCMake.cmake
+++ b/Tests/RunCMake/RunCMake.cmake
@@ -9,6 +9,10 @@ foreach(arg
endforeach()
function(run_cmake test)
+ if(DEFINED ENV{RunCMake_TEST_FILTER} AND NOT test MATCHES "$ENV{RunCMake_TEST_FILTER}")
+ return()
+ endif()
+
set(top_src "${RunCMake_SOURCE_DIR}")
set(top_bin "${RunCMake_BINARY_DIR}")
if(EXISTS ${top_src}/${test}-result.txt)
diff --git a/Tests/RunCMake/install/CMP0087-NEW-check.cmake b/Tests/RunCMake/install/CMP0087-NEW-check.cmake
new file mode 100644
index 0000000..422c532
--- /dev/null
+++ b/Tests/RunCMake/install/CMP0087-NEW-check.cmake
@@ -0,0 +1,7 @@
+execute_process(COMMAND ${CMAKE_COMMAND} -P ${RunCMake_TEST_BINARY_DIR}/cmake_install.cmake
+ OUTPUT_VARIABLE out ERROR_VARIABLE err)
+if(NOT out MATCHES "-- Install configuration: .*-- codegenexlib")
+ string(REGEX REPLACE "\n" "\n " out " ${out}")
+ string(APPEND RunCMake_TEST_FAILED
+ "\"-- codegenexlib\" was not found:\n${out}")
+endif()
diff --git a/Tests/RunCMake/install/CMP0087-NEW.cmake b/Tests/RunCMake/install/CMP0087-NEW.cmake
new file mode 100644
index 0000000..0177960
--- /dev/null
+++ b/Tests/RunCMake/install/CMP0087-NEW.cmake
@@ -0,0 +1,3 @@
+# Need a new directory scope, not just a new policy scope
+# to test this correctly
+add_subdirectory(CMP0087-NEW)
diff --git a/Tests/RunCMake/install/CMP0087-NEW/CMakeLists.txt b/Tests/RunCMake/install/CMP0087-NEW/CMakeLists.txt
new file mode 100644
index 0000000..07b4589
--- /dev/null
+++ b/Tests/RunCMake/install/CMP0087-NEW/CMakeLists.txt
@@ -0,0 +1,7 @@
+# Note that it is the policy settings at the end of the directory
+# scope that will be used when deciding whether or not generator
+# expressions should be evaluated in the installed code.
+cmake_policy(VERSION 3.13)
+cmake_policy(SET CMP0087 NEW)
+add_library( codegenexlib INTERFACE )
+install(CODE "message( STATUS \"$<TARGET_PROPERTY:codegenexlib,NAME>\")")
diff --git a/Tests/RunCMake/install/CMP0087-OLD-check.cmake b/Tests/RunCMake/install/CMP0087-OLD-check.cmake
new file mode 100644
index 0000000..c5984bc
--- /dev/null
+++ b/Tests/RunCMake/install/CMP0087-OLD-check.cmake
@@ -0,0 +1,8 @@
+execute_process(COMMAND ${CMAKE_COMMAND} -P ${RunCMake_TEST_BINARY_DIR}/cmake_install.cmake
+ OUTPUT_VARIABLE out ERROR_VARIABLE err)
+
+if(NOT out MATCHES "-- Install configuration: .*-- \\$<TARGET_PROPERTY:codegenexlib,NAME>")
+ string(REGEX REPLACE "\n" "\n " out " ${out}")
+ string(APPEND RunCMake_TEST_FAILED
+ "\"-- $<TARGET_PROPERTY:codegenexlib,NAME>\" was not found:\n${out}")
+endif()
diff --git a/Tests/RunCMake/install/CMP0087-OLD.cmake b/Tests/RunCMake/install/CMP0087-OLD.cmake
new file mode 100644
index 0000000..e7ed4ee
--- /dev/null
+++ b/Tests/RunCMake/install/CMP0087-OLD.cmake
@@ -0,0 +1,3 @@
+# Need a new directory scope, not just a new policy scope
+# to test this correctly
+add_subdirectory(CMP0087-OLD)
diff --git a/Tests/RunCMake/install/CMP0087-OLD/CMakeLists.txt b/Tests/RunCMake/install/CMP0087-OLD/CMakeLists.txt
new file mode 100644
index 0000000..b1d4e2e
--- /dev/null
+++ b/Tests/RunCMake/install/CMP0087-OLD/CMakeLists.txt
@@ -0,0 +1,6 @@
+# Note that it is the policy settings at the end of the directory
+# scope that will be used when deciding whether or not generator
+# expressions should be evaluated in the installed code.
+cmake_policy(VERSION 3.13)
+cmake_policy(SET CMP0087 OLD)
+install(CODE "message( STATUS \"$<TARGET_PROPERTY:codegenexlib,NAME>\")")
diff --git a/Tests/RunCMake/install/CMP0087-WARN-stderr.txt b/Tests/RunCMake/install/CMP0087-WARN-stderr.txt
new file mode 100644
index 0000000..75fbf2c
--- /dev/null
+++ b/Tests/RunCMake/install/CMP0087-WARN-stderr.txt
@@ -0,0 +1,5 @@
+CMake Warning (dev) in CMakeLists.txt:
+ Policy CMP0087 is not set: Install CODE|SCRIPT allow the use of generator
+ expressions. Run "cmake --help-policy CMP0087" for policy details. Use
+ the cmake_policy command to set the policy and suppress this warning.
+This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/install/CMP0087-WARN.cmake b/Tests/RunCMake/install/CMP0087-WARN.cmake
new file mode 100644
index 0000000..3b8513d
--- /dev/null
+++ b/Tests/RunCMake/install/CMP0087-WARN.cmake
@@ -0,0 +1,2 @@
+add_library( codegenexlib INTERFACE )
+install(CODE "message( STATUS \"$<TARGET_PROPERTY:codegenexlib,NAME>\")")
diff --git a/Tests/RunCMake/install/RunCMakeTest.cmake b/Tests/RunCMake/install/RunCMakeTest.cmake
index f7e1dee..28e8ec4 100644
--- a/Tests/RunCMake/install/RunCMakeTest.cmake
+++ b/Tests/RunCMake/install/RunCMakeTest.cmake
@@ -63,6 +63,9 @@ run_cmake(EXPORT-OldIFace)
run_cmake(CMP0062-OLD)
run_cmake(CMP0062-NEW)
run_cmake(CMP0062-WARN)
+run_cmake(CMP0087-OLD)
+run_cmake(CMP0087-NEW)
+run_cmake(CMP0087-WARN)
run_cmake(TARGETS-NAMELINK_COMPONENT-bad-all)
run_cmake(TARGETS-NAMELINK_COMPONENT-bad-exc)
run_cmake(FILES-DESTINATION-TYPE)
diff --git a/Tests/RunCMake/install/TARGETS-Defaults-Cache-all-check.cmake b/Tests/RunCMake/install/TARGETS-Defaults-Cache-all-check.cmake
index 6fc735c..57ad6e1 100644
--- a/Tests/RunCMake/install/TARGETS-Defaults-Cache-all-check.cmake
+++ b/Tests/RunCMake/install/TARGETS-Defaults-Cache-all-check.cmake
@@ -21,8 +21,8 @@ elseif(CYGWIN)
[[lib4]]
[[lib4/cyglib4\.dll]]
[[mybin]]
- [[mybin/exe\.exe]]
[[mybin/cyglib1\.dll]]
+ [[mybin/exe\.exe]]
[[myinclude]]
[[myinclude/obj4\.h]]
[[myinclude/obj5\.h]]
diff --git a/Tests/RunCMake/install/TARGETS-Defaults-all-check.cmake b/Tests/RunCMake/install/TARGETS-Defaults-all-check.cmake
index 59209e6..c41cb2a 100644
--- a/Tests/RunCMake/install/TARGETS-Defaults-all-check.cmake
+++ b/Tests/RunCMake/install/TARGETS-Defaults-all-check.cmake
@@ -17,8 +17,8 @@ if(WIN32)
elseif(CYGWIN)
set(_check_files
[[bin]]
- [[bin/exe\.exe]]
[[bin/cyglib1\.dll]]
+ [[bin/exe\.exe]]
[[include]]
[[include/obj4\.h]]
[[include/obj5\.h]]
diff --git a/Tests/UseSWIG/CMakeLists.txt b/Tests/UseSWIG/CMakeLists.txt
index f79cda6..434895e 100644
--- a/Tests/UseSWIG/CMakeLists.txt
+++ b/Tests/UseSWIG/CMakeLists.txt
@@ -111,3 +111,15 @@ add_test(NAME UseSWIG.ModuleName COMMAND
--build-options ${build_options}
--test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
)
+
+
+add_test(NAME UseSWIG.SwigSrcFileExtension COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/UseSWIG/SwigSrcFileExtension"
+ "${CMake_BINARY_DIR}/Tests/UseSWIG/SwigSrcFileExtension"
+ ${build_generator_args}
+ --build-project SwigSrcFileExtension
+ --build-options ${build_options}
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+ )
diff --git a/Tests/UseSWIG/SwigSrcFileExtension/CMakeLists.txt b/Tests/UseSWIG/SwigSrcFileExtension/CMakeLists.txt
new file mode 100644
index 0000000..7eb73d4
--- /dev/null
+++ b/Tests/UseSWIG/SwigSrcFileExtension/CMakeLists.txt
@@ -0,0 +1,28 @@
+cmake_minimum_required(VERSION 3.1...3.14)
+
+project(SwigSrcFileExtension C)
+
+include(CTest)
+find_package(SWIG REQUIRED)
+find_package(Python COMPONENTS Interpreter Development REQUIRED)
+
+include(${SWIG_USE_FILE})
+
+# Use the newer target name preference
+set(UseSWIG_TARGET_NAME_PREFERENCE "STANDARD")
+
+# Set the custom source file extension to both .i and .swg
+set(SWIG_SOURCE_FILE_EXTENSIONS ".i" ".swg")
+
+# Generate a Python module out of `.i`
+swig_add_library(my_add LANGUAGE python SOURCES my_add.i)
+target_link_libraries(my_add Python::Python)
+
+# Generate a Python module out of `.swg`
+swig_add_library(my_sub LANGUAGE python SOURCES my_sub.swg)
+target_link_libraries(my_sub Python::Python)
+
+# Add a test
+add_test(NAME SwigSrcFileExtension
+ COMMAND "${CMAKE_COMMAND}" -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}"
+ "${Python_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/runme.py")
diff --git a/Tests/UseSWIG/SwigSrcFileExtension/my_add.i b/Tests/UseSWIG/SwigSrcFileExtension/my_add.i
new file mode 100644
index 0000000..d087ab5
--- /dev/null
+++ b/Tests/UseSWIG/SwigSrcFileExtension/my_add.i
@@ -0,0 +1,9 @@
+%module my_add
+
+%{
+int add(int a, int b) {
+ return a + b;
+}
+%}
+
+int add(int a, int b);
diff --git a/Tests/UseSWIG/SwigSrcFileExtension/my_sub.swg b/Tests/UseSWIG/SwigSrcFileExtension/my_sub.swg
new file mode 100644
index 0000000..df34b44
--- /dev/null
+++ b/Tests/UseSWIG/SwigSrcFileExtension/my_sub.swg
@@ -0,0 +1,9 @@
+%module my_sub
+
+%{
+int sub(int a, int b) {
+ return a - b;
+}
+%}
+
+int sub(int a, int b);
diff --git a/Tests/UseSWIG/SwigSrcFileExtension/runme.py b/Tests/UseSWIG/SwigSrcFileExtension/runme.py
new file mode 100755
index 0000000..290175b
--- /dev/null
+++ b/Tests/UseSWIG/SwigSrcFileExtension/runme.py
@@ -0,0 +1,24 @@
+#!/usr/bin/env python
+
+from __future__ import print_function
+import random
+
+import my_add
+import my_sub
+
+
+# These can be changed, but make sure not to overflow `int`
+a = random.randint(1, 1024)
+b = random.randint(1, 1024)
+
+if my_add.add(a, b) == a + b:
+ print ("Test 1 Passed for SWIG custom source file extension")
+else:
+ print ("Test 1 FAILED for SWIG custom source file extension")
+ exit(1)
+
+if my_sub.sub(a, b) == a - b:
+ print ("Test 2 Passed for SWIG custom source file extension")
+else:
+ print ("Test 2 FAILED for SWIG custom source file extension")
+ exit(1)
diff --git a/Utilities/Sphinx/colors.py b/Utilities/Sphinx/colors.py
index f98a483..dae0063 100644
--- a/Utilities/Sphinx/colors.py
+++ b/Utilities/Sphinx/colors.py
@@ -14,14 +14,14 @@ class CMakeTemplateStyle(Style):
styles = {
Whitespace: "#bbbbbb",
Comment: "italic #408080",
- Operator: "bold #000000",
+ Operator: "#555555",
String: "#217A21",
Number: "#105030",
- Name.Builtin: "#400080", # anything lowercase
- Name.Function: "bold #1010A0", # function
+ Name.Builtin: "#333333", # anything lowercase
+ Name.Function: "#007020", # function
Name.Variable: "#1080B0", # <..>
- Name.Tag: "#19177C", # ${..}
- Name.Constant: "#6020E0", # uppercase only
+ Name.Tag: "#bb60d5", # ${..}
+ Name.Constant: "#4070a0", # uppercase only
Name.Entity: "italic #70A020", # @..@
Name.Attribute: "#906060", # paths, URLs
Name.Label: "#A0A000", # anything left over