summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Help/command/add_custom_command.rst6
-rw-r--r--Help/command/install.rst16
-rw-r--r--Help/manual/cmake-generator-expressions.7.rst42
-rw-r--r--Help/prop_gbl/DEBUG_CONFIGURATIONS.rst7
-rw-r--r--Help/release/dev/CheckIncludeFile-required-libs.rst11
-rw-r--r--Help/release/dev/extend-compile-language-genex.rst15
-rw-r--r--Help/release/dev/iphone-deployment-target.rst2
-rw-r--r--Modules/CheckIncludeFile.cmake3
-rw-r--r--Modules/CheckIncludeFileCXX.cmake3
-rw-r--r--Modules/CheckIncludeFiles.cmake3
-rw-r--r--Modules/Compiler/MSVC-ASM.cmake1
-rw-r--r--Modules/FindBoost.cmake64
-rw-r--r--Modules/FindCUDA.cmake2
-rw-r--r--Modules/FindMPI.cmake60
-rw-r--r--Modules/Platform/AIX-GNU.cmake4
-rw-r--r--Source/CMakeLists.txt1
-rw-r--r--Source/CMakeVersion.cmake2
-rw-r--r--Source/CTest/cmCTestMultiProcessHandler.cxx173
-rw-r--r--Source/CTest/cmCTestMultiProcessHandler.h12
-rw-r--r--Source/CTest/cmCTestRunTest.cxx201
-rw-r--r--Source/CTest/cmCTestRunTest.h30
-rw-r--r--Source/CTest/cmProcess.cxx708
-rw-r--r--Source/CTest/cmProcess.h79
-rw-r--r--Source/CursesDialog/CMakeLists.txt26
-rw-r--r--Source/cmCTest.cxx72
-rw-r--r--Source/cmCTest.h12
-rw-r--r--Source/cmGeneratorExpressionNode.cxx37
-rw-r--r--Source/cmGlobalXCodeGenerator.cxx12
-rw-r--r--Source/cmLocalVisualStudio7Generator.cxx43
-rw-r--r--Source/cmMakefile.cxx31
-rw-r--r--Source/cmMakefile.h15
-rw-r--r--Source/cmQtAutoGeneratorInitializer.cxx21
-rw-r--r--Source/cmSourceFile.cxx5
-rw-r--r--Source/cmSourceFile.h5
-rw-r--r--Source/cmSourceFileLocation.cxx10
-rw-r--r--Source/cmSourceFileLocation.h6
-rw-r--r--Source/cmSourceFileLocationKind.h15
-rw-r--r--Source/cmTarget.cxx7
-rw-r--r--Source/cmVisualStudio10TargetGenerator.cxx73
-rw-r--r--Source/cmVisualStudio10TargetGenerator.h22
-rw-r--r--Source/cmVisualStudioGeneratorOptions.cxx28
-rw-r--r--Tests/CMakeCommands/target_compile_definitions/CMakeLists.txt22
-rw-r--r--Tests/CMakeCommands/target_compile_definitions/consumer.c20
-rw-r--r--Tests/CMakeCommands/target_compile_definitions/consumer.cpp2
-rw-r--r--Tests/CMakeCommands/target_include_directories/CMakeLists.txt20
-rw-r--r--Tests/CMakeCommands/target_include_directories/consumer.c10
-rw-r--r--Tests/CMakeCommands/target_include_directories/consumer.cpp6
-rw-r--r--Tests/CMakeLib/CMakeLists.txt21
-rw-r--r--Tests/CMakeServerLib/CMakeLists.txt5
-rw-r--r--Tests/CudaOnly/CMakeLists.txt3
-rw-r--r--Tests/CudaOnly/GPUDebugFlag/CMakeLists.txt23
-rw-r--r--Tests/CudaOnly/GPUDebugFlag/main.cu66
-rw-r--r--Tests/CudaOnly/ResolveDeviceSymbols/CMakeLists.txt2
-rw-r--r--Tests/CudaOnly/SeparateCompilation/CMakeLists.txt3
-rw-r--r--Tests/CudaOnly/WithDefs/CMakeLists.txt11
-rw-r--r--Tests/CudaOnly/WithDefs/inc_cuda/inc_cuda.h1
-rw-r--r--Tests/CudaOnly/WithDefs/main.notcu29
-rw-r--r--Tests/FindOpenSSL/rand/main.cc2
-rw-r--r--Tests/GeneratorExpression/CMakeLists.txt6
-rw-r--r--Tests/RunCMake/CMakeLists.txt2
-rw-r--r--Tests/RunCMake/COMPILE_LANGUAGE-genex/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileDefinitions-result.txt1
-rw-r--r--Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileDefinitions-stderr-VS.txt9
-rw-r--r--Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileDefinitions-stderr-Xcode.txt9
-rw-r--r--Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileDefinitions.cmake5
-rw-r--r--Tests/RunCMake/COMPILE_LANGUAGE-genex/IncludeDirectories-result.txt1
-rw-r--r--Tests/RunCMake/COMPILE_LANGUAGE-genex/IncludeDirectories-stderr-VS.txt9
-rw-r--r--Tests/RunCMake/COMPILE_LANGUAGE-genex/IncludeDirectories-stderr-Xcode.txt9
-rw-r--r--Tests/RunCMake/COMPILE_LANGUAGE-genex/IncludeDirectories.cmake5
-rw-r--r--Tests/RunCMake/COMPILE_LANGUAGE-genex/PerSourceCompileDefinitions-result.txt1
-rw-r--r--Tests/RunCMake/COMPILE_LANGUAGE-genex/PerSourceCompileDefinitions-stderr-VS.txt7
-rw-r--r--Tests/RunCMake/COMPILE_LANGUAGE-genex/PerSourceCompileDefinitions-stderr-Xcode.txt7
-rw-r--r--Tests/RunCMake/COMPILE_LANGUAGE-genex/PerSourceCompileDefinitions.cmake5
-rw-r--r--Tests/RunCMake/COMPILE_LANGUAGE-genex/RunCMakeTest.cmake23
-rw-r--r--Tests/RunCMake/COMPILE_LANGUAGE-genex/main.cpp5
-rw-r--r--Tests/RunCMake/GenerateExportHeader/GEH.cmake11
-rw-r--r--Tests/RunCMake/GenerateExportHeader/libshared/CMakeLists.txt2
-rw-r--r--Tests/RunCMake/GenerateExportHeader/libstatic/CMakeLists.txt2
-rw-r--r--Utilities/cmlibuv/src/unix/signal.c7
79 files changed, 1488 insertions, 772 deletions
diff --git a/Help/command/add_custom_command.rst b/Help/command/add_custom_command.rst
index 1b0aa14..d4f644a 100644
--- a/Help/command/add_custom_command.rst
+++ b/Help/command/add_custom_command.rst
@@ -146,8 +146,10 @@ The options are:
Specify the primary input source file to the command. This is
treated just like any value given to the ``DEPENDS`` option
but also suggests to Visual Studio generators where to hang
- the custom command. At most one custom command may specify a
- given source file as its main dependency.
+ the custom command. Each source file may have at most one command
+ specifying it as its main dependency. A compile command (i.e. for a
+ library or an executable) counts as an implicit main dependency which
+ gets silently overwritten by a custom command specification.
``OUTPUT``
Specify the output files the command is expected to produce.
diff --git a/Help/command/install.rst b/Help/command/install.rst
index f43b2a0..2506f98 100644
--- a/Help/command/install.rst
+++ b/Help/command/install.rst
@@ -38,7 +38,21 @@ signatures that specify them. The common options are:
``CONFIGURATIONS``
Specify a list of build configurations for which the install rule
- applies (Debug, Release, etc.).
+ applies (Debug, Release, etc.). Note that the values specified for
+ this option only apply to options listed AFTER the ``CONFIGURATIONS``
+ option. For example, to set separate install paths for the Debug and
+ Release configurations, do the following:
+
+ .. code-block:: cmake
+
+ install(TARGETS target
+ CONFIGURATIONS Debug
+ RUNTIME DESTINATION Debug/bin)
+ install(TARGETS target
+ CONFIGURATIONS Release
+ RUNTIME DESTINATION Release/bin)
+
+ Note that ``CONFIGURATIONS`` appears BEFORE ``RUNTIME DESTINATION``.
``COMPONENT``
Specify an installation component name with which the install rule
diff --git a/Help/manual/cmake-generator-expressions.7.rst b/Help/manual/cmake-generator-expressions.7.rst
index dc5621a..0f6d4cf 100644
--- a/Help/manual/cmake-generator-expressions.7.rst
+++ b/Help/manual/cmake-generator-expressions.7.rst
@@ -97,21 +97,35 @@ Available logical expressions are:
compile features and a list of supported compilers.
``$<COMPILE_LANGUAGE:lang>``
``1`` when the language used for compilation unit matches ``lang``,
- otherwise ``0``. This expression may be used to specify compile options for
- source files of a particular language in a target. For example, to specify
- the use of the ``-fno-exceptions`` compile option (compiler id checks
- elided):
+ otherwise ``0``. This expression may be used to specify compile options,
+ compile definitions, and include directories for source files of a
+ particular language in a target. For example:
.. code-block:: cmake
- add_executable(myapp main.cpp foo.c bar.cpp)
+ add_executable(myapp main.cpp foo.c bar.cpp zot.cu)
target_compile_options(myapp
PRIVATE $<$<COMPILE_LANGUAGE:CXX>:-fno-exceptions>
)
+ target_compile_definitions(myapp
+ PRIVATE $<$<COMPILE_LANGUAGE:CXX>:COMPILING_CXX>
+ $<$<COMPILE_LANGUAGE:CUDA>:COMPILING_CUDA>
+ )
+ target_include_directories(myapp
+ PRIVATE $<$<COMPILE_LANGUAGE:CXX>:/opt/foo/cxx_headers>
+ )
+
+ This specifies the use of the ``-fno-exceptions`` compile option,
+ ``COMPILING_CXX`` compile definition, and ``cxx_headers`` include
+ directory for C++ only (compiler id checks elided). It also specifies
+ a ``COMPILING_CUDA`` compile definition for CUDA.
- Note that with :ref:`Visual Studio Generators` there is no way to represent
+ Note that with :ref:`Visual Studio Generators` and :generator:`Xcode` there
+ is no way to represent target-wide compile definitions or include directories
+ separately for ``C`` and ``CXX`` languages.
+ Also, with :ref:`Visual Studio Generators` there is no way to represent
target-wide flags separately for ``C`` and ``CXX`` languages. Under these
- generators, target-wide flags for both C and C++ sources will be evaluated
+ generators, expressions for both C and C++ sources will be evaluated
using ``CXX`` if there are any C++ sources and otherwise using ``C``.
A workaround is to create separate libraries for each source file language
instead:
@@ -124,20 +138,6 @@ Available logical expressions are:
add_executable(myapp main.cpp)
target_link_libraries(myapp myapp_c myapp_cxx)
- The ``Makefile`` and ``Ninja`` based generators can also use this
- expression to specify compile-language specific compile definitions
- and include directories:
-
- .. code-block:: cmake
-
- add_executable(myapp main.cpp foo.c bar.cpp)
- target_compile_definitions(myapp
- PRIVATE $<$<COMPILE_LANGUAGE:CXX>:COMPILING_CXX>
- )
- target_include_directories(myapp
- PRIVATE $<$<COMPILE_LANGUAGE:CXX>:/opt/foo/cxx_headers>
- )
-
Informational Expressions
=========================
diff --git a/Help/prop_gbl/DEBUG_CONFIGURATIONS.rst b/Help/prop_gbl/DEBUG_CONFIGURATIONS.rst
index 690143f..fec6fda 100644
--- a/Help/prop_gbl/DEBUG_CONFIGURATIONS.rst
+++ b/Help/prop_gbl/DEBUG_CONFIGURATIONS.rst
@@ -4,11 +4,10 @@ DEBUG_CONFIGURATIONS
Specify which configurations are for debugging.
The value must be a semi-colon separated list of configuration names.
-Currently this property is used only by the target_link_libraries
-command (see its documentation for details). Additional uses may be
-defined in the future.
+Currently this property is used only by the :command:`target_link_libraries`
+command. Additional uses may be defined in the future.
This property must be set at the top level of the project and before
-the first target_link_libraries command invocation. If any entry in
+the first :command:`target_link_libraries` command invocation. If any entry in
the list does not match a valid configuration for the project the
behavior is undefined.
diff --git a/Help/release/dev/CheckIncludeFile-required-libs.rst b/Help/release/dev/CheckIncludeFile-required-libs.rst
new file mode 100644
index 0000000..14c43d1
--- /dev/null
+++ b/Help/release/dev/CheckIncludeFile-required-libs.rst
@@ -0,0 +1,11 @@
+CheckIncludeFile-required-libs
+------------------------------
+
+* The :module:`CheckIncludeFile` module ``check_include_file`` macro
+ learned to honor the ``CMAKE_REQUIRED_LIBRARIES`` variable.
+
+* The :module:`CheckIncludeFileCXX` module ``check_include_file_cxx`` macro
+ learned to honor the ``CMAKE_REQUIRED_LIBRARIES`` variable.
+
+* The :module:`CheckIncludeFiles` module ``check_include_files`` macro
+ learned to honor the ``CMAKE_REQUIRED_LIBRARIES`` variable.
diff --git a/Help/release/dev/extend-compile-language-genex.rst b/Help/release/dev/extend-compile-language-genex.rst
index 0a0a669..7c09376 100644
--- a/Help/release/dev/extend-compile-language-genex.rst
+++ b/Help/release/dev/extend-compile-language-genex.rst
@@ -1,7 +1,14 @@
extend-compile-language-genex
-----------------------------
-* The ``COMPILE_LANGUAGE`` :manual:`generator expression
- <cmake-generator-expressions(7)>` may now be used with
- :ref:`Visual Studio Generators` in :prop_tgt:`COMPILE_OPTIONS`
- and :command:`file(GENERATE)`.
+* :ref:`Visual Studio Generators` learned to support the ``COMPILE_LANGUAGE``
+ :manual:`generator expression <cmake-generator-expressions(7)>` in
+ target-wide :prop_tgt:`COMPILE_DEFINITIONS`,
+ :prop_tgt:`INCLUDE_DIRECTORIES`, :prop_tgt:`COMPILE_OPTIONS`, and
+ :command:`file(GENERATE)`.
+
+* The :generator:`Xcode` generator learned to support the ``COMPILE_LANGUAGE``
+ :manual:`generator expression <cmake-generator-expressions(7)>` in
+ target-wide :prop_tgt:`COMPILE_DEFINITIONS` and
+ :prop_tgt:`INCLUDE_DIRECTORIES`. It previously supported only
+ :prop_tgt:`COMPILE_OPTIONS` and :command:`file(GENERATE)`.
diff --git a/Help/release/dev/iphone-deployment-target.rst b/Help/release/dev/iphone-deployment-target.rst
index e586df6..7a20a6d 100644
--- a/Help/release/dev/iphone-deployment-target.rst
+++ b/Help/release/dev/iphone-deployment-target.rst
@@ -7,5 +7,5 @@ iphone-deployment-target
set for the target platform selected by :variable:`CMAKE_OSX_SYSROOT`.
If for example the sysroot variable specifies an iOS SDK then the
- value in ``CMAKE_OSX_DEPLOYMENT_TARGET`` is interpreted as minium
+ value in ``CMAKE_OSX_DEPLOYMENT_TARGET`` is interpreted as minimum
iOS version.
diff --git a/Modules/CheckIncludeFile.cmake b/Modules/CheckIncludeFile.cmake
index e5554c4..501fc9a 100644
--- a/Modules/CheckIncludeFile.cmake
+++ b/Modules/CheckIncludeFile.cmake
@@ -27,6 +27,8 @@
# list of macros to define (-DFOO=bar)
# ``CMAKE_REQUIRED_INCLUDES``
# list of include directories
+# ``CMAKE_REQUIRED_LIBRARIES``
+# list of libraries to link
# ``CMAKE_REQUIRED_QUIET``
# execute quietly without messages
#
@@ -59,6 +61,7 @@ macro(CHECK_INCLUDE_FILE INCLUDE VARIABLE)
${CMAKE_BINARY_DIR}
${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckIncludeFile.c
COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS}
+ LINK_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES}
CMAKE_FLAGS
-DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_INCLUDE_FILE_FLAGS}
"${CHECK_INCLUDE_FILE_C_INCLUDE_DIRS}"
diff --git a/Modules/CheckIncludeFileCXX.cmake b/Modules/CheckIncludeFileCXX.cmake
index 7948bab..cdb25fb 100644
--- a/Modules/CheckIncludeFileCXX.cmake
+++ b/Modules/CheckIncludeFileCXX.cmake
@@ -27,6 +27,8 @@
# list of macros to define (-DFOO=bar)
# ``CMAKE_REQUIRED_INCLUDES``
# list of include directories
+# ``CMAKE_REQUIRED_LIBRARIES``
+# list of libraries to link
# ``CMAKE_REQUIRED_QUIET``
# execute quietly without messages
#
@@ -58,6 +60,7 @@ macro(CHECK_INCLUDE_FILE_CXX INCLUDE VARIABLE)
${CMAKE_BINARY_DIR}
${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckIncludeFile.cxx
COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS}
+ LINK_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES}
CMAKE_FLAGS
-DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_INCLUDE_FILE_FLAGS}
"${CHECK_INCLUDE_FILE_CXX_INCLUDE_DIRS}"
diff --git a/Modules/CheckIncludeFiles.cmake b/Modules/CheckIncludeFiles.cmake
index 59afdab..14db68c 100644
--- a/Modules/CheckIncludeFiles.cmake
+++ b/Modules/CheckIncludeFiles.cmake
@@ -33,6 +33,8 @@
# list of macros to define (-DFOO=bar)
# ``CMAKE_REQUIRED_INCLUDES``
# list of include directories
+# ``CMAKE_REQUIRED_LIBRARIES``
+# list of libraries to link
# ``CMAKE_REQUIRED_QUIET``
# execute quietly without messages
#
@@ -102,6 +104,7 @@ macro(CHECK_INCLUDE_FILES INCLUDE VARIABLE)
${CMAKE_BINARY_DIR}
${src}
COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS}
+ LINK_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES}
CMAKE_FLAGS
-DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_INCLUDE_FILES_FLAGS}
"${CHECK_INCLUDE_FILES_INCLUDE_DIRS}"
diff --git a/Modules/Compiler/MSVC-ASM.cmake b/Modules/Compiler/MSVC-ASM.cmake
new file mode 100644
index 0000000..45978c5
--- /dev/null
+++ b/Modules/Compiler/MSVC-ASM.cmake
@@ -0,0 +1 @@
+# This file is loaded when Visual Studio is used for the ASM language.
diff --git a/Modules/FindBoost.cmake b/Modules/FindBoost.cmake
index a0fd90f..ca2a9c5 100644
--- a/Modules/FindBoost.cmake
+++ b/Modules/FindBoost.cmake
@@ -791,9 +791,8 @@ function(_Boost_COMPONENT_DEPENDENCIES component _ret)
set(_Boost_WAVE_DEPENDENCIES filesystem system serialization thread chrono date_time atomic)
set(_Boost_WSERIALIZATION_DEPENDENCIES serialization)
endif()
- if(NOT Boost_VERSION VERSION_LESS 106600)
+ if(NOT Boost_VERSION VERSION_LESS 106700)
message(WARNING "New Boost version may have incorrect or missing dependencies and imported targets")
- set(_Boost_IMPORTED_TARGETS FALSE)
endif()
endif()
@@ -825,8 +824,8 @@ function(_Boost_COMPONENT_HEADERS component _hdrs)
set(_Boost_CONTAINER_HEADERS "boost/container/container_fwd.hpp")
set(_Boost_CONTEXT_HEADERS "boost/context/all.hpp")
set(_Boost_COROUTINE_HEADERS "boost/coroutine/all.hpp")
- set(_Boost_EXCEPTION_HEADERS "boost/exception/exception.hpp")
set(_Boost_DATE_TIME_HEADERS "boost/date_time/date.hpp")
+ set(_Boost_EXCEPTION_HEADERS "boost/exception/exception.hpp")
set(_Boost_FIBER_HEADERS "boost/fiber/all.hpp")
set(_Boost_FILESYSTEM_HEADERS "boost/filesystem/path.hpp")
set(_Boost_GRAPH_HEADERS "boost/graph/adjacency_list.hpp")
@@ -925,8 +924,8 @@ endfunction()
# `${Boost_ROOT}/libs/fiber/build/Jamfile.v2`.
#
function(_Boost_COMPILER_FEATURES component _ret)
- # Boost >= 1.62 and < 1.65
- if(NOT Boost_VERSION VERSION_LESS 106200 AND Boost_VERSION VERSION_LESS 106500)
+ # Boost >= 1.62 and < 1.67
+ if(NOT Boost_VERSION VERSION_LESS 106200 AND Boost_VERSION VERSION_LESS 106700)
set(_Boost_FIBER_COMPILER_FEATURES
cxx_alias_templates
cxx_auto_type
@@ -1032,7 +1031,7 @@ else()
# _Boost_COMPONENT_HEADERS. See the instructions at the top of
# _Boost_COMPONENT_DEPENDENCIES.
set(_Boost_KNOWN_VERSIONS ${Boost_ADDITIONAL_VERSIONS}
- "1.65.1" "1.65.0" "1.65"
+ "1.66.0" "1.66" "1.65.1" "1.65.0" "1.65"
"1.64.0" "1.64" "1.63.0" "1.63" "1.62.0" "1.62" "1.61.0" "1.61" "1.60.0" "1.60"
"1.59.0" "1.59" "1.58.0" "1.58" "1.57.0" "1.57" "1.56.0" "1.56" "1.55.0" "1.55"
"1.54.0" "1.54" "1.53.0" "1.53" "1.52.0" "1.52" "1.51.0" "1.51"
@@ -1379,8 +1378,11 @@ if(Boost_DEBUG)
endif()
#======================
-# Systematically build up the Boost ABI tag
-# http://boost.org/doc/libs/1_41_0/more/getting_started/windows.html#library-naming
+# Systematically build up the Boost ABI tag for the 'tagged' and 'versioned' layouts
+# http://boost.org/doc/libs/1_66_0/more/getting_started/windows.html#library-naming
+# http://boost.org/doc/libs/1_66_0/boost/config/auto_link.hpp
+# http://boost.org/doc/libs/1_66_0/tools/build/src/tools/common.jam
+# http://boost.org/doc/libs/1_66_0/boostcpp.jam
set( _boost_RELEASE_ABI_TAG "-")
set( _boost_DEBUG_ABI_TAG "-")
# Key Use this library when:
@@ -1412,11 +1414,40 @@ if(Boost_USE_STLPORT)
string(APPEND _boost_DEBUG_ABI_TAG "p")
endif()
# n using the STLport deprecated "native iostreams" feature
+# removed from the documentation in 1.43.0 but still present in
+# boost/config/auto_link.hpp
if(Boost_USE_STLPORT_DEPRECATED_NATIVE_IOSTREAMS)
string(APPEND _boost_RELEASE_ABI_TAG "n")
string(APPEND _boost_DEBUG_ABI_TAG "n")
endif()
+# -x86 Architecture and address model tag
+# First character is the architecture, then word-size, either 32 or 64
+# Only used in 'versioned' layout, added in Boost 1.66.0
+set(_boost_ARCHITECTURE_TAG "")
+# {CMAKE_CXX_COMPILER_ARCHITECTURE_ID} is not currently set for all compilers
+if(NOT "x${CMAKE_CXX_COMPILER_ARCHITECTURE_ID}" STREQUAL "x" AND NOT Boost_VERSION VERSION_LESS 106600)
+ string(APPEND _boost_ARCHITECTURE_TAG "-")
+ # This needs to be kept in-sync with the section of CMakePlatformId.h.in
+ # inside 'defined(_WIN32) && defined(_MSC_VER)'
+ if(${CMAKE_CXX_COMPILER_ARCHITECTURE_ID} STREQUAL "IA64")
+ string(APPEND _boost_ARCHITECTURE_TAG "i")
+ elseif(${CMAKE_CXX_COMPILER_ARCHITECTURE_ID} STREQUAL "X86"
+ OR ${CMAKE_CXX_COMPILER_ARCHITECTURE_ID} STREQUAL "x64")
+ string(APPEND _boost_ARCHITECTURE_TAG "x")
+ elseif(${CMAKE_CXX_COMPILER_ARCHITECTURE_ID} MATCHES "^ARM")
+ string(APPEND _boost_ARCHITECTURE_TAG "a")
+ elseif(${CMAKE_CXX_COMPILER_ARCHITECTURE_ID} STREQUAL "MIPS")
+ string(APPEND _boost_ARCHITECTURE_TAG "m")
+ endif()
+
+ if(CMAKE_SIZEOF_VOID_P EQUAL 8)
+ string(APPEND _boost_ARCHITECTURE_TAG "64")
+ else()
+ string(APPEND _boost_ARCHITECTURE_TAG "32")
+ endif()
+endif()
+
if(Boost_DEBUG)
message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
"_boost_RELEASE_ABI_TAG = ${_boost_RELEASE_ABI_TAG}")
@@ -1464,6 +1495,7 @@ foreach(c DEBUG RELEASE)
${Boost_INCLUDE_DIR}/stage/lib
)
_Boost_UPDATE_WINDOWS_LIBRARY_SEARCH_DIRS_WITH_PREBUILT_PATHS(_boost_LIBRARY_SEARCH_DIRS_${c} "${Boost_INCLUDE_DIR}/..")
+ _Boost_UPDATE_WINDOWS_LIBRARY_SEARCH_DIRS_WITH_PREBUILT_PATHS(_boost_LIBRARY_SEARCH_DIRS_${c} "${Boost_INCLUDE_DIR}")
if( Boost_NO_SYSTEM_PATHS )
list(APPEND _boost_LIBRARY_SEARCH_DIRS_${c} NO_CMAKE_SYSTEM_PATH NO_SYSTEM_ENVIRONMENT_PATH)
else()
@@ -1610,22 +1642,22 @@ foreach(COMPONENT ${Boost_FIND_COMPONENTS})
unset(_boost_RELEASE_NAMES)
foreach(compiler IN LISTS _boost_COMPILER)
list(APPEND _boost_RELEASE_NAMES
- ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${COMPONENT}${compiler}${_boost_MULTITHREADED}${_boost_RELEASE_ABI_TAG}-${Boost_LIB_VERSION}
+ ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${COMPONENT}${compiler}${_boost_MULTITHREADED}${_boost_RELEASE_ABI_TAG}${_boost_ARCHITECTURE_TAG}-${Boost_LIB_VERSION}
${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${COMPONENT}${compiler}${_boost_MULTITHREADED}${_boost_RELEASE_ABI_TAG} )
endforeach()
list(APPEND _boost_RELEASE_NAMES
- ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${COMPONENT}${_boost_MULTITHREADED}${_boost_RELEASE_ABI_TAG}-${Boost_LIB_VERSION}
+ ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${COMPONENT}${_boost_MULTITHREADED}${_boost_RELEASE_ABI_TAG}${_boost_ARCHITECTURE_TAG}-${Boost_LIB_VERSION}
${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${COMPONENT}${_boost_MULTITHREADED}${_boost_RELEASE_ABI_TAG}
${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${COMPONENT} )
if(_boost_STATIC_RUNTIME_WORKAROUND)
set(_boost_RELEASE_STATIC_ABI_TAG "-s${_boost_RELEASE_ABI_TAG}")
foreach(compiler IN LISTS _boost_COMPILER)
list(APPEND _boost_RELEASE_NAMES
- ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${COMPONENT}${compiler}${_boost_MULTITHREADED}${_boost_RELEASE_STATIC_ABI_TAG}-${Boost_LIB_VERSION}
+ ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${COMPONENT}${compiler}${_boost_MULTITHREADED}${_boost_RELEASE_STATIC_ABI_TAG}${_boost_ARCHITECTURE_TAG}-${Boost_LIB_VERSION}
${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${COMPONENT}${compiler}${_boost_MULTITHREADED}${_boost_RELEASE_STATIC_ABI_TAG} )
endforeach()
list(APPEND _boost_RELEASE_NAMES
- ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${COMPONENT}${_boost_MULTITHREADED}${_boost_RELEASE_STATIC_ABI_TAG}-${Boost_LIB_VERSION}
+ ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${COMPONENT}${_boost_MULTITHREADED}${_boost_RELEASE_STATIC_ABI_TAG}${_boost_ARCHITECTURE_TAG}-${Boost_LIB_VERSION}
${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${COMPONENT}${_boost_MULTITHREADED}${_boost_RELEASE_STATIC_ABI_TAG} )
endif()
if(Boost_THREADAPI AND ${COMPONENT} STREQUAL "thread")
@@ -1660,11 +1692,11 @@ foreach(COMPONENT ${Boost_FIND_COMPONENTS})
unset(_boost_DEBUG_NAMES)
foreach(compiler IN LISTS _boost_COMPILER)
list(APPEND _boost_DEBUG_NAMES
- ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${COMPONENT}${compiler}${_boost_MULTITHREADED}${_boost_DEBUG_ABI_TAG}-${Boost_LIB_VERSION}
+ ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${COMPONENT}${compiler}${_boost_MULTITHREADED}${_boost_DEBUG_ABI_TAG}${_boost_ARCHITECTURE_TAG}-${Boost_LIB_VERSION}
${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${COMPONENT}${compiler}${_boost_MULTITHREADED}${_boost_DEBUG_ABI_TAG} )
endforeach()
list(APPEND _boost_DEBUG_NAMES
- ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${COMPONENT}${_boost_MULTITHREADED}${_boost_DEBUG_ABI_TAG}-${Boost_LIB_VERSION}
+ ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${COMPONENT}${_boost_MULTITHREADED}${_boost_DEBUG_ABI_TAG}${_boost_ARCHITECTURE_TAG}-${Boost_LIB_VERSION}
${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${COMPONENT}${_boost_MULTITHREADED}${_boost_DEBUG_ABI_TAG}
${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${COMPONENT}${_boost_MULTITHREADED}
${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${COMPONENT} )
@@ -1672,11 +1704,11 @@ foreach(COMPONENT ${Boost_FIND_COMPONENTS})
set(_boost_DEBUG_STATIC_ABI_TAG "-s${_boost_DEBUG_ABI_TAG}")
foreach(compiler IN LISTS _boost_COMPILER)
list(APPEND _boost_DEBUG_NAMES
- ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${COMPONENT}${compiler}${_boost_MULTITHREADED}${_boost_DEBUG_STATIC_ABI_TAG}-${Boost_LIB_VERSION}
+ ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${COMPONENT}${compiler}${_boost_MULTITHREADED}${_boost_DEBUG_STATIC_ABI_TAG}${_boost_ARCHITECTURE_TAG}-${Boost_LIB_VERSION}
${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${COMPONENT}${compiler}${_boost_MULTITHREADED}${_boost_DEBUG_STATIC_ABI_TAG} )
endforeach()
list(APPEND _boost_DEBUG_NAMES
- ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${COMPONENT}${_boost_MULTITHREADED}${_boost_DEBUG_STATIC_ABI_TAG}-${Boost_LIB_VERSION}
+ ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${COMPONENT}${_boost_MULTITHREADED}${_boost_DEBUG_STATIC_ABI_TAG}${_boost_ARCHITECTURE_TAG}-${Boost_LIB_VERSION}
${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${COMPONENT}${_boost_MULTITHREADED}${_boost_DEBUG_STATIC_ABI_TAG} )
endif()
if(Boost_THREADAPI AND ${COMPONENT} STREQUAL "thread")
diff --git a/Modules/FindCUDA.cmake b/Modules/FindCUDA.cmake
index 321121c..0decbb5 100644
--- a/Modules/FindCUDA.cmake
+++ b/Modules/FindCUDA.cmake
@@ -104,7 +104,7 @@
# CUDA_NVCC_FLAGS_<CONFIG> variables. For Visual Studio targets,
# the host compiler is constructed with one or more visual studio macros
# such as $(VCInstallDir), that expands out to the path when
-# the command is run from withing VS.
+# the command is run from within VS.
#
# CUDA_NVCC_FLAGS
# CUDA_NVCC_FLAGS_<CONFIG>
diff --git a/Modules/FindMPI.cmake b/Modules/FindMPI.cmake
index db14a89..c5eabbb 100644
--- a/Modules/FindMPI.cmake
+++ b/Modules/FindMPI.cmake
@@ -744,13 +744,22 @@ function(_MPI_guess_settings LANG)
endif()
mark_as_advanced(MPI_${LANG}_LIB_NAMES)
set(MPI_GUESS_FOUND TRUE)
+
+ if(_MPIEXEC_NOT_GIVEN)
+ unset(MPIEXEC_EXECUTABLE CACHE)
+ endif()
+
+ find_program(MPIEXEC_EXECUTABLE
+ NAMES mpiexec
+ HINTS $ENV{MSMPI_BIN} "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\MPI;InstallRoot]/Bin"
+ DOC "Executable for running MPI programs.")
endif()
endif()
# At this point there's not many MPIs that we could still consider.
# OpenMPI 1.6.x and below supported Windows, but these ship compiler wrappers that still work.
# The only other relevant MPI implementation without a wrapper is MPICH2, which had Windows support in 1.4.1p1 and older.
- if(NOT MPI_GUESS_LIBRARY_NAME OR "${MPI_GUESS_LIBRARY_NAME}" STREQUAL "MPICH2")
+ if(NOT MPI_GUESS_FOUND AND (NOT MPI_GUESS_LIBRARY_NAME OR "${MPI_GUESS_LIBRARY_NAME}" STREQUAL "MPICH2"))
set(MPI_MPICH_PREFIX_PATHS
"$ENV{ProgramW6432}/MPICH2/lib"
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\MPICH\\SMPD;binary]/../lib"
@@ -809,6 +818,17 @@ function(_MPI_guess_settings LANG)
unset(MPI_MPICH_ROOT_DIR)
endif()
set(MPI_GUESS_FOUND TRUE)
+
+ if(_MPIEXEC_NOT_GIVEN)
+ unset(MPIEXEC_EXECUTABLE CACHE)
+ endif()
+
+ find_program(MPIEXEC_EXECUTABLE
+ NAMES ${_MPIEXEC_NAMES}
+ HINTS "$ENV{ProgramW6432}/MPICH2/bin"
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MPICH\\SMPD;binary]"
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MPICH2;Path]/bin"
+ DOC "Executable for running MPI programs.")
endif()
unset(MPI_MPICH_PREFIX_PATHS)
endif()
@@ -1034,9 +1054,6 @@ if("${CMAKE_HOST_SYSTEM_NAME}" STREQUAL "Linux")
# SUSE Linux Enterprise Server stores its MPI implementations under /usr/lib64/mpi/gcc/<name>
# We enumerate the subfolders and append each as a prefix
MPI_search_mpi_prefix_folder("/usr/lib64/mpi/gcc")
-elseif("${CMAKE_HOST_SYSTEM_NAME}" STREQUAL "Windows")
- # MSMPI stores its runtime in a special folder, this adds the possible locations to the hints.
- list(APPEND MPI_HINT_DIRS $ENV{MSMPI_BIN} "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\MPI;InstallRoot]")
elseif("${CMAKE_HOST_SYSTEM_NAME}" STREQUAL "FreeBSD")
# FreeBSD ships mpich under the normal system paths - but available openmpi implementations
# will be found in /usr/local/mpi/<name>
@@ -1046,6 +1063,15 @@ endif()
# Most MPI distributions have some form of mpiexec or mpirun which gives us something we can look for.
# The MPI standard does not mandate the existence of either, but instead only makes requirements if a distribution
# ships an mpiexec program (mpirun executables are not regulated by the standard).
+
+# We defer searching for mpiexec binaries belonging to guesses until later. By doing so, mismatches between mpiexec
+# and the MPI we found should be reduced.
+if(NOT MPIEXEC_EXECUTABLE)
+ set(_MPIEXEC_NOT_GIVEN TRUE)
+else()
+ set(_MPIEXEC_NOT_GIVEN FALSE)
+endif()
+
find_program(MPIEXEC_EXECUTABLE
NAMES ${_MPIEXEC_NAMES}
PATH_SUFFIXES bin sbin
@@ -1233,17 +1259,21 @@ foreach(LANG IN ITEMS C CXX Fortran)
endif()
endif()
- if(NOT MPI_SKIP_GUESSING AND NOT MPI_${LANG}_WRAPPER_FOUND AND NOT MPI_PINNED_COMPILER)
- # For C++, we may use the settings for C. Should a given compiler wrapper for C++ not exist, but one for C does, we copy over the
- # settings for C. An MPI distribution that is in this situation would be IBM Platform MPI.
- if("${LANG}" STREQUAL "CXX" AND MPI_C_WRAPPER_FOUND)
- set(MPI_${LANG}_COMPILE_OPTIONS ${MPI_C_COMPILE_OPTIONS} CACHE STRING "MPI ${LANG} compilation options" )
- set(MPI_${LANG}_COMPILE_DEFINITIONS ${MPI_C_COMPILE_DEFINITIONS} CACHE STRING "MPI ${LANG} compilation definitions" )
- set(MPI_${LANG}_ADDITIONAL_INCLUDE_DIRS ${MPI_C_INCLUDE_DIRS} CACHE STRING "MPI ${LANG} additional include directories")
- set(MPI_${LANG}_LINK_FLAGS ${MPI_C_LINK_FLAGS} CACHE STRING "MPI ${LANG} linker flags" )
- set(MPI_${LANG}_LIB_NAMES ${MPI_C_LIB_NAMES} CACHE STRING "MPI ${LANG} libraries to link against" )
- else()
- _MPI_guess_settings(${LANG})
+ if(NOT MPI_PINNED_COMPILER AND NOT MPI_${LANG}_WRAPPER_FOUND)
+ # If MPI_PINNED_COMPILER wasn't given, and the MPI compiler we potentially found didn't work, we withdraw it.
+ set(MPI_${LANG}_COMPILER "MPI_${LANG}_COMPILER-NOTFOUND" CACHE FILEPATH "MPI compiler for ${LANG}" FORCE)
+ if(NOT MPI_SKIP_GUESSING)
+ # For C++, we may use the settings for C. Should a given compiler wrapper for C++ not exist, but one for C does, we copy over the
+ # settings for C. An MPI distribution that is in this situation would be IBM Platform MPI.
+ if("${LANG}" STREQUAL "CXX" AND MPI_C_WRAPPER_FOUND)
+ set(MPI_${LANG}_COMPILE_OPTIONS ${MPI_C_COMPILE_OPTIONS} CACHE STRING "MPI ${LANG} compilation options" )
+ set(MPI_${LANG}_COMPILE_DEFINITIONS ${MPI_C_COMPILE_DEFINITIONS} CACHE STRING "MPI ${LANG} compilation definitions" )
+ set(MPI_${LANG}_ADDITIONAL_INCLUDE_DIRS ${MPI_C_INCLUDE_DIRS} CACHE STRING "MPI ${LANG} additional include directories")
+ set(MPI_${LANG}_LINK_FLAGS ${MPI_C_LINK_FLAGS} CACHE STRING "MPI ${LANG} linker flags" )
+ set(MPI_${LANG}_LIB_NAMES ${MPI_C_LIB_NAMES} CACHE STRING "MPI ${LANG} libraries to link against" )
+ else()
+ _MPI_guess_settings(${LANG})
+ endif()
endif()
endif()
endif()
diff --git a/Modules/Platform/AIX-GNU.cmake b/Modules/Platform/AIX-GNU.cmake
index 7f08c4a..0abbb61 100644
--- a/Modules/Platform/AIX-GNU.cmake
+++ b/Modules/Platform/AIX-GNU.cmake
@@ -24,5 +24,7 @@ macro(__aix_compiler_gnu lang)
set(CMAKE_${lang}_USE_IMPLICIT_LINK_DIRECTORIES_IN_RUNTIME_PATH 1)
set(CMAKE_${lang}_LINK_FLAGS "-Wl,-bnoipath")
- unset(CMAKE_${lang}_COMPILE_OPTIONS_VISIBILITY)
+ if(CMAKE_${lang}_COMPILER_VERSION VERSION_LESS 7 OR CMAKE_SYSTEM_VERSION VERSION_LESS 7.1)
+ unset(CMAKE_${lang}_COMPILE_OPTIONS_VISIBILITY)
+ endif()
endmacro()
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt
index 7031d5a..1b46377 100644
--- a/Source/CMakeLists.txt
+++ b/Source/CMakeLists.txt
@@ -327,6 +327,7 @@ set(SRCS
cmSourceFile.h
cmSourceFileLocation.cxx
cmSourceFileLocation.h
+ cmSourceFileLocationKind.h
cmSourceGroup.cxx
cmSourceGroup.h
cmState.cxx
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index 0a1834f..8fa82c5 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 10)
-set(CMake_VERSION_PATCH 20180110)
+set(CMake_VERSION_PATCH 20180117)
#set(CMake_VERSION_RC 1)
diff --git a/Source/CTest/cmCTestMultiProcessHandler.cxx b/Source/CTest/cmCTestMultiProcessHandler.cxx
index ae07feb..53c47a2 100644
--- a/Source/CTest/cmCTestMultiProcessHandler.cxx
+++ b/Source/CTest/cmCTestMultiProcessHandler.cxx
@@ -9,10 +9,14 @@
#include "cmSystemTools.h"
#include "cmWorkingDirectory.h"
+#include "cm_uv.h"
+
#include "cmsys/FStream.hxx"
#include "cmsys/String.hxx"
#include "cmsys/SystemInformation.hxx"
+
#include <algorithm>
+#include <chrono>
#include <iomanip>
#include <list>
#include <math.h>
@@ -21,6 +25,43 @@
#include <stdlib.h>
#include <utility>
+#if defined(CMAKE_USE_SYSTEM_LIBUV) && !defined(_WIN32) && \
+ UV_VERSION_MAJOR == 1 && UV_VERSION_MINOR < 19
+#define CMAKE_UV_SIGNAL_HACK
+/*
+ libuv does not use SA_RESTART on its signal handler, but C++ streams
+ depend on it for reliable i/o operations. This RAII helper convinces
+ libuv to install its handler, and then revises the handler to add the
+ SA_RESTART flag. We use a distinct uv loop that never runs to avoid
+ ever really getting a callback. libuv may fill the hack loop's signal
+ pipe and then stop writing, but that won't break any real loops.
+ */
+class cmUVSignalHackRAII
+{
+ uv_loop_t HackLoop;
+ cm::uv_signal_ptr HackSignal;
+ static void HackCB(uv_signal_t*, int) {}
+public:
+ cmUVSignalHackRAII()
+ {
+ uv_loop_init(&this->HackLoop);
+ this->HackSignal.init(this->HackLoop);
+ this->HackSignal.start(HackCB, SIGCHLD);
+ struct sigaction hack_sa;
+ sigaction(SIGCHLD, NULL, &hack_sa);
+ if (!(hack_sa.sa_flags & SA_RESTART)) {
+ hack_sa.sa_flags |= SA_RESTART;
+ sigaction(SIGCHLD, &hack_sa, NULL);
+ }
+ }
+ ~cmUVSignalHackRAII()
+ {
+ this->HackSignal.stop();
+ uv_loop_close(&this->HackLoop);
+ }
+};
+#endif
+
class TestComparator
{
public:
@@ -95,24 +136,32 @@ void cmCTestMultiProcessHandler::RunTests()
if (this->HasCycles) {
return;
}
+#ifdef CMAKE_UV_SIGNAL_HACK
+ cmUVSignalHackRAII hackRAII;
+#endif
this->TestHandler->SetMaxIndex(this->FindMaxIndex());
+
+ uv_loop_init(&this->Loop);
this->StartNextTests();
- while (!this->Tests.empty()) {
- if (this->StopTimePassed) {
- return;
- }
- this->CheckOutput();
- this->StartNextTests();
- }
- // let all running tests finish
- while (this->CheckOutput()) {
- }
+ uv_run(&this->Loop, UV_RUN_DEFAULT);
+ uv_loop_close(&this->Loop);
+
this->MarkFinished();
this->UpdateCostData();
}
-void cmCTestMultiProcessHandler::StartTestProcess(int test)
+bool cmCTestMultiProcessHandler::StartTestProcess(int test)
{
+ std::chrono::system_clock::time_point stop_time = this->CTest->GetStopTime();
+ if (stop_time != std::chrono::system_clock::time_point() &&
+ stop_time <= std::chrono::system_clock::now()) {
+ cmCTestLog(this->CTest, ERROR_MESSAGE, "The stop time has been passed. "
+ "Stopping all tests."
+ << std::endl);
+ this->StopTimePassed = true;
+ return false;
+ }
+
cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
"test " << test << "\n", this->Quiet);
this->TestRunningMap[test] = true; // mark the test as running
@@ -120,7 +169,7 @@ void cmCTestMultiProcessHandler::StartTestProcess(int test)
this->EraseTest(test);
this->RunningCount += GetProcessorsUsed(test);
- cmCTestRunTest* testRun = new cmCTestRunTest(this->TestHandler);
+ cmCTestRunTest* testRun = new cmCTestRunTest(*this);
if (this->CTest->GetRepeatUntilFail()) {
testRun->SetRunUntilFailOn();
testRun->SetNumberOfRuns(this->CTest->GetTestRepeat());
@@ -143,28 +192,11 @@ void cmCTestMultiProcessHandler::StartTestProcess(int test)
this->LockResources(test);
if (testRun->StartTest(this->Total)) {
- this->RunningTests.insert(testRun);
- } else if (testRun->IsStopTimePassed()) {
- this->StopTimePassed = true;
- delete testRun;
- return;
- } else {
-
- for (auto& j : this->Tests) {
- j.second.erase(test);
- }
-
- this->UnlockResources(test);
- this->Completed++;
- this->TestFinishMap[test] = true;
- this->TestRunningMap[test] = false;
- this->RunningCount -= GetProcessorsUsed(test);
- testRun->EndTest(this->Completed, this->Total, false);
- if (!this->Properties[test]->Disabled) {
- this->Failed->push_back(this->Properties[test]->Name);
- }
- delete testRun;
+ return true;
}
+
+ this->FinishTestProcess(testRun, false);
+ return false;
}
void cmCTestMultiProcessHandler::LockResources(int index)
@@ -222,8 +254,7 @@ bool cmCTestMultiProcessHandler::StartTest(int test)
// if there are no depends left then run this test
if (this->Tests[test].empty()) {
- this->StartTestProcess(test);
- return true;
+ return this->StartTestProcess(test);
}
// This test was not able to start because it is waiting
// on depends to run
@@ -233,6 +264,11 @@ bool cmCTestMultiProcessHandler::StartTest(int test)
void cmCTestMultiProcessHandler::StartNextTests()
{
size_t numToStart = 0;
+
+ if (this->Tests.empty()) {
+ return;
+ }
+
if (this->RunningCount < this->ParallelLevel) {
numToStart = this->ParallelLevel - this->RunningCount;
}
@@ -365,45 +401,42 @@ void cmCTestMultiProcessHandler::StartNextTests()
}
}
-bool cmCTestMultiProcessHandler::CheckOutput()
+void cmCTestMultiProcessHandler::FinishTestProcess(cmCTestRunTest* runner,
+ bool started)
{
- // no more output we are done
- if (this->RunningTests.empty()) {
- return false;
- }
- std::vector<cmCTestRunTest*> finished;
- std::string out, err;
- for (cmCTestRunTest* p : this->RunningTests) {
- if (!p->CheckOutput()) {
- finished.push_back(p);
- }
- }
- for (cmCTestRunTest* p : finished) {
- this->Completed++;
- int test = p->GetIndex();
+ this->Completed++;
+
+ int test = runner->GetIndex();
+ auto properties = runner->GetTestProperties();
- bool testResult = p->EndTest(this->Completed, this->Total, true);
- if (p->StartAgain()) {
+ bool testResult = runner->EndTest(this->Completed, this->Total, started);
+ if (started) {
+ if (runner->StartAgain()) {
this->Completed--; // remove the completed test because run again
- continue;
- }
- if (testResult) {
- this->Passed->push_back(p->GetTestProperties()->Name);
- } else {
- this->Failed->push_back(p->GetTestProperties()->Name);
- }
- for (auto& t : this->Tests) {
- t.second.erase(test);
+ return;
}
- this->TestFinishMap[test] = true;
- this->TestRunningMap[test] = false;
- this->RunningTests.erase(p);
- this->WriteCheckpoint(test);
- this->UnlockResources(test);
- this->RunningCount -= GetProcessorsUsed(test);
- delete p;
}
- return true;
+
+ if (testResult) {
+ this->Passed->push_back(properties->Name);
+ } else if (!properties->Disabled) {
+ this->Failed->push_back(properties->Name);
+ }
+
+ for (auto& t : this->Tests) {
+ t.second.erase(test);
+ }
+
+ this->TestFinishMap[test] = true;
+ this->TestRunningMap[test] = false;
+ this->WriteCheckpoint(test);
+ this->UnlockResources(test);
+ this->RunningCount -= GetProcessorsUsed(test);
+
+ delete runner;
+ if (started) {
+ this->StartNextTests();
+ }
}
void cmCTestMultiProcessHandler::UpdateCostData()
@@ -670,7 +703,7 @@ void cmCTestMultiProcessHandler::PrintTestList()
cmWorkingDirectory workdir(p.Directory);
- cmCTestRunTest testRun(this->TestHandler);
+ cmCTestRunTest testRun(*this);
testRun.SetIndex(p.Index);
testRun.SetTestProperties(&p);
testRun.ComputeArguments(); // logs the command in verbose mode
diff --git a/Source/CTest/cmCTestMultiProcessHandler.h b/Source/CTest/cmCTestMultiProcessHandler.h
index dccc2c8..7837ff9 100644
--- a/Source/CTest/cmCTestMultiProcessHandler.h
+++ b/Source/CTest/cmCTestMultiProcessHandler.h
@@ -12,6 +12,8 @@
#include <string>
#include <vector>
+#include "cm_uv.h"
+
class cmCTest;
class cmCTestRunTest;
@@ -23,6 +25,7 @@ class cmCTestRunTest;
class cmCTestMultiProcessHandler
{
friend class TestComparator;
+ friend class cmCTestRunTest;
public:
struct TestSet : public std::set<int>
@@ -75,7 +78,7 @@ protected:
// Start the next test or tests as many as are allowed by
// ParallelLevel
void StartNextTests();
- void StartTestProcess(int test);
+ bool StartTestProcess(int test);
bool StartTest(int test);
// Mark the checkpoint for the given test
void WriteCheckpoint(int index);
@@ -95,9 +98,8 @@ protected:
// Removes the checkpoint file
void MarkFinished();
void EraseTest(int index);
- // Return true if there are still tests running
- // check all running processes for output and exit case
- bool CheckOutput();
+ void FinishTestProcess(cmCTestRunTest* runner, bool started);
+
void RemoveTest(int index);
// Check if we need to resume an interrupted test set
void CheckResume();
@@ -130,7 +132,7 @@ protected:
std::vector<cmCTestTestHandler::cmCTestTestResult>* TestResults;
size_t ParallelLevel; // max number of process that can be run at once
unsigned long TestLoad;
- std::set<cmCTestRunTest*> RunningTests; // current running tests
+ uv_loop_t Loop;
cmCTestTestHandler* TestHandler;
cmCTest* CTest;
bool HasCycles;
diff --git a/Source/CTest/cmCTestRunTest.cxx b/Source/CTest/cmCTestRunTest.cxx
index dbdefae..baf894e 100644
--- a/Source/CTest/cmCTestRunTest.cxx
+++ b/Source/CTest/cmCTestRunTest.cxx
@@ -4,28 +4,27 @@
#include "cmCTest.h"
#include "cmCTestMemCheckHandler.h"
-#include "cmCTestTestHandler.h"
+#include "cmCTestMultiProcessHandler.h"
#include "cmProcess.h"
#include "cmSystemTools.h"
#include "cmWorkingDirectory.h"
-#include "cm_curl.h"
#include "cm_zlib.h"
#include "cmsys/Base64.h"
-#include "cmsys/Process.h"
#include "cmsys/RegularExpression.hxx"
#include <chrono>
+#include <cmAlgorithms.h>
#include <iomanip>
+#include <ratio>
#include <sstream>
#include <stdio.h>
-#include <time.h>
#include <utility>
-cmCTestRunTest::cmCTestRunTest(cmCTestTestHandler* handler)
+cmCTestRunTest::cmCTestRunTest(cmCTestMultiProcessHandler& multiHandler)
+ : MultiTestHandler(multiHandler)
{
- this->CTest = handler->CTest;
- this->TestHandler = handler;
- this->TestProcess = nullptr;
+ this->CTest = multiHandler.CTest;
+ this->TestHandler = multiHandler.TestHandler;
this->TestResult.ExecutionTime = std::chrono::duration<double>::zero();
this->TestResult.ReturnValue = 0;
this->TestResult.Status = cmCTestTestHandler::NOT_RUN;
@@ -34,60 +33,37 @@ cmCTestRunTest::cmCTestRunTest(cmCTestTestHandler* handler)
this->ProcessOutput.clear();
this->CompressedOutput.clear();
this->CompressionRatio = 2;
- this->StopTimePassed = false;
this->NumberOfRunsLeft = 1; // default to 1 run of the test
this->RunUntilFail = false; // default to run the test once
this->RunAgain = false; // default to not having to run again
}
-cmCTestRunTest::~cmCTestRunTest()
+void cmCTestRunTest::CheckOutput(std::string const& line)
{
-}
-
-bool cmCTestRunTest::CheckOutput()
-{
- // Read lines for up to 0.1 seconds of total time.
- std::chrono::duration<double> timeout = std::chrono::milliseconds(100);
- auto timeEnd = std::chrono::steady_clock::now() + timeout;
- std::string line;
- while ((timeout = timeEnd - std::chrono::steady_clock::now(),
- timeout > std::chrono::seconds(0))) {
- int p = this->TestProcess->GetNextOutputLine(line, timeout);
- if (p == cmsysProcess_Pipe_None) {
- // Process has terminated and all output read.
- return false;
- }
- if (p == cmsysProcess_Pipe_STDOUT) {
- // Store this line of output.
- cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, this->GetIndex()
- << ": " << line << std::endl);
- this->ProcessOutput += line;
- this->ProcessOutput += "\n";
-
- // Check for TIMEOUT_AFTER_MATCH property.
- if (!this->TestProperties->TimeoutRegularExpressions.empty()) {
- for (auto& reg : this->TestProperties->TimeoutRegularExpressions) {
- if (reg.first.find(this->ProcessOutput.c_str())) {
- cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, this->GetIndex()
- << ": "
- << "Test timeout changed to "
- << std::chrono::duration_cast<std::chrono::seconds>(
- this->TestProperties->AlternateTimeout)
- .count()
- << std::endl);
- this->TestProcess->ResetStartTime();
- this->TestProcess->ChangeTimeout(
- this->TestProperties->AlternateTimeout);
- this->TestProperties->TimeoutRegularExpressions.clear();
- break;
- }
- }
+ cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, this->GetIndex()
+ << ": " << line << std::endl);
+ this->ProcessOutput += line;
+ this->ProcessOutput += "\n";
+
+ // Check for TIMEOUT_AFTER_MATCH property.
+ if (!this->TestProperties->TimeoutRegularExpressions.empty()) {
+ for (auto& reg : this->TestProperties->TimeoutRegularExpressions) {
+ if (reg.first.find(this->ProcessOutput.c_str())) {
+ cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, this->GetIndex()
+ << ": "
+ << "Test timeout changed to "
+ << std::chrono::duration_cast<std::chrono::seconds>(
+ this->TestProperties->AlternateTimeout)
+ .count()
+ << std::endl);
+ this->TestProcess->ResetStartTime();
+ this->TestProcess->ChangeTimeout(
+ this->TestProperties->AlternateTimeout);
+ this->TestProperties->TimeoutRegularExpressions.clear();
+ break;
}
- } else { // if(p == cmsysProcess_Pipe_Timeout)
- break;
}
}
- return true;
}
// Streamed compression of test output. The compressed data
@@ -160,8 +136,8 @@ bool cmCTestRunTest::EndTest(size_t completed, size_t total, bool started)
this->WriteLogOutputTop(completed, total);
std::string reason;
bool passed = true;
- int res =
- started ? this->TestProcess->GetProcessStatus() : cmsysProcess_State_Error;
+ cmProcess::State res =
+ started ? this->TestProcess->GetProcessStatus() : cmProcess::State::Error;
int retVal = this->TestProcess->GetExitValue();
bool forceFail = false;
bool skipped = false;
@@ -200,7 +176,7 @@ bool cmCTestRunTest::EndTest(size_t completed, size_t total, bool started)
}
}
}
- if (res == cmsysProcess_State_Exited) {
+ if (res == cmProcess::State::Exited) {
bool success = !forceFail &&
(retVal == 0 ||
!this->TestProperties->RequiredRegularExpressions.empty());
@@ -221,29 +197,29 @@ bool cmCTestRunTest::EndTest(size_t completed, size_t total, bool started)
cmCTestLog(this->CTest, HANDLER_OUTPUT, "***Failed " << reason);
outputTestErrorsToConsole = this->CTest->OutputTestOutputOnTestFailure;
}
- } else if (res == cmsysProcess_State_Expired) {
+ } else if (res == cmProcess::State::Expired) {
cmCTestLog(this->CTest, HANDLER_OUTPUT, "***Timeout ");
this->TestResult.Status = cmCTestTestHandler::TIMEOUT;
outputTestErrorsToConsole = this->CTest->OutputTestOutputOnTestFailure;
- } else if (res == cmsysProcess_State_Exception) {
+ } else if (res == cmProcess::State::Exception) {
outputTestErrorsToConsole = this->CTest->OutputTestOutputOnTestFailure;
cmCTestLog(this->CTest, HANDLER_OUTPUT, "***Exception: ");
this->TestResult.ExceptionStatus =
this->TestProcess->GetExitExceptionString();
switch (this->TestProcess->GetExitException()) {
- case cmsysProcess_Exception_Fault:
+ case cmProcess::Exception::Fault:
cmCTestLog(this->CTest, HANDLER_OUTPUT, "SegFault");
this->TestResult.Status = cmCTestTestHandler::SEGFAULT;
break;
- case cmsysProcess_Exception_Illegal:
+ case cmProcess::Exception::Illegal:
cmCTestLog(this->CTest, HANDLER_OUTPUT, "Illegal");
this->TestResult.Status = cmCTestTestHandler::ILLEGAL;
break;
- case cmsysProcess_Exception_Interrupt:
+ case cmProcess::Exception::Interrupt:
cmCTestLog(this->CTest, HANDLER_OUTPUT, "Interrupt");
this->TestResult.Status = cmCTestTestHandler::INTERRUPT;
break;
- case cmsysProcess_Exception_Numerical:
+ case cmProcess::Exception::Numerical:
cmCTestLog(this->CTest, HANDLER_OUTPUT, "Numerical");
this->TestResult.Status = cmCTestTestHandler::NUMERICAL;
break;
@@ -254,7 +230,7 @@ bool cmCTestRunTest::EndTest(size_t completed, size_t total, bool started)
}
} else if ("Disabled" == this->TestResult.CompletionStatus) {
cmCTestLog(this->CTest, HANDLER_OUTPUT, "***Not Run (Disabled) ");
- } else // cmsysProcess_State_Error
+ } else // cmProcess::State::Error
{
cmCTestLog(this->CTest, HANDLER_OUTPUT, "***Not Run ");
}
@@ -350,7 +326,7 @@ bool cmCTestRunTest::EndTest(size_t completed, size_t total, bool started)
if (!this->NeedsToRerun()) {
this->TestHandler->TestResults.push_back(this->TestResult);
}
- delete this->TestProcess;
+ this->TestProcess.reset();
return passed || skipped;
}
@@ -432,7 +408,7 @@ bool cmCTestRunTest::StartTest(size_t total)
this->TestResult.TestCount = this->TestProperties->Index;
this->TestResult.Name = this->TestProperties->Name;
this->TestResult.Path = this->TestProperties->Directory;
- this->TestProcess = new cmProcess;
+ this->TestProcess = cm::make_unique<cmProcess>(*this);
this->TestResult.Output = "Disabled";
this->TestResult.FullCommandLine.clear();
return false;
@@ -453,7 +429,7 @@ bool cmCTestRunTest::StartTest(size_t total)
// its arguments are irrelevant. This matters for the case where a fixture
// dependency might be creating the executable we want to run.
if (!this->FailedDependencies.empty()) {
- this->TestProcess = new cmProcess;
+ this->TestProcess = cm::make_unique<cmProcess>(*this);
std::string msg = "Failed test dependencies:";
for (std::string const& failedDep : this->FailedDependencies) {
msg += " " + failedDep;
@@ -470,7 +446,7 @@ bool cmCTestRunTest::StartTest(size_t total)
this->ComputeArguments();
std::vector<std::string>& args = this->TestProperties->Args;
if (args.size() >= 2 && args[1] == "NOT_AVAILABLE") {
- this->TestProcess = new cmProcess;
+ this->TestProcess = cm::make_unique<cmProcess>(*this);
std::string msg;
if (this->CTest->GetConfigType().empty()) {
msg = "Test not available without configuration.";
@@ -493,7 +469,7 @@ bool cmCTestRunTest::StartTest(size_t total)
for (std::string const& file : this->TestProperties->RequiredFiles) {
if (!cmSystemTools::FileExists(file.c_str())) {
// Required file was not found
- this->TestProcess = new cmProcess;
+ this->TestProcess = cm::make_unique<cmProcess>(*this);
*this->TestHandler->LogFile << "Unable to find required file: " << file
<< std::endl;
cmCTestLog(this->CTest, ERROR_MESSAGE,
@@ -509,7 +485,7 @@ bool cmCTestRunTest::StartTest(size_t total)
if (this->ActualCommand.empty()) {
// if the command was not found create a TestResult object
// that has that information
- this->TestProcess = new cmProcess;
+ this->TestProcess = cm::make_unique<cmProcess>(*this);
*this->TestHandler->LogFile << "Unable to find executable: " << args[1]
<< std::endl;
cmCTestLog(this->CTest, ERROR_MESSAGE,
@@ -522,11 +498,22 @@ bool cmCTestRunTest::StartTest(size_t total)
}
this->StartTime = this->CTest->CurrentTime();
- auto timeout = this->ResolveTimeout();
+ auto timeout = this->TestProperties->Timeout;
- if (this->StopTimePassed) {
- return false;
+ std::chrono::system_clock::time_point stop_time = this->CTest->GetStopTime();
+ if (stop_time != std::chrono::system_clock::time_point()) {
+ std::chrono::duration<double> stop_timeout =
+ (stop_time - std::chrono::system_clock::now()) % std::chrono::hours(24);
+
+ if (stop_timeout <= std::chrono::duration<double>::zero()) {
+ stop_timeout = std::chrono::duration<double>::zero();
+ }
+ if (timeout == std::chrono::duration<double>::zero() ||
+ stop_timeout < timeout) {
+ timeout = stop_timeout;
+ }
}
+
return this->ForkProcess(timeout, this->TestProperties->ExplicitTimeout,
&this->TestProperties->Environment);
}
@@ -603,72 +590,11 @@ void cmCTestRunTest::DartProcessing()
}
}
-std::chrono::duration<double> cmCTestRunTest::ResolveTimeout()
-{
- auto timeout = this->TestProperties->Timeout;
-
- if (this->CTest->GetStopTime().empty()) {
- return timeout;
- }
- struct tm* lctime;
- time_t current_time = time(nullptr);
- lctime = gmtime(&current_time);
- int gm_hour = lctime->tm_hour;
- time_t gm_time = mktime(lctime);
- lctime = localtime(&current_time);
- int local_hour = lctime->tm_hour;
-
- int tzone_offset = local_hour - gm_hour;
- if (gm_time > current_time && gm_hour < local_hour) {
- // this means gm_time is on the next day
- tzone_offset -= 24;
- } else if (gm_time < current_time && gm_hour > local_hour) {
- // this means gm_time is on the previous day
- tzone_offset += 24;
- }
-
- tzone_offset *= 100;
- char buf[1024];
- // add todays year day and month to the time in str because
- // curl_getdate no longer assumes the day is today
- sprintf(buf, "%d%02d%02d %s %+05i", lctime->tm_year + 1900,
- lctime->tm_mon + 1, lctime->tm_mday,
- this->CTest->GetStopTime().c_str(), tzone_offset);
-
- time_t stop_time_t = curl_getdate(buf, &current_time);
- if (stop_time_t == -1) {
- return timeout;
- }
-
- auto stop_time = std::chrono::system_clock::from_time_t(stop_time_t);
-
- // the stop time refers to the next day
- if (this->CTest->NextDayStopTime) {
- stop_time += std::chrono::hours(24);
- }
- auto stop_timeout =
- (stop_time - std::chrono::system_clock::from_time_t(current_time)) %
- std::chrono::hours(24);
- this->CTest->LastStopTimeout = stop_timeout;
-
- if (stop_timeout <= std::chrono::duration<double>::zero() ||
- stop_timeout > this->CTest->LastStopTimeout) {
- cmCTestLog(this->CTest, ERROR_MESSAGE, "The stop time has been passed. "
- "Stopping all tests."
- << std::endl);
- this->StopTimePassed = true;
- return std::chrono::duration<double>::zero();
- }
- return timeout == std::chrono::duration<double>::zero()
- ? stop_timeout
- : (timeout < stop_timeout ? timeout : stop_timeout);
-}
-
bool cmCTestRunTest::ForkProcess(std::chrono::duration<double> testTimeOut,
bool explicitTimeout,
std::vector<std::string>* environment)
{
- this->TestProcess = new cmProcess;
+ this->TestProcess = cm::make_unique<cmProcess>(*this);
this->TestProcess->SetId(this->Index);
this->TestProcess->SetWorkingDirectory(
this->TestProperties->Directory.c_str());
@@ -720,7 +646,7 @@ bool cmCTestRunTest::ForkProcess(std::chrono::duration<double> testTimeOut,
cmSystemTools::AppendEnv(*environment);
}
- return this->TestProcess->StartProcess();
+ return this->TestProcess->StartProcess(this->MultiTestHandler.Loop);
}
void cmCTestRunTest::WriteLogOutputTop(size_t completed, size_t total)
@@ -794,3 +720,8 @@ void cmCTestRunTest::WriteLogOutputTop(size_t completed, size_t total)
cmCTestLog(this->CTest, DEBUG, "Testing " << this->TestProperties->Name
<< " ... ");
}
+
+void cmCTestRunTest::FinalizeTest()
+{
+ this->MultiTestHandler.FinishTestProcess(this, true);
+}
diff --git a/Source/CTest/cmCTestRunTest.h b/Source/CTest/cmCTestRunTest.h
index cd380ca..fbc202f 100644
--- a/Source/CTest/cmCTestRunTest.h
+++ b/Source/CTest/cmCTestRunTest.h
@@ -12,9 +12,10 @@
#include <vector>
#include "cmCTestTestHandler.h"
+#include "cmProcess.h" // IWYU pragma: keep (for unique_ptr)
class cmCTest;
-class cmProcess;
+class cmCTestMultiProcessHandler;
/** \class cmRunTest
* \brief represents a single test to be run
@@ -24,8 +25,9 @@ class cmProcess;
class cmCTestRunTest
{
public:
- cmCTestRunTest(cmCTestTestHandler* handler);
- ~cmCTestRunTest();
+ explicit cmCTestRunTest(cmCTestMultiProcessHandler& multiHandler);
+
+ ~cmCTestRunTest() = default;
void SetNumberOfRuns(int n) { this->NumberOfRunsLeft = n; }
void SetRunUntilFailOn() { this->RunUntilFail = true; }
@@ -50,15 +52,13 @@ public:
std::string GetProcessOutput() { return this->ProcessOutput; }
- bool IsStopTimePassed() { return this->StopTimePassed; }
-
cmCTestTestHandler::cmCTestTestResult GetTestResults()
{
return this->TestResult;
}
// Read and store output. Returns true if it must be called again.
- bool CheckOutput();
+ void CheckOutput(std::string const& line);
// Compresses the output, writing to CompressedOutput
void CompressOutput();
@@ -74,12 +74,14 @@ public:
bool StartAgain();
+ cmCTest* GetCTest() const { return this->CTest; }
+
+ void FinalizeTest();
+
private:
bool NeedsToRerun();
void DartProcessing();
void ExeNotFound(std::string exe);
- // Figures out a final timeout which is min(STOP_TIME, NOW+TIMEOUT)
- std::chrono::duration<double> ResolveTimeout();
bool ForkProcess(std::chrono::duration<double> testTimeOut,
bool explicitTimeout,
std::vector<std::string>* environment);
@@ -91,26 +93,18 @@ private:
// Pointer back to the "parent"; the handler that invoked this test run
cmCTestTestHandler* TestHandler;
cmCTest* CTest;
- cmProcess* TestProcess;
- // If the executable to run is ctest, don't create a new process;
- // just instantiate a new cmTest. (Can be disabled for a single test
- // if this option is set to false.)
- // bool OptimizeForCTest;
-
- bool UsePrefixCommand;
- std::string PrefixCommand;
-
+ std::unique_ptr<cmProcess> TestProcess;
std::string ProcessOutput;
std::string CompressedOutput;
double CompressionRatio;
// The test results
cmCTestTestHandler::cmCTestTestResult TestResult;
+ cmCTestMultiProcessHandler& MultiTestHandler;
int Index;
std::set<std::string> FailedDependencies;
std::string StartTime;
std::string ActualCommand;
std::vector<std::string> Arguments;
- bool StopTimePassed;
bool RunUntilFail;
int NumberOfRunsLeft;
bool RunAgain;
diff --git a/Source/CTest/cmProcess.cxx b/Source/CTest/cmProcess.cxx
index 0db66c3..c8806a7 100644
--- a/Source/CTest/cmProcess.cxx
+++ b/Source/CTest/cmProcess.cxx
@@ -2,12 +2,65 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmProcess.h"
+#include "cmCTest.h"
+#include "cmCTestRunTest.h"
+#include "cmCTestTestHandler.h"
#include "cmProcessOutput.h"
+#include "cmsys/Process.h"
+
+#include <algorithm>
+#include <fcntl.h>
#include <iostream>
+#include <signal.h>
+#include <stdint.h>
+#include <string>
+#if !defined(_WIN32)
+#include <unistd.h>
+#endif
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+#include <io.h>
+
+static int cmProcessGetPipes(int* fds)
+{
+ SECURITY_ATTRIBUTES attr;
+ HANDLE readh, writeh;
+ attr.nLength = sizeof(attr);
+ attr.lpSecurityDescriptor = nullptr;
+ attr.bInheritHandle = FALSE;
+ if (!CreatePipe(&readh, &writeh, &attr, 0))
+ return uv_translate_sys_error(GetLastError());
+ fds[0] = _open_osfhandle((intptr_t)readh, 0);
+ fds[1] = _open_osfhandle((intptr_t)writeh, 0);
+ if (fds[0] == -1 || fds[1] == -1) {
+ CloseHandle(readh);
+ CloseHandle(writeh);
+ return uv_translate_sys_error(GetLastError());
+ }
+ return 0;
+}
+#else
+#include <errno.h>
-cmProcess::cmProcess()
+static int cmProcessGetPipes(int* fds)
+{
+ if (pipe(fds) == -1) {
+ return uv_translate_sys_error(errno);
+ }
+
+ if (fcntl(fds[0], F_SETFD, FD_CLOEXEC) == -1 ||
+ fcntl(fds[1], F_SETFD, FD_CLOEXEC) == -1) {
+ close(fds[0]);
+ close(fds[1]);
+ return uv_translate_sys_error(errno);
+ }
+ return 0;
+}
+#endif
+
+cmProcess::cmProcess(cmCTestRunTest& runner)
+ : Runner(runner)
{
- this->Process = nullptr;
this->Timeout = std::chrono::duration<double>::zero();
this->TotalTime = std::chrono::duration<double>::zero();
this->ExitValue = 0;
@@ -17,8 +70,8 @@ cmProcess::cmProcess()
cmProcess::~cmProcess()
{
- cmsysProcess_Delete(this->Process);
}
+
void cmProcess::SetCommand(const char* command)
{
this->Command = command;
@@ -29,8 +82,9 @@ void cmProcess::SetCommandArguments(std::vector<std::string> const& args)
this->Arguments = args;
}
-bool cmProcess::StartProcess()
+bool cmProcess::StartProcess(uv_loop_t& loop)
{
+ this->ProcessState = cmProcess::State::Error;
if (this->Command.empty()) {
return false;
}
@@ -43,17 +97,83 @@ bool cmProcess::StartProcess()
this->ProcessArgs.push_back(arg.c_str());
}
this->ProcessArgs.push_back(nullptr); // null terminate the list
- this->Process = cmsysProcess_New();
- cmsysProcess_SetCommand(this->Process, &*this->ProcessArgs.begin());
- if (!this->WorkingDirectory.empty()) {
- cmsysProcess_SetWorkingDirectory(this->Process,
- this->WorkingDirectory.c_str());
+
+ cm::uv_timer_ptr timer;
+ int status = timer.init(loop, this);
+ if (status != 0) {
+ cmCTestLog(this->Runner.GetCTest(), ERROR_MESSAGE,
+ "Error initializing timer: " << uv_strerror(status)
+ << std::endl);
+ return false;
+ }
+
+ cm::uv_pipe_ptr pipe_writer;
+ cm::uv_pipe_ptr pipe_reader;
+
+ pipe_writer.init(loop, 0);
+ pipe_reader.init(loop, 0, this);
+
+ int fds[2] = { -1, -1 };
+ status = cmProcessGetPipes(fds);
+ if (status != 0) {
+ cmCTestLog(this->Runner.GetCTest(), ERROR_MESSAGE,
+ "Error initializing pipe: " << uv_strerror(status)
+ << std::endl);
+ return false;
+ }
+
+ uv_pipe_open(pipe_reader, fds[0]);
+ uv_pipe_open(pipe_writer, fds[1]);
+
+ uv_stdio_container_t stdio[3];
+ stdio[0].flags = UV_IGNORE;
+ stdio[1].flags = UV_INHERIT_STREAM;
+ stdio[1].data.stream = pipe_writer;
+ stdio[2] = stdio[1];
+
+ uv_process_options_t options = uv_process_options_t();
+ options.file = this->Command.data();
+ options.args = const_cast<char**>(this->ProcessArgs.data());
+ options.stdio_count = 3; // in, out and err
+ options.exit_cb = &cmProcess::OnExitCB;
+ options.stdio = stdio;
+
+ status =
+ uv_read_start(pipe_reader, &cmProcess::OnAllocateCB, &cmProcess::OnReadCB);
+
+ if (status != 0) {
+ cmCTestLog(this->Runner.GetCTest(), ERROR_MESSAGE,
+ "Error starting read events: " << uv_strerror(status)
+ << std::endl);
+ return false;
+ }
+
+ status = this->Process.spawn(loop, options, this);
+ if (status != 0) {
+ cmCTestLog(this->Runner.GetCTest(), ERROR_MESSAGE, "Process not started\n "
+ << this->Command << "\n[" << uv_strerror(status) << "]\n");
+ return false;
+ }
+
+ this->PipeReader = std::move(pipe_reader);
+ this->Timer = std::move(timer);
+
+ this->StartTimer();
+
+ this->ProcessState = cmProcess::State::Executing;
+ return true;
+}
+
+void cmProcess::StartTimer()
+{
+ auto properties = this->Runner.GetTestProperties();
+ auto msec =
+ std::chrono::duration_cast<std::chrono::milliseconds>(this->Timeout);
+
+ if (msec != std::chrono::milliseconds(0) || !properties->ExplicitTimeout) {
+ this->Timer.start(&cmProcess::OnTimeoutCB,
+ static_cast<uint64_t>(msec.count()), 0);
}
- cmsysProcess_SetTimeout(this->Process, this->Timeout.count());
- cmsysProcess_SetOption(this->Process, cmsysProcess_Option_MergeOutput, 1);
- cmsysProcess_Execute(this->Process);
- return (cmsysProcess_GetState(this->Process) ==
- cmsysProcess_State_Executing);
}
bool cmProcess::Buffer::GetLine(std::string& line)
@@ -100,51 +220,121 @@ bool cmProcess::Buffer::GetLast(std::string& line)
return false;
}
-int cmProcess::GetNextOutputLine(std::string& line,
- std::chrono::duration<double> timeout)
+void cmProcess::OnReadCB(uv_stream_t* stream, ssize_t nread,
+ const uv_buf_t* buf)
{
- cmProcessOutput processOutput(cmProcessOutput::UTF8);
- std::string strdata;
- double waitTimeout = timeout.count();
- for (;;) {
- // Look for lines already buffered.
- if (this->Output.GetLine(line)) {
- return cmsysProcess_Pipe_STDOUT;
- }
+ auto self = static_cast<cmProcess*>(stream->data);
+ self->OnRead(nread, buf);
+}
- // Check for more data from the process.
- char* data;
- int length;
- int p =
- cmsysProcess_WaitForData(this->Process, &data, &length, &waitTimeout);
- if (p == cmsysProcess_Pipe_Timeout) {
- return cmsysProcess_Pipe_Timeout;
- }
- if (p == cmsysProcess_Pipe_STDOUT) {
- processOutput.DecodeText(data, length, strdata);
- this->Output.insert(this->Output.end(), strdata.begin(), strdata.end());
- } else { // p == cmsysProcess_Pipe_None
- // The process will provide no more data.
- break;
+void cmProcess::OnRead(ssize_t nread, const uv_buf_t* buf)
+{
+ std::string line;
+ if (nread > 0) {
+ std::string strdata;
+ cmProcessOutput processOutput(cmProcessOutput::UTF8,
+ static_cast<unsigned int>(buf->len));
+ processOutput.DecodeText(buf->base, static_cast<size_t>(nread), strdata);
+ this->Output.insert(this->Output.end(), strdata.begin(), strdata.end());
+
+ while (this->Output.GetLine(line)) {
+ this->Runner.CheckOutput(line);
+ line.clear();
}
+
+ return;
}
- processOutput.DecodeText(std::string(), strdata);
- if (!strdata.empty()) {
- this->Output.insert(this->Output.end(), strdata.begin(), strdata.end());
+
+ // The process will provide no more data.
+ if (nread != UV_EOF) {
+ auto error = static_cast<int>(nread);
+ cmCTestLog(this->Runner.GetCTest(), ERROR_MESSAGE,
+ "Error reading stream: " << uv_strerror(error) << std::endl);
}
// Look for partial last lines.
if (this->Output.GetLast(line)) {
- return cmsysProcess_Pipe_STDOUT;
+ this->Runner.CheckOutput(line);
+ }
+
+ this->ReadHandleClosed = true;
+ if (this->ProcessHandleClosed) {
+ uv_timer_stop(this->Timer);
+ this->Runner.FinalizeTest();
+ }
+}
+
+void cmProcess::OnAllocateCB(uv_handle_t* handle, size_t suggested_size,
+ uv_buf_t* buf)
+{
+ auto self = static_cast<cmProcess*>(handle->data);
+ self->OnAllocate(suggested_size, buf);
+}
+
+void cmProcess::OnAllocate(size_t suggested_size, uv_buf_t* buf)
+{
+ if (this->Buf.size() < suggested_size) {
+ this->Buf.resize(suggested_size);
+ }
+
+ *buf =
+ uv_buf_init(this->Buf.data(), static_cast<unsigned int>(this->Buf.size()));
+}
+
+void cmProcess::OnTimeoutCB(uv_timer_t* timer)
+{
+ auto self = static_cast<cmProcess*>(timer->data);
+ self->OnTimeout();
+}
+
+void cmProcess::OnTimeout()
+{
+ if (this->ProcessState != cmProcess::State::Executing) {
+ return;
+ }
+ this->ProcessState = cmProcess::State::Expired;
+ bool const was_still_reading = !this->ReadHandleClosed;
+ if (!this->ReadHandleClosed) {
+ this->ReadHandleClosed = true;
+ this->PipeReader.reset();
+ }
+ if (!this->ProcessHandleClosed) {
+ // Kill the child and let our on-exit handler finish the test.
+ cmsysProcess_KillPID(static_cast<unsigned long>(this->Process->pid));
+ } else if (was_still_reading) {
+ // Our on-exit handler already ran but did not finish the test
+ // because we were still reading output. We've just dropped
+ // our read handler, so we need to finish the test now.
+ this->Runner.FinalizeTest();
}
+}
- // No more data. Wait for process exit.
- if (!cmsysProcess_WaitForExit(this->Process, &waitTimeout)) {
- return cmsysProcess_Pipe_Timeout;
+void cmProcess::OnExitCB(uv_process_t* process, int64_t exit_status,
+ int term_signal)
+{
+ auto self = static_cast<cmProcess*>(process->data);
+ self->OnExit(exit_status, term_signal);
+}
+
+void cmProcess::OnExit(int64_t exit_status, int term_signal)
+{
+ if (this->ProcessState != cmProcess::State::Expired) {
+ if (
+#if defined(_WIN32)
+ ((DWORD)exit_status & 0xF0000000) == 0xC0000000
+#else
+ term_signal != 0
+#endif
+ ) {
+ this->ProcessState = cmProcess::State::Exception;
+ } else {
+ this->ProcessState = cmProcess::State::Exited;
+ }
}
// Record exit information.
- this->ExitValue = cmsysProcess_GetExitValue(this->Process);
+ this->ExitValue = static_cast<int>(exit_status);
+ this->Signal = term_signal;
this->TotalTime = std::chrono::steady_clock::now() - this->StartTime;
// Because of a processor clock scew the runtime may become slightly
// negative. If someone changed the system clock while the process was
@@ -153,95 +343,373 @@ int cmProcess::GetNextOutputLine(std::string& line,
if (this->TotalTime <= std::chrono::duration<double>::zero()) {
this->TotalTime = std::chrono::duration<double>::zero();
}
- // std::cerr << "Time to run: " << this->TotalTime << "\n";
- return cmsysProcess_Pipe_None;
-}
-
-// return the process status
-int cmProcess::GetProcessStatus()
-{
- if (!this->Process) {
- return cmsysProcess_State_Exited;
- }
- return cmsysProcess_GetState(this->Process);
-}
-
-int cmProcess::ReportStatus()
-{
- int result = 1;
- switch (cmsysProcess_GetState(this->Process)) {
- case cmsysProcess_State_Starting: {
- std::cerr << "cmProcess: Never started " << this->Command
- << " process.\n";
- } break;
- case cmsysProcess_State_Error: {
- std::cerr << "cmProcess: Error executing " << this->Command
- << " process: " << cmsysProcess_GetErrorString(this->Process)
- << "\n";
- } break;
- case cmsysProcess_State_Exception: {
- std::cerr << "cmProcess: " << this->Command
- << " process exited with an exception: ";
- switch (cmsysProcess_GetExitException(this->Process)) {
- case cmsysProcess_Exception_None: {
- std::cerr << "None";
- } break;
- case cmsysProcess_Exception_Fault: {
- std::cerr << "Segmentation fault";
- } break;
- case cmsysProcess_Exception_Illegal: {
- std::cerr << "Illegal instruction";
- } break;
- case cmsysProcess_Exception_Interrupt: {
- std::cerr << "Interrupted by user";
- } break;
- case cmsysProcess_Exception_Numerical: {
- std::cerr << "Numerical exception";
- } break;
- case cmsysProcess_Exception_Other: {
- std::cerr << "Unknown";
- } break;
- }
- std::cerr << "\n";
- } break;
- case cmsysProcess_State_Executing: {
- std::cerr << "cmProcess: Never terminated " << this->Command
- << " process.\n";
- } break;
- case cmsysProcess_State_Exited: {
- result = cmsysProcess_GetExitValue(this->Process);
- std::cerr << "cmProcess: " << this->Command
- << " process exited with code " << result << "\n";
- } break;
- case cmsysProcess_State_Expired: {
- std::cerr << "cmProcess: killed " << this->Command
- << " process due to timeout.\n";
- } break;
- case cmsysProcess_State_Killed: {
- std::cerr << "cmProcess: killed " << this->Command << " process.\n";
- } break;
- }
- return result;
+
+ this->ProcessHandleClosed = true;
+ if (this->ReadHandleClosed) {
+ uv_timer_stop(this->Timer);
+ this->Runner.FinalizeTest();
+ }
+}
+
+cmProcess::State cmProcess::GetProcessStatus()
+{
+ return this->ProcessState;
}
void cmProcess::ChangeTimeout(std::chrono::duration<double> t)
{
this->Timeout = t;
- cmsysProcess_SetTimeout(this->Process, this->Timeout.count());
+ this->StartTimer();
}
void cmProcess::ResetStartTime()
{
- cmsysProcess_ResetStartTime(this->Process);
this->StartTime = std::chrono::steady_clock::now();
}
-int cmProcess::GetExitException()
+cmProcess::Exception cmProcess::GetExitException()
{
- return cmsysProcess_GetExitException(this->Process);
+ auto exception = Exception::None;
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ auto exit_code = (DWORD) this->ExitValue;
+ if ((exit_code & 0xF0000000) != 0xC0000000) {
+ return exception;
+ }
+
+ if (exit_code) {
+ switch (exit_code) {
+ case STATUS_DATATYPE_MISALIGNMENT:
+ case STATUS_ACCESS_VIOLATION:
+ case STATUS_IN_PAGE_ERROR:
+ case STATUS_INVALID_HANDLE:
+ case STATUS_NONCONTINUABLE_EXCEPTION:
+ case STATUS_INVALID_DISPOSITION:
+ case STATUS_ARRAY_BOUNDS_EXCEEDED:
+ case STATUS_STACK_OVERFLOW:
+ exception = Exception::Fault;
+ break;
+ case STATUS_FLOAT_DENORMAL_OPERAND:
+ case STATUS_FLOAT_DIVIDE_BY_ZERO:
+ case STATUS_FLOAT_INEXACT_RESULT:
+ case STATUS_FLOAT_INVALID_OPERATION:
+ case STATUS_FLOAT_OVERFLOW:
+ case STATUS_FLOAT_STACK_CHECK:
+ case STATUS_FLOAT_UNDERFLOW:
+#ifdef STATUS_FLOAT_MULTIPLE_FAULTS
+ case STATUS_FLOAT_MULTIPLE_FAULTS:
+#endif
+#ifdef STATUS_FLOAT_MULTIPLE_TRAPS
+ case STATUS_FLOAT_MULTIPLE_TRAPS:
+#endif
+ case STATUS_INTEGER_DIVIDE_BY_ZERO:
+ case STATUS_INTEGER_OVERFLOW:
+ exception = Exception::Numerical;
+ break;
+ case STATUS_CONTROL_C_EXIT:
+ exception = Exception::Interrupt;
+ break;
+ case STATUS_ILLEGAL_INSTRUCTION:
+ case STATUS_PRIVILEGED_INSTRUCTION:
+ exception = Exception::Illegal;
+ break;
+ default:
+ exception = Exception::Other;
+ }
+ }
+#else
+ if (this->Signal) {
+ switch (this->Signal) {
+ case SIGSEGV:
+ exception = Exception::Fault;
+ break;
+ case SIGFPE:
+ exception = Exception::Numerical;
+ break;
+ case SIGINT:
+ exception = Exception::Interrupt;
+ break;
+ case SIGILL:
+ exception = Exception::Illegal;
+ break;
+ default:
+ exception = Exception::Other;
+ }
+ }
+#endif
+ return exception;
}
std::string cmProcess::GetExitExceptionString()
{
- return cmsysProcess_GetExceptionString(this->Process);
+ std::string exception_str;
+#if defined(_WIN32)
+ switch (this->ExitValue) {
+ case STATUS_CONTROL_C_EXIT:
+ exception_str = "User interrupt";
+ break;
+ case STATUS_FLOAT_DENORMAL_OPERAND:
+ exception_str = "Floating-point exception (denormal operand)";
+ break;
+ case STATUS_FLOAT_DIVIDE_BY_ZERO:
+ exception_str = "Divide-by-zero";
+ break;
+ case STATUS_FLOAT_INEXACT_RESULT:
+ exception_str = "Floating-point exception (inexact result)";
+ break;
+ case STATUS_FLOAT_INVALID_OPERATION:
+ exception_str = "Invalid floating-point operation";
+ break;
+ case STATUS_FLOAT_OVERFLOW:
+ exception_str = "Floating-point overflow";
+ break;
+ case STATUS_FLOAT_STACK_CHECK:
+ exception_str = "Floating-point stack check failed";
+ break;
+ case STATUS_FLOAT_UNDERFLOW:
+ exception_str = "Floating-point underflow";
+ break;
+#ifdef STATUS_FLOAT_MULTIPLE_FAULTS
+ case STATUS_FLOAT_MULTIPLE_FAULTS:
+ exception_str = "Floating-point exception (multiple faults)";
+ break;
+#endif
+#ifdef STATUS_FLOAT_MULTIPLE_TRAPS
+ case STATUS_FLOAT_MULTIPLE_TRAPS:
+ exception_str = "Floating-point exception (multiple traps)";
+ break;
+#endif
+ case STATUS_INTEGER_DIVIDE_BY_ZERO:
+ exception_str = "Integer divide-by-zero";
+ break;
+ case STATUS_INTEGER_OVERFLOW:
+ exception_str = "Integer overflow";
+ break;
+
+ case STATUS_DATATYPE_MISALIGNMENT:
+ exception_str = "Datatype misalignment";
+ break;
+ case STATUS_ACCESS_VIOLATION:
+ exception_str = "Access violation";
+ break;
+ case STATUS_IN_PAGE_ERROR:
+ exception_str = "In-page error";
+ break;
+ case STATUS_INVALID_HANDLE:
+ exception_str = "Invalid handle";
+ break;
+ case STATUS_NONCONTINUABLE_EXCEPTION:
+ exception_str = "Noncontinuable exception";
+ break;
+ case STATUS_INVALID_DISPOSITION:
+ exception_str = "Invalid disposition";
+ break;
+ case STATUS_ARRAY_BOUNDS_EXCEEDED:
+ exception_str = "Array bounds exceeded";
+ break;
+ case STATUS_STACK_OVERFLOW:
+ exception_str = "Stack overflow";
+ break;
+
+ case STATUS_ILLEGAL_INSTRUCTION:
+ exception_str = "Illegal instruction";
+ break;
+ case STATUS_PRIVILEGED_INSTRUCTION:
+ exception_str = "Privileged instruction";
+ break;
+ case STATUS_NO_MEMORY:
+ default:
+ char buf[1024];
+ _snprintf(buf, 1024, "Exit code 0x%x\n", this->ExitValue);
+ exception_str.assign(buf);
+ }
+#else
+ switch (this->Signal) {
+#ifdef SIGSEGV
+ case SIGSEGV:
+ exception_str = "Segmentation fault";
+ break;
+#endif
+#ifdef SIGBUS
+#if !defined(SIGSEGV) || SIGBUS != SIGSEGV
+ case SIGBUS:
+ exception_str = "Bus error";
+ break;
+#endif
+#endif
+#ifdef SIGFPE
+ case SIGFPE:
+ exception_str = "Floating-point exception";
+ break;
+#endif
+#ifdef SIGILL
+ case SIGILL:
+ exception_str = "Illegal instruction";
+ break;
+#endif
+#ifdef SIGINT
+ case SIGINT:
+ exception_str = "User interrupt";
+ break;
+#endif
+#ifdef SIGABRT
+ case SIGABRT:
+ exception_str = "Child aborted";
+ break;
+#endif
+#ifdef SIGKILL
+ case SIGKILL:
+ exception_str = "Child killed";
+ break;
+#endif
+#ifdef SIGTERM
+ case SIGTERM:
+ exception_str = "Child terminated";
+ break;
+#endif
+#ifdef SIGHUP
+ case SIGHUP:
+ exception_str = "SIGHUP";
+ break;
+#endif
+#ifdef SIGQUIT
+ case SIGQUIT:
+ exception_str = "SIGQUIT";
+ break;
+#endif
+#ifdef SIGTRAP
+ case SIGTRAP:
+ exception_str = "SIGTRAP";
+ break;
+#endif
+#ifdef SIGIOT
+#if !defined(SIGABRT) || SIGIOT != SIGABRT
+ case SIGIOT:
+ exception_str = "SIGIOT";
+ break;
+#endif
+#endif
+#ifdef SIGUSR1
+ case SIGUSR1:
+ exception_str = "SIGUSR1";
+ break;
+#endif
+#ifdef SIGUSR2
+ case SIGUSR2:
+ exception_str = "SIGUSR2";
+ break;
+#endif
+#ifdef SIGPIPE
+ case SIGPIPE:
+ exception_str = "SIGPIPE";
+ break;
+#endif
+#ifdef SIGALRM
+ case SIGALRM:
+ exception_str = "SIGALRM";
+ break;
+#endif
+#ifdef SIGSTKFLT
+ case SIGSTKFLT:
+ exception_str = "SIGSTKFLT";
+ break;
+#endif
+#ifdef SIGCHLD
+ case SIGCHLD:
+ exception_str = "SIGCHLD";
+ break;
+#elif defined(SIGCLD)
+ case SIGCLD:
+ exception_str = "SIGCLD";
+ break;
+#endif
+#ifdef SIGCONT
+ case SIGCONT:
+ exception_str = "SIGCONT";
+ break;
+#endif
+#ifdef SIGSTOP
+ case SIGSTOP:
+ exception_str = "SIGSTOP";
+ break;
+#endif
+#ifdef SIGTSTP
+ case SIGTSTP:
+ exception_str = "SIGTSTP";
+ break;
+#endif
+#ifdef SIGTTIN
+ case SIGTTIN:
+ exception_str = "SIGTTIN";
+ break;
+#endif
+#ifdef SIGTTOU
+ case SIGTTOU:
+ exception_str = "SIGTTOU";
+ break;
+#endif
+#ifdef SIGURG
+ case SIGURG:
+ exception_str = "SIGURG";
+ break;
+#endif
+#ifdef SIGXCPU
+ case SIGXCPU:
+ exception_str = "SIGXCPU";
+ break;
+#endif
+#ifdef SIGXFSZ
+ case SIGXFSZ:
+ exception_str = "SIGXFSZ";
+ break;
+#endif
+#ifdef SIGVTALRM
+ case SIGVTALRM:
+ exception_str = "SIGVTALRM";
+ break;
+#endif
+#ifdef SIGPROF
+ case SIGPROF:
+ exception_str = "SIGPROF";
+ break;
+#endif
+#ifdef SIGWINCH
+ case SIGWINCH:
+ exception_str = "SIGWINCH";
+ break;
+#endif
+#ifdef SIGPOLL
+ case SIGPOLL:
+ exception_str = "SIGPOLL";
+ break;
+#endif
+#ifdef SIGIO
+#if !defined(SIGPOLL) || SIGIO != SIGPOLL
+ case SIGIO:
+ exception_str = "SIGIO";
+ break;
+#endif
+#endif
+#ifdef SIGPWR
+ case SIGPWR:
+ exception_str = "SIGPWR";
+ break;
+#endif
+#ifdef SIGSYS
+ case SIGSYS:
+ exception_str = "SIGSYS";
+ break;
+#endif
+#ifdef SIGUNUSED
+#if !defined(SIGSYS) || SIGUNUSED != SIGSYS
+ case SIGUNUSED:
+ exception_str = "SIGUNUSED";
+ break;
+#endif
+#endif
+ default:
+ exception_str = "Signal ";
+ exception_str += std::to_string(this->Signal);
+ }
+#endif
+ return exception_str;
}
diff --git a/Source/CTest/cmProcess.h b/Source/CTest/cmProcess.h
index f3b0bd7..9250896 100644
--- a/Source/CTest/cmProcess.h
+++ b/Source/CTest/cmProcess.h
@@ -5,11 +5,17 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmsys/Process.h"
+#include "cmUVHandlePtr.h"
+#include "cm_uv.h"
+
#include <chrono>
+#include <stddef.h>
#include <string>
+#include <sys/types.h>
#include <vector>
+class cmCTestRunTest;
+
/** \class cmProcess
* \brief run a process with c++
*
@@ -18,7 +24,7 @@
class cmProcess
{
public:
- cmProcess();
+ explicit cmProcess(cmCTestRunTest& runner);
~cmProcess();
const char* GetCommand() { return this->Command.c_str(); }
void SetCommand(const char* command);
@@ -28,33 +34,70 @@ public:
void ChangeTimeout(std::chrono::duration<double> t);
void ResetStartTime();
// Return true if the process starts
- bool StartProcess();
+ bool StartProcess(uv_loop_t& loop);
+
+ enum class State
+ {
+ Starting,
+ Error,
+ Exception,
+ Executing,
+ Exited,
+ Expired,
+ Killed,
+ Disowned
+ };
- // return the process status
- int GetProcessStatus();
- // Report the status of the program
- int ReportStatus();
+ State GetProcessStatus();
int GetId() { return this->Id; }
void SetId(int id) { this->Id = id; }
int GetExitValue() { return this->ExitValue; }
std::chrono::duration<double> GetTotalTime() { return this->TotalTime; }
- int GetExitException();
+
+ enum class Exception
+ {
+ None,
+ Fault,
+ Illegal,
+ Interrupt,
+ Numerical,
+ Other
+ };
+
+ Exception GetExitException();
std::string GetExitExceptionString();
- /**
- * Read one line of output but block for no more than timeout.
- * Returns:
- * cmsysProcess_Pipe_None = Process terminated and all output read
- * cmsysProcess_Pipe_STDOUT = Line came from stdout or stderr
- * cmsysProcess_Pipe_Timeout = Timeout expired while waiting
- */
- int GetNextOutputLine(std::string& line,
- std::chrono::duration<double> timeout);
private:
std::chrono::duration<double> Timeout;
std::chrono::steady_clock::time_point StartTime;
std::chrono::duration<double> TotalTime;
- cmsysProcess* Process;
+ bool ReadHandleClosed = false;
+ bool ProcessHandleClosed = false;
+
+ cm::uv_process_ptr Process;
+ cm::uv_pipe_ptr PipeReader;
+ cm::uv_timer_ptr Timer;
+ std::vector<char> Buf;
+
+ cmCTestRunTest& Runner;
+ int Signal = 0;
+ cmProcess::State ProcessState = cmProcess::State::Starting;
+
+ static void OnExitCB(uv_process_t* process, int64_t exit_status,
+ int term_signal);
+ static void OnTimeoutCB(uv_timer_t* timer);
+ static void OnReadCB(uv_stream_t* stream, ssize_t nread,
+ const uv_buf_t* buf);
+ static void OnAllocateCB(uv_handle_t* handle, size_t suggested_size,
+ uv_buf_t* buf);
+
+ void OnExit(int64_t exit_status, int term_signal);
+ void OnTimeout();
+ void OnRead(ssize_t nread, const uv_buf_t* buf);
+ void OnAllocate(size_t suggested_size, uv_buf_t* buf);
+
+ void StartTimer();
+
class Buffer : public std::vector<char>
{
// Half-open index range of partial line already scanned.
diff --git a/Source/CursesDialog/CMakeLists.txt b/Source/CursesDialog/CMakeLists.txt
index 6023c83..c51b0dd 100644
--- a/Source/CursesDialog/CMakeLists.txt
+++ b/Source/CursesDialog/CMakeLists.txt
@@ -2,19 +2,19 @@
# file Copyright.txt or https://cmake.org/licensing for details.
set( CURSES_SRCS
- CursesDialog/cmCursesOptionsWidget
- CursesDialog/cmCursesBoolWidget
- CursesDialog/cmCursesCacheEntryComposite
- CursesDialog/cmCursesDummyWidget
- CursesDialog/cmCursesFilePathWidget
- CursesDialog/cmCursesForm
- CursesDialog/cmCursesLabelWidget
- CursesDialog/cmCursesLongMessageForm
- CursesDialog/cmCursesMainForm
- CursesDialog/cmCursesPathWidget
- CursesDialog/cmCursesStringWidget
- CursesDialog/cmCursesWidget
- CursesDialog/ccmake
+ CursesDialog/cmCursesOptionsWidget.cxx
+ CursesDialog/cmCursesBoolWidget.cxx
+ CursesDialog/cmCursesCacheEntryComposite.cxx
+ CursesDialog/cmCursesDummyWidget.cxx
+ CursesDialog/cmCursesFilePathWidget.cxx
+ CursesDialog/cmCursesForm.cxx
+ CursesDialog/cmCursesLabelWidget.cxx
+ CursesDialog/cmCursesLongMessageForm.cxx
+ CursesDialog/cmCursesMainForm.cxx
+ CursesDialog/cmCursesPathWidget.cxx
+ CursesDialog/cmCursesStringWidget.cxx
+ CursesDialog/cmCursesWidget.cxx
+ CursesDialog/ccmake.cxx
)
include_directories(${CURSES_INCLUDE_PATH})
diff --git a/Source/cmCTest.cxx b/Source/cmCTest.cxx
index 26e1dcb..fd7c5e8 100644
--- a/Source/cmCTest.cxx
+++ b/Source/cmCTest.cxx
@@ -279,11 +279,8 @@ cmCTest::cmCTest()
this->InteractiveDebugMode = true;
this->TimeOut = std::chrono::duration<double>::zero();
this->GlobalTimeout = std::chrono::duration<double>::zero();
- this->LastStopTimeout = std::chrono::hours(24);
this->CompressXMLFiles = false;
this->ScheduleType.clear();
- this->StopTime.clear();
- this->NextDayStopTime = false;
this->OutputLogFile = nullptr;
this->OutputLogFileLastTag = -1;
this->SuppressUpdatingCTestConfiguration = false;
@@ -2269,10 +2266,41 @@ void cmCTest::SetNotesFiles(const char* notes)
this->NotesFiles = notes;
}
-void cmCTest::SetStopTime(std::string const& time)
+void cmCTest::SetStopTime(std::string const& time_str)
{
- this->StopTime = time;
- this->DetermineNextDayStop();
+
+ struct tm* lctime;
+ time_t current_time = time(nullptr);
+ lctime = gmtime(&current_time);
+ int gm_hour = lctime->tm_hour;
+ time_t gm_time = mktime(lctime);
+ lctime = localtime(&current_time);
+ int local_hour = lctime->tm_hour;
+
+ int tzone_offset = local_hour - gm_hour;
+ if (gm_time > current_time && gm_hour < local_hour) {
+ // this means gm_time is on the next day
+ tzone_offset -= 24;
+ } else if (gm_time < current_time && gm_hour > local_hour) {
+ // this means gm_time is on the previous day
+ tzone_offset += 24;
+ }
+
+ tzone_offset *= 100;
+ char buf[1024];
+ sprintf(buf, "%d%02d%02d %s %+05i", lctime->tm_year + 1900,
+ lctime->tm_mon + 1, lctime->tm_mday, time_str.c_str(), tzone_offset);
+
+ time_t stop_time = curl_getdate(buf, &current_time);
+ if (stop_time == -1) {
+ this->StopTime = std::chrono::system_clock::time_point();
+ return;
+ }
+ this->StopTime = std::chrono::system_clock::from_time_t(stop_time);
+
+ if (stop_time < current_time) {
+ this->StopTime += std::chrono::hours(24);
+ }
}
int cmCTest::ReadCustomConfigurationFileTree(const char* dir, cmMakefile* mf)
@@ -2430,38 +2458,6 @@ void cmCTest::EmptyCTestConfiguration()
this->CTestConfiguration.clear();
}
-void cmCTest::DetermineNextDayStop()
-{
- struct tm* lctime;
- time_t current_time = time(nullptr);
- lctime = gmtime(&current_time);
- int gm_hour = lctime->tm_hour;
- time_t gm_time = mktime(lctime);
- lctime = localtime(&current_time);
- int local_hour = lctime->tm_hour;
-
- int tzone_offset = local_hour - gm_hour;
- if (gm_time > current_time && gm_hour < local_hour) {
- // this means gm_time is on the next day
- tzone_offset -= 24;
- } else if (gm_time < current_time && gm_hour > local_hour) {
- // this means gm_time is on the previous day
- tzone_offset += 24;
- }
-
- tzone_offset *= 100;
- char buf[1024];
- sprintf(buf, "%d%02d%02d %s %+05i", lctime->tm_year + 1900,
- lctime->tm_mon + 1, lctime->tm_mday, this->StopTime.c_str(),
- tzone_offset);
-
- time_t stop_time = curl_getdate(buf, &current_time);
-
- if (stop_time < current_time) {
- this->NextDayStopTime = true;
- }
-}
-
void cmCTest::SetCTestConfiguration(const char* name, const char* value,
bool suppress)
{
diff --git a/Source/cmCTest.h b/Source/cmCTest.h
index 23d71cb..61487f1 100644
--- a/Source/cmCTest.h
+++ b/Source/cmCTest.h
@@ -226,7 +226,10 @@ public:
bool ShouldCompressTestOutput();
bool CompressString(std::string& str);
- std::string GetStopTime() { return this->StopTime; }
+ std::chrono::system_clock::time_point GetStopTime()
+ {
+ return this->StopTime;
+ }
void SetStopTime(std::string const& time);
/** Used for parallel ctest job scheduling */
@@ -464,8 +467,7 @@ private:
bool RepeatUntilFail;
std::string ConfigType;
std::string ScheduleType;
- std::string StopTime;
- bool NextDayStopTime;
+ std::chrono::system_clock::time_point StopTime;
bool Verbose;
bool ExtraVerbose;
bool ProduceXML;
@@ -481,8 +483,6 @@ private:
int GenerateNotesFile(const char* files);
- void DetermineNextDayStop();
-
// these are helper classes
typedef std::map<std::string, cmCTestGenericHandler*> t_TestingHandlers;
t_TestingHandlers TestingHandlers;
@@ -512,8 +512,6 @@ private:
std::chrono::duration<double> GlobalTimeout;
- std::chrono::duration<double> LastStopTimeout;
-
int MaxTestNameWidth;
int ParallelLevel;
diff --git a/Source/cmGeneratorExpressionNode.cxx b/Source/cmGeneratorExpressionNode.cxx
index 3d311d6..34ef45f 100644
--- a/Source/cmGeneratorExpressionNode.cxx
+++ b/Source/cmGeneratorExpressionNode.cxx
@@ -805,7 +805,7 @@ static const struct CompileLanguageNode : public cmGeneratorExpressionNode
const std::vector<std::string>& parameters,
cmGeneratorExpressionContext* context,
const GeneratorExpressionContent* content,
- cmGeneratorExpressionDAGChecker* dagChecker) const override
+ cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
{
if (context->Language.empty()) {
reportError(
@@ -827,33 +827,14 @@ static const struct CompileLanguageNode : public cmGeneratorExpressionNode
return std::string();
}
std::string genName = gg->GetName();
- if (genName.find("Visual Studio") != std::string::npos) {
- if (dagChecker && (dagChecker->EvaluatingCompileDefinitions() ||
- dagChecker->EvaluatingIncludeDirectories())) {
- reportError(
- context, content->GetOriginalExpression(),
- "$<COMPILE_LANGUAGE:...> may only be used for COMPILE_OPTIONS "
- "and file(GENERATE) with the Visual Studio generator.");
- return std::string();
- }
- } else if (genName.find("Xcode") != std::string::npos) {
- if (dagChecker && (dagChecker->EvaluatingCompileDefinitions() ||
- dagChecker->EvaluatingIncludeDirectories())) {
- reportError(
- context, content->GetOriginalExpression(),
- "$<COMPILE_LANGUAGE:...> may only be used for COMPILE_OPTIONS "
- "and file(GENERATE) with the Xcode generator.");
- return std::string();
- }
- } else {
- if (genName.find("Makefiles") == std::string::npos &&
- genName.find("Ninja") == std::string::npos &&
- genName.find("Watcom WMake") == std::string::npos) {
- reportError(
- context, content->GetOriginalExpression(),
- "$<COMPILE_LANGUAGE:...> not supported for this generator.");
- return std::string();
- }
+ if (genName.find("Makefiles") == std::string::npos &&
+ genName.find("Ninja") == std::string::npos &&
+ genName.find("Visual Studio") == std::string::npos &&
+ genName.find("Xcode") == std::string::npos &&
+ genName.find("Watcom WMake") == std::string::npos) {
+ reportError(context, content->GetOriginalExpression(),
+ "$<COMPILE_LANGUAGE:...> not supported for this generator.");
+ return std::string();
}
if (parameters.empty()) {
return context->Language;
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index 338c2b4..bd51f60 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -1703,6 +1703,7 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt,
gtgt->GetName().c_str());
return;
}
+ std::string const& langForPreprocessor = llang;
if (gtgt->IsIPOEnabled(llang, configName)) {
const char* ltoValue =
@@ -1723,7 +1724,10 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt,
this->AppendDefines(ppDefs, exportMacro);
}
std::vector<std::string> targetDefines;
- gtgt->GetCompileDefinitions(targetDefines, configName, "C");
+ if (!langForPreprocessor.empty()) {
+ gtgt->GetCompileDefinitions(targetDefines, configName,
+ langForPreprocessor);
+ }
this->AppendDefines(ppDefs, targetDefines);
buildSettings->AddAttribute("GCC_PREPROCESSOR_DEFINITIONS",
ppDefs.CreateList());
@@ -1996,8 +2000,10 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt,
const bool emitSystemIncludes = this->XcodeVersion >= 83;
std::vector<std::string> includes;
- this->CurrentLocalGenerator->GetIncludeDirectories(includes, gtgt, "C",
- configName);
+ if (!langForPreprocessor.empty()) {
+ this->CurrentLocalGenerator->GetIncludeDirectories(
+ includes, gtgt, langForPreprocessor, configName);
+ }
std::set<std::string> emitted;
emitted.insert("/System/Library/Frameworks");
diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx
index eccd4d0..59c20a9 100644
--- a/Source/cmLocalVisualStudio7Generator.cxx
+++ b/Source/cmLocalVisualStudio7Generator.cxx
@@ -637,7 +637,8 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(
configType = projectType;
}
std::string flags;
- if (strcmp(configType, "10") != 0) {
+ std::string langForClCompile;
+ if (target->GetType() <= cmStateEnums::OBJECT_LIBRARY) {
const std::string& linkLanguage =
(this->FortranProject ? std::string("Fortran")
: target->GetLinkerLanguage(configName));
@@ -647,10 +648,11 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(
target->GetName().c_str());
return;
}
- if (linkLanguage == "C" || linkLanguage == "CXX" ||
- linkLanguage == "Fortran") {
+ langForClCompile = linkLanguage;
+ if (langForClCompile == "C" || langForClCompile == "CXX" ||
+ langForClCompile == "Fortran") {
std::string baseFlagVar = "CMAKE_";
- baseFlagVar += linkLanguage;
+ baseFlagVar += langForClCompile;
baseFlagVar += "_FLAGS";
flags = this->Makefile->GetRequiredDefinition(baseFlagVar.c_str());
std::string flagVar =
@@ -667,7 +669,7 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(
}
// Add the target-specific flags.
- this->AddCompileOptions(flags, target, linkLanguage, configName);
+ this->AddCompileOptions(flags, target, langForClCompile, configName);
// Check IPO related warning/error.
target->IsIPOEnabled(linkLanguage, configName);
@@ -703,7 +705,9 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(
targetOptions.Parse(defineFlags.c_str());
targetOptions.ParseFinish();
std::vector<std::string> targetDefines;
- target->GetCompileDefinitions(targetDefines, configName, "CXX");
+ if (!langForClCompile.empty()) {
+ target->GetCompileDefinitions(targetDefines, configName, langForClCompile);
+ }
targetOptions.AddDefines(targetDefines);
targetOptions.SetVerboseMakefile(
this->Makefile->IsOn("CMAKE_VERBOSE_MAKEFILE"));
@@ -792,10 +796,13 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(
<< "\\$(ConfigurationName)\"\n";
}
fout << "\t\t\t\tAdditionalIncludeDirectories=\"";
- std::vector<std::string> includes;
- this->GetIncludeDirectories(includes, target, "C", configName);
- std::vector<std::string>::iterator i = includes.begin();
- for (; i != includes.end(); ++i) {
+ std::vector<std::string> includes_cl;
+ if (!langForClCompile.empty()) {
+ this->GetIncludeDirectories(includes_cl, target, langForClCompile,
+ configName);
+ }
+ std::vector<std::string>::iterator i = includes_cl.begin();
+ for (; i != includes_cl.end(); ++i) {
// output the include path
std::string ipath = this->ConvertToXMLOutputPath(i->c_str());
fout << ipath << ";";
@@ -810,7 +817,8 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(
}
fout << "\"\n";
targetOptions.OutputFlagMap(fout, "\t\t\t\t");
- targetOptions.OutputPreprocessorDefinitions(fout, "\t\t\t\t", "\n", "CXX");
+ targetOptions.OutputPreprocessorDefinitions(fout, "\t\t\t\t", "\n",
+ langForClCompile);
fout << "\t\t\t\tObjectFile=\"$(IntDir)\\\"\n";
if (target->GetType() <= cmStateEnums::OBJECT_LIBRARY) {
// Specify the compiler program database file if configured.
@@ -829,9 +837,12 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(
"\t\t\t\tName=\"MASM\"\n"
"\t\t\t\tIncludePaths=\""
;
+ std::vector<std::string> includes_masm;
+ this->GetIncludeDirectories(includes_masm, target, "ASM_MASM",
+ configName);
/* clang-format on */
const char* sep = "";
- for (i = includes.begin(); i != includes.end(); ++i) {
+ for (i = includes_masm.begin(); i != includes_masm.end(); ++i) {
std::string inc = *i;
cmConvertToWindowsSlash(inc);
fout << sep << this->EscapeForXML(inc);
@@ -859,7 +870,9 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(
}
fout << "\t\t\t<Tool\n\t\t\t\tName=\"" << tool << "\"\n"
<< "\t\t\t\tAdditionalIncludeDirectories=\"";
- for (i = includes.begin(); i != includes.end(); ++i) {
+ std::vector<std::string> includes_rc;
+ this->GetIncludeDirectories(includes_rc, target, "RC", configName);
+ for (i = includes_rc.begin(); i != includes_rc.end(); ++i) {
std::string ipath = this->ConvertToXMLOutputPath(i->c_str());
fout << ipath << ";";
}
@@ -873,7 +886,9 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(
}
fout << "\t\t\t<Tool\n\t\t\t\tName=\"" << tool << "\"\n";
fout << "\t\t\t\tAdditionalIncludeDirectories=\"";
- for (i = includes.begin(); i != includes.end(); ++i) {
+ std::vector<std::string> includes_midl;
+ this->GetIncludeDirectories(includes_midl, target, "MIDL", configName);
+ for (i = includes_midl.begin(); i != includes_midl.end(); ++i) {
std::string ipath = this->ConvertToXMLOutputPath(i->c_str());
fout << ipath << ";";
}
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index 1a728c2..eeeb54f 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -855,7 +855,7 @@ cmSourceFile* cmMakefile::AddCustomCommandToOutput(
std::string outName = gg->GenerateRuleFile(outputs[0]);
// Check if the rule file already exists.
- file = this->GetSource(outName);
+ file = this->GetSource(outName, cmSourceFileLocationKind::Known);
if (file && file->GetCustomCommand() && !replace) {
// The rule file already exists.
if (commandLines != file->GetCustomCommand()->GetCommandLines()) {
@@ -868,19 +868,22 @@ cmSourceFile* cmMakefile::AddCustomCommandToOutput(
// Create a cmSourceFile for the rule file.
if (!file) {
- file = this->CreateSource(outName, true);
+ file =
+ this->CreateSource(outName, true, cmSourceFileLocationKind::Known);
}
file->SetProperty("__CMAKE_RULE", "1");
}
// Always create the output sources and mark them generated.
for (std::string const& o : outputs) {
- if (cmSourceFile* out = this->GetOrCreateSource(o, true)) {
+ if (cmSourceFile* out =
+ this->GetOrCreateSource(o, true, cmSourceFileLocationKind::Known)) {
out->SetProperty("GENERATED", "1");
}
}
for (std::string const& o : byproducts) {
- if (cmSourceFile* out = this->GetOrCreateSource(o, true)) {
+ if (cmSourceFile* out =
+ this->GetOrCreateSource(o, true, cmSourceFileLocationKind::Known)) {
out->SetProperty("GENERATED", "1");
}
}
@@ -1092,7 +1095,8 @@ cmTarget* cmMakefile::AddUtilityCommand(
// Always create the byproduct sources and mark them generated.
for (std::string const& byproduct : byproducts) {
- if (cmSourceFile* out = this->GetOrCreateSource(byproduct, true)) {
+ if (cmSourceFile* out = this->GetOrCreateSource(
+ byproduct, true, cmSourceFileLocationKind::Known)) {
out->SetProperty("GENERATED", "1");
}
}
@@ -3131,9 +3135,10 @@ void cmMakefile::SetArgcArgv(const std::vector<std::string>& args)
}
}
-cmSourceFile* cmMakefile::GetSource(const std::string& sourceName) const
+cmSourceFile* cmMakefile::GetSource(const std::string& sourceName,
+ cmSourceFileLocationKind kind) const
{
- cmSourceFileLocation sfl(this, sourceName);
+ cmSourceFileLocation sfl(this, sourceName, kind);
auto name = this->GetCMakeInstance()->StripExtension(sfl.GetName());
#if defined(_WIN32) || defined(__APPLE__)
name = cmSystemTools::LowerCase(name);
@@ -3150,9 +3155,10 @@ cmSourceFile* cmMakefile::GetSource(const std::string& sourceName) const
}
cmSourceFile* cmMakefile::CreateSource(const std::string& sourceName,
- bool generated)
+ bool generated,
+ cmSourceFileLocationKind kind)
{
- cmSourceFile* sf = new cmSourceFile(this, sourceName);
+ cmSourceFile* sf = new cmSourceFile(this, sourceName, kind);
if (generated) {
sf->SetProperty("GENERATED", "1");
}
@@ -3169,12 +3175,13 @@ cmSourceFile* cmMakefile::CreateSource(const std::string& sourceName,
}
cmSourceFile* cmMakefile::GetOrCreateSource(const std::string& sourceName,
- bool generated)
+ bool generated,
+ cmSourceFileLocationKind kind)
{
- if (cmSourceFile* esf = this->GetSource(sourceName)) {
+ if (cmSourceFile* esf = this->GetSource(sourceName, kind)) {
return esf;
}
- return this->CreateSource(sourceName, generated);
+ return this->CreateSource(sourceName, generated, kind);
}
void cmMakefile::AddTargetObject(std::string const& tgtName,
diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h
index c92424b..f06e2ff 100644
--- a/Source/cmMakefile.h
+++ b/Source/cmMakefile.h
@@ -20,6 +20,7 @@
#include "cmListFileCache.h"
#include "cmNewLineStyle.h"
#include "cmPolicies.h"
+#include "cmSourceFileLocationKind.h"
#include "cmStateSnapshot.h"
#include "cmStateTypes.h"
#include "cmTarget.h"
@@ -387,22 +388,26 @@ public:
/** Get a cmSourceFile pointer for a given source name, if the name is
* not found, then a null pointer is returned.
*/
- cmSourceFile* GetSource(const std::string& sourceName) const;
+ cmSourceFile* GetSource(
+ const std::string& sourceName,
+ cmSourceFileLocationKind kind = cmSourceFileLocationKind::Ambiguous) const;
/** Create the source file and return it. generated
* indicates if it is a generated file, this is used in determining
* how to create the source file instance e.g. name
*/
- cmSourceFile* CreateSource(const std::string& sourceName,
- bool generated = false);
+ cmSourceFile* CreateSource(
+ const std::string& sourceName, bool generated = false,
+ cmSourceFileLocationKind kind = cmSourceFileLocationKind::Ambiguous);
/** Get a cmSourceFile pointer for a given source name, if the name is
* not found, then create the source file and return it. generated
* indicates if it is a generated file, this is used in determining
* how to create the source file instance e.g. name
*/
- cmSourceFile* GetOrCreateSource(const std::string& sourceName,
- bool generated = false);
+ cmSourceFile* GetOrCreateSource(
+ const std::string& sourceName, bool generated = false,
+ cmSourceFileLocationKind kind = cmSourceFileLocationKind::Ambiguous);
void AddTargetObject(std::string const& tgtName, std::string const& objFile);
diff --git a/Source/cmQtAutoGeneratorInitializer.cxx b/Source/cmQtAutoGeneratorInitializer.cxx
index 14743de..de0ba4f 100644
--- a/Source/cmQtAutoGeneratorInitializer.cxx
+++ b/Source/cmQtAutoGeneratorInitializer.cxx
@@ -475,10 +475,16 @@ void cmQtAutoGeneratorInitializer::InitCustomTargets()
}
// Read skip files from makefile sources
if (this->MocEnabled || this->UicEnabled) {
- const std::vector<cmSourceFile*>& allSources = makefile->GetSourceFiles();
- for (cmSourceFile* sf : allSources) {
+ std::string pathError;
+ for (cmSourceFile* sf : makefile->GetSourceFiles()) {
// sf->GetExtension() is only valid after sf->GetFullPath() ...
- std::string const& fPath = sf->GetFullPath();
+ // Since we're iterating over source files that might be not in the
+ // target we need to check for path errors (not existing files).
+ std::string const& fPath = sf->GetFullPath(&pathError);
+ if (!pathError.empty()) {
+ pathError.clear();
+ continue;
+ }
cmSystemTools::FileFormat const fileType =
cmSystemTools::GetFileFormat(sf->GetExtension().c_str());
if (!(fileType == cmSystemTools::CXX_FILE_FORMAT) &&
@@ -1188,9 +1194,16 @@ void cmQtAutoGeneratorInitializer::SetupCustomTargetsUic()
std::vector<std::vector<std::string>> uiFileOptions;
{
std::string const uiExt = "ui";
+ std::string pathError;
for (cmSourceFile* sf : makefile->GetSourceFiles()) {
// sf->GetExtension() is only valid after sf->GetFullPath() ...
- std::string const& fPath = sf->GetFullPath();
+ // Since we're iterating over source files that might be not in the
+ // target we need to check for path errors (not existing files).
+ std::string const& fPath = sf->GetFullPath(&pathError);
+ if (!pathError.empty()) {
+ pathError.clear();
+ continue;
+ }
if (sf->GetExtension() == uiExt) {
std::string const absFile = cmSystemTools::GetRealPath(fPath);
// Check if the .ui file should be skipped
diff --git a/Source/cmSourceFile.cxx b/Source/cmSourceFile.cxx
index d5475d2..215f974 100644
--- a/Source/cmSourceFile.cxx
+++ b/Source/cmSourceFile.cxx
@@ -12,8 +12,9 @@
#include "cmSystemTools.h"
#include "cmake.h"
-cmSourceFile::cmSourceFile(cmMakefile* mf, const std::string& name)
- : Location(mf, name)
+cmSourceFile::cmSourceFile(cmMakefile* mf, const std::string& name,
+ cmSourceFileLocationKind kind)
+ : Location(mf, name, kind)
{
this->CustomCommand = nullptr;
this->FindFullPathFailed = false;
diff --git a/Source/cmSourceFile.h b/Source/cmSourceFile.h
index da722ea..1516d98 100644
--- a/Source/cmSourceFile.h
+++ b/Source/cmSourceFile.h
@@ -7,6 +7,7 @@
#include "cmPropertyMap.h"
#include "cmSourceFileLocation.h"
+#include "cmSourceFileLocationKind.h"
#include <string>
#include <vector>
@@ -27,7 +28,9 @@ public:
* Construct with the makefile storing the source and the initial
* name referencing it.
*/
- cmSourceFile(cmMakefile* mf, const std::string& name);
+ cmSourceFile(
+ cmMakefile* mf, const std::string& name,
+ cmSourceFileLocationKind kind = cmSourceFileLocationKind::Ambiguous);
~cmSourceFile();
diff --git a/Source/cmSourceFileLocation.cxx b/Source/cmSourceFileLocation.cxx
index 6add7b3..5558ef3 100644
--- a/Source/cmSourceFileLocation.cxx
+++ b/Source/cmSourceFileLocation.cxx
@@ -27,7 +27,8 @@ cmSourceFileLocation::cmSourceFileLocation(const cmSourceFileLocation& loc)
}
cmSourceFileLocation::cmSourceFileLocation(cmMakefile const* mf,
- const std::string& name)
+ const std::string& name,
+ cmSourceFileLocationKind kind)
: Makefile(mf)
{
this->AmbiguousDirectory = !cmSystemTools::FileIsFullPath(name.c_str());
@@ -37,7 +38,12 @@ cmSourceFileLocation::cmSourceFileLocation(cmMakefile const* mf,
this->Directory = cmSystemTools::CollapseFullPath(this->Directory);
}
this->Name = cmSystemTools::GetFilenameName(name);
- this->UpdateExtension(name);
+ if (kind == cmSourceFileLocationKind::Known) {
+ this->DirectoryUseSource();
+ this->AmbiguousExtension = false;
+ } else {
+ this->UpdateExtension(name);
+ }
}
void cmSourceFileLocation::Update(cmSourceFileLocation const& loc)
diff --git a/Source/cmSourceFileLocation.h b/Source/cmSourceFileLocation.h
index a6819bd..f325e54 100644
--- a/Source/cmSourceFileLocation.h
+++ b/Source/cmSourceFileLocation.h
@@ -7,6 +7,8 @@
#include <string>
+#include "cmSourceFileLocationKind.h"
+
class cmMakefile;
/** \class cmSourceFileLocation
@@ -26,7 +28,9 @@ public:
* Construct for a source file created in a given cmMakefile
* instance with an initial name.
*/
- cmSourceFileLocation(cmMakefile const* mf, const std::string& name);
+ cmSourceFileLocation(
+ cmMakefile const* mf, const std::string& name,
+ cmSourceFileLocationKind kind = cmSourceFileLocationKind::Ambiguous);
cmSourceFileLocation();
cmSourceFileLocation(const cmSourceFileLocation& loc);
diff --git a/Source/cmSourceFileLocationKind.h b/Source/cmSourceFileLocationKind.h
new file mode 100644
index 0000000..dd4c6dd
--- /dev/null
+++ b/Source/cmSourceFileLocationKind.h
@@ -0,0 +1,15 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#ifndef cmSourceFileLocationKind_h
+#define cmSourceFileLocationKind_h
+
+enum class cmSourceFileLocationKind
+{
+ // The location is user-specified and may be ambiguous.
+ Ambiguous,
+ // The location is known to be at the given location; do not try to guess at
+ // extensions or absolute path.
+ Known
+};
+
+#endif
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index de23b08..1974be3 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -23,6 +23,7 @@
#include "cmProperty.h"
#include "cmSourceFile.h"
#include "cmSourceFileLocation.h"
+#include "cmSourceFileLocationKind.h"
#include "cmState.h"
#include "cmStateDirectory.h"
#include "cmStateSnapshot.h"
@@ -606,7 +607,8 @@ public:
cmSourceFile* cmTarget::AddSource(const std::string& src)
{
- cmSourceFileLocation sfl(this->Makefile, src);
+ cmSourceFileLocation sfl(this->Makefile, src,
+ cmSourceFileLocationKind::Known);
if (std::find_if(this->Internal->SourceEntries.begin(),
this->Internal->SourceEntries.end(),
TargetPropertyEntryFinder(sfl)) ==
@@ -618,7 +620,8 @@ cmSourceFile* cmTarget::AddSource(const std::string& src)
if (cmGeneratorExpression::Find(src) != std::string::npos) {
return nullptr;
}
- return this->Makefile->GetOrCreateSource(src);
+ return this->Makefile->GetOrCreateSource(src, false,
+ cmSourceFileLocationKind::Known);
}
void cmTarget::AddLinkDirectory(const std::string& d)
diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index f997a11..6d81f95 100644
--- a/Source/cmVisualStudio10TargetGenerator.cxx
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -2319,6 +2319,18 @@ void cmVisualStudio10TargetGenerator::OutputLinkIncremental(
}
}
+std::vector<std::string> cmVisualStudio10TargetGenerator::GetIncludes(
+ std::string const& config, std::string const& lang) const
+{
+ std::vector<std::string> includes;
+ this->LocalGenerator->GetIncludeDirectories(includes, this->GeneratorTarget,
+ lang, config);
+ for (std::string& i : includes) {
+ this->ConvertToWindowsSlash(i);
+ }
+ return includes;
+}
+
bool cmVisualStudio10TargetGenerator::ComputeClOptions()
{
for (std::string const& i : this->Configurations) {
@@ -2379,6 +2391,7 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions(
}
}
}
+ this->LangForClCompile = langForClCompile;
if (!langForClCompile.empty()) {
std::string baseFlagVar = "CMAKE_";
baseFlagVar += langForClCompile;
@@ -2422,8 +2435,10 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions(
std::vector<std::string> targetDefines;
switch (this->ProjectType) {
case vcxproj:
- this->GeneratorTarget->GetCompileDefinitions(targetDefines, configName,
- "CXX");
+ if (!langForClCompile.empty()) {
+ this->GeneratorTarget->GetCompileDefinitions(targetDefines, configName,
+ langForClCompile);
+ }
break;
case csproj:
this->GeneratorTarget->GetCompileDefinitions(targetDefines, configName,
@@ -2487,7 +2502,7 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions(
}
void cmVisualStudio10TargetGenerator::WriteClOptions(
- std::string const& configName, std::vector<std::string> const& includes)
+ std::string const& configName)
{
Options& clOptions = *(this->ClOptions[configName]);
if (this->ProjectType == csproj) {
@@ -2495,12 +2510,16 @@ void cmVisualStudio10TargetGenerator::WriteClOptions(
}
this->WriteString("<ClCompile>\n", 2);
clOptions.PrependInheritedString("AdditionalOptions");
- clOptions.AppendFlag("AdditionalIncludeDirectories", includes);
+ if (!this->LangForClCompile.empty()) {
+ std::vector<std::string> const includes =
+ this->GetIncludes(configName, this->LangForClCompile);
+ clOptions.AppendFlag("AdditionalIncludeDirectories", includes);
+ }
clOptions.AppendFlag("AdditionalIncludeDirectories",
"%(AdditionalIncludeDirectories)");
clOptions.OutputFlagMap(*this->BuildFileStream, " ");
clOptions.OutputPreprocessorDefinitions(*this->BuildFileStream, " ",
- "\n", "CXX");
+ "\n", this->LangForClCompile);
if (this->NsightTegra) {
if (const char* processMax =
@@ -2581,7 +2600,7 @@ bool cmVisualStudio10TargetGenerator::ComputeRcOptions(
}
void cmVisualStudio10TargetGenerator::WriteRCOptions(
- std::string const& configName, std::vector<std::string> const& includes)
+ std::string const& configName)
{
if (!this->MSTools) {
return;
@@ -2591,6 +2610,8 @@ void cmVisualStudio10TargetGenerator::WriteRCOptions(
Options& rcOptions = *(this->RcOptions[configName]);
rcOptions.OutputPreprocessorDefinitions(*this->BuildFileStream, " ",
"\n", "RC");
+ std::vector<std::string> const includes =
+ this->GetIncludes(configName, "RC");
rcOptions.AppendFlag("AdditionalIncludeDirectories", includes);
rcOptions.AppendFlag("AdditionalIncludeDirectories",
"%(AdditionalIncludeDirectories)");
@@ -2640,6 +2661,12 @@ bool cmVisualStudio10TargetGenerator::ComputeCudaOptions(
cudaOptions.Parse(defineFlags.c_str());
cudaOptions.ParseFinish();
+ // If we haven't explicitly enabled GPU debug information
+ // explicitly disable it
+ if (!cudaOptions.HasFlag("GPUDebugInfo")) {
+ cudaOptions.AddFlag("GPUDebugInfo", "false");
+ }
+
if (this->GeneratorTarget->GetPropertyAsBool("CUDA_SEPARABLE_COMPILATION")) {
cudaOptions.AddFlag("GenerateRelocatableDeviceCode", "true");
} else if (this->GeneratorTarget->GetPropertyAsBool(
@@ -2695,7 +2722,7 @@ bool cmVisualStudio10TargetGenerator::ComputeCudaOptions(
}
void cmVisualStudio10TargetGenerator::WriteCudaOptions(
- std::string const& configName, std::vector<std::string> const& includes)
+ std::string const& configName)
{
if (!this->MSTools || !this->GlobalGenerator->IsCudaEnabled()) {
return;
@@ -2703,6 +2730,8 @@ void cmVisualStudio10TargetGenerator::WriteCudaOptions(
this->WriteString("<CudaCompile>\n", 2);
Options& cudaOptions = *(this->CudaOptions[configName]);
+ std::vector<std::string> const includes =
+ this->GetIncludes(configName, "CUDA");
cudaOptions.AppendFlag("Include", includes);
cudaOptions.AppendFlag("Include", "%(Include)");
cudaOptions.OutputPreprocessorDefinitions(*this->BuildFileStream, " ",
@@ -2817,7 +2846,7 @@ bool cmVisualStudio10TargetGenerator::ComputeMasmOptions(
}
void cmVisualStudio10TargetGenerator::WriteMasmOptions(
- std::string const& configName, std::vector<std::string> const& includes)
+ std::string const& configName)
{
if (!this->MSTools || !this->GlobalGenerator->IsMasmEnabled()) {
return;
@@ -2830,6 +2859,8 @@ void cmVisualStudio10TargetGenerator::WriteMasmOptions(
"\n", "ASM_MASM");
Options& masmOptions = *(this->MasmOptions[configName]);
+ std::vector<std::string> const includes =
+ this->GetIncludes(configName, "ASM_MASM");
masmOptions.AppendFlag("IncludePaths", includes);
masmOptions.AppendFlag("IncludePaths", "%(IncludePaths)");
masmOptions.PrependInheritedString("AdditionalOptions");
@@ -2874,13 +2905,15 @@ bool cmVisualStudio10TargetGenerator::ComputeNasmOptions(
}
void cmVisualStudio10TargetGenerator::WriteNasmOptions(
- std::string const& configName, std::vector<std::string> includes)
+ std::string const& configName)
{
if (!this->GlobalGenerator->IsNasmEnabled()) {
return;
}
this->WriteString("<NASM>\n", 2);
+ std::vector<std::string> includes =
+ this->GetIncludes(configName, "ASM_NASM");
Options& nasmOptions = *(this->NasmOptions[configName]);
for (size_t i = 0; i < includes.size(); i++) {
includes[i] += "\\";
@@ -3428,7 +3461,7 @@ void cmVisualStudio10TargetGenerator::AddTargetsFileAndConfigPair(
}
void cmVisualStudio10TargetGenerator::WriteMidlOptions(
- std::string const& /*config*/, std::vector<std::string> const& includes)
+ std::string const& configName)
{
if (!this->MSTools) {
return;
@@ -3454,6 +3487,8 @@ void cmVisualStudio10TargetGenerator::WriteMidlOptions(
// on the CMake side?
this->WriteString("<Midl>\n", 2);
this->WriteString("<AdditionalIncludeDirectories>", 3);
+ std::vector<std::string> const includes =
+ this->GetIncludes(configName, "MIDL");
for (std::string const& i : includes) {
*this->BuildFileStream << cmVS10EscapeXML(i) << ";";
}
@@ -3478,25 +3513,19 @@ void cmVisualStudio10TargetGenerator::WriteItemDefinitionGroups()
return;
}
for (std::string const& i : this->Configurations) {
- std::vector<std::string> includes;
- this->LocalGenerator->GetIncludeDirectories(includes,
- this->GeneratorTarget, "C", i);
- for (std::string& ii : includes) {
- this->ConvertToWindowsSlash(ii);
- }
this->WritePlatformConfigTag("ItemDefinitionGroup", i, 1);
*this->BuildFileStream << "\n";
// output cl compile flags <ClCompile></ClCompile>
if (this->GeneratorTarget->GetType() <= cmStateEnums::OBJECT_LIBRARY) {
- this->WriteClOptions(i, includes);
+ this->WriteClOptions(i);
// output rc compile flags <ResourceCompile></ResourceCompile>
- this->WriteRCOptions(i, includes);
- this->WriteCudaOptions(i, includes);
- this->WriteMasmOptions(i, includes);
- this->WriteNasmOptions(i, includes);
+ this->WriteRCOptions(i);
+ this->WriteCudaOptions(i);
+ this->WriteMasmOptions(i);
+ this->WriteNasmOptions(i);
}
// output midl flags <Midl></Midl>
- this->WriteMidlOptions(i, includes);
+ this->WriteMidlOptions(i);
// write events
if (this->ProjectType != csproj) {
this->WriteEvents(i);
diff --git a/Source/cmVisualStudio10TargetGenerator.h b/Source/cmVisualStudio10TargetGenerator.h
index fb24f1a..c346164 100644
--- a/Source/cmVisualStudio10TargetGenerator.h
+++ b/Source/cmVisualStudio10TargetGenerator.h
@@ -90,18 +90,18 @@ private:
void WriteTargetSpecificReferences();
void WriteTargetsFileReferences();
+ std::vector<std::string> GetIncludes(std::string const& config,
+ std::string const& lang) const;
+
bool ComputeClOptions();
bool ComputeClOptions(std::string const& configName);
- void WriteClOptions(std::string const& config,
- std::vector<std::string> const& includes);
+ void WriteClOptions(std::string const& config);
bool ComputeRcOptions();
bool ComputeRcOptions(std::string const& config);
- void WriteRCOptions(std::string const& config,
- std::vector<std::string> const& includes);
+ void WriteRCOptions(std::string const& config);
bool ComputeCudaOptions();
bool ComputeCudaOptions(std::string const& config);
- void WriteCudaOptions(std::string const& config,
- std::vector<std::string> const& includes);
+ void WriteCudaOptions(std::string const& config);
bool ComputeCudaLinkOptions();
bool ComputeCudaLinkOptions(std::string const& config);
@@ -109,20 +109,17 @@ private:
bool ComputeMasmOptions();
bool ComputeMasmOptions(std::string const& config);
- void WriteMasmOptions(std::string const& config,
- std::vector<std::string> const& includes);
+ void WriteMasmOptions(std::string const& config);
bool ComputeNasmOptions();
bool ComputeNasmOptions(std::string const& config);
- void WriteNasmOptions(std::string const& config,
- std::vector<std::string> includes);
+ void WriteNasmOptions(std::string const& config);
bool ComputeLinkOptions();
bool ComputeLinkOptions(std::string const& config);
bool ComputeLibOptions();
bool ComputeLibOptions(std::string const& config);
void WriteLinkOptions(std::string const& config);
- void WriteMidlOptions(std::string const& config,
- std::vector<std::string> const& includes);
+ void WriteMidlOptions(std::string const& config);
void WriteAntBuildOptions(std::string const& config);
void OutputLinkIncremental(std::string const& configName);
void WriteCustomRule(cmSourceFile const* source,
@@ -180,6 +177,7 @@ private:
OptionsMap MasmOptions;
OptionsMap NasmOptions;
OptionsMap LinkOptions;
+ std::string LangForClCompile;
std::string PathToProjectFile;
std::string ProjectFileExtension;
enum VsProjectType
diff --git a/Source/cmVisualStudioGeneratorOptions.cxx b/Source/cmVisualStudioGeneratorOptions.cxx
index 9a5986c..106bdff 100644
--- a/Source/cmVisualStudioGeneratorOptions.cxx
+++ b/Source/cmVisualStudioGeneratorOptions.cxx
@@ -239,20 +239,32 @@ void cmVisualStudioGeneratorOptions::FixCudaCodeGeneration()
// It translates to -arch=<virtual> -code=<real>.
cmSystemTools::ReplaceString(arch_name, "sm_", "compute_");
}
- for (std::vector<std::string>::iterator ci = codes.begin();
- ci != codes.end(); ++ci) {
- std::string entry = arch_name + "," + *ci;
+ for (auto const& c : codes) {
+ std::string entry = arch_name + "," + c;
result.push_back(entry);
}
}
- // Now add entries for the -gencode=<arch>,<code> pairs.
- for (std::vector<std::string>::iterator ei = gencode.begin();
- ei != gencode.end(); ++ei) {
- std::string entry = *ei;
+ // Now add entries for the following signatures:
+ // -gencode=<arch>,<code>
+ // -gencode=<arch>,[<code1>,<code2>]
+ // -gencode=<arch>,"<code1>,<code2>"
+ for (auto const& e : gencode) {
+ std::string entry = e;
cmSystemTools::ReplaceString(entry, "arch=", "");
cmSystemTools::ReplaceString(entry, "code=", "");
- result.push_back(entry);
+ cmSystemTools::ReplaceString(entry, "[", "");
+ cmSystemTools::ReplaceString(entry, "]", "");
+ cmSystemTools::ReplaceString(entry, "\"", "");
+
+ std::vector<std::string> codes = cmSystemTools::tokenize(entry, ",");
+ if (codes.size() >= 2) {
+ auto gencode_arch = cm::cbegin(codes);
+ for (auto ci = gencode_arch + 1; ci != cm::cend(codes); ++ci) {
+ std::string code_entry = *gencode_arch + "," + *ci;
+ result.push_back(code_entry);
+ }
+ }
}
}
diff --git a/Tests/CMakeCommands/target_compile_definitions/CMakeLists.txt b/Tests/CMakeCommands/target_compile_definitions/CMakeLists.txt
index f96283d..7dc7995 100644
--- a/Tests/CMakeCommands/target_compile_definitions/CMakeLists.txt
+++ b/Tests/CMakeCommands/target_compile_definitions/CMakeLists.txt
@@ -26,18 +26,18 @@ target_compile_definitions(consumer
PRIVATE
)
-if (CMAKE_GENERATOR MATCHES "Makefiles" OR CMAKE_GENERATOR MATCHES "Ninja")
- target_sources(consumer PRIVATE
- "${CMAKE_CURRENT_SOURCE_DIR}/consumer.c"
- )
- target_compile_definitions(consumer
- PRIVATE
- CONSUMER_LANG_$<COMPILE_LANGUAGE>
- LANG_IS_CXX=$<COMPILE_LANGUAGE:CXX>
- LANG_IS_C=$<COMPILE_LANGUAGE:C>
- )
+target_sources(consumer PRIVATE
+ "${CMAKE_CURRENT_SOURCE_DIR}/consumer.c"
+)
+target_compile_definitions(consumer
+ PRIVATE
+ CONSUMER_LANG_$<COMPILE_LANGUAGE>
+ LANG_IS_CXX=$<COMPILE_LANGUAGE:CXX>
+ LANG_IS_C=$<COMPILE_LANGUAGE:C>
+)
+if(CMAKE_GENERATOR MATCHES "Visual Studio|Xcode")
target_compile_definitions(consumer
- PRIVATE -DTEST_LANG_DEFINES
+ PRIVATE TEST_LANG_DEFINES_FOR_VISUAL_STUDIO_OR_XCODE
)
endif()
diff --git a/Tests/CMakeCommands/target_compile_definitions/consumer.c b/Tests/CMakeCommands/target_compile_definitions/consumer.c
index 7931a6f..e134a8b 100644
--- a/Tests/CMakeCommands/target_compile_definitions/consumer.c
+++ b/Tests/CMakeCommands/target_compile_definitions/consumer.c
@@ -1,5 +1,23 @@
-#ifdef TEST_LANG_DEFINES
+// Visual Studio allows only one set of flags for C and C++.
+// In a target using C++ we pick the C++ flags even for C sources.
+#ifdef TEST_LANG_DEFINES_FOR_VISUAL_STUDIO_OR_XCODE
+#ifndef CONSUMER_LANG_CXX
+#error Expected CONSUMER_LANG_CXX
+#endif
+
+#ifdef CONSUMER_LANG_C
+#error Unexpected CONSUMER_LANG_C
+#endif
+
+#if !LANG_IS_CXX
+#error Expected LANG_IS_CXX
+#endif
+
+#if LANG_IS_C
+#error Unexpected LANG_IS_C
+#endif
+#else
#ifdef CONSUMER_LANG_CXX
#error Unexpected CONSUMER_LANG_CXX
#endif
diff --git a/Tests/CMakeCommands/target_compile_definitions/consumer.cpp b/Tests/CMakeCommands/target_compile_definitions/consumer.cpp
index 0202c17..69ea151 100644
--- a/Tests/CMakeCommands/target_compile_definitions/consumer.cpp
+++ b/Tests/CMakeCommands/target_compile_definitions/consumer.cpp
@@ -15,7 +15,6 @@
#error Expected DASH_D_DEFINE
#endif
-#ifdef TEST_LANG_DEFINES
#ifndef CONSUMER_LANG_CXX
#error Expected CONSUMER_LANG_CXX
#endif
@@ -31,7 +30,6 @@
#if LANG_IS_C
#error Unexpected LANG_IS_C
#endif
-#endif
int main()
{
diff --git a/Tests/CMakeCommands/target_include_directories/CMakeLists.txt b/Tests/CMakeCommands/target_include_directories/CMakeLists.txt
index d57556a..8713d99 100644
--- a/Tests/CMakeCommands/target_include_directories/CMakeLists.txt
+++ b/Tests/CMakeCommands/target_include_directories/CMakeLists.txt
@@ -42,17 +42,17 @@ add_executable(consumer
"${CMAKE_CURRENT_SOURCE_DIR}/consumer.cpp"
)
-if (CMAKE_GENERATOR MATCHES "Makefiles" OR CMAKE_GENERATOR MATCHES "Ninja")
- target_sources(consumer PRIVATE
- "${CMAKE_CURRENT_SOURCE_DIR}/consumer.c"
- )
- target_include_directories(consumer
- PRIVATE
- $<$<COMPILE_LANGUAGE:CXX>:${CMAKE_CURRENT_SOURCE_DIR}/cxx_only>
- $<$<COMPILE_LANGUAGE:C>:${CMAKE_CURRENT_SOURCE_DIR}/c_only>
- )
+target_sources(consumer PRIVATE
+ "${CMAKE_CURRENT_SOURCE_DIR}/consumer.c"
+)
+target_include_directories(consumer
+ PRIVATE
+ $<$<COMPILE_LANGUAGE:CXX>:${CMAKE_CURRENT_SOURCE_DIR}/cxx_only>
+ $<$<COMPILE_LANGUAGE:C>:${CMAKE_CURRENT_SOURCE_DIR}/c_only>
+)
+if(CMAKE_GENERATOR MATCHES "Visual Studio|Xcode")
target_compile_definitions(consumer
- PRIVATE -DTEST_LANG_DEFINES
+ PRIVATE TEST_LANG_DEFINES_FOR_VISUAL_STUDIO_OR_XCODE
)
endif()
diff --git a/Tests/CMakeCommands/target_include_directories/consumer.c b/Tests/CMakeCommands/target_include_directories/consumer.c
index ae88f92..419c2d2 100644
--- a/Tests/CMakeCommands/target_include_directories/consumer.c
+++ b/Tests/CMakeCommands/target_include_directories/consumer.c
@@ -1,5 +1,13 @@
-#ifdef TEST_LANG_DEFINES
+// Visual Studio allows only one set of flags for C and C++.
+// In a target using C++ we pick the C++ flags even for C sources.
+#ifdef TEST_LANG_DEFINES_FOR_VISUAL_STUDIO_OR_XCODE
+#include "cxx_only.h"
+
+#ifndef CXX_ONLY_DEFINE
+#error Expected CXX_ONLY_DEFINE
+#endif
+#else
#include "c_only.h"
#ifndef C_ONLY_DEFINE
diff --git a/Tests/CMakeCommands/target_include_directories/consumer.cpp b/Tests/CMakeCommands/target_include_directories/consumer.cpp
index 0f8153b..1e018ad 100644
--- a/Tests/CMakeCommands/target_include_directories/consumer.cpp
+++ b/Tests/CMakeCommands/target_include_directories/consumer.cpp
@@ -1,12 +1,10 @@
#include "consumer.h"
#include "common.h"
+#include "cxx_only.h"
#include "interfaceinclude.h"
#include "publicinclude.h"
#include "relative_dir.h"
-#ifdef TEST_LANG_DEFINES
-#include "cxx_only.h"
-#endif
#ifdef PRIVATEINCLUDE_DEFINE
#error Unexpected PRIVATEINCLUDE_DEFINE
@@ -32,11 +30,9 @@
#error Expected CONSUMER_DEFINE
#endif
-#ifdef TEST_LANG_DEFINES
#ifndef CXX_ONLY_DEFINE
#error Expected CXX_ONLY_DEFINE
#endif
-#endif
int main()
{
diff --git a/Tests/CMakeLib/CMakeLists.txt b/Tests/CMakeLib/CMakeLists.txt
index 9f09185..06df53f 100644
--- a/Tests/CMakeLib/CMakeLists.txt
+++ b/Tests/CMakeLib/CMakeLists.txt
@@ -5,21 +5,21 @@ include_directories(
)
set(CMakeLib_TESTS
- testGeneratedFileStream
- testRST
- testSystemTools
- testUTF8
- testXMLParser
- testXMLSafe
- testFindPackageCommand
- testUVRAII
+ testGeneratedFileStream.cxx
+ testRST.cxx
+ testSystemTools.cxx
+ testUTF8.cxx
+ testXMLParser.cxx
+ testXMLSafe.cxx
+ testFindPackageCommand.cxx
+ testUVRAII.cxx
)
set(testRST_ARGS ${CMAKE_CURRENT_SOURCE_DIR})
if(WIN32)
list(APPEND CMakeLib_TESTS
- testVisualStudioSlnParser
+ testVisualStudioSlnParser.cxx
)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/testVisualStudioSlnParser.h.in
${CMAKE_CURRENT_BINARY_DIR}/testVisualStudioSlnParser.h @ONLY)
@@ -38,7 +38,8 @@ set_property(TARGET CMakeLibTests PROPERTY CXX_CLANG_TIDY "")
add_executable(testEncoding testEncoding.cxx)
target_link_libraries(testEncoding cmsys)
-foreach(test ${CMakeLib_TESTS})
+foreach(testfile ${CMakeLib_TESTS})
+ get_filename_component(test "${testfile}" NAME_WE)
add_test(CMakeLib.${test} CMakeLibTests ${test} ${${test}_ARGS})
endforeach()
diff --git a/Tests/CMakeServerLib/CMakeLists.txt b/Tests/CMakeServerLib/CMakeLists.txt
index 5e1ad0c..2c23c2d 100644
--- a/Tests/CMakeServerLib/CMakeLists.txt
+++ b/Tests/CMakeServerLib/CMakeLists.txt
@@ -5,7 +5,7 @@ include_directories(
)
set(CMakeServerLib_TESTS
- testServerBuffering
+ testServerBuffering.cpp
)
create_test_sourcelist(CMakeLib_TEST_SRCS CMakeServerLibTests.cxx ${CMakeServerLib_TESTS})
@@ -15,6 +15,7 @@ target_link_libraries(CMakeServerLibTests CMakeLib CMakeServerLib)
SET_PROPERTY(TARGET CMakeServerLibTests PROPERTY C_CLANG_TIDY "")
SET_PROPERTY(TARGET CMakeServerLibTests PROPERTY CXX_CLANG_TIDY "")
-foreach(test ${CMakeServerLib_TESTS})
+foreach(testfile ${CMakeServerLib_TESTS})
+ get_filename_component(test "${testfile}" NAME_WE)
add_test(CMakeServerLib.${test} CMakeServerLibTests ${test} ${${test}_ARGS})
endforeach()
diff --git a/Tests/CudaOnly/CMakeLists.txt b/Tests/CudaOnly/CMakeLists.txt
index 5f456fc..5ad6e6b 100644
--- a/Tests/CudaOnly/CMakeLists.txt
+++ b/Tests/CudaOnly/CMakeLists.txt
@@ -1,6 +1,7 @@
ADD_TEST_MACRO(CudaOnly.EnableStandard CudaOnlyEnableStandard)
ADD_TEST_MACRO(CudaOnly.ExportPTX CudaOnlyExportPTX)
+ADD_TEST_MACRO(CudaOnly.GPUDebugFlag CudaOnlyGPUDebugFlag)
+ADD_TEST_MACRO(CudaOnly.ResolveDeviceSymbols CudaOnlyResolveDeviceSymbols)
ADD_TEST_MACRO(CudaOnly.SeparateCompilation CudaOnlySeparateCompilation)
ADD_TEST_MACRO(CudaOnly.WithDefs CudaOnlyWithDefs)
-ADD_TEST_MACRO(CudaOnly.ResolveDeviceSymbols CudaOnlyResolveDeviceSymbols)
diff --git a/Tests/CudaOnly/GPUDebugFlag/CMakeLists.txt b/Tests/CudaOnly/GPUDebugFlag/CMakeLists.txt
new file mode 100644
index 0000000..5b96906
--- /dev/null
+++ b/Tests/CudaOnly/GPUDebugFlag/CMakeLists.txt
@@ -0,0 +1,23 @@
+
+cmake_minimum_required(VERSION 3.7)
+project (CudaOnlGPUDebugFlag CUDA)
+
+#Goal for this example:
+#verify that -G enables gpu debug flags
+string(APPEND CMAKE_CUDA_FLAGS " -gencode=arch=compute_30,code=compute_30")
+string(APPEND CMAKE_CUDA_FLAGS " -G")
+set(CMAKE_CUDA_STANDARD 11)
+
+add_executable(CudaOnlyGPUDebugFlag main.cu)
+
+if(CMAKE_CUDA_COMPILER_VERSION VERSION_LESS 9.0.0)
+ #CUDA's __CUDACC_DEBUG__ define was added in 9.0
+ #so if we are below 9.0.0 we will manually add the define so that the test
+ #passes
+ target_compile_definitions(CudaOnlyGPUDebugFlag PRIVATE "__CUDACC_DEBUG__")
+endif()
+
+if(APPLE)
+ # Help the static cuda runtime find the driver (libcuda.dyllib) at runtime.
+ set_property(TARGET CudaOnlyGPUDebugFlag PROPERTY BUILD_RPATH ${CMAKE_CUDA_IMPLICIT_LINK_DIRECTORIES})
+endif()
diff --git a/Tests/CudaOnly/GPUDebugFlag/main.cu b/Tests/CudaOnly/GPUDebugFlag/main.cu
new file mode 100644
index 0000000..8b97a3f
--- /dev/null
+++ b/Tests/CudaOnly/GPUDebugFlag/main.cu
@@ -0,0 +1,66 @@
+#include <cuda.h>
+#include <cuda_runtime.h>
+#include <iostream>
+
+static __global__ void debug_kernel(bool* has_debug)
+{
+// Verify using the return code if we have GPU debug flag enabled
+#if defined(__CUDACC__) && defined(__CUDACC_DEBUG__)
+ *has_debug = true;
+#else
+ *has_debug = false;
+#endif
+}
+
+int choose_cuda_device()
+{
+ int nDevices = 0;
+ cudaError_t err = cudaGetDeviceCount(&nDevices);
+ if (err != cudaSuccess) {
+ std::cerr << "Failed to retrieve the number of CUDA enabled devices"
+ << std::endl;
+ return 1;
+ }
+ for (int i = 0; i < nDevices; ++i) {
+ cudaDeviceProp prop;
+ cudaError_t err = cudaGetDeviceProperties(&prop, i);
+ if (err != cudaSuccess) {
+ std::cerr << "Could not retrieve properties from CUDA device " << i
+ << std::endl;
+ return 1;
+ }
+ if (prop.major >= 3) {
+ err = cudaSetDevice(i);
+ if (err != cudaSuccess) {
+ std::cout << "Could not select CUDA device " << i << std::endl;
+ } else {
+ return 0;
+ }
+ }
+ }
+
+ std::cout << "Could not find a CUDA enabled card supporting compute >=3.0"
+ << std::endl;
+
+ return 1;
+}
+
+int main(int argc, char** argv)
+{
+ bool* has_debug;
+ cudaError_t err = cudaMallocManaged(&has_debug, sizeof(bool));
+
+ debug_kernel<<<1, 1>>>(has_debug);
+ err = cudaDeviceSynchronize();
+ if (err != cudaSuccess) {
+ std::cerr << "debug_kernel: kernel launch shouldn't have failed\n"
+ << "reason:\t" << cudaGetErrorString(err) << std::endl;
+ return 1;
+ }
+ if (*has_debug == false) {
+ std::cerr << "debug_kernel: kernel not compiled with device debug"
+ << std::endl;
+ return 1;
+ }
+ return 0;
+}
diff --git a/Tests/CudaOnly/ResolveDeviceSymbols/CMakeLists.txt b/Tests/CudaOnly/ResolveDeviceSymbols/CMakeLists.txt
index 83473ae..0c453a9 100644
--- a/Tests/CudaOnly/ResolveDeviceSymbols/CMakeLists.txt
+++ b/Tests/CudaOnly/ResolveDeviceSymbols/CMakeLists.txt
@@ -21,7 +21,7 @@ endif()
# Resolve the device symbols into that static library
# Verify that we can't use those device symbols from anything that links
# to the static library
-string(APPEND CMAKE_CUDA_FLAGS " -gencode arch=compute_30,code=compute_30")
+string(APPEND CMAKE_CUDA_FLAGS " -gencode arch=compute_30,code=[compute_30] -gencode arch=compute_50,code=\\\"compute_50\\\"")
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CUDA_STANDARD 11)
diff --git a/Tests/CudaOnly/SeparateCompilation/CMakeLists.txt b/Tests/CudaOnly/SeparateCompilation/CMakeLists.txt
index cfca823..c934c51 100644
--- a/Tests/CudaOnly/SeparateCompilation/CMakeLists.txt
+++ b/Tests/CudaOnly/SeparateCompilation/CMakeLists.txt
@@ -9,7 +9,8 @@ project (CudaOnlySeparateCompilation CUDA)
#and executables.
#We complicate the matter by also testing that multiple static libraries
#all containing cuda separable compilation code links properly
-string(APPEND CMAKE_CUDA_FLAGS " -gencode arch=compute_30,code=compute_30")
+string(APPEND CMAKE_CUDA_FLAGS " -gencode arch=compute_30,code=\\\"compute_30,sm_30,sm_35\\\"")
+string(APPEND CMAKE_CUDA_FLAGS " --generate-code=arch=compute_50,code=[compute_50,sm_50,sm_52]")
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CUDA_STANDARD 11)
diff --git a/Tests/CudaOnly/WithDefs/CMakeLists.txt b/Tests/CudaOnly/WithDefs/CMakeLists.txt
index 5bd93a4..ffe4859 100644
--- a/Tests/CudaOnly/WithDefs/CMakeLists.txt
+++ b/Tests/CudaOnly/WithDefs/CMakeLists.txt
@@ -32,8 +32,8 @@ add_executable(CudaOnlyWithDefs ${main})
target_compile_options(CudaOnlyWithDefs
PRIVATE
- -DCOMPILE_LANG_$<COMPILE_LANGUAGE>
- -DLANG_IS_CUDA=$<COMPILE_LANGUAGE:CUDA>
+ -DFLAG_COMPILE_LANG_$<COMPILE_LANGUAGE>
+ -DFLAG_LANG_IS_CUDA=$<COMPILE_LANGUAGE:CUDA>
-Xcompiler=-DHOST_DEFINE
$<$<CONFIG:DEBUG>:$<BUILD_INTERFACE:${debug_compile_flags}>>
)
@@ -41,8 +41,15 @@ target_compile_options(CudaOnlyWithDefs
target_compile_definitions(CudaOnlyWithDefs
PRIVATE
$<$<CONFIG:RELEASE>:$<BUILD_INTERFACE:${release_compile_defs}>>
+ -DDEF_COMPILE_LANG_$<COMPILE_LANGUAGE>
+ -DDEF_LANG_IS_CUDA=$<COMPILE_LANGUAGE:CUDA>
)
+target_include_directories(CudaOnlyWithDefs
+ PRIVATE
+ $<$<COMPILE_LANGUAGE:CUDA>:${CMAKE_CURRENT_SOURCE_DIR}/inc_cuda>
+)
+
if(APPLE)
# Help the static cuda runtime find the driver (libcuda.dyllib) at runtime.
set_property(TARGET CudaOnlyWithDefs PROPERTY BUILD_RPATH ${CMAKE_CUDA_IMPLICIT_LINK_DIRECTORIES})
diff --git a/Tests/CudaOnly/WithDefs/inc_cuda/inc_cuda.h b/Tests/CudaOnly/WithDefs/inc_cuda/inc_cuda.h
new file mode 100644
index 0000000..e228b58
--- /dev/null
+++ b/Tests/CudaOnly/WithDefs/inc_cuda/inc_cuda.h
@@ -0,0 +1 @@
+#define INC_CUDA
diff --git a/Tests/CudaOnly/WithDefs/main.notcu b/Tests/CudaOnly/WithDefs/main.notcu
index bfb3577..3793d74 100644
--- a/Tests/CudaOnly/WithDefs/main.notcu
+++ b/Tests/CudaOnly/WithDefs/main.notcu
@@ -2,6 +2,11 @@
#include <cuda_runtime.h>
#include <iostream>
+#include <inc_cuda.h>
+#ifndef INC_CUDA
+#error "INC_CUDA not defined!"
+#endif
+
#ifndef HOST_DEFINE
#error "HOST_DEFINE not defined!"
#endif
@@ -10,16 +15,28 @@
#error "PACKED_DEFINE not defined!"
#endif
-#ifndef COMPILE_LANG_CUDA
-#error "COMPILE_LANG_CUDA not defined!"
+#ifndef FLAG_COMPILE_LANG_CUDA
+#error "FLAG_COMPILE_LANG_CUDA not defined!"
+#endif
+
+#ifndef FLAG_LANG_IS_CUDA
+#error "FLAG_LANG_IS_CUDA not defined!"
+#endif
+
+#if !FLAG_LANG_IS_CUDA
+#error "Expected FLAG_LANG_IS_CUDA"
+#endif
+
+#ifndef DEF_COMPILE_LANG_CUDA
+#error "DEF_COMPILE_LANG_CUDA not defined!"
#endif
-#ifndef LANG_IS_CUDA
-#error "LANG_IS_CUDA not defined!"
+#ifndef DEF_LANG_IS_CUDA
+#error "DEF_LANG_IS_CUDA not defined!"
#endif
-#if !LANG_IS_CUDA
-#error "Expected LANG_IS_CUDA"
+#if !DEF_LANG_IS_CUDA
+#error "Expected DEF_LANG_IS_CUDA"
#endif
static __global__ void DetermineIfValidCudaDevice()
diff --git a/Tests/FindOpenSSL/rand/main.cc b/Tests/FindOpenSSL/rand/main.cc
index d81b318..147044b 100644
--- a/Tests/FindOpenSSL/rand/main.cc
+++ b/Tests/FindOpenSSL/rand/main.cc
@@ -9,7 +9,7 @@ int main()
unsigned char buf[1024];
// random bytes
- int rezval = RAND_bytes(buf, sizeof(buf)); /* 1 succes, 0 otherwise */
+ int rezval = RAND_bytes(buf, sizeof(buf)); /* 1 success, 0 otherwise */
// check result
if (rezval == 1) {
diff --git a/Tests/GeneratorExpression/CMakeLists.txt b/Tests/GeneratorExpression/CMakeLists.txt
index 0585d0c..4586357 100644
--- a/Tests/GeneratorExpression/CMakeLists.txt
+++ b/Tests/GeneratorExpression/CMakeLists.txt
@@ -269,10 +269,8 @@ set_property(SOURCE srcgenex_flags_COMPILE_LANGUAGE.c PROPERTY COMPILE_FLAGS "$<
add_executable(srcgenex_defs srcgenex_defs.c)
set_property(SOURCE srcgenex_defs.c PROPERTY COMPILE_DEFINITIONS NAME=$<TARGET_PROPERTY:NAME>)
-if (CMAKE_GENERATOR MATCHES "Makefiles|Ninja|Watcom WMake")
- add_executable(srcgenex_defs_COMPILE_LANGUAGE srcgenex_defs_COMPILE_LANGUAGE.c)
- set_property(SOURCE srcgenex_defs_COMPILE_LANGUAGE.c PROPERTY COMPILE_DEFINITIONS $<$<COMPILE_LANGUAGE:C>:NAME=$<TARGET_PROPERTY:NAME>>)
-endif()
+add_executable(srcgenex_defs_COMPILE_LANGUAGE srcgenex_defs_COMPILE_LANGUAGE.c)
+set_property(SOURCE srcgenex_defs_COMPILE_LANGUAGE.c PROPERTY COMPILE_DEFINITIONS $<$<COMPILE_LANGUAGE:C>:NAME=$<TARGET_PROPERTY:NAME>>)
#-----------------------------------------------------------------------------
# Cover test properties with generator expressions.
diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt
index 8eb8568..edd6c79 100644
--- a/Tests/RunCMake/CMakeLists.txt
+++ b/Tests/RunCMake/CMakeLists.txt
@@ -351,8 +351,6 @@ add_RunCMake_test(IfacePaths_INCLUDE_DIRECTORIES TEST_DIR IfacePaths)
set(IfacePaths_SOURCES_ARGS -DTEST_PROP=SOURCES)
add_RunCMake_test(IfacePaths_SOURCES TEST_DIR IfacePaths)
-add_RunCMake_test(COMPILE_LANGUAGE-genex)
-
# Matlab module related tests
if(CMake_TEST_FindMatlab)
add_RunCMake_test(FindMatlab)
diff --git a/Tests/RunCMake/COMPILE_LANGUAGE-genex/CMakeLists.txt b/Tests/RunCMake/COMPILE_LANGUAGE-genex/CMakeLists.txt
deleted file mode 100644
index ef2163c..0000000
--- a/Tests/RunCMake/COMPILE_LANGUAGE-genex/CMakeLists.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-cmake_minimum_required(VERSION 3.1)
-project(${RunCMake_TEST} NONE)
-include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileDefinitions-result.txt b/Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileDefinitions-result.txt
deleted file mode 100644
index d00491f..0000000
--- a/Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileDefinitions-result.txt
+++ /dev/null
@@ -1 +0,0 @@
-1
diff --git a/Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileDefinitions-stderr-VS.txt b/Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileDefinitions-stderr-VS.txt
deleted file mode 100644
index 42c1485..0000000
--- a/Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileDefinitions-stderr-VS.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-CMake Error at CompileDefinitions.cmake:5 \(target_compile_definitions\):
- Error evaluating generator expression:
-
- \$<COMPILE_LANGUAGE:CXX>
-
- \$<COMPILE_LANGUAGE:...> may only be used for COMPILE_OPTIONS and
- file\(GENERATE\) with the Visual Studio generator.
-Call Stack \(most recent call first\):
- CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileDefinitions-stderr-Xcode.txt b/Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileDefinitions-stderr-Xcode.txt
deleted file mode 100644
index 7879a79..0000000
--- a/Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileDefinitions-stderr-Xcode.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-CMake Error at CompileDefinitions.cmake:5 \(target_compile_definitions\):
- Error evaluating generator expression:
-
- \$<COMPILE_LANGUAGE:CXX>
-
- \$<COMPILE_LANGUAGE:...> may only be used for COMPILE_OPTIONS and
- file\(GENERATE\) with the Xcode generator.
-Call Stack \(most recent call first\):
- CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileDefinitions.cmake b/Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileDefinitions.cmake
deleted file mode 100644
index 7935d88..0000000
--- a/Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileDefinitions.cmake
+++ /dev/null
@@ -1,5 +0,0 @@
-
-enable_language(CXX)
-
-add_executable(main main.cpp)
-target_compile_definitions(main PRIVATE $<$<COMPILE_LANGUAGE:CXX>:-DANYTHING>)
diff --git a/Tests/RunCMake/COMPILE_LANGUAGE-genex/IncludeDirectories-result.txt b/Tests/RunCMake/COMPILE_LANGUAGE-genex/IncludeDirectories-result.txt
deleted file mode 100644
index d00491f..0000000
--- a/Tests/RunCMake/COMPILE_LANGUAGE-genex/IncludeDirectories-result.txt
+++ /dev/null
@@ -1 +0,0 @@
-1
diff --git a/Tests/RunCMake/COMPILE_LANGUAGE-genex/IncludeDirectories-stderr-VS.txt b/Tests/RunCMake/COMPILE_LANGUAGE-genex/IncludeDirectories-stderr-VS.txt
deleted file mode 100644
index 3806ed1..0000000
--- a/Tests/RunCMake/COMPILE_LANGUAGE-genex/IncludeDirectories-stderr-VS.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-CMake Error at IncludeDirectories.cmake:5 \(target_include_directories\):
- Error evaluating generator expression:
-
- \$<COMPILE_LANGUAGE:CXX>
-
- \$<COMPILE_LANGUAGE:...> may only be used for COMPILE_OPTIONS and
- file\(GENERATE\) with the Visual Studio generator.
-Call Stack \(most recent call first\):
- CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/COMPILE_LANGUAGE-genex/IncludeDirectories-stderr-Xcode.txt b/Tests/RunCMake/COMPILE_LANGUAGE-genex/IncludeDirectories-stderr-Xcode.txt
deleted file mode 100644
index a3fb9c5..0000000
--- a/Tests/RunCMake/COMPILE_LANGUAGE-genex/IncludeDirectories-stderr-Xcode.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-CMake Error at IncludeDirectories.cmake:5 \(target_include_directories\):
- Error evaluating generator expression:
-
- \$<COMPILE_LANGUAGE:CXX>
-
- \$<COMPILE_LANGUAGE:...> may only be used for COMPILE_OPTIONS and
- file\(GENERATE\) with the Xcode generator.
-Call Stack \(most recent call first\):
- CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/COMPILE_LANGUAGE-genex/IncludeDirectories.cmake b/Tests/RunCMake/COMPILE_LANGUAGE-genex/IncludeDirectories.cmake
deleted file mode 100644
index 31771f6..0000000
--- a/Tests/RunCMake/COMPILE_LANGUAGE-genex/IncludeDirectories.cmake
+++ /dev/null
@@ -1,5 +0,0 @@
-
-enable_language(CXX)
-
-add_executable(main main.cpp)
-target_include_directories(main PRIVATE $<$<COMPILE_LANGUAGE:CXX>:anydir>)
diff --git a/Tests/RunCMake/COMPILE_LANGUAGE-genex/PerSourceCompileDefinitions-result.txt b/Tests/RunCMake/COMPILE_LANGUAGE-genex/PerSourceCompileDefinitions-result.txt
deleted file mode 100644
index d00491f..0000000
--- a/Tests/RunCMake/COMPILE_LANGUAGE-genex/PerSourceCompileDefinitions-result.txt
+++ /dev/null
@@ -1 +0,0 @@
-1
diff --git a/Tests/RunCMake/COMPILE_LANGUAGE-genex/PerSourceCompileDefinitions-stderr-VS.txt b/Tests/RunCMake/COMPILE_LANGUAGE-genex/PerSourceCompileDefinitions-stderr-VS.txt
deleted file mode 100644
index 5d19153..0000000
--- a/Tests/RunCMake/COMPILE_LANGUAGE-genex/PerSourceCompileDefinitions-stderr-VS.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-CMake Error:
- Error evaluating generator expression:
-
- \$<COMPILE_LANGUAGE:CXX>
-
- \$<COMPILE_LANGUAGE:...> may only be used for COMPILE_OPTIONS and
- file\(GENERATE\) with the Visual Studio generator.
diff --git a/Tests/RunCMake/COMPILE_LANGUAGE-genex/PerSourceCompileDefinitions-stderr-Xcode.txt b/Tests/RunCMake/COMPILE_LANGUAGE-genex/PerSourceCompileDefinitions-stderr-Xcode.txt
deleted file mode 100644
index 4a4564e..0000000
--- a/Tests/RunCMake/COMPILE_LANGUAGE-genex/PerSourceCompileDefinitions-stderr-Xcode.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-CMake Error:
- Error evaluating generator expression:
-
- \$<COMPILE_LANGUAGE:CXX>
-
- \$<COMPILE_LANGUAGE:...> may only be used for COMPILE_OPTIONS and
- file\(GENERATE\) with the Xcode generator.
diff --git a/Tests/RunCMake/COMPILE_LANGUAGE-genex/PerSourceCompileDefinitions.cmake b/Tests/RunCMake/COMPILE_LANGUAGE-genex/PerSourceCompileDefinitions.cmake
deleted file mode 100644
index 3a07d7d..0000000
--- a/Tests/RunCMake/COMPILE_LANGUAGE-genex/PerSourceCompileDefinitions.cmake
+++ /dev/null
@@ -1,5 +0,0 @@
-
-enable_language(CXX)
-
-add_executable(main main.cpp)
-set_property(SOURCE main.cpp PROPERTY COMPILE_DEFINITIONS $<$<COMPILE_LANGUAGE:CXX>:ANYTHING>)
diff --git a/Tests/RunCMake/COMPILE_LANGUAGE-genex/RunCMakeTest.cmake b/Tests/RunCMake/COMPILE_LANGUAGE-genex/RunCMakeTest.cmake
deleted file mode 100644
index 1a93dcd..0000000
--- a/Tests/RunCMake/COMPILE_LANGUAGE-genex/RunCMakeTest.cmake
+++ /dev/null
@@ -1,23 +0,0 @@
-include(RunCMake)
-
-if (RunCMake_GENERATOR STREQUAL "Xcode")
- set(RunCMake-stderr-file CompileDefinitions-stderr-Xcode.txt)
- run_cmake(CompileDefinitions)
-elseif (RunCMake_GENERATOR MATCHES "Visual Studio")
- set(RunCMake-stderr-file CompileDefinitions-stderr-VS.txt)
- run_cmake(CompileDefinitions)
-endif()
-if (RunCMake_GENERATOR STREQUAL "Xcode")
- set(RunCMake-stderr-file IncludeDirectories-stderr-Xcode.txt)
- run_cmake(IncludeDirectories)
-elseif (RunCMake_GENERATOR MATCHES "Visual Studio")
- set(RunCMake-stderr-file IncludeDirectories-stderr-VS.txt)
- run_cmake(IncludeDirectories)
-endif()
-if (RunCMake_GENERATOR STREQUAL "Xcode")
- set(RunCMake-stderr-file PerSourceCompileDefinitions-stderr-Xcode.txt)
- run_cmake(PerSourceCompileDefinitions)
-elseif (RunCMake_GENERATOR MATCHES "Visual Studio")
- set(RunCMake-stderr-file PerSourceCompileDefinitions-stderr-VS.txt)
- run_cmake(PerSourceCompileDefinitions)
-endif()
diff --git a/Tests/RunCMake/COMPILE_LANGUAGE-genex/main.cpp b/Tests/RunCMake/COMPILE_LANGUAGE-genex/main.cpp
deleted file mode 100644
index 766b775..0000000
--- a/Tests/RunCMake/COMPILE_LANGUAGE-genex/main.cpp
+++ /dev/null
@@ -1,5 +0,0 @@
-
-int main()
-{
- return 0;
-}
diff --git a/Tests/RunCMake/GenerateExportHeader/GEH.cmake b/Tests/RunCMake/GenerateExportHeader/GEH.cmake
index cfca8fe..cf81f36 100644
--- a/Tests/RunCMake/GenerateExportHeader/GEH.cmake
+++ b/Tests/RunCMake/GenerateExportHeader/GEH.cmake
@@ -53,7 +53,16 @@ endif()
add_subdirectory(lib_shared_and_static)
-add_compiler_export_flags()
+if(CMAKE_SYSTEM_NAME MATCHES "AIX" AND CMAKE_CXX_COMPILER_ID STREQUAL "GNU"
+ AND CMAKE_CXX_COMPILE_OPTIONS_VISIBILITY)
+ # With GNU 7 on AIX, passing -fvisibility=hidden when driving the
+ # linker for a shared library drops the so init/destruct symbols.
+ # Just use the modern approach instead of testing the macro.
+ set(CMAKE_CXX_VISIBILITY_PRESET hidden)
+ set(CMAKE_VISIBILITY_INLINES_HIDDEN 1)
+else()
+ add_compiler_export_flags()
+endif()
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_CURRENT_BINARY_DIR})
diff --git a/Tests/RunCMake/GenerateExportHeader/libshared/CMakeLists.txt b/Tests/RunCMake/GenerateExportHeader/libshared/CMakeLists.txt
index c4a761c..9516a5a 100644
--- a/Tests/RunCMake/GenerateExportHeader/libshared/CMakeLists.txt
+++ b/Tests/RunCMake/GenerateExportHeader/libshared/CMakeLists.txt
@@ -1,7 +1,5 @@
include(GenerateExportHeader)
-add_compiler_export_flags()
-
set(CMAKE_INCLUDE_CURRENT_DIR ON)
add_library(libshared SHARED libshared.cpp)
diff --git a/Tests/RunCMake/GenerateExportHeader/libstatic/CMakeLists.txt b/Tests/RunCMake/GenerateExportHeader/libstatic/CMakeLists.txt
index 0fd136c..56e8335 100644
--- a/Tests/RunCMake/GenerateExportHeader/libstatic/CMakeLists.txt
+++ b/Tests/RunCMake/GenerateExportHeader/libstatic/CMakeLists.txt
@@ -2,8 +2,6 @@ set(CMAKE_INCLUDE_CURRENT_DIR ON)
include(GenerateExportHeader)
-add_compiler_export_flags()
-
# Show that the export header has no effect on a static library.
add_library(libstatic STATIC libstatic.cpp)
diff --git a/Utilities/cmlibuv/src/unix/signal.c b/Utilities/cmlibuv/src/unix/signal.c
index cb09ead..3759778 100644
--- a/Utilities/cmlibuv/src/unix/signal.c
+++ b/Utilities/cmlibuv/src/unix/signal.c
@@ -28,6 +28,9 @@
#include <string.h>
#include <unistd.h>
+#ifndef SA_RESTART
+# define SA_RESTART 0
+#endif
typedef struct {
uv_signal_t* handle;
@@ -216,7 +219,9 @@ static int uv__signal_register_handler(int signum, int oneshot) {
if (sigfillset(&sa.sa_mask))
abort();
sa.sa_handler = uv__signal_handler;
- sa.sa_flags = oneshot ? SA_RESETHAND : 0;
+ sa.sa_flags = SA_RESTART;
+ if (oneshot)
+ sa.sa_flags |= SA_RESETHAND;
/* XXX save old action so we can restore it later on? */
if (sigaction(signum, &sa, NULL))