diff --git a/libcudacxx/cmake/LibcudacxxInternalHeaderTesting.cmake b/libcudacxx/cmake/LibcudacxxInternalHeaderTesting.cmake index de5b77f67b1..4f626cb67e9 100644 --- a/libcudacxx/cmake/LibcudacxxInternalHeaderTesting.cmake +++ b/libcudacxx/cmake/LibcudacxxInternalHeaderTesting.cmake @@ -9,14 +9,6 @@ cccl_get_cudatoolkit() # Meta target for all configs' header builds: add_custom_target(libcudacxx.test.internal_headers) -# We need to handle atomic headers differently as they do not compile on architectures below sm70 -set(architectures_at_least_sm70) -foreach (item IN LISTS CMAKE_CUDA_ARCHITECTURES) - if (item GREATER_EQUAL 70) - list(APPEND architectures_at_least_sm70 ${item}) - endif() -endforeach() - # Grep all internal headers file( GLOB_RECURSE internal_headers @@ -39,94 +31,92 @@ list(FILTER internal_headers EXCLUDE REGEX "__cuda/*") # generated cuda::ptx headers are not standalone list(FILTER internal_headers EXCLUDE REGEX "__ptx/instructions/generated") -function(libcudacxx_create_internal_header_test header_name headertest_src) - # Create the default target for that file - add_library(internal_headertest_${header_name} SHARED "${headertest_src}.cu") - cccl_configure_target(internal_headertest_${header_name}) - target_compile_definitions( - internal_headertest_${header_name} - PRIVATE _CCCL_HEADER_TEST +function(libcudacxx_add_internal_header_test_target target_name) + if (NOT ARGN) + return() + endif() + + cccl_generate_header_tests( + ${target_name} + libcudacxx/include + NO_METATARGETS + LANGUAGE CUDA + HEADER_TEMPLATE "${libcudacxx_SOURCE_DIR}/cmake/header_test.cpp.in" + HEADERS ${ARGN} ) + + target_compile_definitions(${target_name} PRIVATE _CCCL_HEADER_TEST) target_link_libraries( - internal_headertest_${header_name} + ${target_name} PUBLIC # libcudacxx.compiler_interface CUDA::cudart ) - - # Ensure that if this is an atomic header, we only include the right architectures - string( - REGEX MATCH - "atomic|barrier|latch|semaphore|annotated_ptr|pipeline" - match - "${header}" - ) - if (match) - # Ensure that we only compile the header when we have some architectures enabled - if (NOT architectures_at_least_sm70) - return() - endif() - set_target_properties( - internal_headertest_${header_name} - PROPERTIES CUDA_ARCHITECTURES "${architectures_at_least_sm70}" - ) - endif() - - add_dependencies( - libcudacxx.test.internal_headers - internal_headertest_${header_name} - ) + add_dependencies(libcudacxx.test.internal_headers ${target_name}) endfunction() -# We have fallbacks for some type traits that we want to explicitly test so that they do not bitrot -function( - libcudacxx_create_internal_header_fallback_test - header_name - headertest_src +libcudacxx_add_internal_header_test_target( + libcudacxx.test.internal_headers.base + ${internal_headers} ) - # MSVC cannot handle some of the fallbacks + +# We have fallbacks for some type traits that we want to explicitly test so that they do not bitrot. +set(internal_headers_fallback) +set(internal_headers_fallback_per_header_defines) +foreach (header IN LISTS internal_headers) + # MSVC cannot handle some of the fallbacks. if ("MSVC" STREQUAL "${CMAKE_CXX_COMPILER_ID}") if ( "${header}" MATCHES "is_base_of" OR "${header}" MATCHES "is_nothrow_destructible" OR "${header}" MATCHES "is_polymorphic" ) - return() + continue() endif() endif() - # Search the file for a fallback definition - file(READ ${libcudacxx_SOURCE_DIR}/include/${header} header_file) + file(READ "${libcudacxx_SOURCE_DIR}/include/${header}" header_file) string(REGEX MATCH "_LIBCUDACXX_[A-Z_]*_FALLBACK" fallback "${header_file}") if (fallback) - # Adopt the filename for the fallback tests - set(header_name "${header_name}_fallback") - libcudacxx_create_internal_header_test(${header_name} ${headertest_src}) - target_compile_definitions( - internal_headertest_${header_name} - PRIVATE "-D${fallback}" + list(APPEND internal_headers_fallback "${header}") + string( + REGEX REPLACE + "([][+.*^$()|?\\\\])" + "\\\\\\1" + header_regex + "${header}" + ) + list( + APPEND internal_headers_fallback_per_header_defines + DEFINE + "${fallback}" + "^${header_regex}$" ) endif() -endfunction() - -function(libcudacxx_add_internal_header_test header) - # ${header} contains the "/" from the subfolder, replace by "_" for actual names - string(REPLACE "/" "_" header_name "${header}") +endforeach() - # Create the source file for the header target from the template and add the file to the global project - set(headertest_src "headers/${header_name}") - configure_file( - "${CMAKE_CURRENT_SOURCE_DIR}/cmake/header_test.cpp.in" - "${headertest_src}.cu" +if (internal_headers_fallback) + cccl_generate_header_tests( + libcudacxx.test.internal_headers.fallback + libcudacxx/include + NO_METATARGETS + LANGUAGE CUDA + HEADER_TEMPLATE "${libcudacxx_SOURCE_DIR}/cmake/header_test.cpp.in" + HEADERS ${internal_headers_fallback} + PER_HEADER_DEFINES ${internal_headers_fallback_per_header_defines} ) - - # Create the default target for that file - libcudacxx_create_internal_header_test(${header_name} ${headertest_src}) - - # Optionally create a fallback target for that file - libcudacxx_create_internal_header_fallback_test(${header_name} ${headertest_src}) -endfunction() - -foreach (header IN LISTS internal_headers) - libcudacxx_add_internal_header_test(${header}) -endforeach() + target_compile_definitions( + libcudacxx.test.internal_headers.fallback + PRIVATE _CCCL_HEADER_TEST + ) + target_link_libraries( + libcudacxx.test.internal_headers.fallback + PUBLIC # + libcudacxx.compiler_interface + CUDA::cudart + ) + add_dependencies( + libcudacxx.test.internal_headers + libcudacxx.test.internal_headers.fallback + ) +endif() diff --git a/libcudacxx/cmake/LibcudacxxPublicHeaderTesting.cmake b/libcudacxx/cmake/LibcudacxxPublicHeaderTesting.cmake index bdcfd4e1514..4545599686c 100644 --- a/libcudacxx/cmake/LibcudacxxPublicHeaderTesting.cmake +++ b/libcudacxx/cmake/LibcudacxxPublicHeaderTesting.cmake @@ -22,68 +22,26 @@ if ("Clang" STREQUAL "${CMAKE_CUDA_COMPILER_ID}") list(FILTER public_headers EXCLUDE REGEX "annotated_ptr") endif() -# We need to handle atomic headers differently as they do not compile on architectures below sm70 -set(architectures_at_least_sm70) -foreach (item IN LISTS CMAKE_CUDA_ARCHITECTURES) - if (item GREATER_EQUAL 70) - list(APPEND architectures_at_least_sm70 ${item}) +function(libcudacxx_add_public_header_test_target target_name) + if (NOT ARGN) + return() endif() -endforeach() -function(libcudacxx_create_public_header_test header_name headertest_src) - # Create the default target for that file - add_library(public_headertest_${header_name} SHARED "${headertest_src}.cu") - cccl_configure_target(public_headertest_${header_name}) - target_compile_definitions( - public_headertest_${header_name} - PRIVATE _CCCL_HEADER_TEST + cccl_generate_header_tests( + ${target_name} + libcudacxx/include + NO_METATARGETS + LANGUAGE CUDA + HEADER_TEMPLATE "${libcudacxx_SOURCE_DIR}/cmake/header_test.cpp.in" + HEADERS ${ARGN} ) - # Bring in the global CCCL compile definitions - target_link_libraries( - public_headertest_${header_name} - PUBLIC libcudacxx.compiler_interface - ) - - # Ensure that if this is an atomic header, we only include the right architectures - string( - REGEX MATCH - "atomic|barrier|latch|semaphore|annotated_ptr|pipeline" - match - "${header}" - ) - if (match) - # Ensure that we only compile the header when we have some architectures enabled - if (NOT architectures_at_least_sm70) - return() - endif() - set_target_properties( - public_headertest_${header_name} - PROPERTIES CUDA_ARCHITECTURES "${architectures_at_least_sm70}" - ) - endif() - - add_dependencies( - libcudacxx.test.public_headers - public_headertest_${header_name} - ) + target_compile_definitions(${target_name} PRIVATE _CCCL_HEADER_TEST) + target_link_libraries(${target_name} PUBLIC libcudacxx.compiler_interface) + add_dependencies(libcudacxx.test.public_headers ${target_name}) endfunction() -function(libcudacxx_add_public_header_test header) - # ${header} contains the "/" from the subfolder, replace by "_" for actual names - string(REPLACE "/" "_" header_name "${header}") - - # Create the source file for the header target from the template and add the file to the global project - set(headertest_src "headers/${header_name}") - configure_file( - "${CMAKE_CURRENT_SOURCE_DIR}/cmake/header_test.cpp.in" - "${headertest_src}.cu" - ) - - # Create the default target for that file - libcudacxx_create_public_header_test(${header_name} ${headertest_src}) -endfunction() - -foreach (header IN LISTS public_headers) - libcudacxx_add_public_header_test(${header}) -endforeach() +libcudacxx_add_public_header_test_target( + libcudacxx.test.public_headers.base + ${public_headers} +) diff --git a/libcudacxx/cmake/LibcudacxxPublicHeaderTestingHost.cmake b/libcudacxx/cmake/LibcudacxxPublicHeaderTestingHost.cmake index f7dda40b6c5..42327816166 100644 --- a/libcudacxx/cmake/LibcudacxxPublicHeaderTestingHost.cmake +++ b/libcudacxx/cmake/LibcudacxxPublicHeaderTestingHost.cmake @@ -28,82 +28,44 @@ if (CCCL_USE_LIBCXX) list(APPEND public_host_header_cxx_compile_options "-stdlib=libc++") endif() -function(libcudacxx_create_public_header_test_host header_name headertest_src) - # Create the default target for that file - add_library( - public_headers_host_only_${header_name} - SHARED - "${headertest_src}.cpp" - ) - cccl_configure_target(public_headers_host_only_${header_name}) - target_compile_definitions( - public_headers_host_only_${header_name} - PRIVATE # - ${public_host_header_cxx_compile_definitions} - _CCCL_HEADER_TEST - ) - target_compile_options( - public_headers_host_only_${header_name} - PRIVATE ${public_host_header_cxx_compile_options} - ) - target_link_libraries( - public_headers_host_only_${header_name} - PUBLIC libcudacxx.compiler_interface - ) - add_dependencies( - libcudacxx.test.public_headers_host_only - public_headers_host_only_${header_name} - ) -endfunction() - function( - libcudacxx_create_public_header_test_host_with_ctk - header_name - headertest_src + libcudacxx_add_public_header_test_host_target + target_name + parent_target + with_ctk ) - # Create the default target for that file - add_library( - public_headers_host_only_with_ctk_${header_name} - SHARED - "${headertest_src}.cpp" + cccl_generate_header_tests( + ${target_name} + libcudacxx/include + NO_METATARGETS + LANGUAGE CXX + HEADER_TEMPLATE "${libcudacxx_SOURCE_DIR}/cmake/header_test.cpp.in" + HEADERS ${public_headers_host_only} ) - cccl_configure_target(public_headers_host_only_with_ctk_${header_name}) target_compile_definitions( - public_headers_host_only_with_ctk_${header_name} + ${target_name} PRIVATE # ${public_host_header_cxx_compile_definitions} _CCCL_HEADER_TEST ) target_compile_options( - public_headers_host_only_with_ctk_${header_name} + ${target_name} PRIVATE ${public_host_header_cxx_compile_options} ) - target_link_libraries( - public_headers_host_only_with_ctk_${header_name} - PUBLIC libcudacxx.compiler_interface CUDA::cudart - ) - add_dependencies( - libcudacxx.test.public_headers_host_only_with_ctk - public_headers_host_only_with_ctk_${header_name} - ) + target_link_libraries(${target_name} PUBLIC libcudacxx.compiler_interface) + if (with_ctk) + target_link_libraries(${target_name} PUBLIC CUDA::cudart) + endif() + add_dependencies(${parent_target} ${target_name}) endfunction() -function(libcudacxx_add_public_headers_host_only header) - # ${header} contains the "/" from the subfolder, replace by "_" for actual names - string(REPLACE "/" "_" header_name "${header}") - - # Create the source file for the header target from the template and add the file to the global project - set(headertest_src "headers/${header_name}") - configure_file( - "${CMAKE_CURRENT_SOURCE_DIR}/cmake/header_test.cpp.in" - "${headertest_src}.cpp" - ) - - # Create the default target for that file - libcudacxx_create_public_header_test_host(${header_name} ${headertest_src}) - libcudacxx_create_public_header_test_host_with_ctk(${header_name} ${headertest_src}) -endfunction() - -foreach (header IN LISTS public_headers_host_only) - libcudacxx_add_public_headers_host_only(${header}) -endforeach() +libcudacxx_add_public_header_test_host_target( + libcudacxx.test.public_headers_host_only.base + libcudacxx.test.public_headers_host_only + OFF +) +libcudacxx_add_public_header_test_host_target( + libcudacxx.test.public_headers_host_only_with_ctk.base + libcudacxx.test.public_headers_host_only_with_ctk + ON +) diff --git a/libcudacxx/cmake/header_test.cpp.in b/libcudacxx/cmake/header_test.cpp.in index 077e2fe82d2..67280bfb757 100644 --- a/libcudacxx/cmake/header_test.cpp.in +++ b/libcudacxx/cmake/header_test.cpp.in @@ -20,6 +20,6 @@ #endif // This file tests that the respective header is includable on its own with a cuda compiler -#include <${header}> +#include <@header@> int main(int, char**) { return 0; }