Spaces:
Runtime error
Runtime error
| # This file provides utilities for building and working with CUB | |
| # configuration targets. | |
| # | |
| # CUB_TARGETS | |
| # - Built by the calling the `cub_build_target_list()` function. | |
| # - Each item is the name of a CUB interface target that is configured for a | |
| # certain build configuration. Currently only C++ standard dialect is | |
| # considered. | |
| # | |
| # cub_build_target_list() | |
| # - Creates the CUB_TARGETS list. | |
| # | |
| # The following functions can be used to test/set metadata on a CUB target: | |
| # | |
| # cub_get_target_property(<prop_var> <target_name> <prop>) | |
| # - Checks the ${prop} target property on CUB target ${target_name} | |
| # and sets the ${prop_var} variable in the caller's scope. | |
| # - <prop_var> is any valid cmake identifier. | |
| # - <target_name> is the name of a CUB target. | |
| # - <prop> is one of the following: | |
| # - DIALECT: The C++ dialect. Valid values: 11, 14, 17. | |
| # - PREFIX: A unique prefix that should be used to name all | |
| # targets/tests/examples that use this configuration. | |
| # | |
| # cub_get_target_properties(<target_name>) | |
| # - Defines ${target_name}_${prop} in the caller's scope, for `prop` in: | |
| # {DIALECT, PREFIX}. See above for details. | |
| # | |
| # cub_clone_target_properties(<dst_target> <src_target>) | |
| # - Set the {DIALECT, PREFIX} metadata on ${dst_target} to match | |
| # ${src_target}. See above for details. | |
| # - This *MUST* be called on any targets that link to another CUB target | |
| # to ensure that dialect information is updated correctly, e.g. | |
| # `cub_clone_target_properties(${my_cub_test} ${some_cub_target})` | |
| # Dialects: | |
| set(CUB_CPP_DIALECT_OPTIONS | |
| 11 14 17 | |
| CACHE INTERNAL "C++ dialects supported by CUB." FORCE | |
| ) | |
| define_property(TARGET PROPERTY _CUB_DIALECT | |
| BRIEF_DOCS "A target's C++ dialect: 11, 14, or 17." | |
| FULL_DOCS "A target's C++ dialect: 11, 14, or 17." | |
| ) | |
| define_property(TARGET PROPERTY _CUB_PREFIX | |
| BRIEF_DOCS "A prefix describing the config, eg. 'cub.cpp14'." | |
| FULL_DOCS "A prefix describing the config, eg. 'cub.cpp14'." | |
| ) | |
| function(cub_set_target_properties target_name dialect prefix) | |
| set_target_properties(${target_name} | |
| PROPERTIES | |
| _CUB_DIALECT ${dialect} | |
| _CUB_PREFIX ${prefix} | |
| ) | |
| get_target_property(type ${target_name} TYPE) | |
| if (NOT ${type} STREQUAL "INTERFACE_LIBRARY") | |
| set_target_properties(${target_name} | |
| PROPERTIES | |
| CXX_STANDARD ${dialect} | |
| CUDA_STANDARD ${dialect} | |
| ARCHIVE_OUTPUT_DIRECTORY "${CUB_LIBRARY_OUTPUT_DIR}" | |
| LIBRARY_OUTPUT_DIRECTORY "${CUB_LIBRARY_OUTPUT_DIR}" | |
| RUNTIME_OUTPUT_DIRECTORY "${CUB_EXECUTABLE_OUTPUT_DIR}" | |
| ) | |
| # CMake still emits errors about empty CUDA_ARCHITECTURES when CMP0104 | |
| # is set to OLD. This suppresses the errors for good. | |
| if (CMAKE_VERSION VERSION_GREATER_EQUAL 3.18) | |
| set_target_properties(${target_name} | |
| PROPERTIES | |
| CUDA_ARCHITECTURES OFF | |
| ) | |
| endif() | |
| endif() | |
| endfunction() | |
| # Get a cub property from a target and store it in var_name | |
| # cub_get_target_property(<var_name> <target_name> [DIALECT|PREFIX] | |
| macro(cub_get_target_property prop_var target_name prop) | |
| get_property(${prop_var} TARGET ${target_name} PROPERTY _CUB_${prop}) | |
| endmacro() | |
| # Defines the following string variables in the caller's scope: | |
| # - ${target_name}_DIALECT | |
| # - ${target_name}_PREFIX | |
| macro(cub_get_target_properties target_name) | |
| cub_get_target_property(${target_name}_DIALECT ${target_name} DIALECT) | |
| cub_get_target_property(${target_name}_PREFIX ${target_name} PREFIX) | |
| endmacro() | |
| # Set one target's _CUB_* properties to match another target | |
| function(cub_clone_target_properties dst_target src_target) | |
| cub_get_target_properties(${src_target}) | |
| cub_set_target_properties(${dst_target} | |
| ${${src_target}_DIALECT} | |
| ${${src_target}_PREFIX} | |
| ) | |
| endfunction() | |
| # Set ${var_name} to TRUE or FALSE in the caller's scope | |
| function(_cub_is_config_valid var_name dialect) | |
| if (CUB_ENABLE_DIALECT_CPP${dialect}) | |
| set(${var_name} TRUE PARENT_SCOPE) | |
| else() | |
| set(${var_name} FALSE PARENT_SCOPE) | |
| endif() | |
| endfunction() | |
| function(_cub_init_target_list) | |
| set(CUB_TARGETS "" CACHE INTERNAL "" FORCE) | |
| endfunction() | |
| function(_cub_add_target_to_target_list target_name dialect prefix) | |
| cub_set_target_properties(${target_name} ${dialect} ${prefix}) | |
| target_link_libraries(${target_name} INTERFACE | |
| CUB::CUB | |
| cub.compiler_interface | |
| ) | |
| if (TARGET cub.thrust) | |
| target_link_libraries(${target_name} INTERFACE cub.thrust) | |
| endif() | |
| set(CUB_TARGETS ${CUB_TARGETS} ${target_name} CACHE INTERNAL "" FORCE) | |
| set(label "cpp${dialect}") | |
| string(TOLOWER "${label}" label) | |
| message(STATUS "Enabling CUB configuration: ${label}") | |
| endfunction() | |
| # Build a ${CUB_TARGETS} list containing target names for all | |
| # requested configurations | |
| function(cub_build_target_list) | |
| # Clear the list of targets: | |
| _cub_init_target_list() | |
| # Handle dialect options: | |
| foreach (dialect IN LISTS CUB_CPP_DIALECT_OPTIONS) | |
| if (CUB_IN_THRUST) | |
| # Just use Thrust's settings: | |
| if (THRUST_ENABLE_MULTICONFIG) | |
| set(CUB_ENABLE_DIALECT_CPP${dialect} | |
| ${THRUST_MULTICONFIG_ENABLE_DIALECT_CPP${dialect}} | |
| ) | |
| else() | |
| set(val OFF) | |
| if (dialect EQUAL ${THRUST_CPP_DIALECT}) | |
| set(val ON) | |
| endif() | |
| set(CUB_ENABLE_DIALECT_CPP${dialect} ${val}) | |
| endif() | |
| else() | |
| # Create CMake options: | |
| set(default_value OFF) | |
| if (dialect EQUAL 14) # Default to just 14 on: | |
| set(default_value ON) | |
| endif() | |
| option(CUB_ENABLE_DIALECT_CPP${dialect} | |
| "Generate C++${dialect} build configurations." | |
| ${default_value} | |
| ) | |
| endif() | |
| endforeach() | |
| # CMake added C++17 support for CUDA targets in 3.18: | |
| if (CUB_ENABLE_DIALECT_CPP17) | |
| cmake_minimum_required(VERSION 3.18) | |
| endif() | |
| # Supported versions of MSVC do not distinguish between C++11 and C++14. | |
| # Warn the user that they may be generating a ton of redundant targets. | |
| if ("MSVC" STREQUAL "${CMAKE_CXX_COMPILER_ID}" AND | |
| CUB_ENABLE_DIALECT_CPP11) | |
| message(WARNING | |
| "Supported versions of MSVC (2017+) do not distinguish between C++11 " | |
| "and C++14. The requested C++11 targets will be built with C++14." | |
| ) | |
| endif() | |
| # Generic config flags: | |
| macro(add_flag_option flag docstring default) | |
| set(cub_opt "CUB_${flag}") | |
| if (CUB_IN_THRUST) | |
| set(thrust_opt "THRUST_${flag}") | |
| # Use thrust's settings: | |
| set(${cub_opt} ${${thrust_opt}}) | |
| else() | |
| option(${cub_opt} "${docstring}" "${default}") | |
| mark_as_advanced(${cub_opt}) | |
| endif() | |
| endmacro() | |
| add_flag_option(IGNORE_DEPRECATED_CPP_DIALECT "Don't warn about any deprecated C++ standards and compilers." OFF) | |
| add_flag_option(IGNORE_DEPRECATED_CPP_11 "Don't warn about deprecated C++11." OFF) | |
| add_flag_option(IGNORE_DEPRECATED_COMPILER "Don't warn about deprecated compilers." OFF) | |
| # Build cub.compiler_interface with warning flags, etc | |
| # This must be called before _cub_add_target_to_target_list. | |
| cub_build_compiler_targets() | |
| # Set up the CUB target while testing out our find_package scripts. | |
| find_package(CUB REQUIRED CONFIG | |
| NO_DEFAULT_PATH # Only check the explicit path in HINTS: | |
| HINTS "${CUB_SOURCE_DIR}" | |
| ) | |
| # TODO | |
| # Some of the iterators and unittests depend on thrust. We should break the | |
| # cyclical dependency by migrating CUB's Thrust bits into Thrust. | |
| find_package(Thrust ${CUB_VERSION} EXACT CONFIG | |
| HINTS "../../" # Check if we are in thrust/dependencies/cub | |
| ) | |
| if (Thrust_FOUND) | |
| thrust_set_CUB_target(CUB::CUB) | |
| thrust_create_target(cub.thrust HOST CPP DEVICE CUDA) | |
| else() | |
| message(STATUS | |
| "Thrust was not found. Set CMake variable 'Thrust_DIR' to the " | |
| "thrust-config.cmake file of a Thrust ${CUB_VERSION} installation to " | |
| "enable additional testing." | |
| ) | |
| endif() | |
| # Build CUB_TARGETS | |
| foreach(dialect IN LISTS CUB_CPP_DIALECT_OPTIONS) | |
| _cub_is_config_valid(config_valid ${dialect}) | |
| if (config_valid) | |
| set(prefix "cub.cpp${dialect}") | |
| string(TOLOWER "${prefix}" prefix) | |
| set(target_name "${prefix}") | |
| add_library(${target_name} INTERFACE) | |
| # Set configuration metadata for this cub interface target: | |
| _cub_add_target_to_target_list(${target_name} ${dialect} ${prefix}) | |
| endif() | |
| endforeach() # dialects | |
| list(LENGTH CUB_TARGETS count) | |
| message(STATUS "${count} unique cub.dialect configurations generated") | |
| # Top level meta-target. Makes it easier to just build CUB targets when | |
| # building both CUB and Thrust. Add all project files here so IDEs will be | |
| # aware of them. This will not generate build rules. | |
| file(GLOB_RECURSE all_sources | |
| RELATIVE "${CMAKE_CURRENT_LIST_DIR}" | |
| "${CUB_SOURCE_DIR}/cub/*.cuh" | |
| ) | |
| add_custom_target(cub.all SOURCES ${all_sources}) | |
| # Create meta targets for each config: | |
| foreach(cub_target IN LISTS CUB_TARGETS) | |
| cub_get_target_property(config_prefix ${cub_target} PREFIX) | |
| add_custom_target(${config_prefix}.all) | |
| add_dependencies(cub.all ${config_prefix}.all) | |
| endforeach() | |
| endfunction() | |