diff options
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; +} |