diff options
104 files changed, 1177 insertions, 222 deletions
diff --git a/Auxiliary/vim/syntax/cmake.vim b/Auxiliary/vim/syntax/cmake.vim index 1f19cb7..aca7c41 100644 --- a/Auxiliary/vim/syntax/cmake.vim +++ b/Auxiliary/vim/syntax/cmake.vim @@ -320,7 +320,7 @@ syn keyword cmakeKWremove \ contained syn keyword cmakeKWseparate_arguments - \ MSDN UNIX_COMMAND VARIABLE WINDOWS WINDOWS_COMMAND _COMMAND + \ MSDN NATIVE_COMMAND UNIX_COMMAND VARIABLE WINDOWS WINDOWS_COMMAND _COMMAND \ contained syn keyword cmakeKWset diff --git a/Help/command/separate_arguments.rst b/Help/command/separate_arguments.rst index 1fd3cd1..47982a5 100644 --- a/Help/command/separate_arguments.rst +++ b/Help/command/separate_arguments.rst @@ -5,9 +5,9 @@ Parse space-separated arguments into a semicolon-separated list. :: - separate_arguments(<var> <UNIX|WINDOWS>_COMMAND "<args>") + separate_arguments(<var> <NATIVE|UNIX|WINDOWS>_COMMAND "<args>") -Parses a unix- or windows-style command-line string "<args>" and +Parses a UNIX- or Windows-style command-line string "<args>" and stores a semicolon-separated list of the arguments in ``<var>``. The entire command line must be given in one "<args>" argument. @@ -16,12 +16,15 @@ recognizes both single-quote and double-quote pairs. A backslash escapes the next literal character (``\"`` is ``"``); there are no special escapes (``\n`` is just ``n``). -The ``WINDOWS_COMMAND`` mode parses a windows command-line using the same +The ``WINDOWS_COMMAND`` mode parses a Windows command-line using the same syntax the runtime library uses to construct argv at startup. It separates arguments by whitespace that is not double-quoted. Backslashes are literal unless they precede double-quotes. See the MSDN article `Parsing C Command-Line Arguments`_ for details. +The ``NATIVE_COMMAND`` mode parses a Windows command-line if the host +system is Windows, and a UNIX command-line otherwise. + .. _`Parsing C Command-Line Arguments`: https://msdn.microsoft.com/library/a1y7w461.aspx :: diff --git a/Help/manual/cmake-properties.7.rst b/Help/manual/cmake-properties.7.rst index 344bc09..38cc0d8 100644 --- a/Help/manual/cmake-properties.7.rst +++ b/Help/manual/cmake-properties.7.rst @@ -154,6 +154,7 @@ Properties on Targets /prop_tgt/CROSSCOMPILING_EMULATOR /prop_tgt/CUDA_PTX_COMPILATION /prop_tgt/CUDA_SEPARABLE_COMPILATION + /prop_tgt/CUDA_RESOLVE_DEVICE_SYMBOLS /prop_tgt/CUDA_EXTENSIONS /prop_tgt/CUDA_STANDARD /prop_tgt/CUDA_STANDARD_REQUIRED diff --git a/Help/prop_tgt/CUDA_RESOLVE_DEVICE_SYMBOLS.rst b/Help/prop_tgt/CUDA_RESOLVE_DEVICE_SYMBOLS.rst new file mode 100644 index 0000000..127d79f --- /dev/null +++ b/Help/prop_tgt/CUDA_RESOLVE_DEVICE_SYMBOLS.rst @@ -0,0 +1,15 @@ +CUDA_RESOLVE_DEVICE_SYMBOLS +--------------------------- + +CUDA only: Enables device linking for the specific static library target + +If set this will enable device linking on this static library target. Normally +device linking is deferred until a shared library or executable is generated, +allowing for multiple static libraries to resolve device symbols at the same +time. + +For instance: + +.. code-block:: cmake + + set_property(TARGET mystaticlib PROPERTY CUDA_RESOLVE_DEVICE_SYMBOLS ON) diff --git a/Help/release/dev/ctest_test-ignore-skipped-tests.rst b/Help/release/dev/ctest_test-ignore-skipped-tests.rst new file mode 100644 index 0000000..1e2486c --- /dev/null +++ b/Help/release/dev/ctest_test-ignore-skipped-tests.rst @@ -0,0 +1,7 @@ +ctest_test-ignore-skipped-tests +------------------------------- + +* When running tests, CTest learned to treat skipped tests (using the + :prop_test:`SKIP_RETURN_CODE` property) the same as tests with the + :prop_test:`DISABLED` property. Due to this change, CTest will not indicate + failure when all tests are either skipped or pass. diff --git a/Help/release/dev/separgs-native.rst b/Help/release/dev/separgs-native.rst new file mode 100644 index 0000000..943f08e --- /dev/null +++ b/Help/release/dev/separgs-native.rst @@ -0,0 +1,5 @@ +separgs-native +------------------- + +* A ``NATIVE_COMMAND`` mode was added to :command:`separate_arguments` + performing argument separation depening on the host operating system. diff --git a/Modules/CMakeCheckCompilerFlagCommonPatterns.cmake b/Modules/CMakeCheckCompilerFlagCommonPatterns.cmake index 1b5178d..e60ffe0 100644 --- a/Modules/CMakeCheckCompilerFlagCommonPatterns.cmake +++ b/Modules/CMakeCheckCompilerFlagCommonPatterns.cmake @@ -22,6 +22,7 @@ macro (CHECK_COMPILER_FLAG_COMMON_PATTERNS _VAR) FAIL_REGEX "[Ww]arning: [Oo]ption" # SunPro FAIL_REGEX "command option .* is not recognized" # XL FAIL_REGEX "command option .* contains an incorrect subargument" # XL + FAIL_REGEX "Option .* is not recognized. Option will be ignored." # XL FAIL_REGEX "not supported in this configuration. ignored" # AIX FAIL_REGEX "File with unknown suffix passed to linker" # PGI FAIL_REGEX "[Uu]nknown switch" # PGI diff --git a/Modules/CMakeParseImplicitLinkInfo.cmake b/Modules/CMakeParseImplicitLinkInfo.cmake index 3273443..ad3c00f 100644 --- a/Modules/CMakeParseImplicitLinkInfo.cmake +++ b/Modules/CMakeParseImplicitLinkInfo.cmake @@ -38,11 +38,7 @@ function(CMAKE_PARSE_IMPLICIT_LINK_INFO text lib_var dir_var fwk_var log_var obj set(line "${xline}") endif() endif() - if(UNIX) - separate_arguments(args UNIX_COMMAND "${line}") - else() - separate_arguments(args WINDOWS_COMMAND "${line}") - endif() + separate_arguments(args NATIVE_COMMAND "${line}") list(GET args 0 cmd) endif() set(is_msvc 0) diff --git a/Modules/CPackIFW.cmake b/Modules/CPackIFW.cmake index 099dd1c..b4a6dc6 100644 --- a/Modules/CPackIFW.cmake +++ b/Modules/CPackIFW.cmake @@ -717,21 +717,58 @@ set(CPackIFW_CMake_INCLUDED 1) # Framework version #============================================================================= -if(CPACK_IFW_INSTALLERBASE_EXECUTABLE AND CPACK_IFW_DEVTOOL_EXECUTABLE) - execute_process(COMMAND - "${CPACK_IFW_INSTALLERBASE_EXECUTABLE}" --framework-version - OUTPUT_VARIABLE CPACK_IFW_FRAMEWORK_VERSION) - if(CPACK_IFW_FRAMEWORK_VERSION) - string(REPLACE " " "" - CPACK_IFW_FRAMEWORK_VERSION "${CPACK_IFW_FRAMEWORK_VERSION}") - string(REPLACE "\t" "" - CPACK_IFW_FRAMEWORK_VERSION "${CPACK_IFW_FRAMEWORK_VERSION}") - string(REPLACE "\n" "" - CPACK_IFW_FRAMEWORK_VERSION "${CPACK_IFW_FRAMEWORK_VERSION}") - if(CPACK_IFW_VERBOSE) - message(STATUS "Found QtIFW ${CPACK_IFW_FRAMEWORK_VERSION} version") +set(CPACK_IFW_FRAMEWORK_VERSION_FORCED "" + CACHE STRING "The forced version of used QtIFW tools") +mark_as_advanced(CPACK_IFW_FRAMEWORK_VERSION_FORCED) +set(CPACK_IFW_FRAMEWORK_VERSION_TIMEOUT 1 + CACHE STRING "The timeout to return QtIFW framework version string from \"installerbase\" executable") +mark_as_advanced(CPACK_IFW_FRAMEWORK_VERSION_TIMEOUT) +if(CPACK_IFW_INSTALLERBASE_EXECUTABLE AND NOT CPACK_IFW_FRAMEWORK_VERSION_FORCED) + set(CPACK_IFW_FRAMEWORK_VERSION) + # Invoke version from "installerbase" executable + foreach(_ifw_version_argument --framework-version --version) + if(NOT CPACK_IFW_FRAMEWORK_VERSION) + execute_process(COMMAND + "${CPACK_IFW_INSTALLERBASE_EXECUTABLE}" ${_ifw_version_argument} + TIMEOUT ${CPACK_IFW_FRAMEWORK_VERSION_TIMEOUT} + RESULT_VARIABLE CPACK_IFW_FRAMEWORK_VERSION_RESULT + OUTPUT_VARIABLE CPACK_IFW_FRAMEWORK_VERSION_OUTPUT + OUTPUT_STRIP_TRAILING_WHITESPACE + ENCODING UTF8) + if(NOT CPACK_IFW_FRAMEWORK_VERSION_RESULT AND CPACK_IFW_FRAMEWORK_VERSION_OUTPUT) + string(REGEX MATCH "[0-9]+(\\.[0-9]+)*" + CPACK_IFW_FRAMEWORK_VERSION "${CPACK_IFW_FRAMEWORK_VERSION_OUTPUT}") + if(CPACK_IFW_FRAMEWORK_VERSION) + if("${_ifw_version_argument}" STREQUAL "--framework-version") + set(CPACK_IFW_FRAMEWORK_VERSION_SOURCE "INSTALLERBASE_FRAMEWORK_VERSION") + elseif("${_ifw_version_argument}" STREQUAL "--version") + set(CPACK_IFW_FRAMEWORK_VERSION_SOURCE "INSTALLERBASE_FRAMEWORK_VERSION") + endif() + endif() + endif() + endif() + endforeach() + # Finaly try to get version from executable path + if(NOT CPACK_IFW_FRAMEWORK_VERSION) + string(REGEX MATCH "[0-9]+(\\.[0-9]+)*" + CPACK_IFW_FRAMEWORK_VERSION "${CPACK_IFW_INSTALLERBASE_EXECUTABLE}") + if(CPACK_IFW_FRAMEWORK_VERSION) + set(CPACK_IFW_FRAMEWORK_VERSION_SOURCE "INSTALLERBASE_PATH") endif() endif() +elseif(CPACK_IFW_FRAMEWORK_VERSION_FORCED) + set(CPACK_IFW_FRAMEWORK_VERSION ${CPACK_IFW_FRAMEWORK_VERSION_FORCED}) + set(CPACK_IFW_FRAMEWORK_VERSION_SOURCE "FORCED") +endif() +if(CPACK_IFW_VERBOSE) + if(CPACK_IFW_FRAMEWORK_VERSION AND CPACK_IFW_FRAMEWORK_VERSION_FORCED) + message(STATUS "Found QtIFW ${CPACK_IFW_FRAMEWORK_VERSION} (forced) version") + elseif(CPACK_IFW_FRAMEWORK_VERSION) + message(STATUS "Found QtIFW ${CPACK_IFW_FRAMEWORK_VERSION} version") + endif() +endif() +if(CPACK_IFW_INSTALLERBASE_EXECUTABLE AND NOT CPACK_IFW_FRAMEWORK_VERSION) + message(WARNING "Could not detect QtIFW tools version. Set used version to variable \"CPACK_IFW_FRAMEWORK_VERSION_FORCED\" manualy.") endif() #============================================================================= diff --git a/Modules/Compiler/Clang-FindBinUtils.cmake b/Modules/Compiler/Clang-FindBinUtils.cmake new file mode 100644 index 0000000..c81e77a --- /dev/null +++ b/Modules/Compiler/Clang-FindBinUtils.cmake @@ -0,0 +1,25 @@ +if(NOT DEFINED _CMAKE_PROCESSING_LANGUAGE OR _CMAKE_PROCESSING_LANGUAGE STREQUAL "") + message(FATAL_ERROR "Internal error: _CMAKE_PROCESSING_LANGUAGE is not set") +endif() + +# Try to find tools in the same directory as Clang itself +get_filename_component(__clang_hint_1 "${CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER}" REALPATH) +get_filename_component(__clang_hint_1 "${__clang_hint_1}" DIRECTORY) + +get_filename_component(__clang_hint_2 "${CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER}" DIRECTORY) + +set(__clang_hints ${__clang_hint_1} ${__clang_hint_2}) + +# http://manpages.ubuntu.com/manpages/precise/en/man1/llvm-ar.1.html +find_program(CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_AR NAMES + "${_CMAKE_TOOLCHAIN_PREFIX}llvm-ar" + HINTS ${__clang_hints} + DOC "LLVM archiver" +) + +# http://manpages.ubuntu.com/manpages/precise/en/man1/llvm-ranlib.1.html +find_program(CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_RANLIB NAMES + "${_CMAKE_TOOLCHAIN_PREFIX}llvm-ranlib" + HINTS ${__clang_hints} + DOC "Generate index for LLVM archive" +) diff --git a/Modules/Compiler/Clang.cmake b/Modules/Compiler/Clang.cmake index 6b99a08..8c2f87d 100644 --- a/Modules/Compiler/Clang.cmake +++ b/Modules/Compiler/Clang.cmake @@ -28,12 +28,54 @@ else() set(CMAKE_${lang}_COMPILE_OPTIONS_EXTERNAL_TOOLCHAIN "--gcc-toolchain=") endif() - set(_CMAKE_IPO_SUPPORTED_BY_CMAKE NO) - set(_CMAKE_IPO_MAY_BE_SUPPORTED_BY_COMPILER NO) + set(_CMAKE_IPO_SUPPORTED_BY_CMAKE YES) + set(_CMAKE_IPO_MAY_BE_SUPPORTED_BY_COMPILER YES) - unset(CMAKE_${lang}_COMPILE_OPTIONS_IPO) - unset(CMAKE_${lang}_ARCHIVE_CREATE_IPO) - unset(CMAKE_${lang}_ARCHIVE_APPEND_IPO) - unset(CMAKE_${lang}_ARCHIVE_FINISH_IPO) + string(COMPARE EQUAL "${CMAKE_${lang}_COMPILER_ID}" "AppleClang" __is_apple_clang) + + # '-flto=thin' available since Clang 3.9 and Xcode 8 + # * http://clang.llvm.org/docs/ThinLTO.html#clang-llvm + # * https://trac.macports.org/wiki/XcodeVersionInfo + set(_CMAKE_LTO_THIN TRUE) + if(__is_apple_clang) + if(CMAKE_${lang}_COMPILER_VERSION VERSION_LESS 8.0) + set(_CMAKE_LTO_THIN FALSE) + endif() + else() + if(CMAKE_${lang}_COMPILER_VERSION VERSION_LESS 3.9) + set(_CMAKE_LTO_THIN FALSE) + endif() + endif() + + if(_CMAKE_LTO_THIN) + set(CMAKE_${lang}_COMPILE_OPTIONS_IPO "-flto=thin") + else() + set(CMAKE_${lang}_COMPILE_OPTIONS_IPO "-flto") + endif() + + if(ANDROID) + # https://github.com/android-ndk/ndk/issues/242 + set(CMAKE_${lang}_LINK_OPTIONS_IPO "-fuse-ld=gold") + endif() + + if(ANDROID OR __is_apple_clang) + set(__ar "${CMAKE_AR}") + set(__ranlib "${CMAKE_RANLIB}") + else() + set(__ar "${CMAKE_${lang}_COMPILER_AR}") + set(__ranlib "${CMAKE_${lang}_COMPILER_RANLIB}") + endif() + + set(CMAKE_${lang}_ARCHIVE_CREATE_IPO + "${__ar} cr <TARGET> <LINK_FLAGS> <OBJECTS>" + ) + + set(CMAKE_${lang}_ARCHIVE_APPEND_IPO + "${__ar} r <TARGET> <LINK_FLAGS> <OBJECTS>" + ) + + set(CMAKE_${lang}_ARCHIVE_FINISH_IPO + "${__ranlib} <TARGET>" + ) endmacro() endif() diff --git a/Modules/Compiler/XL-C.cmake b/Modules/Compiler/XL-C.cmake index f976c99..ac84da2 100644 --- a/Modules/Compiler/XL-C.cmake +++ b/Modules/Compiler/XL-C.cmake @@ -3,6 +3,50 @@ __compiler_xl(C) string(APPEND CMAKE_C_FLAGS_RELEASE_INIT " -DNDEBUG") string(APPEND CMAKE_C_FLAGS_MINSIZEREL_INIT " -DNDEBUG") -# -qthreaded = Ensures that all optimizations will be thread-safe -# -qhalt=e = Halt on error messages (rather than just severe errors) -string(APPEND CMAKE_C_FLAGS_INIT " -qthreaded -qhalt=e") +# -qthreaded = Ensures that all optimizations will be thread-safe +string(APPEND CMAKE_C_FLAGS_INIT " -qthreaded") + +# XL v13.1.1 for Linux ppc64 little-endian switched to using a clang based +# front end and accepts the -std= option while only reserving -qlanglevel= for +# compatibility. All other versions (previous versions on Linux ppc64 +# little-endian, all versions on Linux ppc64 big-endian, all versions on AIX +# and BGQ, etc) are derived from the UNIX compiler and only accept the +# -qlanglvl option. +if (CMAKE_SYSTEM MATCHES "Linux.*ppc64le" AND + CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 13.1.1) + set(CMAKE_C90_STANDARD_COMPILE_OPTION "-std=c89") + set(CMAKE_C90_EXTENSION_COMPILE_OPTION "-std=gnu89") + set(CMAKE_C99_STANDARD_COMPILE_OPTION "-std=c99") + set(CMAKE_C99_EXTENSION_COMPILE_OPTION "-std=gnu99") + if (CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 13.1.2) + set(CMAKE_C11_STANDARD_COMPILE_OPTION "-std=c11") + set(CMAKE_C11_EXTENSION_COMPILE_OPTION "-std=gnu11") + else () + set(CMAKE_C11_STANDARD_COMPILE_OPTION "-qlanglvl=extc1x") + set(CMAKE_C11_EXTENSION_COMPILE_OPTION "-qlanglvl=extc1x") + endif () +else () + if (CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 10.1) + set(CMAKE_C90_STANDARD_COMPILE_OPTION "-qlanglvl=stdc89") + set(CMAKE_C90_EXTENSION_COMPILE_OPTION "-qlanglvl=extc89") + set(CMAKE_C99_STANDARD_COMPILE_OPTION "-qlanglvl=stdc99") + set(CMAKE_C99_EXTENSION_COMPILE_OPTION "-qlanglvl=extc99") + if (CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 12.1) + set(CMAKE_C11_STANDARD_COMPILE_OPTION "-qlanglvl=extc1x") + set(CMAKE_C11_EXTENSION_COMPILE_OPTION "-qlanglvl=extc1x") + endif () + endif () +endif() + +if (CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 10.1) + if (NOT CMAKE_C_COMPILER_FORCED) + if (NOT CMAKE_C_STANDARD_COMPUTED_DEFAULT) + message(FATAL_ERROR "CMAKE_C_STANDARD_COMPUTED_DEFAULT should be set for ${CMAKE_C_COMPILER_ID} (${CMAKE_C_COMPILER}) version ${CMAKE_C_COMPILER_VERSION}") + else () + set(CMAKE_C_STANDARD_DEFAULT ${CMAKE_C_STANDARD_COMPUTED_DEFAULT}) + endif () + elseif (NOT CMAKE_C_STANDARD_COMPUTED_DEFAULT) + # Compiler id was forced so just guess the default standard level. + set(CMAKE_C_STANDARD_DEFAULT 90) + endif () +endif () diff --git a/Modules/Compiler/XL-CXX.cmake b/Modules/Compiler/XL-CXX.cmake index 545d657..98ccb29 100644 --- a/Modules/Compiler/XL-CXX.cmake +++ b/Modules/Compiler/XL-CXX.cmake @@ -3,9 +3,60 @@ __compiler_xl(CXX) string(APPEND CMAKE_CXX_FLAGS_RELEASE_INIT " -DNDEBUG") string(APPEND CMAKE_CXX_FLAGS_MINSIZEREL_INIT " -DNDEBUG") -# -qthreaded = Ensures that all optimizations will be thread-safe -# -qhalt=e = Halt on error messages (rather than just severe errors) -string(APPEND CMAKE_CXX_FLAGS_INIT " -qthreaded -qhalt=e") +# -qthreaded = Ensures that all optimizations will be thread-safe +string(APPEND CMAKE_CXX_FLAGS_INIT " -qthreaded") + +# XL v13.1.1 for Linux ppc64 little-endian switched to using a clang based +# front end and accepts the -std= option while only reserving -qlanglevel= for +# compatibility. All other versions (previous versions on Linux ppc64 +# little-endian, all versions on Linux ppc64 big-endian, all versions on AIX +# and BGQ, etc) are derived from the UNIX compiler and only accept the +# -qlanglvl option. +if (CMAKE_SYSTEM MATCHES "Linux.*ppc64") + if (CMAKE_SYSTEM MATCHES "Linux.*ppc64le" AND + CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 13.1.1) + set(CMAKE_CXX98_STANDARD_COMPILE_OPTION "-std=c++98") + set(CMAKE_CXX98_EXTENSION_COMPILE_OPTION "-std=gnu++98") + if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 13.1.2) + set(CMAKE_CXX11_STANDARD_COMPILE_OPTION "-std=c++11") + set(CMAKE_CXX11_EXTENSION_COMPILE_OPTION "-std=gnu++11") + set(CMAKE_CXX14_STANDARD_COMPILE_OPTION "-std=c++1y") + set(CMAKE_CXX14_EXTENSION_COMPILE_OPTION "-qlanglvl=extended1y") + else () + set(CMAKE_CXX11_STANDARD_COMPILE_OPTION "-qlanglvl=extended0x") + set(CMAKE_CXX11_EXTENSION_COMPILE_OPTION "-qlanglvl=extended0x") + endif () + else () + # The non-clang based Linux ppc64 compiler, both big-endian and + # little-endian lacks, the non-extension language level flags + if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 10.1) + set(CMAKE_CXX98_STANDARD_COMPILE_OPTION "-qlanglvl=extended") + set(CMAKE_CXX98_EXTENSION_COMPILE_OPTION "-qlanglvl=extended") + set(CMAKE_CXX11_STANDARD_COMPILE_OPTION "-qlanglvl=extended0x") + set(CMAKE_CXX11_EXTENSION_COMPILE_OPTION "-qlanglvl=extended0x") + endif () + endif () +else () + if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 10.1) + set(CMAKE_CXX98_STANDARD_COMPILE_OPTION "-qlanglvl=strict98") + set(CMAKE_CXX98_EXTENSION_COMPILE_OPTION "-qlanglvl=extended") + set(CMAKE_CXX11_STANDARD_COMPILE_OPTION "-qlanglvl=extended0x") + set(CMAKE_CXX11_EXTENSION_COMPILE_OPTION "-qlanglvl=extended0x") + endif () +endif () set(CMAKE_CXX_COMPILE_OBJECT "<CMAKE_CXX_COMPILER> -+ <DEFINES> <INCLUDES> <FLAGS> -o <OBJECT> -c <SOURCE>") + +if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 10.1) + if (NOT CMAKE_CXX_COMPILER_FORCED) + if (NOT CMAKE_CXX_STANDARD_COMPUTED_DEFAULT) + message(FATAL_ERROR "CMAKE_CXX_STANDARD_COMPUTED_DEFAULT should be set for ${CMAKE_CXX_COMPILER_ID} (${CMAKE_CXX_COMPILER}) version ${CMAKE_CXX_COMPILER_VERSION}") + else () + set(CMAKE_CXX_STANDARD_DEFAULT ${CMAKE_CXX_STANDARD_COMPUTED_DEFAULT}) + endif () + elseif (NOT CMAKE_CXX_STANDARD_COMPUTED_DEFAULT) + # Compiler id was forced so just guess the default standard level. + set(CMAKE_CXX_STANDARD_DEFAULT 98) + endif () +endif () diff --git a/Modules/FindBoost.cmake b/Modules/FindBoost.cmake index 093d8c9..b2fb4b7 100644 --- a/Modules/FindBoost.cmake +++ b/Modules/FindBoost.cmake @@ -889,6 +889,33 @@ function(_Boost_MISSING_DEPENDENCIES componentvar extravar) endfunction() # +# Some boost libraries may require particular set of compler features. +# The very first one was `boost::fiber` introduced in Boost 1.62. +# One can check required compiler features of it in +# `${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) + set(_Boost_FIBER_COMPILER_FEATURES + cxx_alias_templates + cxx_auto_type + cxx_constexpr + cxx_defaulted_functions + cxx_final + cxx_lambdas + cxx_noexcept + cxx_nullptr + cxx_rvalue_references + cxx_thread_local + cxx_variadic_templates + ) + endif() + string(TOUPPER ${component} uppercomponent) + set(${_ret} ${_Boost_${uppercomponent}_COMPILER_FEATURES} PARENT_SCOPE) +endfunction() + +# # Update library search directory hint variable with paths used by prebuilt boost binaries. # # Prebuilt windows binaries (https://sourceforge.net/projects/boost/files/boost-binaries/) @@ -1640,6 +1667,9 @@ foreach(COMPONENT ${Boost_FIND_COMPONENTS}) _Boost_ADJUST_LIB_VARS(${UPPERCOMPONENT}) + # Check if component requires some compiler features + _Boost_COMPILER_FEATURES(${COMPONENT} _Boost_${UPPERCOMPONENT}_COMPILER_FEATURES) + endforeach() # Restore the original find library ordering @@ -1811,6 +1841,10 @@ if(Boost_FOUND) set_target_properties(Boost::${COMPONENT} PROPERTIES INTERFACE_LINK_LIBRARIES "${_Boost_${UPPERCOMPONENT}_TARGET_DEPENDENCIES}") endif() + if(_Boost_${UPPERCOMPONENT}_COMPILER_FEATURES) + set_target_properties(Boost::${COMPONENT} PROPERTIES + INTERFACE_COMPILE_FEATURES "${_Boost_${UPPERCOMPONENT}_COMPILER_FEATURES}") + endif() endif() endif() endforeach() diff --git a/Modules/FindGLUT.cmake b/Modules/FindGLUT.cmake index 02e6df0..88d4b29 100644 --- a/Modules/FindGLUT.cmake +++ b/Modules/FindGLUT.cmake @@ -120,10 +120,12 @@ if (GLUT_FOUND) # If not, we need some way to figure out what platform we are on. set( GLUT_LIBRARIES ${GLUT_glut_LIBRARY} - ${GLUT_Xmu_LIBRARY} - ${GLUT_Xi_LIBRARY} - ${GLUT_cocoa_LIBRARY} ) + foreach(v GLUT_Xmu_LIBRARY GLUT_Xi_LIBRARY GLUT_cocoa_LIBRARY) + if(${v}) + list(APPEND GLUT_LIBRARIES ${${v}}) + endif() + endforeach() if(NOT TARGET GLUT::GLUT) add_library(GLUT::GLUT UNKNOWN IMPORTED) diff --git a/Modules/FindHDF5.cmake b/Modules/FindHDF5.cmake index 1e2ea69..5962c5b 100644 --- a/Modules/FindHDF5.cmake +++ b/Modules/FindHDF5.cmake @@ -354,11 +354,7 @@ macro( _HDF5_parse_compile_line libraries libraries_hl) - if(UNIX) - separate_arguments(_HDF5_COMPILE_ARGS UNIX_COMMAND "${${compile_line_var}}") - else() - separate_arguments(_HDF5_COMPILE_ARGS WINDOWS_COMMAND "${${compile_line_var}}") - endif() + separate_arguments(_HDF5_COMPILE_ARGS NATIVE_COMMAND "${${compile_line_var}}") foreach(arg IN LISTS _HDF5_COMPILE_ARGS) if("${arg}" MATCHES "^-I(.*)$") diff --git a/Modules/FindMPI.cmake b/Modules/FindMPI.cmake index fab53cb..37f3255 100644 --- a/Modules/FindMPI.cmake +++ b/Modules/FindMPI.cmake @@ -645,8 +645,7 @@ foreach (lang C CXX Fortran) add_library(MPI::MPI_${lang} INTERFACE IMPORTED) endif() if(MPI_${lang}_COMPILE_FLAGS) - set(_MPI_${lang}_COMPILE_OPTIONS "${MPI_${lang}_COMPILE_FLAGS}") - separate_arguments(_MPI_${lang}_COMPILE_OPTIONS) + separate_arguments(_MPI_${lang}_COMPILE_OPTIONS NATIVE_COMMAND "${MPI_${lang}_COMPILE_FLAGS}") set_property(TARGET MPI::MPI_${lang} PROPERTY INTERFACE_COMPILE_OPTIONS "${_MPI_${lang}_COMPILE_OPTIONS}") endif() diff --git a/Modules/FindOpenMP.cmake b/Modules/FindOpenMP.cmake index 8c1b018..e7d9d5f 100644 --- a/Modules/FindOpenMP.cmake +++ b/Modules/FindOpenMP.cmake @@ -411,11 +411,7 @@ foreach(LANG IN ITEMS C CXX Fortran) add_library(OpenMP::OpenMP_${LANG} INTERFACE IMPORTED) endif() if(OpenMP_${LANG}_FLAGS) - if(CMAKE_HOST_WIN32) - separate_arguments(_OpenMP_${LANG}_OPTIONS WINDOWS_COMMAND "${OpenMP_${LANG}_FLAGS}") - else() - separate_arguments(_OpenMP_${LANG}_OPTIONS UNIX_COMMAND "${OpenMP_${LANG}_FLAGS}") - endif() + separate_arguments(_OpenMP_${LANG}_OPTIONS NATIVE_COMMAND "${OpenMP_${LANG}_FLAGS}") set_property(TARGET OpenMP::OpenMP_${LANG} PROPERTY INTERFACE_COMPILE_OPTIONS "${_OpenMP_${LANG}_OPTIONS}") unset(_OpenMP_${LANG}_OPTIONS) diff --git a/Modules/Platform/AIX-XL-C.cmake b/Modules/Platform/AIX-XL-C.cmake index 5e437fa..cbfd58b 100644 --- a/Modules/Platform/AIX-XL-C.cmake +++ b/Modules/Platform/AIX-XL-C.cmake @@ -1,2 +1,5 @@ include(Platform/AIX-XL) __aix_compiler_xl(C) + +# -qhalt=e = Halt on error messages (rather than just severe errors) +string(APPEND CMAKE_C_FLAGS_INIT " -qhalt=e") diff --git a/Modules/Platform/AIX-XL-CXX.cmake b/Modules/Platform/AIX-XL-CXX.cmake index ef38a5f..78baef5 100644 --- a/Modules/Platform/AIX-XL-CXX.cmake +++ b/Modules/Platform/AIX-XL-CXX.cmake @@ -1,2 +1,5 @@ include(Platform/AIX-XL) __aix_compiler_xl(CXX) + +# -qhalt=s = Halt on severe error messages +string(APPEND CMAKE_CXX_FLAGS_INIT " -qhalt=s") diff --git a/Modules/Platform/BlueGeneP-dynamic-XL-C.cmake b/Modules/Platform/BlueGeneP-dynamic-XL-C.cmake index f13b517..918ee70 100644 --- a/Modules/Platform/BlueGeneP-dynamic-XL-C.cmake +++ b/Modules/Platform/BlueGeneP-dynamic-XL-C.cmake @@ -3,3 +3,6 @@ __BlueGeneP_set_dynamic_flags(XL C) + +# -qhalt=e = Halt on error messages (rather than just severe errors) +string(APPEND CMAKE_C_FLAGS_INIT " -qhalt=e") diff --git a/Modules/Platform/BlueGeneP-dynamic-XL-CXX.cmake b/Modules/Platform/BlueGeneP-dynamic-XL-CXX.cmake index 80c05a1..cfefb0b 100644 --- a/Modules/Platform/BlueGeneP-dynamic-XL-CXX.cmake +++ b/Modules/Platform/BlueGeneP-dynamic-XL-CXX.cmake @@ -3,3 +3,6 @@ __BlueGeneP_set_dynamic_flags(XL CXX) + +# -qhalt=s = Halt on severe error messages +string(APPEND CMAKE_CXX_FLAGS_INIT " -qhalt=s") diff --git a/Modules/Platform/BlueGeneP-static-XL-C.cmake b/Modules/Platform/BlueGeneP-static-XL-C.cmake index a990b5c..7d4fc13 100644 --- a/Modules/Platform/BlueGeneP-static-XL-C.cmake +++ b/Modules/Platform/BlueGeneP-static-XL-C.cmake @@ -3,3 +3,6 @@ __BlueGeneP_set_static_flags(XL C) + +# -qhalt=e = Halt on error messages (rather than just severe errors) +string(APPEND CMAKE_C_FLAGS_INIT " -qhalt=e") diff --git a/Modules/Platform/BlueGeneP-static-XL-CXX.cmake b/Modules/Platform/BlueGeneP-static-XL-CXX.cmake index 116c0bb..1df276e 100644 --- a/Modules/Platform/BlueGeneP-static-XL-CXX.cmake +++ b/Modules/Platform/BlueGeneP-static-XL-CXX.cmake @@ -3,3 +3,6 @@ __BlueGeneP_set_static_flags(XL CXX) + +# -qhalt=s = Halt on severe error messages +string(APPEND CMAKE_CXX_FLAGS_INIT " -qhalt=s") diff --git a/Modules/Platform/BlueGeneQ-dynamic-XL-C.cmake b/Modules/Platform/BlueGeneQ-dynamic-XL-C.cmake index f46fa95..c51dacb 100644 --- a/Modules/Platform/BlueGeneQ-dynamic-XL-C.cmake +++ b/Modules/Platform/BlueGeneQ-dynamic-XL-C.cmake @@ -3,3 +3,6 @@ __BlueGeneQ_setup_dynamic(XL C) + +# -qhalt=e = Halt on error messages (rather than just severe errors) +string(APPEND CMAKE_C_FLAGS_INIT " -qhalt=e") diff --git a/Modules/Platform/BlueGeneQ-dynamic-XL-CXX.cmake b/Modules/Platform/BlueGeneQ-dynamic-XL-CXX.cmake index c463379..5dbc836 100644 --- a/Modules/Platform/BlueGeneQ-dynamic-XL-CXX.cmake +++ b/Modules/Platform/BlueGeneQ-dynamic-XL-CXX.cmake @@ -3,3 +3,6 @@ __BlueGeneQ_setup_dynamic(XL CXX) + +# -qhalt=s = Halt on severe error messages +string(APPEND CMAKE_CXX_FLAGS_INIT " -qhalt=s") diff --git a/Modules/Platform/BlueGeneQ-static-XL-C.cmake b/Modules/Platform/BlueGeneQ-static-XL-C.cmake index 465128f..67cd57d 100644 --- a/Modules/Platform/BlueGeneQ-static-XL-C.cmake +++ b/Modules/Platform/BlueGeneQ-static-XL-C.cmake @@ -3,3 +3,6 @@ __BlueGeneQ_setup_static(XL C) + +# -qhalt=e = Halt on error messages (rather than just severe errors) +string(APPEND CMAKE_C_FLAGS_INIT " -qhalt=e") diff --git a/Modules/Platform/BlueGeneQ-static-XL-CXX.cmake b/Modules/Platform/BlueGeneQ-static-XL-CXX.cmake index abd4ebf..a171e7f 100644 --- a/Modules/Platform/BlueGeneQ-static-XL-CXX.cmake +++ b/Modules/Platform/BlueGeneQ-static-XL-CXX.cmake @@ -3,3 +3,6 @@ __BlueGeneQ_setup_static(XL CXX) + +# -qhalt=s = Halt on severe error messages +string(APPEND CMAKE_CXX_FLAGS_INIT " -qhalt=s") diff --git a/Modules/Platform/Darwin-XL-C.cmake b/Modules/Platform/Darwin-XL-C.cmake index 42e94a9..2aeb132 100644 --- a/Modules/Platform/Darwin-XL-C.cmake +++ b/Modules/Platform/Darwin-XL-C.cmake @@ -3,3 +3,6 @@ set(CMAKE_SHARED_MODULE_CREATE_C_FLAGS "-bundle") # Enable shared library versioning. set(CMAKE_SHARED_LIBRARY_SONAME_C_FLAG "-Wl,-install_name") + +# -qhalt=e = Halt on error messages (rather than just severe errors) +string(APPEND CMAKE_C_FLAGS_INIT " -qhalt=e") diff --git a/Modules/Platform/Darwin-XL-CXX.cmake b/Modules/Platform/Darwin-XL-CXX.cmake index 65c76f8..f8e1906 100644 --- a/Modules/Platform/Darwin-XL-CXX.cmake +++ b/Modules/Platform/Darwin-XL-CXX.cmake @@ -3,3 +3,6 @@ set(CMAKE_SHARED_MODULE_CREATE_CXX_FLAGS "-bundle") # Enable shared library versioning. set(CMAKE_SHARED_LIBRARY_SONAME_CXX_FLAG "-Wl,-install_name") + +# -qhalt=e = Halt on error messages (rather than just severe errors) +string(APPEND CMAKE_C_FLAGS_INIT " -qhalt=e") diff --git a/Modules/UseSWIG.cmake b/Modules/UseSWIG.cmake index 277f4ca..bfe1a6f 100644 --- a/Modules/UseSWIG.cmake +++ b/Modules/UseSWIG.cmake @@ -326,6 +326,9 @@ macro(SWIG_ADD_LIBRARY name) if (APPLE) set_target_properties (${SWIG_MODULE_${name}_REAL_NAME} PROPERTIES SUFFIX ".bundle") endif () + else() + # assume empty prefix because we expect the module to be dynamically loaded + set_target_properties (${SWIG_MODULE_${name}_REAL_NAME} PROPERTIES PREFIX "") endif () endmacro() diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index a7b2e63..5136213 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 8) -set(CMake_VERSION_PATCH 20170427) +set(CMake_VERSION_PATCH 20170501) #set(CMake_VERSION_RC 1) diff --git a/Source/CPack/IFW/cmCPackIFWInstaller.cxx b/Source/CPack/IFW/cmCPackIFWInstaller.cxx index 57b47f1..5e5f066 100644 --- a/Source/CPack/IFW/cmCPackIFWInstaller.cxx +++ b/Source/CPack/IFW/cmCPackIFWInstaller.cxx @@ -171,17 +171,17 @@ void cmCPackIFWInstaller::ConfigureFromOptions() // WizardStyle if (const char* option = GetOption("CPACK_IFW_PACKAGE_WIZARD_STYLE")) { - if (WizardStyle.compare("Modern") == 0 && - WizardStyle.compare("Aero") == 0 && WizardStyle.compare("Mac") == 0 && - WizardStyle.compare("Classic") == 0) { + // Setting the user value in any case + WizardStyle = option; + // Check known values + if (WizardStyle != "Modern" && WizardStyle != "Aero" && + WizardStyle != "Mac" && WizardStyle != "Classic") { cmCPackLogger( cmCPackLog::LOG_WARNING, "Option CPACK_IFW_PACKAGE_WIZARD_STYLE has unknown value \"" << option << "\". Expected values are: Modern, Aero, Mac, Classic." << std::endl); } - - WizardStyle = option; } // WizardDefaultWidth diff --git a/Source/CPack/IFW/cmCPackIFWPackage.cxx b/Source/CPack/IFW/cmCPackIFWPackage.cxx index 99e8b9e..eda383f 100644 --- a/Source/CPack/IFW/cmCPackIFWPackage.cxx +++ b/Source/CPack/IFW/cmCPackIFWPackage.cxx @@ -514,11 +514,11 @@ int cmCPackIFWPackage::ConfigureFromPrefix(const std::string& prefix) Default.clear(); } else if (const char* value = GetOption(option)) { std::string lowerValue = cmsys::SystemTools::LowerCase(value); - if (lowerValue.compare("true") == 0) { + if (lowerValue == "true") { Default = "true"; - } else if (lowerValue.compare("false") == 0) { + } else if (lowerValue == "false") { Default = "false"; - } else if (lowerValue.compare("script") == 0) { + } else if (lowerValue == "script") { Default = "script"; } else { Default = value; diff --git a/Source/CTest/cmCTestRunTest.cxx b/Source/CTest/cmCTestRunTest.cxx index a4853b7..fe23075 100644 --- a/Source/CTest/cmCTestRunTest.cxx +++ b/Source/CTest/cmCTestRunTest.cxx @@ -167,6 +167,7 @@ bool cmCTestRunTest::EndTest(size_t completed, size_t total, bool started) std::vector<std::pair<cmsys::RegularExpression, std::string> >::iterator passIt; bool forceFail = false; + bool skipped = false; bool outputTestErrorsToConsole = false; if (!this->TestProperties->RequiredRegularExpressions.empty() && this->FailedDependencies.empty()) { @@ -219,6 +220,7 @@ bool cmCTestRunTest::EndTest(size_t completed, size_t total, bool started) s << "SKIP_RETURN_CODE=" << this->TestProperties->SkipReturnCode; this->TestResult.CompletionStatus = s.str(); cmCTestLog(this->CTest, HANDLER_OUTPUT, "***Skipped "); + skipped = true; } else if ((success && !this->TestProperties->WillFail) || (!success && this->TestProperties->WillFail)) { this->TestResult.Status = cmCTestTestHandler::COMPLETED; @@ -338,7 +340,9 @@ bool cmCTestRunTest::EndTest(size_t completed, size_t total, bool started) compress ? this->CompressedOutput : this->ProcessOutput; this->TestResult.CompressOutput = compress; this->TestResult.ReturnValue = this->TestProcess->GetExitValue(); - this->TestResult.CompletionStatus = "Completed"; + if (!skipped) { + this->TestResult.CompletionStatus = "Completed"; + } this->TestResult.ExecutionTime = this->TestProcess->GetTotalTime(); this->MemCheckPostProcess(); this->ComputeWeightedCost(); @@ -349,7 +353,7 @@ bool cmCTestRunTest::EndTest(size_t completed, size_t total, bool started) this->TestHandler->TestResults.push_back(this->TestResult); } delete this->TestProcess; - return passed; + return passed || skipped; } bool cmCTestRunTest::StartAgain() diff --git a/Source/CTest/cmCTestTestHandler.cxx b/Source/CTest/cmCTestTestHandler.cxx index 167fecf..d73811b 100644 --- a/Source/CTest/cmCTestTestHandler.cxx +++ b/Source/CTest/cmCTestTestHandler.cxx @@ -17,6 +17,7 @@ #include <string.h> #include <time.h> +#include "cmAlgorithms.h" #include "cmCTest.h" #include "cmCTestBatchTestHandler.h" #include "cmCTestMultiProcessHandler.h" @@ -495,7 +496,8 @@ int cmCTestTestHandler::ProcessHandler() for (SetOfTests::iterator ftit = resultsSet.begin(); ftit != resultsSet.end(); ++ftit) { - if (ftit->CompletionStatus == "Disabled") { + if (cmHasLiteralPrefix(ftit->CompletionStatus, "SKIP_RETURN_CODE=") || + ftit->CompletionStatus == "Disabled") { disabledTests.push_back(*ftit); } } @@ -521,17 +523,22 @@ int cmCTestTestHandler::ProcessHandler() if (!disabledTests.empty()) { cmGeneratedFileStream ofs; cmCTestLog(this->CTest, HANDLER_OUTPUT, std::endl - << "The following tests are disabled and did not run:" - << std::endl); + << "The following tests did not run:" << std::endl); this->StartLogFile("TestsDisabled", ofs); + const char* disabled_reason; for (std::vector<cmCTestTestHandler::cmCTestTestResult>::iterator dtit = disabledTests.begin(); dtit != disabledTests.end(); ++dtit) { ofs << dtit->TestCount << ":" << dtit->Name << std::endl; + if (dtit->CompletionStatus == "Disabled") { + disabled_reason = "Disabled"; + } else { + disabled_reason = "Skipped"; + } cmCTestLog(this->CTest, HANDLER_OUTPUT, "\t" << std::setw(3) << dtit->TestCount << " - " << dtit->Name - << std::endl); + << " (" << disabled_reason << ")" << std::endl); } } @@ -544,6 +551,7 @@ int cmCTestTestHandler::ProcessHandler() for (SetOfTests::iterator ftit = resultsSet.begin(); ftit != resultsSet.end(); ++ftit) { if (ftit->Status != cmCTestTestHandler::COMPLETED && + !cmHasLiteralPrefix(ftit->CompletionStatus, "SKIP_RETURN_CODE=") && ftit->CompletionStatus != "Disabled") { ofs << ftit->TestCount << ":" << ftit->Name << std::endl; cmCTestLog( @@ -1727,7 +1735,7 @@ void cmCTestTestHandler::ExpandTestsToRunInformationForRerunFailed() // bcc crashes if we attempt a normal substring comparison, // hence the following workaround std::string fileNameSubstring = fileName.substr(0, pattern.length()); - if (fileNameSubstring.compare(pattern) != 0) { + if (fileNameSubstring != pattern) { continue; } if (logName == "") { diff --git a/Source/bindexplib.cxx b/Source/bindexplib.cxx index 6026a57..691e3ae 100644 --- a/Source/bindexplib.cxx +++ b/Source/bindexplib.cxx @@ -235,35 +235,29 @@ public: symbol.erase(posAt); } } - // For i386 builds we don't need to remove _ + // For i386 builds we need to remove _ if (this->IsI386 && symbol[0] == '_') { symbol.erase(0, 1); } - /* - Check whether it is "Scalar deleting destructor" and - "Vector deleting destructor" - */ + // Check whether it is "Scalar deleting destructor" and "Vector + // deleting destructor" + // if scalarPrefix and vectorPrefix are not found then print the + // symbol const char* scalarPrefix = "??_G"; const char* vectorPrefix = "??_E"; - // original code had a check for - // symbol.find("real@") == std::string::npos) - // but if this disallows memmber functions with the name real - // if scalarPrefix and vectorPrefix are not found then print - // the symbol if (symbol.compare(0, 4, scalarPrefix) && symbol.compare(0, 4, vectorPrefix)) { SectChar = this->SectionHeaders[pSymbolTable->SectionNumber - 1] .Characteristics; - if (!pSymbolTable->Type && (SectChar & IMAGE_SCN_MEM_WRITE)) { - // Read only (i.e. constants) must be excluded - this->DataSymbols.insert(symbol); - } else { - if (pSymbolTable->Type || !(SectChar & IMAGE_SCN_MEM_READ) || - (SectChar & IMAGE_SCN_MEM_EXECUTE)) { - this->Symbols.insert(symbol); - } else { - // printf(" strange symbol: %s \n",symbol.c_str()); + + if (SectChar & IMAGE_SCN_MEM_EXECUTE) { + this->Symbols.insert(symbol); + } else if (SectChar & IMAGE_SCN_MEM_READ) { + // skip __real@ and __xmm@ + if (symbol.find("_real") == std::string::npos && + symbol.find("_xmm") == std::string::npos) { + this->DataSymbols.insert(symbol); } } } diff --git a/Source/cmCommonTargetGenerator.cxx b/Source/cmCommonTargetGenerator.cxx index 178a7ce..391d65c 100644 --- a/Source/cmCommonTargetGenerator.cxx +++ b/Source/cmCommonTargetGenerator.cxx @@ -43,17 +43,6 @@ const char* cmCommonTargetGenerator::GetFeature(const std::string& feature) return this->GeneratorTarget->GetFeature(feature, this->ConfigName); } -void cmCommonTargetGenerator::AddFeatureFlags(std::string& flags, - const std::string& lang) -{ - // Add language-specific flags. - this->LocalGenerator->AddLanguageFlags(flags, lang, this->ConfigName); - - if (this->GeneratorTarget->IsIPOEnabled(this->ConfigName)) { - this->LocalGenerator->AppendFeatureOptions(flags, lang, "IPO"); - } -} - void cmCommonTargetGenerator::AddModuleDefinitionFlag( cmLinkLineComputer* linkLineComputer, std::string& flags) { diff --git a/Source/cmCommonTargetGenerator.h b/Source/cmCommonTargetGenerator.h index 8ba2e22..c36145f 100644 --- a/Source/cmCommonTargetGenerator.h +++ b/Source/cmCommonTargetGenerator.h @@ -28,9 +28,6 @@ public: std::string const& GetConfigName() const; protected: - // Add language feature flags. - void AddFeatureFlags(std::string& flags, const std::string& lang); - // Feature query methods. const char* GetFeature(const std::string& feature); diff --git a/Source/cmDocumentation.cxx b/Source/cmDocumentation.cxx index 5f25113..c6286b3 100644 --- a/Source/cmDocumentation.cxx +++ b/Source/cmDocumentation.cxx @@ -129,28 +129,19 @@ bool cmDocumentation::PrintRequestedDocumentation(std::ostream& os) this->CurrentArgument = i->Argument; // If a file name was given, use it. Otherwise, default to the // given stream. - cmsys::ofstream* fout = CM_NULLPTR; + cmsys::ofstream fout; std::ostream* s = &os; if (!i->Filename.empty()) { - fout = new cmsys::ofstream(i->Filename.c_str()); - if (fout) { - s = fout; - } else { - result = false; - } + fout.open(i->Filename.c_str()); + s = &fout; } else if (++count > 1) { os << "\n\n"; } // Print this documentation type to the stream. - if (!this->PrintDocumentation(i->HelpType, *s) || !*s) { + if (!this->PrintDocumentation(i->HelpType, *s) || s->fail()) { result = false; } - - // Close the file if we wrote one. - if (fout) { - delete fout; - } } return result; } diff --git a/Source/cmELF.cxx b/Source/cmELF.cxx index 2a8137f..d23abec 100644 --- a/Source/cmELF.cxx +++ b/Source/cmELF.cxx @@ -44,6 +44,9 @@ typedef struct Elf32_Rela Elf32_Rela; #ifdef _SCO_DS #include <link.h> // For DT_SONAME etc. #endif +#ifndef DT_RUNPATH +#define DT_RUNPATH 29 +#endif // Low-level byte swapping implementation. template <size_t s> @@ -154,11 +157,7 @@ public: // Lookup the RUNPATH in the DYNAMIC section. StringEntry const* GetRunPath() { -#if defined(DT_RUNPATH) return this->GetDynamicSectionString(DT_RUNPATH); -#else - return 0; -#endif } // Return the recorded ELF type. diff --git a/Source/cmGhsMultiTargetGenerator.cxx b/Source/cmGhsMultiTargetGenerator.cxx index ba623d5..7032cd5 100644 --- a/Source/cmGhsMultiTargetGenerator.cxx +++ b/Source/cmGhsMultiTargetGenerator.cxx @@ -232,10 +232,12 @@ void cmGhsMultiTargetGenerator::SetCompilerFlags(std::string const& config, const char* lang = language.c_str(); if (notKernel) { - this->LocalGenerator->AddLanguageFlags(flags, lang, config); + this->LocalGenerator->AddLanguageFlags(flags, this->GeneratorTarget, + lang, config); } else { - this->LocalGenerator->AddLanguageFlags( - flags, lang + std::string("_GHS_KERNEL"), config); + this->LocalGenerator->AddLanguageFlags(flags, this->GeneratorTarget, + lang + std::string("_GHS_KERNEL"), + config); } this->LocalGenerator->AddCMP0018Flags(flags, this->GeneratorTarget, lang, config); diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx index 6636329..d99e3bb 100644 --- a/Source/cmGlobalXCodeGenerator.cxx +++ b/Source/cmGlobalXCodeGenerator.cxx @@ -1662,7 +1662,8 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt, std::string& flags = cflags[lang]; // Add language-specific flags. - this->CurrentLocalGenerator->AddLanguageFlags(flags, lang, configName); + this->CurrentLocalGenerator->AddLanguageFlags(flags, gtgt, lang, + configName); // Add shared-library flags if needed. this->CurrentLocalGenerator->AddCMP0018Flags(flags, gtgt, lang, diff --git a/Source/cmLinkLineDeviceComputer.cxx b/Source/cmLinkLineDeviceComputer.cxx index 6789555..bf30b39 100644 --- a/Source/cmLinkLineDeviceComputer.cxx +++ b/Source/cmLinkLineDeviceComputer.cxx @@ -39,9 +39,24 @@ std::string cmLinkLineDeviceComputer::ComputeLinkLibraries( continue; } - if (li->Target->GetType() == cmStateEnums::INTERFACE_LIBRARY || - li->Target->GetType() == cmStateEnums::SHARED_LIBRARY || - li->Target->GetType() == cmStateEnums::MODULE_LIBRARY) { + bool skippable = false; + switch (li->Target->GetType()) { + case cmStateEnums::SHARED_LIBRARY: + case cmStateEnums::MODULE_LIBRARY: + case cmStateEnums::INTERFACE_LIBRARY: + skippable = true; + break; + case cmStateEnums::STATIC_LIBRARY: + // If a static library is resolving its device linking, it should + // be removed for other device linking + skippable = + li->Target->GetPropertyAsBool("CUDA_RESOLVE_DEVICE_SYMBOLS"); + break; + default: + break; + } + + if (skippable) { continue; } diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index 424ab6f..33e32d1 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -915,6 +915,9 @@ void cmLocalGenerator::GetTargetFlags( const char* libraryLinkVariable = "CMAKE_SHARED_LINKER_FLAGS"; // default to shared library + const std::string linkLanguage = + linkLineComputer->GetLinkerLanguage(target, buildType); + switch (target->GetType()) { case cmStateEnums::STATIC_LIBRARY: this->GetStaticLibraryFlags(linkFlags, buildType, target); @@ -976,16 +979,13 @@ void cmLocalGenerator::GetTargetFlags( linkFlags += this->Makefile->GetSafeDefinition(build); linkFlags += " "; } - - const std::string linkLanguage = - linkLineComputer->GetLinkerLanguage(target, buildType); if (linkLanguage.empty()) { cmSystemTools::Error( "CMake can not determine linker language for target: ", target->GetName().c_str()); return; } - this->AddLanguageFlags(flags, linkLanguage, buildType); + this->AddLanguageFlags(flags, target, linkLanguage, buildType); if (pcli) { this->OutputLinkLibraries(pcli, linkLineComputer, linkLibs, frameworkPath, linkPath); @@ -1040,6 +1040,8 @@ void cmLocalGenerator::GetTargetFlags( default: break; } + + this->AppendIPOLinkerFlags(linkFlags, target, config, linkLanguage); } void cmLocalGenerator::GetTargetCompileFlags(cmGeneratorTarget* target, @@ -1050,11 +1052,7 @@ void cmLocalGenerator::GetTargetCompileFlags(cmGeneratorTarget* target, cmMakefile* mf = this->GetMakefile(); // Add language-specific flags. - this->AddLanguageFlags(flags, lang, config); - - if (target->IsIPOEnabled(config)) { - this->AppendFeatureOptions(flags, lang, "IPO"); - } + this->AddLanguageFlags(flags, target, lang, config); this->AddArchitectureFlags(flags, target, lang, config); @@ -1287,6 +1285,7 @@ void cmLocalGenerator::AddArchitectureFlags(std::string& flags, } void cmLocalGenerator::AddLanguageFlags(std::string& flags, + cmGeneratorTarget const* target, const std::string& lang, const std::string& config) { @@ -1295,6 +1294,10 @@ void cmLocalGenerator::AddLanguageFlags(std::string& flags, flagsVar += lang; flagsVar += "_FLAGS"; this->AddConfigVariableFlags(flags, flagsVar, config); + + if (target->IsIPOEnabled(config)) { + this->AppendFeatureOptions(flags, lang, "IPO"); + } } cmGeneratorTarget* cmLocalGenerator::FindGeneratorTargetToUse( @@ -1768,6 +1771,38 @@ void cmLocalGenerator::AppendFlagEscape(std::string& flags, this->AppendFlags(flags, this->EscapeForShell(rawFlag)); } +void cmLocalGenerator::AppendIPOLinkerFlags(std::string& flags, + cmGeneratorTarget* target, + const std::string& config, + const std::string& lang) +{ + if (!target->IsIPOEnabled(config)) { + return; + } + + switch (target->GetType()) { + case cmStateEnums::EXECUTABLE: + case cmStateEnums::SHARED_LIBRARY: + case cmStateEnums::MODULE_LIBRARY: + break; + default: + return; + } + + const std::string name = "CMAKE_" + lang + "_LINK_OPTIONS_IPO"; + const char* rawFlagsList = this->Makefile->GetDefinition(name); + if (rawFlagsList == CM_NULLPTR) { + return; + } + + std::vector<std::string> flagsList; + cmSystemTools::ExpandListArgument(rawFlagsList, flagsList); + for (std::vector<std::string>::const_iterator oi = flagsList.begin(); + oi != flagsList.end(); ++oi) { + this->AppendFlagEscape(flags, *oi); + } +} + void cmLocalGenerator::AppendDefines(std::set<std::string>& defines, const char* defines_list) const { diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h index 1459a05..1a238a8 100644 --- a/Source/cmLocalGenerator.h +++ b/Source/cmLocalGenerator.h @@ -98,8 +98,8 @@ public: const std::string& lang, const std::string& config); - void AddLanguageFlags(std::string& flags, const std::string& lang, - const std::string& config); + void AddLanguageFlags(std::string& flags, cmGeneratorTarget const* target, + const std::string& lang, const std::string& config); void AddCMP0018Flags(std::string& flags, cmGeneratorTarget const* target, std::string const& lang, const std::string& config); void AddVisibilityPresetFlags(std::string& flags, @@ -115,6 +115,9 @@ public: virtual void AppendFlags(std::string& flags, const char* newFlags); virtual void AppendFlagEscape(std::string& flags, const std::string& rawFlag); + void AppendIPOLinkerFlags(std::string& flags, cmGeneratorTarget* target, + const std::string& config, + const std::string& lang); ///! Get the include flags for the current makefile and language std::string GetIncludeFlags(const std::vector<std::string>& includes, cmGeneratorTarget* target, diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index b8a5293..cb11060 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -3153,7 +3153,7 @@ void cmMakefile::EnableLanguage(std::vector<std::string> const& lang, langs.reserve(lang.size()); for (std::vector<std::string>::const_iterator i = lang.begin(); i != lang.end(); ++i) { - if (i->compare("RC") == 0) { + if (*i == "RC") { langsRC.push_back(*i); } else { langs.push_back(*i); diff --git a/Source/cmMakefileExecutableTargetGenerator.cxx b/Source/cmMakefileExecutableTargetGenerator.cxx index a93b42d..fb39f01 100644 --- a/Source/cmMakefileExecutableTargetGenerator.cxx +++ b/Source/cmMakefileExecutableTargetGenerator.cxx @@ -122,7 +122,11 @@ void cmMakefileExecutableTargetGenerator::WriteDeviceExecutableRule( std::string buildEcho = "Linking "; buildEcho += linkLanguage; buildEcho += " device code "; - buildEcho += targetOutputReal; + buildEcho += this->LocalGenerator->ConvertToOutputFormat( + this->LocalGenerator->MaybeConvertToRelativePath( + this->LocalGenerator->GetCurrentBinaryDirectory(), + this->DeviceLinkObject), + cmOutputConverter::SHELL); this->LocalGenerator->AppendEcho( commands, buildEcho, cmLocalUnixMakefileGenerator3::EchoLink, &progress); } @@ -146,7 +150,8 @@ void cmMakefileExecutableTargetGenerator::WriteDeviceExecutableRule( linkLanguage, *this->GeneratorTarget)); // Add language feature flags. - this->AddFeatureFlags(flags, linkLanguage); + this->LocalGenerator->AddLanguageFlags(flags, this->GeneratorTarget, + linkLanguage, this->ConfigName); this->LocalGenerator->AddArchitectureFlags(flags, this->GeneratorTarget, linkLanguage, this->ConfigName); @@ -429,7 +434,8 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink) } // Add language feature flags. - this->AddFeatureFlags(flags, linkLanguage); + this->LocalGenerator->AddLanguageFlags(flags, this->GeneratorTarget, + linkLanguage, this->ConfigName); this->LocalGenerator->AddArchitectureFlags(flags, this->GeneratorTarget, linkLanguage, this->ConfigName); @@ -451,6 +457,9 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink) this->AddModuleDefinitionFlag(linkLineComputer.get(), linkFlags); } + this->LocalGenerator->AppendIPOLinkerFlags(linkFlags, this->GeneratorTarget, + this->ConfigName, linkLanguage); + // Construct a list of files associated with this executable that // may need to be cleaned. std::vector<std::string> exeCleanFiles; diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx index e017b29..5ee9f45 100644 --- a/Source/cmMakefileLibraryTargetGenerator.cxx +++ b/Source/cmMakefileLibraryTargetGenerator.cxx @@ -127,6 +127,24 @@ void cmMakefileLibraryTargetGenerator::WriteObjectLibraryRules() void cmMakefileLibraryTargetGenerator::WriteStaticLibraryRules() { + const std::string cuda_lang("CUDA"); + cmGeneratorTarget::LinkClosure const* closure = + this->GeneratorTarget->GetLinkClosure(this->ConfigName); + + const bool hasCUDA = + (std::find(closure->Languages.begin(), closure->Languages.end(), + cuda_lang) != closure->Languages.end()); + + const bool resolveDeviceSymbols = + this->GeneratorTarget->GetPropertyAsBool("CUDA_RESOLVE_DEVICE_SYMBOLS"); + if (hasCUDA && resolveDeviceSymbols) { + std::string linkRuleVar = "CMAKE_CUDA_DEVICE_LINK_LIBRARY"; + std::string extraFlags; + this->LocalGenerator->AppendFlags( + extraFlags, this->GeneratorTarget->GetProperty("LINK_FLAGS")); + this->WriteDeviceLibraryRules(linkRuleVar, extraFlags, false); + } + std::string linkLanguage = this->GeneratorTarget->GetLinkerLanguage(this->ConfigName); @@ -292,8 +310,12 @@ void cmMakefileLibraryTargetGenerator::WriteDeviceLibraryRules( cmLocalUnixMakefileGenerator3::EchoProgress progress; this->MakeEchoProgress(progress); // Add the link message. - std::string buildEcho = "Linking " + linkLanguage + " device code"; - buildEcho += targetOutputReal; + std::string buildEcho = "Linking " + linkLanguage + " device code "; + buildEcho += this->LocalGenerator->ConvertToOutputFormat( + this->LocalGenerator->MaybeConvertToRelativePath( + this->LocalGenerator->GetCurrentBinaryDirectory(), + this->DeviceLinkObject), + cmOutputConverter::SHELL); this->LocalGenerator->AppendEcho( commands, buildEcho, cmLocalUnixMakefileGenerator3::EchoLink, &progress); } @@ -373,9 +395,10 @@ void cmMakefileLibraryTargetGenerator::WriteDeviceLibraryRules( vars.LinkFlags = linkFlags.c_str(); vars.TargetCompilePDB = targetOutPathCompilePDB.c_str(); - // Add language feature flags. + // Add language-specific flags. std::string langFlags; - this->AddFeatureFlags(langFlags, linkLanguage); + this->LocalGenerator->AddLanguageFlags(langFlags, this->GeneratorTarget, + linkLanguage, this->ConfigName); vars.LanguageCompileFlags = langFlags.c_str(); @@ -471,6 +494,8 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules( // Create set of linking flags. std::string linkFlags; this->LocalGenerator->AppendFlags(linkFlags, extraFlags); + this->LocalGenerator->AppendIPOLinkerFlags(linkFlags, this->GeneratorTarget, + this->ConfigName, linkLanguage); // Add OSX version flags, if any. if (this->GeneratorTarget->GetType() == cmStateEnums::SHARED_LIBRARY || @@ -831,9 +856,10 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules( } } - // Add language feature flags. + // Add language-specific flags. std::string langFlags; - this->AddFeatureFlags(langFlags, linkLanguage); + this->LocalGenerator->AddLanguageFlags(langFlags, this->GeneratorTarget, + linkLanguage, this->ConfigName); this->LocalGenerator->AddArchitectureFlags( langFlags, this->GeneratorTarget, linkLanguage, this->ConfigName); @@ -857,6 +883,16 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules( std::vector<std::string> object_strings; this->WriteObjectsStrings(object_strings, archiveCommandLimit); + // Add the cuda device object to the list of archive files. This will + // only occur on archives which have CUDA_RESOLVE_DEVICE_SYMBOLS enabled + if (!this->DeviceLinkObject.empty()) { + object_strings.push_back(this->LocalGenerator->ConvertToOutputFormat( + this->LocalGenerator->MaybeConvertToRelativePath( + this->LocalGenerator->GetCurrentBinaryDirectory(), + this->DeviceLinkObject), + cmOutputConverter::SHELL)); + } + // Create the archive with the first set of objects. std::vector<std::string>::iterator osi = object_strings.begin(); { diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx index cfc91bd..54ae196 100644 --- a/Source/cmNinjaNormalTargetGenerator.cxx +++ b/Source/cmNinjaNormalTargetGenerator.cxx @@ -447,6 +447,7 @@ std::vector<std::string> cmNinjaNormalTargetGenerator::ComputeDeviceLinkCmd() // an executable or a dynamic library. std::string linkCmd; switch (this->GetGeneratorTarget()->GetType()) { + case cmStateEnums::STATIC_LIBRARY: case cmStateEnums::SHARED_LIBRARY: case cmStateEnums::MODULE_LIBRARY: { const std::string cudaLinkCmd( @@ -559,11 +560,15 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkStatement() case cmStateEnums::EXECUTABLE: shouldHaveDeviceLinking = true; break; + case cmStateEnums::STATIC_LIBRARY: + shouldHaveDeviceLinking = + genTarget.GetPropertyAsBool("CUDA_RESOLVE_DEVICE_SYMBOLS"); + break; default: break; } - if (!shouldHaveDeviceLinking || !hasCUDA) { + if (!(shouldHaveDeviceLinking && hasCUDA)) { return; } @@ -650,7 +655,7 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkStatement() localGen.AddArchitectureFlags(t, &genTarget, cudaLinkLanguage, cfgName); vars["ARCH_FLAGS"] = t; t = ""; - localGen.AddLanguageFlags(t, cudaLinkLanguage, cfgName); + localGen.AddLanguageFlags(t, &genTarget, cudaLinkLanguage, cfgName); vars["LANGUAGE_COMPILE_FLAGS"] = t; } if (this->GetGeneratorTarget()->HasSOName(cfgName)) { @@ -869,7 +874,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement() vars["ARCH_FLAGS"] = t; t = ""; t += lwyuFlags; - localGen.AddLanguageFlags(t, TargetLinkLanguage, cfgName); + localGen.AddLanguageFlags(t, &genTarget, TargetLinkLanguage, cfgName); vars["LANGUAGE_COMPILE_FLAGS"] = t; } if (this->GetGeneratorTarget()->HasSOName(cfgName)) { diff --git a/Source/cmSeparateArgumentsCommand.cxx b/Source/cmSeparateArgumentsCommand.cxx index b27d227..7b222a0 100644 --- a/Source/cmSeparateArgumentsCommand.cxx +++ b/Source/cmSeparateArgumentsCommand.cxx @@ -40,6 +40,13 @@ bool cmSeparateArgumentsCommand::InitialPass( if (doing == DoingVariable) { var = args[i]; doing = DoingMode; + } else if (doing == DoingMode && args[i] == "NATIVE_COMMAND") { +#ifdef _WIN32 + mode = ModeWindows; +#else + mode = ModeUnix; +#endif + doing = DoingCommand; } else if (doing == DoingMode && args[i] == "UNIX_COMMAND") { mode = ModeUnix; doing = DoingCommand; diff --git a/Source/cmServerProtocol.cxx b/Source/cmServerProtocol.cxx index 8227ab7..11ee897 100644 --- a/Source/cmServerProtocol.cxx +++ b/Source/cmServerProtocol.cxx @@ -50,9 +50,8 @@ std::vector<std::string> getConfigurations(const cmake* cm) bool hasString(const Json::Value& v, const std::string& s) { return !v.isNull() && - std::find_if(v.begin(), v.end(), [s](const Json::Value& i) { - return i.asString() == s; - }) != v.end(); + std::any_of(v.begin(), v.end(), + [s](const Json::Value& i) { return i.asString() == s; }); } template <class T> @@ -493,16 +492,14 @@ cmServerResponse cmServerProtocol1_0::ProcessCache( if (keys.empty()) { keys = allKeys; } else { - for (auto i : keys) { - if (std::find_if(allKeys.begin(), allKeys.end(), - [i](const std::string& j) { return i == j; }) == - allKeys.end()) { + for (const auto& i : keys) { + if (std::find(allKeys.begin(), allKeys.end(), i) == allKeys.end()) { return request.ReportError("Key \"" + i + "\" not found in cache."); } } } std::sort(keys.begin(), keys.end()); - for (auto key : keys) { + for (const auto& key : keys) { Json::Value entry = Json::objectValue; entry[kKEY_KEY] = key; entry[kTYPE_KEY] = @@ -511,7 +508,7 @@ cmServerResponse cmServerProtocol1_0::ProcessCache( Json::Value props = Json::objectValue; bool haveProperties = false; - for (auto prop : state->GetCacheEntryPropertyList(key)) { + for (const auto& prop : state->GetCacheEntryPropertyList(key)) { haveProperties = true; props[prop] = state->GetCacheEntryProperty(key, prop); } @@ -598,7 +595,7 @@ bool LanguageData::operator==(const LanguageData& other) const void LanguageData::SetDefines(const std::set<std::string>& defines) { std::vector<std::string> result; - for (auto i : defines) { + for (const auto& i : defines) { result.push_back(i); } std::sort(result.begin(), result.end()); @@ -615,11 +612,11 @@ struct hash<LanguageData> using std::hash; size_t result = hash<std::string>()(in.Language) ^ hash<std::string>()(in.Flags); - for (auto i : in.IncludePathList) { + for (const auto& i : in.IncludePathList) { result = result ^ (hash<std::string>()(i.first) ^ (i.second ? std::numeric_limits<size_t>::max() : 0)); } - for (auto i : in.Defines) { + for (const auto& i : in.Defines) { result = result ^ hash<std::string>()(i); } result = @@ -643,7 +640,7 @@ static Json::Value DumpSourceFileGroup(const LanguageData& data, } if (!data.IncludePathList.empty()) { Json::Value includes = Json::arrayValue; - for (auto i : data.IncludePathList) { + for (const auto& i : data.IncludePathList) { Json::Value tmp = Json::objectValue; tmp[kPATH_KEY] = i.first; if (i.second) { @@ -661,7 +658,7 @@ static Json::Value DumpSourceFileGroup(const LanguageData& data, result[kIS_GENERATED_KEY] = data.IsGenerated; Json::Value sourcesValue = Json::arrayValue; - for (auto i : files) { + for (const auto& i : files) { const std::string relPath = cmSystemTools::RelativePath(baseDir.c_str(), i.c_str()); sourcesValue.append(relPath.size() < i.size() ? relPath : i); @@ -819,7 +816,7 @@ static Json::Value DumpTarget(cmGeneratorTarget* target, std::set<std::string> languages; target->GetLanguages(languages, config); std::map<std::string, LanguageData> languageDataMap; - for (auto lang : languages) { + for (const auto& lang : languages) { LanguageData& ld = languageDataMap[lang]; ld.Language = lang; lg->GetTargetCompileFlags(target, config, lang, ld.Flags); @@ -1095,7 +1092,7 @@ cmServerResponse cmServerProtocol1_0::ProcessSetGlobalSettings( kWARN_UNINITIALIZED_KEY, kWARN_UNUSED_KEY, kWARN_UNUSED_CLI_KEY, kCHECK_SYSTEM_VARS_KEY }; - for (auto i : boolValues) { + for (const auto& i : boolValues) { if (!request.Data[i].isNull() && !request.Data[i].isBool()) { return request.ReportError("\"" + i + "\" must be unset or a bool value."); diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index d83662e..5a09718 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -116,6 +116,10 @@ cmVisualStudio10TargetGenerator::~cmVisualStudio10TargetGenerator() i != this->CudaOptions.end(); ++i) { delete i->second; } + for (OptionsMap::iterator i = this->CudaLinkOptions.begin(); + i != this->CudaLinkOptions.end(); ++i) { + delete i->second; + } if (!this->BuildFileStream) { return; } @@ -213,6 +217,9 @@ void cmVisualStudio10TargetGenerator::Generate() if (!this->ComputeCudaOptions()) { return; } + if (!this->ComputeCudaLinkOptions()) { + return; + } if (!this->ComputeMasmOptions()) { return; } @@ -2524,6 +2531,70 @@ void cmVisualStudio10TargetGenerator::WriteCudaOptions( this->WriteString("</CudaCompile>\n", 2); } +bool cmVisualStudio10TargetGenerator::ComputeCudaLinkOptions() +{ + if (!this->GlobalGenerator->IsCudaEnabled()) { + return true; + } + for (std::vector<std::string>::const_iterator i = + this->Configurations.begin(); + i != this->Configurations.end(); ++i) { + if (!this->ComputeCudaLinkOptions(*i)) { + return false; + } + } + return true; +} + +bool cmVisualStudio10TargetGenerator::ComputeCudaLinkOptions( + std::string const& configName) +{ + cmGlobalVisualStudio10Generator* gg = + static_cast<cmGlobalVisualStudio10Generator*>(this->GlobalGenerator); + CM_AUTO_PTR<Options> pOptions(new Options( + this->LocalGenerator, Options::CudaCompiler, gg->GetCudaFlagTable())); + Options& cudaLinkOptions = *pOptions; + + // Determine if we need to do a device link + bool doDeviceLinking = false; + switch (this->GeneratorTarget->GetType()) { + case cmStateEnums::SHARED_LIBRARY: + case cmStateEnums::MODULE_LIBRARY: + case cmStateEnums::EXECUTABLE: + doDeviceLinking = true; + break; + case cmStateEnums::STATIC_LIBRARY: + doDeviceLinking = this->GeneratorTarget->GetPropertyAsBool( + "CUDA_RESOLVE_DEVICE_SYMBOLS"); + break; + default: + break; + } + + cudaLinkOptions.AddFlag("PerformDeviceLink", + doDeviceLinking ? "true" : "false"); + + this->CudaLinkOptions[configName] = pOptions.release(); + return true; +} + +void cmVisualStudio10TargetGenerator::WriteCudaLinkOptions( + std::string const& configName) +{ + if (this->GeneratorTarget->GetType() > cmStateEnums::MODULE_LIBRARY) { + return; + } + + if (!this->MSTools || !this->GlobalGenerator->IsCudaEnabled()) { + return; + } + + this->WriteString("<CudaLink>\n", 2); + Options& cudaLinkOptions = *(this->CudaLinkOptions[configName]); + cudaLinkOptions.OutputFlagMap(*this->BuildFileStream, " "); + this->WriteString("</CudaLink>\n", 2); +} + bool cmVisualStudio10TargetGenerator::ComputeMasmOptions() { if (!this->GlobalGenerator->IsMasmEnabled()) { @@ -3283,6 +3354,7 @@ void cmVisualStudio10TargetGenerator::WriteItemDefinitionGroups() } // output link flags <Link></Link> this->WriteLinkOptions(*i); + this->WriteCudaLinkOptions(*i); // output lib flags <Lib></Lib> this->WriteLibOptions(*i); // output manifest flags <Manifest></Manifest> diff --git a/Source/cmVisualStudio10TargetGenerator.h b/Source/cmVisualStudio10TargetGenerator.h index bd270bf..6106615 100644 --- a/Source/cmVisualStudio10TargetGenerator.h +++ b/Source/cmVisualStudio10TargetGenerator.h @@ -101,6 +101,11 @@ private: bool ComputeCudaOptions(std::string const& config); void WriteCudaOptions(std::string const& config, std::vector<std::string> const& includes); + + bool ComputeCudaLinkOptions(); + bool ComputeCudaLinkOptions(std::string const& config); + void WriteCudaLinkOptions(std::string const& config); + bool ComputeMasmOptions(); bool ComputeMasmOptions(std::string const& config); void WriteMasmOptions(std::string const& config, @@ -154,6 +159,7 @@ private: OptionsMap ClOptions; OptionsMap RcOptions; OptionsMap CudaOptions; + OptionsMap CudaLinkOptions; OptionsMap MasmOptions; OptionsMap NasmOptions; OptionsMap LinkOptions; diff --git a/Tests/CMakeTests/CMakeLists.txt b/Tests/CMakeTests/CMakeLists.txt index 1cca35d..1619081 100644 --- a/Tests/CMakeTests/CMakeLists.txt +++ b/Tests/CMakeTests/CMakeLists.txt @@ -19,7 +19,6 @@ AddCMakeTest(GetFilenameComponentRealpath "") AddCMakeTest(Version "") AddCMakeTest(Message "") AddCMakeTest(File "") -AddCMakeTest(SeparateArguments "") AddCMakeTest(ImplicitLinkInfo "") AddCMakeTest(ModuleNotices "") AddCMakeTest(GetProperty "") diff --git a/Tests/CMakeTests/SeparateArgumentsTest.cmake.in b/Tests/CMakeTests/SeparateArgumentsTest.cmake.in deleted file mode 100644 index 48964b8..0000000 --- a/Tests/CMakeTests/SeparateArgumentsTest.cmake.in +++ /dev/null @@ -1,25 +0,0 @@ -set(old_out "a b c") -separate_arguments(old_out) -set(old_exp "a;b;;c") - -set(unix_cmd "a \"b c\" 'd e' \";\" \\ \\'\\\" '\\'' \"\\\"\"") -set(unix_exp "a;b c;d e;\;; '\";';\"") -separate_arguments(unix_out UNIX_COMMAND "${unix_cmd}") - -set(windows_cmd "a \"b c\" 'd e' \";\" \\ \"c:\\windows\\path\\\\\" \\\"") -set(windows_exp "a;b c;'d;e';\;;\\;c:\\windows\\path\\;\"") -separate_arguments(windows_out WINDOWS_COMMAND "${windows_cmd}") - -foreach(mode old unix windows) - if(NOT "${${mode}_out}" STREQUAL "${${mode}_exp}") - message(FATAL_ERROR "separate_arguments ${mode}-style failed. " - "Expected\n [${${mode}_exp}]\nbut got\n [${${mode}_out}]\n") - endif() -endforeach() - -set(nothing) -separate_arguments(nothing) -if(DEFINED nothing) - message(FATAL_ERROR "separate_arguments null-case failed: " - "nothing=[${nothing}]") -endif() diff --git a/Tests/Cuda/Complex/dynamic.cu b/Tests/Cuda/Complex/dynamic.cu index f677868..a76973d 100644 --- a/Tests/Cuda/Complex/dynamic.cu +++ b/Tests/Cuda/Complex/dynamic.cu @@ -37,7 +37,7 @@ EXPORT int choose_cuda_device() << std::endl; return 1; } - if (prop.major >= 4) { + if (prop.major >= 3) { err = cudaSetDevice(i); if (err != cudaSuccess) { std::cout << "Could not select CUDA device " << i << std::endl; diff --git a/Tests/CudaOnly/CMakeLists.txt b/Tests/CudaOnly/CMakeLists.txt index a3bd707..5f456fc 100644 --- a/Tests/CudaOnly/CMakeLists.txt +++ b/Tests/CudaOnly/CMakeLists.txt @@ -3,3 +3,4 @@ ADD_TEST_MACRO(CudaOnly.EnableStandard CudaOnlyEnableStandard) ADD_TEST_MACRO(CudaOnly.ExportPTX CudaOnlyExportPTX) ADD_TEST_MACRO(CudaOnly.SeparateCompilation CudaOnlySeparateCompilation) ADD_TEST_MACRO(CudaOnly.WithDefs CudaOnlyWithDefs) +ADD_TEST_MACRO(CudaOnly.ResolveDeviceSymbols CudaOnlyResolveDeviceSymbols) diff --git a/Tests/CudaOnly/ResolveDeviceSymbols/CMakeLists.txt b/Tests/CudaOnly/ResolveDeviceSymbols/CMakeLists.txt new file mode 100644 index 0000000..b96bb98 --- /dev/null +++ b/Tests/CudaOnly/ResolveDeviceSymbols/CMakeLists.txt @@ -0,0 +1,52 @@ +cmake_minimum_required(VERSION 3.7) +project (CudaOnlyResolveDeviceSymbols CUDA) + +# Find nm and dumpbin +if(CMAKE_NM) + set(dump_command ${CMAKE_NM}) + set(dump_args -g) +else() + include(GetPrerequisites) + message(STATUS "calling list_prerequisites to find dumpbin") + list_prerequisites("${CMAKE_COMMAND}" 0 0 0) + if(gp_dumpbin) + set(dump_command ${gp_dumpbin}) + set(dump_args /ARCHIVEMEMBERS) + endif() +endif() + +#Goal for this example: +#Build a static library that defines multiple methods and kernels that +#use each other. +#Use a custom command to build an executable that uses this static library +#We do these together to verify that we can get a static library to do +#device symbol linking, and not have it done when the executable is made +string(APPEND CMAKE_CUDA_FLAGS " -gencode arch=compute_30,code=compute_30") +set(CMAKE_CXX_STANDARD 11) +set(CMAKE_CUDA_STANDARD 11) + +add_library(CUDAResolveDeviceLib STATIC file1.cu file2.cu) +set_target_properties(CUDAResolveDeviceLib + PROPERTIES + CUDA_SEPARABLE_COMPILATION ON + CUDA_RESOLVE_DEVICE_SYMBOLS ON + POSITION_INDEPENDENT_CODE ON) + +if(dump_command) +add_custom_command(TARGET CUDAResolveDeviceLib POST_BUILD + COMMAND ${CMAKE_COMMAND} + -DDUMP_COMMAND=${dump_command} + -DDUMP_ARGS=${dump_args} + -DTEST_LIBRARY_PATH=$<TARGET_FILE:CUDAResolveDeviceLib> + -P ${CMAKE_CURRENT_SOURCE_DIR}/verify.cmake + ) +endif() + +add_executable(CudaOnlyResolveDeviceSymbols main.cu) +target_link_libraries(CudaOnlyResolveDeviceSymbols PRIVATE CUDAResolveDeviceLib) + +if(APPLE) + # We need to add the default path to the driver (libcuda.dylib) as an rpath, so that + # the static cuda runtime can find it at runtime. + target_link_libraries(CudaOnlyResolveDeviceSymbols PRIVATE -Wl,-rpath,/usr/local/cuda/lib) +endif() diff --git a/Tests/CudaOnly/ResolveDeviceSymbols/file1.cu b/Tests/CudaOnly/ResolveDeviceSymbols/file1.cu new file mode 100644 index 0000000..1ce63bf --- /dev/null +++ b/Tests/CudaOnly/ResolveDeviceSymbols/file1.cu @@ -0,0 +1,10 @@ + +#include "file1.h" + +result_type __device__ file1_func(int x) +{ + result_type r; + r.input = x; + r.sum = x * x; + return r; +} diff --git a/Tests/CudaOnly/ResolveDeviceSymbols/file1.h b/Tests/CudaOnly/ResolveDeviceSymbols/file1.h new file mode 100644 index 0000000..ff1945c --- /dev/null +++ b/Tests/CudaOnly/ResolveDeviceSymbols/file1.h @@ -0,0 +1,7 @@ + +#pragma once +struct result_type +{ + int input; + int sum; +}; diff --git a/Tests/CudaOnly/ResolveDeviceSymbols/file2.cu b/Tests/CudaOnly/ResolveDeviceSymbols/file2.cu new file mode 100644 index 0000000..278fd6c --- /dev/null +++ b/Tests/CudaOnly/ResolveDeviceSymbols/file2.cu @@ -0,0 +1,25 @@ + +#include "file2.h" + +result_type __device__ file1_func(int x); + +result_type_dynamic __device__ file2_func(int x) +{ + const result_type r = file1_func(x); + const result_type_dynamic rd{ r.input, r.sum, true }; + return rd; +} + +static __global__ void file2_kernel(result_type_dynamic& r, int x) +{ + // call static_func which is a method that is defined in the + // static library that is always out of date + r = file2_func(x); +} + +int file2_launch_kernel(int x) +{ + result_type_dynamic r; + file2_kernel<<<1, 1>>>(r, x); + return r.sum; +} diff --git a/Tests/CudaOnly/ResolveDeviceSymbols/file2.h b/Tests/CudaOnly/ResolveDeviceSymbols/file2.h new file mode 100644 index 0000000..d2dbaa4 --- /dev/null +++ b/Tests/CudaOnly/ResolveDeviceSymbols/file2.h @@ -0,0 +1,10 @@ + +#pragma once +#include "file1.h" + +struct result_type_dynamic +{ + int input; + int sum; + bool from_static; +}; diff --git a/Tests/CudaOnly/ResolveDeviceSymbols/main.cu b/Tests/CudaOnly/ResolveDeviceSymbols/main.cu new file mode 100644 index 0000000..b4b5b9e --- /dev/null +++ b/Tests/CudaOnly/ResolveDeviceSymbols/main.cu @@ -0,0 +1,85 @@ + +#include <iostream> + +#include "file1.h" +#include "file2.h" + +int file2_launch_kernel(int x); + +result_type_dynamic __device__ file2_func(int x); +static __global__ void main_kernel(result_type_dynamic& r, int x) +{ + // call function that was not device linked to us, this will cause + // a runtime failure of "invalid device function" + r = file2_func(x); +} + +int main_launch_kernel(int x) +{ + result_type_dynamic r; + main_kernel<<<1, 1>>>(r, x); + return r.sum; +} + +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; + } + std::cout << "prop.major: " << prop.major << std::endl; + 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) +{ + int ret = choose_cuda_device(); + if (ret) { + return 0; + } + + cudaError_t err; + file2_launch_kernel(42); + err = cudaGetLastError(); + if (err != cudaSuccess) { + std::cerr << "file2_launch_kernel: kernel launch failed: " + << cudaGetErrorString(err) << std::endl; + return 1; + } + + main_launch_kernel(1); + err = cudaGetLastError(); + if (err == cudaSuccess) { + // This kernel launch should fail as the file2_func was device linked + // into the static library and is not usable by the executable + std::cerr << "main_launch_kernel: kernel launch should have failed" + << std::endl; + return 1; + } + + return 0; +} diff --git a/Tests/CudaOnly/ResolveDeviceSymbols/verify.cmake b/Tests/CudaOnly/ResolveDeviceSymbols/verify.cmake new file mode 100644 index 0000000..94d388b --- /dev/null +++ b/Tests/CudaOnly/ResolveDeviceSymbols/verify.cmake @@ -0,0 +1,14 @@ +execute_process(COMMAND ${DUMP_COMMAND} ${DUMP_ARGS} ${TEST_LIBRARY_PATH} + RESULT_VARIABLE RESULT + OUTPUT_VARIABLE OUTPUT + ERROR_VARIABLE ERROR +) + +if(NOT "${RESULT}" STREQUAL "0") + message(FATAL_ERROR "${DUMP_COMMAND} failed [${RESULT}] [${OUTPUT}] [${ERROR}]") +endif() + +if(NOT "${OUTPUT}" MATCHES "(cmake_device_link|device-link)") + message(FATAL_ERROR + "No cuda device objects found, device linking did not occur") +endif() diff --git a/Tests/CudaOnly/SeparateCompilation/CMakeLists.txt b/Tests/CudaOnly/SeparateCompilation/CMakeLists.txt index 420d7a9..0a2542a 100644 --- a/Tests/CudaOnly/SeparateCompilation/CMakeLists.txt +++ b/Tests/CudaOnly/SeparateCompilation/CMakeLists.txt @@ -12,6 +12,7 @@ project (CudaOnlySeparateCompilation CUDA) string(APPEND CMAKE_CUDA_FLAGS " -gencode arch=compute_30,code=compute_30") set(CMAKE_CXX_STANDARD 11) set(CMAKE_CUDA_STANDARD 11) + add_library(CUDASeparateLibA STATIC file1.cu file2.cu file3.cu) #Having file4/file5 in a shared library causes serious problems @@ -22,12 +23,24 @@ add_library(CUDASeparateLibB STATIC file4.cu file5.cu) target_link_libraries(CUDASeparateLibB PRIVATE CUDASeparateLibA) add_executable(CudaOnlySeparateCompilation main.cu) -target_link_libraries(CudaOnlySeparateCompilation PRIVATE CUDASeparateLibB) +target_link_libraries(CudaOnlySeparateCompilation + PRIVATE CUDASeparateLibB) + +set_target_properties(CUDASeparateLibA + CUDASeparateLibB + PROPERTIES CUDA_SEPARABLE_COMPILATION ON + POSITION_INDEPENDENT_CODE ON) -set_target_properties( CUDASeparateLibA - CUDASeparateLibB - PROPERTIES CUDA_SEPARABLE_COMPILATION ON) +if (CMAKE_GENERATOR MATCHES "^Visual Studio") + #Visual Studio CUDA integration will not perform device linking + #on a target that itself does not have GenerateRelocatableDeviceCode + #enabled. + set_target_properties(CudaOnlySeparateCompilation + PROPERTIES CUDA_SEPARABLE_COMPILATION ON) +endif() -set_target_properties( CUDASeparateLibA - CUDASeparateLibB - PROPERTIES POSITION_INDEPENDENT_CODE ON) +if (APPLE) + # We need to add the default path to the driver (libcuda.dylib) as an rpath, so that + # the static cuda runtime can find it at runtime. + target_link_libraries(CudaOnlySeparateCompilation PRIVATE -Wl,-rpath,/usr/local/cuda/lib) +endif() diff --git a/Tests/CudaOnly/SeparateCompilation/main.cu b/Tests/CudaOnly/SeparateCompilation/main.cu index 03e0921..40dbe5d 100644 --- a/Tests/CudaOnly/SeparateCompilation/main.cu +++ b/Tests/CudaOnly/SeparateCompilation/main.cu @@ -7,9 +7,62 @@ int file4_launch_kernel(int x); int file5_launch_kernel(int x); +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) { + int ret = choose_cuda_device(); + if (ret) { + return 0; + } + + cudaError_t err; file4_launch_kernel(42); + err = cudaGetLastError(); + if (err != cudaSuccess) { + std::cerr << "file4_launch_kernel: kernel launch failed: " + << cudaGetErrorString(err) << std::endl; + return 1; + } + file5_launch_kernel(42); + err = cudaGetLastError(); + if (err != cudaSuccess) { + std::cerr << "file5_launch_kernel: kernel launch failed: " + << cudaGetErrorString(err) << std::endl; + return 1; + } + return 0; } diff --git a/Tests/FindOpenMP/Test/CMakeLists.txt b/Tests/FindOpenMP/Test/CMakeLists.txt index 4ba0e5c..6313ef6 100644 --- a/Tests/FindOpenMP/Test/CMakeLists.txt +++ b/Tests/FindOpenMP/Test/CMakeLists.txt @@ -39,11 +39,7 @@ foreach(c C CXX Fortran) add_test(NAME test_tgt_${c} COMMAND test_tgt_${c}) add_executable(test_var_${c} ${OpenMPTEST_SOURCE_FILE}) - if(CMAKE_HOST_WIN32) - separate_arguments(_OpenMP_${c}_OPTIONS WINDOWS_COMMAND "${OpenMP_${c}_FLAGS}") - else() - separate_arguments(_OpenMP_${c}_OPTIONS UNIX_COMMAND "${OpenMP_${c}_FLAGS}") - endif() + separate_arguments(_OpenMP_${c}_OPTIONS NATIVE_COMMAND "${OpenMP_${c}_FLAGS}") target_compile_options(test_var_${c} PRIVATE "${_OpenMP_${c}_OPTIONS}") target_link_libraries(test_var_${c} PRIVATE "${OpenMP_${c}_FLAGS}") set_property(TARGET test_var_${c} PROPERTY LINKER_LANGUAGE ${c}) diff --git a/Tests/RunCMake/AutoExportDll/foo.c b/Tests/RunCMake/AutoExportDll/foo.c index 4b1318b..e70fbb5 100644 --- a/Tests/RunCMake/AutoExportDll/foo.c +++ b/Tests/RunCMake/AutoExportDll/foo.c @@ -13,3 +13,5 @@ int bar() { return 5; } + +const char testconst[] = "testconst"; diff --git a/Tests/RunCMake/AutoExportDll/say.cxx b/Tests/RunCMake/AutoExportDll/say.cxx index 51060e8..eb9c0ff 100644 --- a/Tests/RunCMake/AutoExportDll/say.cxx +++ b/Tests/RunCMake/AutoExportDll/say.cxx @@ -13,6 +13,14 @@ int WINAPI foo(); int bar(); int objlib(); void justnop(); + +// test const export +#ifdef _WIN32 +// data symbols must be explicitly imported +__declspec(dllimport) extern const char testconst[]; +#else +extern const char testconst[]; +#endif } // test c++ functions @@ -43,6 +51,8 @@ int main() bar(); objlib(); printf("\n"); + printf("%s", testconst); + printf("\n"); #ifdef HAS_JUSTNOP justnop(); #endif diff --git a/Tests/RunCMake/BuildDepends/MakeCustomIncludes.cmake b/Tests/RunCMake/BuildDepends/MakeCustomIncludes.cmake new file mode 100644 index 0000000..0f92e0e --- /dev/null +++ b/Tests/RunCMake/BuildDepends/MakeCustomIncludes.cmake @@ -0,0 +1,13 @@ +add_custom_command( + OUTPUT output.cxx + COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/MakeCustomIncludes.cxx output.cxx + DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/MakeCustomIncludes.cxx + IMPLICIT_DEPENDS CXX ${CMAKE_CURRENT_SOURCE_DIR}/MakeCustomIncludes.cxx) +add_custom_target(generate ALL DEPENDS output.cxx) +set_property(TARGET generate PROPERTY INCLUDE_DIRECTORIES ${CMAKE_CURRENT_BINARY_DIR}) + +file(GENERATE OUTPUT check-$<LOWER_CASE:$<CONFIG>>.cmake CONTENT " +set(check_pairs + \"${CMAKE_CURRENT_BINARY_DIR}/output.cxx|${CMAKE_CURRENT_BINARY_DIR}/MakeCustomIncludes.h\" + ) +") diff --git a/Tests/RunCMake/BuildDepends/MakeCustomIncludes.cxx b/Tests/RunCMake/BuildDepends/MakeCustomIncludes.cxx new file mode 100644 index 0000000..9a0edef --- /dev/null +++ b/Tests/RunCMake/BuildDepends/MakeCustomIncludes.cxx @@ -0,0 +1,6 @@ +#include "MakeCustomIncludes.h" + +int main() +{ + return MakeCustomIncludes(); +} diff --git a/Tests/RunCMake/BuildDepends/MakeCustomIncludes.step1.cmake b/Tests/RunCMake/BuildDepends/MakeCustomIncludes.step1.cmake new file mode 100644 index 0000000..6bb01a6 --- /dev/null +++ b/Tests/RunCMake/BuildDepends/MakeCustomIncludes.step1.cmake @@ -0,0 +1,3 @@ +file(WRITE "${RunCMake_TEST_BINARY_DIR}/MakeCustomIncludes.h" [[ +inline int MakeCustomIncludes() { return 1; } +]]) diff --git a/Tests/RunCMake/BuildDepends/MakeCustomIncludes.step2.cmake b/Tests/RunCMake/BuildDepends/MakeCustomIncludes.step2.cmake new file mode 100644 index 0000000..6b3151d --- /dev/null +++ b/Tests/RunCMake/BuildDepends/MakeCustomIncludes.step2.cmake @@ -0,0 +1,3 @@ +file(WRITE "${RunCMake_TEST_BINARY_DIR}/MakeCustomIncludes.h" [[ +inline int MakeCustomIncludes() { return 2; } +]]) diff --git a/Tests/RunCMake/BuildDepends/RunCMakeTest.cmake b/Tests/RunCMake/BuildDepends/RunCMakeTest.cmake index 67a6101..9941c70 100644 --- a/Tests/RunCMake/BuildDepends/RunCMakeTest.cmake +++ b/Tests/RunCMake/BuildDepends/RunCMakeTest.cmake @@ -43,9 +43,11 @@ endif() run_BuildDepends(Custom-Symbolic-and-Byproduct) run_BuildDepends(Custom-Always) -if(RunCMake_GENERATOR MATCHES "Make" AND - NOT "${RunCMake_BINARY_DIR}" STREQUAL "${RunCMake_SOURCE_DIR}") - run_BuildDepends(MakeInProjectOnly) +if(RunCMake_GENERATOR MATCHES "Make") + run_BuildDepends(MakeCustomIncludes) + if(NOT "${RunCMake_BINARY_DIR}" STREQUAL "${RunCMake_SOURCE_DIR}") + run_BuildDepends(MakeInProjectOnly) + endif() endif() function(run_ReGeneration) diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt index 7db5243..75d4e29 100644 --- a/Tests/RunCMake/CMakeLists.txt +++ b/Tests/RunCMake/CMakeLists.txt @@ -199,6 +199,7 @@ add_RunCMake_test(ctest_start) add_RunCMake_test(ctest_submit) add_RunCMake_test(ctest_test) add_RunCMake_test(ctest_disabled_test) +add_RunCMake_test(ctest_skipped_test) add_RunCMake_test(ctest_upload) add_RunCMake_test(ctest_fixtures) add_RunCMake_test(file) @@ -216,6 +217,7 @@ add_RunCMake_test(list) add_RunCMake_test(message) add_RunCMake_test(project -DCMake_TEST_RESOURCES=${CMake_TEST_RESOURCES}) add_RunCMake_test(return) +add_RunCMake_test(separate_arguments) add_RunCMake_test(set_property) add_RunCMake_test(string) foreach(var diff --git a/Tests/RunCMake/ctest_disabled_test/DisableCleanupTest-stdout.txt b/Tests/RunCMake/ctest_disabled_test/DisableCleanupTest-stdout.txt index ee0dc51..9449e65 100644 --- a/Tests/RunCMake/ctest_disabled_test/DisableCleanupTest-stdout.txt +++ b/Tests/RunCMake/ctest_disabled_test/DisableCleanupTest-stdout.txt @@ -7,5 +7,5 @@ + Total Test time \(real\) = +[0-9.]+ sec + -The following tests are disabled and did not run: -.*2 \- CleanupTest +The following tests did not run: +.*2 \- CleanupTest \(Disabled\) diff --git a/Tests/RunCMake/ctest_disabled_test/DisableFailingTest-stdout.txt b/Tests/RunCMake/ctest_disabled_test/DisableFailingTest-stdout.txt index e2c9f92..486722e 100644 --- a/Tests/RunCMake/ctest_disabled_test/DisableFailingTest-stdout.txt +++ b/Tests/RunCMake/ctest_disabled_test/DisableFailingTest-stdout.txt @@ -2,8 +2,8 @@ + Total Test time \(real\) = +[0-9.]+ sec + -The following tests are disabled and did not run: -.*3 \- DisabledFailingTest +The following tests did not run: +.*3 \- DisabledFailingTest \(Disabled\) + The following tests FAILED: .*2 \- FailingTest \(Failed\) diff --git a/Tests/RunCMake/ctest_disabled_test/DisableNotRunTest-stdout.txt b/Tests/RunCMake/ctest_disabled_test/DisableNotRunTest-stdout.txt index d8bf966..9078aeb 100644 --- a/Tests/RunCMake/ctest_disabled_test/DisableNotRunTest-stdout.txt +++ b/Tests/RunCMake/ctest_disabled_test/DisableNotRunTest-stdout.txt @@ -10,8 +10,8 @@ + Total Test time \(real\) = +[0-9.]+ sec + -The following tests are disabled and did not run: -.*2 \- DisabledTest +The following tests did not run: +.*2 \- DisabledTest \(Disabled\) + The following tests FAILED: .*3 - NotRunTest \(Not Run\) diff --git a/Tests/RunCMake/ctest_disabled_test/DisableRequiredTest-stdout.txt b/Tests/RunCMake/ctest_disabled_test/DisableRequiredTest-stdout.txt index 886efb8..10d385e 100644 --- a/Tests/RunCMake/ctest_disabled_test/DisableRequiredTest-stdout.txt +++ b/Tests/RunCMake/ctest_disabled_test/DisableRequiredTest-stdout.txt @@ -9,5 +9,5 @@ + Total Test time \(real\) = +[0-9.]+ sec + -The following tests are disabled and did not run: -.*2 \- DisabledTest +The following tests did not run: +.*2 \- DisabledTest \(Disabled\) diff --git a/Tests/RunCMake/ctest_disabled_test/DisableSetupTest-stdout.txt b/Tests/RunCMake/ctest_disabled_test/DisableSetupTest-stdout.txt index dc27950..2dfd10d 100644 --- a/Tests/RunCMake/ctest_disabled_test/DisableSetupTest-stdout.txt +++ b/Tests/RunCMake/ctest_disabled_test/DisableSetupTest-stdout.txt @@ -9,5 +9,5 @@ + Total Test time \(real\) = +[0-9.]+ sec + -The following tests are disabled and did not run: -.*2 \- DisabledTest +The following tests did not run: +.*2 \- DisabledTest \(Disabled\) diff --git a/Tests/RunCMake/ctest_disabled_test/DisabledTest-stdout.txt b/Tests/RunCMake/ctest_disabled_test/DisabledTest-stdout.txt index d8bf966..9078aeb 100644 --- a/Tests/RunCMake/ctest_disabled_test/DisabledTest-stdout.txt +++ b/Tests/RunCMake/ctest_disabled_test/DisabledTest-stdout.txt @@ -10,8 +10,8 @@ + Total Test time \(real\) = +[0-9.]+ sec + -The following tests are disabled and did not run: -.*2 \- DisabledTest +The following tests did not run: +.*2 \- DisabledTest \(Disabled\) + The following tests FAILED: .*3 - NotRunTest \(Not Run\) diff --git a/Tests/RunCMake/ctest_skipped_test/CMakeLists.txt.in b/Tests/RunCMake/ctest_skipped_test/CMakeLists.txt.in new file mode 100644 index 0000000..cc4b8ed --- /dev/null +++ b/Tests/RunCMake/ctest_skipped_test/CMakeLists.txt.in @@ -0,0 +1,12 @@ +cmake_minimum_required(VERSION 3.8) +project(@CASE_NAME@ C) +include(CTest) + +if (WIN32) + set(skip_command "@CMAKE_CURRENT_LIST_DIR@/skip.bat") +else () + set(skip_command "@CMAKE_CURRENT_LIST_DIR@/skip.sh") +endif () + +add_test(NAME SuccessfulTest COMMAND "${CMAKE_COMMAND}" --version) +@CASE_CMAKELISTS_SUFFIX_CODE@ diff --git a/Tests/RunCMake/ctest_skipped_test/CTestConfig.cmake.in b/Tests/RunCMake/ctest_skipped_test/CTestConfig.cmake.in new file mode 100644 index 0000000..c0d7e42 --- /dev/null +++ b/Tests/RunCMake/ctest_skipped_test/CTestConfig.cmake.in @@ -0,0 +1 @@ +set(CTEST_PROJECT_NAME "@CASE_NAME@") diff --git a/Tests/RunCMake/ctest_skipped_test/RunCMakeTest.cmake b/Tests/RunCMake/ctest_skipped_test/RunCMakeTest.cmake new file mode 100644 index 0000000..dcf5cd4 --- /dev/null +++ b/Tests/RunCMake/ctest_skipped_test/RunCMakeTest.cmake @@ -0,0 +1,51 @@ +include(RunCTest) + +function(run_SkipTest) + set(CASE_CMAKELISTS_SUFFIX_CODE [[ +add_test(NAME SkipTest COMMAND ${skip_command}) + +set_tests_properties(SkipTest PROPERTIES SKIP_RETURN_CODE 125) + ]]) + run_ctest(SkipTest) +endfunction() +run_SkipTest() + +function(run_SkipSetupTest) + set(CASE_CMAKELISTS_SUFFIX_CODE [[ +add_test(NAME SkipTest COMMAND ${skip_command}) +add_test(NAME SuccessfulCleanupTest COMMAND "${CMAKE_COMMAND}" --version) + +set_tests_properties(SkipTest PROPERTIES SKIP_RETURN_CODE 125 + FIXTURES_SETUP "Foo") +set_tests_properties(SuccessfulTest PROPERTIES FIXTURES_REQUIRED "Foo") +set_tests_properties(SuccessfulCleanupTest PROPERTIES FIXTURES_CLEANUP "Foo") + ]]) + run_ctest(SkipSetupTest) +endfunction() +run_SkipSetupTest() + +function(run_SkipRequiredTest) + set(CASE_CMAKELISTS_SUFFIX_CODE [[ +add_test(NAME SkipTest COMMAND ${skip_command}) +add_test(NAME SuccessfulCleanupTest COMMAND "${CMAKE_COMMAND}" --version) + +set_tests_properties(SuccessfulTest PROPERTIES FIXTURES_SETUP "Foo") +set_tests_properties(SkipTest PROPERTIES SKIP_RETURN_CODE 125 + FIXTURES_REQUIRED "Foo") +set_tests_properties(SuccessfulCleanupTest PROPERTIES FIXTURES_CLEANUP "Foo") + ]]) + run_ctest(SkipRequiredTest) +endfunction() +run_SkipRequiredTest() + +function(run_SkipCleanupTest) + set(CASE_CMAKELISTS_SUFFIX_CODE [[ +add_test(NAME CleanupTest COMMAND ${skip_command}) + +set_tests_properties(SuccessfulTest PROPERTIES FIXTURES_REQUIRED "Foo") +set_tests_properties(CleanupTest PROPERTIES SKIP_RETURN_CODE 125 + FIXTURES_CLEANUP "Foo") + ]]) + run_ctest(SkipCleanupTest) +endfunction() +run_SkipCleanupTest() diff --git a/Tests/RunCMake/ctest_skipped_test/SkipCleanupTest-stdout.txt b/Tests/RunCMake/ctest_skipped_test/SkipCleanupTest-stdout.txt new file mode 100644 index 0000000..3b14b7a --- /dev/null +++ b/Tests/RunCMake/ctest_skipped_test/SkipCleanupTest-stdout.txt @@ -0,0 +1,11 @@ + Start 1: SuccessfulTest +1/2 Test #1: SuccessfulTest ................... Passed +[0-9.]+ sec + Start 2: CleanupTest +2/2 Test #2: CleanupTest ......................\*\*\*\Skipped +[0-9.]+ sec ++ +100% tests passed, 0 tests failed out of 2 ++ +Total Test time \(real\) = +[0-9.]+ sec ++ +The following tests did not run: +.*2 \- CleanupTest \(Skipped\) diff --git a/Tests/RunCMake/ctest_skipped_test/SkipRequiredTest-stdout.txt b/Tests/RunCMake/ctest_skipped_test/SkipRequiredTest-stdout.txt new file mode 100644 index 0000000..8ecc6e3 --- /dev/null +++ b/Tests/RunCMake/ctest_skipped_test/SkipRequiredTest-stdout.txt @@ -0,0 +1,13 @@ + Start 1: SuccessfulTest +1/3 Test #1: SuccessfulTest ................... Passed +[0-9.]+ sec + Start 2: SkipTest +2/3 Test #2: SkipTest .........................\*\*\*\Skipped +[0-9.]+ sec + Start 3: SuccessfulCleanupTest +3/3 Test #3: SuccessfulCleanupTest ............ Passed +[0-9.]+ sec ++ +100% tests passed, 0 tests failed out of 3 ++ +Total Test time \(real\) = +[0-9.]+ sec ++ +The following tests did not run: +.*2 \- SkipTest \(Skipped\) diff --git a/Tests/RunCMake/ctest_skipped_test/SkipSetupTest-stdout.txt b/Tests/RunCMake/ctest_skipped_test/SkipSetupTest-stdout.txt new file mode 100644 index 0000000..fe9bf34 --- /dev/null +++ b/Tests/RunCMake/ctest_skipped_test/SkipSetupTest-stdout.txt @@ -0,0 +1,13 @@ + Start 2: SkipTest +1/3 Test #2: SkipTest .........................\*\*\*\Skipped +[0-9.]+ sec + Start 1: SuccessfulTest +2/3 Test #1: SuccessfulTest ................... Passed +[0-9.]+ sec + Start 3: SuccessfulCleanupTest +3/3 Test #3: SuccessfulCleanupTest ............ Passed +[0-9.]+ sec ++ +100% tests passed, 0 tests failed out of 3 ++ +Total Test time \(real\) = +[0-9.]+ sec ++ +The following tests did not run: +.*2 \- SkipTest \(Skipped\) diff --git a/Tests/RunCMake/ctest_skipped_test/SkipTest-stdout.txt b/Tests/RunCMake/ctest_skipped_test/SkipTest-stdout.txt new file mode 100644 index 0000000..52e7a0b --- /dev/null +++ b/Tests/RunCMake/ctest_skipped_test/SkipTest-stdout.txt @@ -0,0 +1,11 @@ + Start 1: SuccessfulTest +1/2 Test #1: SuccessfulTest ................... Passed +[0-9.]+ sec + Start 2: SkipTest +2/2 Test #2: SkipTest .........................\*\*\*\Skipped +[0-9.]+ sec ++ +100% tests passed, 0 tests failed out of 2 ++ +Total Test time \(real\) = +[0-9.]+ sec ++ +The following tests did not run: +.*2 \- SkipTest \(Skipped\) diff --git a/Tests/RunCMake/ctest_skipped_test/skip.bat b/Tests/RunCMake/ctest_skipped_test/skip.bat new file mode 100755 index 0000000..80e1290 --- /dev/null +++ b/Tests/RunCMake/ctest_skipped_test/skip.bat @@ -0,0 +1 @@ +EXIT 125 diff --git a/Tests/RunCMake/ctest_skipped_test/skip.sh b/Tests/RunCMake/ctest_skipped_test/skip.sh new file mode 100755 index 0000000..f9c4603 --- /dev/null +++ b/Tests/RunCMake/ctest_skipped_test/skip.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +exit 125 diff --git a/Tests/RunCMake/ctest_skipped_test/test.cmake.in b/Tests/RunCMake/ctest_skipped_test/test.cmake.in new file mode 100644 index 0000000..ca23c83 --- /dev/null +++ b/Tests/RunCMake/ctest_skipped_test/test.cmake.in @@ -0,0 +1,16 @@ +cmake_minimum_required(VERSION 3.7) + +set(CTEST_SITE "test-site") +set(CTEST_BUILD_NAME "test-build-name") +set(CTEST_SOURCE_DIRECTORY "@RunCMake_BINARY_DIR@/@CASE_NAME@") +set(CTEST_BINARY_DIRECTORY "@RunCMake_BINARY_DIR@/@CASE_NAME@-build") +set(CTEST_CMAKE_GENERATOR "@RunCMake_GENERATOR@") +set(CTEST_CMAKE_GENERATOR_PLATFORM "@RunCMake_GENERATOR_PLATFORM@") +set(CTEST_CMAKE_GENERATOR_TOOLSET "@RunCMake_GENERATOR_TOOLSET@") +set(CTEST_BUILD_CONFIGURATION "$ENV{CMAKE_CONFIG_TYPE}") + +set(ctest_test_args "@CASE_CTEST_TEST_ARGS@") +ctest_start(Experimental) +ctest_configure() +ctest_build() +ctest_test(${ctest_test_args}) diff --git a/Tests/RunCMake/install/FILES-TARGET_OBJECTS-all-check.cmake b/Tests/RunCMake/install/FILES-TARGET_OBJECTS-all-check.cmake new file mode 100644 index 0000000..f7f2a3a --- /dev/null +++ b/Tests/RunCMake/install/FILES-TARGET_OBJECTS-all-check.cmake @@ -0,0 +1 @@ +check_installed([[^objs;objs/obj1(\.c)?\.(o|obj);objs/obj2(\.c)?\.(o|obj)$]]) diff --git a/Tests/RunCMake/install/FILES-TARGET_OBJECTS.cmake b/Tests/RunCMake/install/FILES-TARGET_OBJECTS.cmake new file mode 100644 index 0000000..40c58ad --- /dev/null +++ b/Tests/RunCMake/install/FILES-TARGET_OBJECTS.cmake @@ -0,0 +1,3 @@ +enable_language(C) +add_library(objs OBJECT obj1.c obj2.c) +install(FILES $<TARGET_OBJECTS:objs> DESTINATION objs) diff --git a/Tests/RunCMake/install/RunCMakeTest.cmake b/Tests/RunCMake/install/RunCMakeTest.cmake index 45693b5..1a60f0c 100644 --- a/Tests/RunCMake/install/RunCMakeTest.cmake +++ b/Tests/RunCMake/install/RunCMakeTest.cmake @@ -13,12 +13,15 @@ function(run_install_test case) # Check "all" components. set(CMAKE_INSTALL_PREFIX ${RunCMake_TEST_BINARY_DIR}/root-all) run_cmake_command(${case}-all ${CMAKE_COMMAND} -DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX} -DBUILD_TYPE=Debug -P cmake_install.cmake) - # Check unspecified component. - set(CMAKE_INSTALL_PREFIX ${RunCMake_TEST_BINARY_DIR}/root-uns) - run_cmake_command(${case}-uns ${CMAKE_COMMAND} -DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX} -DBUILD_TYPE=Debug -DCOMPONENT=Unspecified -P cmake_install.cmake) - # Check explicit component. - set(CMAKE_INSTALL_PREFIX ${RunCMake_TEST_BINARY_DIR}/root-exc) - run_cmake_command(${case}-exc ${CMAKE_COMMAND} -DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX} -DBUILD_TYPE=Debug -DCOMPONENT=exc -P cmake_install.cmake) + + if(run_install_test_components) + # Check unspecified component. + set(CMAKE_INSTALL_PREFIX ${RunCMake_TEST_BINARY_DIR}/root-uns) + run_cmake_command(${case}-uns ${CMAKE_COMMAND} -DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX} -DBUILD_TYPE=Debug -DCOMPONENT=Unspecified -P cmake_install.cmake) + # Check explicit component. + set(CMAKE_INSTALL_PREFIX ${RunCMake_TEST_BINARY_DIR}/root-exc) + run_cmake_command(${case}-exc ${CMAKE_COMMAND} -DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX} -DBUILD_TYPE=Debug -DCOMPONENT=exc -P cmake_install.cmake) + endif() endfunction() # Function called in *-check.cmake scripts to check installed files. @@ -57,5 +60,10 @@ run_cmake(CMP0062-OLD) run_cmake(CMP0062-NEW) run_cmake(CMP0062-WARN) +if(NOT RunCMake_GENERATOR STREQUAL "Xcode" OR NOT "$ENV{CMAKE_OSX_ARCHITECTURES}" MATCHES "[;$]") + run_install_test(FILES-TARGET_OBJECTS) +endif() + +set(run_install_test_components 1) run_install_test(FILES-EXCLUDE_FROM_ALL) run_install_test(TARGETS-EXCLUDE_FROM_ALL) diff --git a/Tests/RunCMake/install/obj1.c b/Tests/RunCMake/install/obj1.c new file mode 100644 index 0000000..2411aab --- /dev/null +++ b/Tests/RunCMake/install/obj1.c @@ -0,0 +1,4 @@ +int obj1(void) +{ + return 0; +} diff --git a/Tests/RunCMake/install/obj2.c b/Tests/RunCMake/install/obj2.c new file mode 100644 index 0000000..2dad71e --- /dev/null +++ b/Tests/RunCMake/install/obj2.c @@ -0,0 +1,4 @@ +int obj2(void) +{ + return 0; +} diff --git a/Tests/RunCMake/separate_arguments/CMakeLists.txt b/Tests/RunCMake/separate_arguments/CMakeLists.txt new file mode 100644 index 0000000..2897109 --- /dev/null +++ b/Tests/RunCMake/separate_arguments/CMakeLists.txt @@ -0,0 +1,3 @@ +cmake_minimum_required(VERSION 3.0) +project(${RunCMake_TEST} NONE) +include(${RunCMake_TEST}.cmake) diff --git a/Tests/RunCMake/separate_arguments/EmptyCommand.cmake b/Tests/RunCMake/separate_arguments/EmptyCommand.cmake new file mode 100644 index 0000000..895b6ac --- /dev/null +++ b/Tests/RunCMake/separate_arguments/EmptyCommand.cmake @@ -0,0 +1,6 @@ +set(nothing) +separate_arguments(nothing) +if(DEFINED nothing) + message(FATAL_ERROR "separate_arguments null-case failed: " + "nothing=[${nothing}]") +endif() diff --git a/Tests/RunCMake/separate_arguments/NativeCommand.cmake b/Tests/RunCMake/separate_arguments/NativeCommand.cmake new file mode 100644 index 0000000..1cb009e --- /dev/null +++ b/Tests/RunCMake/separate_arguments/NativeCommand.cmake @@ -0,0 +1,19 @@ +set(unix_cmd "a \"b c\" 'd e' \";\" \\ \\'\\\" '\\'' \"\\\"\"") +set(unix_exp "a;b c;d e;\;; '\";';\"") + +set(windows_cmd "a \"b c\" 'd e' \";\" \\ \"c:\\windows\\path\\\\\" \\\"") +set(windows_exp "a;b c;'d;e';\;;\\;c:\\windows\\path\\;\"") + +if(CMAKE_HOST_WIN32) + set(native_cmd "${windows_cmd}") + set(native_exp "${windows_exp}") +else() + set(native_cmd "${unix_cmd}") + set(native_exp "${unix_exp}") +endif() +separate_arguments(native_out NATIVE_COMMAND "${native_cmd}") + +if(NOT "${native_out}" STREQUAL "${native_exp}") + message(FATAL_ERROR "separate_arguments native-style failed. " + "Expected\n [${native_exp}]\nbut got\n [${native_out}]\n") +endif() diff --git a/Tests/RunCMake/separate_arguments/PlainCommand.cmake b/Tests/RunCMake/separate_arguments/PlainCommand.cmake new file mode 100644 index 0000000..311a993 --- /dev/null +++ b/Tests/RunCMake/separate_arguments/PlainCommand.cmake @@ -0,0 +1,8 @@ +set(old_out "a b c") +separate_arguments(old_out) +set(old_exp "a;b;;c") + +if(NOT "${old_out}" STREQUAL "${old_exp}") + message(FATAL_ERROR "separate_arguments old-style failed. " + "Expected\n [${old_exp}]\nbut got\n [${old_out}]\n") +endif() diff --git a/Tests/RunCMake/separate_arguments/RunCMakeTest.cmake b/Tests/RunCMake/separate_arguments/RunCMakeTest.cmake new file mode 100644 index 0000000..07951bb --- /dev/null +++ b/Tests/RunCMake/separate_arguments/RunCMakeTest.cmake @@ -0,0 +1,7 @@ +include(RunCMake) + +run_cmake(EmptyCommand) +run_cmake(PlainCommand) +run_cmake(UnixCommand) +run_cmake(WindowsCommand) +run_cmake(NativeCommand) diff --git a/Tests/RunCMake/separate_arguments/UnixCommand.cmake b/Tests/RunCMake/separate_arguments/UnixCommand.cmake new file mode 100644 index 0000000..0b5767a --- /dev/null +++ b/Tests/RunCMake/separate_arguments/UnixCommand.cmake @@ -0,0 +1,8 @@ +set(unix_cmd "a \"b c\" 'd e' \";\" \\ \\'\\\" '\\'' \"\\\"\"") +set(unix_exp "a;b c;d e;\;; '\";';\"") +separate_arguments(unix_out UNIX_COMMAND "${unix_cmd}") + +if(NOT "${unix_out}" STREQUAL "${unix_exp}") + message(FATAL_ERROR "separate_arguments unix-style failed. " + "Expected\n [${unix_exp}]\nbut got\n [${unix_out}]\n") +endif() diff --git a/Tests/RunCMake/separate_arguments/WindowsCommand.cmake b/Tests/RunCMake/separate_arguments/WindowsCommand.cmake new file mode 100644 index 0000000..86aa14a --- /dev/null +++ b/Tests/RunCMake/separate_arguments/WindowsCommand.cmake @@ -0,0 +1,8 @@ +set(windows_cmd "a \"b c\" 'd e' \";\" \\ \"c:\\windows\\path\\\\\" \\\"") +set(windows_exp "a;b c;'d;e';\;;\\;c:\\windows\\path\\;\"") +separate_arguments(windows_out WINDOWS_COMMAND "${windows_cmd}") + +if(NOT "${windows_out}" STREQUAL "${windows_exp}") + message(FATAL_ERROR "separate_arguments windows-style failed. " + "Expected\n [${windows_exp}]\nbut got\n [${windows_out}]\n") +endif() |