From 2467a2b3184595a87e93db510408fc14ddbaf3b9 Mon Sep 17 00:00:00 2001 From: Robert Maynard Date: Fri, 1 Nov 2019 08:12:05 -0400 Subject: [PATCH] CUDA: Add cuda meta-features (e.g. ``cuda_std_11``) support --- Auxiliary/vim/syntax/cmake.vim | 2 + Help/command/target_compile_features.rst | 6 +- Help/manual/cmake-compile-features.7.rst | 13 +- Help/manual/cmake-properties.7.rst | 1 + Help/manual/cmake-variables.7.rst | 1 + Help/prop_gbl/CMAKE_CUDA_KNOWN_FEATURES.rst | 30 +++ Help/prop_tgt/COMPILE_FEATURES.rst | 3 +- Help/release/dev/cuda-gains-meta-features.rst | 7 + Help/variable/CMAKE_CUDA_COMPILE_FEATURES.rst | 11 + Modules/CMakeCUDACompiler.cmake.in | 7 + Modules/CMakeCUDACompilerId.cu.in | 2 +- Modules/CMakeDetermineCompileFeatures.cmake | 51 ++++ Modules/CMakeTestCUDACompiler.cmake | 3 + .../Compiler/CMakeCommonCompilerMacros.cmake | 44 ++++ Modules/Compiler/NVIDIA-CUDA.cmake | 25 +- Modules/Internal/FeatureTesting.cmake | 14 ++ Source/cmLocalGenerator.cxx | 23 +- Source/cmMakefile.cxx | 219 +++++++++++++++--- Source/cmMakefile.h | 12 +- Source/cmState.cxx | 3 + Source/cmake.h | 7 + Tests/CMakeLists.txt | 4 +- Tests/Cuda/CMakeLists.txt | 7 +- .../CMakeLists.txt | 8 +- .../main.cu | 0 .../Cuda/MixedStandardLevels1/CMakeLists.txt | 14 ++ Tests/Cuda/MixedStandardLevels1/lib.cpp | 7 + Tests/Cuda/MixedStandardLevels1/main.cu | 9 + .../Cuda/MixedStandardLevels2/CMakeLists.txt | 14 ++ Tests/Cuda/MixedStandardLevels2/lib.cpp | 7 + Tests/Cuda/MixedStandardLevels2/main.cu | 11 + .../Cuda/MixedStandardLevels3/CMakeLists.txt | 12 + Tests/Cuda/MixedStandardLevels3/lib.cpp | 7 + Tests/Cuda/MixedStandardLevels3/main.cu | 5 + .../Cuda/MixedStandardLevels4/CMakeLists.txt | 14 ++ Tests/Cuda/MixedStandardLevels4/lib.cpp | 16 ++ Tests/Cuda/MixedStandardLevels4/main.cu | 5 + .../Cuda/MixedStandardLevels5/CMakeLists.txt | 13 ++ Tests/Cuda/MixedStandardLevels5/lib.cpp | 13 ++ Tests/Cuda/MixedStandardLevels5/main.cu | 8 + Tests/CudaOnly/CMakeLists.txt | 1 + Tests/CudaOnly/EnableStandard/CMakeLists.txt | 5 +- .../ResolveDeviceSymbols/CMakeLists.txt | 4 +- .../SeparateCompilation/CMakeLists.txt | 6 +- Tests/CudaOnly/Standard98/CMakeLists.txt | 15 ++ Tests/CudaOnly/Standard98/main.cu | 8 + Tests/ExportImport/Export/CMakeLists.txt | 12 + Tests/ExportImport/Import/A/CMakeLists.txt | 7 + Tests/ExportImport/InitialCache.cmake.in | 1 + Tests/RunCMake/try_compile/RunCMakeTest.cmake | 6 +- 50 files changed, 652 insertions(+), 71 deletions(-) create mode 100644 Help/prop_gbl/CMAKE_CUDA_KNOWN_FEATURES.rst create mode 100644 Help/release/dev/cuda-gains-meta-features.rst create mode 100644 Help/variable/CMAKE_CUDA_COMPILE_FEATURES.rst rename Tests/Cuda/{MixedStandardLevels => CXXStandardSetTwice}/CMakeLists.txt (57%) rename Tests/Cuda/{MixedStandardLevels => CXXStandardSetTwice}/main.cu (100%) create mode 100644 Tests/Cuda/MixedStandardLevels1/CMakeLists.txt create mode 100644 Tests/Cuda/MixedStandardLevels1/lib.cpp create mode 100644 Tests/Cuda/MixedStandardLevels1/main.cu create mode 100644 Tests/Cuda/MixedStandardLevels2/CMakeLists.txt create mode 100644 Tests/Cuda/MixedStandardLevels2/lib.cpp create mode 100644 Tests/Cuda/MixedStandardLevels2/main.cu create mode 100644 Tests/Cuda/MixedStandardLevels3/CMakeLists.txt create mode 100644 Tests/Cuda/MixedStandardLevels3/lib.cpp create mode 100644 Tests/Cuda/MixedStandardLevels3/main.cu create mode 100644 Tests/Cuda/MixedStandardLevels4/CMakeLists.txt create mode 100644 Tests/Cuda/MixedStandardLevels4/lib.cpp create mode 100644 Tests/Cuda/MixedStandardLevels4/main.cu create mode 100644 Tests/Cuda/MixedStandardLevels5/CMakeLists.txt create mode 100644 Tests/Cuda/MixedStandardLevels5/lib.cpp create mode 100644 Tests/Cuda/MixedStandardLevels5/main.cu create mode 100644 Tests/CudaOnly/Standard98/CMakeLists.txt create mode 100644 Tests/CudaOnly/Standard98/main.cu diff --git a/Auxiliary/vim/syntax/cmake.vim b/Auxiliary/vim/syntax/cmake.vim index 5de117b826..31ec1d09f2 100644 --- a/Auxiliary/vim/syntax/cmake.vim +++ b/Auxiliary/vim/syntax/cmake.vim @@ -101,6 +101,7 @@ syn keyword cmakeProperty contained \ CLEAN_NO_CUSTOM \ CMAKE_CONFIGURE_DEPENDS \ CMAKE_CXX_KNOWN_FEATURES + \ CMAKE_CUDA_KNOWN_FEATURES \ CMAKE_C_KNOWN_FEATURES \ CMAKE_ROLE \ COMMON_LANGUAGE_RUNTIME @@ -725,6 +726,7 @@ syn keyword cmakeVariable contained \ CMAKE_CUDA_COMPILER_AR \ CMAKE_CUDA_COMPILER_ARCHITECTURE_ID \ CMAKE_CUDA_COMPILER_EXTERNAL_TOOLCHAIN + \ CMAKE_CUDA_COMPILE_FEATURES \ CMAKE_CUDA_COMPILER_ID \ CMAKE_CUDA_COMPILER_LAUNCHER \ CMAKE_CUDA_COMPILER_LOADED diff --git a/Help/command/target_compile_features.rst b/Help/command/target_compile_features.rst index 9271cd56c8..c5401e6ec8 100644 --- a/Help/command/target_compile_features.rst +++ b/Help/command/target_compile_features.rst @@ -8,9 +8,9 @@ Add expected compiler features to a target. target_compile_features( [...]) Specifies compiler features required when compiling a given target. If the -feature is not listed in the :variable:`CMAKE_C_COMPILE_FEATURES` variable -or :variable:`CMAKE_CXX_COMPILE_FEATURES` variable, -then an error will be reported by CMake. If the use of the feature requires +feature is not listed in the :variable:`CMAKE_C_COMPILE_FEATURES`, +:variable:`CMAKE_CUDA_COMPILE_FEATURES`, or :variable:`CMAKE_CXX_COMPILE_FEATURES` +variables, then an error will be reported by CMake. If the use of the feature requires an additional compiler flag, such as ``-std=gnu++11``, the flag will be added automatically. diff --git a/Help/manual/cmake-compile-features.7.rst b/Help/manual/cmake-compile-features.7.rst index a14e3222c0..05dc038be8 100644 --- a/Help/manual/cmake-compile-features.7.rst +++ b/Help/manual/cmake-compile-features.7.rst @@ -19,11 +19,11 @@ While features are typically specified in programming language standards, CMake provides a primary user interface based on granular handling of the features, not the language standard that introduced the feature. -The :prop_gbl:`CMAKE_C_KNOWN_FEATURES` and -:prop_gbl:`CMAKE_CXX_KNOWN_FEATURES` global properties contain all the +The :prop_gbl:`CMAKE_C_KNOWN_FEATURES`, :prop_gbl:`CMAKE_CUDA_KNOWN_FEATURES`, +and :prop_gbl:`CMAKE_CXX_KNOWN_FEATURES` global properties contain all the features known to CMake, regardless of compiler support for the feature. -The :variable:`CMAKE_C_COMPILE_FEATURES` and -:variable:`CMAKE_CXX_COMPILE_FEATURES` variables contain all features +The :variable:`CMAKE_C_COMPILE_FEATURES`, :variable:`CMAKE_CUDA_COMPILE_FEATURES` +, and :variable:`CMAKE_CXX_COMPILE_FEATURES` variables contain all features CMake knows are known to the compiler, regardless of language standard or compile flags needed to use them. @@ -368,8 +368,9 @@ versions specified for each: * all compilers and versions listed above with only meta-features for C++. * ``TI``: Texas Instruments compiler. -CMake is currently aware of the :prop_tgt:`CUDA standards ` -from the following :variable:`compiler ids _COMPILER_ID>` as of the +CMake is currently aware of the :prop_tgt:`CUDA standards ` and +their associated meta-features (e.g. ``cuda_std_11``) available from the +following :variable:`compiler ids _COMPILER_ID>` as of the versions specified for each: * ``NVIDIA``: NVIDIA nvcc compiler 7.5+. diff --git a/Help/manual/cmake-properties.7.rst b/Help/manual/cmake-properties.7.rst index c5ef09abef..b9db12d6ae 100644 --- a/Help/manual/cmake-properties.7.rst +++ b/Help/manual/cmake-properties.7.rst @@ -22,6 +22,7 @@ Properties of Global Scope /prop_gbl/AUTOMOC_TARGETS_FOLDER /prop_gbl/AUTORCC_SOURCE_GROUP /prop_gbl/CMAKE_C_KNOWN_FEATURES + /prop_gbl/CMAKE_CUDA_KNOWN_FEATURES /prop_gbl/CMAKE_CXX_KNOWN_FEATURES /prop_gbl/CMAKE_ROLE /prop_gbl/DEBUG_CONFIGURATIONS diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst index 0c1d510995..d4b855db2d 100644 --- a/Help/manual/cmake-variables.7.rst +++ b/Help/manual/cmake-variables.7.rst @@ -472,6 +472,7 @@ Variables for Languages /variable/CMAKE_COMPILER_IS_GNUCC /variable/CMAKE_COMPILER_IS_GNUCXX /variable/CMAKE_COMPILER_IS_GNUG77 + /variable/CMAKE_CUDA_COMPILE_FEATURES /variable/CMAKE_CUDA_HOST_COMPILER /variable/CMAKE_CUDA_EXTENSIONS /variable/CMAKE_CUDA_STANDARD diff --git a/Help/prop_gbl/CMAKE_CUDA_KNOWN_FEATURES.rst b/Help/prop_gbl/CMAKE_CUDA_KNOWN_FEATURES.rst new file mode 100644 index 0000000000..44e37fe1c5 --- /dev/null +++ b/Help/prop_gbl/CMAKE_CUDA_KNOWN_FEATURES.rst @@ -0,0 +1,30 @@ +CMAKE_CUDA_KNOWN_FEATURES +------------------------- + +List of CUDA features known to this version of CMake. + +The features listed in this global property may be known to be available to the +CUDA compiler. If the feature is available with the C++ compiler, it will +be listed in the :variable:`CMAKE_CUDA_COMPILE_FEATURES` variable. + +The features listed here may be used with the :command:`target_compile_features` +command. See the :manual:`cmake-compile-features(7)` manual for information on +compile features and a list of supported compilers. + + +The features known to this version of CMake are: + +``cuda_std_03`` + Compiler mode is at least CUDA/C++ 03. + +``cuda_std_11`` + Compiler mode is at least CUDA/C++ 11. + +``cuda_std_14`` + Compiler mode is at least CUDA/C++ 14. + +``cuda_std_17`` + Compiler mode is at least CUDA/C++ 17. + +``cuda_std_20`` + Compiler mode is at least CUDA/C++ 20. diff --git a/Help/prop_tgt/COMPILE_FEATURES.rst b/Help/prop_tgt/COMPILE_FEATURES.rst index 195215e3c8..46aec4ff41 100644 --- a/Help/prop_tgt/COMPILE_FEATURES.rst +++ b/Help/prop_tgt/COMPILE_FEATURES.rst @@ -4,7 +4,8 @@ COMPILE_FEATURES Compiler features enabled for this target. The list of features in this property are a subset of the features listed -in the :variable:`CMAKE_CXX_COMPILE_FEATURES` variable. +in the :variable:`CMAKE_C_COMPILE_FEATURES`, :variable:`CMAKE_CUDA_COMPILE_FEATURES`, and +:variable:`CMAKE_CXX_COMPILE_FEATURES` variables. Contents of ``COMPILE_FEATURES`` may use "generator expressions" with the syntax ``$<...>``. See the :manual:`cmake-generator-expressions(7)` manual for diff --git a/Help/release/dev/cuda-gains-meta-features.rst b/Help/release/dev/cuda-gains-meta-features.rst new file mode 100644 index 0000000000..e5e1022895 --- /dev/null +++ b/Help/release/dev/cuda-gains-meta-features.rst @@ -0,0 +1,7 @@ +cuda-gains-meta-features +------------------------ + +* The :manual:`Compile Features ` functionality + now offers meta-features for the CUDA language standard levels + (e.g. ``cuda_std_03``, ``cuda_std_14``). See + :prop_gbl:`CMAKE_CUDA_KNOWN_FEATURES`. diff --git a/Help/variable/CMAKE_CUDA_COMPILE_FEATURES.rst b/Help/variable/CMAKE_CUDA_COMPILE_FEATURES.rst new file mode 100644 index 0000000000..2cd2650c4d --- /dev/null +++ b/Help/variable/CMAKE_CUDA_COMPILE_FEATURES.rst @@ -0,0 +1,11 @@ +CMAKE_CUDA_COMPILE_FEATURES +--------------------------- + +List of features known to the CUDA compiler + +These features are known to be available for use with the CUDA compiler. This +list is a subset of the features listed in the +:prop_gbl:`CMAKE_CUDA_KNOWN_FEATURES` global property. + +See the :manual:`cmake-compile-features(7)` manual for information on +compile features and a list of supported compilers. diff --git a/Modules/CMakeCUDACompiler.cmake.in b/Modules/CMakeCUDACompiler.cmake.in index e012abf946..ea491a9985 100644 --- a/Modules/CMakeCUDACompiler.cmake.in +++ b/Modules/CMakeCUDACompiler.cmake.in @@ -4,6 +4,13 @@ set(CMAKE_CUDA_HOST_LINK_LAUNCHER "@CMAKE_CUDA_HOST_LINK_LAUNCHER@") set(CMAKE_CUDA_COMPILER_ID "@CMAKE_CUDA_COMPILER_ID@") set(CMAKE_CUDA_COMPILER_VERSION "@CMAKE_CUDA_COMPILER_VERSION@") set(CMAKE_CUDA_STANDARD_COMPUTED_DEFAULT "@CMAKE_CUDA_STANDARD_COMPUTED_DEFAULT@") +set(CMAKE_CUDA_COMPILE_FEATURES "@CMAKE_CUDA_COMPILE_FEATURES@") +set(CMAKE_CUDA03_COMPILE_FEATURES "@CMAKE_CUDA03_COMPILE_FEATURES@") +set(CMAKE_CUDA11_COMPILE_FEATURES "@CMAKE_CUDA11_COMPILE_FEATURES@") +set(CMAKE_CUDA14_COMPILE_FEATURES "@CMAKE_CUDA14_COMPILE_FEATURES@") +set(CMAKE_CUDA17_COMPILE_FEATURES "@CMAKE_CUDA17_COMPILE_FEATURES@") +set(CMAKE_CUDA20_COMPILE_FEATURES "@CMAKE_CUDA20_COMPILE_FEATURES@") + set(CMAKE_CUDA_SIMULATE_ID "@CMAKE_CUDA_SIMULATE_ID@") set(CMAKE_CUDA_SIMULATE_VERSION "@CMAKE_CUDA_SIMULATE_VERSION@") @SET_MSVC_CUDA_ARCHITECTURE_ID@ diff --git a/Modules/CMakeCUDACompilerId.cu.in b/Modules/CMakeCUDACompilerId.cu.in index 6eda9244cd..2055de2181 100644 --- a/Modules/CMakeCUDACompilerId.cu.in +++ b/Modules/CMakeCUDACompilerId.cu.in @@ -26,7 +26,7 @@ const char* info_language_dialect_default = "INFO" ":" "dialect_default[" #elif __cplusplus >= 201103L "11" #else - "98" + "03" #endif "]"; diff --git a/Modules/CMakeDetermineCompileFeatures.cmake b/Modules/CMakeDetermineCompileFeatures.cmake index 6adebaef6d..b50e5f1723 100644 --- a/Modules/CMakeDetermineCompileFeatures.cmake +++ b/Modules/CMakeDetermineCompileFeatures.cmake @@ -91,6 +91,57 @@ function(cmake_determine_compile_features lang) set(CMAKE_CXX20_COMPILE_FEATURES ${CMAKE_CXX20_COMPILE_FEATURES} PARENT_SCOPE) message(CHECK_PASS "done") + + elseif(lang STREQUAL CUDA AND COMMAND cmake_record_cuda_compile_features) + message(CHECK_START "Detecting ${lang} compile features") + + set(CMAKE_CUDA03_COMPILE_FEATURES) + set(CMAKE_CUDA11_COMPILE_FEATURES) + set(CMAKE_CUDA14_COMPILE_FEATURES) + set(CMAKE_CUDA17_COMPILE_FEATURES) + set(CMAKE_CUDA20_COMPILE_FEATURES) + + include("${CMAKE_ROOT}/Modules/Internal/FeatureTesting.cmake") + + cmake_record_cuda_compile_features() + + if(NOT _result EQUAL 0) + message(CHECK_FAIL "failed") + return() + endif() + + if (CMAKE_CUDA17_COMPILE_FEATURES AND CMAKE_CUDA20_COMPILE_FEATURES) + list(REMOVE_ITEM CMAKE_CUDA20_COMPILE_FEATURES ${CMAKE_CUDA17_COMPILE_FEATURES}) + endif() + if (CMAKE_CUDA14_COMPILE_FEATURES AND CMAKE_CUDA17_COMPILE_FEATURES) + list(REMOVE_ITEM CMAKE_CUDA17_COMPILE_FEATURES ${CMAKE_CUDA14_COMPILE_FEATURES}) + endif() + if (CMAKE_CUDA11_COMPILE_FEATURES AND CMAKE_CUDA14_COMPILE_FEATURES) + list(REMOVE_ITEM CMAKE_CUDA14_COMPILE_FEATURES ${CMAKE_CUDA11_COMPILE_FEATURES}) + endif() + if (CMAKE_CUDA03_COMPILE_FEATURES AND CMAKE_CUDA11_COMPILE_FEATURES) + list(REMOVE_ITEM CMAKE_CUDA11_COMPILE_FEATURES ${CMAKE_CUDA03_COMPILE_FEATURES}) + endif() + + if(NOT CMAKE_CUDA_COMPILE_FEATURES) + set(CMAKE_CUDA_COMPILE_FEATURES + ${CMAKE_CUDA03_COMPILE_FEATURES} + ${CMAKE_CUDA11_COMPILE_FEATURES} + ${CMAKE_CUDA14_COMPILE_FEATURES} + ${CMAKE_CUDA17_COMPILE_FEATURES} + ${CMAKE_CUDA20_COMPILE_FEATURES} + ) + endif() + + set(CMAKE_CUDA_COMPILE_FEATURES ${CMAKE_CUDA_COMPILE_FEATURES} PARENT_SCOPE) + set(CMAKE_CUDA03_COMPILE_FEATURES ${CMAKE_CUDA03_COMPILE_FEATURES} PARENT_SCOPE) + set(CMAKE_CUDA11_COMPILE_FEATURES ${CMAKE_CUDA11_COMPILE_FEATURES} PARENT_SCOPE) + set(CMAKE_CUDA14_COMPILE_FEATURES ${CMAKE_CUDA14_COMPILE_FEATURES} PARENT_SCOPE) + set(CMAKE_CUDA17_COMPILE_FEATURES ${CMAKE_CUDA17_COMPILE_FEATURES} PARENT_SCOPE) + set(CMAKE_CUDA20_COMPILE_FEATURES ${CMAKE_CUDA20_COMPILE_FEATURES} PARENT_SCOPE) + + message(CHECK_PASS "done") + endif() endfunction() diff --git a/Modules/CMakeTestCUDACompiler.cmake b/Modules/CMakeTestCUDACompiler.cmake index c145813efb..a0f6bc949a 100644 --- a/Modules/CMakeTestCUDACompiler.cmake +++ b/Modules/CMakeTestCUDACompiler.cmake @@ -58,6 +58,9 @@ else() # Try to identify the ABI and configure it into CMakeCUDACompiler.cmake include(${CMAKE_ROOT}/Modules/CMakeDetermineCompilerABI.cmake) CMAKE_DETERMINE_COMPILER_ABI(CUDA ${CMAKE_ROOT}/Modules/CMakeCUDACompilerABI.cu) + # Try to identify the compiler features + include(${CMAKE_ROOT}/Modules/CMakeDetermineCompileFeatures.cmake) + CMAKE_DETERMINE_COMPILE_FEATURES(CUDA) if("x${CMAKE_CUDA_SIMULATE_ID}" STREQUAL "xMSVC") set(CMAKE_CUDA_IMPLICIT_LINK_LIBRARIES "${CMAKE_CUDA_HOST_IMPLICIT_LINK_LIBRARIES}") diff --git a/Modules/Compiler/CMakeCommonCompilerMacros.cmake b/Modules/Compiler/CMakeCommonCompilerMacros.cmake index 96537f8dda..409b65a5f5 100644 --- a/Modules/Compiler/CMakeCommonCompilerMacros.cmake +++ b/Modules/Compiler/CMakeCommonCompilerMacros.cmake @@ -134,3 +134,47 @@ macro(cmake_record_cxx_compile_features) unset(CMAKE_CXX98_STANDARD__HAS_FULL_SUPPORT) endif() endmacro() + +macro(cmake_record_cuda_compile_features) + set(_result 0) + if(_result EQUAL 0 AND DEFINED CMAKE_CUDA20_STANDARD_COMPILE_OPTION) + if(CMAKE_CUDA20_STANDARD__HAS_FULL_SUPPORT) + _has_compiler_features_cuda(20) + else() + _record_compiler_features_cuda(20) + endif() + unset(CMAKE_CUDA20_STANDARD__HAS_FULL_SUPPORT) + endif() + if(_result EQUAL 0 AND DEFINED CMAKE_CUDA17_STANDARD_COMPILE_OPTION) + if(CMAKE_CUDA17_STANDARD__HAS_FULL_SUPPORT) + _has_compiler_features_cuda(17) + else() + _record_compiler_features_cuda(17) + endif() + unset(CMAKE_CUDA17_STANDARD__HAS_FULL_SUPPORT) + endif() + if(_result EQUAL 0 AND DEFINED CMAKE_CUDA14_STANDARD_COMPILE_OPTION) + if(CMAKE_CUDA14_STANDARD__HAS_FULL_SUPPORT) + _has_compiler_features_cuda(14) + else() + _record_compiler_features_cuda(14) + endif() + unset(CMAKE_CUDA14_STANDARD__HAS_FULL_SUPPORT) + endif() + if(_result EQUAL 0 AND DEFINED CMAKE_CUDA11_STANDARD_COMPILE_OPTION) + if(CMAKE_CUDA11_STANDARD__HAS_FULL_SUPPORT) + _has_compiler_features_cuda(11) + else() + _record_compiler_features_cuda(11) + endif() + unset(CMAKE_CUDA11_STANDARD__HAS_FULL_SUPPORT) + endif() + if(_result EQUAL 0 AND DEFINED CMAKE_CUDA03_STANDARD_COMPILE_OPTION) + if(CMAKE_CUDA03_STANDARD__HAS_FULL_SUPPORT) + _has_compiler_features_cuda(03) + else() + _record_compiler_features_cuda(03) + endif() + unset(CMAKE_CUDA03_STANDARD__HAS_FULL_SUPPORT) + endif() +endmacro() diff --git a/Modules/Compiler/NVIDIA-CUDA.cmake b/Modules/Compiler/NVIDIA-CUDA.cmake index 2b24fa57cd..ad7f084281 100644 --- a/Modules/Compiler/NVIDIA-CUDA.cmake +++ b/Modules/Compiler/NVIDIA-CUDA.cmake @@ -1,3 +1,5 @@ +include(Compiler/CMakeCommonCompilerMacros) + set(CMAKE_CUDA_COMPILER_HAS_DEVICE_LINK_PHASE True) set(CMAKE_CUDA_VERBOSE_FLAG "-v") set(CMAKE_CUDA_VERBOSE_COMPILE_FLAG "-Xcompiler=-v") @@ -42,17 +44,26 @@ set(CMAKE_SHARED_LIBRARY_CREATE_CUDA_FLAGS -shared) set(CMAKE_INCLUDE_SYSTEM_FLAG_CUDA -isystem=) if("x${CMAKE_CUDA_SIMULATE_ID}" STREQUAL "xMSVC") - set(CMAKE_CUDA_STANDARD_DEFAULT "") + set(CMAKE_CUDA03_STANDARD_COMPILE_OPTION "") + set(CMAKE_CUDA03_EXTENSION_COMPILE_OPTION "") + + set(CMAKE_CUDA11_STANDARD_COMPILE_OPTION "") + set(CMAKE_CUDA11_EXTENSION_COMPILE_OPTION "") + + if (NOT CMAKE_CUDA_COMPILER_VERSION VERSION_LESS 9.0) + set(CMAKE_CUDA14_STANDARD_COMPILE_OPTION "") + set(CMAKE_CUDA14_EXTENSION_COMPILE_OPTION "") + endif() else() - set(CMAKE_CUDA_STANDARD_DEFAULT 98) - set(CMAKE_CUDA98_STANDARD_COMPILE_OPTION "") - set(CMAKE_CUDA98_EXTENSION_COMPILE_OPTION "") + set(CMAKE_CUDA03_STANDARD_COMPILE_OPTION "") + set(CMAKE_CUDA03_EXTENSION_COMPILE_OPTION "") + set(CMAKE_CUDA11_STANDARD_COMPILE_OPTION "-std=c++11") set(CMAKE_CUDA11_EXTENSION_COMPILE_OPTION "-std=c++11") if (NOT CMAKE_CUDA_COMPILER_VERSION VERSION_LESS 9.0) - set(CMAKE_CUDA98_STANDARD_COMPILE_OPTION "-std=c++03") - set(CMAKE_CUDA98_EXTENSION_COMPILE_OPTION "-std=c++03") + set(CMAKE_CUDA03_STANDARD_COMPILE_OPTION "-std=c++03") + set(CMAKE_CUDA03_EXTENSION_COMPILE_OPTION "-std=c++03") set(CMAKE_CUDA14_STANDARD_COMPILE_OPTION "-std=c++14") set(CMAKE_CUDA14_EXTENSION_COMPILE_OPTION "-std=c++14") endif() @@ -69,3 +80,5 @@ if (CMAKE_CUDA_COMPILER_VERSION VERSION_GREATER_EQUAL "9.0") set(CMAKE_CUDA_RESPONSE_FILE_LINK_FLAG "--options-file ") set(CMAKE_CUDA_RESPONSE_FILE_FLAG "--options-file ") endif() + +__compiler_check_default_language_standard(CUDA 6.0 03) diff --git a/Modules/Internal/FeatureTesting.cmake b/Modules/Internal/FeatureTesting.cmake index 75be473f39..72d96b33fc 100644 --- a/Modules/Internal/FeatureTesting.cmake +++ b/Modules/Internal/FeatureTesting.cmake @@ -89,6 +89,16 @@ macro(_record_compiler_features_cxx std) unset(lang_level_has_features) endmacro() +macro(_record_compiler_features_cuda std) + list(APPEND CMAKE_CUDA${std}_COMPILE_FEATURES cuda_std_${std}) + + get_property(lang_level_has_features GLOBAL PROPERTY CMAKE_CUDA${std}_KNOWN_FEATURES) + if(lang_level_has_features) + _record_compiler_features(CUDA "${CMAKE_CUDA${std}_STANDARD_COMPILE_OPTION}" CMAKE_CUDA${std}_COMPILE_FEATURES) + endif() + unset(lang_level_has_features) +endmacro() + macro(_has_compiler_features lang level compile_flags feature_list) # presume all known features are supported get_property(known_features GLOBAL PROPERTY CMAKE_${lang}${level}_KNOWN_FEATURES) @@ -103,3 +113,7 @@ macro(_has_compiler_features_cxx std) list(APPEND CMAKE_CXX${std}_COMPILE_FEATURES cxx_std_${std}) _has_compiler_features(CXX ${std} "${CMAKE_CXX${std}_STANDARD_COMPILE_OPTION}" CMAKE_CXX${std}_COMPILE_FEATURES) endmacro() +macro(_has_compiler_features_cuda std) + list(APPEND CMAKE_CUDA${std}_COMPILE_FEATURES cuda_std_${std}) + _has_compiler_features(CUDA ${std} "${CMAKE_CUDA${std}_STANDARD_COMPILE_OPTION}" CMAKE_CUDA${std}_COMPILE_FEATURES) +endmacro() diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index c58603f1d1..e7494ee9b0 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -696,11 +696,12 @@ bool cmLocalGenerator::ComputeTargetCompileFeatures() using LanguagePair = std::pair; std::vector pairedLanguages{ { "OBJC", "C" }, - { "OBJCXX", "CXX" } }; - std::set objcEnabledLanguages; + { "OBJCXX", "CXX" }, + { "CUDA", "CXX" } }; + std::set inferredEnabledLanguages; for (auto const& lang : pairedLanguages) { if (this->Makefile->GetState()->GetLanguageEnabled(lang.first)) { - objcEnabledLanguages.insert(lang); + inferredEnabledLanguages.insert(lang); } } @@ -739,12 +740,17 @@ bool cmLocalGenerator::ComputeTargetCompileFeatures() target->GetProperty(cmStrCat(lang.second, property))); } }; - for (auto const& lang : objcEnabledLanguages) { + for (auto const& lang : pairedLanguages) { if (copyStandardToObjLang(lang)) { copyPropertyToObjLang(lang, "_STANDARD_REQUIRED"); copyPropertyToObjLang(lang, "_EXTENSIONS"); } } + if (const char* standard = target->GetProperty("CUDA_STANDARD")) { + if (std::string{ standard } == "98") { + target->Target->SetProperty("CUDA_STANDARD", "03"); + } + } } } @@ -2090,17 +2096,22 @@ void cmLocalGenerator::AddCompilerRequirementFlag( langStdMap["OBJC"].emplace_back("99"); langStdMap["OBJC"].emplace_back("90"); + langStdMap["CUDA"].emplace_back("20"); + langStdMap["CUDA"].emplace_back("17"); langStdMap["CUDA"].emplace_back("14"); langStdMap["CUDA"].emplace_back("11"); - langStdMap["CUDA"].emplace_back("98"); + langStdMap["CUDA"].emplace_back("03"); } std::string standard(standardProp); - + if (lang == "CUDA" && standard == "98") { + standard = "03"; + } std::vector& stds = langStdMap[lang]; auto stdIt = std::find(stds.begin(), stds.end(), standard); if (stdIt == stds.end()) { + std::string e = lang + "_STANDARD is set to invalid value '" + standard + "'"; this->GetGlobalGenerator()->GetCMakeInstance()->IssueMessage( diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index dc0b50f413..ac494b4d55 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -4535,10 +4535,14 @@ static const char* const C_FEATURES[] = { nullptr FOR_EACH_C_FEATURE( static const char* const CXX_FEATURES[] = { nullptr FOR_EACH_CXX_FEATURE( FEATURE_STRING) }; + +static const char* const CUDA_FEATURES[] = { nullptr FOR_EACH_CUDA_FEATURE( + FEATURE_STRING) }; #undef FEATURE_STRING static const char* const C_STANDARDS[] = { "90", "99", "11" }; static const char* const CXX_STANDARDS[] = { "98", "11", "14", "17", "20" }; +static const char* const CUDA_STANDARDS[] = { "03", "11", "14", "17", "20" }; bool cmMakefile::AddRequiredTargetFeature(cmTarget* target, const std::string& feature, @@ -4578,9 +4582,13 @@ bool cmMakefile::AddRequiredTargetFeature(cmTarget* target, target->AppendProperty("COMPILE_FEATURES", feature.c_str()); - return lang == "C" || lang == "OBJC" - ? this->AddRequiredTargetCFeature(target, feature, lang, error) - : this->AddRequiredTargetCxxFeature(target, feature, lang, error); + if (lang == "C" || lang == "OBJC") { + return this->AddRequiredTargetCFeature(target, feature, lang, error); + } + if (lang == "CUDA") { + return this->AddRequiredTargetCudaFeature(target, feature, lang, error); + } + return this->AddRequiredTargetCxxFeature(target, feature, lang, error); } bool cmMakefile::CompileFeatureKnown(cmTarget const* target, @@ -4604,6 +4612,13 @@ bool cmMakefile::CompileFeatureKnown(cmTarget const* target, lang = "CXX"; return true; } + bool isCudaFeature = + std::find_if(cm::cbegin(CUDA_FEATURES) + 1, cm::cend(CUDA_FEATURES), + cmStrCmp(feature)) != cm::cend(CUDA_FEATURES); + if (isCudaFeature) { + lang = "CUDA"; + return true; + } std::ostringstream e; if (error) { e << "specified"; @@ -4672,9 +4687,13 @@ bool cmMakefile::HaveStandardAvailable(cmTarget const* target, std::string const& lang, const std::string& feature) const { - return lang == "C" || lang == "OBJC" - ? this->HaveCStandardAvailable(target, feature, lang) - : this->HaveCxxStandardAvailable(target, feature, lang); + if (lang == "C" || lang == "OBJC") { + return this->HaveCStandardAvailable(target, feature, lang); + } + if (lang == "CUDA") { + return this->HaveCudaStandardAvailable(target, feature, lang); + } + return this->HaveCxxStandardAvailable(target, feature, lang); } bool cmMakefile::HaveCStandardAvailable(cmTarget const* target, @@ -4757,6 +4776,14 @@ bool cmMakefile::IsLaterStandard(std::string const& lang, return std::find_if(rhsIt, cm::cend(C_STANDARDS), cmStrCmp(lhs)) != cm::cend(C_STANDARDS); } + if (lang == "CUDA") { + const char* const* rhsIt = std::find_if( + cm::cbegin(CUDA_STANDARDS), cm::cend(CUDA_STANDARDS), cmStrCmp(rhs)); + + return std::find_if(rhsIt, cm::cend(CUDA_STANDARDS), cmStrCmp(lhs)) != + cm::cend(CUDA_STANDARDS); + } + const char* const* rhsIt = std::find_if( cm::cbegin(CXX_STANDARDS), cm::cend(CXX_STANDARDS), cmStrCmp(rhs)); @@ -4901,27 +4928,6 @@ bool cmMakefile::AddRequiredTargetCxxFeature(cmTarget* target, } } - const char* existingCudaStandard = target->GetProperty("CUDA_STANDARD"); - const char* const* existingCudaLevel = nullptr; - if (existingCudaStandard) { - existingCudaLevel = - std::find_if(cm::cbegin(CXX_STANDARDS), cm::cend(CXX_STANDARDS), - cmStrCmp(existingCudaStandard)); - if (existingCudaLevel == cm::cend(CXX_STANDARDS)) { - std::ostringstream e; - e << "The CUDA_STANDARD property on target \"" << target->GetName() - << "\" contained an invalid value: \"" << existingCudaStandard - << "\"."; - if (error) { - *error = e.str(); - } else { - this->GetCMakeInstance()->IssueMessage(MessageType::FATAL_ERROR, - e.str(), this->Backtrace); - } - return false; - } - } - /* clang-format off */ const char* const* needCxxLevel = needCxx20 ? &CXX_STANDARDS[4] @@ -4938,11 +4944,164 @@ bool cmMakefile::AddRequiredTargetCxxFeature(cmTarget* target, if (!existingCxxLevel || existingCxxLevel < needCxxLevel) { target->SetProperty(cmStrCat(lang, "_STANDARD"), *needCxxLevel); } + } + return true; +} + +bool cmMakefile::HaveCudaStandardAvailable(cmTarget const* target, + const std::string& feature, + std::string const& lang) const +{ + const char* defaultCudaStandard = + this->GetDefinition(cmStrCat("CMAKE_", lang, "_STANDARD_DEFAULT")); + if (!defaultCudaStandard) { + this->IssueMessage( + MessageType::INTERNAL_ERROR, + cmStrCat("CMAKE_", lang, + "_STANDARD_DEFAULT is not set. COMPILE_FEATURES support " + "not fully configured for this compiler.")); + // Return true so the caller does not try to lookup the default standard. + return true; + } + if (std::find_if(cm::cbegin(CUDA_STANDARDS), cm::cend(CUDA_STANDARDS), + cmStrCmp(defaultCudaStandard)) == + cm::cend(CUDA_STANDARDS)) { + const std::string e = + cmStrCat("The CMAKE_", lang, "_STANDARD_DEFAULT variable contains an ", + "invalid value: \"", defaultCudaStandard, "\"."); + this->IssueMessage(MessageType::INTERNAL_ERROR, e); + return false; + } + + bool needCuda03 = false; + bool needCuda11 = false; + bool needCuda14 = false; + bool needCuda17 = false; + bool needCuda20 = false; + this->CheckNeededCudaLanguage(feature, lang, needCuda03, needCuda11, + needCuda14, needCuda17, needCuda20); + + const char* existingCudaStandard = + target->GetProperty(cmStrCat(lang, "_STANDARD")); + if (!existingCudaStandard) { + existingCudaStandard = defaultCudaStandard; + } + + const char* const* existingCudaLevel = + std::find_if(cm::cbegin(CUDA_STANDARDS), cm::cend(CUDA_STANDARDS), + cmStrCmp(existingCudaStandard)); + if (existingCudaLevel == cm::cend(CUDA_STANDARDS)) { + const std::string e = cmStrCat( + "The ", lang, "_STANDARD property on target \"", target->GetName(), + "\" contained an invalid value: \"", existingCudaStandard, "\"."); + this->IssueMessage(MessageType::FATAL_ERROR, e); + return false; + } + + /* clang-format off */ + const char* const* needCudaLevel = + needCuda20 ? &CUDA_STANDARDS[4] + : needCuda17 ? &CUDA_STANDARDS[3] + : needCuda14 ? &CUDA_STANDARDS[2] + : needCuda11 ? &CUDA_STANDARDS[1] + : needCuda03 ? &CUDA_STANDARDS[0] + : nullptr; + /* clang-format on */ + + return !needCudaLevel || needCudaLevel <= existingCudaLevel; +} + +void cmMakefile::CheckNeededCudaLanguage(const std::string& feature, + std::string const& lang, + bool& needCuda03, bool& needCuda11, + bool& needCuda14, bool& needCuda17, + bool& needCuda20) const +{ + if (const char* propCuda03 = + this->GetDefinition(cmStrCat("CMAKE_", lang, "03_COMPILE_FEATURES"))) { + std::vector props = cmExpandedList(propCuda03); + needCuda03 = cmContains(props, feature); + } + if (const char* propCuda11 = + this->GetDefinition(cmStrCat("CMAKE_", lang, "11_COMPILE_FEATURES"))) { + std::vector props = cmExpandedList(propCuda11); + needCuda11 = cmContains(props, feature); + } + if (const char* propCuda14 = + this->GetDefinition(cmStrCat("CMAKE_", lang, "14_COMPILE_FEATURES"))) { + std::vector props = cmExpandedList(propCuda14); + needCuda14 = cmContains(props, feature); + } + if (const char* propCuda17 = + this->GetDefinition(cmStrCat("CMAKE_", lang, "17_COMPILE_FEATURES"))) { + std::vector props = cmExpandedList(propCuda17); + needCuda17 = cmContains(props, feature); + } + if (const char* propCuda20 = + this->GetDefinition(cmStrCat("CMAKE_", lang, "20_COMPILE_FEATURES"))) { + std::vector props = cmExpandedList(propCuda20); + needCuda20 = cmContains(props, feature); + } +} + +bool cmMakefile::AddRequiredTargetCudaFeature(cmTarget* target, + const std::string& feature, + std::string const& lang, + std::string* error) const +{ + bool needCuda03 = false; + bool needCuda11 = false; + bool needCuda14 = false; + bool needCuda17 = false; + bool needCuda20 = false; + + this->CheckNeededCudaLanguage(feature, lang, needCuda03, needCuda11, + needCuda14, needCuda17, needCuda20); + + const char* existingCudaStandard = + target->GetProperty(cmStrCat(lang, "_STANDARD")); + if (existingCudaStandard == nullptr) { + const char* defaultCudaStandard = + this->GetDefinition(cmStrCat("CMAKE_", lang, "_STANDARD_DEFAULT")); + if (defaultCudaStandard && *defaultCudaStandard) { + existingCudaStandard = defaultCudaStandard; + } + } + const char* const* existingCudaLevel = nullptr; + if (existingCudaStandard) { + existingCudaLevel = + std::find_if(cm::cbegin(CUDA_STANDARDS), cm::cend(CUDA_STANDARDS), + cmStrCmp(existingCudaStandard)); + if (existingCudaLevel == cm::cend(CUDA_STANDARDS)) { + const std::string e = cmStrCat( + "The ", lang, "_STANDARD property on target \"", target->GetName(), + "\" contained an invalid value: \"", existingCudaStandard, "\"."); + if (error) { + *error = e; + } else { + this->GetCMakeInstance()->IssueMessage(MessageType::FATAL_ERROR, e, + this->Backtrace); + } + return false; + } + } + + /* clang-format off */ + const char* const* needCudaLevel = + needCuda20 ? &CUDA_STANDARDS[4] + : needCuda17 ? &CUDA_STANDARDS[3] + : needCuda14 ? &CUDA_STANDARDS[2] + : needCuda11 ? &CUDA_STANDARDS[1] + : needCuda03 ? &CUDA_STANDARDS[0] + : nullptr; + /* clang-format on */ + + if (needCudaLevel) { // Ensure the CUDA language level is high enough to support - // the needed C++ features. - if (!existingCudaLevel || existingCudaLevel < needCxxLevel) { - target->SetProperty("CUDA_STANDARD", *needCxxLevel); + // the needed CUDA features. + if (!existingCudaLevel || existingCudaLevel < needCudaLevel) { + target->SetProperty("CUDA_STANDARD", *needCudaLevel); } } diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h index d0dceb95e1..672244ec0f 100644 --- a/Source/cmMakefile.h +++ b/Source/cmMakefile.h @@ -1138,11 +1138,14 @@ private: bool AddRequiredTargetCFeature(cmTarget* target, const std::string& feature, std::string const& lang, std::string* error = nullptr) const; - bool AddRequiredTargetCxxFeature(cmTarget* target, const std::string& feature, std::string const& lang, std::string* error = nullptr) const; + bool AddRequiredTargetCudaFeature(cmTarget* target, + const std::string& feature, + std::string const& lang, + std::string* error = nullptr) const; void CheckNeededCLanguage(const std::string& feature, std::string const& lang, bool& needC90, @@ -1151,6 +1154,10 @@ private: std::string const& lang, bool& needCxx98, bool& needCxx11, bool& needCxx14, bool& needCxx17, bool& needCxx20) const; + void CheckNeededCudaLanguage(const std::string& feature, + std::string const& lang, bool& needCuda03, + bool& needCuda11, bool& needCuda14, + bool& needCuda17, bool& needCuda20) const; bool HaveCStandardAvailable(cmTarget const* target, const std::string& feature, @@ -1158,6 +1165,9 @@ private: bool HaveCxxStandardAvailable(cmTarget const* target, const std::string& feature, std::string const& lang) const; + bool HaveCudaStandardAvailable(cmTarget const* target, + const std::string& feature, + std::string const& lang) const; void CheckForUnusedVariables() const; diff --git a/Source/cmState.cxx b/Source/cmState.cxx index f9b5ed1c08..d337bd7a79 100644 --- a/Source/cmState.cxx +++ b/Source/cmState.cxx @@ -615,6 +615,9 @@ const char* cmState::GetGlobalProperty(const std::string& prop) if (prop == "CMAKE_CXX14_KNOWN_FEATURES") { return &FOR_EACH_CXX14_FEATURE(STRING_LIST_ELEMENT)[1]; } + if (prop == "CMAKE_CUDA_KNOWN_FEATURES") { + return &FOR_EACH_CUDA_FEATURE(STRING_LIST_ELEMENT)[1]; + } #undef STRING_LIST_ELEMENT return this->GlobalProperties.GetPropertyValue(prop); diff --git a/Source/cmake.h b/Source/cmake.h index 9e78436ff7..02de4c1af9 100644 --- a/Source/cmake.h +++ b/Source/cmake.h @@ -746,4 +746,11 @@ private: FOR_EACH_CXX11_FEATURE(F) \ FOR_EACH_CXX14_FEATURE(F) +#define FOR_EACH_CUDA_FEATURE(F) \ + F(cuda_std_03) \ + F(cuda_std_11) \ + F(cuda_std_14) \ + F(cuda_std_17) \ + F(cuda_std_20) + #endif diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index 0d9e43f633..2c8340cd64 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -436,7 +436,9 @@ if(BUILD_TESTING) ADD_TEST_MACRO(Assembler HelloAsm) ADD_TEST_MACRO(SourceGroups SourceGroups) ADD_TEST_MACRO(Preprocess Preprocess) - set(ExportImport_BUILD_OPTIONS -DCMake_TEST_NESTED_MAKE_PROGRAM:FILEPATH=${CMake_TEST_EXPLICIT_MAKE_PROGRAM}) + set(ExportImport_BUILD_OPTIONS -DCMake_TEST_NESTED_MAKE_PROGRAM:FILEPATH=${CMake_TEST_EXPLICIT_MAKE_PROGRAM} + -DCMake_TEST_CUDA:BOOL=${CMake_TEST_CUDA} + ) ADD_TEST_MACRO(ExportImport ExportImport) ADD_TEST_MACRO(Unset Unset) ADD_TEST_MACRO(PolicyScope PolicyScope) diff --git a/Tests/Cuda/CMakeLists.txt b/Tests/Cuda/CMakeLists.txt index a30071fd3a..3b6a6110b5 100644 --- a/Tests/Cuda/CMakeLists.txt +++ b/Tests/Cuda/CMakeLists.txt @@ -1,8 +1,13 @@ ADD_TEST_MACRO(Cuda.Complex CudaComplex) ADD_TEST_MACRO(Cuda.ConsumeCompileFeatures CudaConsumeCompileFeatures) +ADD_TEST_MACRO(Cuda.CXXStandardSetTwice CXXStandardSetTwice) ADD_TEST_MACRO(Cuda.ObjectLibrary CudaObjectLibrary) -ADD_TEST_MACRO(Cuda.MixedStandardLevels MixedStandardLevels) +ADD_TEST_MACRO(Cuda.MixedStandardLevels1 MixedStandardLevels1) +ADD_TEST_MACRO(Cuda.MixedStandardLevels2 MixedStandardLevels2) +ADD_TEST_MACRO(Cuda.MixedStandardLevels3 MixedStandardLevels3) +ADD_TEST_MACRO(Cuda.MixedStandardLevels4 MixedStandardLevels4) +ADD_TEST_MACRO(Cuda.MixedStandardLevels5 MixedStandardLevels5) ADD_TEST_MACRO(Cuda.NotEnabled CudaNotEnabled) ADD_TEST_MACRO(Cuda.ToolkitInclude CudaToolkitInclude) ADD_TEST_MACRO(Cuda.ProperDeviceLibraries ProperDeviceLibraries) diff --git a/Tests/Cuda/MixedStandardLevels/CMakeLists.txt b/Tests/Cuda/CXXStandardSetTwice/CMakeLists.txt similarity index 57% rename from Tests/Cuda/MixedStandardLevels/CMakeLists.txt rename to Tests/Cuda/CXXStandardSetTwice/CMakeLists.txt index b399662a76..1941c49526 100644 --- a/Tests/Cuda/MixedStandardLevels/CMakeLists.txt +++ b/Tests/Cuda/CXXStandardSetTwice/CMakeLists.txt @@ -1,14 +1,14 @@ cmake_minimum_required(VERSION 3.7) -project(MixedStandardLevels CXX CUDA) +project(CXXStandardSetTwice CXX CUDA) string(APPEND CMAKE_CUDA_FLAGS " -gencode arch=compute_30,code=compute_30") set(CMAKE_CXX_STANDARD 11) -add_executable(MixedStandardLevels main.cu) -target_compile_features(MixedStandardLevels PUBLIC cxx_std_11) +add_executable(CXXStandardSetTwice main.cu) +target_compile_features(CXXStandardSetTwice PUBLIC cxx_std_11) if(APPLE) # Help the static cuda runtime find the driver (libcuda.dyllib) at runtime. - set_property(TARGET MixedStandardLevels PROPERTY BUILD_RPATH ${CMAKE_CUDA_IMPLICIT_LINK_DIRECTORIES}) + set_property(TARGET CXXStandardSetTwice PROPERTY BUILD_RPATH ${CMAKE_CUDA_IMPLICIT_LINK_DIRECTORIES}) endif() diff --git a/Tests/Cuda/MixedStandardLevels/main.cu b/Tests/Cuda/CXXStandardSetTwice/main.cu similarity index 100% rename from Tests/Cuda/MixedStandardLevels/main.cu rename to Tests/Cuda/CXXStandardSetTwice/main.cu diff --git a/Tests/Cuda/MixedStandardLevels1/CMakeLists.txt b/Tests/Cuda/MixedStandardLevels1/CMakeLists.txt new file mode 100644 index 0000000000..b03e51e3e2 --- /dev/null +++ b/Tests/Cuda/MixedStandardLevels1/CMakeLists.txt @@ -0,0 +1,14 @@ +cmake_minimum_required(VERSION 3.7) +project(MixedStandardLevels1 CXX CUDA) + +string(APPEND CMAKE_CUDA_FLAGS " -gencode arch=compute_30,code=compute_30") + +set(CMAKE_CXX_STANDARD 14) +set(CMAKE_CUDA_STANDARD 11) + +add_executable(MixedStandardLevels1 main.cu lib.cpp) + +if(APPLE) + # Help the static cuda runtime find the driver (libcuda.dyllib) at runtime. + set_property(TARGET MixedStandardLevels1 PROPERTY BUILD_RPATH ${CMAKE_CUDA_IMPLICIT_LINK_DIRECTORIES}) +endif() diff --git a/Tests/Cuda/MixedStandardLevels1/lib.cpp b/Tests/Cuda/MixedStandardLevels1/lib.cpp new file mode 100644 index 0000000000..cabbacb085 --- /dev/null +++ b/Tests/Cuda/MixedStandardLevels1/lib.cpp @@ -0,0 +1,7 @@ + +int func(int A, int B) +{ + // Verify that we have at least c++14 + auto mult_func = [](auto a, auto b) { return a * b; }; + return mult_func(A, B); +} diff --git a/Tests/Cuda/MixedStandardLevels1/main.cu b/Tests/Cuda/MixedStandardLevels1/main.cu new file mode 100644 index 0000000000..bc02c6d10d --- /dev/null +++ b/Tests/Cuda/MixedStandardLevels1/main.cu @@ -0,0 +1,9 @@ + +#include + +int main(int argc, char** argv) +{ + // Verify that we have at least c++11 + using returnv = std::integral_constant; + return returnv::value; +} diff --git a/Tests/Cuda/MixedStandardLevels2/CMakeLists.txt b/Tests/Cuda/MixedStandardLevels2/CMakeLists.txt new file mode 100644 index 0000000000..12dd3285f5 --- /dev/null +++ b/Tests/Cuda/MixedStandardLevels2/CMakeLists.txt @@ -0,0 +1,14 @@ +cmake_minimum_required(VERSION 3.7) +project(MixedStandardLevels2 CXX CUDA) + +string(APPEND CMAKE_CUDA_FLAGS " -gencode arch=compute_30,code=compute_30") + +set(CMAKE_CXX_STANDARD 17) #this can decay + +add_executable(MixedStandardLevels2 main.cu lib.cpp) +target_compile_features(MixedStandardLevels2 PUBLIC cuda_std_11) + +if(APPLE) + # Help the static cuda runtime find the driver (libcuda.dyllib) at runtime. + set_property(TARGET MixedStandardLevels2 PROPERTY BUILD_RPATH ${CMAKE_CUDA_IMPLICIT_LINK_DIRECTORIES}) +endif() diff --git a/Tests/Cuda/MixedStandardLevels2/lib.cpp b/Tests/Cuda/MixedStandardLevels2/lib.cpp new file mode 100644 index 0000000000..cabbacb085 --- /dev/null +++ b/Tests/Cuda/MixedStandardLevels2/lib.cpp @@ -0,0 +1,7 @@ + +int func(int A, int B) +{ + // Verify that we have at least c++14 + auto mult_func = [](auto a, auto b) { return a * b; }; + return mult_func(A, B); +} diff --git a/Tests/Cuda/MixedStandardLevels2/main.cu b/Tests/Cuda/MixedStandardLevels2/main.cu new file mode 100644 index 0000000000..a97a41ebd4 --- /dev/null +++ b/Tests/Cuda/MixedStandardLevels2/main.cu @@ -0,0 +1,11 @@ + +#if __cplusplus < 201103L && !defined(_MSC_VER) +# error "invalid standard value" +#endif +#include + +int main(int argc, char** argv) +{ + using returnv = std::integral_constant; + return returnv::value; +} diff --git a/Tests/Cuda/MixedStandardLevels3/CMakeLists.txt b/Tests/Cuda/MixedStandardLevels3/CMakeLists.txt new file mode 100644 index 0000000000..2b611be8e1 --- /dev/null +++ b/Tests/Cuda/MixedStandardLevels3/CMakeLists.txt @@ -0,0 +1,12 @@ +cmake_minimum_required(VERSION 3.7) +project(MixedStandardLevels3 CXX CUDA) + +string(APPEND CMAKE_CUDA_FLAGS " -gencode arch=compute_30,code=compute_30") + +add_executable(MixedStandardLevels3 main.cu lib.cpp) +target_compile_features(MixedStandardLevels3 PUBLIC cuda_std_03 cxx_std_14) + +if(APPLE) + # Help the static cuda runtime find the driver (libcuda.dyllib) at runtime. + set_property(TARGET MixedStandardLevels3 PROPERTY BUILD_RPATH ${CMAKE_CUDA_IMPLICIT_LINK_DIRECTORIES}) +endif() diff --git a/Tests/Cuda/MixedStandardLevels3/lib.cpp b/Tests/Cuda/MixedStandardLevels3/lib.cpp new file mode 100644 index 0000000000..cabbacb085 --- /dev/null +++ b/Tests/Cuda/MixedStandardLevels3/lib.cpp @@ -0,0 +1,7 @@ + +int func(int A, int B) +{ + // Verify that we have at least c++14 + auto mult_func = [](auto a, auto b) { return a * b; }; + return mult_func(A, B); +} diff --git a/Tests/Cuda/MixedStandardLevels3/main.cu b/Tests/Cuda/MixedStandardLevels3/main.cu new file mode 100644 index 0000000000..1c19e8dc31 --- /dev/null +++ b/Tests/Cuda/MixedStandardLevels3/main.cu @@ -0,0 +1,5 @@ + +int main(int argc, char** argv) +{ + return 0; +} diff --git a/Tests/Cuda/MixedStandardLevels4/CMakeLists.txt b/Tests/Cuda/MixedStandardLevels4/CMakeLists.txt new file mode 100644 index 0000000000..faf68692fe --- /dev/null +++ b/Tests/Cuda/MixedStandardLevels4/CMakeLists.txt @@ -0,0 +1,14 @@ +cmake_minimum_required(VERSION 3.7) +project(MixedStandardLevels4 CXX CUDA) + +string(APPEND CMAKE_CUDA_FLAGS " -gencode arch=compute_30,code=compute_30") + +set(CMAKE_CUDA_STANDARD 03) + +add_executable(MixedStandardLevels4 main.cu lib.cpp) +target_compile_features(MixedStandardLevels4 PUBLIC cxx_std_14) + +if(APPLE) + # Help the static cuda runtime find the driver (libcuda.dyllib) at runtime. + set_property(TARGET MixedStandardLevels4 PROPERTY BUILD_RPATH ${CMAKE_CUDA_IMPLICIT_LINK_DIRECTORIES}) +endif() diff --git a/Tests/Cuda/MixedStandardLevels4/lib.cpp b/Tests/Cuda/MixedStandardLevels4/lib.cpp new file mode 100644 index 0000000000..ef6fc20056 --- /dev/null +++ b/Tests/Cuda/MixedStandardLevels4/lib.cpp @@ -0,0 +1,16 @@ + + +constexpr int func(int A, int B) +{ +#if defined(_MSC_VER) && _MSC_VER < 1913 + // no suppport for extended constexpr + return B * A; +#else + // Verify that we have at least c++14 + if (A < B) { + return A + B; + } else { + return B * A; + } +#endif +} diff --git a/Tests/Cuda/MixedStandardLevels4/main.cu b/Tests/Cuda/MixedStandardLevels4/main.cu new file mode 100644 index 0000000000..1c19e8dc31 --- /dev/null +++ b/Tests/Cuda/MixedStandardLevels4/main.cu @@ -0,0 +1,5 @@ + +int main(int argc, char** argv) +{ + return 0; +} diff --git a/Tests/Cuda/MixedStandardLevels5/CMakeLists.txt b/Tests/Cuda/MixedStandardLevels5/CMakeLists.txt new file mode 100644 index 0000000000..7209f60857 --- /dev/null +++ b/Tests/Cuda/MixedStandardLevels5/CMakeLists.txt @@ -0,0 +1,13 @@ +cmake_minimum_required(VERSION 3.7) +project(MixedStandardLevels5 CXX CUDA) + +string(APPEND CMAKE_CUDA_FLAGS " -gencode arch=compute_30,code=compute_30") + +set(CMAKE_CXX_STANDARD 98) + +add_executable(MixedStandardLevels5 main.cu lib.cpp) + +if(APPLE) + # Help the static cuda runtime find the driver (libcuda.dyllib) at runtime. + set_property(TARGET MixedStandardLevels5 PROPERTY BUILD_RPATH ${CMAKE_CUDA_IMPLICIT_LINK_DIRECTORIES}) +endif() diff --git a/Tests/Cuda/MixedStandardLevels5/lib.cpp b/Tests/Cuda/MixedStandardLevels5/lib.cpp new file mode 100644 index 0000000000..dd7b31bb55 --- /dev/null +++ b/Tests/Cuda/MixedStandardLevels5/lib.cpp @@ -0,0 +1,13 @@ + +#if __cplusplus >= 201103L +# error "invalid standard value" +#endif +int func(int A, int B) +{ + // Verify that we have at least c++14 + if (A < B) { + return A + B; + } else { + return B * A; + } +} diff --git a/Tests/Cuda/MixedStandardLevels5/main.cu b/Tests/Cuda/MixedStandardLevels5/main.cu new file mode 100644 index 0000000000..c79afd6094 --- /dev/null +++ b/Tests/Cuda/MixedStandardLevels5/main.cu @@ -0,0 +1,8 @@ + +#if __cplusplus >= 201103L +# error "invalid standard value" +#endif +int main(int argc, char** argv) +{ + return 0; +} diff --git a/Tests/CudaOnly/CMakeLists.txt b/Tests/CudaOnly/CMakeLists.txt index f1fd344871..0dd33093a5 100644 --- a/Tests/CudaOnly/CMakeLists.txt +++ b/Tests/CudaOnly/CMakeLists.txt @@ -5,6 +5,7 @@ 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.Standard98 CudaOnlyStandard98) ADD_TEST_MACRO(CudaOnly.WithDefs CudaOnlyWithDefs) add_test(NAME CudaOnly.DontResolveDeviceSymbols COMMAND diff --git a/Tests/CudaOnly/EnableStandard/CMakeLists.txt b/Tests/CudaOnly/EnableStandard/CMakeLists.txt index 54e2c14132..dfcb8da41b 100644 --- a/Tests/CudaOnly/EnableStandard/CMakeLists.txt +++ b/Tests/CudaOnly/EnableStandard/CMakeLists.txt @@ -11,8 +11,9 @@ add_library(CUDADynamic11 SHARED shared.cu) add_executable(CudaOnlyEnableStandard main.cu) target_link_libraries(CudaOnlyEnableStandard PRIVATE CUDAStatic11 CUDADynamic11) -set_target_properties(CUDAStatic11 CUDADynamic11 PROPERTIES CUDA_STANDARD 11) -set_target_properties(CUDAStatic11 CUDADynamic11 PROPERTIES CUDA_STANDARD_REQUIRED TRUE) +target_compile_features(CUDADynamic11 PRIVATE cuda_std_11) +set_target_properties(CUDAStatic11 PROPERTIES CUDA_STANDARD 11) +set_target_properties(CUDAStatic11 PROPERTIES CUDA_STANDARD_REQUIRED TRUE) #Verify CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES foreach(dir ${CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES}) diff --git a/Tests/CudaOnly/ResolveDeviceSymbols/CMakeLists.txt b/Tests/CudaOnly/ResolveDeviceSymbols/CMakeLists.txt index 64845c5ce9..57aa0b9e82 100644 --- a/Tests/CudaOnly/ResolveDeviceSymbols/CMakeLists.txt +++ b/Tests/CudaOnly/ResolveDeviceSymbols/CMakeLists.txt @@ -22,11 +22,11 @@ endif() # 3. Verify that we can't use those device symbols from anything that links # to the static library string(APPEND CMAKE_CUDA_FLAGS " -gencode arch=compute_30,code=[sm_30] -gencode arch=compute_50,code=\\\"compute_50\\\"") -set(CMAKE_CXX_STANDARD 11) -set(CMAKE_CUDA_STANDARD 11) add_library(CUDAResolveDeviceDepsA STATIC file1.cu) add_library(CUDAResolveDeviceDepsB STATIC file2.cu) +target_compile_features(CUDAResolveDeviceDepsA PUBLIC cuda_std_11) +target_compile_features(CUDAResolveDeviceDepsB PUBLIC cuda_std_11) set_target_properties(CUDAResolveDeviceDepsA CUDAResolveDeviceDepsB PROPERTIES CUDA_SEPARABLE_COMPILATION ON diff --git a/Tests/CudaOnly/SeparateCompilation/CMakeLists.txt b/Tests/CudaOnly/SeparateCompilation/CMakeLists.txt index 1e574d6cce..c1bd64aacb 100644 --- a/Tests/CudaOnly/SeparateCompilation/CMakeLists.txt +++ b/Tests/CudaOnly/SeparateCompilation/CMakeLists.txt @@ -11,11 +11,10 @@ project (SeparateCompilation CUDA) #all containing cuda separable compilation code links properly string(APPEND CMAKE_CUDA_FLAGS " -gencode arch=compute_30,code=\\\"compute_30,sm_30,sm_35\\\"") string(APPEND CMAKE_CUDA_FLAGS " --generate-code=arch=compute_50,code=[compute_50,sm_50,sm_52]") -set(CMAKE_CXX_STANDARD 11) -set(CMAKE_CUDA_STANDARD 11) set(CMAKE_CUDA_SEPARABLE_COMPILATION ON) add_library(CUDASeparateLibA STATIC file1.cu file2.cu file3.cu) +target_compile_features(CUDASeparateLibA PRIVATE cuda_std_11) get_property(sep_comp TARGET CUDASeparateLibA PROPERTY CUDA_SEPARABLE_COMPILATION) if(NOT sep_comp) message(FATAL_ERROR "CUDA_SEPARABLE_COMPILATION not initialized") @@ -36,11 +35,14 @@ endif() #cause a segv when trying to run the executable # add_library(CUDASeparateLibB STATIC file4.cu file5.cu) +target_compile_features(CUDASeparateLibB PRIVATE cuda_std_11) target_link_libraries(CUDASeparateLibB PRIVATE CUDASeparateLibA) add_executable(CudaOnlySeparateCompilation main.cu) target_link_libraries(CudaOnlySeparateCompilation PRIVATE CUDASeparateLibB) +set_target_properties(CudaOnlySeparateCompilation PROPERTIES CUDA_STANDARD 11) +set_target_properties(CudaOnlySeparateCompilation PROPERTIES CUDA_STANDARD_REQUIRED TRUE) set_target_properties(CUDASeparateLibA CUDASeparateLibB diff --git a/Tests/CudaOnly/Standard98/CMakeLists.txt b/Tests/CudaOnly/Standard98/CMakeLists.txt new file mode 100644 index 0000000000..ef9a68536d --- /dev/null +++ b/Tests/CudaOnly/Standard98/CMakeLists.txt @@ -0,0 +1,15 @@ +cmake_minimum_required(VERSION 3.7) +project(CudaOnlyStandard98 CUDA) + +string(APPEND CMAKE_CUDA_FLAGS " -gencode arch=compute_30,code=compute_30") + +# Support setting CUDA Standard to 98 which internally gets transformed to +# CUDA03 +set(CMAKE_CUDA_STANDARD 98) + +add_executable(CudaOnlyStandard98 main.cu) + +if(APPLE) + # Help the static cuda runtime find the driver (libcuda.dyllib) at runtime. + set_property(TARGET CudaOnlyStandard98 PROPERTY BUILD_RPATH ${CMAKE_CUDA_IMPLICIT_LINK_DIRECTORIES}) +endif() diff --git a/Tests/CudaOnly/Standard98/main.cu b/Tests/CudaOnly/Standard98/main.cu new file mode 100644 index 0000000000..c79afd6094 --- /dev/null +++ b/Tests/CudaOnly/Standard98/main.cu @@ -0,0 +1,8 @@ + +#if __cplusplus >= 201103L +# error "invalid standard value" +#endif +int main(int argc, char** argv) +{ + return 0; +} diff --git a/Tests/ExportImport/Export/CMakeLists.txt b/Tests/ExportImport/Export/CMakeLists.txt index 9d8a248524..4d411a9419 100644 --- a/Tests/ExportImport/Export/CMakeLists.txt +++ b/Tests/ExportImport/Export/CMakeLists.txt @@ -646,6 +646,18 @@ if(CMAKE_GENERATOR MATCHES "Make|Ninja") export(TARGETS testLinkDepends NAMESPACE bld_ APPEND FILE ExportBuildTree.cmake) endif() +#------------------------------------------------------------------------------ +# test export of CUDA language +if(CMake_TEST_CUDA) + enable_language(CUDA) + add_library(cudaInterfaceLib INTERFACE) + target_compile_features(cudaInterfaceLib INTERFACE $ $) + + install(TARGETS cudaInterfaceLib + EXPORT RequiredExp DESTINATION lib) + export(TARGETS cudaInterfaceLib NAMESPACE bld_ APPEND FILE ExportBuildTree.cmake) +endif() + # Test the presence of targets named the same as languages. # IMPORTED_LINK_INTERFACE_LANGUAGES entries should not be targets. add_library(C INTERFACE) diff --git a/Tests/ExportImport/Import/A/CMakeLists.txt b/Tests/ExportImport/Import/A/CMakeLists.txt index b5df961689..c5304da5a6 100644 --- a/Tests/ExportImport/Import/A/CMakeLists.txt +++ b/Tests/ExportImport/Import/A/CMakeLists.txt @@ -499,3 +499,10 @@ if(CMAKE_GENERATOR MATCHES "Make|Ninja") checkForProperty(bld_testLinkDepends "INTERFACE_LINK_DEPENDS" "BUILD_LINK_DEPENDS") checkForProperty(Req::testLinkDepends "INTERFACE_LINK_DEPENDS" "${CMAKE_INSTALL_PREFIX}/INSTALL_LINK_DEPENDS") endif() + +#------------------------------------------------------------------------------ +# test import of CUDA language level +if(CMake_TEST_CUDA) + checkForProperty(bld_cudaInterfaceLib "INTERFACE_COMPILE_FEATURES" "cuda_std_11") + checkForProperty(Req::cudaInterfaceLib "INTERFACE_COMPILE_FEATURES" "cuda_std_14") +endif() diff --git a/Tests/ExportImport/InitialCache.cmake.in b/Tests/ExportImport/InitialCache.cmake.in index f600d90e7e..44cd1799df 100644 --- a/Tests/ExportImport/InitialCache.cmake.in +++ b/Tests/ExportImport/InitialCache.cmake.in @@ -14,3 +14,4 @@ set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "@CMAKE_CXX_FLAGS_RELWITHDEBINFO@" CACHE STRI set(CMAKE_INSTALL_PREFIX "@ExportImport_BINARY_DIR@/Root" CACHE STRING "Installation Prefix") set(CMAKE_SKIP_RPATH ON CACHE BOOL "No RPATH") set(CMAKE_GNUtoMS "@ExportImport_GNUtoMS@" CACHE BOOL "CMAKE_GNUtoMS") +set(CMake_TEST_CUDA "@CMake_TEST_CUDA@" CACHE BOOL "CMake_TEST_CUDA") diff --git a/Tests/RunCMake/try_compile/RunCMakeTest.cmake b/Tests/RunCMake/try_compile/RunCMakeTest.cmake index 91f014e4d2..e838b2debe 100644 --- a/Tests/RunCMake/try_compile/RunCMakeTest.cmake +++ b/Tests/RunCMake/try_compile/RunCMakeTest.cmake @@ -49,11 +49,7 @@ if(CMAKE_OBJCXX_STANDARD_DEFAULT) run_cmake(ObjCxxStandard) endif() if(CMake_TEST_CUDA) - if(CMAKE_HOST_WIN32) - run_cmake(CudaStandardNoDefault) - else() - run_cmake(CudaStandard) - endif() + run_cmake(CudaStandard) endif() if(CMAKE_C_COMPILER_ID STREQUAL "GNU" AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.4) run_cmake(CStandardGNU)