Skip to content

Commit b42e71b

Browse files
committed
WIP [skip-vdc][skip-docs][skip-tpt]
1 parent 68b3ecb commit b42e71b

16 files changed

+265
-244
lines changed

c2h/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,5 +46,5 @@ else()
4646
target_compile_definitions(cccl.c2h PRIVATE C2H_HAS_CURAND=0)
4747
endif()
4848

49-
add_library(cccl.c2h.main OBJECT catch2_runner.cpp catch2_runner_helper.cu)
49+
add_library(cccl.c2h.main STATIC catch2_runner.cpp catch2_runner_helper.cu)
5050
target_link_libraries(cccl.c2h.main PUBLIC cccl.c2h)

ci/matrix.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ workflows:
2121
# args: '--preset libcudacxx --lit-tests "cuda/utility/basic_any.pass.cpp"' }
2222
#
2323
override:
24+
- {jobs: ['test'], project: ['thrust', 'cub'], std: 20, cxx: ['gcc', 'clang', 'msvc'] }
25+
# TODO add nightly/weekly coverage for this:
26+
- {jobs: ['test'], project: 'cub', std: 20, cxx: ['gcc', 'clang', 'msvc'], cmake_options: "-DCUB_FORCE_RDC=ON" }
2427

2528
pull_request:
2629
# Old CTK: Oldest/newest supported host compilers:

cmake/CCCLAddExecutable.cmake

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -11,33 +11,34 @@ function(cccl_add_executable target_name)
1111
set(oneValueArgs METATARGET_PATH)
1212
set(multiValueArgs SOURCES)
1313
cmake_parse_arguments(
14-
_cccl
14+
self
1515
"${options}"
1616
"${oneValueArgs}"
1717
"${multiValueArgs}"
1818
${ARGN}
1919
)
20+
cccl_parse_arguments_error_checks(
21+
"cccl_add_executable"
22+
"self"
23+
"${options}"
24+
"${oneValueArgs}"
25+
"${multiValueArgs}"
26+
ERROR_UNPARSED
27+
REQUIRED_VALUES SOURCES
28+
DEFAULT_VALUES METATARGET_PATH "${target_name}"
29+
)
2030

21-
if (_cccl_UNPARSED_ARGUMENTS)
22-
message(FATAL_ERROR "Unrecognized arguments: ${_cccl_UNPARSED_ARGUMENTS}")
23-
endif()
24-
25-
if (NOT DEFINED _cccl_SOURCES)
26-
message(FATAL_ERROR "cccl_add_executable requires SOURCES argument")
27-
endif()
28-
29-
add_executable(${target_name} ${_cccl_SOURCES})
31+
add_executable(${target_name} ${self_SOURCES})
3032
cccl_configure_target(${target_name})
3133

32-
if (_cccl_ADD_CTEST)
34+
if (self_ADD_CTEST)
3335
add_test(NAME ${target_name} COMMAND "$<TARGET_FILE:${target_name}>")
3436
endif()
3537

36-
if (NOT _cccl_NO_METATARGETS)
37-
set(metatarget_path ${target_name})
38-
if (DEFINED _cccl_METATARGET_PATH)
39-
set(metatarget_path ${_cccl_METATARGET_PATH})
40-
endif()
41-
cccl_ensure_metatargets(${target_name} METATARGET_PATH ${metatarget_path})
38+
if (NOT self_NO_METATARGETS)
39+
cccl_ensure_metatargets(
40+
${target_name}
41+
METATARGET_PATH ${self_METATARGET_PATH}
42+
)
4243
endif()
4344
endfunction()

cmake/CCCLAddSubdirHelper.cmake

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,14 @@ function(cccl_add_subdir_helper project_name)
1818
"${multiValueArgs}"
1919
${ARGN}
2020
)
21+
cccl_parse_arguments_error_checks(
22+
"cccl_add_subdir_helper"
23+
"CCCL_SUBDIR"
24+
"${options}"
25+
"${oneValueArgs}"
26+
"${multiValueArgs}"
27+
ERROR_UNPARSED
28+
)
2129

2230
if (DEFINED CCCL_SUBDIR_PACKAGE_FILEBASE)
2331
set(package_filebase "${CCCL_SUBDIR_PACKAGE_FILEBASE}")

cmake/CCCLConfigureTarget.cmake

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,14 @@ function(cccl_configure_target target_name)
1313
"${multiValueArgs}"
1414
${ARGN}
1515
)
16+
cccl_parse_arguments_error_checks(
17+
"cccl_configure_target"
18+
"CCT"
19+
"${options}"
20+
"${oneValueArgs}"
21+
"${multiValueArgs}"
22+
ERROR_UNPARSED
23+
)
1624

1725
get_target_property(type ${target_name} TYPE)
1826

cmake/CCCLEnsureMetaTargets.cmake

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,15 @@ function(cccl_ensure_metatargets target_name)
1616
"${multiValueArgs}"
1717
${ARGN}
1818
)
19-
20-
if (_cccl_UNPARSED_ARGUMENTS)
21-
message(FATAL_ERROR "Unrecognized arguments: ${_cccl_UNPARSED_ARGUMENTS}")
22-
endif()
23-
24-
if (NOT DEFINED _cccl_METATARGET_PATH)
25-
set(_cccl_METATARGET_PATH ${target_name})
26-
endif()
19+
cccl_parse_arguments_error_checks(
20+
"cccl_ensure_metatargets"
21+
"_cccl"
22+
"${options}"
23+
"${oneValueArgs}"
24+
"${multiValueArgs}"
25+
ERROR_UNPARSED
26+
DEFAULT_VALUES METATARGET_PATH "${target_name}"
27+
)
2728

2829
set(parent_path "")
2930
set(current_path "")

cmake/CCCLGenerateHeaderTests.cmake

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -39,19 +39,16 @@ function(cccl_generate_header_tests target_name project_include_path)
3939
"${multiValueArgs}"
4040
${ARGN}
4141
)
42-
43-
if (CGHT_UNPARSED_ARGUMENTS)
44-
message(FATAL_ERROR "Unrecognized arguments: ${CGHT_UNPARSED_ARGUMENTS}")
45-
endif()
46-
47-
# Setup defaults
48-
if (NOT DEFINED CGHT_LANGUAGE)
49-
set(CGHT_LANGUAGE CUDA)
50-
endif()
51-
52-
if (NOT DEFINED CGHT_HEADER_TEMPLATE)
53-
set(CGHT_HEADER_TEMPLATE "${CCCL_SOURCE_DIR}/cmake/header_test.cu.in")
54-
endif()
42+
cccl_parse_arguments_error_checks(
43+
"cccl_generate_header_tests"
44+
"CGHT"
45+
"${options}"
46+
"${oneValueArgs}"
47+
"${multiValueArgs}"
48+
DEFAULT_VALUES #
49+
LANGUAGE "CUDA"
50+
HEADER_TEMPLATE "${CCCL_SOURCE_DIR}/cmake/header_test.cu.in"
51+
)
5552

5653
# Derived vars:
5754
if (${CGHT_LANGUAGE} STREQUAL "C")

cmake/CCCLInstallRules.cmake

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
include(${CMAKE_CURRENT_LIST_DIR}/CCCLParseArguments.cmake)
2+
13
# Bring in CMAKE_INSTALL_* vars
24
include(GNUInstallDirs)
35

@@ -41,6 +43,14 @@ function(cccl_generate_install_rules project_name enable_rules_by_default)
4143
"${multiValueArgs}"
4244
${ARGN}
4345
)
46+
cccl_parse_arguments_error_checks(
47+
"cccl_generate_install_rules"
48+
"CGIR"
49+
"${options}"
50+
"${oneValueArgs}"
51+
"${multiValueArgs}"
52+
ERROR_UNPARSED
53+
)
4454

4555
string(TOLOWER ${project_name} project_name_lower)
4656
set(project_source_dir "${CCCL_SOURCE_DIR}/${project_name_lower}")

cmake/CCCLParseArguments.cmake

Lines changed: 93 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1,84 +1,112 @@
1+
# This file defines helpers for common operations with cmake_parse_arguments.
2+
3+
include_guard(GLOBAL)
14
include(CMakeParseArguments)
25

3-
# A nicer wrapper around cmake_parse_arguments:
6+
# Routine error checks for argument parsing.
47
#
5-
# cccl_parse_arguments(
6-
# <parent_name> # Required; function / macro calling this helper. Must be first.
7-
# [OPTIONS <option1> <option2> ...] # Optional; If specified, passed to cmake_parse_arguments.
8-
# [ONE_VALUE_ARGS <arg1> <arg2> ...] # Optional; If specified, passed to cmake_parse_arguments.
9-
# [MULTI_VALUE_ARGS <arg1> <arg2> ...] # Optional; If specified, passed to cmake_parse_arguments.
10-
# [ERROR_IF_UNPARSED] # Optional; If specified, unparsed args cause fatal error.
11-
# [PREFIX <prefix>] # Optional; default: "self"
12-
# [PARENT_NAME <parent_scope_name>] # Optional; function / macro for nicer error messages.
13-
# PARENT_ARGN <parent_argn> # Required, must be last.
14-
# )
15-
16-
function(cccl_parse_arguments)
17-
# Provided def in .gersemi/ext/cccl.py:
18-
# gersemi: ignore
19-
set(options ERROR_IF_UNPARSED)
20-
set(oneValueArgs PREFIX PARENT_NAME)
21-
set(multiValueArgs PARENT_ARGN OPTIONS ONE_VALUE_ARGS MULTI_VALUE_ARGS)
8+
# Required positional arguments:
9+
# caller_name: Name of the calling function (for error messages).
10+
# caller_prefix: Prefix used for the caller's cmake_parse_arguments.
11+
# caller_opts: List of option keywords used by the caller.
12+
# caller_svas: List of single-value argument keywords used by the caller.
13+
# caller_mvas: List of multi-value argument keywords used by the caller.
14+
#
15+
# Checks:
16+
# [ERROR_UNPARSED]
17+
# Checks that there were no unparsed arguments.
18+
# [REQUIRED_KEYWORDS kw1 [kw2]...]
19+
# Check that the listed keywords were provided (even if with empty values).
20+
# [REQUIRED_VALUES kw1 [kw2]...]
21+
# Check that the listed keywords were provided with non-empty values.
22+
# [DEFAULT_VALUES kw1 val1 [kw2 val2]...]
23+
# For any of the listed keywords not provided, set them to the given default
24+
# values.
25+
function(
26+
cccl_parse_arguments_error_checks
27+
caller_name
28+
caller_prefix
29+
caller_opts
30+
caller_svas
31+
caller_mvas
32+
)
33+
set(options ERROR_UNPARSED)
34+
set(singleValueArgs "")
35+
set(multiValueArgs REQUIRED_KEYWORDS REQUIRED_VALUES DEFAULT_VALUES)
36+
# gersemi: hints { DEFAULT_VALUES: pairs }
37+
# gersemi: hints { REQUIRED_KEYWORDS: sort+unique }
38+
# gersemi: hints { REQUIRED_VALUES: sort+unique }
2239
cmake_parse_arguments(
23-
"__self_"
40+
__self
2441
"${options}"
25-
"${oneValueArgs}"
42+
"${singleValueArgs}"
2643
"${multiValueArgs}"
2744
${ARGN}
2845
)
2946

30-
if (NOT DEFINED "__self_PARENT_ARGN")
31-
message(FATAL_ERROR "cccl_parse_arguments requires PARENT_ARGN to be defined.")
32-
endif()
33-
34-
if (NOT DEFINED "__self_PREFIX")
35-
set(__self_PREFIX "self")
36-
endif()
37-
38-
if (NOT DEFINED "__self_PARENT_NAME")
39-
set(__self_PARENT_NAME "cccl_parse_arguments's parent function")
40-
endif()
41-
42-
# Reset args for cmake_parse_arguments call:
43-
set(options)
44-
if (DEFINED "__self_OPTIONS")
45-
set(options "${__self_OPTIONS}")
46-
endif()
47-
48-
set(one_value_args)
49-
if (DEFINED "__self_ONE_VALUE_ARGS")
50-
set(one_value_args "${__self_ONE_VALUE_ARGS}")
51-
endif()
52-
53-
set(multi_value_args)
54-
if (DEFINED "__self_MULTI_VALUE_ARGS")
55-
set(multi_value_args "${__self_MULTI_VALUE_ARGS}")
47+
if (__self_ERROR_UNPARSED AND DEFINED ${caller_prefix}_UNPARSED_ARGUMENTS)
48+
message(
49+
FATAL_ERROR
50+
"${caller_name}: Unrecognized arguments: ${${caller_prefix}_UNPARSED_ARGUMENTS}"
51+
)
5652
endif()
5753

58-
cmake_parse_arguments(
59-
"${__self_PREFIX}"
60-
"${options}"
61-
"${one_value_args}"
62-
"${multi_value_args}"
63-
${__self_PARENT_ARGN}
64-
)
65-
54+
# Check that required keywords were detected, include those with empty values:
55+
foreach (kw IN LISTS __self_REQUIRED_KEYWORDS __self_REQUIRED_VALUES)
56+
set(caller_kw "${caller_prefix}_${kw}")
57+
# gersemi: off
58+
if (kw IN_LIST caller_opts AND DEFINED ${caller_kw})
59+
message(FATAL_ERROR "${caller_name}: Internal error: Options cannot be required keywords: '${kw}'.")
60+
elseif(kw IN_LIST caller_svas OR kw IN_LIST caller_mvas)
61+
if (DEFINED ${caller_kw} OR ${kw} IN_LIST ${caller_prefix}_KEYWORDS_MISSING_VALUES)
62+
continue()
63+
endif()
64+
else()
65+
message(FATAL_ERROR "${caller_name}: Internal error: Unrecognized required keyword: '${kw}'.")
66+
endif()
67+
message(FATAL_ERROR "${caller_name}: Required argument '${kw}' not provided.")
68+
# gersemi: on
69+
endforeach()
6670

67-
if (DEFINED "${__self_PREFIX}_UNPARSED_ARGUMENTS")
68-
if (DEFINED "__self_NO_UNPARSED")
69-
message(FATAL_ERROR "${${__self_PREFIX}_PARENT_NAME} given invalid arguments: ${${__self_PREFIX}_UNPARSED_ARGUMENTS}")
71+
# Check that required values were provided, failing for keywords with empty values:
72+
foreach (kw IN LISTS __self_REQUIRED_VALUES)
73+
set(caller_kw "${caller_prefix}_${kw}")
74+
# gersemi: off
75+
if (kw IN_LIST caller_opts)
76+
message(FATAL_ERROR "${caller_name}: Internal error: Options cannot have values: '${kw}'.")
77+
elseif(kw IN_LIST caller_svas OR kw IN_LIST caller_mvas)
78+
if (DEFINED ${caller_kw})
79+
continue()
80+
endif()
7081
else()
71-
set("${__self_PREFIX}_UNPARSED_ARGUMENTS" "${${__self_PREFIX}_UNPARSED_ARGUMENTS}" PARENT_SCOPE)
82+
message(FATAL_ERROR "${caller_name}: Internal error: Unrecognized required value keyword: '${kw}'.")
7283
endif()
73-
else()
74-
unset("${__self_PREFIX}_UNPARSED_ARGUMENTS" PARENT_SCOPE)
75-
endif()
84+
message(FATAL_ERROR "${caller_name}: Required argument '${kw}' not provided or missing required value.")
85+
# gersemi: on
86+
endforeach()
87+
88+
# Set defaults if not defined:
89+
set(kw)
90+
foreach (iter IN LISTS __self_DEFAULT_VALUES)
91+
# Alternates key / values. Only single values allowed.
92+
if (NOT kw)
93+
set(kw "${iter}")
94+
continue()
95+
endif()
96+
set(caller_kw "${caller_prefix}_${kw}")
97+
set(value "${iter}")
7698

77-
foreach(arg IN LISTS options one_value_args multi_value_args)
78-
if (DEFINED "${__self_PREFIX}_${arg}")
79-
set("${__self_PREFIX}_${arg}" "${${__self_PREFIX}_${arg}}" PARENT_SCOPE)
99+
# gersemi: off
100+
if (kw IN_LIST caller_opts)
101+
message(FATAL_ERROR "${caller_name}: Internal error: Options cannot have default values: '${kw}'.")
102+
elseif (kw IN_LIST caller_svas OR kw IN_LIST caller_mvas)
103+
if (NOT DEFINED ${caller_kw} AND NOT ${kw} IN_LIST ${caller}_KEYWORDS_MISSING_VALUES)
104+
set(${caller_kw} "${value}" PARENT_SCOPE)
105+
endif()
80106
else()
81-
unset("${__self_PREFIX}_${arg}" PARENT_SCOPE)
107+
message(FATAL_ERROR "${caller_name}: Internal error: Unrecognized default value keyword: '${kw}'.")
82108
endif()
109+
set(kw) # Clear to signal next pair
110+
# gersemi: on
83111
endforeach()
84112
endfunction()

0 commit comments

Comments
 (0)