summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Help/dev/source.rst144
-rw-r--r--Help/release/dev/GoogleTest-XML_OUTPUT_DIR.rst6
-rw-r--r--Modules/CMakeASMCompiler.cmake.in1
-rw-r--r--Modules/CMakeDetermineASMCompiler.cmake7
-rw-r--r--Modules/CMakeDetermineCompilerId.cmake14
-rw-r--r--Modules/Compiler/GNU-ASM.cmake6
-rw-r--r--Modules/FindRuby.cmake26
-rw-r--r--Modules/FindThreads.cmake45
-rw-r--r--Modules/GoogleTest.cmake11
-rw-r--r--Modules/GoogleTestAddTests.cmake6
-rw-r--r--Source/CMakeVersion.cmake2
-rw-r--r--Source/cmCPluginAPI.cxx5
-rw-r--r--Source/cmDefinePropertyCommand.cxx2
-rw-r--r--Source/cmExportFileGenerator.cxx2
-rw-r--r--Source/cmMakefileProfilingData.cxx15
-rw-r--r--Source/cmPropertyDefinition.cxx26
-rw-r--r--Source/cmPropertyDefinition.h11
-rw-r--r--Source/cmPropertyDefinitionMap.cxx18
-rw-r--r--Source/cmPropertyDefinitionMap.h4
-rw-r--r--Source/cmState.cxx4
-rw-r--r--Source/cmState.h4
-rw-r--r--Tests/RunCMake/BuildDepends/GNU-AS-stdout.txt4
-rw-r--r--Tests/RunCMake/BuildDepends/GNU-AS.cmake13
-rw-r--r--Tests/RunCMake/BuildDepends/GNU-AS.step1.cmake1
-rw-r--r--Tests/RunCMake/BuildDepends/GNU-AS.step2.cmake1
-rw-r--r--Tests/RunCMake/BuildDepends/RunCMakeTest.cmake5
-rw-r--r--Tests/RunCMake/BuildDepends/gnu_as.s1
-rw-r--r--Tests/RunCMake/CMakeLists.txt15
-rw-r--r--Tests/RunCMake/GoogleTest/GoogleTestXML-result-check.cmake4
-rw-r--r--Tests/RunCMake/GoogleTest/GoogleTestXML.cmake11
-rw-r--r--Tests/RunCMake/GoogleTest/RunCMakeTest.cmake28
-rw-r--r--Tests/RunCMake/GoogleTest/xml_output.cpp26
32 files changed, 393 insertions, 75 deletions
diff --git a/Help/dev/source.rst b/Help/dev/source.rst
index 0f7488b..5371353 100644
--- a/Help/dev/source.rst
+++ b/Help/dev/source.rst
@@ -23,12 +23,142 @@ format only a subset of files, such as those that are locally modified.
C++ Subset Permitted
====================
-CMake requires compiling as C++11 or above. However, in order to support
-building on older toolchains some constructs need to be handled with care:
+CMake requires compiling as C++11 in order to support building on older
+toolchains. However, to facilitate development, some standard library
+features from more recent C++ standards are supported through a compatibility
+layer. These features are defined under the namespace ``cm`` and headers
+are accessible under the ``cm/`` directory. The headers under ``cm/`` can
+be used in place of the standard ones when extended features are needed.
+For example ``<cm/memory>`` can be used in place of ``<memory>``.
-* Do not use ``std::auto_ptr``.
+Available features are:
- The ``std::auto_ptr`` template is deprecated in C++11. Use ``std::unique_ptr``.
+* From ``C++14``:
+
+ * ``<cm/iterator>``:
+ ``cm::make_reverse_iterator``, ``cm::cbegin``, ``cm::cend``,
+ ``cm::rbegin``, ``cm::rend``, ``cm::crbegin``, ``cm::crend``
+
+ * ``<cm/memory>``:
+ ``cm::make_unique``
+
+ * ``<cm/shared_mutex>``:
+ ``cm::shared_lock``
+
+ * ``<cm/type_traits>``:
+ ``cm::enable_if_t``
+
+* From ``C++17``:
+
+ * ``<cm/algorithm>``:
+ ``cm::clamp``
+
+ * ``<cm/iterator>``:
+ ``cm::size``, ``cm::empty``, ``cm::data``
+
+ * ``<cm/optional>``:
+ ``cm::nullopt_t``, ``cm::nullopt``, ``cm::optional``,
+ ``cm::make_optional``, ``cm::bad_optional_access``
+
+ * ``<cm/shared_mutex>``:
+ ``cm::shared_mutex``
+
+ * ``<cm/string_view>``:
+ ``cm::string_view``
+
+ * ``<cm/type_traits>``:
+ ``cm::bool_constant``, ``cm::invoke_result_t``, ``cm::invoke_result``,
+ ``cm::void_t``
+
+ * ``<cm/utility>``:
+ ``cm::in_place_t``, ``cm::in_place``
+
+* From ``C++20``:
+
+ * ``<cm/deque>``:
+ ``cm::erase``, ``cm::erase_if``
+
+ * ``<cm/list>``:
+ ``cm::erase``, ``cm::erase_if``
+
+ * ``<cm/map>`` :
+ ``cm::erase_if``
+
+ * ``<cm/set>`` :
+ ``cm::erase_if``
+
+ * ``<cm/string>``:
+ ``cm::erase``, ``cm::erase_if``
+
+ * ``<cm/unordered_map>``:
+ ``cm::erase_if``
+
+ * ``<cm/unordered_set>``:
+ ``cm::erase_if``
+
+ * ``<cm/vector>``:
+ ``cm::erase``, ``cm::erase_if``
+
+Additionally, some useful non-standard extensions to the C++ standard library
+are available in headers under the directory ``cmext/`` in namespace ``cm``.
+These are:
+
+* ``<cmext/algorithm>``:
+
+ * ``cm::append``:
+ Append elements to a sequential container.
+
+* ``<cmext/iterator>``:
+
+ * ``cm::is_terator``:
+ Checks if a type is an iterator type.
+
+ * ``cm::is_input_iterator``:
+ Checks if a type is an input iterator type.
+
+ * ``cm::is_range``:
+ Checks if a type is a range type: must have methods ``begin()`` and
+ ``end()`` returning an iterator.
+
+ * ``cm::is_input_range``:
+ Checks if a type is an input range type: must have methods ``begin()`` and
+ ``end()`` returning an input iterator.
+
+* ``<cmext/memory>``:
+
+ * ``cm::static_reference_cast``:
+ Apply a ``static_cast`` to a smart pointer.
+
+ * ``cm::dynamic_reference_cast``:
+ Apply a ``dynamic_cast`` to a smart pointer.
+
+* ``<cmext/type_traits>``:
+
+ * ``cm::is_container``:
+ Checks if a type is a container type.
+
+ * ``cm::is_associative_container``:
+ Checks if a type is an associative container type.
+
+ * ``cm::is_unordered_associative_container``:
+ Checks if a type is an unordered associative container type.
+
+ * ``cm::is_sequence_container``:
+ Checks if a type is a sequence container type.
+
+ * ``cm::is_unique_ptr``:
+ Checks if a type is a ``std::unique_ptr`` type.
+
+Dynamic Memory Management
+=========================
+
+To ensure efficient memory management, i.e. no memory leaks, it is required
+to use smart pointers. Any dynamic memory allocation must be handled by a
+smart pointer such as ``std::unique_ptr`` or ``std::shared_ptr``.
+
+It is allowed to pass raw pointers between objects to enable objects sharing.
+A raw pointer **must** not be deleted. Only the object(s) owning the smart
+pointer are allowed to delete dynamically allocated memory.
Source Tree Layout
==================
@@ -69,6 +199,12 @@ The CMake source tree is organized as follows.
* ``Utilities/``:
Scripts, third-party source code.
+ * ``Utilities/std/cm``:
+ Support files for various C++ standards.
+
+ * ``Utilities/std/cmext``:
+ Extensions to the C++ STL.
+
* ``Utilities/Sphinx/``:
Sphinx configuration to build CMake user documentation.
diff --git a/Help/release/dev/GoogleTest-XML_OUTPUT_DIR.rst b/Help/release/dev/GoogleTest-XML_OUTPUT_DIR.rst
new file mode 100644
index 0000000..ee29e60
--- /dev/null
+++ b/Help/release/dev/GoogleTest-XML_OUTPUT_DIR.rst
@@ -0,0 +1,6 @@
+GoogleTest-XML_OUTPUT_DIR
+-------------------------
+
+* The :module:`GoogleTest` module ``gtest_discover_test`` command
+ gained a new optional parameter ``XML_OUTPUT_DIR``. When set the JUnit XML
+ test results are stored in that directory.
diff --git a/Modules/CMakeASMCompiler.cmake.in b/Modules/CMakeASMCompiler.cmake.in
index b8e09fe..858c053 100644
--- a/Modules/CMakeASMCompiler.cmake.in
+++ b/Modules/CMakeASMCompiler.cmake.in
@@ -10,6 +10,7 @@ set(CMAKE_ASM@ASM_DIALECT@_COMPILER_LOADED 1)
set(CMAKE_ASM@ASM_DIALECT@_COMPILER_ID "@_CMAKE_ASM_COMPILER_ID@")
set(CMAKE_ASM@ASM_DIALECT@_COMPILER_VERSION "@_CMAKE_ASM_COMPILER_VERSION@")
set(CMAKE_ASM@ASM_DIALECT@_COMPILER_ENV_VAR "@_CMAKE_ASM_COMPILER_ENV_VAR@")
+@_SET_CMAKE_ASM_COMPILER_ID_VENDOR_MATCH@
@_SET_CMAKE_ASM_COMPILER_ARCHITECTURE_ID@
set(CMAKE_ASM@ASM_DIALECT@_IGNORE_EXTENSIONS h;H;o;O;obj;OBJ;def;DEF;rc;RC)
diff --git a/Modules/CMakeDetermineASMCompiler.cmake b/Modules/CMakeDetermineASMCompiler.cmake
index e47f3a4..86fb057 100644
--- a/Modules/CMakeDetermineASMCompiler.cmake
+++ b/Modules/CMakeDetermineASMCompiler.cmake
@@ -211,6 +211,13 @@ foreach(_var
set(_CMAKE_ASM_${_var} "${CMAKE_ASM${ASM_DIALECT}_${_var}}")
endforeach()
+if(CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDOR_MATCH)
+ set(_SET_CMAKE_ASM_COMPILER_ID_VENDOR_MATCH
+ "set(CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDOR_MATCH [==[${CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDOR_MATCH}]==])")
+else()
+ set(_SET_CMAKE_ASM_COMPILER_ID_VENDOR_MATCH "")
+endif()
+
if(CMAKE_ASM${ASM_DIALECT}_COMPILER_ARCHITECTURE_ID)
set(_SET_CMAKE_ASM_COMPILER_ARCHITECTURE_ID
"set(CMAKE_ASM${ASM_DIALECT}_COMPILER_ARCHITECTURE_ID ${CMAKE_ASM${ASM_DIALECT}_COMPILER_ARCHITECTURE_ID})")
diff --git a/Modules/CMakeDetermineCompilerId.cmake b/Modules/CMakeDetermineCompilerId.cmake
index d125791..812f032 100644
--- a/Modules/CMakeDetermineCompilerId.cmake
+++ b/Modules/CMakeDetermineCompilerId.cmake
@@ -868,6 +868,14 @@ function(CMAKE_DETERMINE_COMPILER_ID_VENDOR lang userflags)
file(MAKE_DIRECTORY ${CMAKE_${lang}_COMPILER_ID_DIR})
endif()
+ # Save the current LC_ALL, LC_MESSAGES, and LANG environment variables
+ # and set them to "C" so we get the expected output to match.
+ set(_orig_lc_all $ENV{LC_ALL})
+ set(_orig_lc_messages $ENV{LC_MESSAGES})
+ set(_orig_lang $ENV{LANG})
+ set(ENV{LC_ALL} C)
+ set(ENV{LC_MESSAGES} C)
+ set(ENV{LANG} C)
foreach(vendor ${CMAKE_${lang}_COMPILER_ID_VENDORS})
set(flags ${CMAKE_${lang}_COMPILER_ID_VENDOR_FLAGS_${vendor}})
@@ -889,6 +897,7 @@ function(CMAKE_DETERMINE_COMPILER_ID_VENDOR lang userflags)
"matched \"${regex}\":\n${output}")
set(CMAKE_${lang}_COMPILER_ID "${vendor}" PARENT_SCOPE)
set(CMAKE_${lang}_COMPILER_ID_OUTPUT "${output}" PARENT_SCOPE)
+ set(CMAKE_${lang}_COMPILER_ID_VENDOR_MATCH "${CMAKE_MATCH_1}" PARENT_SCOPE)
break()
else()
if("${result}" MATCHES "timeout")
@@ -902,6 +911,11 @@ function(CMAKE_DETERMINE_COMPILER_ID_VENDOR lang userflags)
endif()
endif()
endforeach()
+
+ # Restore original LC_ALL, LC_MESSAGES, and LANG
+ set(ENV{LC_ALL} ${_orig_lc_all})
+ set(ENV{LC_MESSAGES} ${_orig_lc_messages})
+ set(ENV{LANG} ${_orig_lang})
endfunction()
function(CMAKE_DETERMINE_MSVC_SHOWINCLUDES_PREFIX lang userflags)
diff --git a/Modules/Compiler/GNU-ASM.cmake b/Modules/Compiler/GNU-ASM.cmake
index e07401d..4aa680f 100644
--- a/Modules/Compiler/GNU-ASM.cmake
+++ b/Modules/Compiler/GNU-ASM.cmake
@@ -4,3 +4,9 @@ include(Compiler/GNU)
set(CMAKE_ASM_SOURCE_FILE_EXTENSIONS s;S;asm)
__compiler_gnu(ASM)
+
+if(CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDOR_MATCH STREQUAL "GNU assembler")
+ set(CMAKE_DEPFILE_FLAGS_ASM${ASM_DIALECT} "--MD <DEPFILE>")
+ set(CMAKE_ASM${ASM_DIALECT}_LINK_EXECUTABLE
+ "<CMAKE_LINKER> <FLAGS> <CMAKE_ASM${ASM_DIALECT}_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
+endif()
diff --git a/Modules/FindRuby.cmake b/Modules/FindRuby.cmake
index 6918aed..5df242b 100644
--- a/Modules/FindRuby.cmake
+++ b/Modules/FindRuby.cmake
@@ -21,7 +21,7 @@ the following variables:
full path to the ruby binary
``Ruby_INCLUDE_DIRS``
include dirs to be used when using the ruby library
-``Ruby_LIBARY``
+``Ruby_LIBRARY``
full path to the ruby library
``Ruby_VERSION``
the version of ruby which was found, e.g. "1.8.7"
@@ -34,6 +34,22 @@ Also:
same as Ruby_INCLUDE_DIRS, only provided for compatibility reasons, don't use it
#]=======================================================================]
+# Backwards compatibility
+# Define camel case versions of input variables
+foreach(UPPER
+ RUBY_EXECUTABLE
+ RUBY_LIBRARY
+ RUBY_INCLUDE_DIR
+ RUBY_CONFIG_INCLUDE_DIR
+ )
+ if (DEFINED ${UPPER})
+ string(REPLACE "RUBY_" "Ruby_" Camel ${UPPER})
+ if (NOT DEFINED ${Camel})
+ set(${Camel} ${${UPPER}})
+ endif()
+ endif()
+endforeach()
+
# Ruby_ARCHDIR=`$RUBY -r rbconfig -e 'printf("%s",Config::CONFIG@<:@"archdir"@:>@)'`
# Ruby_SITEARCHDIR=`$RUBY -r rbconfig -e 'printf("%s",Config::CONFIG@<:@"sitearchdir"@:>@)'`
# Ruby_SITEDIR=`$RUBY -r rbconfig -e 'printf("%s",Config::CONFIG@<:@"sitelibdir"@:>@)'`
@@ -255,10 +271,10 @@ if(WIN32)
"${_Ruby_ARCH_PREFIX}msvcrt-ruby${_Ruby_NODOT_VERSION}-static" )
endif()
-find_library(Ruby_LIBARY NAMES ${_Ruby_POSSIBLE_LIB_NAMES} HINTS ${Ruby_POSSIBLE_LIB_DIR} )
+find_library(Ruby_LIBRARY NAMES ${_Ruby_POSSIBLE_LIB_NAMES} HINTS ${Ruby_POSSIBLE_LIB_DIR} )
include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
-set(_Ruby_REQUIRED_VARS Ruby_EXECUTABLE Ruby_INCLUDE_DIR Ruby_LIBARY)
+set(_Ruby_REQUIRED_VARS Ruby_EXECUTABLE Ruby_INCLUDE_DIR Ruby_LIBRARY)
if(_Ruby_VERSION_SHORT_NODOT GREATER 18)
list(APPEND _Ruby_REQUIRED_VARS Ruby_CONFIG_INCLUDE_DIR)
endif()
@@ -273,7 +289,7 @@ if(_Ruby_DEBUG_OUTPUT)
message(STATUS "Found Ruby_VERSION: \"${Ruby_VERSION}\" , short: \"${_Ruby_VERSION_SHORT}\", nodot: \"${_Ruby_VERSION_SHORT_NODOT}\"")
message(STATUS "_Ruby_REQUIRED_VARS: ${_Ruby_REQUIRED_VARS}")
message(STATUS "Ruby_EXECUTABLE: ${Ruby_EXECUTABLE}")
- message(STATUS "Ruby_LIBARY: ${Ruby_LIBARY}")
+ message(STATUS "Ruby_LIBRARY: ${Ruby_LIBRARY}")
message(STATUS "Ruby_INCLUDE_DIR: ${Ruby_INCLUDE_DIR}")
message(STATUS "Ruby_CONFIG_INCLUDE_DIR: ${Ruby_CONFIG_INCLUDE_DIR}")
message(STATUS "--------------------")
@@ -284,7 +300,7 @@ FIND_PACKAGE_HANDLE_STANDARD_ARGS(Ruby REQUIRED_VARS ${_Ruby_REQUIRED_VARS}
mark_as_advanced(
Ruby_EXECUTABLE
- Ruby_LIBARY
+ Ruby_LIBRARY
Ruby_INCLUDE_DIR
Ruby_CONFIG_INCLUDE_DIR
)
diff --git a/Modules/FindThreads.cmake b/Modules/FindThreads.cmake
index 85174d9..f97e5c8 100644
--- a/Modules/FindThreads.cmake
+++ b/Modules/FindThreads.cmake
@@ -7,31 +7,44 @@ FindThreads
This module determines the thread library of the system.
-The following variables are set
+Imported Targets
+^^^^^^^^^^^^^^^^
-::
+This module defines the following :prop_tgt:`IMPORTED` target:
- CMAKE_THREAD_LIBS_INIT - the thread library
- CMAKE_USE_WIN32_THREADS_INIT - using WIN32 threads?
- CMAKE_USE_PTHREADS_INIT - are we using pthreads
- CMAKE_HP_PTHREADS_INIT - are we using hp pthreads
+``Threads::Threads``
+ The thread library, if found.
-The following import target is created
+Result Variables
+^^^^^^^^^^^^^^^^
-::
+The following variables are set:
- Threads::Threads
+``Threads_FOUND``
+ If a supported thread library was found.
+``CMAKE_THREAD_LIBS_INIT``
+ The thread library to use. This may be empty if the thread functions
+ are provided by the system libraries and no special flags are needed
+ to use them.
+``CMAKE_USE_WIN32_THREADS_INIT``
+ If the found thread library is the win32 one.
+``CMAKE_USE_PTHREADS_INIT``
+ If the found thread library is pthread compatible.
+``CMAKE_HP_PTHREADS_INIT``
+ If the found thread library is the HP thread library.
-If the use of the -pthread compiler and linker flag is preferred then the
-caller can set
+Variables Affecting Behavior
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-::
+.. variable:: THREADS_PREFER_PTHREAD_FLAG
- THREADS_PREFER_PTHREAD_FLAG
+ If the use of the -pthread compiler and linker flag is preferred then
+ the caller can set this variable to TRUE. 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.
-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 variable has no effect if the system libraries provide the
+ thread functions, i.e. when ``CMAKE_THREAD_LIBS_INIT`` will be empty.
#]=======================================================================]
include (CheckLibraryExists)
diff --git a/Modules/GoogleTest.cmake b/Modules/GoogleTest.cmake
index a5bb863..1d4398e 100644
--- a/Modules/GoogleTest.cmake
+++ b/Modules/GoogleTest.cmake
@@ -151,6 +151,7 @@ same as the Google Test name (i.e. ``suite.testcase``); see also
[PROPERTIES name1 value1...]
[TEST_LIST var]
[DISCOVERY_TIMEOUT seconds]
+ [XML_OUTPUT_DIR dir]
)
``gtest_discover_tests`` sets up a post-build command on the test executable
@@ -236,6 +237,13 @@ same as the Google Test name (i.e. ``suite.testcase``); see also
problem. The ambiguous behavior of the ``TIMEOUT`` keyword in 3.10.1
and 3.10.2 has not been preserved.
+ ``XML_OUTPUT_DIR dir``
+ If specified, the parameter is passed along with ``--gtest_output=xml:``
+ to test executable. The actual file name is the same as the test target,
+ including prefix and suffix. This should be used instead of
+ ``EXTRA_ARGS --gtest_output=xml`` to avoid race conditions writing the
+ XML result output when using parallel test execution.
+
#]=======================================================================]
# Save project's policies
@@ -372,7 +380,7 @@ function(gtest_discover_tests TARGET)
cmake_parse_arguments(
""
"NO_PRETTY_TYPES;NO_PRETTY_VALUES"
- "TEST_PREFIX;TEST_SUFFIX;WORKING_DIRECTORY;TEST_LIST;DISCOVERY_TIMEOUT"
+ "TEST_PREFIX;TEST_SUFFIX;WORKING_DIRECTORY;TEST_LIST;DISCOVERY_TIMEOUT;XML_OUTPUT_DIR"
"EXTRA_ARGS;PROPERTIES"
${ARGN}
)
@@ -434,6 +442,7 @@ function(gtest_discover_tests TARGET)
-D "TEST_LIST=${_TEST_LIST}"
-D "CTEST_FILE=${ctest_tests_file}"
-D "TEST_DISCOVERY_TIMEOUT=${_DISCOVERY_TIMEOUT}"
+ -D "TEST_XML_OUTPUT_DIR=${_XML_OUTPUT_DIR}"
-P "${_GOOGLETEST_DISCOVER_TESTS_SCRIPT}"
VERBATIM
)
diff --git a/Modules/GoogleTestAddTests.cmake b/Modules/GoogleTestAddTests.cmake
index 73e55ea..753319f 100644
--- a/Modules/GoogleTestAddTests.cmake
+++ b/Modules/GoogleTestAddTests.cmake
@@ -99,6 +99,11 @@ foreach(line ${output})
endif()
string(REGEX REPLACE "^DISABLED_" "" pretty_test "${pretty_test}")
string(REGEX REPLACE "#.*" "" test "${test}")
+ if(NOT TEST_XML_OUTPUT_DIR STREQUAL "")
+ set(TEST_XML_OUTPUT_PARAM "--gtest_output=xml:${TEST_XML_OUTPUT_DIR}/${prefix}${pretty_suite}.${pretty_test}${suffix}.xml")
+ else()
+ unset(TEST_XML_OUTPUT_PARAM)
+ endif()
# ...and add to script
add_command(add_test
"${prefix}${pretty_suite}.${pretty_test}${suffix}"
@@ -106,6 +111,7 @@ foreach(line ${output})
"${TEST_EXECUTABLE}"
"--gtest_filter=${suite}.${test}"
"--gtest_also_run_disabled_tests"
+ ${TEST_XML_OUTPUT_PARAM}
${extra_args}
)
if(suite MATCHES "^DISABLED" OR test MATCHES "^DISABLED")
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index 1b452f8..d68a4c9 100644
--- a/Source/CMakeVersion.cmake
+++ b/Source/CMakeVersion.cmake
@@ -1,7 +1,7 @@
# CMake version number components.
set(CMake_VERSION_MAJOR 3)
set(CMake_VERSION_MINOR 17)
-set(CMake_VERSION_PATCH 20200313)
+set(CMake_VERSION_PATCH 20200317)
#set(CMake_VERSION_RC 0)
set(CMake_VERSION_IS_DIRTY 0)
diff --git a/Source/cmCPluginAPI.cxx b/Source/cmCPluginAPI.cxx
index 0104ef7..874efa5 100644
--- a/Source/cmCPluginAPI.cxx
+++ b/Source/cmCPluginAPI.cxx
@@ -776,8 +776,9 @@ void CCONV DefineSourceFileProperty(void* arg, const char* name,
const char* longDocs, int chained)
{
cmMakefile* mf = static_cast<cmMakefile*>(arg);
- mf->GetState()->DefineProperty(name, cmProperty::SOURCE_FILE, briefDocs,
- longDocs, chained != 0);
+ mf->GetState()->DefineProperty(name, cmProperty::SOURCE_FILE,
+ briefDocs ? briefDocs : "",
+ longDocs ? longDocs : "", chained != 0);
}
} // close the extern "C" scope
diff --git a/Source/cmDefinePropertyCommand.cxx b/Source/cmDefinePropertyCommand.cxx
index f4e4fda..4e2d9b0 100644
--- a/Source/cmDefinePropertyCommand.cxx
+++ b/Source/cmDefinePropertyCommand.cxx
@@ -95,7 +95,7 @@ bool cmDefinePropertyCommand(std::vector<std::string> const& args,
// Actually define the property.
status.GetMakefile().GetState()->DefineProperty(
- PropertyName, scope, BriefDocs.c_str(), FullDocs.c_str(), inherited);
+ PropertyName, scope, BriefDocs, FullDocs, inherited);
return true;
}
diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx
index 72a0d74..003019a 100644
--- a/Source/cmExportFileGenerator.cxx
+++ b/Source/cmExportFileGenerator.cxx
@@ -1116,7 +1116,7 @@ void cmExportFileGenerator::GenerateMissingTargetsCheckCode(
return;
}
/* clang-format off */
- os << "# Make sure the targets which have been exported in some other \n"
+ os << "# Make sure the targets which have been exported in some other\n"
"# export set exist.\n"
"unset(${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE_targets)\n"
"foreach(_target ";
diff --git a/Source/cmMakefileProfilingData.cxx b/Source/cmMakefileProfilingData.cxx
index ea64132..adf4eee 100644
--- a/Source/cmMakefileProfilingData.cxx
+++ b/Source/cmMakefileProfilingData.cxx
@@ -3,7 +3,6 @@
#include "cmMakefileProfilingData.h"
#include <chrono>
-#include <cstdint>
#include <stdexcept>
#include <vector>
@@ -61,9 +60,10 @@ void cmMakefileProfilingData::StartEntry(const cmListFileFunction& lff,
v["ph"] = "B";
v["name"] = lff.Name.Original;
v["cat"] = "cmake";
- v["ts"] = uint64_t(std::chrono::duration_cast<std::chrono::microseconds>(
- std::chrono::steady_clock::now().time_since_epoch())
- .count());
+ v["ts"] = Json::Value::UInt64(
+ std::chrono::duration_cast<std::chrono::microseconds>(
+ std::chrono::steady_clock::now().time_since_epoch())
+ .count());
v["pid"] = static_cast<int>(info.GetProcessId());
v["tid"] = 0;
Json::Value argsValue;
@@ -98,9 +98,10 @@ void cmMakefileProfilingData::StopEntry()
cmsys::SystemInformation info;
Json::Value v;
v["ph"] = "E";
- v["ts"] = uint64_t(std::chrono::duration_cast<std::chrono::microseconds>(
- std::chrono::steady_clock::now().time_since_epoch())
- .count());
+ v["ts"] = Json::Value::UInt64(
+ std::chrono::duration_cast<std::chrono::microseconds>(
+ std::chrono::steady_clock::now().time_since_epoch())
+ .count());
v["pid"] = static_cast<int>(info.GetProcessId());
v["tid"] = 0;
this->JsonWriter->write(v, &this->ProfileStream);
diff --git a/Source/cmPropertyDefinition.cxx b/Source/cmPropertyDefinition.cxx
index 6a3174c..c8efaf6 100644
--- a/Source/cmPropertyDefinition.cxx
+++ b/Source/cmPropertyDefinition.cxx
@@ -2,19 +2,17 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmPropertyDefinition.h"
-void cmPropertyDefinition::DefineProperty(const std::string& name,
- cmProperty::ScopeType scope,
- const char* shortDescription,
- const char* fullDescription,
- bool chain)
+#include <utility>
+
+cmPropertyDefinition::cmPropertyDefinition(std::string name,
+ cmProperty::ScopeType scope,
+ std::string shortDescription,
+ std::string fullDescription,
+ bool chain)
+ : Name(std::move(name))
+ , ShortDescription(std::move(shortDescription))
+ , FullDescription(std::move(fullDescription))
+ , Scope(scope)
+ , Chained(chain)
{
- this->Name = name;
- this->Scope = scope;
- this->Chained = chain;
- if (shortDescription) {
- this->ShortDescription = shortDescription;
- }
- if (fullDescription) {
- this->FullDescription = fullDescription;
- }
}
diff --git a/Source/cmPropertyDefinition.h b/Source/cmPropertyDefinition.h
index 0d68c32..d2e4467 100644
--- a/Source/cmPropertyDefinition.h
+++ b/Source/cmPropertyDefinition.h
@@ -21,13 +21,10 @@
class cmPropertyDefinition
{
public:
- /// Define this property
- void DefineProperty(const std::string& name, cmProperty::ScopeType scope,
- const char* ShortDescription,
- const char* FullDescription, bool chained);
-
- /// Default constructor
- cmPropertyDefinition() { this->Chained = false; }
+ /// Constructor
+ cmPropertyDefinition(std::string name, cmProperty::ScopeType scope,
+ std::string ShortDescription,
+ std::string FullDescription, bool chained = false);
/// Is the property chained?
bool IsChained() const { return this->Chained; }
diff --git a/Source/cmPropertyDefinitionMap.cxx b/Source/cmPropertyDefinitionMap.cxx
index f752ed7..614d5a4 100644
--- a/Source/cmPropertyDefinitionMap.cxx
+++ b/Source/cmPropertyDefinitionMap.cxx
@@ -2,20 +2,20 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmPropertyDefinitionMap.h"
+#include <tuple>
#include <utility>
-void cmPropertyDefinitionMap::DefineProperty(const std::string& name,
- cmProperty::ScopeType scope,
- const char* ShortDescription,
- const char* FullDescription,
- bool chain)
+void cmPropertyDefinitionMap::DefineProperty(
+ const std::string& name, cmProperty::ScopeType scope,
+ const std::string& ShortDescription, const std::string& FullDescription,
+ bool chain)
{
auto it = this->find(name);
- cmPropertyDefinition* prop;
if (it == this->end()) {
- prop = &(*this)[name];
- prop->DefineProperty(name, scope, ShortDescription, FullDescription,
- chain);
+ // try_emplace() since C++17
+ this->emplace(std::piecewise_construct, std::forward_as_tuple(name),
+ std::forward_as_tuple(name, scope, ShortDescription,
+ FullDescription, chain));
}
}
diff --git a/Source/cmPropertyDefinitionMap.h b/Source/cmPropertyDefinitionMap.h
index 8ec7910..2ae6efb 100644
--- a/Source/cmPropertyDefinitionMap.h
+++ b/Source/cmPropertyDefinitionMap.h
@@ -17,8 +17,8 @@ class cmPropertyDefinitionMap
public:
// define the property
void DefineProperty(const std::string& name, cmProperty::ScopeType scope,
- const char* ShortDescription,
- const char* FullDescription, bool chain);
+ const std::string& ShortDescription,
+ const std::string& FullDescription, bool chain);
// has a named property been defined
bool IsPropertyDefined(const std::string& name) const;
diff --git a/Source/cmState.cxx b/Source/cmState.cxx
index 1e2d83e..f424afa 100644
--- a/Source/cmState.cxx
+++ b/Source/cmState.cxx
@@ -335,8 +335,8 @@ cmStateSnapshot cmState::Reset()
void cmState::DefineProperty(const std::string& name,
cmProperty::ScopeType scope,
- const char* ShortDescription,
- const char* FullDescription, bool chained)
+ const std::string& ShortDescription,
+ const std::string& FullDescription, bool chained)
{
this->PropertyDefinitions[scope].DefineProperty(
name, scope, ShortDescription, FullDescription, chained);
diff --git a/Source/cmState.h b/Source/cmState.h
index 6ee2b0c..460c6bb 100644
--- a/Source/cmState.h
+++ b/Source/cmState.h
@@ -121,8 +121,8 @@ public:
cmStateSnapshot Reset();
// Define a property
void DefineProperty(const std::string& name, cmProperty::ScopeType scope,
- const char* ShortDescription,
- const char* FullDescription, bool chain = false);
+ const std::string& ShortDescription,
+ const std::string& FullDescription, bool chain = false);
// get property definition
cmPropertyDefinition const* GetPropertyDefinition(
diff --git a/Tests/RunCMake/BuildDepends/GNU-AS-stdout.txt b/Tests/RunCMake/BuildDepends/GNU-AS-stdout.txt
new file mode 100644
index 0000000..c4326ae
--- /dev/null
+++ b/Tests/RunCMake/BuildDepends/GNU-AS-stdout.txt
@@ -0,0 +1,4 @@
+-- The ASM compiler identification is GNU
+-- Found assembler: [^
+]*/as(\.exe)?
+-- CMAKE_ASM_COMPILER_ID_VENDOR_MATCH='GNU assembler'
diff --git a/Tests/RunCMake/BuildDepends/GNU-AS.cmake b/Tests/RunCMake/BuildDepends/GNU-AS.cmake
new file mode 100644
index 0000000..21921ef
--- /dev/null
+++ b/Tests/RunCMake/BuildDepends/GNU-AS.cmake
@@ -0,0 +1,13 @@
+enable_language(ASM)
+
+# Validate undocumented implementation detail.
+message(STATUS "CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDOR_MATCH='${CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDOR_MATCH}'")
+
+add_library(gnu_as STATIC gnu_as.s)
+target_include_directories(gnu_as PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
+
+file(GENERATE OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/check-$<LOWER_CASE:$<CONFIG>>.cmake CONTENT "
+set(check_pairs
+ \"$<TARGET_FILE:gnu_as>|${CMAKE_CURRENT_BINARY_DIR}/gnu_as.inc\"
+ )
+")
diff --git a/Tests/RunCMake/BuildDepends/GNU-AS.step1.cmake b/Tests/RunCMake/BuildDepends/GNU-AS.step1.cmake
new file mode 100644
index 0000000..15a5e96
--- /dev/null
+++ b/Tests/RunCMake/BuildDepends/GNU-AS.step1.cmake
@@ -0,0 +1 @@
+file(WRITE "${RunCMake_TEST_BINARY_DIR}/gnu_as.inc" "")
diff --git a/Tests/RunCMake/BuildDepends/GNU-AS.step2.cmake b/Tests/RunCMake/BuildDepends/GNU-AS.step2.cmake
new file mode 100644
index 0000000..15a5e96
--- /dev/null
+++ b/Tests/RunCMake/BuildDepends/GNU-AS.step2.cmake
@@ -0,0 +1 @@
+file(WRITE "${RunCMake_TEST_BINARY_DIR}/gnu_as.inc" "")
diff --git a/Tests/RunCMake/BuildDepends/RunCMakeTest.cmake b/Tests/RunCMake/BuildDepends/RunCMakeTest.cmake
index 14ae243..753417d 100644
--- a/Tests/RunCMake/BuildDepends/RunCMakeTest.cmake
+++ b/Tests/RunCMake/BuildDepends/RunCMakeTest.cmake
@@ -103,3 +103,8 @@ endfunction()
if(RunCMake_GENERATOR STREQUAL "Xcode")
run_ReGeneration(regenerate-project)
endif()
+
+if(CMake_TEST_BuildDepends_GNU_AS)
+ set(ENV{ASM} "${CMake_TEST_BuildDepends_GNU_AS}")
+ run_BuildDepends(GNU-AS)
+endif()
diff --git a/Tests/RunCMake/BuildDepends/gnu_as.s b/Tests/RunCMake/BuildDepends/gnu_as.s
new file mode 100644
index 0000000..a2e7dfb
--- /dev/null
+++ b/Tests/RunCMake/BuildDepends/gnu_as.s
@@ -0,0 +1 @@
+.include "gnu_as.inc"
diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt
index 4b5475e..f99f704 100644
--- a/Tests/RunCMake/CMakeLists.txt
+++ b/Tests/RunCMake/CMakeLists.txt
@@ -169,7 +169,20 @@ if(CMake_TEST_Qt5 AND Qt5Widgets_FOUND)
set(autogen_with_qt5 TRUE)
endif ()
add_RunCMake_test(Autogen -Dwith_qt5=${autogen_with_qt5})
-add_RunCMake_test(BuildDepends)
+if(NOT DEFINED CMake_TEST_BuildDepends_GNU_AS
+ AND CMAKE_C_COMPILER_ID STREQUAL "GNU"
+ AND CMAKE_GENERATOR MATCHES "^Ninja"
+ )
+ execute_process(COMMAND "${CMAKE_C_COMPILER}" -print-prog-name=as
+ RESULT_VARIABLE _gnu_res
+ OUTPUT_VARIABLE _gnu_as OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET)
+ if(_gnu_res EQUAL 0 AND _gnu_as)
+ set(CMake_TEST_BuildDepends_GNU_AS "${_gnu_as}")
+ endif()
+endif()
+add_RunCMake_test(BuildDepends
+ -DCMake_TEST_BuildDepends_GNU_AS=${CMake_TEST_BuildDepends_GNU_AS}
+ )
if(UNIX AND "${CMAKE_GENERATOR}" MATCHES "Unix Makefiles|Ninja")
add_RunCMake_test(Byproducts)
endif()
diff --git a/Tests/RunCMake/GoogleTest/GoogleTestXML-result-check.cmake b/Tests/RunCMake/GoogleTest/GoogleTestXML-result-check.cmake
new file mode 100644
index 0000000..3bfdac3
--- /dev/null
+++ b/Tests/RunCMake/GoogleTest/GoogleTestXML-result-check.cmake
@@ -0,0 +1,4 @@
+set(RESULT_FILE "${RunCMake_TEST_BINARY_DIR}/GoogleTestXML.Foo.xml")
+if(NOT EXISTS ${RESULT_FILE})
+ set(RunCMake_TEST_FAILED "Result XML file ${RESULT_FILE} was not created")
+endif()
diff --git a/Tests/RunCMake/GoogleTest/GoogleTestXML.cmake b/Tests/RunCMake/GoogleTest/GoogleTestXML.cmake
new file mode 100644
index 0000000..c86de63
--- /dev/null
+++ b/Tests/RunCMake/GoogleTest/GoogleTestXML.cmake
@@ -0,0 +1,11 @@
+project(test_include_dirs)
+include(CTest)
+include(GoogleTest)
+
+enable_testing()
+
+add_executable(xml_output xml_output.cpp)
+gtest_discover_tests(
+ xml_output
+ XML_OUTPUT_DIR ${CMAKE_BINARY_DIR}
+)
diff --git a/Tests/RunCMake/GoogleTest/RunCMakeTest.cmake b/Tests/RunCMake/GoogleTest/RunCMakeTest.cmake
index 8c6b507..8070512 100644
--- a/Tests/RunCMake/GoogleTest/RunCMakeTest.cmake
+++ b/Tests/RunCMake/GoogleTest/RunCMakeTest.cmake
@@ -78,4 +78,32 @@ function(run_GoogleTest)
)
endfunction()
+function(run_GoogleTestXML)
+ # Use a single build tree for a few tests without cleaning.
+ set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/GoogleTestXML-build)
+ set(RunCMake_TEST_NO_CLEAN 1)
+ if(NOT RunCMake_GENERATOR_IS_MULTI_CONFIG)
+ set(RunCMake_TEST_OPTIONS -DCMAKE_BUILD_TYPE=Debug)
+ endif()
+ file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+ file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+
+ run_cmake(GoogleTestXML)
+
+ run_cmake_command(GoogleTestXML-discovery
+ ${CMAKE_COMMAND}
+ --build .
+ --config Debug
+ --target xml_output
+ )
+
+ run_cmake_command(GoogleTestXML-result
+ ${CMAKE_CTEST_COMMAND}
+ -C Debug
+ -R GoogleTestXML
+ --no-label-summary
+ )
+endfunction()
+
run_GoogleTest()
+run_GoogleTestXML()
diff --git a/Tests/RunCMake/GoogleTest/xml_output.cpp b/Tests/RunCMake/GoogleTest/xml_output.cpp
new file mode 100644
index 0000000..e130231
--- /dev/null
+++ b/Tests/RunCMake/GoogleTest/xml_output.cpp
@@ -0,0 +1,26 @@
+#include <fstream>
+#include <iostream>
+#include <string>
+
+int main(int argc, char** argv)
+{
+ // Note: GoogleTestXML.cmake doesn't actually depend on Google Test as such;
+ // it only mimicks the output file creation using the path passed to this
+ // test without any content
+ for (int i = 0; i < argc; i++) {
+ std::string param(argv[i]);
+ if (param.find("--gtest_list_tests") != std::string::npos) {
+ // This actually defines the name of the file passed in the 2nd run
+ std::cout << "GoogleTestXML." << std::endl;
+ std::cout << " Foo" << std::endl;
+ } else if (param.find("--gtest_output=xml:") != std::string::npos) {
+ std::string::size_type split = param.find(":");
+ std::string filepath = param.substr(split + 1);
+ // The full file path is passed
+ std::ofstream ostrm(filepath.c_str(), std::ios::binary);
+ ostrm << "--gtest_output=xml: mockup file\n";
+ }
+ }
+
+ return 0;
+}