diff options
105 files changed, 1574 insertions, 339 deletions
diff --git a/Help/manual/cmake-properties.7.rst b/Help/manual/cmake-properties.7.rst index 3a62371..bcf21a5 100644 --- a/Help/manual/cmake-properties.7.rst +++ b/Help/manual/cmake-properties.7.rst @@ -173,6 +173,7 @@ Properties on Targets /prop_tgt/CUDA_PTX_COMPILATION /prop_tgt/CUDA_SEPARABLE_COMPILATION /prop_tgt/CUDA_RESOLVE_DEVICE_SYMBOLS + /prop_tgt/CUDA_RUNTIME_LIBRARY /prop_tgt/CUDA_EXTENSIONS /prop_tgt/CUDA_STANDARD /prop_tgt/CUDA_STANDARD_REQUIRED @@ -301,6 +302,8 @@ Properties on Targets /prop_tgt/OBJCXX_STANDARD_REQUIRED /prop_tgt/OSX_ARCHITECTURES_CONFIG /prop_tgt/OSX_ARCHITECTURES + /prop_tgt/OSX_CURRENT_VERSION + /prop_tgt/OSX_COMPATIBILITY_VERSION /prop_tgt/OUTPUT_NAME_CONFIG /prop_tgt/OUTPUT_NAME /prop_tgt/PDB_NAME_CONFIG diff --git a/Help/manual/cmake-toolchains.7.rst b/Help/manual/cmake-toolchains.7.rst index f233d08..e8badd4 100644 --- a/Help/manual/cmake-toolchains.7.rst +++ b/Help/manual/cmake-toolchains.7.rst @@ -233,6 +233,9 @@ value to those supported compilers when compiling: set(CMAKE_CXX_COMPILER QCC) set(CMAKE_CXX_COMPILER_TARGET ${arch}) + set(CMAKE_SYSROOT $ENV{QNX_TARGET}) + + Cross Compiling for Windows CE ------------------------------ diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst index 1f5b39c..63deda5 100644 --- a/Help/manual/cmake-variables.7.rst +++ b/Help/manual/cmake-variables.7.rst @@ -373,6 +373,7 @@ Variables that Control the Build /variable/CMAKE_CTEST_ARGUMENTS /variable/CMAKE_CUDA_SEPARABLE_COMPILATION /variable/CMAKE_CUDA_RESOLVE_DEVICE_SYMBOLS + /variable/CMAKE_CUDA_RUNTIME_LIBRARY /variable/CMAKE_DEBUG_POSTFIX /variable/CMAKE_DISABLE_PRECOMPILE_HEADERS /variable/CMAKE_ENABLE_EXPORTS diff --git a/Help/prop_tgt/CUDA_RUNTIME_LIBRARY-VALUES.txt b/Help/prop_tgt/CUDA_RUNTIME_LIBRARY-VALUES.txt new file mode 100644 index 0000000..a6d7050 --- /dev/null +++ b/Help/prop_tgt/CUDA_RUNTIME_LIBRARY-VALUES.txt @@ -0,0 +1,9 @@ +``None`` + Link with ``-cudart=none`` or equivalent flag(s) to use no CUDA + runtime library. +``Shared`` + Link with ``-cudart=shared`` or equivalent flag(s) to use a + dynamically-linked CUDA runtime library. +``Static`` + Link with ``-cudart=static`` or equivalent flag(s) to use a + statically-linked CUDA runtime library. diff --git a/Help/prop_tgt/CUDA_RUNTIME_LIBRARY.rst b/Help/prop_tgt/CUDA_RUNTIME_LIBRARY.rst new file mode 100644 index 0000000..0782765 --- /dev/null +++ b/Help/prop_tgt/CUDA_RUNTIME_LIBRARY.rst @@ -0,0 +1,21 @@ +CUDA_RUNTIME_LIBRARY +-------------------- + +Select the CUDA runtime library for use by compilers targeting the CUDA language. + +The allowed case insensitive values are: + +.. include:: CUDA_RUNTIME_LIBRARY-VALUES.txt + +Contents of ``CUDA_RUNTIME_LIBRARY`` may use +:manual:`generator expressions <cmake-generator-expressions(7)>`. + +If this property is not set then CMake uses the default value +``Static`` to select the CUDA runtime library. + +.. note:: + + This property has effect only when the ``CUDA`` language is enabled. To + control the CUDA runtime linking when only using the CUDA SDK with the + ``C`` or ``C++`` language we recommend using the :module:`FindCUDAToolkit` + module. diff --git a/Help/prop_tgt/OSX_COMPATIBILITY_VERSION.rst b/Help/prop_tgt/OSX_COMPATIBILITY_VERSION.rst new file mode 100644 index 0000000..1694df1 --- /dev/null +++ b/Help/prop_tgt/OSX_COMPATIBILITY_VERSION.rst @@ -0,0 +1,14 @@ +OSX_COMPATIBILITY_VERSION +------------------------- + +What current version number is this target for OSX. + +For shared libraries on Mach-O systems (e.g. macOS, iOS) +the ``OSX_COMPATIBILITY_VERSION`` property correspond to +``compatibility version`` and :prop_tgt:`OSX_CURRENT_VERSION` to +``current version``. +See the :prop_tgt:`FRAMEWORK` target property for an example. + +Versions of Mach-O binaries may be checked with the ``otool -L <binary>`` +command. If ``OSX_COMPATIBILITY_VERSION`` is not set, the value of +the :prop_tgt:``SOVERSION`` property will be used. diff --git a/Help/prop_tgt/OSX_CURRENT_VERSION.rst b/Help/prop_tgt/OSX_CURRENT_VERSION.rst new file mode 100644 index 0000000..609924d --- /dev/null +++ b/Help/prop_tgt/OSX_CURRENT_VERSION.rst @@ -0,0 +1,13 @@ +OSX_CURRENT_VERSION +------------------- + +What current version number is this target for OSX. + +For shared libraries on Mach-O systems (e.g. macOS, iOS) +the :prop_tgt:`OSX_COMPATIBILITY_VERSION` property correspond to +``compatibility version`` and ``OSX_CURRENT_VERSION`` to ``current version``. +See the :prop_tgt:`FRAMEWORK` target property for an example. + +Versions of Mach-O binaries may be checked with the ``otool -L <binary>`` +command. If ``OSX_CURRENT_VERSION`` is not set, the value of +the :prop_tgt:``VERSION`` property will be used. diff --git a/Help/prop_tgt/SOVERSION.rst b/Help/prop_tgt/SOVERSION.rst index b07c17c..1a66c8f 100644 --- a/Help/prop_tgt/SOVERSION.rst +++ b/Help/prop_tgt/SOVERSION.rst @@ -21,7 +21,9 @@ Mach-O Versions ^^^^^^^^^^^^^^^ For shared libraries and executables on Mach-O systems (e.g. macOS, iOS), -the ``SOVERSION`` property corresponds to *compatibility version* and -:prop_tgt:`VERSION` to *current version*. See the :prop_tgt:`FRAMEWORK` target -property for an example. Versions of Mach-O binaries may be checked with the -``otool -L <binary>`` command. +the ``SOVERSION`` property is a fallback to +:prop_tgt:`OSX_COMPATIBILITY_VERSION` property which corresponds to +*compatiblity version* and :prop_tgt:`VERSION` is a fallback to +:prop_tgt:`OSX_CURRENT_VERSION` which corresponds to *current version*. +See the :prop_tgt:`FRAMEWORK` target property for an example. Versions +of Mach-O binaries may be checked with the ``otool -L <binary>`` command. diff --git a/Help/prop_tgt/VERSION.rst b/Help/prop_tgt/VERSION.rst index ff3b303..a24b613 100644 --- a/Help/prop_tgt/VERSION.rst +++ b/Help/prop_tgt/VERSION.rst @@ -23,7 +23,9 @@ Mach-O Versions ^^^^^^^^^^^^^^^ For shared libraries and executables on Mach-O systems (e.g. macOS, iOS), -the :prop_tgt:`SOVERSION` property correspond to *compatibility version* and -``VERSION`` to *current version*. See the :prop_tgt:`FRAMEWORK` target +the ``VERSION`` property is a fallback to :prop_tgt:`OSX_CURRENT_VERSION` +property which corresponds to *current version* and :prop_tgt:`SOVERSION` +is a fallback to :prop_tgt:`OSX_COMPATIBILITY_VERSION` which corresponds +to *compatiblity version*. See the :prop_tgt:`FRAMEWORK` target property for an example. Versions of Mach-O binaries may be checked with the ``otool -L <binary>`` command. diff --git a/Help/release/dev/cuda-runtime-library.rst b/Help/release/dev/cuda-runtime-library.rst new file mode 100644 index 0000000..0d5b1f6 --- /dev/null +++ b/Help/release/dev/cuda-runtime-library.rst @@ -0,0 +1,7 @@ +cuda-runtime-library +-------------------- + +* The :variable:`CMAKE_CUDA_RUNTIME_LIBRARY` variable and + :prop_tgt:`CUDA_RUNTIME_LIBRARY` target property were introduced to + select the CUDA runtime library used when linking targets that + use CUDA. diff --git a/Help/release/dev/osx-version-flags.rst b/Help/release/dev/osx-version-flags.rst new file mode 100644 index 0000000..329aca3 --- /dev/null +++ b/Help/release/dev/osx-version-flags.rst @@ -0,0 +1,9 @@ +add_osx_compatiblity_property +----------------------------- + +* Target properties :prop_tgt:`OSX_COMPATIBILITY_VERSION` and + :prop_tgt:`OSX_CURRENT_VERSION` were added to set the + ``compatibility_version`` and ``curent_version`` respectively + on macOS. For backwards compatibility, if these properties + are not set, :prop_tgt:`SOVERSION` and :prop_tgt:`VERSION` + are used respectively as fallbacks. diff --git a/Help/variable/CMAKE_CUDA_RUNTIME_LIBRARY.rst b/Help/variable/CMAKE_CUDA_RUNTIME_LIBRARY.rst new file mode 100644 index 0000000..ea1c1b8 --- /dev/null +++ b/Help/variable/CMAKE_CUDA_RUNTIME_LIBRARY.rst @@ -0,0 +1,24 @@ +CMAKE_CUDA_RUNTIME_LIBRARY +-------------------------- + +Select the CUDA runtime library for use by compilers targeting the MSVC ABI. +This variable is used to initialize the :prop_tgt:`CUDA_RUNTIME_LIBRARY` +property on all targets as they are created. + +The allowed case insensitive values are: + +.. include:: ../prop_tgt/CUDA_RUNTIME_LIBRARY-VALUES.txt + +Contents of ``CMAKE_CUDA_RUNTIME_LIBRARY`` may use +:manual:`generator expressions <cmake-generator-expressions(7)>`. + +If this variable is not set then the :prop_tgt:`CUDA_RUNTIME_LIBRARY` target +property will not be set automatically. If that property is not set then +CMake uses the default value ``Static`` to select the CUDA runtime library. + +.. note:: + + This property has effect only when the ``CUDA`` language is enabled. To + control the CUDA runtime linking when only using the CUDA SDK with the + ``C`` or ``C++`` language we recommend using the :module:`FindCUDAToolkit` + module. diff --git a/Modules/CMakeDetermineCompilerABI.cmake b/Modules/CMakeDetermineCompilerABI.cmake index c5611b5..99447e4 100644 --- a/Modules/CMakeDetermineCompilerABI.cmake +++ b/Modules/CMakeDetermineCompilerABI.cmake @@ -161,6 +161,18 @@ function(CMAKE_DETERMINE_COMPILER_ABI lang src) break() endif() endforeach() + elseif(CMAKE_CXX_COMPILER_ID STREQUAL QCC) + foreach(dir ${implicit_dirs}) + if (dir MATCHES "/lib$") + get_filename_component(assumedArchDir "${dir}" DIRECTORY) + get_filename_component(archParentDir "${assumedArchDir}" DIRECTORY) + if (archParentDir STREQUAL CMAKE_SYSROOT) + get_filename_component(archDirName "${assumedArchDir}" NAME) + set(CMAKE_${lang}_LIBRARY_ARCHITECTURE "${archDirName}" PARENT_SCOPE) + break() + endif() + endif() + endforeach() endif() else() diff --git a/Modules/CMakeTestCUDACompiler.cmake b/Modules/CMakeTestCUDACompiler.cmake index a0f6bc9..d80b55a 100644 --- a/Modules/CMakeTestCUDACompiler.cmake +++ b/Modules/CMakeTestCUDACompiler.cmake @@ -67,6 +67,17 @@ else() set(CMAKE_CUDA_IMPLICIT_LINK_DIRECTORIES "${CMAKE_CUDA_HOST_IMPLICIT_LINK_DIRECTORIES}") endif() + # Remove the following libraries from CMAKE_CUDA_HOST_IMPLICIT_LINK_LIBRARIES and + # CMAKE_CUDA_IMPLICIT_LINK_LIBRARIES + # + # - cudart + # - cudart_static + # - cudadevrt + # + # These are controlled by CMAKE_CUDA_RUNTIME_LIBRARY + list(REMOVE_ITEM CMAKE_CUDA_IMPLICIT_LINK_LIBRARIES cudart cudart_static cudadevrt) + list(REMOVE_ITEM CMAKE_CUDA_HOST_IMPLICIT_LINK_LIBRARIES cudart cudart_static cudadevrt) + # Re-configure to save learned information. configure_file( ${CMAKE_ROOT}/Modules/CMakeCUDACompiler.cmake.in diff --git a/Modules/Compiler/Clang-C.cmake b/Modules/Compiler/Clang-C.cmake index 0448965..7c4a263 100644 --- a/Modules/Compiler/Clang-C.cmake +++ b/Modules/Compiler/Clang-C.cmake @@ -6,6 +6,10 @@ if(APPLE AND NOT appleClangPolicy STREQUAL NEW) return() endif() +if("x${CMAKE_C_COMPILER_FRONTEND_VARIANT}" STREQUAL "xMSVC") + set(CMAKE_C_CLANG_TIDY_DRIVER_MODE "cl") +endif() + if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 3.4) if(NOT "x${CMAKE_C_SIMULATE_ID}" STREQUAL "xMSVC") set(CMAKE_C90_STANDARD_COMPILE_OPTION "-std=c90") diff --git a/Modules/Compiler/Clang-CXX.cmake b/Modules/Compiler/Clang-CXX.cmake index 61709f8..cb240f9 100644 --- a/Modules/Compiler/Clang-CXX.cmake +++ b/Modules/Compiler/Clang-CXX.cmake @@ -10,6 +10,9 @@ if(APPLE AND NOT appleClangPolicy STREQUAL NEW) return() endif() +if("x${CMAKE_CXX_COMPILER_FRONTEND_VARIANT}" STREQUAL "xMSVC") + set(CMAKE_CXX_CLANG_TIDY_DRIVER_MODE "cl") +endif() if("x${CMAKE_CXX_COMPILER_FRONTEND_VARIANT}" STREQUAL "xGNU") if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 2.1) diff --git a/Modules/Compiler/Intel-C.cmake b/Modules/Compiler/Intel-C.cmake index e9e59a2..ec3bfd8 100644 --- a/Modules/Compiler/Intel-C.cmake +++ b/Modules/Compiler/Intel-C.cmake @@ -9,6 +9,8 @@ set(CMAKE_DEPFILE_FLAGS_C "-MD -MT <OBJECT> -MF <DEPFILE>") if("x${CMAKE_C_SIMULATE_ID}" STREQUAL "xMSVC") + set(CMAKE_C_CLANG_TIDY_DRIVER_MODE "cl") + if (NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 16.0.0) set(CMAKE_C11_STANDARD_COMPILE_OPTION "-Qstd=c11") set(CMAKE_C11_EXTENSION_COMPILE_OPTION "-Qstd=c11") diff --git a/Modules/Compiler/Intel-CXX.cmake b/Modules/Compiler/Intel-CXX.cmake index b630a6b..1ed1b08 100644 --- a/Modules/Compiler/Intel-CXX.cmake +++ b/Modules/Compiler/Intel-CXX.cmake @@ -9,6 +9,8 @@ set(CMAKE_DEPFILE_FLAGS_CXX "-MD -MT <OBJECT> -MF <DEPFILE>") if("x${CMAKE_CXX_SIMULATE_ID}" STREQUAL "xMSVC") + set(CMAKE_CXX_CLANG_TIDY_DRIVER_MODE "cl") + if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 18.0.0) set(CMAKE_CXX17_STANDARD_COMPILE_OPTION "-Qstd=c++17") set(CMAKE_CXX17_EXTENSION_COMPILE_OPTION "-Qstd=c++17") diff --git a/Modules/Compiler/MSVC-C.cmake b/Modules/Compiler/MSVC-C.cmake index 20787a3..bca9764 100644 --- a/Modules/Compiler/MSVC-C.cmake +++ b/Modules/Compiler/MSVC-C.cmake @@ -11,6 +11,8 @@ set(CMAKE_C11_EXTENSION_COMPILE_OPTION "") # There is no meaningful default for this set(CMAKE_C_STANDARD_DEFAULT "") +set(CMAKE_C_CLANG_TIDY_DRIVER_MODE "cl") + # There are no C compiler modes so we hard-code the known compiler supported # features. Override the default macro for this special case. Pretend that # all language standards are available so that at least compilation diff --git a/Modules/Compiler/MSVC-CXX.cmake b/Modules/Compiler/MSVC-CXX.cmake index 915295d..1dfc760 100644 --- a/Modules/Compiler/MSVC-CXX.cmake +++ b/Modules/Compiler/MSVC-CXX.cmake @@ -3,6 +3,8 @@ include(Compiler/CMakeCommonCompilerMacros) +set(CMAKE_CXX_CLANG_TIDY_DRIVER_MODE "cl") + if ((CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 19.0.24215.1 AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 19.10) OR CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 19.10.25017) diff --git a/Modules/Compiler/NVIDIA-CUDA.cmake b/Modules/Compiler/NVIDIA-CUDA.cmake index fb1fc20..a786fb9 100644 --- a/Modules/Compiler/NVIDIA-CUDA.cmake +++ b/Modules/Compiler/NVIDIA-CUDA.cmake @@ -43,6 +43,11 @@ endif() set(CMAKE_SHARED_LIBRARY_CREATE_CUDA_FLAGS -shared) set(CMAKE_INCLUDE_SYSTEM_FLAG_CUDA -isystem=) +set(CMAKE_CUDA_RUNTIME_LIBRARY_DEFAULT "STATIC") +set(CMAKE_CUDA_RUNTIME_LIBRARY_LINK_OPTIONS_STATIC "cudadevrt;cudart_static") +set(CMAKE_CUDA_RUNTIME_LIBRARY_LINK_OPTIONS_SHARED "cudadevrt;cudart") +set(CMAKE_CUDA_RUNTIME_LIBRARY_LINK_OPTIONS_NONE "") + if("x${CMAKE_CUDA_SIMULATE_ID}" STREQUAL "xMSVC") set(CMAKE_CUDA03_STANDARD_COMPILE_OPTION "") set(CMAKE_CUDA03_EXTENSION_COMPILE_OPTION "") diff --git a/Modules/Compiler/QCC.cmake b/Modules/Compiler/QCC.cmake index 9df8269..10e1389 100644 --- a/Modules/Compiler/QCC.cmake +++ b/Modules/Compiler/QCC.cmake @@ -10,6 +10,9 @@ macro(__compiler_qcc lang) # http://www.qnx.com/developers/docs/6.4.0/neutrino/utilities/q/qcc.html#examples set(CMAKE_${lang}_COMPILE_OPTIONS_TARGET "-V") + set(CMAKE_PREFIX_LIBRARY_ARCHITECTURE "ON") + + set(CMAKE_${lang}_COMPILE_OPTIONS_SYSROOT "-Wc,-isysroot,") set(CMAKE_INCLUDE_SYSTEM_FLAG_${lang} "-Wp,-isystem,") set(CMAKE_DEPFILE_FLAGS_${lang} "-Wp,-MD,<DEPFILE> -Wp,-MT,<OBJECT> -Wp,-MF,<DEPFILE>") diff --git a/Modules/FindBoost.cmake b/Modules/FindBoost.cmake index deac9ef..3c52466 100644 --- a/Modules/FindBoost.cmake +++ b/Modules/FindBoost.cmake @@ -1470,43 +1470,6 @@ _Boost_DEBUG_PRINT_VAR("${CMAKE_CURRENT_LIST_FILE}" "${CMAKE_CURRENT_LIST_LINE}" _Boost_DEBUG_PRINT_VAR("${CMAKE_CURRENT_LIST_FILE}" "${CMAKE_CURRENT_LIST_LINE}" "Boost_ADDITIONAL_VERSIONS") _Boost_DEBUG_PRINT_VAR("${CMAKE_CURRENT_LIST_FILE}" "${CMAKE_CURRENT_LIST_LINE}" "Boost_NO_SYSTEM_PATHS") -# Supply Boost_LIB_DIAGNOSTIC_DEFINITIONS as a convenience target. It -# will only contain any interface definitions on WIN32, but is created -# on all platforms to keep end user code free from platform dependent -# code. Also provide convenience targets to disable autolinking and -# enable dynamic linking. -if(NOT TARGET Boost::diagnostic_definitions) - add_library(Boost::diagnostic_definitions INTERFACE IMPORTED) - add_library(Boost::disable_autolinking INTERFACE IMPORTED) - add_library(Boost::dynamic_linking INTERFACE IMPORTED) - set_target_properties(Boost::dynamic_linking PROPERTIES - INTERFACE_COMPILE_DEFINITIONS "BOOST_ALL_DYN_LINK") -endif() -if(WIN32) - # In windows, automatic linking is performed, so you do not have - # to specify the libraries. If you are linking to a dynamic - # runtime, then you can choose to link to either a static or a - # dynamic Boost library, the default is to do a static link. You - # can alter this for a specific library "whatever" by defining - # BOOST_WHATEVER_DYN_LINK to force Boost library "whatever" to be - # linked dynamically. Alternatively you can force all Boost - # libraries to dynamic link by defining BOOST_ALL_DYN_LINK. - - # This feature can be disabled for Boost library "whatever" by - # defining BOOST_WHATEVER_NO_LIB, or for all of Boost by defining - # BOOST_ALL_NO_LIB. - - # If you want to observe which libraries are being linked against - # then defining BOOST_LIB_DIAGNOSTIC will cause the auto-linking - # code to emit a #pragma message each time a library is selected - # for linking. - set(Boost_LIB_DIAGNOSTIC_DEFINITIONS "-DBOOST_LIB_DIAGNOSTIC") - set_target_properties(Boost::diagnostic_definitions PROPERTIES - INTERFACE_COMPILE_DEFINITIONS "BOOST_LIB_DIAGNOSTIC") - set_target_properties(Boost::disable_autolinking PROPERTIES - INTERFACE_COMPILE_DEFINITIONS "BOOST_ALL_NO_LIB") -endif() - cmake_policy(GET CMP0074 _Boost_CMP0074) if(NOT "x${_Boost_CMP0074}x" STREQUAL "xNEWx") _Boost_CHECK_SPELLING(Boost_ROOT) @@ -2299,6 +2262,43 @@ if(Boost_FOUND) endif() endif() endforeach() + + # Supply Boost_LIB_DIAGNOSTIC_DEFINITIONS as a convenience target. It + # will only contain any interface definitions on WIN32, but is created + # on all platforms to keep end user code free from platform dependent + # code. Also provide convenience targets to disable autolinking and + # enable dynamic linking. + if(NOT TARGET Boost::diagnostic_definitions) + add_library(Boost::diagnostic_definitions INTERFACE IMPORTED) + add_library(Boost::disable_autolinking INTERFACE IMPORTED) + add_library(Boost::dynamic_linking INTERFACE IMPORTED) + set_target_properties(Boost::dynamic_linking PROPERTIES + INTERFACE_COMPILE_DEFINITIONS "BOOST_ALL_DYN_LINK") + endif() + if(WIN32) + # In windows, automatic linking is performed, so you do not have + # to specify the libraries. If you are linking to a dynamic + # runtime, then you can choose to link to either a static or a + # dynamic Boost library, the default is to do a static link. You + # can alter this for a specific library "whatever" by defining + # BOOST_WHATEVER_DYN_LINK to force Boost library "whatever" to be + # linked dynamically. Alternatively you can force all Boost + # libraries to dynamic link by defining BOOST_ALL_DYN_LINK. + + # This feature can be disabled for Boost library "whatever" by + # defining BOOST_WHATEVER_NO_LIB, or for all of Boost by defining + # BOOST_ALL_NO_LIB. + + # If you want to observe which libraries are being linked against + # then defining BOOST_LIB_DIAGNOSTIC will cause the auto-linking + # code to emit a #pragma message each time a library is selected + # for linking. + set(Boost_LIB_DIAGNOSTIC_DEFINITIONS "-DBOOST_LIB_DIAGNOSTIC") + set_target_properties(Boost::diagnostic_definitions PROPERTIES + INTERFACE_COMPILE_DEFINITIONS "BOOST_LIB_DIAGNOSTIC") + set_target_properties(Boost::disable_autolinking PROPERTIES + INTERFACE_COMPILE_DEFINITIONS "BOOST_ALL_NO_LIB") + endif() endif() # ------------------------------------------------------------------------ diff --git a/Modules/FindCUDAToolkit.cmake b/Modules/FindCUDAToolkit.cmake index 6a40ace..a6523ef 100644 --- a/Modules/FindCUDAToolkit.cmake +++ b/Modules/FindCUDAToolkit.cmake @@ -668,13 +668,23 @@ if(CMAKE_CROSSCOMPILING) if (EXISTS "${CUDAToolkit_ROOT_DIR}/targets/${CUDAToolkit_TARGET_NAME}") set(CUDAToolkit_TARGET_DIR "${CUDAToolkit_ROOT_DIR}/targets/${CUDAToolkit_TARGET_NAME}") # add known CUDA target root path to the set of directories we search for programs, libraries and headers - list(APPEND CMAKE_FIND_ROOT_PATH "${CUDAToolkit_TARGET_DIR}") + list(PREPEND CMAKE_FIND_ROOT_PATH "${CUDAToolkit_TARGET_DIR}") + + # Mark that we need to pop the root search path changes after we have + # found all cuda libraries so that searches for our cross-compilation + # libraries work when another cuda sdk is in CMAKE_PREFIX_PATH or + # PATh + set(_CUDAToolkit_Pop_ROOT_PATH True) endif() else() # Not cross compiling set(CUDAToolkit_TARGET_DIR "${CUDAToolkit_ROOT_DIR}") # Now that we have the real ROOT_DIR, find components inside it. list(APPEND CMAKE_PREFIX_PATH ${CUDAToolkit_ROOT_DIR}) + + # Mark that we need to pop the prefix path changes after we have + # found the cudart library. + set(_CUDAToolkit_Pop_Prefix True) endif() @@ -693,12 +703,9 @@ if (NOT CUDA_CUDART AND NOT CUDAToolkit_FIND_QUIETLY) endif() unset(CUDAToolkit_ROOT_DIR) -if(CMAKE_CROSSCOMPILING) - if(CUDAToolkit_TARGET_DIR) - list(REMOVE_AT CMAKE_FIND_ROOT_PATH -1) - endif() -else() +if(_CUDAToolkit_Pop_Prefix) list(REMOVE_AT CMAKE_PREFIX_PATH -1) + unset(_CUDAToolkit_Pop_Prefix) endif() #----------------------------------------------------------------------------- @@ -724,7 +731,7 @@ endif() # Construct import targets if(CUDAToolkit_FOUND) - function(find_and_add_cuda_import_lib lib_name) + function(_CUDAToolkit_find_and_add_import_lib lib_name) if(ARGC GREATER 1) set(search_names ${ARGN}) @@ -734,7 +741,7 @@ if(CUDAToolkit_FOUND) find_library(CUDA_${lib_name}_LIBRARY NAMES ${search_names} - PATHS ${CUDAToolkit_LIBRARY_DIR} + HINTS ${CUDAToolkit_LIBRARY_DIR} ENV CUDA_PATH PATH_SUFFIXES nvidia/current lib64 lib64/stubs lib/x64 lib lib/stubs ) @@ -746,7 +753,7 @@ if(CUDAToolkit_FOUND) endif() endfunction() - function(add_cuda_link_dependency lib_name) + function(_CUDAToolkit_add_link_dependency lib_name) if(TARGET CUDA::${lib_name}) foreach(dependency IN LISTS ARGN) if(TARGET CUDA::${dependency}) @@ -761,40 +768,40 @@ if(CUDAToolkit_FOUND) target_link_directories(CUDA::toolkit INTERFACE "${CUDAToolkit_LIBRARY_DIR}") - find_and_add_cuda_import_lib(cuda_driver cuda) + _CUDAToolkit_find_and_add_import_lib(cuda_driver cuda) - find_and_add_cuda_import_lib(cudart) - find_and_add_cuda_import_lib(cudart_static) + _CUDAToolkit_find_and_add_import_lib(cudart) + _CUDAToolkit_find_and_add_import_lib(cudart_static) foreach (cuda_lib cublas cufft cufftw curand cusolver cusparse nvgraph nvjpeg) - find_and_add_cuda_import_lib(${cuda_lib}) + _CUDAToolkit_find_and_add_import_lib(${cuda_lib}) - find_and_add_cuda_import_lib(${cuda_lib}_static) + _CUDAToolkit_find_and_add_import_lib(${cuda_lib}_static) endforeach() # cuSOLVER depends on cuBLAS, and cuSPARSE - add_cuda_link_dependency(cusolver cublas cusparse) - add_cuda_link_dependency(cusolver_static cublas_static cusparse) + _CUDAToolkit_add_link_dependency(cusolver cublas cusparse) + _CUDAToolkit_add_link_dependency(cusolver_static cublas_static cusparse) # nvGRAPH depends on cuRAND, and cuSOLVER. - add_cuda_link_dependency(nvgraph curand cusolver) - add_cuda_link_dependency(nvgraph_static curand_static cusolver_static) + _CUDAToolkit_add_link_dependency(nvgraph curand cusolver) + _CUDAToolkit_add_link_dependency(nvgraph_static curand_static cusolver_static) - find_and_add_cuda_import_lib(nppc) - find_and_add_cuda_import_lib(nppc_static) + _CUDAToolkit_find_and_add_import_lib(nppc) + _CUDAToolkit_find_and_add_import_lib(nppc_static) # Process the majority of the NPP libraries. foreach (cuda_lib nppial nppicc nppidei nppif nppig nppim nppist nppitc npps nppicom nppisu) - find_and_add_cuda_import_lib(${cuda_lib}) - find_and_add_cuda_import_lib(${cuda_lib}_static) - add_cuda_link_dependency(${cuda_lib} nppc) - add_cuda_link_dependency(${cuda_lib}_static nppc_static) + _CUDAToolkit_find_and_add_import_lib(${cuda_lib}) + _CUDAToolkit_find_and_add_import_lib(${cuda_lib}_static) + _CUDAToolkit_add_link_dependency(${cuda_lib} nppc) + _CUDAToolkit_add_link_dependency(${cuda_lib}_static nppc_static) endforeach() - find_and_add_cuda_import_lib(nvrtc) - add_cuda_link_dependency(nvrtc cuda_driver) + _CUDAToolkit_find_and_add_import_lib(nvrtc) + _CUDAToolkit_add_link_dependency(nvrtc cuda_driver) - find_and_add_cuda_import_lib(nvml nvidia-ml nvml) + _CUDAToolkit_find_and_add_import_lib(nvml nvidia-ml nvml) if(WIN32) # nvtools can be installed outside the CUDA toolkit directory @@ -807,15 +814,20 @@ if(CUDAToolkit_FOUND) PATH_SUFFIXES lib/x64 lib ) endif() - find_and_add_cuda_import_lib(nvToolsExt nvToolsExt nvToolsExt64) + _CUDAToolkit_find_and_add_import_lib(nvToolsExt nvToolsExt nvToolsExt64) - find_and_add_cuda_import_lib(OpenCL) + _CUDAToolkit_find_and_add_import_lib(OpenCL) - find_and_add_cuda_import_lib(culibos) + _CUDAToolkit_find_and_add_import_lib(culibos) if(TARGET CUDA::culibos) foreach (cuda_lib cublas cufft cusparse curand nppc nvjpeg) - add_cuda_link_dependency(${cuda_lib}_static culibos) + _CUDAToolkit_add_link_dependency(${cuda_lib}_static culibos) endforeach() endif() endif() + +if(_CUDAToolkit_Pop_ROOT_PATH) + list(REMOVE_AT CMAKE_FIND_ROOT_PATH 0) + unset(_CUDAToolkit_Pop_ROOT_PATH) +endif() diff --git a/Modules/Platform/Windows-NVIDIA-CUDA.cmake b/Modules/Platform/Windows-NVIDIA-CUDA.cmake index 30b5aa9..f809094 100644 --- a/Modules/Platform/Windows-NVIDIA-CUDA.cmake +++ b/Modules/Platform/Windows-NVIDIA-CUDA.cmake @@ -69,6 +69,11 @@ else() endif() unset(_cmp0092) +set(CMAKE_CUDA_RUNTIME_LIBRARY_DEFAULT "STATIC") +set(CMAKE_CUDA_RUNTIME_LIBRARY_LINK_OPTIONS_STATIC "cudadevrt;cudart_static") +set(CMAKE_CUDA_RUNTIME_LIBRARY_LINK_OPTIONS_SHARED "cudadevrt;cudart") +set(CMAKE_CUDA_RUNTIME_LIBRARY_LINK_OPTIONS_NONE "") + string(APPEND CMAKE_CUDA_FLAGS_INIT " ${PLATFORM_DEFINES_CUDA} -D_WINDOWS -Xcompiler=\"${_W3}${_FLAGS_CXX}\"") string(APPEND CMAKE_CUDA_FLAGS_DEBUG_INIT " -Xcompiler=\"${_MDd}-Zi -Ob0 -Od ${_RTC1}\"") string(APPEND CMAKE_CUDA_FLAGS_RELEASE_INIT " -Xcompiler=\"${_MD}-O2 -Ob2\" -DNDEBUG") diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 74d779f..413b587 100644 --- a/Source/CMakeVersion.cmake +++ b/Source/CMakeVersion.cmake @@ -1,7 +1,7 @@ # CMake version number components. set(CMake_VERSION_MAJOR 3) set(CMake_VERSION_MINOR 16) -set(CMake_VERSION_PATCH 20200128) +set(CMake_VERSION_PATCH 20200129) #set(CMake_VERSION_RC 0) set(CMake_VERSION_IS_DIRTY 0) diff --git a/Source/cmArchiveWrite.cxx b/Source/cmArchiveWrite.cxx index e5eea79..f8d1aa7 100644 --- a/Source/cmArchiveWrite.cxx +++ b/Source/cmArchiveWrite.cxx @@ -200,8 +200,10 @@ bool cmArchiveWrite::Add(std::string path, size_t skip, const char* prefix, bool cmArchiveWrite::AddPath(const char* path, size_t skip, const char* prefix, bool recursive) { - if (!this->AddFile(path, skip, prefix)) { - return false; + if (strcmp(path, ".") != 0 || this->Format != "zip") { + if (!this->AddFile(path, skip, prefix)) { + return false; + } } if ((!cmSystemTools::FileIsDirectory(path) || !recursive) || cmSystemTools::FileIsSymlink(path)) { @@ -210,6 +212,9 @@ bool cmArchiveWrite::AddPath(const char* path, size_t skip, const char* prefix, cmsys::Directory d; if (d.Load(path)) { std::string next = cmStrCat(path, '/'); + if (next == "./" && this->Format == "zip") { + next.clear(); + } std::string::size_type end = next.size(); unsigned long n = d.GetNumberOfFiles(); for (unsigned long i = 0; i < n; ++i) { diff --git a/Source/cmCacheManager.cxx b/Source/cmCacheManager.cxx index 265941a..dc9aba1 100644 --- a/Source/cmCacheManager.cxx +++ b/Source/cmCacheManager.cxx @@ -648,8 +648,8 @@ void cmCacheManager::CacheEntry::AppendProperty(const std::string& prop, bool asString) { if (prop == "TYPE") { - this->Type = cmState::StringToCacheEntryType(!value.empty() ? value.c_str() - : "STRING"); + this->Type = + cmState::StringToCacheEntryType(!value.empty() ? value : "STRING"); } else if (prop == "VALUE") { if (!value.empty()) { if (!this->Value.empty() && !asString) { @@ -658,7 +658,7 @@ void cmCacheManager::CacheEntry::AppendProperty(const std::string& prop, this->Value += value; } } else { - this->Properties.AppendProperty(prop, value.c_str(), asString); + this->Properties.AppendProperty(prop, value, asString); } } diff --git a/Source/cmCommonTargetGenerator.cxx b/Source/cmCommonTargetGenerator.cxx index 9106e70..b8d8b96 100644 --- a/Source/cmCommonTargetGenerator.cxx +++ b/Source/cmCommonTargetGenerator.cxx @@ -233,7 +233,10 @@ void cmCommonTargetGenerator::AppendOSXVerFlag(std::string& flags, int major; int minor; int patch; - this->GeneratorTarget->GetTargetVersion(so, major, minor, patch); + std::string prop = cmStrCat("OSX_", name, "_VERSION"); + std::string fallback_prop = so ? "SOVERSION" : "VERSION"; + this->GeneratorTarget->GetTargetVersionFallback(prop, fallback_prop, major, + minor, patch); if (major > 0 || minor > 0 || patch > 0) { // Append the flag since a non-zero version is specified. std::ostringstream vflag; diff --git a/Source/cmComputeLinkInformation.cxx b/Source/cmComputeLinkInformation.cxx index 8773d10..7be6d2c 100644 --- a/Source/cmComputeLinkInformation.cxx +++ b/Source/cmComputeLinkInformation.cxx @@ -8,8 +8,11 @@ #include <sstream> #include <utility> +#include <cm/memory> + #include "cmAlgorithms.h" #include "cmComputeLinkDepends.h" +#include "cmGeneratorExpression.h" #include "cmGeneratorTarget.h" #include "cmGlobalGenerator.h" #include "cmListFileCache.h" @@ -256,11 +259,10 @@ cmComputeLinkInformation::cmComputeLinkInformation( "FIND_LIBRARY_USE_OPENBSD_VERSIONING"); // Allocate internals. - this->OrderLinkerSearchPath = new cmOrderDirectories( + this->OrderLinkerSearchPath = cm::make_unique<cmOrderDirectories>( this->GlobalGenerator, target, "linker search path"); - this->OrderRuntimeSearchPath = new cmOrderDirectories( + this->OrderRuntimeSearchPath = cm::make_unique<cmOrderDirectories>( this->GlobalGenerator, target, "runtime search path"); - this->OrderDependentRPath = nullptr; // Get the language used for linking this target. this->LinkLanguage = this->Target->GetLinkerLanguage(config); @@ -358,7 +360,7 @@ cmComputeLinkInformation::cmComputeLinkInformation( this->SharedDependencyMode = SharedDepModeLibDir; } else if (!this->RPathLinkFlag.empty()) { this->SharedDependencyMode = SharedDepModeDir; - this->OrderDependentRPath = new cmOrderDirectories( + this->OrderDependentRPath = cm::make_unique<cmOrderDirectories>( this->GlobalGenerator, target, "dependent library path"); } @@ -400,12 +402,7 @@ cmComputeLinkInformation::cmComputeLinkInformation( "CMAKE_POLICY_WARNING_CMP0060"); } -cmComputeLinkInformation::~cmComputeLinkInformation() -{ - delete this->OrderLinkerSearchPath; - delete this->OrderRuntimeSearchPath; - delete this->OrderDependentRPath; -} +cmComputeLinkInformation::~cmComputeLinkInformation() = default; void cmComputeLinkInformation::AppendValues( std::string& result, std::vector<BT<std::string>>& values) @@ -573,6 +570,15 @@ void cmComputeLinkInformation::AddImplicitLinkInfo() cmGeneratorTarget::LinkClosure const* lc = this->Target->GetLinkClosure(this->Config); for (std::string const& li : lc->Languages) { + + if (li == "CUDA") { + // These need to go before the other implicit link information + // as they could require symbols from those other library + // Currently restricted to CUDA as it is the only language + // we have documented runtime behavior controls for + this->AddRuntimeLinkLibrary(li); + } + // Skip those of the linker language. They are implicit. if (li != this->LinkLanguage) { this->AddImplicitLinkInfo(li); @@ -580,6 +586,39 @@ void cmComputeLinkInformation::AddImplicitLinkInfo() } } +void cmComputeLinkInformation::AddRuntimeLinkLibrary(std::string const& lang) +{ // Add the lang runtime library flags. This is activated by the presence + // of a default selection whether or not it is overridden by a property. + std::string defaultVar = + cmStrCat("CMAKE_", lang, "_RUNTIME_LIBRARY_DEFAULT"); + const char* langRuntimeLibraryDefault = + this->Makefile->GetDefinition(defaultVar); + if (langRuntimeLibraryDefault && *langRuntimeLibraryDefault) { + const char* runtimeLibraryValue = + this->Target->GetProperty(cmStrCat(lang, "_RUNTIME_LIBRARY")); + if (!runtimeLibraryValue) { + runtimeLibraryValue = langRuntimeLibraryDefault; + } + + std::string runtimeLibrary = + cmSystemTools::UpperCase(cmGeneratorExpression::Evaluate( + runtimeLibraryValue, this->Target->GetLocalGenerator(), this->Config, + this->Target)); + if (!runtimeLibrary.empty()) { + if (const char* runtimeLinkOptions = this->Makefile->GetDefinition( + "CMAKE_" + lang + "_RUNTIME_LIBRARY_LINK_OPTIONS_" + + runtimeLibrary)) { + std::vector<std::string> libsVec = cmExpandedList(runtimeLinkOptions); + for (std::string const& i : libsVec) { + if (!cmContains(this->ImplicitLinkLibs, i)) { + this->AddItem(i, nullptr); + } + } + } + } + } +} + void cmComputeLinkInformation::AddImplicitLinkInfo(std::string const& lang) { // Add libraries for this language that are not implied by the @@ -747,10 +786,10 @@ void cmComputeLinkInformation::AddSharedDepItem(std::string const& item, if (this->SharedDependencyMode == SharedDepModeLibDir && !this->LinkWithRuntimePath /* AddLibraryRuntimeInfo adds it */) { // Add the item to the linker search path. - order = this->OrderLinkerSearchPath; + order = this->OrderLinkerSearchPath.get(); } else if (this->SharedDependencyMode == SharedDepModeDir) { // Add the item to the separate dependent library search path. - order = this->OrderDependentRPath; + order = this->OrderDependentRPath.get(); } if (order) { if (tgt) { diff --git a/Source/cmComputeLinkInformation.h b/Source/cmComputeLinkInformation.h index 92ab83b..3bc9c16 100644 --- a/Source/cmComputeLinkInformation.h +++ b/Source/cmComputeLinkInformation.h @@ -6,6 +6,7 @@ #include "cmConfigure.h" // IWYU pragma: keep #include <iosfwd> +#include <memory> #include <set> #include <string> #include <utility> @@ -29,6 +30,9 @@ class cmComputeLinkInformation public: cmComputeLinkInformation(cmGeneratorTarget const* target, const std::string& config); + cmComputeLinkInformation(const cmComputeLinkInformation&) = delete; + cmComputeLinkInformation& operator=(const cmComputeLinkInformation&) = + delete; ~cmComputeLinkInformation(); bool Compute(); @@ -164,7 +168,7 @@ private: cmsys::RegularExpression SplitFramework; // Linker search path computation. - cmOrderDirectories* OrderLinkerSearchPath; + std::unique_ptr<cmOrderDirectories> OrderLinkerSearchPath; bool FinishLinkerSearchDirectories(); void PrintLinkPolicyDiagnosis(std::ostream&); @@ -172,6 +176,7 @@ private: void LoadImplicitLinkInfo(); void AddImplicitLinkInfo(); void AddImplicitLinkInfo(std::string const& lang); + void AddRuntimeLinkLibrary(std::string const& lang); std::set<std::string> ImplicitLinkDirs; std::set<std::string> ImplicitLinkLibs; @@ -184,9 +189,9 @@ private: std::vector<std::string> OldUserFlagItems; std::set<std::string> CMP0060WarnItems; // Dependent library path computation. - cmOrderDirectories* OrderDependentRPath; + std::unique_ptr<cmOrderDirectories> OrderDependentRPath; // Runtime path computation. - cmOrderDirectories* OrderRuntimeSearchPath; + std::unique_ptr<cmOrderDirectories> OrderRuntimeSearchPath; bool OldLinkDirMode; bool OpenBSD; diff --git a/Source/cmGeneratorExpressionNode.cxx b/Source/cmGeneratorExpressionNode.cxx index 66f1c71..14478c2 100644 --- a/Source/cmGeneratorExpressionNode.cxx +++ b/Source/cmGeneratorExpressionNode.cxx @@ -14,6 +14,7 @@ #include <utility> #include <cm/iterator> +#include <cm/string_view> #include "cmsys/RegularExpression.hxx" #include "cmsys/String.h" @@ -37,7 +38,6 @@ #include "cmState.h" #include "cmStateSnapshot.h" #include "cmStateTypes.h" -#include "cmString.hxx" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmTarget.h" diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index 792cd4d..c525a6e 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -5280,11 +5280,23 @@ cmComputeLinkInformation* cmGeneratorTarget::GetLinkInformation( void cmGeneratorTarget::GetTargetVersion(int& major, int& minor) const { int patch; - this->GetTargetVersion(false, major, minor, patch); + this->GetTargetVersion("VERSION", major, minor, patch); } -void cmGeneratorTarget::GetTargetVersion(bool soversion, int& major, - int& minor, int& patch) const +void cmGeneratorTarget::GetTargetVersionFallback( + const std::string& property, const std::string& fallback_property, + int& major, int& minor, int& patch) const +{ + if (this->GetProperty(property)) { + this->GetTargetVersion(property, major, minor, patch); + } else { + this->GetTargetVersion(fallback_property, major, minor, patch); + } +} + +void cmGeneratorTarget::GetTargetVersion(const std::string& property, + int& major, int& minor, + int& patch) const { // Set the default values. major = 0; @@ -5293,9 +5305,7 @@ void cmGeneratorTarget::GetTargetVersion(bool soversion, int& major, assert(this->GetType() != cmStateEnums::INTERFACE_LIBRARY); - // Look for a VERSION or SOVERSION property. - const char* prop = soversion ? "SOVERSION" : "VERSION"; - if (const char* version = this->GetProperty(prop)) { + if (const char* version = this->GetProperty(property)) { // Try to parse the version number and store the results that were // successfully parsed. int parsed_major; diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h index 9d06104..ac254c1 100644 --- a/Source/cmGeneratorTarget.h +++ b/Source/cmGeneratorTarget.h @@ -755,11 +755,19 @@ public: void GetTargetVersion(int& major, int& minor) const; /** Get the target major, minor, and patch version numbers - interpreted from the VERSION or SOVERSION property. Version 0 + interpreted from the given property. Version 0 is returned if the property is not set or cannot be parsed. */ - void GetTargetVersion(bool soversion, int& major, int& minor, + void GetTargetVersion(std::string const& property, int& major, int& minor, int& patch) const; + /** Get the target major, minor, and patch version numbers + interpreted from the given property and if empty use the + fallback property. Version 0 is returned if the property is + not set or cannot be parsed. */ + void GetTargetVersionFallback(const std::string& property, + const std::string& fallback_property, + int& major, int& minor, int& patch) const; + std::string GetFortranModuleDirectory(std::string const& working_dir) const; const char* GetSourcesProperty() const; diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index 38ff3ae..1f084f5 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -1645,7 +1645,9 @@ void cmGlobalGenerator::FinalizeTargetCompileInfo() for (std::string const& c : configs) { std::string defPropName = cmStrCat("COMPILE_DEFINITIONS_", cmSystemTools::UpperCase(c)); - t->AppendProperty(defPropName, mf->GetProperty(defPropName)); + if (const char* val = mf->GetProperty(defPropName)) { + t->AppendProperty(defPropName, val); + } } } } @@ -2525,6 +2527,7 @@ void cmGlobalGenerator::AddGlobalTarget_RebuildCache( gti.PerConfig = false; cmCustomCommandLine singleLine; singleLine.push_back(cmSystemTools::GetCMakeCommand()); + singleLine.push_back("--regenerate-during-build"); singleLine.push_back("-S$(CMAKE_SOURCE_DIR)"); singleLine.push_back("-B$(CMAKE_BINARY_DIR)"); gti.CommandLines.push_back(std::move(singleLine)); diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx index 2dd89e3..d093c43 100644 --- a/Source/cmGlobalNinjaGenerator.cxx +++ b/Source/cmGlobalNinjaGenerator.cxx @@ -528,6 +528,19 @@ void cmGlobalNinjaGenerator::Generate() this->CloseRulesFileStream(); this->CloseBuildFileStreams(); +#ifdef _WIN32 + // The ninja tools will not be able to update metadata on Windows + // when we are re-generating inside an existing 'ninja' invocation + // because the outer tool has the files open for write. + if (!this->GetCMakeInstance()->GetRegenerateDuringBuild()) +#endif + { + this->CleanMetaData(); + } +} + +void cmGlobalNinjaGenerator::CleanMetaData() +{ auto run_ninja_tool = [this](std::vector<char const*> const& args) { std::vector<std::string> command; command.push_back(this->NinjaCommand); @@ -549,22 +562,33 @@ void cmGlobalNinjaGenerator::Generate() } }; + // Can the tools below expect 'build.ninja' to be loadable? + bool const expectBuildManifest = + !this->IsMultiConfig() && this->OutputPathPrefix.empty(); + + // Skip some ninja tools if they need 'build.ninja' but it is missing. + bool const missingBuildManifest = expectBuildManifest && + (this->NinjaSupportsCleanDeadTool || + this->NinjaSupportsUnconditionalRecompactTool) && + !cmSystemTools::FileExists("build.ninja"); + // The `cleandead` tool needs to know about all outputs in the build we just // wrote out. Ninja-Multi doesn't have a single `build.ninja` we can use that // is the union of all generated configurations, so we can't run it reliably // in that case. - if (this->NinjaSupportsCleanDeadTool && !this->IsMultiConfig()) { + if (this->NinjaSupportsCleanDeadTool && expectBuildManifest && + !missingBuildManifest) { run_ninja_tool({ "cleandead" }); } // The `recompact` tool loads the manifest. As above, we don't have a single // `build.ninja` to load for this in Ninja-Multi. This may be relaxed in the // future pending further investigation into how Ninja works upstream // (ninja#1721). - if (this->NinjaSupportsUnconditionalRecompactTool && - !this->IsMultiConfig()) { + if (this->NinjaSupportsUnconditionalRecompactTool && expectBuildManifest && + !missingBuildManifest) { run_ninja_tool({ "recompact" }); } - if (this->NinjaSupportsRestatTool) { + if (this->NinjaSupportsRestatTool && this->OutputPathPrefix.empty()) { // XXX(ninja): We only list `build.ninja` entry files here because CMake // *always* rewrites these files on a reconfigure. If CMake ever gets // smarter about this, all CMake-time created/edited files listed as @@ -1514,7 +1538,7 @@ void cmGlobalNinjaGenerator::WriteTargetRebuildManifest(std::ostream& os) { cmNinjaRule rule("RERUN_CMAKE"); rule.Command = - cmStrCat(CMakeCmd(), " -S", + cmStrCat(CMakeCmd(), " --regenerate-during-build -S", lg->ConvertToOutputFormat(lg->GetSourceDirectory(), cmOutputConverter::SHELL), " -B", diff --git a/Source/cmGlobalNinjaGenerator.h b/Source/cmGlobalNinjaGenerator.h index d00a061..9d5521a 100644 --- a/Source/cmGlobalNinjaGenerator.h +++ b/Source/cmGlobalNinjaGenerator.h @@ -438,6 +438,7 @@ private: bool OpenRulesFileStream(); void CloseRulesFileStream(); + void CleanMetaData(); /// Write the common disclaimer text at the top of each build file. void WriteDisclaimer(std::ostream& os); diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx index f887284..3d5c9c4 100644 --- a/Source/cmGlobalXCodeGenerator.cxx +++ b/Source/cmGlobalXCodeGenerator.cxx @@ -528,7 +528,8 @@ void cmGlobalXCodeGenerator::AddExtraTargets( root->GetMakefile()->IsOn("CMAKE_XCODE_GENERATE_TOP_LEVEL_PROJECT_ONLY"); bool isTopLevel = !root->GetStateSnapshot().GetBuildsystemDirectoryParent().IsValid(); - if (regenerate && (isTopLevel || !generateTopLevelProjectOnly)) { + bool isGenerateProject = isTopLevel || !generateTopLevelProjectOnly; + if (regenerate && isGenerateProject) { this->CreateReRunCMakeFile(root, gens); std::string file = this->ConvertToRelativeForMake(this->CurrentReRunCMakeMakefile); @@ -558,7 +559,8 @@ void cmGlobalXCodeGenerator::AddExtraTargets( // run the depend check makefile as a post build rule // this will make sure that when the next target is built // things are up-to-date - if (target->GetType() == cmStateEnums::OBJECT_LIBRARY) { + if (isGenerateProject && + target->GetType() == cmStateEnums::OBJECT_LIBRARY) { commandLines.front().back() = // fill placeholder this->PostBuildMakeTarget(target->GetName(), "$(CONFIGURATION)"); gen->AddCustomCommandToTarget( @@ -2366,8 +2368,9 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt, int minor; int patch; - // VERSION -> current_version - gtgt->GetTargetVersion(false, major, minor, patch); + // OSX_CURRENT_VERSION or VERSION -> current_version + gtgt->GetTargetVersionFallback("OSX_CURRENT_VERSION", "VERSION", major, + minor, patch); std::ostringstream v; // Xcode always wants at least 1.0.0 or nothing @@ -2377,8 +2380,9 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt, buildSettings->AddAttribute("DYLIB_CURRENT_VERSION", this->CreateString(v.str())); - // SOVERSION -> compatibility_version - gtgt->GetTargetVersion(true, major, minor, patch); + // OSX_COMPATIBILITY_VERSION or SOVERSION -> compatibility_version + gtgt->GetTargetVersionFallback("OSX_COMPATIBILITY_VERSION", "SOVERSION", + major, minor, patch); std::ostringstream vso; // Xcode always wants at least 1.0.0 or nothing diff --git a/Source/cmLinkLibrariesCommand.cxx b/Source/cmLinkLibrariesCommand.cxx index cb63ceb..2b8f836 100644 --- a/Source/cmLinkLibrariesCommand.cxx +++ b/Source/cmLinkLibrariesCommand.cxx @@ -32,7 +32,7 @@ bool cmLinkLibrariesCommand(std::vector<std::string> const& args, } mf.AppendProperty("LINK_LIBRARIES", "optimized"); } - mf.AppendProperty("LINK_LIBRARIES", i->c_str()); + mf.AppendProperty("LINK_LIBRARIES", *i); } return true; diff --git a/Source/cmMacroCommand.cxx b/Source/cmMacroCommand.cxx index a35dc20..0b0d9ac 100644 --- a/Source/cmMacroCommand.cxx +++ b/Source/cmMacroCommand.cxx @@ -167,7 +167,7 @@ bool cmMacroFunctionBlocker::Replay(std::vector<cmListFileFunction> functions, cmExecutionStatus& status) { cmMakefile& mf = status.GetMakefile(); - mf.AppendProperty("MACROS", this->Args[0].c_str()); + mf.AppendProperty("MACROS", this->Args[0]); // create a new command and add it to cmake cmMacroHelperCommand f; f.Args = this->Args; diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index 83eef38..b2e59bd 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -1287,17 +1287,17 @@ void cmMakefile::RemoveDefineFlag(std::string const& flag) void cmMakefile::AddCompileDefinition(std::string const& option) { - this->AppendProperty("COMPILE_DEFINITIONS", option.c_str()); + this->AppendProperty("COMPILE_DEFINITIONS", option); } void cmMakefile::AddCompileOption(std::string const& option) { - this->AppendProperty("COMPILE_OPTIONS", option.c_str()); + this->AppendProperty("COMPILE_OPTIONS", option); } void cmMakefile::AddLinkOption(std::string const& option) { - this->AppendProperty("LINK_OPTIONS", option.c_str()); + this->AppendProperty("LINK_OPTIONS", option); } void cmMakefile::AddLinkDirectory(std::string const& directory, bool before) @@ -4038,8 +4038,8 @@ void cmMakefile::SetProperty(const std::string& prop, const char* value) this->StateSnapshot.GetDirectory().SetProperty(prop, value, this->Backtrace); } -void cmMakefile::AppendProperty(const std::string& prop, const char* value, - bool asString) +void cmMakefile::AppendProperty(const std::string& prop, + const std::string& value, bool asString) { this->StateSnapshot.GetDirectory().AppendProperty(prop, value, asString, this->Backtrace); diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h index b13716b..68f2c2f 100644 --- a/Source/cmMakefile.h +++ b/Source/cmMakefile.h @@ -135,7 +135,7 @@ public: std::unique_ptr<cmFunctionBlocker> RemoveFunctionBlocker(); /** - * Try running cmake and building a file. This is used for dynalically + * Try running cmake and building a file. This is used for dynamically * loaded commands, not as part of the usual build process. */ int TryCompile(const std::string& srcdir, const std::string& bindir, @@ -784,7 +784,7 @@ public: //! Set/Get a property of this directory void SetProperty(const std::string& prop, const char* value); - void AppendProperty(const std::string& prop, const char* value, + void AppendProperty(const std::string& prop, const std::string& value, bool asString = false); const char* GetProperty(const std::string& prop) const; const char* GetProperty(const std::string& prop, bool chain) const; diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx index 714d01e..a2fa3b1 100644 --- a/Source/cmMakefileTargetGenerator.cxx +++ b/Source/cmMakefileTargetGenerator.cxx @@ -782,7 +782,13 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles( } if (tidy && *tidy) { run_iwyu += " --tidy="; - run_iwyu += this->LocalGenerator->EscapeForShell(tidy); + const char* driverMode = this->Makefile->GetDefinition( + "CMAKE_" + lang + "_CLANG_TIDY_DRIVER_MODE"); + if (!(driverMode && *driverMode)) { + driverMode = lang == "C" ? "gcc" : "g++"; + } + run_iwyu += this->LocalGenerator->EscapeForShell( + cmStrCat(tidy, ";--driver-mode=", driverMode)); } if (cpplint && *cpplint) { run_iwyu += " --cpplint="; diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx index 4ebdd24..5e8cc7d 100644 --- a/Source/cmNinjaTargetGenerator.cxx +++ b/Source/cmNinjaTargetGenerator.cxx @@ -761,7 +761,13 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang, } if (tidy && *tidy) { run_iwyu += " --tidy="; - run_iwyu += this->GetLocalGenerator()->EscapeForShell(tidy); + const char* driverMode = this->Makefile->GetDefinition( + "CMAKE_" + lang + "_CLANG_TIDY_DRIVER_MODE"); + if (!(driverMode && *driverMode)) { + driverMode = lang == "C" ? "gcc" : "g++"; + } + run_iwyu += this->GetLocalGenerator()->EscapeForShell( + cmStrCat(tidy, ";--driver-mode=", driverMode)); } if (cpplint && *cpplint) { run_iwyu += " --cpplint="; diff --git a/Source/cmPropertyMap.cxx b/Source/cmPropertyMap.cxx index a3d4946..d4b3552 100644 --- a/Source/cmPropertyMap.cxx +++ b/Source/cmPropertyMap.cxx @@ -20,11 +20,11 @@ void cmPropertyMap::SetProperty(const std::string& name, const char* value) Map_[name] = value; } -void cmPropertyMap::AppendProperty(const std::string& name, const char* value, - bool asString) +void cmPropertyMap::AppendProperty(const std::string& name, + const std::string& value, bool asString) { // Skip if nothing to append. - if (!value || !*value) { + if (value.empty()) { return; } diff --git a/Source/cmPropertyMap.h b/Source/cmPropertyMap.h index 9aed349..bea4372 100644 --- a/Source/cmPropertyMap.h +++ b/Source/cmPropertyMap.h @@ -27,7 +27,7 @@ public: void SetProperty(const std::string& name, const char* value); //! Append to the property value - void AppendProperty(const std::string& name, const char* value, + void AppendProperty(const std::string& name, const std::string& value, bool asString = false); //! Get the property value diff --git a/Source/cmQtAutoGenInitializer.cxx b/Source/cmQtAutoGenInitializer.cxx index ebb522b..acd85a0 100644 --- a/Source/cmQtAutoGenInitializer.cxx +++ b/Source/cmQtAutoGenInitializer.cxx @@ -42,7 +42,6 @@ #include "cmSourceGroup.h" #include "cmState.h" #include "cmStateTypes.h" -#include "cmString.hxx" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmTarget.h" diff --git a/Source/cmSearchPath.cxx b/Source/cmSearchPath.cxx index d15ce57..766d347 100644 --- a/Source/cmSearchPath.cxx +++ b/Source/cmSearchPath.cxx @@ -181,7 +181,13 @@ void cmSearchPath::AddPrefixPaths(const std::vector<std::string>& paths, const char* arch = this->FC->Makefile->GetDefinition("CMAKE_LIBRARY_ARCHITECTURE"); if (arch && *arch) { - this->AddPathInternal(dir + subdir + "/" + arch, base); + if (this->FC->Makefile->IsDefinitionSet("CMAKE_SYSROOT") && + this->FC->Makefile->IsDefinitionSet( + "CMAKE_PREFIX_LIBRARY_ARCHITECTURE")) { + this->AddPathInternal(cmStrCat('/', arch, dir, subdir), base); + } else { + this->AddPathInternal(cmStrCat(dir, subdir, '/', arch), base); + } } } std::string add = dir + subdir; diff --git a/Source/cmSetPropertyCommand.cxx b/Source/cmSetPropertyCommand.cxx index 112d832..3705727 100644 --- a/Source/cmSetPropertyCommand.cxx +++ b/Source/cmSetPropertyCommand.cxx @@ -194,9 +194,8 @@ namespace { bool HandleGlobalMode(cmExecutionStatus& status, const std::set<std::string>& names, const std::string& propertyName, - const std::string& propertyValue, - const bool appendAsString, const bool appendMode, - const bool remove) + const std::string& propertyValue, bool appendAsString, + bool appendMode, bool remove) { if (!names.empty()) { status.SetError("given names for GLOBAL scope."); @@ -205,14 +204,14 @@ bool HandleGlobalMode(cmExecutionStatus& status, // Set or append the property. cmake* cm = status.GetMakefile().GetCMakeInstance(); - const char* value = propertyValue.c_str(); - if (remove) { - value = nullptr; - } if (appendMode) { - cm->AppendProperty(propertyName, value ? value : "", appendAsString); + cm->AppendProperty(propertyName, propertyValue, appendAsString); } else { - cm->SetProperty(propertyName, value); + if (remove) { + cm->SetProperty(propertyName, nullptr); + } else { + cm->SetProperty(propertyName, propertyValue.c_str()); + } } return true; @@ -221,9 +220,8 @@ bool HandleGlobalMode(cmExecutionStatus& status, bool HandleDirectoryMode(cmExecutionStatus& status, const std::set<std::string>& names, const std::string& propertyName, - const std::string& propertyValue, - const bool appendAsString, const bool appendMode, - const bool remove) + const std::string& propertyValue, bool appendAsString, + bool appendMode, bool remove) { if (names.size() > 1) { status.SetError("allows at most one name for DIRECTORY scope."); @@ -258,14 +256,14 @@ bool HandleDirectoryMode(cmExecutionStatus& status, } // Set or append the property. - const char* value = propertyValue.c_str(); - if (remove) { - value = nullptr; - } if (appendMode) { - mf->AppendProperty(propertyName, value ? value : "", appendAsString); + mf->AppendProperty(propertyName, propertyValue, appendAsString); } else { - mf->SetProperty(propertyName, value); + if (remove) { + mf->SetProperty(propertyName, nullptr); + } else { + mf->SetProperty(propertyName, propertyValue.c_str()); + } } return true; @@ -274,9 +272,8 @@ bool HandleDirectoryMode(cmExecutionStatus& status, bool HandleTargetMode(cmExecutionStatus& status, const std::set<std::string>& names, const std::string& propertyName, - const std::string& propertyValue, - const bool appendAsString, const bool appendMode, - const bool remove) + const std::string& propertyValue, bool appendAsString, + bool appendMode, bool remove) { for (std::string const& name : names) { if (status.GetMakefile().IsAlias(name)) { @@ -300,18 +297,18 @@ bool HandleTargetMode(cmExecutionStatus& status, bool HandleTarget(cmTarget* target, cmMakefile& makefile, const std::string& propertyName, - const std::string& propertyValue, const bool appendAsString, - const bool appendMode, const bool remove) + const std::string& propertyValue, bool appendAsString, + bool appendMode, bool remove) { // Set or append the property. - const char* value = propertyValue.c_str(); - if (remove) { - value = nullptr; - } if (appendMode) { - target->AppendProperty(propertyName, value, appendAsString); + target->AppendProperty(propertyName, propertyValue, appendAsString); } else { - target->SetProperty(propertyName, value); + if (remove) { + target->SetProperty(propertyName, nullptr); + } else { + target->SetProperty(propertyName, propertyValue.c_str()); + } } // Check the resulting value. @@ -323,9 +320,8 @@ bool HandleTarget(cmTarget* target, cmMakefile& makefile, bool HandleSourceMode(cmExecutionStatus& status, const std::set<std::string>& names, const std::string& propertyName, - const std::string& propertyValue, - const bool appendAsString, const bool appendMode, - const bool remove) + const std::string& propertyValue, bool appendAsString, + bool appendMode, bool remove) { for (std::string const& name : names) { // Get the source file. @@ -344,28 +340,26 @@ bool HandleSourceMode(cmExecutionStatus& status, } bool HandleSource(cmSourceFile* sf, const std::string& propertyName, - const std::string& propertyValue, const bool appendAsString, - const bool appendMode, const bool remove) + const std::string& propertyValue, bool appendAsString, + bool appendMode, bool remove) { // Set or append the property. - const char* value = propertyValue.c_str(); - if (remove) { - value = nullptr; - } - if (appendMode) { - sf->AppendProperty(propertyName, value, appendAsString); + sf->AppendProperty(propertyName, propertyValue, appendAsString); } else { - sf->SetProperty(propertyName, value); + if (remove) { + sf->SetProperty(propertyName, nullptr); + } else { + sf->SetProperty(propertyName, propertyValue.c_str()); + } } return true; } bool HandleTestMode(cmExecutionStatus& status, std::set<std::string>& names, const std::string& propertyName, - const std::string& propertyValue, - const bool appendAsString, const bool appendMode, - const bool remove) + const std::string& propertyValue, bool appendAsString, + bool appendMode, bool remove) { // Look for tests with all names given. std::set<std::string>::iterator next; @@ -396,18 +390,18 @@ bool HandleTestMode(cmExecutionStatus& status, std::set<std::string>& names, } bool HandleTest(cmTest* test, const std::string& propertyName, - const std::string& propertyValue, const bool appendAsString, - const bool appendMode, const bool remove) + const std::string& propertyValue, bool appendAsString, + bool appendMode, bool remove) { // Set or append the property. - const char* value = propertyValue.c_str(); - if (remove) { - value = nullptr; - } if (appendMode) { - test->AppendProperty(propertyName, value, appendAsString); + test->AppendProperty(propertyName, propertyValue, appendAsString); } else { - test->SetProperty(propertyName, value); + if (remove) { + test->SetProperty(propertyName, nullptr); + } else { + test->SetProperty(propertyName, propertyValue.c_str()); + } } return true; @@ -416,9 +410,8 @@ bool HandleTest(cmTest* test, const std::string& propertyName, bool HandleCacheMode(cmExecutionStatus& status, const std::set<std::string>& names, const std::string& propertyName, - const std::string& propertyValue, - const bool appendAsString, const bool appendMode, - const bool remove) + const std::string& propertyValue, bool appendAsString, + bool appendMode, bool remove) { if (propertyName == "ADVANCED") { if (!remove && !cmIsOn(propertyValue) && !cmIsOff(propertyValue)) { @@ -463,9 +456,8 @@ bool HandleCacheMode(cmExecutionStatus& status, bool HandleCacheEntry(std::string const& cacheKey, const cmMakefile& makefile, const std::string& propertyName, - const std::string& propertyValue, - const bool appendAsString, const bool appendMode, - const bool remove) + const std::string& propertyValue, bool appendAsString, + bool appendMode, bool remove) { // Set or append the property. const char* value = propertyValue.c_str(); @@ -486,9 +478,8 @@ bool HandleCacheEntry(std::string const& cacheKey, const cmMakefile& makefile, bool HandleInstallMode(cmExecutionStatus& status, const std::set<std::string>& names, const std::string& propertyName, - const std::string& propertyValue, - const bool appendAsString, const bool appendMode, - const bool remove) + const std::string& propertyValue, bool appendAsString, + bool appendMode, bool remove) { cmake* cm = status.GetMakefile().GetCMakeInstance(); @@ -510,8 +501,8 @@ bool HandleInstallMode(cmExecutionStatus& status, bool HandleInstall(cmInstalledFile* file, cmMakefile& makefile, const std::string& propertyName, - const std::string& propertyValue, const bool appendAsString, - const bool appendMode, const bool remove) + const std::string& propertyValue, bool appendAsString, + bool appendMode, bool remove) { // Set or append the property. const char* value = propertyValue.c_str(); diff --git a/Source/cmSourceFile.cxx b/Source/cmSourceFile.cxx index 60adf7f..fd9cacd 100644 --- a/Source/cmSourceFile.cxx +++ b/Source/cmSourceFile.cxx @@ -260,21 +260,21 @@ void cmSourceFile::SetProperty(const std::string& prop, const char* value) } } -void cmSourceFile::AppendProperty(const std::string& prop, const char* value, - bool asString) +void cmSourceFile::AppendProperty(const std::string& prop, + const std::string& value, bool asString) { if (prop == propINCLUDE_DIRECTORIES) { - if (value && *value) { + if (!value.empty()) { cmListFileBacktrace lfbt = this->Location.GetMakefile()->GetBacktrace(); this->IncludeDirectories.emplace_back(value, lfbt); } } else if (prop == propCOMPILE_OPTIONS) { - if (value && *value) { + if (!value.empty()) { cmListFileBacktrace lfbt = this->Location.GetMakefile()->GetBacktrace(); this->CompileOptions.emplace_back(value, lfbt); } } else if (prop == propCOMPILE_DEFINITIONS) { - if (value && *value) { + if (!value.empty()) { cmListFileBacktrace lfbt = this->Location.GetMakefile()->GetBacktrace(); this->CompileDefinitions.emplace_back(value, lfbt); } diff --git a/Source/cmSourceFile.h b/Source/cmSourceFile.h index 19a0d29..e22829f 100644 --- a/Source/cmSourceFile.h +++ b/Source/cmSourceFile.h @@ -42,7 +42,7 @@ public: //! Set/Get a property of this source file void SetProperty(const std::string& prop, const char* value); - void AppendProperty(const std::string& prop, const char* value, + void AppendProperty(const std::string& prop, const std::string& value, bool asString = false); //! Might return a nullptr if the property is not set or invalid const char* GetProperty(const std::string& prop) const; diff --git a/Source/cmState.cxx b/Source/cmState.cxx index 35f07a1..0ce8dd7 100644 --- a/Source/cmState.cxx +++ b/Source/cmState.cxx @@ -557,8 +557,8 @@ void cmState::SetGlobalProperty(const std::string& prop, const char* value) this->GlobalProperties.SetProperty(prop, value); } -void cmState::AppendGlobalProperty(const std::string& prop, const char* value, - bool asString) +void cmState::AppendGlobalProperty(const std::string& prop, + const std::string& value, bool asString) { this->GlobalProperties.AppendProperty(prop, value, asString); } diff --git a/Source/cmState.h b/Source/cmState.h index a744266..817046f 100644 --- a/Source/cmState.h +++ b/Source/cmState.h @@ -168,7 +168,7 @@ public: std::vector<std::string> GetCommandNames() const; void SetGlobalProperty(const std::string& prop, const char* value); - void AppendGlobalProperty(const std::string& prop, const char* value, + void AppendGlobalProperty(const std::string& prop, const std::string& value, bool asString = false); const char* GetGlobalProperty(const std::string& prop); bool GetGlobalPropertyAsBool(const std::string& prop); diff --git a/Source/cmStateDirectory.cxx b/Source/cmStateDirectory.cxx index 97fdbbe..4f003ed 100644 --- a/Source/cmStateDirectory.cxx +++ b/Source/cmStateDirectory.cxx @@ -521,7 +521,7 @@ void cmStateDirectory::SetProperty(const std::string& prop, const char* value, } void cmStateDirectory::AppendProperty(const std::string& prop, - const char* value, bool asString, + const std::string& value, bool asString, cmListFileBacktrace const& lfbt) { if (prop == "INCLUDE_DIRECTORIES") { diff --git a/Source/cmStateDirectory.h b/Source/cmStateDirectory.h index fe15563..53a2d54 100644 --- a/Source/cmStateDirectory.h +++ b/Source/cmStateDirectory.h @@ -84,7 +84,7 @@ public: void SetProperty(const std::string& prop, const char* value, cmListFileBacktrace const& lfbt); - void AppendProperty(const std::string& prop, const char* value, + void AppendProperty(const std::string& prop, const std::string& value, bool asString, cmListFileBacktrace const& lfbt); const char* GetProperty(const std::string& prop) const; const char* GetProperty(const std::string& prop, bool chain) const; diff --git a/Source/cmString.hxx b/Source/cmString.hxx index 073f4c9..9e91986 100644 --- a/Source/cmString.hxx +++ b/Source/cmString.hxx @@ -88,18 +88,6 @@ struct IntoString<std::string> : std::true_type }; template <> -struct IntoString<string_view> : std::true_type -{ - static std::string into_string(string_view s) { return std::string(s); } -}; - -template <> -struct IntoString<static_string_view> : std::true_type -{ - static string_view into_string(static_string_view s) { return s; } -}; - -template <> struct IntoString<char> : std::true_type { static std::string into_string(char const& c) { return std::string(1, c); } @@ -239,6 +227,25 @@ public: { } + /** + * Construct via static_string_view constructor. + * explicit is required to avoid ambiguous overloaded operators (i.e ==, + * etc...) with the ones provided by string_view. + */ + explicit String(static_string_view s) + : String(s, Private()) + { + } + /** + * Construct via string_view constructor. + * explicit is required to avoid ambiguous overloaded operators (i.e ==, + * etc...) with the ones provided by string_view. + */ + explicit String(string_view s) + : String(std::string(s), Private()) + { + } + /** Construct via std::string initializer list constructor. */ String(std::initializer_list<char> il) : String(std::string(il)) @@ -306,6 +313,17 @@ public: This shares ownership of the other string's buffer. */ String& operator=(String const&) noexcept = default; + String& operator=(static_string_view s) + { + *this = String(s); + return *this; + } + String& operator=(string_view s) + { + *this = String(s); + return *this; + } + /** Assign from any type implementing the IntoString trait. */ template <typename T> typename // NOLINT(*) @@ -328,6 +346,7 @@ public: /** Return a view of the string. */ string_view view() const noexcept { return view_; } + operator string_view() const noexcept { return this->view(); } /** Return true if the instance is an empty stringn or null string. */ bool empty() const noexcept { return view_.empty(); } @@ -638,58 +657,155 @@ private: string_view view_; }; -template <typename L, typename R> -typename std::enable_if<AsStringView<L>::value && AsStringView<R>::value, - bool>::type -operator==(L&& l, R&& r) +/** + * Trait for comparable types. + */ +template <typename T> +struct IsComparable : std::false_type +{ +}; + +template <typename T> +struct IsComparable<T&> : IsComparable<T> +{ +}; + +template <typename T> +struct IsComparable<T const> : IsComparable<T> +{ +}; + +template <typename T> +struct IsComparable<T const*> : IsComparable<T*> +{ +}; + +template <typename T, std::string::size_type N> +struct IsComparable<T const[N]> : IsComparable<T[N]> +{ +}; + +template <> +struct IsComparable<char*> : std::true_type { - return (AsStringView<L>::view(std::forward<L>(l)) == - AsStringView<R>::view(std::forward<R>(r))); +}; + +template <std::string::size_type N> +struct IsComparable<char[N]> : std::true_type +{ +}; + +template <> +struct IsComparable<std::string> : std::true_type +{ +}; + +template <> +struct IsComparable<char> : std::true_type +{ +}; + +/** comparison operators */ +inline bool operator==(const String& l, const String& r) +{ + return l.view() == r.view(); +} +template <typename L> +typename std::enable_if<IsComparable<L>::value, bool>::type operator==( + L&& l, const String& r) +{ + return AsStringView<L>::view(std::forward<L>(l)) == r.view(); +} +template <typename R> +typename std::enable_if<IsComparable<R>::value, bool>::type operator==( + const String& l, R&& r) +{ + return l.view() == AsStringView<R>::view(std::forward<R>(r)); } -template <typename L, typename R> -typename std::enable_if<AsStringView<L>::value && AsStringView<R>::value, - bool>::type -operator!=(L&& l, R&& r) +inline bool operator!=(const String& l, const String& r) +{ + return l.view() != r.view(); +} +template <typename L> +typename std::enable_if<IsComparable<L>::value, bool>::type operator!=( + L&& l, const String& r) { - return (AsStringView<L>::view(std::forward<L>(l)) != - AsStringView<R>::view(std::forward<R>(r))); + return AsStringView<L>::view(std::forward<L>(l)) != r.view(); +} +template <typename R> +typename std::enable_if<IsComparable<R>::value, bool>::type operator!=( + const String& l, R&& r) +{ + return l.view() != AsStringView<R>::view(std::forward<R>(r)); } -template <typename L, typename R> -typename std::enable_if<AsStringView<L>::value && AsStringView<R>::value, - bool>::type -operator<(L&& l, R&& r) +inline bool operator<(const String& l, const String& r) { - return (AsStringView<L>::view(std::forward<L>(l)) < - AsStringView<R>::view(std::forward<R>(r))); + return l.view() < r.view(); +} +template <typename L> +typename std::enable_if<IsComparable<L>::value, bool>::type operator<( + L&& l, const String& r) +{ + return AsStringView<L>::view(std::forward<L>(l)) < r.view(); +} +template <typename R> +typename std::enable_if<IsComparable<R>::value, bool>::type operator<( + const String& l, R&& r) +{ + return l.view() < AsStringView<R>::view(std::forward<R>(r)); } -template <typename L, typename R> -typename std::enable_if<AsStringView<L>::value && AsStringView<R>::value, - bool>::type -operator<=(L&& l, R&& r) +inline bool operator<=(const String& l, const String& r) +{ + return l.view() <= r.view(); +} +template <typename L> +typename std::enable_if<IsComparable<L>::value, bool>::type operator<=( + L&& l, const String& r) +{ + return AsStringView<L>::view(std::forward<L>(l)) <= r.view(); +} +template <typename R> +typename std::enable_if<IsComparable<R>::value, bool>::type operator<=( + const String& l, R&& r) { - return (AsStringView<L>::view(std::forward<L>(l)) <= - AsStringView<R>::view(std::forward<R>(r))); + return l.view() <= AsStringView<R>::view(std::forward<R>(r)); } -template <typename L, typename R> -typename std::enable_if<AsStringView<L>::value && AsStringView<R>::value, - bool>::type -operator>(L&& l, R&& r) +inline bool operator>(const String& l, const String& r) +{ + return l.view() > r.view(); +} +template <typename L> +typename std::enable_if<IsComparable<L>::value, bool>::type operator>( + L&& l, const String& r) +{ + return AsStringView<L>::view(std::forward<L>(l)) > r.view(); +} +template <typename R> +typename std::enable_if<IsComparable<R>::value, bool>::type operator>( + const String& l, R&& r) { - return (AsStringView<L>::view(std::forward<L>(l)) > - AsStringView<R>::view(std::forward<R>(r))); + return l.view() > AsStringView<R>::view(std::forward<R>(r)); } -template <typename L, typename R> -typename std::enable_if<AsStringView<L>::value && AsStringView<R>::value, - bool>::type -operator>=(L&& l, R&& r) +inline bool operator>=(const String& l, const String& r) +{ + return l.view() >= r.view(); +} +template <typename L> +typename std::enable_if<IsComparable<L>::value, bool>::type operator>=( + L&& l, const String& r) +{ + return AsStringView<L>::view(std::forward<L>(l)) >= r.view(); +} +template <typename R> +typename std::enable_if<IsComparable<R>::value, bool>::type operator>=( + const String& l, R&& r) { - return (AsStringView<L>::view(std::forward<L>(l)) >= - AsStringView<R>::view(std::forward<R>(r))); + return l.view() >= AsStringView<R>::view(std::forward<R>(r)); } std::ostream& operator<<(std::ostream& os, String const& s); diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index d46bf56..b69d4e8 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -358,6 +358,7 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type, initProp("CUDA_COMPILER_LAUNCHER"); initProp("CUDA_SEPARABLE_COMPILATION"); initProp("CUDA_RESOLVE_DEVICE_SYMBOLS"); + initProp("CUDA_RUNTIME_LIBRARY"); initProp("LINK_SEARCH_START_STATIC"); initProp("LINK_SEARCH_END_STATIC"); initProp("Swift_LANGUAGE_VERSION"); @@ -1297,8 +1298,8 @@ void cmTarget::SetProperty(const std::string& prop, const char* value) } } -void cmTarget::AppendProperty(const std::string& prop, const char* value, - bool asString) +void cmTarget::AppendProperty(const std::string& prop, + const std::string& value, bool asString) { if (!cmTargetPropertyComputer::PassesWhitelist( this->GetType(), prop, impl->Makefile->GetMessenger(), @@ -1333,37 +1334,37 @@ void cmTarget::AppendProperty(const std::string& prop, const char* value, return; } if (prop == "INCLUDE_DIRECTORIES") { - if (value && *value) { + if (!value.empty()) { impl->IncludeDirectoriesEntries.emplace_back(value); cmListFileBacktrace lfbt = impl->Makefile->GetBacktrace(); impl->IncludeDirectoriesBacktraces.push_back(lfbt); } } else if (prop == "COMPILE_OPTIONS") { - if (value && *value) { + if (!value.empty()) { impl->CompileOptionsEntries.emplace_back(value); cmListFileBacktrace lfbt = impl->Makefile->GetBacktrace(); impl->CompileOptionsBacktraces.push_back(lfbt); } } else if (prop == "COMPILE_FEATURES") { - if (value && *value) { + if (!value.empty()) { impl->CompileFeaturesEntries.emplace_back(value); cmListFileBacktrace lfbt = impl->Makefile->GetBacktrace(); impl->CompileFeaturesBacktraces.push_back(lfbt); } } else if (prop == "COMPILE_DEFINITIONS") { - if (value && *value) { + if (!value.empty()) { impl->CompileDefinitionsEntries.emplace_back(value); cmListFileBacktrace lfbt = impl->Makefile->GetBacktrace(); impl->CompileDefinitionsBacktraces.push_back(lfbt); } } else if (prop == "LINK_OPTIONS") { - if (value && *value) { + if (!value.empty()) { impl->LinkOptionsEntries.emplace_back(value); cmListFileBacktrace lfbt = impl->Makefile->GetBacktrace(); impl->LinkOptionsBacktraces.push_back(lfbt); } } else if (prop == "LINK_DIRECTORIES") { - if (value && *value) { + if (!value.empty()) { impl->LinkDirectoriesEntries.emplace_back(value); cmListFileBacktrace lfbt = impl->Makefile->GetBacktrace(); impl->LinkDirectoriesBacktraces.push_back(lfbt); @@ -1377,13 +1378,13 @@ void cmTarget::AppendProperty(const std::string& prop, const char* value, impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str()); return; } - if (value && *value) { + if (!value.empty()) { impl->PrecompileHeadersEntries.emplace_back(value); cmListFileBacktrace lfbt = impl->Makefile->GetBacktrace(); impl->PrecompileHeadersBacktraces.push_back(lfbt); } } else if (prop == "LINK_LIBRARIES") { - if (value && *value) { + if (!value.empty()) { cmListFileBacktrace lfbt = impl->Makefile->GetBacktrace(); impl->LinkImplementationPropertyEntries.emplace_back(value); impl->LinkImplementationPropertyBacktraces.push_back(lfbt); diff --git a/Source/cmTarget.h b/Source/cmTarget.h index ca37f0d..d4cca23 100644 --- a/Source/cmTarget.h +++ b/Source/cmTarget.h @@ -166,13 +166,8 @@ public: { SetProperty(prop, value.c_str()); } - void AppendProperty(const std::string& prop, const char* value, - bool asString = false); void AppendProperty(const std::string& prop, const std::string& value, - bool asString = false) - { - AppendProperty(prop, value.c_str(), asString); - } + bool asString = false); //! Might return a nullptr if the property is not set or invalid const char* GetProperty(const std::string& prop) const; //! Always returns a valid pointer diff --git a/Source/cmTest.cxx b/Source/cmTest.cxx index d5c61c1..3b731cc 100644 --- a/Source/cmTest.cxx +++ b/Source/cmTest.cxx @@ -55,7 +55,7 @@ void cmTest::SetProperty(const std::string& prop, const char* value) this->Properties.SetProperty(prop, value); } -void cmTest::AppendProperty(const std::string& prop, const char* value, +void cmTest::AppendProperty(const std::string& prop, const std::string& value, bool asString) { this->Properties.AppendProperty(prop, value, asString); diff --git a/Source/cmTest.h b/Source/cmTest.h index dd246c4..72d4ed9 100644 --- a/Source/cmTest.h +++ b/Source/cmTest.h @@ -35,7 +35,7 @@ public: //! Set/Get a property of this source file void SetProperty(const std::string& prop, const char* value); - void AppendProperty(const std::string& prop, const char* value, + void AppendProperty(const std::string& prop, const std::string& value, bool asString = false); const char* GetProperty(const std::string& prop) const; bool GetPropertyAsBool(const std::string& prop) const; diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index 6761c64..5ef5597 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -3650,18 +3650,7 @@ bool cmVisualStudio10TargetGenerator::ComputeLinkOptions( this->AddLibraries(cli, libVec, vsTargetVec, config); if (cmContains(linkClosure->Languages, "CUDA") && this->CudaOptions[config] != nullptr) { - switch (this->CudaOptions[config]->GetCudaRuntime()) { - case cmVisualStudioGeneratorOptions::CudaRuntimeStatic: - libVec.push_back("cudadevrt.lib"); - libVec.push_back("cudart_static.lib"); - break; - case cmVisualStudioGeneratorOptions::CudaRuntimeShared: - libVec.push_back("cudadevrt.lib"); - libVec.push_back("cudart.lib"); - break; - case cmVisualStudioGeneratorOptions::CudaRuntimeNone: - break; - } + this->CudaOptions[config]->FixCudaRuntime(this->GeneratorTarget); } std::string standardLibsVar = cmStrCat("CMAKE_", linkLanguage, "_STANDARD_LIBRARIES"); diff --git a/Source/cmVisualStudioGeneratorOptions.cxx b/Source/cmVisualStudioGeneratorOptions.cxx index 18c19b7..4004b66 100644 --- a/Source/cmVisualStudioGeneratorOptions.cxx +++ b/Source/cmVisualStudioGeneratorOptions.cxx @@ -3,6 +3,8 @@ #include <cm/iterator> #include "cmAlgorithms.h" +#include "cmGeneratorExpression.h" +#include "cmGeneratorTarget.h" #include "cmLocalVisualStudioGenerator.h" #include "cmOutputConverter.h" #include "cmSystemTools.h" @@ -149,25 +151,33 @@ bool cmVisualStudioGeneratorOptions::UsingSBCS() const return false; } -cmVisualStudioGeneratorOptions::CudaRuntime -cmVisualStudioGeneratorOptions::GetCudaRuntime() const +void cmVisualStudioGeneratorOptions::FixCudaRuntime(cmGeneratorTarget* target) { std::map<std::string, FlagValue>::const_iterator i = this->FlagMap.find("CudaRuntime"); - if (i != this->FlagMap.end() && i->second.size() == 1) { - std::string const& cudaRuntime = i->second[0]; - if (cudaRuntime == "Static") { - return CudaRuntimeStatic; - } - if (cudaRuntime == "Shared") { - return CudaRuntimeShared; - } - if (cudaRuntime == "None") { - return CudaRuntimeNone; + if (i == this->FlagMap.end()) { + // User didn't provide am override so get the property value + const char* runtimeLibraryValue = + target->GetProperty("CUDA_RUNTIME_LIBRARY"); + if (runtimeLibraryValue) { + std::string cudaRuntime = + cmSystemTools::UpperCase(cmGeneratorExpression::Evaluate( + runtimeLibraryValue, this->LocalGenerator, this->Configuration, + target)); + if (cudaRuntime == "STATIC") { + this->AddFlag("CudaRuntime", "Static"); + } + if (cudaRuntime == "SHARED") { + this->AddFlag("CudaRuntime", "Shared"); + } + if (cudaRuntime == "NONE") { + this->AddFlag("CudaRuntime", "None"); + } + } else { + // nvcc default is static + this->AddFlag("CudaRuntime", "Static"); } } - // nvcc default is static - return CudaRuntimeStatic; } void cmVisualStudioGeneratorOptions::FixCudaCodeGeneration() diff --git a/Source/cmVisualStudioGeneratorOptions.h b/Source/cmVisualStudioGeneratorOptions.h index d8dcfe2..b335694 100644 --- a/Source/cmVisualStudioGeneratorOptions.h +++ b/Source/cmVisualStudioGeneratorOptions.h @@ -13,6 +13,7 @@ #include "cmIDEOptions.h" class cmLocalVisualStudioGenerator; +class cmGeneratorTarget; using cmVS7FlagTable = cmIDEFlagTable; @@ -61,15 +62,8 @@ public: bool UsingUnicode() const; bool UsingSBCS() const; - enum CudaRuntime - { - CudaRuntimeStatic, - CudaRuntimeShared, - CudaRuntimeNone - }; - CudaRuntime GetCudaRuntime() const; - void FixCudaCodeGeneration(); + void FixCudaRuntime(cmGeneratorTarget* target); void FixManifestUACFlags(); diff --git a/Source/cmake.cxx b/Source/cmake.cxx index ab76df9..8214c52 100644 --- a/Source/cmake.cxx +++ b/Source/cmake.cxx @@ -663,6 +663,8 @@ void cmake::SetArgs(const std::vector<std::string>& args) } else if ((i < args.size() - 1) && (arg.find("--check-stamp-list", 0) == 0)) { this->CheckStampList = args[++i]; + } else if (arg == "--regenerate-during-build") { + this->RegenerateDuringBuild = true; } #if defined(CMAKE_HAVE_VS_GENERATORS) else if ((i < args.size() - 1) && @@ -2374,7 +2376,7 @@ void cmake::SetProperty(const std::string& prop, const char* value) this->State->SetGlobalProperty(prop, value); } -void cmake::AppendProperty(const std::string& prop, const char* value, +void cmake::AppendProperty(const std::string& prop, const std::string& value, bool asString) { this->State->AppendGlobalProperty(prop, value, asString); diff --git a/Source/cmake.h b/Source/cmake.h index 22d3c39..35425ec 100644 --- a/Source/cmake.h +++ b/Source/cmake.h @@ -359,7 +359,7 @@ public: //! Set/Get a property of this target file void SetProperty(const std::string& prop, const char* value); - void AppendProperty(const std::string& prop, const char* value, + void AppendProperty(const std::string& prop, const std::string& value, bool asString = false); const char* GetProperty(const std::string& prop); bool GetPropertyAsBool(const std::string& prop); @@ -547,6 +547,8 @@ public: } cmStateSnapshot GetCurrentSnapshot() const { return this->CurrentSnapshot; } + bool GetRegenerateDuringBuild() const { return this->RegenerateDuringBuild; } + protected: void RunCheckForUnusedVariables(); int HandleDeleteCacheVariables(const std::string& var); @@ -621,6 +623,7 @@ private: FileExtensions FortranFileExtensions; bool ClearBuildSystem = false; bool DebugTryCompile = false; + bool RegenerateDuringBuild = false; std::unique_ptr<cmFileTimeCache> FileTimeCache; std::string GraphVizFile; InstalledFilesMap InstalledFiles; diff --git a/Tests/CMakeLib/testString.cxx b/Tests/CMakeLib/testString.cxx index d7b3200..1fd3f38 100644 --- a/Tests/CMakeLib/testString.cxx +++ b/Tests/CMakeLib/testString.cxx @@ -191,7 +191,7 @@ static bool testConstructFromView() { std::cout << "testConstructFromView()\n"; cm::string_view view = cstr; - return testFromCStr(view); + return testFromCStr(cm::String(view)); } static bool testAssignFromView() @@ -297,7 +297,7 @@ static bool testFromStaticStringView(cm::String str) static bool testConstructFromStaticStringView() { std::cout << "testConstructFromStaticStringView()\n"; - return testFromStaticStringView(staticStringView); + return testFromStaticStringView(cm::String(staticStringView)); } static bool testAssignFromStaticStringView() @@ -796,7 +796,7 @@ static bool testMethod_substr_AtEnd(cm::String str) static bool testMethod_substr_AtEndBorrowed() { std::cout << "testMethod_substr_AtEndBorrowed()\n"; - return testMethod_substr_AtEnd("abc"_s); + return testMethod_substr_AtEnd(cm::String("abc"_s)); } static bool testMethod_substr_AtEndOwned() @@ -855,7 +855,7 @@ static bool testMethod_substr_AtStart(cm::String str) static bool testMethod_substr_AtStartBorrowed() { std::cout << "testMethod_substr_AtStartBorrowed()\n"; - return testMethod_substr_AtStart("abc"_s); + return testMethod_substr_AtStart(cm::String("abc"_s)); } static bool testMethod_substr_AtStartOwned() @@ -1146,7 +1146,7 @@ static bool testAddition() static bool testStability() { std::cout << "testStability()\n"; - cm::String str = "abc"_s; + cm::String str("abc"_s); ASSERT_TRUE(!str.is_stable()); ASSERT_TRUE(str.str_if_stable() == nullptr); str.stabilize(); diff --git a/Tests/Cuda/Complex/CMakeLists.txt b/Tests/Cuda/Complex/CMakeLists.txt index d3d4b7c..08d1e16 100644 --- a/Tests/Cuda/Complex/CMakeLists.txt +++ b/Tests/Cuda/Complex/CMakeLists.txt @@ -22,18 +22,11 @@ set(CMAKE_CUDA_STANDARD_REQUIRED TRUE) set(CMAKE_CXX_STANDARD_REQUIRED TRUE) add_library(CudaComplexCppBase SHARED dynamic.cpp) -add_library(CudaComplexSeperableLib STATIC file1.cu file2.cu file3.cu) -set_target_properties(CudaComplexSeperableLib - PROPERTIES CUDA_SEPARABLE_COMPILATION ON) -set_target_properties( CudaComplexSeperableLib - PROPERTIES POSITION_INDEPENDENT_CODE ON) - add_library(CudaComplexSharedLib SHARED dynamic.cu) target_link_libraries(CudaComplexSharedLib PUBLIC CudaComplexCppBase) +add_library(CudaComplexSeperableLib STATIC file1.cu file2.cu file3.cu) add_library(CudaComplexMixedLib SHARED mixed.cpp mixed.cu) -set_target_properties(CudaComplexMixedLib - PROPERTIES CUDA_SEPARABLE_COMPILATION ON) target_link_libraries(CudaComplexMixedLib PUBLIC CudaComplexSharedLib PRIVATE CudaComplexSeperableLib) @@ -41,7 +34,27 @@ target_link_libraries(CudaComplexMixedLib add_executable(CudaComplex main.cpp) target_link_libraries(CudaComplex PUBLIC CudaComplexMixedLib) + +set_target_properties(CudaComplexMixedLib + CudaComplexSeperableLib + PROPERTIES + POSITION_INDEPENDENT_CODE ON + CUDA_SEPARABLE_COMPILATION ON + ) +set_target_properties(CudaComplexMixedLib + CudaComplexSharedLib + PROPERTIES + CUDA_RUNTIME_LIBRARY shared + ) + + if(APPLE) # Help the static cuda runtime find the driver (libcuda.dyllib) at runtime. set_property(TARGET CudaComplex PROPERTY BUILD_RPATH ${CMAKE_CUDA_IMPLICIT_LINK_DIRECTORIES}) endif() + +if(UNIX) + # Help the shared cuda runtime find libcudart as it is not located + # in a default system searched location + set_property(TARGET CudaComplexMixedLib PROPERTY BUILD_RPATH ${CMAKE_CUDA_IMPLICIT_LINK_DIRECTORIES}) +endif() diff --git a/Tests/Cuda/Complex/dynamic.cu b/Tests/Cuda/Complex/dynamic.cu index 9da8853..7f2f2b5 100644 --- a/Tests/Cuda/Complex/dynamic.cu +++ b/Tests/Cuda/Complex/dynamic.cu @@ -54,17 +54,20 @@ EXPORT int choose_cuda_device() return 1; } -EXPORT void cuda_dynamic_lib_func() +EXPORT bool cuda_dynamic_lib_func() { - DetermineIfValidCudaDevice<<<1, 1>>>(); cudaError_t err = cudaGetLastError(); if (err != cudaSuccess) { - std::cerr << "DetermineIfValidCudaDevice [SYNC] failed: " + std::cerr << "DetermineIfValidCudaDevice [Per Launch] failed: " << cudaGetErrorString(err) << std::endl; + return false; } + DetermineIfValidCudaDevice<<<1, 1>>>(); err = cudaDeviceSynchronize(); if (err != cudaSuccess) { - std::cerr << "DetermineIfValidCudaDevice [ASYNC] failed: " + std::cerr << "DetermineIfValidCudaDevice [SYNC] failed: " << cudaGetErrorString(cudaGetLastError()) << std::endl; + return false; } + return true; } diff --git a/Tests/Cuda/Complex/main.cpp b/Tests/Cuda/Complex/main.cpp index 6ca5952..da09b44 100644 --- a/Tests/Cuda/Complex/main.cpp +++ b/Tests/Cuda/Complex/main.cpp @@ -22,5 +22,6 @@ int main(int argc, char** argv) int r1 = call_cuda_seperable_code(42); int r2 = mixed_launch_kernel(42); + return (r1 == 42 || r2 == 42) ? 1 : 0; } diff --git a/Tests/Cuda/Complex/mixed.cu b/Tests/Cuda/Complex/mixed.cu index 5b85aec..76119ad 100644 --- a/Tests/Cuda/Complex/mixed.cu +++ b/Tests/Cuda/Complex/mixed.cu @@ -15,7 +15,7 @@ result_type __device__ file1_func(int x); result_type_dynamic __device__ file2_func(int x); -IMPORT void __host__ cuda_dynamic_lib_func(); +IMPORT bool __host__ cuda_dynamic_lib_func(); static __global__ void mixed_kernel(result_type* r, int x) { @@ -25,7 +25,9 @@ static __global__ void mixed_kernel(result_type* r, int x) EXPORT int mixed_launch_kernel(int x) { - cuda_dynamic_lib_func(); + if (!cuda_dynamic_lib_func()) { + return x; + } result_type* r; cudaError_t err = cudaMallocManaged(&r, sizeof(result_type)); diff --git a/Tests/CudaOnly/CMakeLists.txt b/Tests/CudaOnly/CMakeLists.txt index a0575cd..cc1ee1a 100644 --- a/Tests/CudaOnly/CMakeLists.txt +++ b/Tests/CudaOnly/CMakeLists.txt @@ -5,10 +5,21 @@ ADD_TEST_MACRO(CudaOnly.ExportPTX CudaOnlyExportPTX) ADD_TEST_MACRO(CudaOnly.GPUDebugFlag CudaOnlyGPUDebugFlag) ADD_TEST_MACRO(CudaOnly.ResolveDeviceSymbols CudaOnlyResolveDeviceSymbols) ADD_TEST_MACRO(CudaOnly.SeparateCompilation CudaOnlySeparateCompilation) +ADD_TEST_MACRO(CudaOnly.SharedRuntimePlusToolkit CudaOnlySharedRuntimePlusToolkit) ADD_TEST_MACRO(CudaOnly.Standard98 CudaOnlyStandard98) ADD_TEST_MACRO(CudaOnly.Toolkit CudaOnlyToolkit) ADD_TEST_MACRO(CudaOnly.WithDefs CudaOnlyWithDefs) +# The CUDA only ships the shared version of the toolkit libraries +# on windows +if(NOT WIN32) + ADD_TEST_MACRO(Cuda.StaticRuntimePlusToolkit StaticRuntimePlusToolkit) +endif() + +if(MSVC) + ADD_TEST_MACRO(CudaOnly.PDB CudaOnlyPDB) +endif() + add_test(NAME CudaOnly.DontResolveDeviceSymbols COMMAND ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION> --build-and-test @@ -20,6 +31,14 @@ add_test(NAME CudaOnly.DontResolveDeviceSymbols COMMAND --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION> ) -if(MSVC) - ADD_TEST_MACRO(CudaOnly.PDB CudaOnlyPDB) -endif() +add_test(NAME CudaOnly.RuntimeControls COMMAND + ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION> + --build-and-test + "${CMAKE_CURRENT_SOURCE_DIR}/RuntimeControls/" + "${CMAKE_CURRENT_BINARY_DIR}/RuntimeControls/" + --build-two-config + ${build_generator_args} + --build-project RuntimeControls + --build-options ${build_options} + --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION> + ) diff --git a/Tests/CudaOnly/RuntimeControls/CMakeLists.txt b/Tests/CudaOnly/RuntimeControls/CMakeLists.txt new file mode 100644 index 0000000..8b58fec --- /dev/null +++ b/Tests/CudaOnly/RuntimeControls/CMakeLists.txt @@ -0,0 +1,60 @@ +cmake_minimum_required(VERSION 3.7) +project (RuntimeControls 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() + +string(APPEND CMAKE_CUDA_FLAGS " -gencode arch=compute_30,code=[compute_30]") + +set(CMAKE_CUDA_STANDARD 11) +set(CMAKE_CUDA_RUNTIME_LIBRARY static) + +if(NOT "x${CMAKE_CUDA_SIMULATE_ID}" STREQUAL "xMSVC") + add_library(UsesNoCudaRT SHARED file1.cu) + set_target_properties(UsesNoCudaRT PROPERTIES CUDA_RUNTIME_LIBRARY none) +endif() + +add_library(UsesStaticCudaRT SHARED file2.cu) + +add_executable(CudaOnlyRuntimeControls main.cu) +set_target_properties(CudaOnlyRuntimeControls PROPERTIES CUDA_RUNTIME_LIBRARY shared) + +target_link_libraries(CudaOnlyRuntimeControls PRIVATE $<TARGET_NAME_IF_EXISTS:UsesNoCudaRT> UsesStaticCudaRT) + + +if(dump_command) + if(TARGET UsesNoCudaRT) + add_custom_command(TARGET UsesNoCudaRT POST_BUILD + COMMAND ${CMAKE_COMMAND} + -DDUMP_COMMAND=${dump_command} + -DDUMP_ARGS=${dump_args} + -DTEST_LIBRARY_PATH=$<TARGET_FILE:UsesNoCudaRT> + -P ${CMAKE_CURRENT_SOURCE_DIR}/no_runtime.cmake + ) + endif() + add_custom_command(TARGET UsesStaticCudaRT POST_BUILD + COMMAND ${CMAKE_COMMAND} + -DDUMP_COMMAND=${dump_command} + -DDUMP_ARGS=${dump_args} + -DTEST_LIBRARY_PATH=$<TARGET_FILE:UsesStaticCudaRT> + -P ${CMAKE_CURRENT_SOURCE_DIR}/uses_static_runtime.cmake + ) + string(REPLACE ";" "|" dirs "${CMAKE_CUDA_IMPLICIT_LINK_DIRECTORIES}") + add_custom_command(TARGET CudaOnlyRuntimeControls POST_BUILD + COMMAND ${CMAKE_COMMAND} + -DEXEC_PATH=$<TARGET_FILE:CudaOnlyRuntimeControls> + -DEXTRA_LIB_DIRS="${dirs}" + -P ${CMAKE_CURRENT_SOURCE_DIR}/verify_runtime.cmake + ) +endif() diff --git a/Tests/CudaOnly/RuntimeControls/file1.cu b/Tests/CudaOnly/RuntimeControls/file1.cu new file mode 100644 index 0000000..28beb5e --- /dev/null +++ b/Tests/CudaOnly/RuntimeControls/file1.cu @@ -0,0 +1,18 @@ + +#ifdef _WIN32 +# define EXPORT __declspec(dllexport) +#else +# define EXPORT +#endif + +void __global__ file1_kernel(int x, int& r) +{ + r = -x; +} + +EXPORT int file1_launch_kernel(int x) +{ + int r = 0; + file1_kernel<<<1, 1>>>(x, r); + return r; +} diff --git a/Tests/CudaOnly/RuntimeControls/file2.cu b/Tests/CudaOnly/RuntimeControls/file2.cu new file mode 100644 index 0000000..ff68a70 --- /dev/null +++ b/Tests/CudaOnly/RuntimeControls/file2.cu @@ -0,0 +1,18 @@ + +#ifdef _WIN32 +# define EXPORT __declspec(dllexport) +#else +# define EXPORT +#endif + +void __global__ file2_kernel(int x, int& r) +{ + r = -x; +} + +EXPORT int file2_launch_kernel(int x) +{ + int r = 0; + file2_kernel<<<1, 1>>>(x, r); + return r; +} diff --git a/Tests/CudaOnly/RuntimeControls/main.cu b/Tests/CudaOnly/RuntimeControls/main.cu new file mode 100644 index 0000000..0be22af --- /dev/null +++ b/Tests/CudaOnly/RuntimeControls/main.cu @@ -0,0 +1,81 @@ + +#include <iostream> + +#include "cuda.h" + +#ifdef _WIN32 +# define IMPORT __declspec(dllimport) +#else +# define IMPORT +#endif + +#ifndef _WIN32 +IMPORT int file1_launch_kernel(int x); +#endif + +IMPORT int file2_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; + } + 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; +#ifndef _WIN32 + file1_launch_kernel(1); + err = cudaGetLastError(); + if (err != cudaSuccess) { + std::cerr << "file1_launch_kernel: kernel launch should have passed.\n " + "Error message: " + << cudaGetErrorString(err) << std::endl; + return 1; + } +#endif + + file2_launch_kernel(1); + err = cudaGetLastError(); + if (err != cudaSuccess) { + std::cerr << "file2_launch_kernel: kernel launch should have passed.\n " + "Error message: " + << cudaGetErrorString(err) << std::endl; + return 1; + } + + return 0; +} diff --git a/Tests/CudaOnly/RuntimeControls/no_runtime.cmake b/Tests/CudaOnly/RuntimeControls/no_runtime.cmake new file mode 100644 index 0000000..55f28cc --- /dev/null +++ b/Tests/CudaOnly/RuntimeControls/no_runtime.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 "(__cuda)") + message(FATAL_ERROR + "not missing cuda device symbols, static runtime linking was used.") +endif() diff --git a/Tests/CudaOnly/RuntimeControls/uses_static_runtime.cmake b/Tests/CudaOnly/RuntimeControls/uses_static_runtime.cmake new file mode 100644 index 0000000..b372fea --- /dev/null +++ b/Tests/CudaOnly/RuntimeControls/uses_static_runtime.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("${OUTPUT}" MATCHES "__cuda") + message(FATAL_ERROR + "missing cuda device symbols, static runtime linking was not used.") +endif() diff --git a/Tests/CudaOnly/RuntimeControls/verify_runtime.cmake b/Tests/CudaOnly/RuntimeControls/verify_runtime.cmake new file mode 100644 index 0000000..b313dac --- /dev/null +++ b/Tests/CudaOnly/RuntimeControls/verify_runtime.cmake @@ -0,0 +1,16 @@ + +string(REPLACE "|" ";" dirs "${EXTRA_LIB_DIRS}") +file(GET_RUNTIME_DEPENDENCIES + RESOLVED_DEPENDENCIES_VAR resolved_libs + UNRESOLVED_DEPENDENCIES_VAR unresolved_libs + DIRECTORIES ${dirs} + EXECUTABLES ${EXEC_PATH} + ) + +list(FILTER resolved_libs INCLUDE REGEX ".*cudart.*") +list(LENGTH resolved_libs has_cudart) + +if(has_cudart EQUAL 0) + message(FATAL_ERROR + "missing cudart shared library from runtime dependency output.") +endif() diff --git a/Tests/CudaOnly/SharedRuntimePlusToolkit/CMakeLists.txt b/Tests/CudaOnly/SharedRuntimePlusToolkit/CMakeLists.txt new file mode 100644 index 0000000..03fba22 --- /dev/null +++ b/Tests/CudaOnly/SharedRuntimePlusToolkit/CMakeLists.txt @@ -0,0 +1,42 @@ +cmake_minimum_required(VERSION 3.15) +project(SharedRuntimePlusToolkit CUDA) + +#Goal for this example: +# Validate that with c++ we can use some components of the CUDA toolkit, and +# specify the cuda runtime +find_package(CUDAToolkit REQUIRED) + +add_library(Common OBJECT curand.cu nppif.cu) +target_link_libraries(Common PRIVATE CUDA::toolkit) +set_target_properties(Common PROPERTIES POSITION_INDEPENDENT_CODE ON) + +#shared runtime with shared toolkit libraries +add_library(SharedToolkit SHARED shared.cu) +target_link_libraries(SharedToolkit PRIVATE Common PUBLIC CUDA::curand CUDA::nppif) +set_target_properties(SharedToolkit PROPERTIES CUDA_RUNTIME_LIBRARY none) +target_link_libraries(SharedToolkit PUBLIC CUDA::cudart) + +# The CUDA only ships the shared version of the toolkit libraries +# on windows +if(NOT WIN32) + #shared runtime with static toolkit libraries + add_library(StaticToolkit SHARED static.cu) + target_link_libraries(StaticToolkit PRIVATE Common CUDA::curand_static CUDA::nppif_static) + set_target_properties(StaticToolkit PROPERTIES CUDA_RUNTIME_LIBRARY Shared) + + #static runtime with mixed toolkit libraries + add_library(MixedToolkit SHARED mixed.cu) + target_link_libraries(MixedToolkit PRIVATE Common CUDA::curand_static CUDA::nppif) + set_target_properties(MixedToolkit PROPERTIES CUDA_RUNTIME_LIBRARY Shared) +endif() + +add_executable(CudaOnlySharedRuntimePlusToolkit main.cu) +target_link_libraries(CudaOnlySharedRuntimePlusToolkit PRIVATE SharedToolkit + $<TARGET_NAME_IF_EXISTS:StaticToolkit> + $<TARGET_NAME_IF_EXISTS:MixedToolkit>) + +if(UNIX) + # Help the shared cuda runtime find libcudart as it is not located + # in a default system searched location + set_property(TARGET CudaOnlySharedRuntimePlusToolkit PROPERTY BUILD_RPATH ${CMAKE_CUDA_IMPLICIT_LINK_DIRECTORIES}) +endif() diff --git a/Tests/CudaOnly/SharedRuntimePlusToolkit/curand.cu b/Tests/CudaOnly/SharedRuntimePlusToolkit/curand.cu new file mode 100644 index 0000000..fdd7b53 --- /dev/null +++ b/Tests/CudaOnly/SharedRuntimePlusToolkit/curand.cu @@ -0,0 +1,65 @@ +// Comes from: +// https://docs.nvidia.com/cuda/curand/host-api-overview.html#host-api-example + +#ifdef _WIN32 +# define EXPORT __declspec(dllexport) +#else +# define EXPORT +#endif + +/* + * This program uses the host CURAND API to generate 100 + * pseudorandom floats. + */ +#include <cuda.h> +#include <curand.h> +#include <stdio.h> +#include <stdlib.h> + +#define CUDA_CALL(x) \ + do { \ + if ((x) != cudaSuccess) { \ + printf("Error at %s:%d\n", __FILE__, __LINE__); \ + return EXIT_FAILURE; \ + } \ + } while (0) +#define CURAND_CALL(x) \ + do { \ + if ((x) != CURAND_STATUS_SUCCESS) { \ + printf("Error at %s:%d\n", __FILE__, __LINE__); \ + return EXIT_FAILURE; \ + } \ + } while (0) + +EXPORT int curand_main() +{ + size_t n = 100; + size_t i; + curandGenerator_t gen; + float *devData, *hostData; + + /* Allocate n floats on host */ + hostData = (float*)calloc(n, sizeof(float)); + + /* Allocate n floats on device */ + CUDA_CALL(cudaMalloc((void**)&devData, n * sizeof(float))); + + /* Create pseudo-random number generator */ + CURAND_CALL(curandCreateGenerator(&gen, CURAND_RNG_PSEUDO_DEFAULT)); + + /* Set seed */ + CURAND_CALL(curandSetPseudoRandomGeneratorSeed(gen, 1234ULL)); + + /* Generate n floats on device */ + CURAND_CALL(curandGenerateUniform(gen, devData, n)); + + /* Copy device memory to host */ + CUDA_CALL( + cudaMemcpy(hostData, devData, n * sizeof(float), cudaMemcpyDeviceToHost)); + + /* Cleanup */ + CURAND_CALL(curandDestroyGenerator(gen)); + CUDA_CALL(cudaFree(devData)); + free(hostData); + return EXIT_SUCCESS; +} diff --git a/Tests/CudaOnly/SharedRuntimePlusToolkit/main.cu b/Tests/CudaOnly/SharedRuntimePlusToolkit/main.cu new file mode 100644 index 0000000..2a4da22 --- /dev/null +++ b/Tests/CudaOnly/SharedRuntimePlusToolkit/main.cu @@ -0,0 +1,23 @@ + +#ifdef _WIN32 +# define IMPORT __declspec(dllimport) +IMPORT int shared_version(); +int static_version() +{ + return 0; +} +int mixed_version() +{ + return 0; +} +#else +int shared_version(); +int static_version(); +int mixed_version(); +#endif + +int main() +{ + return mixed_version() == 0 && shared_version() == 0 && + static_version() == 0; +} diff --git a/Tests/CudaOnly/SharedRuntimePlusToolkit/mixed.cu b/Tests/CudaOnly/SharedRuntimePlusToolkit/mixed.cu new file mode 100644 index 0000000..6de6886 --- /dev/null +++ b/Tests/CudaOnly/SharedRuntimePlusToolkit/mixed.cu @@ -0,0 +1,16 @@ + +#ifdef _WIN32 +# define IMPORT __declspec(dllimport) +# define EXPORT __declspec(dllexport) +#else +# define IMPORT +# define EXPORT +#endif + +IMPORT int curand_main(); +IMPORT int nppif_main(); + +EXPORT int mixed_version() +{ + return curand_main() == 0 && nppif_main() == 0; +} diff --git a/Tests/CudaOnly/SharedRuntimePlusToolkit/nppif.cu b/Tests/CudaOnly/SharedRuntimePlusToolkit/nppif.cu new file mode 100644 index 0000000..ac5341c --- /dev/null +++ b/Tests/CudaOnly/SharedRuntimePlusToolkit/nppif.cu @@ -0,0 +1,92 @@ +// Comes from +// https://devtalk.nvidia.com/default/topic/1037482/gpu-accelerated-libraries/help-me-help-you-with-modern-cmake-and-cuda-mwe-for-npp/post/5271066/#5271066 + +#ifdef _WIN32 +# define EXPORT __declspec(dllexport) +#else +# define EXPORT +#endif + +#include <cstdio> +#include <iostream> + +#include <assert.h> +#include <cuda_runtime_api.h> +#include <nppi_filtering_functions.h> + +EXPORT int nppif_main() +{ + /** + * 8-bit unsigned single-channel 1D row convolution. + */ + const int simgrows = 32; + const int simgcols = 32; + Npp8u *d_pSrc, *d_pDst; + const int nMaskSize = 3; + NppiSize oROI; + oROI.width = simgcols - nMaskSize; + oROI.height = simgrows; + const int simgsize = simgrows * simgcols * sizeof(d_pSrc[0]); + const int dimgsize = oROI.width * oROI.height * sizeof(d_pSrc[0]); + const int simgpix = simgrows * simgcols; + const int dimgpix = oROI.width * oROI.height; + const int nSrcStep = simgcols * sizeof(d_pSrc[0]); + const int nDstStep = oROI.width * sizeof(d_pDst[0]); + const int pixval = 1; + const int nDivisor = 1; + const Npp32s h_pKernel[nMaskSize] = { pixval, pixval, pixval }; + Npp32s* d_pKernel; + const Npp32s nAnchor = 2; + cudaError_t err = cudaMalloc((void**)&d_pSrc, simgsize); + if (err != cudaSuccess) { + fprintf(stderr, "Cuda error %d\n", __LINE__); + return 1; + } + err = cudaMalloc((void**)&d_pDst, dimgsize); + if (err != cudaSuccess) { + fprintf(stderr, "Cuda error %d\n", __LINE__); + return 1; + } + err = cudaMalloc((void**)&d_pKernel, nMaskSize * sizeof(d_pKernel[0])); + if (err != cudaSuccess) { + fprintf(stderr, "Cuda error %d\n", __LINE__); + return 1; + } + // set image to pixval initially + err = cudaMemset(d_pSrc, pixval, simgsize); + if (err != cudaSuccess) { + fprintf(stderr, "Cuda error %d\n", __LINE__); + return 1; + } + err = cudaMemset(d_pDst, 0, dimgsize); + if (err != cudaSuccess) { + fprintf(stderr, "Cuda error %d\n", __LINE__); + return 1; + } + err = cudaMemcpy(d_pKernel, h_pKernel, nMaskSize * sizeof(d_pKernel[0]), + cudaMemcpyHostToDevice); + if (err != cudaSuccess) { + fprintf(stderr, "Cuda error %d\n", __LINE__); + return 1; + } + // copy src to dst + NppStatus ret = + nppiFilterRow_8u_C1R(d_pSrc, nSrcStep, d_pDst, nDstStep, oROI, d_pKernel, + nMaskSize, nAnchor, nDivisor); + assert(ret == NPP_NO_ERROR); + Npp8u* h_imgres = new Npp8u[dimgpix]; + err = cudaMemcpy(h_imgres, d_pDst, dimgsize, cudaMemcpyDeviceToHost); + if (err != cudaSuccess) { + fprintf(stderr, "Cuda error %d\n", __LINE__); + return 1; + } + // test for filtering + for (int i = 0; i < dimgpix; i++) { + if (h_imgres[i] != (pixval * pixval * nMaskSize)) { + fprintf(stderr, "h_imgres at index %d failed to match\n", i); + return 1; + } + } + + return 0; +} diff --git a/Tests/CudaOnly/SharedRuntimePlusToolkit/shared.cu b/Tests/CudaOnly/SharedRuntimePlusToolkit/shared.cu new file mode 100644 index 0000000..f3c3dbc --- /dev/null +++ b/Tests/CudaOnly/SharedRuntimePlusToolkit/shared.cu @@ -0,0 +1,16 @@ + +#ifdef _WIN32 +# define IMPORT __declspec(dllimport) +# define EXPORT __declspec(dllexport) +#else +# define IMPORT +# define EXPORT +#endif + +int curand_main(); +int nppif_main(); + +EXPORT int shared_version() +{ + return curand_main() == 0 && nppif_main() == 0; +} diff --git a/Tests/CudaOnly/SharedRuntimePlusToolkit/static.cu b/Tests/CudaOnly/SharedRuntimePlusToolkit/static.cu new file mode 100644 index 0000000..6932fa3 --- /dev/null +++ b/Tests/CudaOnly/SharedRuntimePlusToolkit/static.cu @@ -0,0 +1,16 @@ + +#ifdef _WIN32 +# define IMPORT __declspec(dllimport) +# define EXPORT __declspec(dllexport) +#else +# define IMPORT +# define EXPORT +#endif + +IMPORT int curand_main(); +IMPORT int nppif_main(); + +EXPORT int static_version() +{ + return curand_main() == 0 && nppif_main() == 0; +} diff --git a/Tests/CudaOnly/StaticRuntimePlusToolkit/CMakeLists.txt b/Tests/CudaOnly/StaticRuntimePlusToolkit/CMakeLists.txt new file mode 100644 index 0000000..97ac229 --- /dev/null +++ b/Tests/CudaOnly/StaticRuntimePlusToolkit/CMakeLists.txt @@ -0,0 +1,29 @@ +cmake_minimum_required(VERSION 3.15) +project(StaticRuntimePlusToolkit CUDA) + +#Goal for this example: +# Validate that with cuda we can use some components of the CUDA toolkit, and +# specify the cuda runtime +find_package(CUDAToolkit REQUIRED) + +add_library(Common OBJECT curand.cu nppif.cu) +target_link_libraries(Common PRIVATE CUDA::toolkit) +set_target_properties(Common PROPERTIES POSITION_INDEPENDENT_CODE ON) + +#static runtime with shared toolkit libraries +add_library(SharedToolkit SHARED shared.cu) +target_link_libraries(SharedToolkit PRIVATE Common CUDA::curand CUDA::nppif ) +set_target_properties(SharedToolkit PROPERTIES CUDA_RUNTIME_LIBRARY none) +target_link_libraries(SharedToolkit PUBLIC CUDA::cudart_static) + +#static runtime with static toolkit libraries +add_library(StaticToolkit SHARED static.cu) +target_link_libraries(StaticToolkit PRIVATE Common CUDA::curand_static CUDA::nppif_static) + +#static runtime with mixed toolkit libraries +add_library(MixedToolkit SHARED mixed.cu) +target_link_libraries(MixedToolkit PRIVATE Common CUDA::curand CUDA::nppif_static) +set_target_properties(MixedToolkit PROPERTIES CUDA_RUNTIME_LIBRARY Static) + +add_executable(CudaOnlyStaticRuntimePlusToolkit main.cu) +target_link_libraries(CudaOnlyStaticRuntimePlusToolkit PRIVATE SharedToolkit StaticToolkit MixedToolkit) diff --git a/Tests/CudaOnly/StaticRuntimePlusToolkit/curand.cu b/Tests/CudaOnly/StaticRuntimePlusToolkit/curand.cu new file mode 100644 index 0000000..95872f0 --- /dev/null +++ b/Tests/CudaOnly/StaticRuntimePlusToolkit/curand.cu @@ -0,0 +1,59 @@ +// Comes from: +// https://docs.nvidia.com/cuda/curand/host-api-overview.html#host-api-example + +/* + * This program uses the host CURAND API to generate 100 + * pseudorandom floats. + */ +#include <cuda.h> +#include <curand.h> +#include <stdio.h> +#include <stdlib.h> + +#define CUDA_CALL(x) \ + do { \ + if ((x) != cudaSuccess) { \ + printf("Error at %s:%d\n", __FILE__, __LINE__); \ + return EXIT_FAILURE; \ + } \ + } while (0) +#define CURAND_CALL(x) \ + do { \ + if ((x) != CURAND_STATUS_SUCCESS) { \ + printf("Error at %s:%d\n", __FILE__, __LINE__); \ + return EXIT_FAILURE; \ + } \ + } while (0) + +int curand_main() +{ + size_t n = 100; + size_t i; + curandGenerator_t gen; + float *devData, *hostData; + + /* Allocate n floats on host */ + hostData = (float*)calloc(n, sizeof(float)); + + /* Allocate n floats on device */ + CUDA_CALL(cudaMalloc((void**)&devData, n * sizeof(float))); + + /* Create pseudo-random number generator */ + CURAND_CALL(curandCreateGenerator(&gen, CURAND_RNG_PSEUDO_DEFAULT)); + + /* Set seed */ + CURAND_CALL(curandSetPseudoRandomGeneratorSeed(gen, 1234ULL)); + + /* Generate n floats on device */ + CURAND_CALL(curandGenerateUniform(gen, devData, n)); + + /* Copy device memory to host */ + CUDA_CALL( + cudaMemcpy(hostData, devData, n * sizeof(float), cudaMemcpyDeviceToHost)); + + /* Cleanup */ + CURAND_CALL(curandDestroyGenerator(gen)); + CUDA_CALL(cudaFree(devData)); + free(hostData); + return EXIT_SUCCESS; +} diff --git a/Tests/CudaOnly/StaticRuntimePlusToolkit/main.cu b/Tests/CudaOnly/StaticRuntimePlusToolkit/main.cu new file mode 100644 index 0000000..5a09f8e --- /dev/null +++ b/Tests/CudaOnly/StaticRuntimePlusToolkit/main.cu @@ -0,0 +1,11 @@ + + +int shared_version(); +int static_version(); +int mixed_version(); + +int main() +{ + return mixed_version() == 0 && shared_version() == 0 && + static_version() == 0; +} diff --git a/Tests/CudaOnly/StaticRuntimePlusToolkit/mixed.cu b/Tests/CudaOnly/StaticRuntimePlusToolkit/mixed.cu new file mode 100644 index 0000000..a05140d --- /dev/null +++ b/Tests/CudaOnly/StaticRuntimePlusToolkit/mixed.cu @@ -0,0 +1,8 @@ + +int curand_main(); +int nppif_main(); + +int mixed_version() +{ + return curand_main() == 0 && nppif_main() == 0; +} diff --git a/Tests/CudaOnly/StaticRuntimePlusToolkit/nppif.cu b/Tests/CudaOnly/StaticRuntimePlusToolkit/nppif.cu new file mode 100644 index 0000000..2871090 --- /dev/null +++ b/Tests/CudaOnly/StaticRuntimePlusToolkit/nppif.cu @@ -0,0 +1,86 @@ +// Comes from +// https://devtalk.nvidia.com/default/topic/1037482/gpu-accelerated-libraries/help-me-help-you-with-modern-cmake-and-cuda-mwe-for-npp/post/5271066/#5271066 + +#include <cstdio> +#include <iostream> + +#include <assert.h> +#include <cuda_runtime_api.h> +#include <nppi_filtering_functions.h> + +int nppif_main() +{ + /** + * 8-bit unsigned single-channel 1D row convolution. + */ + const int simgrows = 32; + const int simgcols = 32; + Npp8u *d_pSrc, *d_pDst; + const int nMaskSize = 3; + NppiSize oROI; + oROI.width = simgcols - nMaskSize; + oROI.height = simgrows; + const int simgsize = simgrows * simgcols * sizeof(d_pSrc[0]); + const int dimgsize = oROI.width * oROI.height * sizeof(d_pSrc[0]); + const int simgpix = simgrows * simgcols; + const int dimgpix = oROI.width * oROI.height; + const int nSrcStep = simgcols * sizeof(d_pSrc[0]); + const int nDstStep = oROI.width * sizeof(d_pDst[0]); + const int pixval = 1; + const int nDivisor = 1; + const Npp32s h_pKernel[nMaskSize] = { pixval, pixval, pixval }; + Npp32s* d_pKernel; + const Npp32s nAnchor = 2; + cudaError_t err = cudaMalloc((void**)&d_pSrc, simgsize); + if (err != cudaSuccess) { + fprintf(stderr, "Cuda error %d\n", __LINE__); + return 1; + } + err = cudaMalloc((void**)&d_pDst, dimgsize); + if (err != cudaSuccess) { + fprintf(stderr, "Cuda error %d\n", __LINE__); + return 1; + } + err = cudaMalloc((void**)&d_pKernel, nMaskSize * sizeof(d_pKernel[0])); + if (err != cudaSuccess) { + fprintf(stderr, "Cuda error %d\n", __LINE__); + return 1; + } + // set image to pixval initially + err = cudaMemset(d_pSrc, pixval, simgsize); + if (err != cudaSuccess) { + fprintf(stderr, "Cuda error %d\n", __LINE__); + return 1; + } + err = cudaMemset(d_pDst, 0, dimgsize); + if (err != cudaSuccess) { + fprintf(stderr, "Cuda error %d\n", __LINE__); + return 1; + } + err = cudaMemcpy(d_pKernel, h_pKernel, nMaskSize * sizeof(d_pKernel[0]), + cudaMemcpyHostToDevice); + if (err != cudaSuccess) { + fprintf(stderr, "Cuda error %d\n", __LINE__); + return 1; + } + // copy src to dst + NppStatus ret = + nppiFilterRow_8u_C1R(d_pSrc, nSrcStep, d_pDst, nDstStep, oROI, d_pKernel, + nMaskSize, nAnchor, nDivisor); + assert(ret == NPP_NO_ERROR); + Npp8u* h_imgres = new Npp8u[dimgpix]; + err = cudaMemcpy(h_imgres, d_pDst, dimgsize, cudaMemcpyDeviceToHost); + if (err != cudaSuccess) { + fprintf(stderr, "Cuda error %d\n", __LINE__); + return 1; + } + // test for filtering + for (int i = 0; i < dimgpix; i++) { + if (h_imgres[i] != (pixval * pixval * nMaskSize)) { + fprintf(stderr, "h_imgres at index %d failed to match\n", i); + return 1; + } + } + + return 0; +} diff --git a/Tests/CudaOnly/StaticRuntimePlusToolkit/shared.cu b/Tests/CudaOnly/StaticRuntimePlusToolkit/shared.cu new file mode 100644 index 0000000..9967b66 --- /dev/null +++ b/Tests/CudaOnly/StaticRuntimePlusToolkit/shared.cu @@ -0,0 +1,8 @@ + +int curand_main(); +int nppif_main(); + +int shared_version() +{ + return curand_main() == 0 && nppif_main() == 0; +} diff --git a/Tests/CudaOnly/StaticRuntimePlusToolkit/static.cu b/Tests/CudaOnly/StaticRuntimePlusToolkit/static.cu new file mode 100644 index 0000000..ca7eb4c --- /dev/null +++ b/Tests/CudaOnly/StaticRuntimePlusToolkit/static.cu @@ -0,0 +1,8 @@ + +int curand_main(); +int nppif_main(); + +int static_version() +{ + return curand_main() == 0 && nppif_main() == 0; +} diff --git a/Tests/RunCMake/CMP0037/RunCMakeTest.cmake b/Tests/RunCMake/CMP0037/RunCMakeTest.cmake index 98274f0..5952279 100644 --- a/Tests/RunCMake/CMP0037/RunCMakeTest.cmake +++ b/Tests/RunCMake/CMP0037/RunCMakeTest.cmake @@ -1,5 +1,24 @@ include(RunCMake) +if(RunCMake_GENERATOR MATCHES "^Ninja") + # Detect ninja version so we know what tests can be supported. + execute_process( + COMMAND "${RunCMake_MAKE_PROGRAM}" --version + OUTPUT_VARIABLE ninja_out + ERROR_VARIABLE ninja_out + RESULT_VARIABLE ninja_res + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + if(ninja_res EQUAL 0 AND "x${ninja_out}" MATCHES "^x[0-9]+\\.[0-9]+") + set(ninja_version "${ninja_out}") + message(STATUS "ninja version: ${ninja_version}") + else() + message(FATAL_ERROR "'ninja --version' reported:\n${ninja_out}") + endif() +else() + set(ninja_version "") +endif() + run_cmake(CMP0037-OLD-space) run_cmake(CMP0037-NEW-space) run_cmake(CMP0037-WARN-space) @@ -9,8 +28,10 @@ if(NOT (WIN32 AND "${RunCMake_GENERATOR}" MATCHES "Make")) run_cmake(CMP0037-WARN-colon) endif() -run_cmake(CMP0037-WARN-reserved) -run_cmake(CMP0037-OLD-reserved) +if(NOT ninja_version VERSION_GREATER_EQUAL 1.10) + run_cmake(CMP0037-WARN-reserved) + run_cmake(CMP0037-OLD-reserved) +endif() run_cmake(CMP0037-NEW-reserved) run_cmake(NEW-cond) diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt index cd6e9ae..ad70a34 100644 --- a/Tests/RunCMake/CMakeLists.txt +++ b/Tests/RunCMake/CMakeLists.txt @@ -306,6 +306,7 @@ add_RunCMake_test(test_include_dirs) add_RunCMake_test(BundleUtilities) if(APPLE) add_RunCMake_test(INSTALL_NAME_DIR) + add_RunCMake_test(MacOSVersions) endif() function(add_RunCMake_test_try_compile) @@ -473,7 +474,9 @@ add_RunCMake_test(install -DNO_NAMELINK=${NO_NAMELINK} -DCYGWIN=${CYGWIN} -DCMAK -DCMAKE_SHARED_LIBRARY_RPATH_ORIGIN_TOKEN=${CMAKE_SHARED_LIBRARY_RPATH_ORIGIN_TOKEN} -DCMAKE_SYSTEM_NAME=${CMAKE_SYSTEM_NAME} -DCMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG=${CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG} - -DCMAKE_EXECUTABLE_FORMAT=${CMAKE_EXECUTABLE_FORMAT}) + -DCMAKE_EXECUTABLE_FORMAT=${CMAKE_EXECUTABLE_FORMAT} + -DCMake_INSTALL_NAME_TOOL_BUG=${CMake_INSTALL_NAME_TOOL_BUG} + ) add_RunCMake_test(CPackCommandLine) add_RunCMake_test(CPackConfig) diff --git a/Tests/RunCMake/MacOSVersions/CMakeLists.txt b/Tests/RunCMake/MacOSVersions/CMakeLists.txt new file mode 100644 index 0000000..2632ffa --- /dev/null +++ b/Tests/RunCMake/MacOSVersions/CMakeLists.txt @@ -0,0 +1,3 @@ +cmake_minimum_required(VERSION 3.16) +project(${RunCMake_TEST} NONE) +include(${RunCMake_TEST}.cmake) diff --git a/Tests/RunCMake/MacOSVersions/MacOSVersions-build-check.cmake b/Tests/RunCMake/MacOSVersions/MacOSVersions-build-check.cmake new file mode 100644 index 0000000..c4faa8b --- /dev/null +++ b/Tests/RunCMake/MacOSVersions/MacOSVersions-build-check.cmake @@ -0,0 +1,27 @@ +set(cfg_dir) +if(RunCMake_GENERATOR_IS_MULTI_CONFIG) + set(cfg_dir /Debug) +endif() + +set(lib "${RunCMake_TEST_BINARY_DIR}${cfg_dir}/libfoo.1.0.dylib") +if(NOT EXISTS "${lib}") + set(RunCMake_TEST_FAILED "Library file is missing:\n ${lib}") + return() +endif() + +execute_process(COMMAND otool -l "${lib}" OUTPUT_VARIABLE out ERROR_VARIABLE err RESULT_VARIABLE res) +if(NOT res EQUAL 0) + string(REPLACE "\n" "\n " err " ${err}") + set(RunCMake_TEST_FAILED "Running 'otool -l' on file:\n ${lib}\nfailed:\n${err}") + return() +endif() + +foreach(ver + [[current version 3\.2\.1]] + [[compatibility version 2\.1\.0]] + ) + if(NOT "${out}" MATCHES "( |\n)${ver}( |\n)") + set(RunCMake_TEST_FAILED "Library file:\n ${lib}\ndoes not contain '${ver}'") + return() + endif() +endforeach() diff --git a/Tests/RunCMake/MacOSVersions/MacOSVersions.cmake b/Tests/RunCMake/MacOSVersions/MacOSVersions.cmake new file mode 100644 index 0000000..629e445 --- /dev/null +++ b/Tests/RunCMake/MacOSVersions/MacOSVersions.cmake @@ -0,0 +1,9 @@ +enable_language(C) + +add_library(foo SHARED foo.c) +set_target_properties(foo PROPERTIES + VERSION 1.0 + SOVERSION 1 + OSX_COMPATIBILITY_VERSION 2.1.0 + OSX_CURRENT_VERSION 3.2.1 + ) diff --git a/Tests/RunCMake/MacOSVersions/RunCMakeTest.cmake b/Tests/RunCMake/MacOSVersions/RunCMakeTest.cmake new file mode 100644 index 0000000..eb7ca48 --- /dev/null +++ b/Tests/RunCMake/MacOSVersions/RunCMakeTest.cmake @@ -0,0 +1,11 @@ +include(RunCMake) + +function(run_MacOSVersions) + set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/MacOSVersions-build) + run_cmake(MacOSVersions) + + set(RunCMake_TEST_NO_CLEAN 1) + run_cmake_command(MacOSVersions-build ${CMAKE_COMMAND} --build . --config Debug) +endfunction() + +run_MacOSVersions() diff --git a/Tests/RunCMake/MacOSVersions/foo.c b/Tests/RunCMake/MacOSVersions/foo.c new file mode 100644 index 0000000..c83d856 --- /dev/null +++ b/Tests/RunCMake/MacOSVersions/foo.c @@ -0,0 +1,4 @@ +int foo(void) +{ + return 0; +} diff --git a/Tests/RunCMake/Ninja/CustomCommandJobPool.cmake b/Tests/RunCMake/Ninja/CustomCommandJobPool.cmake index 1e36e65..a96802a 100644 --- a/Tests/RunCMake/Ninja/CustomCommandJobPool.cmake +++ b/Tests/RunCMake/Ninja/CustomCommandJobPool.cmake @@ -1,3 +1,4 @@ +set_property(GLOBAL PROPERTY JOB_POOLS custom_command_pool=2 custom_target_pool=2) add_custom_command( OUTPUT hello.copy.c COMMAND "${CMAKE_COMMAND}" -E copy diff --git a/Tests/RunCMake/XcodeProject/RunCMakeTest.cmake b/Tests/RunCMake/XcodeProject/RunCMakeTest.cmake index 6ecf3f2..f1dda54 100644 --- a/Tests/RunCMake/XcodeProject/RunCMakeTest.cmake +++ b/Tests/RunCMake/XcodeProject/RunCMakeTest.cmake @@ -8,6 +8,16 @@ run_cmake(XcodeAttributeLocation) run_cmake(XcodeAttributeGenex) run_cmake(XcodeAttributeGenexError) run_cmake(XcodeGenerateTopLevelProjectOnly) + +function(XcodeGenerateTopLevelProjectOnlyWithObjectLibrary) + set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/XcodeGenerateTopLevelProjectOnlyWithObjectLibrary-build) + run_cmake(XcodeGenerateTopLevelProjectOnlyWithObjectLibrary) + set(RunCMake_TEST_NO_CLEAN 1) + run_cmake_command(XcodeGenerateTopLevelProjectOnlyWithObjectLibrary-build ${CMAKE_COMMAND} --build . --target shared_lib) +endfunction() + +XcodeGenerateTopLevelProjectOnlyWithObjectLibrary() + run_cmake(XcodeObjectNeedsEscape) run_cmake(XcodeObjectNeedsQuote) run_cmake(XcodeOptimizationFlags) diff --git a/Tests/RunCMake/XcodeProject/XcodeGenerateTopLevelProjectOnlyWithObjectLibrary.cmake b/Tests/RunCMake/XcodeProject/XcodeGenerateTopLevelProjectOnlyWithObjectLibrary.cmake new file mode 100644 index 0000000..67e4a00 --- /dev/null +++ b/Tests/RunCMake/XcodeProject/XcodeGenerateTopLevelProjectOnlyWithObjectLibrary.cmake @@ -0,0 +1,3 @@ +set(CMAKE_XCODE_GENERATE_TOP_LEVEL_PROJECT_ONLY TRUE) +project(XcodeGenerateTopLevelProjectOnly NONE) +add_subdirectory(subproject_with_object_lib) diff --git a/Tests/RunCMake/XcodeProject/subproject_with_object_lib/CMakeLists.txt b/Tests/RunCMake/XcodeProject/subproject_with_object_lib/CMakeLists.txt new file mode 100644 index 0000000..ab400f4 --- /dev/null +++ b/Tests/RunCMake/XcodeProject/subproject_with_object_lib/CMakeLists.txt @@ -0,0 +1,7 @@ +project(subproject_with_object_lib) + +add_library(object_lib_dependency OBJECT dummy.cpp) + +add_library(shared_lib SHARED dummy.cpp) +target_sources(shared_lib PRIVATE $<TARGET_OBJECTS:object_lib_dependency>) +set_target_properties(shared_lib PROPERTIES MACOSX_RPATH ON) diff --git a/Tests/RunCMake/XcodeProject/subproject_with_object_lib/dummy.cpp b/Tests/RunCMake/XcodeProject/subproject_with_object_lib/dummy.cpp new file mode 100644 index 0000000..bb4218a --- /dev/null +++ b/Tests/RunCMake/XcodeProject/subproject_with_object_lib/dummy.cpp @@ -0,0 +1,5 @@ +namespace { +void dummy() +{ +} +} diff --git a/Tests/RunCMake/install/RunCMakeTest.cmake b/Tests/RunCMake/install/RunCMakeTest.cmake index 21c320b..70570b7 100644 --- a/Tests/RunCMake/install/RunCMakeTest.cmake +++ b/Tests/RunCMake/install/RunCMakeTest.cmake @@ -156,10 +156,12 @@ run_install_test(TARGETS-RPATH) run_install_test(InstallRequiredSystemLibraries) if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Darwin") - run_install_test(file-GET_RUNTIME_DEPENDENCIES-macos) - run_install_test(file-GET_RUNTIME_DEPENDENCIES-macos-unresolved) - run_install_test(file-GET_RUNTIME_DEPENDENCIES-macos-conflict) - run_install_test(file-GET_RUNTIME_DEPENDENCIES-macos-notfile) + if(NOT CMake_INSTALL_NAME_TOOL_BUG) + run_install_test(file-GET_RUNTIME_DEPENDENCIES-macos) + run_install_test(file-GET_RUNTIME_DEPENDENCIES-macos-unresolved) + run_install_test(file-GET_RUNTIME_DEPENDENCIES-macos-conflict) + run_install_test(file-GET_RUNTIME_DEPENDENCIES-macos-notfile) + endif() run_cmake(file-GET_RUNTIME_DEPENDENCIES-project) run_cmake(file-GET_RUNTIME_DEPENDENCIES-badargs1) run_cmake(file-GET_RUNTIME_DEPENDENCIES-badargs2) |