summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt8
-rw-r--r--Help/release/dev/apple-clang-supports-cxx20.rst4
-rw-r--r--Help/release/dev/iar-new_architectures.rst6
-rw-r--r--Modules/CMakePlatformId.h.in9
-rw-r--r--Modules/Compiler/AppleClang-CXX.cmake8
-rw-r--r--Modules/Compiler/IAR-ASM.cmake15
-rw-r--r--Modules/Compiler/IAR-C.cmake21
-rw-r--r--Modules/Compiler/IAR-CXX.cmake34
-rw-r--r--Modules/Compiler/IAR-DetermineCompiler.cmake2
-rw-r--r--Modules/Compiler/IAR-FindBinUtils.cmake9
-rw-r--r--Modules/Compiler/Intel-CXX-FeatureTests.cmake2
-rw-r--r--Modules/Compiler/Intel-CXX.cmake8
-rw-r--r--Modules/Compiler/MSVC-CXX-FeatureTests.cmake6
-rw-r--r--Modules/Compiler/MSVC-CXX.cmake1
-rw-r--r--Modules/FindProtobuf.cmake7
-rw-r--r--Modules/FindSWIG.cmake2
-rw-r--r--Modules/FindXCTest.cmake19
-rw-r--r--Source/CMakeInstallSignTool.cmake.in51
-rw-r--r--Source/CMakeLists.txt2
-rw-r--r--Source/CMakeVersion.cmake2
-rw-r--r--Source/cmGlobalGenerator.cxx4
-rw-r--r--Source/cmGlobalNinjaGenerator.cxx268
-rw-r--r--Source/cmGlobalNinjaGenerator.h31
-rw-r--r--Source/cmInstallDirectoryGenerator.cxx5
-rw-r--r--Source/cmInstallDirectoryGenerator.h2
-rw-r--r--Source/cmInstallExportAndroidMKGenerator.cxx3
-rw-r--r--Source/cmInstallExportAndroidMKGenerator.h2
-rw-r--r--Source/cmInstallExportGenerator.cxx3
-rw-r--r--Source/cmInstallExportGenerator.h2
-rw-r--r--Source/cmInstallFilesGenerator.cxx3
-rw-r--r--Source/cmInstallFilesGenerator.h2
-rw-r--r--Source/cmInstallGenerator.h2
-rw-r--r--Source/cmInstallScriptGenerator.cxx4
-rw-r--r--Source/cmInstallScriptGenerator.h2
-rw-r--r--Source/cmInstallSubdirectoryGenerator.cxx3
-rw-r--r--Source/cmInstallSubdirectoryGenerator.h2
-rw-r--r--Source/cmInstallTargetGenerator.cxx4
-rw-r--r--Source/cmInstallTargetGenerator.h2
-rw-r--r--Source/cmLocalNinjaGenerator.cxx9
-rw-r--r--Source/cmNinjaTargetGenerator.cxx152
-rw-r--r--Source/cmNinjaTargetGenerator.h4
-rw-r--r--Source/cmQtAutoGenerator.cxx3
-rw-r--r--Source/cmQtAutoRcc.cxx123
-rw-r--r--Source/cmQtAutoRcc.h2
-rw-r--r--Source/cmUVHandlePtr.cxx8
-rw-r--r--Source/cmUVProcessChain.cxx392
-rw-r--r--Source/cmUVProcessChain.h100
-rw-r--r--Source/cmUVStreambuf.h8
-rw-r--r--Source/cmake.cxx5
-rw-r--r--Tests/CMakeLib/CMakeLists.txt4
-rw-r--r--Tests/CMakeLib/testUVProcessChain.cxx335
-rw-r--r--Tests/CMakeLib/testUVProcessChainHelper.cxx72
-rw-r--r--Tests/CompileFeatures/cxx_relaxed_constexpr.cpp3
-rw-r--r--Tests/RunCMake/CMP0069/CMP0069-NEW-cmake-stderr.txt4
-rw-r--r--Tests/RunCMake/CMP0069/CMP0069-NEW-compiler-stderr.txt4
-rw-r--r--Tests/RunCMake/CMP0069/CMP0069-NEW-generator-stderr.txt4
-rw-r--r--Tests/RunCMake/GeneratorExpression/BadAND-stderr.txt4
-rw-r--r--Tests/RunCMake/GeneratorExpression/BadCONFIG-stderr.txt4
-rw-r--r--Tests/RunCMake/GeneratorExpression/BadNOT-stderr.txt4
-rw-r--r--Tests/RunCMake/GeneratorExpression/BadOR-stderr.txt4
-rw-r--r--Tests/RunCMake/GeneratorExpression/BadStrEqual-stderr.txt4
-rw-r--r--Tests/RunCMake/GeneratorExpression/BadTargetName-stderr.txt4
-rw-r--r--Tests/RunCMake/MSVCRuntimeLibrary/CMP0091-NEW-stderr.txt4
-rw-r--r--Tests/RunCMake/ObjectLibrary/OwnSources-stderr.txt4
-rw-r--r--Tests/RunCMake/TargetPropertyGeneratorExpressions/BadInvalidName-stderr.txt4
-rw-r--r--Tests/RunCMake/TargetPropertyGeneratorExpressions/BadNonTarget-stderr.txt4
-rw-r--r--Tests/RunCMake/TargetPropertyGeneratorExpressions/BadSelfReference-stderr.txt4
-rw-r--r--Tests/RunCMake/XcodeProject/PerConfigPerSourceDefinitions-stderr.txt4
-rw-r--r--Tests/RunCMake/XcodeProject/PerConfigPerSourceFlags-stderr.txt4
-rw-r--r--Tests/RunCMake/XcodeProject/PerConfigPerSourceIncludeDirs-stderr.txt4
-rw-r--r--Tests/RunCMake/XcodeProject/PerConfigPerSourceOptions-stderr.txt4
-rw-r--r--Tests/RunCMake/XcodeProject/RunCMakeTest.cmake15
-rw-r--r--Tests/RunCMake/XcodeProject/XCTestLookup.cmake3
-rw-r--r--Tests/RunCMake/add_executable/NoSources-stderr.txt4
-rw-r--r--Tests/RunCMake/add_executable/NoSourcesButLinkObjects-stderr.txt4
-rw-r--r--Tests/RunCMake/add_library/MODULEwithNoSources-stderr.txt4
-rw-r--r--Tests/RunCMake/add_library/MODULEwithNoSourcesButLinkObjects-stderr.txt4
-rw-r--r--Tests/RunCMake/add_library/OBJECTwithNoSources-stderr.txt4
-rw-r--r--Tests/RunCMake/add_library/OBJECTwithNoSourcesButLinkObjects-stderr.txt4
-rw-r--r--Tests/RunCMake/add_library/SHAREDwithNoSources-stderr.txt4
-rw-r--r--Tests/RunCMake/add_library/SHAREDwithNoSourcesButLinkObjects-stderr.txt4
-rw-r--r--Tests/RunCMake/add_library/STATICwithNoSources-stderr.txt4
-rw-r--r--Tests/RunCMake/add_library/STATICwithNoSourcesButLinkObjects-stderr.txt4
-rw-r--r--Utilities/Doxygen/CMakeLists.txt2
-rw-r--r--Utilities/Release/linux64_release.cmake1
-rw-r--r--Utilities/Release/osx_release.cmake1
-rwxr-xr-xUtilities/Release/release_cmake.sh.in2
-rw-r--r--Utilities/Release/win32_release.cmake4
-rw-r--r--Utilities/Release/win64_release.cmake4
-rw-r--r--Utilities/Sphinx/CMakeLists.txt2
-rwxr-xr-xbootstrap2
91 files changed, 1526 insertions, 402 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index fc033ba..51a1d8b 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,7 +1,7 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.
-cmake_minimum_required(VERSION 3.1...3.12 FATAL_ERROR)
+cmake_minimum_required(VERSION 3.1...3.14 FATAL_ERROR)
set(CMAKE_USER_MAKE_RULES_OVERRIDE_C ${CMAKE_CURRENT_SOURCE_DIR}/Source/Modules/OverrideC.cmake)
set(CMAKE_USER_MAKE_RULES_OVERRIDE_CXX ${CMAKE_CURRENT_SOURCE_DIR}/Source/Modules/OverrideCXX.cmake)
project(CMake)
@@ -822,4 +822,10 @@ if(NOT CMake_TEST_EXTERNAL_CMAKE)
# Install auxiliary files integrating with other tools.
add_subdirectory(Auxiliary)
+
+ # Optionally sign installed binaries.
+ if(CMake_INSTALL_SIGNTOOL)
+ configure_file(Source/CMakeInstallSignTool.cmake.in Source/CMakeInstallSignTool.cmake @ONLY)
+ install(SCRIPT ${CMAKE_CURRENT_BINARY_DIR}/Source/CMakeInstallSignTool.cmake)
+ endif()
endif()
diff --git a/Help/release/dev/apple-clang-supports-cxx20.rst b/Help/release/dev/apple-clang-supports-cxx20.rst
new file mode 100644
index 0000000..f19ee68
--- /dev/null
+++ b/Help/release/dev/apple-clang-supports-cxx20.rst
@@ -0,0 +1,4 @@
+apple-clang-supports-cxx20
+--------------------------
+
+* AppleClang compiler have learned how to compile C++20.
diff --git a/Help/release/dev/iar-new_architectures.rst b/Help/release/dev/iar-new_architectures.rst
new file mode 100644
index 0000000..d661c80
--- /dev/null
+++ b/Help/release/dev/iar-new_architectures.rst
@@ -0,0 +1,6 @@
+iar-new_architectures
+---------------------
+
+* Support was added for the IAR compiler architectures Renesas RX,
+ RL78, RH850 and Texas Instruments MSP430.
+* The IAR compilers built for Linux (IAR BuildLx) now work as well.
diff --git a/Modules/CMakePlatformId.h.in b/Modules/CMakePlatformId.h.in
index c88094a..8f5747a 100644
--- a/Modules/CMakePlatformId.h.in
+++ b/Modules/CMakePlatformId.h.in
@@ -159,9 +159,18 @@
# elif defined(__ICCRX__)
# define ARCHITECTURE_ID "RX"
+# elif defined(__ICCRH850__)
+# define ARCHITECTURE_ID "RH850"
+
+# elif defined(__ICCRL78__)
+# define ARCHITECTURE_ID "RL78"
+
# elif defined(__ICCAVR__)
# define ARCHITECTURE_ID "AVR"
+# elif defined(__ICC430__)
+# define ARCHITECTURE_ID "MSP430"
+
# else /* unknown architecture */
# define ARCHITECTURE_ID ""
# endif
diff --git a/Modules/Compiler/AppleClang-CXX.cmake b/Modules/Compiler/AppleClang-CXX.cmake
index 2042360..3fa6990 100644
--- a/Modules/Compiler/AppleClang-CXX.cmake
+++ b/Modules/Compiler/AppleClang-CXX.cmake
@@ -17,10 +17,12 @@ endif()
if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 6.1)
set(CMAKE_CXX14_STANDARD_COMPILE_OPTION "-std=c++14")
set(CMAKE_CXX14_EXTENSION_COMPILE_OPTION "-std=gnu++14")
+ set(CMAKE_CXX14_STANDARD__HAS_FULL_SUPPORT ON)
elseif(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.1)
# AppleClang 5.0 knows this flag, but does not set a __cplusplus macro greater than 201103L
set(CMAKE_CXX14_STANDARD_COMPILE_OPTION "-std=c++1y")
set(CMAKE_CXX14_EXTENSION_COMPILE_OPTION "-std=gnu++1y")
+ set(CMAKE_CXX14_STANDARD__HAS_FULL_SUPPORT ON)
endif()
if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 6.1)
@@ -28,9 +30,13 @@ if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 6.1)
set(CMAKE_CXX17_EXTENSION_COMPILE_OPTION "-std=gnu++1z")
endif()
-
if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 8.0)
set(CMAKE_CXX11_STANDARD__HAS_FULL_SUPPORT ON)
endif()
+if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 10.0)
+ set(CMAKE_CXX20_STANDARD_COMPILE_OPTION "-std=c++2a")
+ set(CMAKE_CXX20_EXTENSION_COMPILE_OPTION "-std=gnu++2a")
+endif()
+
__compiler_check_default_language_standard(CXX 4.0 98)
diff --git a/Modules/Compiler/IAR-ASM.cmake b/Modules/Compiler/IAR-ASM.cmake
index f9c0ced..71f2ac6 100644
--- a/Modules/Compiler/IAR-ASM.cmake
+++ b/Modules/Compiler/IAR-ASM.cmake
@@ -12,11 +12,26 @@ elseif("${CMAKE_ASM${ASM_DIALECT}_COMPILER_ARCHITECTURE_ID}" STREQUAL "RX")
__compiler_iar_ilink(ASM)
set(CMAKE_ASM_SOURCE_FILE_EXTENSIONS s;asm;msa)
+elseif("${CMAKE_ASM${ASM_DIALECT}_COMPILER_ARCHITECTURE_ID}" STREQUAL "RH850")
+ set(CMAKE_ASM_COMPILE_OBJECT "<CMAKE_ASM_COMPILER> --silent <SOURCE> <DEFINES> <INCLUDES> <FLAGS> -o <OBJECT>")
+ __compiler_iar_ilink(ASM)
+ set(CMAKE_ASM_SOURCE_FILE_EXTENSIONS s;asm;msa)
+
+elseif("${CMAKE_ASM${ASM_DIALECT}_COMPILER_ARCHITECTURE_ID}" STREQUAL "RL78")
+ set(CMAKE_ASM_COMPILE_OBJECT "<CMAKE_ASM_COMPILER> --silent <SOURCE> <DEFINES> <INCLUDES> <FLAGS> -o <OBJECT>")
+ __compiler_iar_ilink(ASM)
+ set(CMAKE_ASM_SOURCE_FILE_EXTENSIONS s;asm;msa)
+
elseif("${CMAKE_ASM${ASM_DIALECT}_COMPILER_ARCHITECTURE_ID}" STREQUAL "AVR")
set(CMAKE_ASM_COMPILE_OBJECT "<CMAKE_ASM_COMPILER> -S <SOURCE> <DEFINES> <INCLUDES> <FLAGS> -o <OBJECT>")
__compiler_iar_xlink(ASM)
set(CMAKE_ASM_SOURCE_FILE_EXTENSIONS s90;asm;msa)
+elseif("${CMAKE_ASM${ASM_DIALECT}_COMPILER_ARCHITECTURE_ID}" STREQUAL "MSP430")
+ set(CMAKE_ASM_COMPILE_OBJECT "<CMAKE_ASM_COMPILER> -S <SOURCE> <DEFINES> <INCLUDES> <FLAGS> -o <OBJECT>")
+ __compiler_iar_xlink(ASM)
+ set(CMAKE_ASM_SOURCE_FILE_EXTENSIONS s43;asm;msa)
+
else()
message(FATAL_ERROR "CMAKE_ASM${ASM_DIALECT}_COMPILER_ARCHITECTURE_ID not detected. This should be automatic.")
endif()
diff --git a/Modules/Compiler/IAR-C.cmake b/Modules/Compiler/IAR-C.cmake
index af5874c..4b02a9a 100644
--- a/Modules/Compiler/IAR-C.cmake
+++ b/Modules/Compiler/IAR-C.cmake
@@ -38,20 +38,23 @@ elseif("${CMAKE_C_COMPILER_ARCHITECTURE_ID}" STREQUAL "RX")
__compiler_iar_ilink(C)
__compiler_check_default_language_standard(C 1.10 90 2.10 99 4.10 11)
+elseif("${CMAKE_C_COMPILER_ARCHITECTURE_ID}" STREQUAL "RH850")
+ __compiler_iar_ilink(C)
+ __compiler_check_default_language_standard(C 1.10 90 1.10 99 2.10 11)
+
+elseif("${CMAKE_C_COMPILER_ARCHITECTURE_ID}" STREQUAL "RL78")
+ __compiler_iar_ilink(C)
+ __compiler_check_default_language_standard(C 1.10 90 1.10 99 4.10 11)
+
elseif("${CMAKE_C_COMPILER_ARCHITECTURE_ID}" STREQUAL "AVR")
__compiler_iar_xlink(C)
__compiler_check_default_language_standard(C 7.10 99)
set(CMAKE_C_OUTPUT_EXTENSION ".r90")
- if(NOT CMAKE_C_LINK_FLAGS)
- set(CMAKE_C_LINK_FLAGS "-Fmotorola")
- endif()
-
- # add the target specific include directory:
- get_filename_component(_compilerDir "${CMAKE_C_COMPILER}" PATH)
- get_filename_component(_compilerDir "${_compilerDir}" PATH)
- include_directories("${_compilerDir}/inc" )
- include_directories("${_compilerDir}/inc/Atmel" )
+elseif("${CMAKE_C_COMPILER_ARCHITECTURE_ID}" STREQUAL "MSP430")
+ __compiler_iar_xlink(C)
+ __compiler_check_default_language_standard(C 1.10 90 5.10 99)
+ set(CMAKE_C_OUTPUT_EXTENSION ".r43")
else()
message(FATAL_ERROR "CMAKE_C_COMPILER_ARCHITECTURE_ID not detected. This should be automatic.")
diff --git a/Modules/Compiler/IAR-CXX.cmake b/Modules/Compiler/IAR-CXX.cmake
index 04ccbe5..22ec118 100644
--- a/Modules/Compiler/IAR-CXX.cmake
+++ b/Modules/Compiler/IAR-CXX.cmake
@@ -4,12 +4,14 @@ include(Compiler/IAR)
include(Compiler/CMakeCommonCompilerMacros)
# Common
-if(NOT CMAKE_IAR_CXX_FLAG)
- if(NOT CMAKE_CXX_COMPILER_VERSION)
- message(FATAL_ERROR "CMAKE_CXX_COMPILER_VERSION not detected. This should be automatic.")
- endif()
+if(NOT CMAKE_CXX_COMPILER_VERSION)
+ message(FATAL_ERROR "CMAKE_CXX_COMPILER_VERSION not detected. This should be automatic.")
+endif()
- if(CMAKE_CXX_COMPILER_VERSION_INTERNAL VERSION_GREATER 7)
+if(NOT CMAKE_IAR_CXX_FLAG)
+ # The --c++ flag was introduced in platform version 9 for all architectures except ARM where it was introduced already in version 7
+ if(CMAKE_CXX_COMPILER_VERSION_INTERNAL VERSION_GREATER 8 OR
+ (CMAKE_CXX_COMPILER_VERSION_INTERNAL VERSION_GREATER 6 AND "${CMAKE_CXX_COMPILER_ARCHITECTURE_ID}" STREQUAL "ARM") )
set(CMAKE_IAR_CXX_FLAG --c++)
else()
set(CMAKE_IAR_CXX_FLAG --eec++)
@@ -45,20 +47,22 @@ elseif("${CMAKE_CXX_COMPILER_ARCHITECTURE_ID}" STREQUAL "RX")
__compiler_iar_ilink(CXX)
__compiler_check_default_language_standard(CXX 2.10 98 4.10 14)
+elseif("${CMAKE_CXX_COMPILER_ARCHITECTURE_ID}" STREQUAL "RH850")
+ __compiler_iar_ilink(CXX)
+ __compiler_check_default_language_standard(CXX 1.10 98 2.10 14)
+
+elseif("${CMAKE_CXX_COMPILER_ARCHITECTURE_ID}" STREQUAL "RL78")
+ __compiler_iar_ilink(CXX)
+ __compiler_check_default_language_standard(CXX 1.10 98 4.10 14)
+
elseif("${CMAKE_CXX_COMPILER_ARCHITECTURE_ID}" STREQUAL "AVR")
__compiler_iar_xlink(CXX)
__compiler_check_default_language_standard(CXX 7.10 98)
- set(CMAKE_CXX_OUTPUT_EXTENSION ".r90")
- if(NOT CMAKE_CXX_LINK_FLAGS)
- set(CMAKE_CXX_LINK_FLAGS "-Fmotorola")
- endif()
-
- # add the target specific include directory:
- get_filename_component(_compilerDir "${CMAKE_C_COMPILER}" PATH)
- get_filename_component(_compilerDir "${_compilerDir}" PATH)
- include_directories("${_compilerDir}/inc" )
- include_directories("${_compilerDir}/inc/Atmel" )
+elseif("${CMAKE_CXX_COMPILER_ARCHITECTURE_ID}" STREQUAL "MSP430")
+ __compiler_iar_xlink(CXX)
+ __compiler_check_default_language_standard(CXX 5.10 98)
+ set(CMAKE_CXX_OUTPUT_EXTENSION ".r43")
else()
message(FATAL_ERROR "CMAKE_CXX_COMPILER_ARCHITECTURE_ID not detected. This should be automatic." )
diff --git a/Modules/Compiler/IAR-DetermineCompiler.cmake b/Modules/Compiler/IAR-DetermineCompiler.cmake
index cdfb095..6b09c40 100644
--- a/Modules/Compiler/IAR-DetermineCompiler.cmake
+++ b/Modules/Compiler/IAR-DetermineCompiler.cmake
@@ -31,7 +31,7 @@ set(_compiler_id_version_compute "
# define @PREFIX@COMPILER_VERSION_MINOR @MACRO_DEC@(((__VER__) / 1000) % 1000)
# define @PREFIX@COMPILER_VERSION_PATCH @MACRO_DEC@((__VER__) % 1000)
# define @PREFIX@COMPILER_VERSION_INTERNAL @MACRO_DEC@(__IAR_SYSTEMS_ICC__)
-# elif defined(__VER__) && (defined(__ICCAVR__) || defined(__ICCRX__))
+# elif defined(__VER__) && (defined(__ICCAVR__) || defined(__ICCRX__) || defined(__ICCRH850__) || defined(__ICCRL78__) || defined(__ICC430__))
# define @PREFIX@COMPILER_VERSION_MAJOR @MACRO_DEC@((__VER__) / 100)
# define @PREFIX@COMPILER_VERSION_MINOR @MACRO_DEC@((__VER__) - (((__VER__) / 100)*100))
# define @PREFIX@COMPILER_VERSION_PATCH @MACRO_DEC@(__SUBVERSION__)
diff --git a/Modules/Compiler/IAR-FindBinUtils.cmake b/Modules/Compiler/IAR-FindBinUtils.cmake
index 7fc6b59..3f13dce 100644
--- a/Modules/Compiler/IAR-FindBinUtils.cmake
+++ b/Modules/Compiler/IAR-FindBinUtils.cmake
@@ -11,7 +11,9 @@ get_filename_component(__iar_hint_2 "${CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPI
set(__iar_hints "${__iar_hint_1}" "${__iar_hint_2}")
if("${CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_ARCHITECTURE_ID}" STREQUAL "ARM" OR
- "${CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_ARCHITECTURE_ID}" STREQUAL "RX")
+ "${CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_ARCHITECTURE_ID}" STREQUAL "RX" OR
+ "${CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_ARCHITECTURE_ID}" STREQUAL "RH850" OR
+ "${CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_ARCHITECTURE_ID}" STREQUAL "RL78")
string(TOLOWER "${CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_ARCHITECTURE_ID}" _archid_lower)
@@ -41,9 +43,10 @@ set(CMAKE_IAR_OBJMANIP \"${CMAKE_IAR_OBJMANIP}\")
set(CMAKE_IAR_LINKER \"${CMAKE_IAR_LINKER}\")
")
-elseif("${CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_ARCHITECTURE_ID}" STREQUAL "AVR")
+elseif("${CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_ARCHITECTURE_ID}" STREQUAL "AVR" OR
+ "${CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_ARCHITECTURE_ID}" STREQUAL "MSP430")
- # For AVR and AVR32, IAR uses the "xlink" linker and the "xar" archiver:
+ # Find the "xlink" linker and "xar" archiver:
find_program(CMAKE_IAR_LINKER xlink HINTS ${__iar_hints}
DOC "The IAR XLINK linker")
find_program(CMAKE_IAR_AR xar HINTS ${__iar_hints}
diff --git a/Modules/Compiler/Intel-CXX-FeatureTests.cmake b/Modules/Compiler/Intel-CXX-FeatureTests.cmake
index aa35b97..bbefe15 100644
--- a/Modules/Compiler/Intel-CXX-FeatureTests.cmake
+++ b/Modules/Compiler/Intel-CXX-FeatureTests.cmake
@@ -24,7 +24,7 @@ set(DETECT_CXX14 "((__cplusplus >= 201300L) || ((__cplusplus == 201103L) && !def
unset(DETECT_BUGGY_ICC15)
set(Intel17_CXX14 "__INTEL_COMPILER >= 1700 && ${DETECT_CXX14}")
-set(_cmake_feature_test_cxx_relaxed_constexpr "__cpp_constexpr >= 201304 || (${Intel17_CXX14} && !(__INTEL_COMPILER == 1800 && __INTEL_COMPILER_UPDATE < 5) && !defined(_MSC_VER))")
+set(_cmake_feature_test_cxx_relaxed_constexpr "__cpp_constexpr >= 201304 || (${Intel17_CXX14} && !defined(_MSC_VER))")
set(Intel16_CXX14 "__INTEL_COMPILER >= 1600 && ${DETECT_CXX14}")
set(_cmake_feature_test_cxx_aggregate_default_initializers "${Intel16_CXX14}")
diff --git a/Modules/Compiler/Intel-CXX.cmake b/Modules/Compiler/Intel-CXX.cmake
index 44b0c3d..b630a6b 100644
--- a/Modules/Compiler/Intel-CXX.cmake
+++ b/Modules/Compiler/Intel-CXX.cmake
@@ -40,13 +40,7 @@ else()
set(CMAKE_CXX17_EXTENSION_COMPILE_OPTION "-std=gnu++17")
endif()
- # While full C++14 support was first introduced in Intel 17,
- # Intel 18.0.0-4 don't have full support as they broke
- # support for cxx_relaxed_constexpr.
- if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 18.0.4)
- set(CMAKE_CXX14_STANDARD__HAS_FULL_SUPPORT ON)
- elseif(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 17.0.0
- AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 18.0.0)
+ if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 17.0)
set(CMAKE_CXX14_STANDARD__HAS_FULL_SUPPORT ON)
endif()
diff --git a/Modules/Compiler/MSVC-CXX-FeatureTests.cmake b/Modules/Compiler/MSVC-CXX-FeatureTests.cmake
index 9c604f2..125974a 100644
--- a/Modules/Compiler/MSVC-CXX-FeatureTests.cmake
+++ b/Modules/Compiler/MSVC-CXX-FeatureTests.cmake
@@ -9,10 +9,8 @@ set(_cmake_oldestSupported "_MSC_VER >= 1600")
# https://docs.microsoft.com/en-us/cpp/cpp-conformance-improvements-2017#update_153
set(_cmake_feature_test_cxx_decltype_incomplete_return_types "_MSC_VER >= 1911")
-set(MSVC_2017 "_MSC_VER >= 1910")
-# VS 2017 introduces support for "N3652 Extended constexpr"
-# but as of v15.6 there are still bugs in the implementation
-#set(_cmake_feature_test_cxx_relaxed_constexpr "${MSVC_2017}")
+# VS 2017 v15.3 fixes support for "N3652 Extended constexpr"
+set(_cmake_feature_test_cxx_relaxed_constexpr "_MSC_VER >= 1911")
# VS 2017 Preview introduces support for aggregate initializers.
set(_cmake_feature_test_cxx_aggregate_default_initializers "_MSC_FULL_VER >= 190024406")
diff --git a/Modules/Compiler/MSVC-CXX.cmake b/Modules/Compiler/MSVC-CXX.cmake
index 787c17e..f3a7408 100644
--- a/Modules/Compiler/MSVC-CXX.cmake
+++ b/Modules/Compiler/MSVC-CXX.cmake
@@ -18,6 +18,7 @@ if ((CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 19.0.24215.1 AND
set(CMAKE_CXX14_EXTENSION_COMPILE_OPTION "-std:c++14")
if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 19.11.25505)
set(CMAKE_CXX11_STANDARD__HAS_FULL_SUPPORT ON)
+ set(CMAKE_CXX14_STANDARD__HAS_FULL_SUPPORT ON)
set(CMAKE_CXX17_STANDARD_COMPILE_OPTION "-std:c++17")
set(CMAKE_CXX17_EXTENSION_COMPILE_OPTION "-std:c++17")
else()
diff --git a/Modules/FindProtobuf.cmake b/Modules/FindProtobuf.cmake
index 1758fb3..76bc873 100644
--- a/Modules/FindProtobuf.cmake
+++ b/Modules/FindProtobuf.cmake
@@ -207,9 +207,14 @@ function(protobuf_generate)
get_filename_component(_basename ${_proto} NAME_WE)
file(RELATIVE_PATH _rel_dir ${CMAKE_CURRENT_SOURCE_DIR} ${_abs_dir})
+ set(_possible_rel_dir)
+ if (NOT protobuf_generate_APPEND_PATH)
+ set(_possible_rel_dir ${_rel_dir}/)
+ endif()
+
set(_generated_srcs)
foreach(_ext ${protobuf_generate_GENERATE_EXTENSIONS})
- list(APPEND _generated_srcs "${protobuf_generate_PROTOC_OUT_DIR}/${_basename}${_ext}")
+ list(APPEND _generated_srcs "${protobuf_generate_PROTOC_OUT_DIR}/${_possible_rel_dir}${_basename}${_ext}")
endforeach()
if(protobuf_generate_DESCRIPTORS AND protobuf_generate_LANGUAGE STREQUAL cpp)
diff --git a/Modules/FindSWIG.cmake b/Modules/FindSWIG.cmake
index a5e3a37..ae6ae56 100644
--- a/Modules/FindSWIG.cmake
+++ b/Modules/FindSWIG.cmake
@@ -26,7 +26,7 @@ to be found can be changed from the command line by means of setting
``SWIG_EXECUTABLE``
#]=======================================================================]
-find_program(SWIG_EXECUTABLE NAMES swig3.0 swig2.0 swig)
+find_program(SWIG_EXECUTABLE NAMES swig4.0 swig3.0 swig2.0 swig)
if(SWIG_EXECUTABLE)
execute_process(COMMAND ${SWIG_EXECUTABLE} -swiglib
diff --git a/Modules/FindXCTest.cmake b/Modules/FindXCTest.cmake
index 8497336..15721e1 100644
--- a/Modules/FindXCTest.cmake
+++ b/Modules/FindXCTest.cmake
@@ -61,6 +61,22 @@ The following variables are set by including this module:
#]=======================================================================]
+set(_PRESERVED_CMAKE_FIND_ROOT_PATH "${CMAKE_FIND_ROOT_PATH}")
+
+if(CMAKE_EFFECTIVE_SYSTEM_NAME STREQUAL "Apple"
+ AND NOT CMAKE_SYSTEM_NAME STREQUAL "Darwin")
+ # Non-macos systems set the CMAKE_FIND_ROOT_PATH_MODE to "ONLY" which
+ # restricts the search paths too much to find XCTest.framework. In
+ # contrast to the regular system frameworks which reside within the
+ # SDK direectory the XCTest framework is located in the respective
+ # platform directory which is not added to the CMAKE_FIND_ROOT_PATH
+ # (only to CMAKE_SYSTEM_FRAMEWORK_PATH) and therefore not searched.
+ #
+ # Until this is properly addressed, temporaily add the platform
+ # directory to CMAKE_FIND_ROOT_PATH.
+ list(APPEND CMAKE_FIND_ROOT_PATH "${_CMAKE_OSX_SYSROOT_PATH}/../..")
+endif()
+
find_path(XCTest_INCLUDE_DIR
NAMES "XCTest/XCTest.h"
DOC "XCTest include directory")
@@ -71,6 +87,9 @@ find_library(XCTest_LIBRARY
DOC "XCTest Framework library")
mark_as_advanced(XCTest_LIBRARY)
+set(CMAKE_FIND_ROOT_PATH "${_PRESERVED_CMAKE_FIND_ROOT_PATH}")
+unset(_PRESERVED_CMAKE_FIND_ROOT_PATH)
+
execute_process(
COMMAND xcrun --find xctest
OUTPUT_VARIABLE _xcrun_out OUTPUT_STRIP_TRAILING_WHITESPACE
diff --git a/Source/CMakeInstallSignTool.cmake.in b/Source/CMakeInstallSignTool.cmake.in
new file mode 100644
index 0000000..fca629c
--- /dev/null
+++ b/Source/CMakeInstallSignTool.cmake.in
@@ -0,0 +1,51 @@
+# The signtool. Default to PATH.
+set(CMake_INSTALL_SIGNTOOL "@CMake_INSTALL_SIGNTOOL@")
+if(NOT CMake_INSTALL_SIGNTOOL)
+ set(CMake_INSTALL_SIGNTOOL signtool)
+endif()
+
+# Select a certificate by Subject Name. Default to automatic selection.
+set(CMake_INSTALL_SIGNTOOL_SUBJECT_NAME "@CMake_INSTALL_SIGNTOOL_SUBJECT_NAME@")
+if(CMake_INSTALL_SIGNTOOL_SUBJECT_NAME)
+ set(select_cert -n "${CMake_INSTALL_SIGNTOOL_SUBJECT_NAME}")
+else()
+ set(select_cert -a)
+endif()
+
+# Timestamp URL. Default to a common provider.
+set(CMake_INSTALL_SIGNTOOL_TIMESTAMP_URL "@CMake_INSTALL_SIGNTOOL_TIMESTAMP_URL@")
+if(NOT CMake_INSTALL_SIGNTOOL_TIMESTAMP_URL)
+ set(CMake_INSTALL_SIGNTOOL_TIMESTAMP_URL "http://timestamp.digicert.com")
+endif()
+
+# Glob files that need a signature.
+file(GLOB files "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/bin/*.exe")
+
+# Sign all files at once.
+if(files)
+ # Run the signtool through 'cmd /c' to enable password prompt popup.
+ # Some providers have trouble when signtool is invoked with SW_HIDE.
+ set(cmd cmd /c "${CMake_INSTALL_SIGNTOOL}" sign -v ${select_cert})
+
+ # Sign with SHA-1 for Windows 7 and below.
+ execute_process(
+ COMMAND ${cmd} -t "${CMake_INSTALL_SIGNTOOL_TIMESTAMP_URL}" ${files}
+ RESULT_VARIABLE result
+ ERROR_VARIABLE stderr
+ )
+ if(NOT result EQUAL 0)
+ string(REPLACE "\n" "\n " stderr " ${stderr}")
+ message(WARNING "signtool failed:\n${stderr}")
+ endif()
+
+ # Sign with SHA-256 for Windows 8 and above.
+ execute_process(
+ COMMAND ${cmd} -tr "${CMake_INSTALL_SIGNTOOL_TIMESTAMP_URL}" -fd sha256 -td sha256 -as ${files}
+ RESULT_VARIABLE result
+ ERROR_VARIABLE stderr
+ )
+ if(NOT result EQUAL 0)
+ string(REPLACE "\n" "\n " stderr " ${stderr}")
+ message(WARNING "signtool failed:\n${stderr}")
+ endif()
+endif()
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt
index 01c6cd7..42eed4d 100644
--- a/Source/CMakeLists.txt
+++ b/Source/CMakeLists.txt
@@ -388,6 +388,8 @@ set(SRCS
cmUuid.cxx
cmUVHandlePtr.cxx
cmUVHandlePtr.h
+ cmUVProcessChain.cxx
+ cmUVProcessChain.h
cmUVStreambuf.h
cmUVSignalHackRAII.h
cmVariableWatch.cxx
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index 31a220f..9f2754f 100644
--- a/Source/CMakeVersion.cmake
+++ b/Source/CMakeVersion.cmake
@@ -1,5 +1,5 @@
# CMake version number components.
set(CMake_VERSION_MAJOR 3)
set(CMake_VERSION_MINOR 14)
-set(CMake_VERSION_PATCH 20190510)
+set(CMake_VERSION_PATCH 20190514)
#set(CMake_VERSION_RC 1)
diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx
index 8223dd1..b08dd1c 100644
--- a/Source/cmGlobalGenerator.cxx
+++ b/Source/cmGlobalGenerator.cxx
@@ -1372,7 +1372,9 @@ bool cmGlobalGenerator::Compute()
for (cmLocalGenerator* localGen : this->LocalGenerators) {
cmMakefile* mf = localGen->GetMakefile();
for (cmInstallGenerator* g : mf->GetInstallGenerators()) {
- g->Compute(localGen);
+ if (!g->Compute(localGen)) {
+ return false;
+ }
}
}
diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx
index 4fa6ee6..1b973e0 100644
--- a/Source/cmGlobalNinjaGenerator.cxx
+++ b/Source/cmGlobalNinjaGenerator.cxx
@@ -136,17 +136,15 @@ void cmGlobalNinjaGenerator::WriteBuild(
{
// Make sure there is a rule.
if (rule.empty()) {
- cmSystemTools::Error("No rule for WriteBuildStatement! called "
- "with comment: " +
+ cmSystemTools::Error("No rule for WriteBuild! called with comment: " +
comment);
return;
}
// Make sure there is at least one output file.
if (outputs.empty()) {
- cmSystemTools::Error("No output files for WriteBuildStatement! called "
- "with comment: " +
- comment);
+ cmSystemTools::Error(
+ "No output files for WriteBuild! called with comment: " + comment);
return;
}
@@ -292,14 +290,8 @@ void cmGlobalNinjaGenerator::WriteCustomCommandBuild(
void cmGlobalNinjaGenerator::AddMacOSXContentRule()
{
- cmLocalGenerator* lg = this->LocalGenerators[0];
-
- std::ostringstream cmd;
- cmd << lg->ConvertToOutputFormat(cmSystemTools::GetCMakeCommand(),
- cmOutputConverter::SHELL)
- << " -E copy $in $out";
-
- this->AddRule("COPY_OSX_CONTENT", cmd.str(), "Copying OS X Content $out",
+ this->AddRule("COPY_OSX_CONTENT", CMakeCmd() + " -E copy $in $out",
+ "Copying OS X Content $out",
"Rule for copying OS X bundle content file.",
/*depfile*/ "",
/*deptype*/ "",
@@ -332,71 +324,57 @@ void cmGlobalNinjaGenerator::WriteRule(
const std::string& rspfile, const std::string& rspcontent,
const std::string& restat, bool generator)
{
+ // -- Parameter checks
// Make sure the rule has a name.
if (name.empty()) {
- cmSystemTools::Error("No name given for WriteRuleStatement! called "
- "with comment: " +
+ cmSystemTools::Error("No name given for WriteRule! called with comment: " +
comment);
return;
}
// Make sure a command is given.
if (command.empty()) {
- cmSystemTools::Error("No command given for WriteRuleStatement! called "
- "with comment: " +
- comment);
+ cmSystemTools::Error(
+ "No command given for WriteRule! called with comment: " + comment);
return;
}
- cmGlobalNinjaGenerator::WriteComment(os, comment);
-
- // Write the rule.
- os << "rule " << name << "\n";
-
- // Write the depfile if any.
- if (!depfile.empty()) {
- cmGlobalNinjaGenerator::Indent(os, 1);
- os << "depfile = " << depfile << "\n";
- }
-
- // Write the deptype if any.
- if (!deptype.empty()) {
- cmGlobalNinjaGenerator::Indent(os, 1);
- os << "deps = " << deptype << "\n";
+ // Make sure response file content is given
+ if (!rspfile.empty() && rspcontent.empty()) {
+ cmSystemTools::Error("rspfile but no rspfile_content given for WriteRule! "
+ "called with comment: " +
+ comment);
+ return;
}
- // Write the command.
- cmGlobalNinjaGenerator::Indent(os, 1);
- os << "command = " << command << "\n";
-
- // Write the description if any.
- if (!description.empty()) {
- cmGlobalNinjaGenerator::Indent(os, 1);
- os << "description = " << description << "\n";
- }
+ // -- Write rule
+ // Write rule intro
+ cmGlobalNinjaGenerator::WriteComment(os, comment);
+ os << "rule " << name << '\n';
- if (!rspfile.empty()) {
- if (rspcontent.empty()) {
- cmSystemTools::Error("No rspfile_content given!" + comment);
- return;
+ // Write rule key/value pairs
+ auto writeKV = [&os](const char* key, std::string const& value) {
+ if (!value.empty()) {
+ cmGlobalNinjaGenerator::Indent(os, 1);
+ os << key << " = " << value << '\n';
}
- cmGlobalNinjaGenerator::Indent(os, 1);
- os << "rspfile = " << rspfile << "\n";
- cmGlobalNinjaGenerator::Indent(os, 1);
- os << "rspfile_content = " << rspcontent << "\n";
- }
+ };
- if (!restat.empty()) {
- cmGlobalNinjaGenerator::Indent(os, 1);
- os << "restat = " << restat << "\n";
+ writeKV("depfile", depfile);
+ writeKV("deps", deptype);
+ writeKV("command", command);
+ writeKV("description", description);
+ if (!rspfile.empty()) {
+ writeKV("rspfile", rspfile);
+ writeKV("rspfile_content", rspcontent);
}
-
+ writeKV("restat", restat);
if (generator) {
- cmGlobalNinjaGenerator::Indent(os, 1);
- os << "generator = 1\n";
+ writeKV("generator", "1");
}
- os << "\n";
+ // Finish rule
+ os << '\n';
}
void cmGlobalNinjaGenerator::WriteVariable(std::ostream& os,
@@ -446,9 +424,6 @@ void cmGlobalNinjaGenerator::WriteDefault(std::ostream& os,
cmGlobalNinjaGenerator::cmGlobalNinjaGenerator(cmake* cm)
: cmGlobalCommonGenerator(cm)
- , BuildFileStream(nullptr)
- , RulesFileStream(nullptr)
- , CompileCommandsStream(nullptr)
, UsingGCCOnWindows(false)
, ComputingUnknownDependencies(false)
, PolicyCMP0058(cmPolicies::WARN)
@@ -509,8 +484,12 @@ void cmGlobalNinjaGenerator::Generate()
msg.str());
return;
}
- this->OpenBuildFileStream();
- this->OpenRulesFileStream();
+ if (!this->OpenBuildFileStream()) {
+ return;
+ }
+ if (!this->OpenRulesFileStream()) {
+ return;
+ }
this->TargetDependsClosures.clear();
@@ -700,11 +679,7 @@ cmGlobalNinjaGenerator::GenerateBuildCommand(
makeCommand.Add(makeOptions.begin(), makeOptions.end());
for (const auto& tname : targetNames) {
if (!tname.empty()) {
- if (tname == "clean") {
- makeCommand.Add("-t", "clean");
- } else {
- makeCommand.Add(tname);
- }
+ makeCommand.Add(tname);
}
}
return { std::move(makeCommand) };
@@ -720,22 +695,20 @@ void cmGlobalNinjaGenerator::AddRule(
const std::string& restat, bool generator)
{
// Do not add the same rule twice.
- if (this->HasRule(name)) {
+ if (!this->Rules.insert(name).second) {
return;
}
-
- this->Rules.insert(name);
+ // Store command length
+ this->RuleCmdLength[name] = static_cast<int>(command.size());
+ // Write rule
cmGlobalNinjaGenerator::WriteRule(*this->RulesFileStream, name, command,
description, comment, depfile, deptype,
rspfile, rspcontent, restat, generator);
-
- this->RuleCmdLength[name] = static_cast<int>(command.size());
}
bool cmGlobalNinjaGenerator::HasRule(const std::string& name)
{
- RulesSetType::const_iterator rule = this->Rules.find(name);
- return (rule != this->Rules.end());
+ return (this->Rules.find(name) != this->Rules.end());
}
// Private virtual overrides
@@ -761,7 +734,7 @@ void cmGlobalNinjaGenerator::ComputeTargetObjectDirectory(
// Private methods
-void cmGlobalNinjaGenerator::OpenBuildFileStream()
+bool cmGlobalNinjaGenerator::OpenBuildFileStream()
{
// Compute Ninja's build file path.
std::string buildFilePath =
@@ -771,12 +744,12 @@ void cmGlobalNinjaGenerator::OpenBuildFileStream()
// Get a stream where to generate things.
if (!this->BuildFileStream) {
- this->BuildFileStream = new cmGeneratedFileStream(
+ this->BuildFileStream = cm::make_unique<cmGeneratedFileStream>(
buildFilePath, false, this->GetMakefileEncoding());
- if (!this->BuildFileStream) {
+ if (!(*this->BuildFileStream)) {
// An error message is generated by the constructor if it cannot
// open the file.
- return;
+ return false;
}
}
@@ -787,19 +760,20 @@ void cmGlobalNinjaGenerator::OpenBuildFileStream()
*this->BuildFileStream
<< "# This file contains all the build statements describing the\n"
<< "# compilation DAG.\n\n";
+
+ return true;
}
void cmGlobalNinjaGenerator::CloseBuildFileStream()
{
if (this->BuildFileStream) {
- delete this->BuildFileStream;
- this->BuildFileStream = nullptr;
+ this->BuildFileStream.reset();
} else {
cmSystemTools::Error("Build file stream was not open.");
}
}
-void cmGlobalNinjaGenerator::OpenRulesFileStream()
+bool cmGlobalNinjaGenerator::OpenRulesFileStream()
{
// Compute Ninja's build file path.
std::string rulesFilePath =
@@ -809,12 +783,12 @@ void cmGlobalNinjaGenerator::OpenRulesFileStream()
// Get a stream where to generate things.
if (!this->RulesFileStream) {
- this->RulesFileStream = new cmGeneratedFileStream(
+ this->RulesFileStream = cm::make_unique<cmGeneratedFileStream>(
rulesFilePath, false, this->GetMakefileEncoding());
- if (!this->RulesFileStream) {
+ if (!(*this->RulesFileStream)) {
// An error message is generated by the constructor if it cannot
// open the file.
- return;
+ return false;
}
}
@@ -829,13 +803,13 @@ void cmGlobalNinjaGenerator::OpenRulesFileStream()
<< "# It is included in the main '" << NINJA_BUILD_FILE << "'.\n\n"
;
/* clang-format on */
+ return true;
}
void cmGlobalNinjaGenerator::CloseRulesFileStream()
{
if (this->RulesFileStream) {
- delete this->RulesFileStream;
- this->RulesFileStream = nullptr;
+ this->RulesFileStream.reset();
} else {
cmSystemTools::Error("Rules file stream was not open.");
}
@@ -892,7 +866,8 @@ void cmGlobalNinjaGenerator::AddCXXCompileCommand(
}
// Get a stream where to generate things.
- this->CompileCommandsStream = new cmGeneratedFileStream(buildFilePath);
+ this->CompileCommandsStream =
+ cm::make_unique<cmGeneratedFileStream>(buildFilePath);
*this->CompileCommandsStream << "[";
} else {
*this->CompileCommandsStream << "," << std::endl;
@@ -920,8 +895,7 @@ void cmGlobalNinjaGenerator::CloseCompileCommandsStream()
{
if (this->CompileCommandsStream) {
*this->CompileCommandsStream << "\n]";
- delete this->CompileCommandsStream;
- this->CompileCommandsStream = nullptr;
+ this->CompileCommandsStream.reset();
}
}
@@ -1017,8 +991,7 @@ void cmGlobalNinjaGenerator::AppendTargetDepends(
{
if (target->GetType() == cmStateEnums::GLOBAL_TARGET) {
// These depend only on other CMake-provided targets, e.g. "all".
- std::set<BT<std::string>> const& utils = target->GetUtilities();
- for (BT<std::string> const& util : utils) {
+ for (BT<std::string> const& util : target->GetUtilities()) {
std::string d =
target->GetLocalGenerator()->GetCurrentBinaryDirectory() + "/" +
util.Value;
@@ -1026,8 +999,8 @@ void cmGlobalNinjaGenerator::AppendTargetDepends(
}
} else {
cmNinjaDeps outs;
- cmTargetDependSet const& targetDeps = this->GetTargetDirectDepends(target);
- for (cmTargetDepend const& targetDep : targetDeps) {
+ for (cmTargetDepend const& targetDep :
+ this->GetTargetDirectDepends(target)) {
if (targetDep->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
continue;
}
@@ -1061,10 +1034,9 @@ void cmGlobalNinjaGenerator::AppendTargetDependsClosure(
// relevant for filling the cache entries properly isolated and a global
// result set that is relevant for the result of the top level call to
// AppendTargetDependsClosure.
- auto const& targetDeps = this->GetTargetDirectDepends(target);
cmNinjaOuts this_outs; // this will be the new cache entry
- for (auto const& dep_target : targetDeps) {
+ for (auto const& dep_target : this->GetTargetDirectDepends(target)) {
if (dep_target->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
continue;
}
@@ -1160,9 +1132,7 @@ void cmGlobalNinjaGenerator::WriteFolderTargets(std::ostream& os)
// The directory-level rule should depend on the directory-level
// rules of the subdirectories.
- std::vector<cmStateSnapshot> const& children =
- lg->GetStateSnapshot().GetChildren();
- for (cmStateSnapshot const& state : children) {
+ for (cmStateSnapshot const& state : lg->GetStateSnapshot().GetChildren()) {
std::string const currentBinaryDir =
state.GetDirectory().GetCurrentBinary();
@@ -1223,26 +1193,21 @@ void cmGlobalNinjaGenerator::WriteUnknownExplicitDependencies(std::ostream& os)
for (cmLocalGenerator* lg : this->LocalGenerators) {
// get the vector of files created by this makefile and convert them
// to ninja paths, which are all relative in respect to the build directory
- const std::vector<std::string>& files =
- lg->GetMakefile()->GetOutputFiles();
- for (std::string const& file : files) {
+ for (std::string const& file : lg->GetMakefile()->GetOutputFiles()) {
knownDependencies.insert(this->ConvertToNinjaPath(file));
}
if (!this->GlobalSettingIsOn("CMAKE_SUPPRESS_REGENERATION")) {
// get list files which are implicit dependencies as well and will be
// phony for rebuild manifest
- std::vector<std::string> const& lf = lg->GetMakefile()->GetListFiles();
- for (std::string const& j : lf) {
+ for (std::string const& j : lg->GetMakefile()->GetListFiles()) {
knownDependencies.insert(this->ConvertToNinjaPath(j));
}
}
- std::vector<cmGeneratorExpressionEvaluationFile*> const& ef =
- lg->GetMakefile()->GetEvaluationFiles();
- for (cmGeneratorExpressionEvaluationFile* li : ef) {
+ for (cmGeneratorExpressionEvaluationFile* li :
+ lg->GetMakefile()->GetEvaluationFiles()) {
// get all the files created by generator expressions and convert them
// to ninja paths
- std::vector<std::string> evaluationFiles = li->GetFiles();
- for (std::string const& evaluationFile : evaluationFiles) {
+ for (std::string const& evaluationFile : li->GetFiles()) {
knownDependencies.insert(this->ConvertToNinjaPath(evaluationFile));
}
}
@@ -1348,30 +1313,28 @@ void cmGlobalNinjaGenerator::WriteTargetRebuildManifest(std::ostream& os)
}
cmLocalGenerator* lg = this->LocalGenerators[0];
- std::ostringstream cmd;
- cmd << lg->ConvertToOutputFormat(cmSystemTools::GetCMakeCommand(),
- cmOutputConverter::SHELL)
- << " -S"
- << lg->ConvertToOutputFormat(lg->GetSourceDirectory(),
- cmOutputConverter::SHELL)
- << " -B"
- << lg->ConvertToOutputFormat(lg->GetBinaryDirectory(),
- cmOutputConverter::SHELL);
- WriteRule(*this->RulesFileStream, "RERUN_CMAKE", cmd.str(),
- "Re-running CMake...", "Rule for re-running cmake.",
- /*depfile=*/"",
- /*deptype=*/"",
- /*rspfile=*/"",
- /*rspcontent*/ "",
- /*restat=*/"",
- /*generator=*/true);
+ {
+ std::string cmd = CMakeCmd();
+ cmd += " -S";
+ cmd += lg->ConvertToOutputFormat(lg->GetSourceDirectory(),
+ cmOutputConverter::SHELL);
+ cmd += " -B";
+ cmd += lg->ConvertToOutputFormat(lg->GetBinaryDirectory(),
+ cmOutputConverter::SHELL);
+ WriteRule(*this->RulesFileStream, "RERUN_CMAKE", cmd,
+ "Re-running CMake...", "Rule for re-running cmake.",
+ /*depfile=*/"",
+ /*deptype=*/"",
+ /*rspfile=*/"",
+ /*rspcontent*/ "",
+ /*restat=*/"",
+ /*generator=*/true);
+ }
cmNinjaDeps implicitDeps;
cmNinjaDeps explicitDeps;
for (cmLocalGenerator* localGen : this->LocalGenerators) {
- std::vector<std::string> const& lf =
- localGen->GetMakefile()->GetListFiles();
- for (std::string const& fi : lf) {
+ for (std::string const& fi : localGen->GetMakefile()->GetListFiles()) {
implicitDeps.push_back(this->ConvertToNinjaPath(fi));
}
}
@@ -1386,22 +1349,22 @@ void cmGlobalNinjaGenerator::WriteTargetRebuildManifest(std::ostream& os)
cmake* cm = this->GetCMakeInstance();
if (this->SupportsManifestRestat() && cm->DoWriteGlobVerifyTarget()) {
- std::ostringstream verify_cmd;
- verify_cmd << lg->ConvertToOutputFormat(cmSystemTools::GetCMakeCommand(),
- cmOutputConverter::SHELL)
- << " -P "
- << lg->ConvertToOutputFormat(cm->GetGlobVerifyScript(),
- cmOutputConverter::SHELL);
-
- WriteRule(*this->RulesFileStream, "VERIFY_GLOBS", verify_cmd.str(),
- "Re-checking globbed directories...",
- "Rule for re-checking globbed directories.",
- /*depfile=*/"",
- /*deptype=*/"",
- /*rspfile=*/"",
- /*rspcontent*/ "",
- /*restat=*/"",
- /*generator=*/true);
+ {
+ std::string cmd = CMakeCmd();
+ cmd += " -P ";
+ cmd += lg->ConvertToOutputFormat(cm->GetGlobVerifyScript(),
+ cmOutputConverter::SHELL);
+
+ WriteRule(*this->RulesFileStream, "VERIFY_GLOBS", cmd,
+ "Re-checking globbed directories...",
+ "Rule for re-checking globbed directories.",
+ /*depfile=*/"",
+ /*deptype=*/"",
+ /*rspfile=*/"",
+ /*rspcontent*/ "",
+ /*restat=*/"",
+ /*generator=*/true);
+ }
std::string verifyForce = cm->GetGlobVerifyScript() + "_force";
cmNinjaDeps verifyForceDeps(1, this->NinjaOutputPath(verifyForce));
@@ -1464,10 +1427,17 @@ void cmGlobalNinjaGenerator::WriteTargetRebuildManifest(std::ostream& os)
missingInputs, cmNinjaDeps());
}
-std::string cmGlobalNinjaGenerator::ninjaCmd() const
+std::string cmGlobalNinjaGenerator::CMakeCmd() const
+{
+ cmLocalGenerator* lgen = this->LocalGenerators.at(0);
+ return lgen->ConvertToOutputFormat(cmSystemTools::GetCMakeCommand(),
+ cmOutputConverter::SHELL);
+}
+
+std::string cmGlobalNinjaGenerator::NinjaCmd() const
{
cmLocalGenerator* lgen = this->LocalGenerators[0];
- if (lgen) {
+ if (lgen != nullptr) {
return lgen->ConvertToOutputFormat(this->NinjaCommand,
cmOutputConverter::SHELL);
}
@@ -1496,7 +1466,7 @@ bool cmGlobalNinjaGenerator::SupportsMultilineDepfile() const
void cmGlobalNinjaGenerator::WriteTargetClean(std::ostream& os)
{
- WriteRule(*this->RulesFileStream, "CLEAN", ninjaCmd() + " -t clean",
+ WriteRule(*this->RulesFileStream, "CLEAN", NinjaCmd() + " -t clean",
"Cleaning all built files...",
"Rule for cleaning all built files.",
/*depfile=*/"",
@@ -1516,7 +1486,7 @@ void cmGlobalNinjaGenerator::WriteTargetClean(std::ostream& os)
void cmGlobalNinjaGenerator::WriteTargetHelp(std::ostream& os)
{
- WriteRule(*this->RulesFileStream, "HELP", ninjaCmd() + " -t targets",
+ WriteRule(*this->RulesFileStream, "HELP", NinjaCmd() + " -t targets",
"All primary targets available:",
"Rule for printing all primary targets available.",
/*depfile=*/"",
diff --git a/Source/cmGlobalNinjaGenerator.h b/Source/cmGlobalNinjaGenerator.h
index efd1d8f..ffcea60 100644
--- a/Source/cmGlobalNinjaGenerator.h
+++ b/Source/cmGlobalNinjaGenerator.h
@@ -7,12 +7,15 @@
#include <iosfwd>
#include <map>
+#include <memory> // IWYU pragma: keep
#include <set>
#include <string>
#include <unordered_map>
+#include <unordered_set>
#include <utility>
#include <vector>
+#include "cmGeneratedFileStream.h"
#include "cmGlobalCommonGenerator.h"
#include "cmGlobalGenerator.h"
#include "cmGlobalGeneratorFactory.h"
@@ -21,7 +24,6 @@
#include "cm_codecvt.hxx"
class cmCustomCommand;
-class cmGeneratedFileStream;
class cmGeneratorTarget;
class cmLinkLineComputer;
class cmLocalGenerator;
@@ -41,8 +43,6 @@ struct cmDocumentationEntry;
* it is handle by Ninja's -v option.
* - We don't care about computing any progress status since Ninja manages
* it itself.
- * - We don't care about generating a clean target since Ninja already have
- * a clean tool.
* - We generate one build.ninja and one rules.ninja per project.
* - We try to minimize the number of generated rules: one per target and
* language.
@@ -233,12 +233,12 @@ public:
cmGeneratedFileStream* GetBuildFileStream() const
{
- return this->BuildFileStream;
+ return this->BuildFileStream.get();
}
cmGeneratedFileStream* GetRulesFileStream() const
{
- return this->RulesFileStream;
+ return this->RulesFileStream.get();
}
std::string const& ConvertToNinjaPath(const std::string& path) const;
@@ -378,12 +378,12 @@ private:
cmMakefile* mf) const override;
bool CheckFortran(cmMakefile* mf) const;
- void OpenBuildFileStream();
+ bool OpenBuildFileStream();
void CloseBuildFileStream();
void CloseCompileCommandsStream();
- void OpenRulesFileStream();
+ bool OpenRulesFileStream();
void CloseRulesFileStream();
/// Write the common disclaimer text at the top of each build file.
@@ -405,25 +405,22 @@ private:
cmGeneratorTarget const* target,
std::set<cmGeneratorTarget const*>& depends);
- std::string ninjaCmd() const;
+ std::string CMakeCmd() const;
+ std::string NinjaCmd() const;
/// The file containing the build statement. (the relationship of the
/// compilation DAG).
- cmGeneratedFileStream* BuildFileStream;
+ std::unique_ptr<cmGeneratedFileStream> BuildFileStream;
/// The file containing the rule statements. (The action attached to each
/// edge of the compilation DAG).
- cmGeneratedFileStream* RulesFileStream;
- cmGeneratedFileStream* CompileCommandsStream;
-
- /// The type used to store the set of rules added to the generated build
- /// system.
- typedef std::set<std::string> RulesSetType;
+ std::unique_ptr<cmGeneratedFileStream> RulesFileStream;
+ std::unique_ptr<cmGeneratedFileStream> CompileCommandsStream;
/// The set of rules added to the generated build system.
- RulesSetType Rules;
+ std::unordered_set<std::string> Rules;
/// Length of rule command, used by rsp file evaluation
- std::map<std::string, int> RuleCmdLength;
+ std::unordered_map<std::string, int> RuleCmdLength;
/// The set of dependencies to add to the "all" target.
cmNinjaDeps AllDependencies;
diff --git a/Source/cmInstallDirectoryGenerator.cxx b/Source/cmInstallDirectoryGenerator.cxx
index 62ce9f2..14288f6 100644
--- a/Source/cmInstallDirectoryGenerator.cxx
+++ b/Source/cmInstallDirectoryGenerator.cxx
@@ -43,9 +43,10 @@ cmInstallDirectoryGenerator::cmInstallDirectoryGenerator(
cmInstallDirectoryGenerator::~cmInstallDirectoryGenerator() = default;
-void cmInstallDirectoryGenerator::Compute(cmLocalGenerator* lg)
+bool cmInstallDirectoryGenerator::Compute(cmLocalGenerator* lg)
{
- LocalGenerator = lg;
+ this->LocalGenerator = lg;
+ return true;
}
void cmInstallDirectoryGenerator::GenerateScriptActions(std::ostream& os,
diff --git a/Source/cmInstallDirectoryGenerator.h b/Source/cmInstallDirectoryGenerator.h
index ac6e504..e30849f 100644
--- a/Source/cmInstallDirectoryGenerator.h
+++ b/Source/cmInstallDirectoryGenerator.h
@@ -29,7 +29,7 @@ public:
bool optional = false);
~cmInstallDirectoryGenerator() override;
- void Compute(cmLocalGenerator* lg) override;
+ bool Compute(cmLocalGenerator* lg) override;
std::string GetDestination(std::string const& config) const;
diff --git a/Source/cmInstallExportAndroidMKGenerator.cxx b/Source/cmInstallExportAndroidMKGenerator.cxx
index 186b9df..7de3dd4 100644
--- a/Source/cmInstallExportAndroidMKGenerator.cxx
+++ b/Source/cmInstallExportAndroidMKGenerator.cxx
@@ -30,10 +30,11 @@ cmInstallExportAndroidMKGenerator::~cmInstallExportAndroidMKGenerator()
{
}
-void cmInstallExportAndroidMKGenerator::Compute(cmLocalGenerator* lg)
+bool cmInstallExportAndroidMKGenerator::Compute(cmLocalGenerator* lg)
{
this->LocalGenerator = lg;
this->ExportSet->Compute(lg);
+ return true;
}
void cmInstallExportAndroidMKGenerator::GenerateScript(std::ostream& os)
diff --git a/Source/cmInstallExportAndroidMKGenerator.h b/Source/cmInstallExportAndroidMKGenerator.h
index 189084a..a92ff27 100644
--- a/Source/cmInstallExportAndroidMKGenerator.h
+++ b/Source/cmInstallExportAndroidMKGenerator.h
@@ -24,7 +24,7 @@ public:
const char* name_space, bool exportOld);
~cmInstallExportAndroidMKGenerator();
- void Compute(cmLocalGenerator* lg);
+ bool Compute(cmLocalGenerator* lg) override;
protected:
virtual void GenerateScript(std::ostream& os);
diff --git a/Source/cmInstallExportGenerator.cxx b/Source/cmInstallExportGenerator.cxx
index 73a37cb..f5bedab 100644
--- a/Source/cmInstallExportGenerator.cxx
+++ b/Source/cmInstallExportGenerator.cxx
@@ -45,10 +45,11 @@ cmInstallExportGenerator::~cmInstallExportGenerator()
delete this->EFGen;
}
-void cmInstallExportGenerator::Compute(cmLocalGenerator* lg)
+bool cmInstallExportGenerator::Compute(cmLocalGenerator* lg)
{
this->LocalGenerator = lg;
this->ExportSet->Compute(lg);
+ return true;
}
void cmInstallExportGenerator::ComputeTempDir()
diff --git a/Source/cmInstallExportGenerator.h b/Source/cmInstallExportGenerator.h
index d23cf06..c4d252c 100644
--- a/Source/cmInstallExportGenerator.h
+++ b/Source/cmInstallExportGenerator.h
@@ -34,7 +34,7 @@ public:
cmExportSet* GetExportSet() { return this->ExportSet; }
- void Compute(cmLocalGenerator* lg) override;
+ bool Compute(cmLocalGenerator* lg) override;
cmLocalGenerator* GetLocalGenerator() const { return this->LocalGenerator; }
diff --git a/Source/cmInstallFilesGenerator.cxx b/Source/cmInstallFilesGenerator.cxx
index 9eb8ad4..2ed9f73 100644
--- a/Source/cmInstallFilesGenerator.cxx
+++ b/Source/cmInstallFilesGenerator.cxx
@@ -42,9 +42,10 @@ cmInstallFilesGenerator::cmInstallFilesGenerator(
cmInstallFilesGenerator::~cmInstallFilesGenerator() = default;
-void cmInstallFilesGenerator::Compute(cmLocalGenerator* lg)
+bool cmInstallFilesGenerator::Compute(cmLocalGenerator* lg)
{
this->LocalGenerator = lg;
+ return true;
}
std::string cmInstallFilesGenerator::GetDestination(
diff --git a/Source/cmInstallFilesGenerator.h b/Source/cmInstallFilesGenerator.h
index 0ef2a06..ac462d4 100644
--- a/Source/cmInstallFilesGenerator.h
+++ b/Source/cmInstallFilesGenerator.h
@@ -29,7 +29,7 @@ public:
bool optional = false);
~cmInstallFilesGenerator() override;
- void Compute(cmLocalGenerator* lg) override;
+ bool Compute(cmLocalGenerator* lg) override;
std::string GetDestination(std::string const& config) const;
diff --git a/Source/cmInstallGenerator.h b/Source/cmInstallGenerator.h
index 9bd7ac3..dbe707d 100644
--- a/Source/cmInstallGenerator.h
+++ b/Source/cmInstallGenerator.h
@@ -60,7 +60,7 @@ public:
/** Select message level from CMAKE_INSTALL_MESSAGE or 'never'. */
static MessageLevel SelectMessageLevel(cmMakefile* mf, bool never = false);
- virtual void Compute(cmLocalGenerator*) {}
+ virtual bool Compute(cmLocalGenerator*) { return true; }
protected:
void GenerateScript(std::ostream& os) override;
diff --git a/Source/cmInstallScriptGenerator.cxx b/Source/cmInstallScriptGenerator.cxx
index a513958..5832d27 100644
--- a/Source/cmInstallScriptGenerator.cxx
+++ b/Source/cmInstallScriptGenerator.cxx
@@ -29,7 +29,7 @@ cmInstallScriptGenerator::cmInstallScriptGenerator(const char* script,
cmInstallScriptGenerator::~cmInstallScriptGenerator() = default;
-void cmInstallScriptGenerator::Compute(cmLocalGenerator* lg)
+bool cmInstallScriptGenerator::Compute(cmLocalGenerator* lg)
{
this->LocalGenerator = lg;
@@ -49,6 +49,8 @@ void cmInstallScriptGenerator::Compute(cmLocalGenerator* lg)
break;
}
}
+
+ return true;
}
void cmInstallScriptGenerator::AddScriptInstallRule(std::ostream& os,
diff --git a/Source/cmInstallScriptGenerator.h b/Source/cmInstallScriptGenerator.h
index 05199d7..6af7371 100644
--- a/Source/cmInstallScriptGenerator.h
+++ b/Source/cmInstallScriptGenerator.h
@@ -23,7 +23,7 @@ public:
const char* component, bool exclude_from_all);
~cmInstallScriptGenerator() override;
- void Compute(cmLocalGenerator* lg) override;
+ bool Compute(cmLocalGenerator* lg) override;
protected:
void GenerateScriptActions(std::ostream& os, Indent indent) override;
diff --git a/Source/cmInstallSubdirectoryGenerator.cxx b/Source/cmInstallSubdirectoryGenerator.cxx
index ad7121f..1c0512c 100644
--- a/Source/cmInstallSubdirectoryGenerator.cxx
+++ b/Source/cmInstallSubdirectoryGenerator.cxx
@@ -41,9 +41,10 @@ void cmInstallSubdirectoryGenerator::CheckCMP0082(
}
}
-void cmInstallSubdirectoryGenerator::Compute(cmLocalGenerator* lg)
+bool cmInstallSubdirectoryGenerator::Compute(cmLocalGenerator* lg)
{
this->LocalGenerator = lg;
+ return true;
}
void cmInstallSubdirectoryGenerator::GenerateScript(std::ostream& os)
diff --git a/Source/cmInstallSubdirectoryGenerator.h b/Source/cmInstallSubdirectoryGenerator.h
index 35471dd..22759d9 100644
--- a/Source/cmInstallSubdirectoryGenerator.h
+++ b/Source/cmInstallSubdirectoryGenerator.h
@@ -28,7 +28,7 @@ public:
void CheckCMP0082(bool& haveSubdirectoryInstall,
bool& haveInstallAfterSubdirectory) override;
- void Compute(cmLocalGenerator* lg) override;
+ bool Compute(cmLocalGenerator* lg) override;
protected:
void GenerateScript(std::ostream& os) override;
diff --git a/Source/cmInstallTargetGenerator.cxx b/Source/cmInstallTargetGenerator.cxx
index 4fefe23..7c5a55b 100644
--- a/Source/cmInstallTargetGenerator.cxx
+++ b/Source/cmInstallTargetGenerator.cxx
@@ -430,7 +430,7 @@ std::string cmInstallTargetGenerator::GetInstallFilename(
return fname;
}
-void cmInstallTargetGenerator::Compute(cmLocalGenerator* lg)
+bool cmInstallTargetGenerator::Compute(cmLocalGenerator* lg)
{
// Lookup this target in the current directory.
this->Target = lg->FindLocalNonAliasGeneratorTarget(this->TargetName);
@@ -439,6 +439,8 @@ void cmInstallTargetGenerator::Compute(cmLocalGenerator* lg)
this->Target =
lg->GetGlobalGenerator()->FindGeneratorTarget(this->TargetName);
}
+
+ return true;
}
void cmInstallTargetGenerator::AddTweak(std::ostream& os, Indent indent,
diff --git a/Source/cmInstallTargetGenerator.h b/Source/cmInstallTargetGenerator.h
index 6df5b1a..ed3ab52 100644
--- a/Source/cmInstallTargetGenerator.h
+++ b/Source/cmInstallTargetGenerator.h
@@ -58,7 +58,7 @@ public:
const std::string& config,
NameType nameType = NameNormal);
- void Compute(cmLocalGenerator* lg) override;
+ bool Compute(cmLocalGenerator* lg) override;
cmGeneratorTarget* GetTarget() const { return this->Target; }
diff --git a/Source/cmLocalNinjaGenerator.cxx b/Source/cmLocalNinjaGenerator.cxx
index f4e3ed8..e6d4457 100644
--- a/Source/cmLocalNinjaGenerator.cxx
+++ b/Source/cmLocalNinjaGenerator.cxx
@@ -79,19 +79,17 @@ void cmLocalNinjaGenerator::Generate()
}
}
- const std::vector<cmGeneratorTarget*>& targets = this->GetGeneratorTargets();
- for (cmGeneratorTarget* target : targets) {
+ for (cmGeneratorTarget* target : this->GetGeneratorTargets()) {
if (target->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
continue;
}
- cmNinjaTargetGenerator* tg = cmNinjaTargetGenerator::New(target);
+ auto tg = cmNinjaTargetGenerator::New(target);
if (tg) {
tg->Generate();
// Add the target to "all" if required.
if (!this->GetGlobalNinjaGenerator()->IsExcluded(target)) {
this->GetGlobalNinjaGenerator()->AddDependencyToAll(target);
}
- delete tg;
}
}
@@ -283,8 +281,7 @@ void cmLocalNinjaGenerator::AppendTargetDepends(cmGeneratorTarget* target,
void cmLocalNinjaGenerator::AppendCustomCommandDeps(
cmCustomCommandGenerator const& ccg, cmNinjaDeps& ninjaDeps)
{
- const std::vector<std::string>& deps = ccg.GetDepends();
- for (std::string const& i : deps) {
+ for (std::string const& i : ccg.GetDepends()) {
std::string dep;
if (this->GetRealDependency(i, this->GetConfigName(), dep)) {
ninjaDeps.push_back(
diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx
index 2324839..506711a 100644
--- a/Source/cmNinjaTargetGenerator.cxx
+++ b/Source/cmNinjaTargetGenerator.cxx
@@ -9,7 +9,7 @@
#include <iterator>
#include <map>
#include <memory> // IWYU pragma: keep
-#include <sstream>
+#include <ostream>
#include <utility>
#include "cmAlgorithms.h"
@@ -33,7 +33,8 @@
#include "cmSystemTools.h"
#include "cmake.h"
-cmNinjaTargetGenerator* cmNinjaTargetGenerator::New(cmGeneratorTarget* target)
+std::unique_ptr<cmNinjaTargetGenerator> cmNinjaTargetGenerator::New(
+ cmGeneratorTarget* target)
{
switch (target->GetType()) {
case cmStateEnums::EXECUTABLE:
@@ -41,14 +42,14 @@ cmNinjaTargetGenerator* cmNinjaTargetGenerator::New(cmGeneratorTarget* target)
case cmStateEnums::STATIC_LIBRARY:
case cmStateEnums::MODULE_LIBRARY:
case cmStateEnums::OBJECT_LIBRARY:
- return new cmNinjaNormalTargetGenerator(target);
+ return cm::make_unique<cmNinjaNormalTargetGenerator>(target);
case cmStateEnums::UTILITY:
case cmStateEnums::GLOBAL_TARGET:
- return new cmNinjaUtilityTargetGenerator(target);
+ return cm::make_unique<cmNinjaUtilityTargetGenerator>(target);
default:
- return nullptr;
+ return std::unique_ptr<cmNinjaTargetGenerator>();
}
}
@@ -496,12 +497,11 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang)
launcher += " ";
}
- if (explicitPP) {
- // Lookup the explicit preprocessing rule.
- std::string const ppVar = "CMAKE_" + lang + "_PREPROCESS_SOURCE";
- std::string const& ppCmd =
- this->GetMakefile()->GetRequiredDefinition(ppVar);
+ std::string const cmakeCmd =
+ this->GetLocalGenerator()->ConvertToOutputFormat(
+ cmSystemTools::GetCMakeCommand(), cmLocalGenerator::SHELL);
+ if (explicitPP) {
// Explicit preprocessing always uses a depfile.
std::string const ppDeptype; // no deps= for multiple outputs
std::string const ppDepfile = "$DEP_FILE";
@@ -535,8 +535,12 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang)
std::string ppRspContent;
if (!responseFlag.empty()) {
ppRspFile = "$RSP_FILE";
- ppRspContent = std::string(" ") + ppVars.Defines + " " +
- ppVars.Includes + " " + ppFlags;
+ ppRspContent = " ";
+ ppRspContent += ppVars.Defines;
+ ppRspContent += " ";
+ ppRspContent += ppVars.Includes;
+ ppRspContent += " ";
+ ppRspContent += ppFlags;
ppFlags = responseFlag + ppRspFile;
ppVars.Defines = "";
ppVars.Includes = "";
@@ -546,7 +550,13 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang)
// Rule for preprocessing source file.
std::vector<std::string> ppCmds;
- cmSystemTools::ExpandListArgument(ppCmd, ppCmds);
+ {
+ // Lookup the explicit preprocessing rule.
+ std::string ppVar = "CMAKE_" + lang;
+ ppVar += "_PREPROCESS_SOURCE";
+ cmSystemTools::ExpandListArgument(
+ this->GetMakefile()->GetRequiredDefinition(ppVar), ppCmds);
+ }
for (std::string& i : ppCmds) {
i = launcher + i;
@@ -555,67 +565,73 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang)
}
// Run CMake dependency scanner on preprocessed output.
- std::string const cmake = this->GetLocalGenerator()->ConvertToOutputFormat(
- cmSystemTools::GetCMakeCommand(), cmLocalGenerator::SHELL);
- ppCmds.push_back(
- cmake +
- " -E cmake_ninja_depends"
- " --tdi=" +
- tdi + " --lang=" + lang +
- " --pp=$out"
- " --dep=$DEP_FILE" +
- (needDyndep ? " --obj=$OBJ_FILE --ddi=$DYNDEP_INTERMEDIATE_FILE" : ""));
-
+ {
+ std::string ccmd = cmakeCmd;
+ ccmd += " -E cmake_ninja_depends --tdi=";
+ ccmd += tdi;
+ ccmd += " --lang=";
+ ccmd += lang;
+ ccmd += " --pp=$out --dep=$DEP_FILE";
+ if (needDyndep) {
+ ccmd += " --obj=$OBJ_FILE --ddi=$DYNDEP_INTERMEDIATE_FILE";
+ }
+ ppCmds.emplace_back(std::move(ccmd));
+ }
std::string const ppCmdLine =
this->GetLocalGenerator()->BuildCommandLine(ppCmds);
// Write the rule for preprocessing file of the given language.
- std::ostringstream ppComment;
- ppComment << "Rule for preprocessing " << lang << " files.";
- std::ostringstream ppDesc;
- ppDesc << "Building " << lang << " preprocessed $out";
+ std::string ppComment = "Rule for preprocessing ";
+ ppComment += lang;
+ ppComment += " files.";
+ std::string ppDesc = "Building ";
+ ppDesc += lang;
+ ppDesc += " preprocessed $out";
this->GetGlobalGenerator()->AddRule(
- this->LanguagePreprocessRule(lang), ppCmdLine, ppDesc.str(),
- ppComment.str(), ppDepfile, ppDeptype, ppRspFile, ppRspContent,
+ this->LanguagePreprocessRule(lang), ppCmdLine, ppDesc, ppComment,
+ ppDepfile, ppDeptype, ppRspFile, ppRspContent,
/*restat*/ "",
/*generator*/ false);
}
if (needDyndep) {
// Write the rule for ninja dyndep file generation.
- std::vector<std::string> ddCmds;
// Command line length is almost always limited -> use response file for
// dyndep rules
std::string ddRspFile = "$out.rsp";
std::string ddRspContent = "$in";
- std::string ddInput = "@" + ddRspFile;
+ std::string ddCmdLine;
// Run CMake dependency scanner on the source file (using the preprocessed
// source if that was performed).
- std::string const cmake = this->GetLocalGenerator()->ConvertToOutputFormat(
- cmSystemTools::GetCMakeCommand(), cmLocalGenerator::SHELL);
- ddCmds.push_back(cmake +
- " -E cmake_ninja_dyndep"
- " --tdi=" +
- tdi + " --lang=" + lang +
- " --dd=$out"
- " " +
- ddInput);
-
- std::string const ddCmdLine =
- this->GetLocalGenerator()->BuildCommandLine(ddCmds);
-
- std::ostringstream ddComment;
- ddComment << "Rule to generate ninja dyndep files for " << lang << ".";
- std::ostringstream ddDesc;
- ddDesc << "Generating " << lang << " dyndep file $out";
- this->GetGlobalGenerator()->AddRule(
- this->LanguageDyndepRule(lang), ddCmdLine, ddDesc.str(), ddComment.str(),
- /*depfile*/ "",
- /*deps*/ "", ddRspFile, ddRspContent,
- /*restat*/ "",
- /*generator*/ false);
+ {
+ std::vector<std::string> ddCmds;
+ {
+ std::string ccmd = cmakeCmd;
+ ccmd += " -E cmake_ninja_dyndep --tdi=";
+ ccmd += tdi;
+ ccmd += " --lang=";
+ ccmd += lang;
+ ccmd += " --dd=$out ";
+ ccmd += "@";
+ ccmd += ddRspFile;
+ ddCmds.emplace_back(std::move(ccmd));
+ }
+ ddCmdLine = this->GetLocalGenerator()->BuildCommandLine(ddCmds);
+ }
+ std::string ddComment = "Rule to generate ninja dyndep files for ";
+ ddComment += lang;
+ ddComment += ".";
+ std::string ddDesc = "Generating ";
+ ddDesc += lang;
+ ddDesc += " dyndep file $out";
+ this->GetGlobalGenerator()->AddRule(this->LanguageDyndepRule(lang),
+ ddCmdLine, ddDesc, ddComment,
+ /*depfile*/ "",
+ /*deps*/ "", ddRspFile, ddRspContent,
+ /*restat*/ "",
+ /*generator*/ false);
}
// If using a response file, move defines, includes, and flags into it.
@@ -716,8 +732,7 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang)
const char* cppcheck = this->GeneratorTarget->GetProperty(cppcheck_prop);
if ((iwyu && *iwyu) || (tidy && *tidy) || (cpplint && *cpplint) ||
(cppcheck && *cppcheck)) {
- std::string run_iwyu = this->GetLocalGenerator()->ConvertToOutputFormat(
- cmSystemTools::GetCMakeCommand(), cmOutputConverter::SHELL);
+ std::string run_iwyu = cmakeCmd;
run_iwyu += " -E __run_co_compile";
if (!compilerLauncher.empty()) {
// In __run_co_compile case the launcher command is supplied
@@ -776,15 +791,17 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang)
this->GetLocalGenerator()->BuildCommandLine(compileCmds);
// Write the rule for compiling file of the given language.
- std::ostringstream comment;
- comment << "Rule for compiling " << lang << " files.";
- std::ostringstream description;
- description << "Building " << lang << " object $out";
- this->GetGlobalGenerator()->AddRule(
- this->LanguageCompilerRule(lang), cmdLine, description.str(),
- comment.str(), depfile, deptype, rspfile, rspcontent,
- /*restat*/ "",
- /*generator*/ false);
+ std::string comment = "Rule for compiling ";
+ comment += lang;
+ comment += " files.";
+ std::string description = "Building ";
+ description += lang;
+ description += " object $out";
+ this->GetGlobalGenerator()->AddRule(this->LanguageCompilerRule(lang),
+ cmdLine, description, comment, depfile,
+ deptype, rspfile, rspcontent,
+ /*restat*/ "",
+ /*generator*/ false);
}
void cmNinjaTargetGenerator::WriteObjectBuildStatements()
@@ -1212,8 +1229,7 @@ void cmNinjaTargetGenerator::WriteTargetDependInfo(std::string const& lang)
Json::Value& tdi_linked_target_dirs = tdi["linked-target-dirs"] =
Json::arrayValue;
- std::vector<std::string> linked = this->GetLinkedTargetDirectories();
- for (std::string const& l : linked) {
+ for (std::string const& l : this->GetLinkedTargetDirectories()) {
tdi_linked_target_dirs.append(l);
}
diff --git a/Source/cmNinjaTargetGenerator.h b/Source/cmNinjaTargetGenerator.h
index 51c9ac7..3dbc1b5 100644
--- a/Source/cmNinjaTargetGenerator.h
+++ b/Source/cmNinjaTargetGenerator.h
@@ -11,6 +11,7 @@
#include "cmOSXBundleGenerator.h"
#include <map>
+#include <memory> // IWYU pragma: keep
#include <set>
#include <string>
#include <vector>
@@ -26,7 +27,8 @@ class cmNinjaTargetGenerator : public cmCommonTargetGenerator
{
public:
/// Create a cmNinjaTargetGenerator according to the @a target's type.
- static cmNinjaTargetGenerator* New(cmGeneratorTarget* target);
+ static std::unique_ptr<cmNinjaTargetGenerator> New(
+ cmGeneratorTarget* target);
/// Build a NinjaTargetGenerator.
cmNinjaTargetGenerator(cmGeneratorTarget* target);
diff --git a/Source/cmQtAutoGenerator.cxx b/Source/cmQtAutoGenerator.cxx
index f7e377d..e1c435b 100644
--- a/Source/cmQtAutoGenerator.cxx
+++ b/Source/cmQtAutoGenerator.cxx
@@ -279,10 +279,11 @@ bool cmQtAutoGenerator::Run(std::string const& infoFile,
InfoFile_ = infoFile;
cmSystemTools::ConvertToUnixSlashes(InfoFile_);
if (!InfoFileTime_.Load(InfoFile_)) {
- std::string msg = "Autogen: The info file ";
+ std::string msg = "AutoGen: The info file ";
msg += Quoted(InfoFile_);
msg += " is not readable\n";
cmSystemTools::Stderr(msg);
+ return false;
}
InfoDir_ = cmSystemTools::GetFilenamePath(infoFile);
InfoConfig_ = config;
diff --git a/Source/cmQtAutoRcc.cxx b/Source/cmQtAutoRcc.cxx
index bb40c39..7ac7339 100644
--- a/Source/cmQtAutoRcc.cxx
+++ b/Source/cmQtAutoRcc.cxx
@@ -3,6 +3,8 @@
#include "cmQtAutoRcc.h"
#include "cmQtAutoGen.h"
+#include <sstream>
+
#include "cmAlgorithms.h"
#include "cmCryptoHash.h"
#include "cmDuration.h"
@@ -49,11 +51,16 @@ bool cmQtAutoRcc::Init(cmMakefile* makefile)
cmSystemTools::ExpandListArgument(InfoGetConfig(key), list);
return list;
};
+ auto LogInfoError = [this](std::string const& msg) -> bool {
+ std::ostringstream err;
+ err << "In " << Quoted(this->InfoFile()) << ":\n" << msg;
+ this->Log().Error(GenT::RCC, err.str());
+ return false;
+ };
// -- Read info file
if (!makefile->ReadListFile(InfoFile())) {
- Log().ErrorFile(GenT::RCC, InfoFile(), "File processing failed.");
- return false;
+ return LogInfoError("File processing failed.");
}
// - Configurations
@@ -63,18 +70,22 @@ bool cmQtAutoRcc::Init(cmMakefile* makefile)
// - Directories
AutogenBuildDir_ = InfoGet("ARCC_BUILD_DIR");
if (AutogenBuildDir_.empty()) {
- Log().ErrorFile(GenT::RCC, InfoFile(), "Build directory empty.");
- return false;
+ return LogInfoError("Build directory empty.");
}
IncludeDir_ = InfoGetConfig("ARCC_INCLUDE_DIR");
if (IncludeDir_.empty()) {
- Log().ErrorFile(GenT::RCC, InfoFile(), "Include directory empty.");
- return false;
+ return LogInfoError("Include directory empty.");
}
// - Rcc executable
RccExecutable_ = InfoGet("ARCC_RCC_EXECUTABLE");
+ if (!RccExecutableTime_.Load(RccExecutable_)) {
+ std::string error = "The rcc executable ";
+ error += Quoted(RccExecutable_);
+ error += " does not exist.";
+ return LogInfoError(error);
+ }
RccListOptions_ = InfoGetList("ARCC_RCC_LIST_OPTIONS");
// - Job
@@ -92,28 +103,22 @@ bool cmQtAutoRcc::Init(cmMakefile* makefile)
// - Validity checks
if (LockFile_.empty()) {
- Log().ErrorFile(GenT::RCC, InfoFile(), "Lock file name missing.");
- return false;
+ return LogInfoError("Lock file name missing.");
}
if (SettingsFile_.empty()) {
- Log().ErrorFile(GenT::RCC, InfoFile(), "Settings file name missing.");
- return false;
+ return LogInfoError("Settings file name missing.");
}
if (AutogenBuildDir_.empty()) {
- Log().ErrorFile(GenT::RCC, InfoFile(), "Autogen build directory missing.");
- return false;
+ return LogInfoError("Autogen build directory missing.");
}
if (RccExecutable_.empty()) {
- Log().ErrorFile(GenT::RCC, InfoFile(), "rcc executable missing.");
- return false;
+ return LogInfoError("rcc executable missing.");
}
if (QrcFile_.empty()) {
- Log().ErrorFile(GenT::RCC, InfoFile(), "rcc input file missing.");
- return false;
+ return LogInfoError("rcc input file missing.");
}
if (RccFileName_.empty()) {
- Log().ErrorFile(GenT::RCC, InfoFile(), "rcc output file missing.");
- return false;
+ return LogInfoError("rcc output file missing.");
}
// Init derived information
@@ -301,12 +306,10 @@ bool cmQtAutoRcc::TestQrcRccFiles(bool& generate)
// Test if the rcc output file exists
if (!RccFileTime_.Load(RccFileOutput_)) {
if (Log().Verbose()) {
- std::string reason = "Generating ";
- reason += Quoted(RccFileOutput_);
- reason += " from its source file ";
- reason += Quoted(QrcFile_);
- reason += " because it doesn't exist";
- Log().Info(GenT::RCC, reason);
+ Reason = "Generating ";
+ Reason += Quoted(RccFileOutput_);
+ Reason += ", because it doesn't exist, from ";
+ Reason += Quoted(QrcFile_);
}
generate = true;
return true;
@@ -315,12 +318,10 @@ bool cmQtAutoRcc::TestQrcRccFiles(bool& generate)
// Test if the settings changed
if (SettingsChanged_) {
if (Log().Verbose()) {
- std::string reason = "Generating ";
- reason += Quoted(RccFileOutput_);
- reason += " from ";
- reason += Quoted(QrcFile_);
- reason += " because the RCC settings changed";
- Log().Info(GenT::RCC, reason);
+ Reason = "Generating ";
+ Reason += Quoted(RccFileOutput_);
+ Reason += ", because the rcc settings changed, from ";
+ Reason += Quoted(QrcFile_);
}
generate = true;
return true;
@@ -329,11 +330,24 @@ bool cmQtAutoRcc::TestQrcRccFiles(bool& generate)
// Test if the rcc output file is older than the .qrc file
if (RccFileTime_.Older(QrcFileTime_)) {
if (Log().Verbose()) {
- std::string reason = "Generating ";
- reason += Quoted(RccFileOutput_);
- reason += " because it is older than ";
- reason += Quoted(QrcFile_);
- Log().Info(GenT::RCC, reason);
+ Reason = "Generating ";
+ Reason += Quoted(RccFileOutput_);
+ Reason += ", because it is older than ";
+ Reason += Quoted(QrcFile_);
+ Reason += ", from ";
+ Reason += Quoted(QrcFile_);
+ }
+ generate = true;
+ return true;
+ }
+
+ // Test if the rcc output file is older than the rcc executable
+ if (RccFileTime_.Older(RccExecutableTime_)) {
+ if (Log().Verbose()) {
+ Reason = "Generating ";
+ Reason += Quoted(RccFileOutput_);
+ Reason += ", because it is older than the rcc executable, from ";
+ Reason += Quoted(QrcFile_);
}
generate = true;
return true;
@@ -354,6 +368,7 @@ bool cmQtAutoRcc::TestResources(bool& generate)
}
}
+ // Check if any resource file is newer than the rcc output file
for (std::string const& resFile : Inputs_) {
// Check if the resource file exists
cmFileTime fileTime;
@@ -365,16 +380,15 @@ bool cmQtAutoRcc::TestResources(bool& generate)
Log().ErrorFile(GenT::RCC, QrcFile_, error);
return false;
}
- // Check if the resource file is newer than the build file
+ // Check if the resource file is newer than the rcc output file
if (RccFileTime_.Older(fileTime)) {
if (Log().Verbose()) {
- std::string reason = "Generating ";
- reason += Quoted(RccFileOutput_);
- reason += " from ";
- reason += Quoted(QrcFile_);
- reason += " because it is older than ";
- reason += Quoted(resFile);
- Log().Info(GenT::RCC, reason);
+ Reason = "Generating ";
+ Reason += Quoted(RccFileOutput_);
+ Reason += ", because it is older than ";
+ Reason += Quoted(resFile);
+ Reason += ", from ";
+ Reason += Quoted(QrcFile_);
}
generate = true;
break;
@@ -386,17 +400,7 @@ bool cmQtAutoRcc::TestResources(bool& generate)
bool cmQtAutoRcc::TestInfoFile()
{
// Test if the rcc output file is older than the info file
-
- cmFileTime infoFileTime;
- if (!infoFileTime.Load(InfoFile())) {
- std::string error;
- error = "Could not find the info file ";
- error += Quoted(InfoFile());
- error += '\n';
- Log().ErrorFile(GenT::RCC, QrcFile_, error);
- return false;
- }
- if (RccFileTime_.Older(infoFileTime)) {
+ if (RccFileTime_.Older(InfoFileTime())) {
if (Log().Verbose()) {
std::string reason = "Touching ";
reason += Quoted(RccFileOutput_);
@@ -424,7 +428,7 @@ bool cmQtAutoRcc::GenerateRcc()
return false;
}
- // Start a rcc process
+ // Compose rcc command
std::vector<std::string> cmd;
cmd.push_back(RccExecutable_);
cmd.insert(cmd.end(), Options_.begin(), Options_.end());
@@ -432,12 +436,15 @@ bool cmQtAutoRcc::GenerateRcc()
cmd.push_back(RccFileOutput_);
cmd.push_back(QrcFile_);
- // Log command
+ // Log reason and command
if (Log().Verbose()) {
- std::string msg = "Running command:\n";
+ std::string msg = Reason;
+ if (!msg.empty() && (msg.back() != '\n')) {
+ msg += '\n';
+ }
msg += QuotedCommand(cmd);
msg += '\n';
- cmSystemTools::Stdout(msg);
+ Log().Info(GenT::RCC, msg);
}
std::string rccStdOut;
diff --git a/Source/cmQtAutoRcc.h b/Source/cmQtAutoRcc.h
index 01c3fb9..636a667 100644
--- a/Source/cmQtAutoRcc.h
+++ b/Source/cmQtAutoRcc.h
@@ -54,6 +54,7 @@ private:
std::string IncludeDir_;
// -- Qt environment
std::string RccExecutable_;
+ cmFileTime RccExecutableTime_;
std::vector<std::string> RccListOptions_;
// -- Job
std::string LockFile_;
@@ -67,6 +68,7 @@ private:
std::string RccFileOutput_;
std::string RccFilePublic_;
cmFileTime RccFileTime_;
+ std::string Reason;
std::vector<std::string> Options_;
std::vector<std::string> Inputs_;
// -- Settings file
diff --git a/Source/cmUVHandlePtr.cxx b/Source/cmUVHandlePtr.cxx
index 27069ee..db67463 100644
--- a/Source/cmUVHandlePtr.cxx
+++ b/Source/cmUVHandlePtr.cxx
@@ -211,7 +211,6 @@ uv_pipe_ptr::operator uv_stream_t*() const
return reinterpret_cast<uv_stream_t*>(handle.get());
}
-#ifdef CMAKE_BUILD_WITH_CMAKE
int uv_process_ptr::spawn(uv_loop_t& loop, uv_process_options_t const& options,
void* data)
{
@@ -231,6 +230,7 @@ int uv_timer_ptr::start(uv_timer_cb cb, uint64_t timeout, uint64_t repeat)
return uv_timer_start(*this, cb, timeout, repeat);
}
+#ifdef CMAKE_BUILD_WITH_CMAKE
uv_tty_ptr::operator uv_stream_t*() const
{
return reinterpret_cast<uv_stream_t*>(handle.get());
@@ -255,13 +255,13 @@ UV_HANDLE_PTR_INSTANTIATE_EXPLICIT(pipe)
UV_HANDLE_PTR_INSTANTIATE_EXPLICIT(stream)
-#ifdef CMAKE_BUILD_WITH_CMAKE
-UV_HANDLE_PTR_INSTANTIATE_EXPLICIT(async)
-
UV_HANDLE_PTR_INSTANTIATE_EXPLICIT(process)
UV_HANDLE_PTR_INSTANTIATE_EXPLICIT(timer)
+#ifdef CMAKE_BUILD_WITH_CMAKE
+UV_HANDLE_PTR_INSTANTIATE_EXPLICIT(async)
+
UV_HANDLE_PTR_INSTANTIATE_EXPLICIT(tty)
#endif
}
diff --git a/Source/cmUVProcessChain.cxx b/Source/cmUVProcessChain.cxx
new file mode 100644
index 0000000..c4e30d4
--- /dev/null
+++ b/Source/cmUVProcessChain.cxx
@@ -0,0 +1,392 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#include "cmUVProcessChain.h"
+
+#include "cmAlgorithms.h"
+#include "cmGetPipes.h"
+#include "cmUVHandlePtr.h"
+#include "cmUVStreambuf.h"
+#include "cm_uv.h"
+
+#include <iterator>
+#include <memory>
+#include <utility>
+
+struct cmUVProcessChain::InternalData
+{
+ struct BasicStreamData
+ {
+ cmUVStreambuf Streambuf;
+ cm::uv_pipe_ptr BuiltinStream;
+ uv_stdio_container_t Stdio;
+ };
+
+ template <typename IOStream>
+ struct StreamData : public BasicStreamData
+ {
+ StreamData()
+ : BuiltinIOStream(&this->Streambuf)
+ {
+ }
+
+ IOStream BuiltinIOStream;
+
+ IOStream* GetBuiltinStream()
+ {
+ if (this->BuiltinStream.get()) {
+ return &this->BuiltinIOStream;
+ }
+ return nullptr;
+ }
+ };
+
+ struct ProcessData
+ {
+ cmUVProcessChain::InternalData* Data;
+ cm::uv_process_ptr Process;
+ cm::uv_pipe_ptr OutputPipe;
+ bool Finished = false;
+ Status ProcessStatus;
+ };
+
+ const cmUVProcessChainBuilder* Builder = nullptr;
+
+ bool Valid = false;
+
+ cm::uv_loop_ptr Loop;
+
+ StreamData<std::istream> OutputStreamData;
+ StreamData<std::istream> ErrorStreamData;
+
+ unsigned int ProcessesCompleted = 0;
+ std::vector<std::unique_ptr<ProcessData>> Processes;
+
+ bool Prepare(const cmUVProcessChainBuilder* builder);
+ bool AddCommand(const cmUVProcessChainBuilder::ProcessConfiguration& config,
+ bool first, bool last);
+ bool Finish();
+
+ static const Status* GetStatus(const ProcessData& data);
+};
+
+cmUVProcessChainBuilder::cmUVProcessChainBuilder()
+{
+ this->SetNoStream(Stream_INPUT)
+ .SetNoStream(Stream_OUTPUT)
+ .SetNoStream(Stream_ERROR);
+}
+
+cmUVProcessChainBuilder& cmUVProcessChainBuilder::AddCommand(
+ const std::vector<std::string>& arguments)
+{
+ if (!arguments.empty()) {
+ this->Processes.emplace_back();
+ this->Processes.back().Arguments = arguments;
+ }
+ return *this;
+}
+
+cmUVProcessChainBuilder& cmUVProcessChainBuilder::SetNoStream(Stream stdio)
+{
+ switch (stdio) {
+ case Stream_INPUT:
+ case Stream_OUTPUT:
+ case Stream_ERROR: {
+ auto& streamData = this->Stdio[stdio];
+ streamData.Type = None;
+ break;
+ }
+ }
+ return *this;
+}
+
+cmUVProcessChainBuilder& cmUVProcessChainBuilder::SetBuiltinStream(
+ Stream stdio)
+{
+ switch (stdio) {
+ case Stream_INPUT:
+ // FIXME
+ break;
+
+ case Stream_OUTPUT:
+ case Stream_ERROR: {
+ auto& streamData = this->Stdio[stdio];
+ streamData.Type = Builtin;
+ break;
+ }
+ }
+ return *this;
+}
+
+cmUVProcessChainBuilder& cmUVProcessChainBuilder::SetExternalStream(
+ Stream stdio, int fd)
+{
+ switch (stdio) {
+ case Stream_INPUT:
+ // FIXME
+ break;
+
+ case Stream_OUTPUT:
+ case Stream_ERROR: {
+ auto& streamData = this->Stdio[stdio];
+ streamData.Type = External;
+ streamData.FileDescriptor = fd;
+ break;
+ }
+ }
+ return *this;
+}
+
+cmUVProcessChain cmUVProcessChainBuilder::Start() const
+{
+ cmUVProcessChain chain;
+
+ if (!chain.Data->Prepare(this)) {
+ return chain;
+ }
+
+ for (auto it = this->Processes.begin(); it != this->Processes.end(); ++it) {
+ if (!chain.Data->AddCommand(*it, it == this->Processes.begin(),
+ it == std::prev(this->Processes.end()))) {
+ return chain;
+ }
+ }
+
+ chain.Data->Finish();
+
+ return chain;
+}
+
+const cmUVProcessChain::Status* cmUVProcessChain::InternalData::GetStatus(
+ const cmUVProcessChain::InternalData::ProcessData& data)
+{
+ if (data.Finished) {
+ return &data.ProcessStatus;
+ }
+ return nullptr;
+}
+
+bool cmUVProcessChain::InternalData::Prepare(
+ const cmUVProcessChainBuilder* builder)
+{
+ this->Builder = builder;
+
+ auto const& output =
+ this->Builder->Stdio[cmUVProcessChainBuilder::Stream_OUTPUT];
+ auto& outputData = this->OutputStreamData;
+ switch (output.Type) {
+ case cmUVProcessChainBuilder::None:
+ outputData.Stdio.flags = UV_IGNORE;
+ break;
+
+ case cmUVProcessChainBuilder::Builtin:
+ outputData.BuiltinStream.init(*this->Loop, 0);
+ outputData.Stdio.flags =
+ static_cast<uv_stdio_flags>(UV_CREATE_PIPE | UV_WRITABLE_PIPE);
+ outputData.Stdio.data.stream = outputData.BuiltinStream;
+ break;
+
+ case cmUVProcessChainBuilder::External:
+ outputData.Stdio.flags = UV_INHERIT_FD;
+ outputData.Stdio.data.fd = output.FileDescriptor;
+ break;
+ }
+
+ auto const& error =
+ this->Builder->Stdio[cmUVProcessChainBuilder::Stream_ERROR];
+ auto& errorData = this->ErrorStreamData;
+ switch (error.Type) {
+ case cmUVProcessChainBuilder::None:
+ errorData.Stdio.flags = UV_IGNORE;
+ break;
+
+ case cmUVProcessChainBuilder::Builtin: {
+ int pipeFd[2];
+ if (cmGetPipes(pipeFd) < 0) {
+ return false;
+ }
+
+ errorData.BuiltinStream.init(*this->Loop, 0);
+ if (uv_pipe_open(errorData.BuiltinStream, pipeFd[0]) < 0) {
+ return false;
+ }
+ errorData.Stdio.flags = UV_INHERIT_FD;
+ errorData.Stdio.data.fd = pipeFd[1];
+ break;
+ }
+
+ case cmUVProcessChainBuilder::External:
+ errorData.Stdio.flags = UV_INHERIT_FD;
+ errorData.Stdio.data.fd = error.FileDescriptor;
+ break;
+ }
+
+ return true;
+}
+
+bool cmUVProcessChain::InternalData::AddCommand(
+ const cmUVProcessChainBuilder::ProcessConfiguration& config, bool first,
+ bool last)
+{
+ this->Processes.emplace_back(cm::make_unique<ProcessData>());
+ auto& process = *this->Processes.back();
+ process.Data = this;
+
+ auto options = uv_process_options_t();
+
+ // Bounds were checked at add time, first element is guaranteed to exist
+ options.file = config.Arguments[0].c_str();
+
+ std::vector<const char*> arguments;
+ for (auto const& arg : config.Arguments) {
+ arguments.push_back(arg.c_str());
+ }
+ arguments.push_back(nullptr);
+ options.args = const_cast<char**>(arguments.data());
+ options.flags = UV_PROCESS_WINDOWS_HIDE;
+
+ std::array<uv_stdio_container_t, 3> stdio;
+ stdio[0] = uv_stdio_container_t();
+ if (first) {
+ stdio[0].flags = UV_IGNORE;
+ } else {
+ auto& prev = **std::prev(this->Processes.end(), 2);
+ stdio[0].flags = UV_INHERIT_STREAM;
+ stdio[0].data.stream = prev.OutputPipe;
+ }
+ if (last) {
+ stdio[1] = this->OutputStreamData.Stdio;
+ } else {
+ if (process.OutputPipe.init(*this->Loop, 0) < 0) {
+ return false;
+ }
+ stdio[1] = uv_stdio_container_t();
+ stdio[1].flags =
+ static_cast<uv_stdio_flags>(UV_CREATE_PIPE | UV_WRITABLE_PIPE);
+ stdio[1].data.stream = process.OutputPipe;
+ }
+ stdio[2] = this->ErrorStreamData.Stdio;
+
+ options.stdio = stdio.data();
+ options.stdio_count = 3;
+ options.exit_cb = [](uv_process_t* handle, int64_t exitStatus,
+ int termSignal) {
+ auto* processData = static_cast<ProcessData*>(handle->data);
+ processData->Finished = true;
+ processData->ProcessStatus.ExitStatus = exitStatus;
+ processData->ProcessStatus.TermSignal = termSignal;
+ processData->Data->ProcessesCompleted++;
+ };
+
+ return process.Process.spawn(*this->Loop, options, &process) >= 0;
+}
+
+bool cmUVProcessChain::InternalData::Finish()
+{
+ if (this->Builder->Stdio[cmUVProcessChainBuilder::Stream_OUTPUT].Type ==
+ cmUVProcessChainBuilder::Builtin) {
+ this->OutputStreamData.Streambuf.open(
+ this->OutputStreamData.BuiltinStream);
+ }
+
+ if (this->Builder->Stdio[cmUVProcessChainBuilder::Stream_ERROR].Type ==
+ cmUVProcessChainBuilder::Builtin) {
+ cm::uv_pipe_ptr tmpPipe;
+ if (tmpPipe.init(*this->Loop, 0) < 0) {
+ return false;
+ }
+ if (uv_pipe_open(tmpPipe, this->ErrorStreamData.Stdio.data.fd) < 0) {
+ return false;
+ }
+ tmpPipe.reset();
+
+ this->ErrorStreamData.Streambuf.open(this->ErrorStreamData.BuiltinStream);
+ }
+
+ this->Valid = true;
+ return true;
+}
+
+cmUVProcessChain::cmUVProcessChain()
+ : Data(cm::make_unique<InternalData>())
+{
+ this->Data->Loop.init();
+}
+
+cmUVProcessChain::cmUVProcessChain(cmUVProcessChain&& other) noexcept
+ : Data(std::move(other.Data))
+{
+}
+
+cmUVProcessChain::~cmUVProcessChain() = default;
+
+cmUVProcessChain& cmUVProcessChain::operator=(
+ cmUVProcessChain&& other) noexcept
+{
+ this->Data = std::move(other.Data);
+ return *this;
+}
+
+uv_loop_t& cmUVProcessChain::GetLoop()
+{
+ return *this->Data->Loop;
+}
+
+std::istream* cmUVProcessChain::OutputStream()
+{
+ return this->Data->OutputStreamData.GetBuiltinStream();
+}
+
+std::istream* cmUVProcessChain::ErrorStream()
+{
+ return this->Data->ErrorStreamData.GetBuiltinStream();
+}
+
+bool cmUVProcessChain::Valid() const
+{
+ return this->Data->Valid;
+}
+
+bool cmUVProcessChain::Wait(int64_t milliseconds)
+{
+ bool timeout = false;
+ cm::uv_timer_ptr timer;
+
+ if (milliseconds >= 0) {
+ timer.init(*this->Data->Loop, &timeout);
+ timer.start(
+ [](uv_timer_t* handle) {
+ auto* timeoutPtr = static_cast<bool*>(handle->data);
+ *timeoutPtr = true;
+ },
+ milliseconds, 0);
+ }
+
+ while (!timeout &&
+ this->Data->ProcessesCompleted < this->Data->Processes.size()) {
+ uv_run(this->Data->Loop, UV_RUN_ONCE);
+ }
+
+ return !timeout;
+}
+
+std::vector<const cmUVProcessChain::Status*> cmUVProcessChain::GetStatus()
+ const
+{
+ std::vector<const cmUVProcessChain::Status*> statuses(
+ this->Data->Processes.size(), nullptr);
+ for (std::size_t i = 0; i < statuses.size(); i++) {
+ statuses[i] = this->GetStatus(i);
+ }
+ return statuses;
+}
+
+const cmUVProcessChain::Status* cmUVProcessChain::GetStatus(
+ std::size_t index) const
+{
+ auto const& process = *this->Data->Processes[index];
+ if (process.Finished) {
+ return &process.ProcessStatus;
+ }
+ return nullptr;
+}
diff --git a/Source/cmUVProcessChain.h b/Source/cmUVProcessChain.h
new file mode 100644
index 0000000..2b33520
--- /dev/null
+++ b/Source/cmUVProcessChain.h
@@ -0,0 +1,100 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#ifndef cmUVProcessChain_h
+#define cmUVProcessChain_h
+
+#include "cm_uv.h"
+
+#include <array>
+#include <iosfwd>
+#include <memory> // IWYU pragma: keep
+#include <string>
+#include <vector>
+
+#include <stdint.h>
+
+class cmUVProcessChain;
+
+class cmUVProcessChainBuilder
+{
+public:
+ enum Stream
+ {
+ Stream_INPUT = 0,
+ Stream_OUTPUT = 1,
+ Stream_ERROR = 2,
+ };
+
+ cmUVProcessChainBuilder();
+
+ cmUVProcessChainBuilder& AddCommand(
+ const std::vector<std::string>& arguments);
+ cmUVProcessChainBuilder& SetNoStream(Stream stdio);
+ cmUVProcessChainBuilder& SetBuiltinStream(Stream stdio);
+ cmUVProcessChainBuilder& SetExternalStream(Stream stdio, int fd);
+
+ cmUVProcessChain Start() const;
+
+private:
+ enum StdioType
+ {
+ None,
+ Builtin,
+ External,
+ };
+
+ friend class cmUVProcessChain;
+
+ struct StdioConfiguration
+ {
+ StdioType Type;
+ int FileDescriptor;
+ };
+
+ struct ProcessConfiguration
+ {
+ std::vector<std::string> Arguments;
+ };
+
+ std::array<StdioConfiguration, 3> Stdio;
+ std::vector<ProcessConfiguration> Processes;
+};
+
+class cmUVProcessChain
+{
+public:
+ struct Status
+ {
+ int64_t ExitStatus;
+ int TermSignal;
+ };
+
+ cmUVProcessChain(const cmUVProcessChain& other) = delete;
+ cmUVProcessChain(cmUVProcessChain&& other) noexcept;
+
+ ~cmUVProcessChain();
+
+ cmUVProcessChain& operator=(const cmUVProcessChain& other) = delete;
+ cmUVProcessChain& operator=(cmUVProcessChain&& other) noexcept;
+
+ uv_loop_t& GetLoop();
+
+ // FIXME: Add stdin support
+ std::istream* OutputStream();
+ std::istream* ErrorStream();
+
+ bool Valid() const;
+ bool Wait(int64_t milliseconds = -1);
+ std::vector<const Status*> GetStatus() const;
+ const Status* GetStatus(std::size_t index) const;
+
+private:
+ friend class cmUVProcessChainBuilder;
+
+ cmUVProcessChain();
+
+ struct InternalData;
+ std::unique_ptr<InternalData> Data;
+};
+
+#endif
diff --git a/Source/cmUVStreambuf.h b/Source/cmUVStreambuf.h
index 29e4fde..873352b 100644
--- a/Source/cmUVStreambuf.h
+++ b/Source/cmUVStreambuf.h
@@ -68,10 +68,10 @@ protected:
private:
uv_stream_t* Stream = nullptr;
- void* OldStreamData;
- const std::size_t PutBack;
+ void* OldStreamData = nullptr;
+ const std::size_t PutBack = 0;
std::vector<CharT> InputBuffer;
- bool EndOfFile;
+ bool EndOfFile = false;
void StreamReadStartStop();
@@ -208,7 +208,7 @@ void cmBasicUVStreambuf<CharT, Traits>::StreamRead(ssize_t nread)
this->setg(this->eback(), this->gptr(),
this->egptr() + nread / sizeof(CharT));
uv_read_stop(this->Stream);
- } else if (nread < 0 || nread == UV_EOF) {
+ } else if (nread < 0 /*|| nread == UV_EOF*/) {
this->EndOfFile = true;
uv_read_stop(this->Stream);
}
diff --git a/Source/cmake.cxx b/Source/cmake.cxx
index 121d12d..d19de21 100644
--- a/Source/cmake.cxx
+++ b/Source/cmake.cxx
@@ -1733,6 +1733,11 @@ int cmake::Run(const std::vector<std::string>& args, bool noconfigure)
return ret;
}
ret = this->Generate();
+ if (ret) {
+ cmSystemTools::Message("CMake Generate step failed. "
+ "Build files cannot be regenerated correctly.");
+ return ret;
+ }
std::string message = "Build files have been written to: ";
message += this->GetHomeOutputDirectory();
this->UpdateProgress(message, -1);
diff --git a/Tests/CMakeLib/CMakeLists.txt b/Tests/CMakeLib/CMakeLists.txt
index e04bba2..a25f25a 100644
--- a/Tests/CMakeLib/CMakeLists.txt
+++ b/Tests/CMakeLib/CMakeLists.txt
@@ -15,11 +15,15 @@ set(CMakeLib_TESTS
testXMLParser.cxx
testXMLSafe.cxx
testFindPackageCommand.cxx
+ testUVProcessChain.cxx
testUVRAII.cxx
testUVStreambuf.cxx
)
+add_executable(testUVProcessChainHelper testUVProcessChainHelper.cxx)
+
set(testRST_ARGS ${CMAKE_CURRENT_SOURCE_DIR})
+set(testUVProcessChain_ARGS $<TARGET_FILE:testUVProcessChainHelper>)
set(testUVStreambuf_ARGS $<TARGET_FILE:cmake>)
if(WIN32)
diff --git a/Tests/CMakeLib/testUVProcessChain.cxx b/Tests/CMakeLib/testUVProcessChain.cxx
new file mode 100644
index 0000000..72ae602
--- /dev/null
+++ b/Tests/CMakeLib/testUVProcessChain.cxx
@@ -0,0 +1,335 @@
+#include "cmUVProcessChain.h"
+
+#include "cmAlgorithms.h"
+#include "cmGetPipes.h"
+#include "cmUVHandlePtr.h"
+#include "cmUVStreambuf.h"
+
+#include "cm_uv.h"
+
+#include <algorithm>
+#include <functional>
+#include <iostream>
+#include <sstream>
+#include <string>
+#include <vector>
+
+#include <csignal>
+
+struct ExpectedStatus
+{
+ bool Finished;
+ bool MatchExitStatus;
+ bool MatchTermSignal;
+ cmUVProcessChain::Status Status;
+};
+
+static const std::vector<ExpectedStatus> status1 = {
+ { false, false, false, { 0, 0 } },
+ { false, false, false, { 0, 0 } },
+ { false, false, false, { 0, 0 } },
+};
+
+static const std::vector<ExpectedStatus> status2 = {
+ { true, true, true, { 0, 0 } },
+ { false, false, false, { 0, 0 } },
+ { false, false, false, { 0, 0 } },
+};
+
+static const std::vector<ExpectedStatus> status3 = {
+ { true, true, true, { 0, 0 } },
+ { true, true, true, { 1, 0 } },
+#ifdef _WIN32
+ { true, true, true, { 2, 0 } },
+#else
+ { true, false, true, { 0, SIGABRT } },
+#endif
+};
+
+bool operator==(const cmUVProcessChain::Status* actual,
+ const ExpectedStatus& expected)
+{
+ if (!expected.Finished) {
+ return !actual;
+ } else if (!actual) {
+ return false;
+ }
+ if (expected.MatchExitStatus &&
+ expected.Status.ExitStatus != actual->ExitStatus) {
+ return false;
+ }
+ if (expected.MatchTermSignal &&
+ expected.Status.TermSignal != actual->TermSignal) {
+ return false;
+ }
+ return true;
+}
+
+bool resultsMatch(const std::vector<const cmUVProcessChain::Status*>& actual,
+ const std::vector<ExpectedStatus>& expected)
+{
+ return actual.size() == expected.size() &&
+ std::equal(actual.begin(), actual.end(), expected.begin());
+}
+
+std::string getInput(std::istream& input)
+{
+ char buffer[1024];
+ std::ostringstream str;
+ do {
+ input.read(buffer, 1024);
+ str.write(buffer, input.gcount());
+ } while (input.gcount() > 0);
+ return str.str();
+}
+
+template <typename T>
+std::function<std::ostream&(std::ostream&)> printExpected(bool match,
+ const T& value)
+{
+ return [match, value](std::ostream& stream) -> std::ostream& {
+ if (match) {
+ stream << value;
+ } else {
+ stream << "*";
+ }
+ return stream;
+ };
+}
+
+std::ostream& operator<<(
+ std::ostream& stream,
+ const std::function<std::ostream&(std::ostream&)>& func)
+{
+ return func(stream);
+}
+
+void printResults(const std::vector<const cmUVProcessChain::Status*>& actual,
+ const std::vector<ExpectedStatus>& expected)
+{
+ std::cout << "Expected: " << std::endl;
+ for (auto const& e : expected) {
+ if (e.Finished) {
+ std::cout << " ExitStatus: "
+ << printExpected(e.MatchExitStatus, e.Status.ExitStatus)
+ << ", TermSignal: "
+ << printExpected(e.MatchTermSignal, e.Status.TermSignal)
+ << std::endl;
+ } else {
+ std::cout << " null" << std::endl;
+ }
+ }
+ std::cout << "Actual:" << std::endl;
+ for (auto const& a : actual) {
+ if (a) {
+ std::cout << " ExitStatus: " << a->ExitStatus
+ << ", TermSignal: " << a->TermSignal << std::endl;
+ } else {
+ std::cout << " null" << std::endl;
+ }
+ }
+}
+
+bool checkExecution(cmUVProcessChainBuilder& builder,
+ std::unique_ptr<cmUVProcessChain>& chain)
+{
+ std::vector<const cmUVProcessChain::Status*> status;
+
+ chain = cm::make_unique<cmUVProcessChain>(builder.Start());
+ if (!chain->Valid()) {
+ std::cout << "Valid() returned false, should be true" << std::endl;
+ return false;
+ }
+ status = chain->GetStatus();
+ if (!resultsMatch(status, status1)) {
+ std::cout << "GetStatus() did not produce expected output" << std::endl;
+ printResults(status, status1);
+ return false;
+ }
+
+ if (chain->Wait(6000)) {
+ std::cout << "Wait() returned true, should be false" << std::endl;
+ return false;
+ }
+ status = chain->GetStatus();
+ if (!resultsMatch(status, status2)) {
+ std::cout << "GetStatus() did not produce expected output" << std::endl;
+ printResults(status, status2);
+ return false;
+ }
+
+ if (!chain->Wait()) {
+ std::cout << "Wait() returned false, should be true" << std::endl;
+ return false;
+ }
+ status = chain->GetStatus();
+ if (!resultsMatch(status, status3)) {
+ std::cout << "GetStatus() did not produce expected output" << std::endl;
+ printResults(status, status3);
+ return false;
+ }
+
+ return true;
+}
+
+bool checkOutput(std::istream& outputStream, std::istream& errorStream)
+{
+ std::string output = getInput(outputStream);
+ if (output != "HELO WRD!") {
+ std::cout << "Output was \"" << output << "\", expected \"HELO WRD!\""
+ << std::endl;
+ return false;
+ }
+
+ std::string error = getInput(errorStream);
+ if (error.length() != 3 || error.find('1') == std::string::npos ||
+ error.find('2') == std::string::npos ||
+ error.find('3') == std::string::npos) {
+ std::cout << "Error was \"" << error << "\", expected \"123\""
+ << std::endl;
+ return false;
+ }
+
+ return true;
+}
+
+bool testUVProcessChainBuiltin(const char* helperCommand)
+{
+ cmUVProcessChainBuilder builder;
+ std::unique_ptr<cmUVProcessChain> chain;
+ builder.AddCommand({ helperCommand, "echo" })
+ .AddCommand({ helperCommand, "capitalize" })
+ .AddCommand({ helperCommand, "dedup" })
+ .SetBuiltinStream(cmUVProcessChainBuilder::Stream_OUTPUT)
+ .SetBuiltinStream(cmUVProcessChainBuilder::Stream_ERROR);
+
+ if (!checkExecution(builder, chain)) {
+ return false;
+ }
+
+ if (!chain->OutputStream()) {
+ std::cout << "OutputStream() was null, expecting not null" << std::endl;
+ return false;
+ }
+ if (!chain->ErrorStream()) {
+ std::cout << "ErrorStream() was null, expecting not null" << std::endl;
+ return false;
+ }
+
+ if (!checkOutput(*chain->OutputStream(), *chain->ErrorStream())) {
+ return false;
+ }
+
+ return true;
+}
+
+bool testUVProcessChainExternal(const char* helperCommand)
+{
+ cmUVProcessChainBuilder builder;
+ std::unique_ptr<cmUVProcessChain> chain;
+ int outputPipe[2], errorPipe[2];
+ cm::uv_pipe_ptr outputInPipe, outputOutPipe, errorInPipe, errorOutPipe;
+
+ if (cmGetPipes(outputPipe) < 0) {
+ std::cout << "Error creating pipes" << std::endl;
+ return false;
+ }
+ if (cmGetPipes(errorPipe) < 0) {
+ std::cout << "Error creating pipes" << std::endl;
+ return false;
+ }
+
+ builder.AddCommand({ helperCommand, "echo" })
+ .AddCommand({ helperCommand, "capitalize" })
+ .AddCommand({ helperCommand, "dedup" })
+ .SetExternalStream(cmUVProcessChainBuilder::Stream_OUTPUT, outputPipe[1])
+ .SetExternalStream(cmUVProcessChainBuilder::Stream_ERROR, errorPipe[1]);
+
+ if (!checkExecution(builder, chain)) {
+ return false;
+ }
+
+ if (chain->OutputStream()) {
+ std::cout << "OutputStream() was not null, expecting null" << std::endl;
+ return false;
+ }
+ if (chain->ErrorStream()) {
+ std::cout << "ErrorStream() was not null, expecting null" << std::endl;
+ return false;
+ }
+
+ outputOutPipe.init(chain->GetLoop(), 0);
+ uv_pipe_open(outputOutPipe, outputPipe[1]);
+ outputOutPipe.reset();
+
+ errorOutPipe.init(chain->GetLoop(), 0);
+ uv_pipe_open(errorOutPipe, errorPipe[1]);
+ errorOutPipe.reset();
+
+ outputInPipe.init(chain->GetLoop(), 0);
+ uv_pipe_open(outputInPipe, outputPipe[0]);
+ cmUVStreambuf outputBuf;
+ outputBuf.open(outputInPipe);
+ std::istream outputStream(&outputBuf);
+
+ errorInPipe.init(chain->GetLoop(), 0);
+ uv_pipe_open(errorInPipe, errorPipe[0]);
+ cmUVStreambuf errorBuf;
+ errorBuf.open(errorInPipe);
+ std::istream errorStream(&errorBuf);
+
+ if (!checkOutput(outputStream, errorStream)) {
+ return false;
+ }
+
+ return true;
+}
+
+bool testUVProcessChainNone(const char* helperCommand)
+{
+ cmUVProcessChainBuilder builder;
+ std::unique_ptr<cmUVProcessChain> chain;
+ builder.AddCommand({ helperCommand, "echo" })
+ .AddCommand({ helperCommand, "capitalize" })
+ .AddCommand({ helperCommand, "dedup" });
+
+ if (!checkExecution(builder, chain)) {
+ return false;
+ }
+
+ if (chain->OutputStream()) {
+ std::cout << "OutputStream() was not null, expecting null" << std::endl;
+ return false;
+ }
+ if (chain->ErrorStream()) {
+ std::cout << "ErrorStream() was not null, expecting null" << std::endl;
+ return false;
+ }
+
+ return true;
+}
+
+int testUVProcessChain(int argc, char** const argv)
+{
+ if (argc < 2) {
+ std::cout << "Invalid arguments.\n";
+ return -1;
+ }
+
+ if (!testUVProcessChainBuiltin(argv[1])) {
+ std::cout << "While executing testUVProcessChainBuiltin().\n";
+ return -1;
+ }
+
+ if (!testUVProcessChainExternal(argv[1])) {
+ std::cout << "While executing testUVProcessChainExternal().\n";
+ return -1;
+ }
+
+ if (!testUVProcessChainNone(argv[1])) {
+ std::cout << "While executing testUVProcessChainNone().\n";
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/Tests/CMakeLib/testUVProcessChainHelper.cxx b/Tests/CMakeLib/testUVProcessChainHelper.cxx
new file mode 100644
index 0000000..263665d
--- /dev/null
+++ b/Tests/CMakeLib/testUVProcessChainHelper.cxx
@@ -0,0 +1,72 @@
+#include <chrono>
+#include <iostream>
+#include <set>
+#include <sstream>
+#include <string>
+#include <thread>
+
+#include <cctype>
+#include <cstdlib>
+
+std::string getStdin()
+{
+ char buffer[1024];
+ std::ostringstream str;
+ do {
+ std::cin.read(buffer, 1024);
+ str.write(buffer, std::cin.gcount());
+ } while (std::cin.gcount() > 0);
+ return str.str();
+}
+
+int main(int argc, char** argv)
+{
+ if (argc < 2) {
+ return -1;
+ }
+
+ std::string command = argv[1];
+ if (command == "echo") {
+ std::this_thread::sleep_for(std::chrono::milliseconds(3000));
+ std::cout << "HELLO world!" << std::flush;
+ std::cerr << "1" << std::flush;
+ return 0;
+ }
+ if (command == "capitalize") {
+ std::this_thread::sleep_for(std::chrono::milliseconds(9000));
+ std::string input = getStdin();
+ for (auto& c : input) {
+ c = static_cast<char>(std::toupper(c));
+ }
+ std::cout << input << std::flush;
+ std::cerr << "2" << std::flush;
+ return 1;
+ }
+ if (command == "dedup") {
+ // Use a nested scope to free all resources before aborting below.
+ {
+ std::string input = getStdin();
+ std::set<char> seen;
+ std::string output;
+ for (auto c : input) {
+ if (!seen.count(c)) {
+ seen.insert(c);
+ output += c;
+ }
+ }
+ std::cout << output << std::flush;
+ std::cerr << "3" << std::flush;
+ }
+
+ // On Windows, the exit code of abort() is different between debug and
+ // release builds, and does not yield a term_signal in libuv in either
+ // case. For the sake of simplicity, we just return another non-zero code.
+#ifdef _WIN32
+ return 2;
+#else
+ std::abort();
+#endif
+ }
+
+ return -1;
+}
diff --git a/Tests/CompileFeatures/cxx_relaxed_constexpr.cpp b/Tests/CompileFeatures/cxx_relaxed_constexpr.cpp
index 7b3602c..953148d 100644
--- a/Tests/CompileFeatures/cxx_relaxed_constexpr.cpp
+++ b/Tests/CompileFeatures/cxx_relaxed_constexpr.cpp
@@ -22,6 +22,7 @@ constexpr int g(const int (&is)[4])
int someFunc()
{
- constexpr int k3 = g({ 4, 5, 6, 7 });
+ constexpr int values[4] = { 4, 5, 6, 7 };
+ constexpr int k3 = g(values);
return k3 - 42;
}
diff --git a/Tests/RunCMake/CMP0069/CMP0069-NEW-cmake-stderr.txt b/Tests/RunCMake/CMP0069/CMP0069-NEW-cmake-stderr.txt
index ddb3cae..87ac88e 100644
--- a/Tests/RunCMake/CMP0069/CMP0069-NEW-cmake-stderr.txt
+++ b/Tests/RunCMake/CMP0069/CMP0069-NEW-cmake-stderr.txt
@@ -1,4 +1,6 @@
^CMake Error at CMP0069-NEW-cmake\.cmake:[0-9]+ \(add_executable\):
CMake doesn't support IPO for current compiler
Call Stack \(most recent call first\):
- CMakeLists\.txt:[0-9]+ \(include\)$
+ CMakeLists\.txt:[0-9]+ \(include\)
++
+CMake Generate step failed\. Build files cannot be regenerated correctly\.$
diff --git a/Tests/RunCMake/CMP0069/CMP0069-NEW-compiler-stderr.txt b/Tests/RunCMake/CMP0069/CMP0069-NEW-compiler-stderr.txt
index 8decfab..cb9d19b 100644
--- a/Tests/RunCMake/CMP0069/CMP0069-NEW-compiler-stderr.txt
+++ b/Tests/RunCMake/CMP0069/CMP0069-NEW-compiler-stderr.txt
@@ -1,4 +1,6 @@
^CMake Error at CMP0069-NEW-compiler\.cmake:[0-9]+ \(add_executable\):
Compiler doesn't support IPO
Call Stack \(most recent call first\):
- CMakeLists\.txt:[0-9]+ \(include\)$
+ CMakeLists\.txt:[0-9]+ \(include\)
++
+CMake Generate step failed\. Build files cannot be regenerated correctly\.$
diff --git a/Tests/RunCMake/CMP0069/CMP0069-NEW-generator-stderr.txt b/Tests/RunCMake/CMP0069/CMP0069-NEW-generator-stderr.txt
index 0e05ee7..1159ec0 100644
--- a/Tests/RunCMake/CMP0069/CMP0069-NEW-generator-stderr.txt
+++ b/Tests/RunCMake/CMP0069/CMP0069-NEW-generator-stderr.txt
@@ -1,4 +1,6 @@
^CMake Error at CMP0069-NEW-generator\.cmake:[0-9]+ \(add_executable\):
CMake doesn't support IPO for current generator
Call Stack \(most recent call first\):
- CMakeLists\.txt:[0-9]+ \(include\)$
+ CMakeLists\.txt:[0-9]+ \(include\)
++
+CMake Generate step failed\. Build files cannot be regenerated correctly\.$
diff --git a/Tests/RunCMake/GeneratorExpression/BadAND-stderr.txt b/Tests/RunCMake/GeneratorExpression/BadAND-stderr.txt
index 0e48ba4..86d3e04 100644
--- a/Tests/RunCMake/GeneratorExpression/BadAND-stderr.txt
+++ b/Tests/RunCMake/GeneratorExpression/BadAND-stderr.txt
@@ -50,4 +50,6 @@ CMake Error at BadAND.cmake:1 \(add_custom_target\):
Parameters to \$<AND> must resolve to either '0' or '1'.
Call Stack \(most recent call first\):
- CMakeLists.txt:3 \(include\)$
+ CMakeLists.txt:3 \(include\)
++
+CMake Generate step failed\. Build files cannot be regenerated correctly\.$
diff --git a/Tests/RunCMake/GeneratorExpression/BadCONFIG-stderr.txt b/Tests/RunCMake/GeneratorExpression/BadCONFIG-stderr.txt
index 964ea4d..42dd0ce 100644
--- a/Tests/RunCMake/GeneratorExpression/BadCONFIG-stderr.txt
+++ b/Tests/RunCMake/GeneratorExpression/BadCONFIG-stderr.txt
@@ -32,4 +32,6 @@ CMake Error at BadCONFIG.cmake:1 \(add_custom_target\):
Expression syntax not recognized.
Call Stack \(most recent call first\):
- CMakeLists.txt:3 \(include\)$
+ CMakeLists.txt:3 \(include\)
++
+CMake Generate step failed\. Build files cannot be regenerated correctly\.$
diff --git a/Tests/RunCMake/GeneratorExpression/BadNOT-stderr.txt b/Tests/RunCMake/GeneratorExpression/BadNOT-stderr.txt
index e5e628c..627327c 100644
--- a/Tests/RunCMake/GeneratorExpression/BadNOT-stderr.txt
+++ b/Tests/RunCMake/GeneratorExpression/BadNOT-stderr.txt
@@ -49,4 +49,6 @@ CMake Error at BadNOT.cmake:1 \(add_custom_target\):
\$<NOT> parameter must resolve to exactly one '0' or '1' value.
Call Stack \(most recent call first\):
- CMakeLists.txt:3 \(include\)$
+ CMakeLists.txt:3 \(include\)
++
+CMake Generate step failed\. Build files cannot be regenerated correctly\.$
diff --git a/Tests/RunCMake/GeneratorExpression/BadOR-stderr.txt b/Tests/RunCMake/GeneratorExpression/BadOR-stderr.txt
index eb26328..56e6af0 100644
--- a/Tests/RunCMake/GeneratorExpression/BadOR-stderr.txt
+++ b/Tests/RunCMake/GeneratorExpression/BadOR-stderr.txt
@@ -50,4 +50,6 @@ CMake Error at BadOR.cmake:1 \(add_custom_target\):
Parameters to \$<OR> must resolve to either '0' or '1'.
Call Stack \(most recent call first\):
- CMakeLists.txt:3 \(include\)$
+ CMakeLists.txt:3 \(include\)
++
+CMake Generate step failed\. Build files cannot be regenerated correctly\.$
diff --git a/Tests/RunCMake/GeneratorExpression/BadStrEqual-stderr.txt b/Tests/RunCMake/GeneratorExpression/BadStrEqual-stderr.txt
index dd0d931..2f04c78 100644
--- a/Tests/RunCMake/GeneratorExpression/BadStrEqual-stderr.txt
+++ b/Tests/RunCMake/GeneratorExpression/BadStrEqual-stderr.txt
@@ -35,4 +35,6 @@ CMake Error at BadStrEqual.cmake:1 \(add_custom_target\):
\$<STREQUAL> expression requires 2 comma separated parameters, but got 3
instead.
Call Stack \(most recent call first\):
- CMakeLists.txt:3 \(include\)$
+ CMakeLists.txt:3 \(include\)
++
+CMake Generate step failed\. Build files cannot be regenerated correctly\.$
diff --git a/Tests/RunCMake/GeneratorExpression/BadTargetName-stderr.txt b/Tests/RunCMake/GeneratorExpression/BadTargetName-stderr.txt
index 969393a..98eed1f 100644
--- a/Tests/RunCMake/GeneratorExpression/BadTargetName-stderr.txt
+++ b/Tests/RunCMake/GeneratorExpression/BadTargetName-stderr.txt
@@ -5,4 +5,6 @@ CMake Error at BadTargetName.cmake:1 \(add_custom_target\):
\$<TARGET_NAME> expression requires literal input.
Call Stack \(most recent call first\):
- CMakeLists.txt:3 \(include\)$
+ CMakeLists.txt:3 \(include\)
++
+CMake Generate step failed\. Build files cannot be regenerated correctly\.$
diff --git a/Tests/RunCMake/MSVCRuntimeLibrary/CMP0091-NEW-stderr.txt b/Tests/RunCMake/MSVCRuntimeLibrary/CMP0091-NEW-stderr.txt
index 803058d..9afa461 100644
--- a/Tests/RunCMake/MSVCRuntimeLibrary/CMP0091-NEW-stderr.txt
+++ b/Tests/RunCMake/MSVCRuntimeLibrary/CMP0091-NEW-stderr.txt
@@ -1,2 +1,4 @@
^CMake Error in CMakeLists.txt:
- MSVC_RUNTIME_LIBRARY value 'BogusValue' not known for this C compiler.$
+ MSVC_RUNTIME_LIBRARY value 'BogusValue' not known for this C compiler.
++
+CMake Generate step failed\. Build files cannot be regenerated correctly\.$
diff --git a/Tests/RunCMake/ObjectLibrary/OwnSources-stderr.txt b/Tests/RunCMake/ObjectLibrary/OwnSources-stderr.txt
index 40d650e..208f3c9 100644
--- a/Tests/RunCMake/ObjectLibrary/OwnSources-stderr.txt
+++ b/Tests/RunCMake/ObjectLibrary/OwnSources-stderr.txt
@@ -2,4 +2,6 @@
The SOURCES of "A" use a generator expression that depends on the SOURCES
themselves.
Call Stack \(most recent call first\):
- CMakeLists.txt:[0-9]+ \(include\)$
+ CMakeLists.txt:[0-9]+ \(include\)
++
+CMake Generate step failed\. Build files cannot be regenerated correctly\.$
diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadInvalidName-stderr.txt b/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadInvalidName-stderr.txt
index fec12ae..6da79b7 100644
--- a/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadInvalidName-stderr.txt
+++ b/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadInvalidName-stderr.txt
@@ -47,4 +47,6 @@
\$<TARGET_PROPERTY:>
\$<TARGET_PROPERTY:...> expression requires a non-empty property name.
-*)+$
+*)+
++
+CMake Generate step failed\. Build files cannot be regenerated correctly\.$
diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadNonTarget-stderr.txt b/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadNonTarget-stderr.txt
index 75865ad..d40b16b 100644
--- a/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadNonTarget-stderr.txt
+++ b/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadNonTarget-stderr.txt
@@ -5,4 +5,6 @@ CMake Error at BadNonTarget.cmake:7 \(include_directories\):
Target "NonExistent" not found.
Call Stack \(most recent call first\):
- CMakeLists\.txt:[0-9]+ \(include\)$
+ CMakeLists\.txt:[0-9]+ \(include\)
++
+CMake Generate step failed\. Build files cannot be regenerated correctly\.$
diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadSelfReference-stderr.txt b/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadSelfReference-stderr.txt
index f0f71ec..fa26861 100644
--- a/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadSelfReference-stderr.txt
+++ b/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadSelfReference-stderr.txt
@@ -34,4 +34,6 @@
\$<TARGET_PROPERTY:BadSelfReference6,COMPILE_DEFINITIONS>
Self reference on target "BadSelfReference6".
-*)+$
+*)+
++
+CMake Generate step failed\. Build files cannot be regenerated correctly\.$
diff --git a/Tests/RunCMake/XcodeProject/PerConfigPerSourceDefinitions-stderr.txt b/Tests/RunCMake/XcodeProject/PerConfigPerSourceDefinitions-stderr.txt
index 46a294d..69c61e6 100644
--- a/Tests/RunCMake/XcodeProject/PerConfigPerSourceDefinitions-stderr.txt
+++ b/Tests/RunCMake/XcodeProject/PerConfigPerSourceDefinitions-stderr.txt
@@ -5,4 +5,6 @@
specified for source:
- .*/Tests/RunCMake/XcodeProject/main.c$
+ .*/Tests/RunCMake/XcodeProject/main.c
++
+CMake Generate step failed\. Build files cannot be regenerated correctly\.$
diff --git a/Tests/RunCMake/XcodeProject/PerConfigPerSourceFlags-stderr.txt b/Tests/RunCMake/XcodeProject/PerConfigPerSourceFlags-stderr.txt
index 6500649..c3e9e31 100644
--- a/Tests/RunCMake/XcodeProject/PerConfigPerSourceFlags-stderr.txt
+++ b/Tests/RunCMake/XcodeProject/PerConfigPerSourceFlags-stderr.txt
@@ -5,4 +5,6 @@
specified for source:
- .*/Tests/RunCMake/XcodeProject/main.c$
+ .*/Tests/RunCMake/XcodeProject/main.c
++
+CMake Generate step failed\. Build files cannot be regenerated correctly\.$
diff --git a/Tests/RunCMake/XcodeProject/PerConfigPerSourceIncludeDirs-stderr.txt b/Tests/RunCMake/XcodeProject/PerConfigPerSourceIncludeDirs-stderr.txt
index f9b8ee7..ff70b95 100644
--- a/Tests/RunCMake/XcodeProject/PerConfigPerSourceIncludeDirs-stderr.txt
+++ b/Tests/RunCMake/XcodeProject/PerConfigPerSourceIncludeDirs-stderr.txt
@@ -5,4 +5,6 @@
specified for source:
- .*/Tests/RunCMake/XcodeProject/main.c$
+ .*/Tests/RunCMake/XcodeProject/main.c
++
+CMake Generate step failed\. Build files cannot be regenerated correctly\.$
diff --git a/Tests/RunCMake/XcodeProject/PerConfigPerSourceOptions-stderr.txt b/Tests/RunCMake/XcodeProject/PerConfigPerSourceOptions-stderr.txt
index bfca020..100008a 100644
--- a/Tests/RunCMake/XcodeProject/PerConfigPerSourceOptions-stderr.txt
+++ b/Tests/RunCMake/XcodeProject/PerConfigPerSourceOptions-stderr.txt
@@ -5,4 +5,6 @@
specified for source:
- .*/Tests/RunCMake/XcodeProject/main.c$
+ .*/Tests/RunCMake/XcodeProject/main.c
++
+CMake Generate step failed\. Build files cannot be regenerated correctly\.$
diff --git a/Tests/RunCMake/XcodeProject/RunCMakeTest.cmake b/Tests/RunCMake/XcodeProject/RunCMakeTest.cmake
index 4918f7c..191f56d 100644
--- a/Tests/RunCMake/XcodeProject/RunCMakeTest.cmake
+++ b/Tests/RunCMake/XcodeProject/RunCMakeTest.cmake
@@ -256,4 +256,19 @@ if(XCODE_VERSION VERSION_GREATER_EQUAL 8)
deployment_target_test(watchOS watchsimulator)
endif()
+if(XCODE_VERSION VERSION_GREATER_EQUAL 8)
+ function(xctest_lookup_test SystemName SDK)
+ set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/XCTestLookup-${SDK}-build)
+ set(RunCMake_TEST_OPTIONS "-DCMAKE_SYSTEM_NAME=${SystemName}" "-DCMAKE_OSX_SYSROOT=${SDK}")
+
+ run_cmake(XCTestLookup)
+ endfunction()
+
+ xctest_lookup_test(Darwin macosx)
+ xctest_lookup_test(iOS iphoneos)
+ xctest_lookup_test(iOS iphonesimulator)
+ xctest_lookup_test(tvOS appletvos)
+ xctest_lookup_test(tvOS appletvsimulator)
+endif()
+
# Please add macOS-only tests above before the device-specific tests.
diff --git a/Tests/RunCMake/XcodeProject/XCTestLookup.cmake b/Tests/RunCMake/XcodeProject/XCTestLookup.cmake
new file mode 100644
index 0000000..77676e5
--- /dev/null
+++ b/Tests/RunCMake/XcodeProject/XCTestLookup.cmake
@@ -0,0 +1,3 @@
+enable_language(C)
+
+find_package(XCTest REQUIRED)
diff --git a/Tests/RunCMake/add_executable/NoSources-stderr.txt b/Tests/RunCMake/add_executable/NoSources-stderr.txt
index 4fcfd49..abefc6d 100644
--- a/Tests/RunCMake/add_executable/NoSources-stderr.txt
+++ b/Tests/RunCMake/add_executable/NoSources-stderr.txt
@@ -1,4 +1,6 @@
^CMake Error at NoSources.cmake:[0-9]+ \(add_executable\):
No SOURCES given to target: TestExeWithoutSources
Call Stack \(most recent call first\):
- CMakeLists.txt:[0-9]+ \(include\)$
+ CMakeLists.txt:[0-9]+ \(include\)
++
+CMake Generate step failed\. Build files cannot be regenerated correctly\.$
diff --git a/Tests/RunCMake/add_executable/NoSourcesButLinkObjects-stderr.txt b/Tests/RunCMake/add_executable/NoSourcesButLinkObjects-stderr.txt
index 5561daa..80026bf 100644
--- a/Tests/RunCMake/add_executable/NoSourcesButLinkObjects-stderr.txt
+++ b/Tests/RunCMake/add_executable/NoSourcesButLinkObjects-stderr.txt
@@ -1,4 +1,6 @@
^CMake Error at NoSourcesButLinkObjects.cmake:[0-9]+ \(add_executable\):
No SOURCES given to target: TestExeWithoutSources
Call Stack \(most recent call first\):
- CMakeLists.txt:[0-9]+ \(include\)$
+ CMakeLists.txt:[0-9]+ \(include\)
++
+CMake Generate step failed\. Build files cannot be regenerated correctly\.$
diff --git a/Tests/RunCMake/add_library/MODULEwithNoSources-stderr.txt b/Tests/RunCMake/add_library/MODULEwithNoSources-stderr.txt
index 41da381..72b92ce 100644
--- a/Tests/RunCMake/add_library/MODULEwithNoSources-stderr.txt
+++ b/Tests/RunCMake/add_library/MODULEwithNoSources-stderr.txt
@@ -1,4 +1,6 @@
^CMake Error at MODULEwithNoSources.cmake:[0-9]+ \(add_library\):
No SOURCES given to target: TestModuleLibWithoutSources
Call Stack \(most recent call first\):
- CMakeLists.txt:[0-9]+ \(include\)$
+ CMakeLists.txt:[0-9]+ \(include\)
++
+CMake Generate step failed\. Build files cannot be regenerated correctly\.$
diff --git a/Tests/RunCMake/add_library/MODULEwithNoSourcesButLinkObjects-stderr.txt b/Tests/RunCMake/add_library/MODULEwithNoSourcesButLinkObjects-stderr.txt
index 67dd87c..1490524 100644
--- a/Tests/RunCMake/add_library/MODULEwithNoSourcesButLinkObjects-stderr.txt
+++ b/Tests/RunCMake/add_library/MODULEwithNoSourcesButLinkObjects-stderr.txt
@@ -1,4 +1,6 @@
^CMake Error at MODULEwithNoSourcesButLinkObjects.cmake:[0-9]+ \(add_library\):
No SOURCES given to target: TestModuleLibWithoutSources
Call Stack \(most recent call first\):
- CMakeLists.txt:[0-9]+ \(include\)$
+ CMakeLists.txt:[0-9]+ \(include\)
++
+CMake Generate step failed\. Build files cannot be regenerated correctly\.$
diff --git a/Tests/RunCMake/add_library/OBJECTwithNoSources-stderr.txt b/Tests/RunCMake/add_library/OBJECTwithNoSources-stderr.txt
index 20d3a8a..be7634c 100644
--- a/Tests/RunCMake/add_library/OBJECTwithNoSources-stderr.txt
+++ b/Tests/RunCMake/add_library/OBJECTwithNoSources-stderr.txt
@@ -1,4 +1,6 @@
^CMake Error at OBJECTwithNoSources.cmake:[0-9]+ \(add_library\):
No SOURCES given to target: TestObjectLibWithoutSources
Call Stack \(most recent call first\):
- CMakeLists.txt:[0-9]+ \(include\)$
+ CMakeLists.txt:[0-9]+ \(include\)
++
+CMake Generate step failed\. Build files cannot be regenerated correctly\.$
diff --git a/Tests/RunCMake/add_library/OBJECTwithNoSourcesButLinkObjects-stderr.txt b/Tests/RunCMake/add_library/OBJECTwithNoSourcesButLinkObjects-stderr.txt
index 1bcc114..3f85916 100644
--- a/Tests/RunCMake/add_library/OBJECTwithNoSourcesButLinkObjects-stderr.txt
+++ b/Tests/RunCMake/add_library/OBJECTwithNoSourcesButLinkObjects-stderr.txt
@@ -1,4 +1,6 @@
^CMake Error at OBJECTwithNoSourcesButLinkObjects.cmake:[0-9]+ \(add_library\):
No SOURCES given to target: TestObjectLibWithoutSources
Call Stack \(most recent call first\):
- CMakeLists.txt:[0-9]+ \(include\)$
+ CMakeLists.txt:[0-9]+ \(include\)
++
+CMake Generate step failed\. Build files cannot be regenerated correctly\.$
diff --git a/Tests/RunCMake/add_library/SHAREDwithNoSources-stderr.txt b/Tests/RunCMake/add_library/SHAREDwithNoSources-stderr.txt
index 5cedd62..471eda1 100644
--- a/Tests/RunCMake/add_library/SHAREDwithNoSources-stderr.txt
+++ b/Tests/RunCMake/add_library/SHAREDwithNoSources-stderr.txt
@@ -1,4 +1,6 @@
^CMake Error at SHAREDwithNoSources.cmake:[0-9]+ \(add_library\):
No SOURCES given to target: TestSharedLibWithoutSources
Call Stack \(most recent call first\):
- CMakeLists.txt:[0-9]+ \(include\)$
+ CMakeLists.txt:[0-9]+ \(include\)
++
+CMake Generate step failed\. Build files cannot be regenerated correctly\.$
diff --git a/Tests/RunCMake/add_library/SHAREDwithNoSourcesButLinkObjects-stderr.txt b/Tests/RunCMake/add_library/SHAREDwithNoSourcesButLinkObjects-stderr.txt
index d621e76..4bec7ae 100644
--- a/Tests/RunCMake/add_library/SHAREDwithNoSourcesButLinkObjects-stderr.txt
+++ b/Tests/RunCMake/add_library/SHAREDwithNoSourcesButLinkObjects-stderr.txt
@@ -1,4 +1,6 @@
^CMake Error at SHAREDwithNoSourcesButLinkObjects.cmake:[0-9]+ \(add_library\):
No SOURCES given to target: TestSharedLibWithoutSources
Call Stack \(most recent call first\):
- CMakeLists.txt:[0-9]+ \(include\)$
+ CMakeLists.txt:[0-9]+ \(include\)
++
+CMake Generate step failed\. Build files cannot be regenerated correctly\.$
diff --git a/Tests/RunCMake/add_library/STATICwithNoSources-stderr.txt b/Tests/RunCMake/add_library/STATICwithNoSources-stderr.txt
index 10b2112..f655221 100644
--- a/Tests/RunCMake/add_library/STATICwithNoSources-stderr.txt
+++ b/Tests/RunCMake/add_library/STATICwithNoSources-stderr.txt
@@ -1,4 +1,6 @@
^CMake Error at STATICwithNoSources.cmake:[0-9]+ \(add_library\):
No SOURCES given to target: TestStaticLibWithoutSources
Call Stack \(most recent call first\):
- CMakeLists.txt:[0-9]+ \(include\)$
+ CMakeLists.txt:[0-9]+ \(include\)
++
+CMake Generate step failed\. Build files cannot be regenerated correctly\.$
diff --git a/Tests/RunCMake/add_library/STATICwithNoSourcesButLinkObjects-stderr.txt b/Tests/RunCMake/add_library/STATICwithNoSourcesButLinkObjects-stderr.txt
index 33c23b2..185aad8 100644
--- a/Tests/RunCMake/add_library/STATICwithNoSourcesButLinkObjects-stderr.txt
+++ b/Tests/RunCMake/add_library/STATICwithNoSourcesButLinkObjects-stderr.txt
@@ -1,4 +1,6 @@
^CMake Error at STATICwithNoSourcesButLinkObjects.cmake:[0-9]+ \(add_library\):
No SOURCES given to target: TestStaticLibWithoutSources
Call Stack \(most recent call first\):
- CMakeLists.txt:[0-9]+ \(include\)$
+ CMakeLists.txt:[0-9]+ \(include\)
++
+CMake Generate step failed\. Build files cannot be regenerated correctly\.$
diff --git a/Utilities/Doxygen/CMakeLists.txt b/Utilities/Doxygen/CMakeLists.txt
index 2cdd767..ce4cfaf 100644
--- a/Utilities/Doxygen/CMakeLists.txt
+++ b/Utilities/Doxygen/CMakeLists.txt
@@ -3,7 +3,7 @@
if(NOT CMake_SOURCE_DIR)
set(CMakeDeveloperReference_STANDALONE 1)
- cmake_minimum_required(VERSION 3.1...3.12 FATAL_ERROR)
+ cmake_minimum_required(VERSION 3.1...3.14 FATAL_ERROR)
get_filename_component(tmp "${CMAKE_CURRENT_SOURCE_DIR}" PATH)
get_filename_component(CMake_SOURCE_DIR "${tmp}" PATH)
include(${CMake_SOURCE_DIR}/Modules/CTestUseLaunchers.cmake)
diff --git a/Utilities/Release/linux64_release.cmake b/Utilities/Release/linux64_release.cmake
index fa585d7..958ed25 100644
--- a/Utilities/Release/linux64_release.cmake
+++ b/Utilities/Release/linux64_release.cmake
@@ -44,6 +44,7 @@ CMake_QT_STATIC_QXcbIntegrationPlugin_LIBRARIES:STRING=${qt_xcb_libs}
set(ENV [[
export CMAKE_PREFIX_PATH=/opt/binutils-2.31
]])
+set(SIGN "")
# Exclude Qt5 tests because our Qt5 is static.
set(EXTRA_CTEST_ARGS "-E Qt5")
diff --git a/Utilities/Release/osx_release.cmake b/Utilities/Release/osx_release.cmake
index be11d47..ac35872 100644
--- a/Utilities/Release/osx_release.cmake
+++ b/Utilities/Release/osx_release.cmake
@@ -29,5 +29,6 @@ CMake_TEST_NO_FindPackageModeMakefileTest:BOOL=TRUE
set(ENV [[
export CMAKE_PREFIX_PATH='/Users/kitware/SDKs/qt-5.6.2-clang-x64'
]])
+set(SIGN "")
get_filename_component(path "${CMAKE_CURRENT_LIST_FILE}" PATH)
include(${path}/release_cmake.cmake)
diff --git a/Utilities/Release/release_cmake.sh.in b/Utilities/Release/release_cmake.sh.in
index f363b3d..696a3f4 100755
--- a/Utilities/Release/release_cmake.sh.in
+++ b/Utilities/Release/release_cmake.sh.in
@@ -150,7 +150,7 @@ for GEN in $generators; do
check_exit_value $? "Create $GEN package" || exit 1
done
-
+@SIGN@
echo "End release"
date
diff --git a/Utilities/Release/win32_release.cmake b/Utilities/Release/win32_release.cmake
index 974c402..468e5f4 100644
--- a/Utilities/Release/win32_release.cmake
+++ b/Utilities/Release/win32_release.cmake
@@ -45,5 +45,9 @@ set(GIT_EXTRA "git config core.autocrlf true")
if(CMAKE_CREATE_VERSION STREQUAL "nightly")
# Some tests fail spuriously too often.
set(EXTRA_CTEST_ARGS "-E 'ConsoleBuf|Module.ExternalData'")
+ set(SIGN "")
+else()
+ string(APPEND INITIAL_CACHE "CMake_INSTALL_SIGNTOOL:STRING=signtool\n")
+ set(SIGN [[signtool sign -v -a -tr http://timestamp.digicert.com -fd sha256 -td sha256 -d "CMake Windows Installer" cmake-*.msi]])
endif()
include(${path}/release_cmake.cmake)
diff --git a/Utilities/Release/win64_release.cmake b/Utilities/Release/win64_release.cmake
index 20529f0..5a93ce6 100644
--- a/Utilities/Release/win64_release.cmake
+++ b/Utilities/Release/win64_release.cmake
@@ -45,5 +45,9 @@ set(GIT_EXTRA "git config core.autocrlf true")
if(CMAKE_CREATE_VERSION STREQUAL "nightly")
# Some tests fail spuriously too often.
set(EXTRA_CTEST_ARGS "-E 'ConsoleBuf|Module.ExternalData'")
+ set(SIGN "")
+else()
+ string(APPEND INITIAL_CACHE "CMake_INSTALL_SIGNTOOL:STRING=signtool\n")
+ set(SIGN [[signtool sign -v -a -tr http://timestamp.digicert.com -fd sha256 -td sha256 -d "CMake Windows Installer" cmake-*.msi]])
endif()
include(${path}/release_cmake.cmake)
diff --git a/Utilities/Sphinx/CMakeLists.txt b/Utilities/Sphinx/CMakeLists.txt
index 15204d6..c5b2bfe 100644
--- a/Utilities/Sphinx/CMakeLists.txt
+++ b/Utilities/Sphinx/CMakeLists.txt
@@ -3,7 +3,7 @@
if(NOT CMake_SOURCE_DIR)
set(CMakeHelp_STANDALONE 1)
- cmake_minimum_required(VERSION 3.1...3.12 FATAL_ERROR)
+ cmake_minimum_required(VERSION 3.1...3.14 FATAL_ERROR)
get_filename_component(tmp "${CMAKE_CURRENT_SOURCE_DIR}" PATH)
get_filename_component(CMake_SOURCE_DIR "${tmp}" PATH)
include(${CMake_SOURCE_DIR}/Modules/CTestUseLaunchers.cmake)
diff --git a/bootstrap b/bootstrap
index 8b9c404..c5274ce 100755
--- a/bootstrap
+++ b/bootstrap
@@ -329,6 +329,7 @@ CMAKE_CXX_SOURCES="\
cmGetCMakePropertyCommand \
cmGetDirectoryPropertyCommand \
cmGetFilenameComponentCommand \
+ cmGetPipes \
cmGetPropertyCommand \
cmGetSourceFilePropertyCommand \
cmGetTargetPropertyCommand \
@@ -427,6 +428,7 @@ CMAKE_CXX_SOURCES="\
cmUnexpectedCommand \
cmUnsetCommand \
cmUVHandlePtr \
+ cmUVProcessChain \
cmVersion \
cmWhileCommand \
cmWorkingDirectory \