From eaf54e5de3a252822a31629207a8bc4e3830a5d9 Mon Sep 17 00:00:00 2001 From: Vyas Ramasubramani Date: Tue, 5 May 2026 10:28:52 -0700 Subject: [PATCH 01/21] Introduce centralized dependency management infrastructure Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus --- cpp/CMakeLists.txt | 75 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 71 insertions(+), 4 deletions(-) diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt index 5a0b2f95e83..f1738716dd1 100644 --- a/cpp/CMakeLists.txt +++ b/cpp/CMakeLists.txt @@ -58,8 +58,31 @@ option(CUDA_ENABLE_LINEINFO ) option(CUDA_WARNINGS_AS_ERRORS "Enable -Werror=all-warnings for all CUDA compilation" ON) +# CUDF_BUILD_STATIC_DEPS should almost never be set to OFF since there is no reason to prefer +# building shared libraries for dependencies under normal circumstances. FORCE is a necessary +# setting for building a standalone binary with no external dependencies. +set(CUDF_BUILD_STATIC_DEPS + "ON" + CACHE + STRING + "Three-state control for static library dependencies. ON (default) = use static when a CPM build is triggered, OFF = prefer shared (rarely useful), FORCE = guarantee using a static build by rebuilding or downloading even when local copies of a library exist" +) +set_property(CACHE CUDF_BUILD_STATIC_DEPS PROPERTY STRINGS "ON" "OFF" "FORCE") + # cudart can be statically linked or dynamically linked. The python ecosystem wants dynamic linking option(CUDA_STATIC_RUNTIME "Statically link the CUDA runtime" OFF) +# FORCE mode implies static CUDA runtime +if(CUDF_BUILD_STATIC_DEPS STREQUAL "FORCE") + set(CUDA_STATIC_RUNTIME + ON + CACHE BOOL "Statically link the CUDA runtime" FORCE + ) +else() + set(CUDA_STATIC_RUNTIME + OFF + CACHE BOOL "Statically link the CUDA runtime" FORCE + ) +endif() set(DEFAULT_CUDF_BUILD_STREAMS_TEST_UTIL ON) @@ -102,6 +125,44 @@ message(VERBOSE "CUDF: Build with remote IO (e.g. AWS S3) support through KvikIO: ${CUDF_KVIKIO_REMOTE_IO}" ) +# CUDF_INSTALL_LIBRARY_DEPS: Derived variable indicating whether to install library dependencies +if(NOT BUILD_SHARED_LIBS) + # A static libcudf.a will not contain the code for its dependencies, so we must install them to + # ensure downstream projects can find them + set(CUDF_INSTALL_LIBRARY_DEPS ON) +elseif(CUDF_BUILD_STATIC_DEPS STREQUAL "OFF") + # If dependencies are built as shared they will be needed at runtime + set(CUDF_INSTALL_LIBRARY_DEPS ON) +else() + # If dependencies are statically linked into a libcudf shared library they aren't needed at + # runtime + set(CUDF_INSTALL_LIBRARY_DEPS OFF) +endif() + +# Derived flags for EXCLUDE_FROM_ALL handling across dependency fetching. +# CUDF_EXCLUDE_DEPS_FROM_ALL: ON/OFF value for rapids_cpm_find() calls (key-value style) +# CUDF_EXCLUDE_DEPS_FROM_ALL_FLAG: "EXCLUDE_FROM_ALL" or "" for rapids_cpm_* wrapper calls (flag +# style) We need both because of https://github.com/cpm-cmake/CPM.cmake/issues/693 +if(CUDF_INSTALL_LIBRARY_DEPS) + set(CUDF_EXCLUDE_DEPS_FROM_ALL OFF) + set(CUDF_EXCLUDE_DEPS_FROM_ALL_FLAG) +else() + set(CUDF_EXCLUDE_DEPS_FROM_ALL ON) + set(CUDF_EXCLUDE_DEPS_FROM_ALL_FLAG EXCLUDE_FROM_ALL) +endif() + +# CUDF_DEPS_BUILD_SHARED: Boolean reduction of the 3-state CUDF_BUILD_STATIC_DEPS for passing to +# dependency configuration functions that accept a BUILD_SHARED parameter. +if(CUDF_BUILD_STATIC_DEPS STREQUAL "OFF") + set(CUDF_DEPS_BUILD_SHARED ON) +else() + set(CUDF_DEPS_BUILD_SHARED OFF) +endif() + +message(VERBOSE "CUDF: Build static library dependencies: ${CUDF_BUILD_STATIC_DEPS}") +message(VERBOSE "CUDF: Install library dependencies: ${CUDF_INSTALL_LIBRARY_DEPS}") +message(VERBOSE "CUDF: Build dependencies as shared libraries: ${CUDF_DEPS_BUILD_SHARED}") + # Set a default build type if none was specified rapids_cmake_build_type("Release") set(CUDF_BUILD_TESTS ${BUILD_TESTS}) @@ -257,19 +318,22 @@ if(CUDF_BUILD_TESTUTIL) ) endif() +# Set CPM_DOWNLOAD_ALL if CUDF_BUILD_STATIC_DEPS is FORCE to skip find_package for all CPM packages +if(CUDF_BUILD_STATIC_DEPS STREQUAL "FORCE") + set(CPM_DOWNLOAD_ALL ON) +endif() + # add third party dependencies using CPM rapids_cpm_init() include(${rapids-cmake-dir}/cpm/rapids_logger.cmake) rapids_cpm_rapids_logger(BUILD_EXPORT_SET cudf-exports INSTALL_EXPORT_SET cudf-exports) + create_logger_macros(CUDF "cudf::default_logger()" include/cudf) # find jitify include(cmake/thirdparty/get_jitify.cmake) -# find NVTX -include(cmake/thirdparty/get_nvtx.cmake) - # find nvCOMP include(cmake/thirdparty/get_nvcomp.cmake) @@ -279,6 +343,9 @@ include(cmake/thirdparty/get_cccl.cmake) # find rmm, should come after including CCCL to allow overriding the CCCL version used for testing include(cmake/thirdparty/get_rmm.cmake) +# find NVTX, after rmm so we defer to rmm to decide the interface since nvtx is private for cudf +include(cmake/thirdparty/get_nvtx.cmake) + # find croaring include(cmake/thirdparty/get_croaring.cmake) @@ -1004,7 +1071,7 @@ target_link_libraries( cudf PUBLIC CCCL::CCCL rapids_logger::rapids_logger rmm::rmm $ PRIVATE $ $ ZLIB::ZLIB - nvcomp::nvcomp kvikio::kvikio nanoarrow::nanoarrow zstd + ${CUDF_nvcomp_TARGET} kvikio::kvikio ${CUDF_nanoarrow_TARGET} zstd ) # Add Conda library, and include paths if specified From 010e72908452ad0363a2d995f1a4634764e31177 Mon Sep 17 00:00:00 2001 From: Vyas Ramasubramani Date: Tue, 5 May 2026 10:29:53 -0700 Subject: [PATCH 02/21] Refactor core dependency fetchers for shared/static controls Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus --- cpp/cmake/thirdparty/get_nanoarrow.cmake | 24 ++++++--- cpp/cmake/thirdparty/get_nvcomp.cmake | 65 +++++++++++++----------- cpp/cmake/thirdparty/get_nvtx.cmake | 8 +-- cpp/cmake/thirdparty/get_rmm.cmake | 20 ++++++-- 4 files changed, 74 insertions(+), 43 deletions(-) diff --git a/cpp/cmake/thirdparty/get_nanoarrow.cmake b/cpp/cmake/thirdparty/get_nanoarrow.cmake index a4bb50dc928..7e0c06a279d 100644 --- a/cpp/cmake/thirdparty/get_nanoarrow.cmake +++ b/cpp/cmake/thirdparty/get_nanoarrow.cmake @@ -6,17 +6,16 @@ # ============================================================================= # This function finds nanoarrow and sets any additional necessary environment variables. -function(find_and_configure_nanoarrow) - set(_exclude_from_all EXCLUDE_FROM_ALL ${BUILD_SHARED_LIBS}) - +function(find_and_configure_nanoarrow BUILD_SHARED EXCLUDE_FROM_ALL) rapids_cpm_find( nanoarrow 0.7.0 - GLOBAL_TARGETS nanoarrow + GLOBAL_TARGETS nanoarrow_static nanoarrow_shared CPM_ARGS GIT_REPOSITORY https://github.com/apache/arrow-nanoarrow.git GIT_TAG 2cfba631b40886f1418a463f3b7c4552c8ae0dc7 GIT_SHALLOW FALSE - OPTIONS "BUILD_SHARED_LIBS OFF" "NANOARROW_NAMESPACE cudf" ${_exclude_from_all} + OPTIONS "BUILD_SHARED_LIBS ${BUILD_SHARED}" "NANOARROW_NAMESPACE cudf" + EXCLUDE_FROM_ALL ${EXCLUDE_FROM_ALL} ) if(nanoarrow_ADDED) set_target_properties(nanoarrow_static PROPERTIES POSITION_INDEPENDENT_CODE ON) @@ -26,4 +25,17 @@ function(find_and_configure_nanoarrow) endif() endfunction() -find_and_configure_nanoarrow() +if(NOT DEFINED CUDF_DEPS_BUILD_SHARED) + set(CUDF_DEPS_BUILD_SHARED OFF) +endif() +if(NOT DEFINED CUDF_EXCLUDE_DEPS_FROM_ALL) + set(CUDF_EXCLUDE_DEPS_FROM_ALL OFF) +endif() + +find_and_configure_nanoarrow(${CUDF_DEPS_BUILD_SHARED} ${CUDF_EXCLUDE_DEPS_FROM_ALL}) + +if(CUDF_DEPS_BUILD_SHARED) + set(CUDF_nanoarrow_TARGET nanoarrow_shared) +else() + set(CUDF_nanoarrow_TARGET nanoarrow_static) +endif() diff --git a/cpp/cmake/thirdparty/get_nvcomp.cmake b/cpp/cmake/thirdparty/get_nvcomp.cmake index 6eba68f3541..248595ca17c 100644 --- a/cpp/cmake/thirdparty/get_nvcomp.cmake +++ b/cpp/cmake/thirdparty/get_nvcomp.cmake @@ -13,7 +13,7 @@ # This function finds nvcomp and sets any additional necessary environment variables. function(find_and_configure_nvcomp) - set(options DOWNLOAD_ONLY) + set(options DOWNLOAD_ONLY INSTALL_LIBRARY) set(one_value VERSION) cmake_parse_arguments(_NVCOMP "${options}" "${one_value}" "" ${ARGN}) @@ -22,9 +22,7 @@ function(find_and_configure_nvcomp) include("${rapids-cmake-dir}/find/package.cmake") rapids_find_package( nvcomp ${_NVCOMP_VERSION} - GLOBAL_TARGETS nvcomp::nvcomp - BUILD_EXPORT_SET cudf-exports - INSTALL_EXPORT_SET cudf-exports + GLOBAL_TARGETS nvcomp::nvcomp nvcomp::nvcomp_static FIND_ARGS QUIET ) if(nvcomp_FOUND) @@ -100,40 +98,49 @@ function(find_and_configure_nvcomp) include("${rapids-cmake-dir}/find/package.cmake") rapids_find_package( nvcomp ${_NVCOMP_VERSION} - GLOBAL_TARGETS nvcomp::nvcomp - BUILD_EXPORT_SET cudf-exports - INSTALL_EXPORT_SET cudf-exports + GLOBAL_TARGETS nvcomp::nvcomp nvcomp::nvcomp_static FIND_ARGS REQUIRED ) include(GNUInstallDirs) - install(DIRECTORY "${nvcomp_ROOT}/${lib_dir}/" DESTINATION "${lib_dir}") - install(DIRECTORY "${nvcomp_ROOT}/${CMAKE_INSTALL_INCLUDEDIR}/" - DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" - ) - if(EXISTS "${nvcomp_ROOT}/${CMAKE_INSTALL_BINDIR}") - install(DIRECTORY "${nvcomp_ROOT}/${CMAKE_INSTALL_BINDIR}/" - DESTINATION "${CMAKE_INSTALL_BINDIR}" + if(_NVCOMP_INSTALL_LIBRARY) + install(DIRECTORY "${nvcomp_ROOT}/${lib_dir}/" DESTINATION "${lib_dir}") + install(DIRECTORY "${nvcomp_ROOT}/${CMAKE_INSTALL_INCLUDEDIR}/" + DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" + ) + if(EXISTS "${nvcomp_ROOT}/${CMAKE_INSTALL_BINDIR}") + install(DIRECTORY "${nvcomp_ROOT}/${CMAKE_INSTALL_BINDIR}/" + DESTINATION "${CMAKE_INSTALL_BINDIR}" + ) + endif() + install( + FILES "${nvcomp_ROOT}/NOTICE" + DESTINATION info/ + RENAME NVCOMP_NOTICE + ) + install( + FILES "${nvcomp_ROOT}/LICENSE" + DESTINATION info/ + RENAME NVCOMP_LICENSE ) endif() - install( - FILES "${nvcomp_ROOT}/NOTICE" - DESTINATION info/ - RENAME NVCOMP_NOTICE - ) - install( - FILES "${nvcomp_ROOT}/LICENSE" - DESTINATION info/ - RENAME NVCOMP_LICENSE - ) - - include("${rapids-cmake-dir}/export/find_package_root.cmake") - rapids_export_find_package_root(BUILD nvcomp "${nvcomp_ROOT}" EXPORT_SET cudf-exports) - endfunction() -find_and_configure_nvcomp(VERSION 5.2.0.10) +set(_nvcomp_args VERSION 5.2.0.10) +if(CUDF_BUILD_STATIC_DEPS STREQUAL "FORCE") + list(APPEND _nvcomp_args DOWNLOAD_ONLY) +endif() +if(CUDF_INSTALL_LIBRARY_DEPS) + list(APPEND _nvcomp_args INSTALL_LIBRARY) +endif() +find_and_configure_nvcomp(${_nvcomp_args}) + +if(CUDF_DEPS_BUILD_SHARED OR NOT TARGET nvcomp::nvcomp_static) + set(CUDF_nvcomp_TARGET nvcomp::nvcomp) +else() + set(CUDF_nvcomp_TARGET nvcomp::nvcomp_static) +endif() # Per-thread default stream if(TARGET nvcomp AND CUDF_USE_PER_THREAD_DEFAULT_STREAM) diff --git a/cpp/cmake/thirdparty/get_nvtx.cmake b/cpp/cmake/thirdparty/get_nvtx.cmake index 7de59c20d69..bd49db12d75 100644 --- a/cpp/cmake/thirdparty/get_nvtx.cmake +++ b/cpp/cmake/thirdparty/get_nvtx.cmake @@ -1,6 +1,6 @@ # ============================================================================= # cmake-format: off -# SPDX-FileCopyrightText: Copyright (c) 2024-2025, NVIDIA CORPORATION. +# SPDX-FileCopyrightText: Copyright (c) 2024-2026, NVIDIA CORPORATION. # SPDX-License-Identifier: Apache-2.0 # cmake-format: on # ============================================================================= @@ -10,8 +10,10 @@ function(find_and_configure_nvtx) include(${rapids-cmake-dir}/cpm/nvtx3.cmake) - # Find or install nvtx3 - rapids_cpm_nvtx3(BUILD_EXPORT_SET cudf-exports INSTALL_EXPORT_SET cudf-exports) + rapids_cpm_nvtx3( + BUILD_EXPORT_SET cudf-exports INSTALL_EXPORT_SET cudf-exports + ${CUDF_EXCLUDE_DEPS_FROM_ALL_FLAG} + ) endfunction() diff --git a/cpp/cmake/thirdparty/get_rmm.cmake b/cpp/cmake/thirdparty/get_rmm.cmake index c6e31f8f64f..ebb02a5f74b 100644 --- a/cpp/cmake/thirdparty/get_rmm.cmake +++ b/cpp/cmake/thirdparty/get_rmm.cmake @@ -1,17 +1,27 @@ # ============================================================================= # cmake-format: off -# SPDX-FileCopyrightText: Copyright (c) 2020-2025, NVIDIA CORPORATION. +# SPDX-FileCopyrightText: Copyright (c) 2020-2026, NVIDIA CORPORATION. # SPDX-License-Identifier: Apache-2.0 # cmake-format: on # ============================================================================= # This function finds rmm and sets any additional necessary environment variables. -function(find_and_configure_rmm) +function(find_and_configure_rmm BUILD_SHARED EXCLUDE_FROM_ALL) include(${rapids-cmake-dir}/cpm/rmm.cmake) - # Find or install RMM - rapids_cpm_rmm(BUILD_EXPORT_SET cudf-exports INSTALL_EXPORT_SET cudf-exports) + if(EXCLUDE_FROM_ALL) + set(_exclude_flag EXCLUDE_FROM_ALL) + else() + set(_exclude_flag) + endif() + + # Find or install RMM. + set(_rmm_args BUILD_EXPORT_SET cudf-exports) + if(NOT EXCLUDE_FROM_ALL) + list(APPEND _rmm_args INSTALL_EXPORT_SET cudf-exports) + endif() + rapids_cpm_rmm(${_rmm_args} ${_exclude_flag} CPM_ARGS OPTIONS "BUILD_SHARED_LIBS ${BUILD_SHARED}") endfunction() -find_and_configure_rmm() +find_and_configure_rmm(${CUDF_DEPS_BUILD_SHARED} ${CUDF_EXCLUDE_DEPS_FROM_ALL}) From d9150bfca40e2218c3134b24e36762bb31a9514f Mon Sep 17 00:00:00 2001 From: Vyas Ramasubramani Date: Tue, 5 May 2026 10:30:13 -0700 Subject: [PATCH 03/21] Apply exclude-from-all flags to shared dependency fetchers Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus --- cpp/cmake/thirdparty/get_arrow.cmake | 25 ++++++++++++---------- cpp/cmake/thirdparty/get_croaring.cmake | 8 +++---- cpp/cmake/thirdparty/get_dlpack.cmake | 11 +++++++--- cpp/cmake/thirdparty/get_flatbuffers.cmake | 8 +++---- 4 files changed, 30 insertions(+), 22 deletions(-) diff --git a/cpp/cmake/thirdparty/get_arrow.cmake b/cpp/cmake/thirdparty/get_arrow.cmake index 1fe213862a9..2689237b530 100644 --- a/cpp/cmake/thirdparty/get_arrow.cmake +++ b/cpp/cmake/thirdparty/get_arrow.cmake @@ -1,6 +1,6 @@ # ============================================================================= # cmake-format: off -# SPDX-FileCopyrightText: Copyright (c) 2020-2025, NVIDIA CORPORATION. +# SPDX-FileCopyrightText: Copyright (c) 2020-2026, NVIDIA CORPORATION. # SPDX-License-Identifier: Apache-2.0 # cmake-format: on # ============================================================================= @@ -380,15 +380,6 @@ if(NOT DEFINED CUDF_VERSION_Arrow) endif() # Default to static arrow builds -if(NOT DEFINED CUDF_USE_ARROW_STATIC) - set(CUDF_USE_ARROW_STATIC ON) -endif() - -# Default to excluding from installation since we generally privately and statically link Arrow. -if(NOT DEFINED CUDF_EXCLUDE_ARROW_FROM_ALL) - set(CUDF_EXCLUDE_ARROW_FROM_ALL OFF) -endif() - if(NOT DEFINED CUDF_ENABLE_ARROW_PARQUET) set(CUDF_ENABLE_ARROW_PARQUET OFF) endif() @@ -397,7 +388,19 @@ if(NOT DEFINED CUDF_ENABLE_ARROW_COMPUTE) set(CUDF_ENABLE_ARROW_COMPUTE OFF) endif() +# Derive arrow build mode from CUDF_BUILD_STATIC_DEPS +if(CUDF_BUILD_STATIC_DEPS STREQUAL "OFF") + set(_cudf_arrow_static OFF) +else() + set(_cudf_arrow_static ON) +endif() +if(CUDF_INSTALL_LIBRARY_DEPS) + set(_cudf_arrow_exclude_from_all OFF) +else() + set(_cudf_arrow_exclude_from_all ON) +endif() + find_and_configure_arrow( - ${CUDF_VERSION_Arrow} ${CUDF_USE_ARROW_STATIC} ${CUDF_EXCLUDE_ARROW_FROM_ALL} + ${CUDF_VERSION_Arrow} ${_cudf_arrow_static} ${_cudf_arrow_exclude_from_all} ${CUDF_ENABLE_ARROW_PARQUET} ${CUDF_ENABLE_ARROW_COMPUTE} ) diff --git a/cpp/cmake/thirdparty/get_croaring.cmake b/cpp/cmake/thirdparty/get_croaring.cmake index bf6a8e9c398..fd39eae3557 100644 --- a/cpp/cmake/thirdparty/get_croaring.cmake +++ b/cpp/cmake/thirdparty/get_croaring.cmake @@ -6,8 +6,7 @@ # ============================================================================= # Use CPM to clone CRoaring and set up the necessary targets and include directories. -function(find_and_configure_roaring VERSION) - set(_exclude_from_all EXCLUDE_FROM_ALL ${BUILD_SHARED_LIBS}) +function(find_and_configure_roaring VERSION EXCLUDE_FROM_ALL) rapids_cpm_find( roaring ${VERSION} @@ -15,7 +14,8 @@ function(find_and_configure_roaring VERSION) CPM_ARGS GIT_REPOSITORY https://github.com/RoaringBitmap/CRoaring.git GIT_TAG v${VERSION} - GIT_SHALLOW TRUE ${_exclude_from_all} + GIT_SHALLOW TRUE + EXCLUDE_FROM_ALL ${EXCLUDE_FROM_ALL} OPTIONS "ROARING_BUILD_STATIC ON" "BUILD_SHARED_LIBS OFF" "ENABLE_ROARING_TESTS OFF" @@ -39,4 +39,4 @@ function(find_and_configure_roaring VERSION) endfunction() set(roaring_VERSION_cudf "4.3.11") -find_and_configure_roaring(${roaring_VERSION_cudf}) +find_and_configure_roaring(${roaring_VERSION_cudf} ${CUDF_EXCLUDE_DEPS_FROM_ALL}) diff --git a/cpp/cmake/thirdparty/get_dlpack.cmake b/cpp/cmake/thirdparty/get_dlpack.cmake index f935b0cb08e..9593ad50384 100644 --- a/cpp/cmake/thirdparty/get_dlpack.cmake +++ b/cpp/cmake/thirdparty/get_dlpack.cmake @@ -1,12 +1,12 @@ # ============================================================================= # cmake-format: off -# SPDX-FileCopyrightText: Copyright (c) 2020-2025, NVIDIA CORPORATION. +# SPDX-FileCopyrightText: Copyright (c) 2020-2026, NVIDIA CORPORATION. # SPDX-License-Identifier: Apache-2.0 # cmake-format: on # ============================================================================= # This function finds dlpack and sets any additional necessary environment variables. -function(find_and_configure_dlpack VERSION) +function(find_and_configure_dlpack VERSION EXCLUDE_FROM_ALL) include(${rapids-cmake-dir}/find/generate_module.cmake) rapids_find_generate_module(DLPACK HEADER_NAMES dlpack.h) @@ -17,6 +17,7 @@ function(find_and_configure_dlpack VERSION) GIT_TAG v${VERSION} GIT_SHALLOW TRUE DOWNLOAD_ONLY TRUE + EXCLUDE_FROM_ALL ${EXCLUDE_FROM_ALL} OPTIONS "BUILD_MOCK OFF" ) @@ -31,4 +32,8 @@ endfunction() set(CUDF_MIN_VERSION_dlpack 0.8) -find_and_configure_dlpack(${CUDF_MIN_VERSION_dlpack}) +if(NOT DEFINED CUDF_EXCLUDE_DEPS_FROM_ALL) + set(CUDF_EXCLUDE_DEPS_FROM_ALL OFF) +endif() + +find_and_configure_dlpack(${CUDF_MIN_VERSION_dlpack} ${CUDF_EXCLUDE_DEPS_FROM_ALL}) diff --git a/cpp/cmake/thirdparty/get_flatbuffers.cmake b/cpp/cmake/thirdparty/get_flatbuffers.cmake index 618730ef97e..9a178429a0b 100644 --- a/cpp/cmake/thirdparty/get_flatbuffers.cmake +++ b/cpp/cmake/thirdparty/get_flatbuffers.cmake @@ -6,8 +6,7 @@ # ============================================================================= # Use CPM to find or clone flatbuffers -function(find_and_configure_flatbuffers VERSION) - set(_exclude_from_all EXCLUDE_FROM_ALL ${BUILD_SHARED_LIBS}) +function(find_and_configure_flatbuffers VERSION EXCLUDE_FROM_ALL) rapids_cpm_find( flatbuffers ${VERSION} @@ -15,7 +14,8 @@ function(find_and_configure_flatbuffers VERSION) CPM_ARGS GIT_REPOSITORY https://github.com/google/flatbuffers.git GIT_TAG v${VERSION} - GIT_SHALLOW TRUE ${_exclude_from_all} + GIT_SHALLOW TRUE + EXCLUDE_FROM_ALL ${EXCLUDE_FROM_ALL} OPTIONS "FLATBUFFERS_BUILD_TESTS OFF" ) @@ -25,4 +25,4 @@ function(find_and_configure_flatbuffers VERSION) endfunction() -find_and_configure_flatbuffers(24.3.25) +find_and_configure_flatbuffers(24.3.25 ${CUDF_EXCLUDE_DEPS_FROM_ALL}) From 56fcec020542c738e76baadb6cf02ebc42bc934f Mon Sep 17 00:00:00 2001 From: Vyas Ramasubramani Date: Tue, 5 May 2026 10:30:39 -0700 Subject: [PATCH 04/21] Align remaining dependency wrappers with centralized flags Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus --- cpp/cmake/thirdparty/get_cucollections.cmake | 2 +- cpp/cmake/thirdparty/get_kvikio.cmake | 4 ++-- cpp/cmake/thirdparty/get_thread_pool.cmake | 4 ++-- cpp/cmake/thirdparty/get_zstd.cmake | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/cpp/cmake/thirdparty/get_cucollections.cmake b/cpp/cmake/thirdparty/get_cucollections.cmake index cb02192012d..0a479ff8957 100644 --- a/cpp/cmake/thirdparty/get_cucollections.cmake +++ b/cpp/cmake/thirdparty/get_cucollections.cmake @@ -9,7 +9,7 @@ function(find_and_configure_cucollections) include(${rapids-cmake-dir}/cpm/cuco.cmake) - rapids_cpm_cuco(BUILD_EXPORT_SET cudf-exports) + rapids_cpm_cuco(${CUDF_EXCLUDE_DEPS_FROM_ALL_FLAG}) endfunction() find_and_configure_cucollections() diff --git a/cpp/cmake/thirdparty/get_kvikio.cmake b/cpp/cmake/thirdparty/get_kvikio.cmake index 9b30248905f..7523cdae39f 100644 --- a/cpp/cmake/thirdparty/get_kvikio.cmake +++ b/cpp/cmake/thirdparty/get_kvikio.cmake @@ -7,7 +7,6 @@ # This function finds KvikIO function(find_and_configure_kvikio VERSION) - set(_exclude_from_all EXCLUDE_FROM_ALL ${BUILD_SHARED_LIBS}) rapids_cpm_find( kvikio ${VERSION} @@ -15,7 +14,8 @@ function(find_and_configure_kvikio VERSION) CPM_ARGS GIT_REPOSITORY https://github.com/rapidsai/kvikio.git GIT_TAG "${RAPIDS_BRANCH}" - GIT_SHALLOW TRUE SOURCE_SUBDIR cpp ${_exclude_from_all} + GIT_SHALLOW TRUE SOURCE_SUBDIR cpp + EXCLUDE_FROM_ALL ${CUDF_EXCLUDE_DEPS_FROM_ALL} OPTIONS "KvikIO_BUILD_EXAMPLES OFF" "KvikIO_REMOTE_SUPPORT ${CUDF_KVIKIO_REMOTE_IO}" "BUILD_SHARED_LIBS OFF" ) diff --git a/cpp/cmake/thirdparty/get_thread_pool.cmake b/cpp/cmake/thirdparty/get_thread_pool.cmake index 4840db56c9a..5bcaf7e3ad5 100644 --- a/cpp/cmake/thirdparty/get_thread_pool.cmake +++ b/cpp/cmake/thirdparty/get_thread_pool.cmake @@ -1,6 +1,6 @@ # ============================================================================= # cmake-format: off -# SPDX-FileCopyrightText: Copyright (c) 2024-2025, NVIDIA CORPORATION. +# SPDX-FileCopyrightText: Copyright (c) 2024-2026, NVIDIA CORPORATION. # SPDX-License-Identifier: Apache-2.0 # cmake-format: on # ============================================================================= @@ -11,7 +11,7 @@ function(find_and_configure_thread_pool) include(${rapids-cmake-dir}/cpm/bs_thread_pool.cmake) # Find or install thread-pool - rapids_cpm_bs_thread_pool() + rapids_cpm_bs_thread_pool(${CUDF_EXCLUDE_DEPS_FROM_ALL_FLAG}) endfunction() diff --git a/cpp/cmake/thirdparty/get_zstd.cmake b/cpp/cmake/thirdparty/get_zstd.cmake index 50ae831337e..01e62e5c455 100644 --- a/cpp/cmake/thirdparty/get_zstd.cmake +++ b/cpp/cmake/thirdparty/get_zstd.cmake @@ -7,7 +7,6 @@ # Use CPM to find or clone libzstd function(find_and_configure_zstd) - set(_exclude_from_all EXCLUDE_FROM_ALL ${BUILD_SHARED_LIBS}) set(CPM_DOWNLOAD_zstd ON) rapids_cpm_find( @@ -16,7 +15,8 @@ function(find_and_configure_zstd) CPM_ARGS GIT_REPOSITORY https://github.com/facebook/zstd.git GIT_TAG v1.5.7 - GIT_SHALLOW FALSE SOURCE_SUBDIR build/cmake ${_exclude_from_all} + GIT_SHALLOW FALSE SOURCE_SUBDIR build/cmake + EXCLUDE_FROM_ALL ${CUDF_EXCLUDE_DEPS_FROM_ALL} OPTIONS "ZSTD_BUILD_STATIC ON" "ZSTD_BUILD_SHARED OFF" "ZSTD_BUILD_TESTS OFF" "ZSTD_BUILD_PROGRAMS OFF" "BUILD_SHARED_LIBS OFF" ) From 72ac0f3061b2d1a0855d061ec791a220fb1fd673 Mon Sep 17 00:00:00 2001 From: Vyas Ramasubramani Date: Tue, 5 May 2026 10:31:00 -0700 Subject: [PATCH 05/21] Update test dependency exclusion settings Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus --- cpp/tests/CMakeLists.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/cpp/tests/CMakeLists.txt b/cpp/tests/CMakeLists.txt index 68cde65c57b..b680d1759fa 100644 --- a/cpp/tests/CMakeLists.txt +++ b/cpp/tests/CMakeLists.txt @@ -85,7 +85,9 @@ endfunction() # ################################################################################################## # No need to install Arrow libs when only the final test executables are shipped. -set(CUDF_EXCLUDE_ARROW_FROM_ALL ON) +set(CUDF_INSTALL_LIBRARY_DEPS OFF) +set(CUDF_EXCLUDE_DEPS_FROM_ALL ON) +set(CUDF_EXCLUDE_DEPS_FROM_ALL_FLAG EXCLUDE_FROM_ALL) set(CUDF_ENABLE_ARROW_COMPUTE ON) include(../cmake/thirdparty/get_arrow.cmake) From 1bac96aa57d35441b8833e187cce9880865b791c Mon Sep 17 00:00:00 2001 From: Vyas Ramasubramani Date: Tue, 5 May 2026 10:31:24 -0700 Subject: [PATCH 06/21] Ensure install metadata for Java and stream tests Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus --- dependencies.yaml | 1 + java/src/main/native/CMakeLists.txt | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/dependencies.yaml b/dependencies.yaml index 2ffd2e9318f..c87114b6541 100644 --- a/dependencies.yaml +++ b/dependencies.yaml @@ -154,6 +154,7 @@ files: - build_base - cuda - cuda_version + - depends_on_rapids_logger docs: output: none includes: diff --git a/java/src/main/native/CMakeLists.txt b/java/src/main/native/CMakeLists.txt index 1e7df3802b9..ba4c42d3116 100644 --- a/java/src/main/native/CMakeLists.txt +++ b/java/src/main/native/CMakeLists.txt @@ -92,6 +92,10 @@ get_target_property(CUDF_CUDA_FLAGS cudf::cudf CUDF_CUDA_FLAGS) get_target_property(CUDF_CXX_DEFINITIONS cudf::cudf CUDF_CXX_DEFINITIONS) get_target_property(CUDF_CUDA_DEFINITIONS cudf::cudf CUDF_CUDA_DEFINITIONS) +# The Java/JNI build always triggers static builds of both libcudf itself and its dependencies, and +# therefore needs all of them to be installed to link against later. +set(CUDF_INSTALL_LIBRARY_DEPS ON) + # ################################################################################################## # * nvtx3 and nvcomp------------------------------------------------------------------------------- # Reuse any cached package that is already available after configuring/installing libcudf. Only From 039fbf7d338297067b0fbc22b770a6720b30227f Mon Sep 17 00:00:00 2001 From: Vyas Ramasubramani Date: Tue, 5 May 2026 10:47:17 -0700 Subject: [PATCH 07/21] Just export nvtx for now --- cpp/CMakeLists.txt | 6 +++--- cpp/cmake/thirdparty/get_nvtx.cmake | 4 ++++ 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt index f1738716dd1..fd9614c657a 100644 --- a/cpp/CMakeLists.txt +++ b/cpp/CMakeLists.txt @@ -334,6 +334,9 @@ create_logger_macros(CUDF "cudf::default_logger()" include/cudf) # find jitify include(cmake/thirdparty/get_jitify.cmake) +# find NVTX +include(cmake/thirdparty/get_nvtx.cmake) + # find nvCOMP include(cmake/thirdparty/get_nvcomp.cmake) @@ -343,9 +346,6 @@ include(cmake/thirdparty/get_cccl.cmake) # find rmm, should come after including CCCL to allow overriding the CCCL version used for testing include(cmake/thirdparty/get_rmm.cmake) -# find NVTX, after rmm so we defer to rmm to decide the interface since nvtx is private for cudf -include(cmake/thirdparty/get_nvtx.cmake) - # find croaring include(cmake/thirdparty/get_croaring.cmake) diff --git a/cpp/cmake/thirdparty/get_nvtx.cmake b/cpp/cmake/thirdparty/get_nvtx.cmake index bd49db12d75..d3386c40f96 100644 --- a/cpp/cmake/thirdparty/get_nvtx.cmake +++ b/cpp/cmake/thirdparty/get_nvtx.cmake @@ -10,6 +10,10 @@ function(find_and_configure_nvtx) include(${rapids-cmake-dir}/cpm/nvtx3.cmake) + # TODO: nvtx is linked privately, so we shouldn't have to export it, but it is part of rmm's + # public export set and we run into ordering/first find wins issues if we don't export it in cudf + # as well. We should be able to remove this once we have a better solution for handling rmm's + # export sets consistently from cudf. rapids_cpm_nvtx3( BUILD_EXPORT_SET cudf-exports INSTALL_EXPORT_SET cudf-exports ${CUDF_EXCLUDE_DEPS_FROM_ALL_FLAG} From 7b85d4f4d36e6ce40e68d9c1c2a1eda943e1bc9b Mon Sep 17 00:00:00 2001 From: Vyas Ramasubramani Date: Tue, 5 May 2026 11:10:48 -0700 Subject: [PATCH 08/21] Fix and clean up rmm args --- cpp/cmake/thirdparty/get_rmm.cmake | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/cpp/cmake/thirdparty/get_rmm.cmake b/cpp/cmake/thirdparty/get_rmm.cmake index ebb02a5f74b..911d0da8bd5 100644 --- a/cpp/cmake/thirdparty/get_rmm.cmake +++ b/cpp/cmake/thirdparty/get_rmm.cmake @@ -9,19 +9,15 @@ function(find_and_configure_rmm BUILD_SHARED EXCLUDE_FROM_ALL) include(${rapids-cmake-dir}/cpm/rmm.cmake) - if(EXCLUDE_FROM_ALL) - set(_exclude_flag EXCLUDE_FROM_ALL) - else() - set(_exclude_flag) - endif() - # Find or install RMM. set(_rmm_args BUILD_EXPORT_SET cudf-exports) - if(NOT EXCLUDE_FROM_ALL) + if(EXCLUDE_FROM_ALL) + list(APPEND _rmm_args EXCLUDE_FROM_ALL) + else() list(APPEND _rmm_args INSTALL_EXPORT_SET cudf-exports) endif() - rapids_cpm_rmm(${_rmm_args} ${_exclude_flag} CPM_ARGS OPTIONS "BUILD_SHARED_LIBS ${BUILD_SHARED}") + rapids_cpm_rmm(${_rmm_args} CPM_ARGS OPTIONS "BUILD_SHARED_LIBS ${BUILD_SHARED}") endfunction() -find_and_configure_rmm(${CUDF_DEPS_BUILD_SHARED} ${CUDF_EXCLUDE_DEPS_FROM_ALL}) +find_and_configure_rmm(${CUDF_DEPS_BUILD_SHARED}) From 40cab9b749d9b9b04433545a4c6ab65ae1e432da Mon Sep 17 00:00:00 2001 From: Vyas Ramasubramani Date: Tue, 5 May 2026 11:20:07 -0700 Subject: [PATCH 09/21] One more fix --- cpp/cmake/thirdparty/get_rmm.cmake | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/cpp/cmake/thirdparty/get_rmm.cmake b/cpp/cmake/thirdparty/get_rmm.cmake index 911d0da8bd5..5b6f20440fe 100644 --- a/cpp/cmake/thirdparty/get_rmm.cmake +++ b/cpp/cmake/thirdparty/get_rmm.cmake @@ -20,4 +20,6 @@ function(find_and_configure_rmm BUILD_SHARED EXCLUDE_FROM_ALL) endfunction() -find_and_configure_rmm(${CUDF_DEPS_BUILD_SHARED}) +# The EXCLUDE_FROM_ALL functionality is not leveraged for RMM since it is a public dependency. +# Future work will add more granular handling of exclusion for public dependencies. +find_and_configure_rmm(${CUDF_DEPS_BUILD_SHARED} OFF) From 4fbc4e12e2f00ff12dcbf36e3d13b673638f06c9 Mon Sep 17 00:00:00 2001 From: Vyas Ramasubramani Date: Tue, 5 May 2026 12:41:02 -0700 Subject: [PATCH 10/21] Absorb rmm and rapids_logger into shared libcudf via whole-archive When building shared libcudf with static dependencies, rmm and rapids_logger are absorbed into the shared library using --whole-archive to ensure all symbols are exported. This commit adds: - Conditional WHOLE_ARCHIVE linkage for rmm/rapids_logger - BUILD_INTERFACE wrapping to hide absorbed static deps from install - Transitive dependency promotion for absorbed libraries - Export set merging (rmm-exports/rapids_logger-exports into cudf-exports) - Conda/pre-installed shared library detection (TYPE introspection) - DSO header installation for standalone mode - get_rmm.cmake: full EXCLUDE_FROM_ALL support + conda fix - get_nvtx.cmake: remove export sets (rmm handles nvtx publicly) - rapids_logger: conditional static build + export package for conda --- cpp/CMakeLists.txt | 134 ++++++++++++++++++++++++++-- cpp/cmake/thirdparty/get_nvtx.cmake | 9 +- cpp/cmake/thirdparty/get_rmm.cmake | 37 ++++++-- 3 files changed, 160 insertions(+), 20 deletions(-) diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt index a27fd81e88a..fe040e11365 100644 --- a/cpp/CMakeLists.txt +++ b/cpp/CMakeLists.txt @@ -326,16 +326,32 @@ endif() rapids_cpm_init() include(${rapids-cmake-dir}/cpm/rapids_logger.cmake) -rapids_cpm_rapids_logger(BUILD_EXPORT_SET cudf-exports INSTALL_EXPORT_SET cudf-exports) +set(_rapids_logger_args BUILD_EXPORT_SET cudf-exports) +if(CUDF_INSTALL_LIBRARY_DEPS) + list(APPEND _rapids_logger_args INSTALL_EXPORT_SET cudf-exports) +endif() +if(NOT CUDF_BUILD_STATIC_DEPS STREQUAL "OFF") + list(APPEND _rapids_logger_args ${CUDF_EXCLUDE_DEPS_FROM_ALL_FLAG} CPM_ARGS OPTIONS + "BUILD_SHARED_LIBS OFF" + ) +endif() +rapids_cpm_rapids_logger(${_rapids_logger_args}) + +# If rapids_logger was found as a pre-existing shared library (e.g. conda), we need +# find_dependency(rapids_logger) in the installed config even when CUDF_INSTALL_LIBRARY_DEPS is OFF. +if(NOT CUDF_INSTALL_LIBRARY_DEPS) + get_target_property(_rapids_logger_type rapids_logger::rapids_logger TYPE) + if(NOT _rapids_logger_type STREQUAL "STATIC_LIBRARY") + include("${rapids-cmake-dir}/export/package.cmake") + rapids_export_package(INSTALL rapids_logger cudf-exports VERSION ${rapids_logger_VERSION}) + endif() +endif() create_logger_macros(CUDF "cudf::default_logger()" include/cudf) # find jitify include(cmake/thirdparty/get_jitify.cmake) -# find NVTX -include(cmake/thirdparty/get_nvtx.cmake) - # find nvCOMP include(cmake/thirdparty/get_nvcomp.cmake) @@ -345,6 +361,9 @@ include(cmake/thirdparty/get_cccl.cmake) # find rmm, should come after including CCCL to allow overriding the CCCL version used for testing include(cmake/thirdparty/get_rmm.cmake) +# find NVTX, after rmm so we defer to rmm to decide the interface since nvtx is private for cudf +include(cmake/thirdparty/get_nvtx.cmake) + # find croaring include(cmake/thirdparty/get_croaring.cmake) @@ -1068,11 +1087,100 @@ add_dependencies(cudf jitify_preprocess_run) # Specify the target module library dependencies target_link_libraries( cudf - PUBLIC CCCL::CCCL rapids_logger::rapids_logger rmm::rmm $ + PUBLIC CCCL::CCCL $ PRIVATE $ $ ZLIB::ZLIB ${CUDF_nvcomp_TARGET} kvikio::kvikio ${CUDF_nanoarrow_TARGET} zstd ) +# Public deps with conditional WHOLE_ARCHIVE for shared builds. --whole-archive ensures all symbols +# from static rmm/rapids_logger are exported from shared libcudf. This is a no-op when those deps +# are themselves shared libraries. +# +# When building a shared libcudf with static deps that are absorbed via whole-archive, the deps +# should not appear in the installed interface -- consumers link only to libcudf.so. However, if we +# found a pre-existing shared library (e.g. in conda), it is NOT absorbed and must remain in the +# installed interface so consumers can link it at runtime. +set(_rmm_link rmm::rmm) +set(_rapids_logger_link rapids_logger::rapids_logger) +if(BUILD_SHARED_LIBS) + set(_rmm_link $) + set(_rapids_logger_link $) + # Only hide from install interface if the dep is actually a static library absorbed into cudf. If + # it's a shared library (found pre-installed), it must remain in the public interface. + get_target_property(_rmm_type rmm::rmm TYPE) + get_target_property(_rapids_logger_type rapids_logger::rapids_logger TYPE) + if(_rmm_type STREQUAL "STATIC_LIBRARY") + set(_rmm_link $) + endif() + if(_rapids_logger_type STREQUAL "STATIC_LIBRARY") + set(_rapids_logger_link $) + endif() +endif() + +# When a static library is absorbed into shared libcudf via whole-archive, its own public transitive +# dependencies must be promoted into cudf's installed interface. The absorbed library itself is +# hidden (BUILD_INTERFACE), but consumers still need its deps at link time. For example, rmm's +# public deps include CUDA::cudart, nvtx3, etc. We also merge the absorbed library's export set +# metadata (find_dependency calls, global targets) into cudf-exports so the installed config can +# locate those transitive deps. +foreach(_absorbed_target rmm::rmm rapids_logger::rapids_logger) + get_target_property(_target_type ${_absorbed_target} TYPE) + if(BUILD_SHARED_LIBS AND _target_type STREQUAL "STATIC_LIBRARY") + get_target_property(_iface_libs ${_absorbed_target} INTERFACE_LINK_LIBRARIES) + if(_iface_libs) + target_link_libraries(cudf PUBLIC ${_iface_libs}) + endif() + endif() +endforeach() + +# Merge absorbed libraries' export sets into cudf-exports so installed config has find_dependency() +# calls for all transitive deps (e.g. nvtx3, CUDAToolkit from rmm-exports). +if(BUILD_SHARED_LIBS) + foreach(_src_export_set rmm-exports rapids_logger-exports) + foreach(_mode build install) + set(_src_target rapids_export_${_mode}_${_src_export_set}) + set(_dst_target rapids_export_${_mode}_cudf-exports) + if(TARGET ${_src_target} AND TARGET ${_dst_target}) + get_property( + _pkg_names + TARGET ${_src_target} + PROPERTY "PACKAGE_NAMES" + ) + foreach(_pkg IN LISTS _pkg_names) + # Copy the per-package cmake file into cudf-exports directory + set(_src_file + "${CMAKE_BINARY_DIR}/rapids-cmake/${_src_export_set}/${_mode}/package_${_pkg}.cmake" + ) + set(_dst_file + "${CMAKE_BINARY_DIR}/rapids-cmake/cudf-exports/${_mode}/package_${_pkg}.cmake" + ) + if(EXISTS "${_src_file}" AND NOT EXISTS "${_dst_file}") + configure_file("${_src_file}" "${_dst_file}" COPYONLY) + endif() + set_property( + TARGET ${_dst_target} + APPEND + PROPERTY "PACKAGE_NAMES" "${_pkg}" + ) + endforeach() + get_property( + _global_tgts + TARGET ${_src_target} + PROPERTY "GLOBAL_TARGETS" + ) + if(_global_tgts) + set_property( + TARGET ${_dst_target} + APPEND + PROPERTY "GLOBAL_TARGETS" ${_global_tgts} + ) + endif() + endif() + endforeach() + endforeach() +endif() +target_link_libraries(cudf PUBLIC ${_rapids_logger_link} ${_rmm_link}) + # Add Conda library, and include paths if specified if(TARGET conda_env) target_link_libraries(cudf PRIVATE conda_env) @@ -1302,6 +1410,22 @@ install(DIRECTORY ${CUDF_SOURCE_DIR}/include/cudf ${CUDF_SOURCE_DIR}/include/cud ${CUDF_SOURCE_DIR}/include/nvtext DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} ) +# In standalone DSO mode, rmm and rapids_logger are absorbed into libcudf via whole-archive. Their +# headers are still needed by consumers, so install them manually. +if(NOT CUDF_INSTALL_LIBRARY_DEPS) + # rmm uses SOURCE_SUBDIR cpp, so headers are at ${rmm_SOURCE_DIR}/cpp/include/rmm/ Generated + # headers (version_config.hpp, logger_macros.hpp) are at ${rmm_BINARY_DIR}/include/rmm/ + if(rmm_SOURCE_DIR) + install(DIRECTORY ${rmm_SOURCE_DIR}/cpp/include/rmm DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) + install(DIRECTORY ${rmm_BINARY_DIR}/include/rmm DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) + endif() + if(rapids_logger_SOURCE_DIR) + install(DIRECTORY ${rapids_logger_SOURCE_DIR}/include/rapids_logger + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} + ) + endif() +endif() + if(CUDF_BUILD_STREAMS_TEST_UTIL) install( TARGETS cudf_identify_stream_usage_mode_cudf diff --git a/cpp/cmake/thirdparty/get_nvtx.cmake b/cpp/cmake/thirdparty/get_nvtx.cmake index d3386c40f96..be8c373cc13 100644 --- a/cpp/cmake/thirdparty/get_nvtx.cmake +++ b/cpp/cmake/thirdparty/get_nvtx.cmake @@ -10,14 +10,7 @@ function(find_and_configure_nvtx) include(${rapids-cmake-dir}/cpm/nvtx3.cmake) - # TODO: nvtx is linked privately, so we shouldn't have to export it, but it is part of rmm's - # public export set and we run into ordering/first find wins issues if we don't export it in cudf - # as well. We should be able to remove this once we have a better solution for handling rmm's - # export sets consistently from cudf. - rapids_cpm_nvtx3( - BUILD_EXPORT_SET cudf-exports INSTALL_EXPORT_SET cudf-exports - ${CUDF_EXCLUDE_DEPS_FROM_ALL_FLAG} - ) + rapids_cpm_nvtx3(${CUDF_EXCLUDE_DEPS_FROM_ALL_FLAG}) endfunction() diff --git a/cpp/cmake/thirdparty/get_rmm.cmake b/cpp/cmake/thirdparty/get_rmm.cmake index 5b6f20440fe..9594b82d820 100644 --- a/cpp/cmake/thirdparty/get_rmm.cmake +++ b/cpp/cmake/thirdparty/get_rmm.cmake @@ -9,17 +9,40 @@ function(find_and_configure_rmm BUILD_SHARED EXCLUDE_FROM_ALL) include(${rapids-cmake-dir}/cpm/rmm.cmake) - # Find or install RMM. - set(_rmm_args BUILD_EXPORT_SET cudf-exports) if(EXCLUDE_FROM_ALL) - list(APPEND _rmm_args EXCLUDE_FROM_ALL) + set(_exclude_flag EXCLUDE_FROM_ALL) else() + set(_exclude_flag) + endif() + + # Find or install RMM. + set(_rmm_args BUILD_EXPORT_SET cudf-exports) + if(NOT EXCLUDE_FROM_ALL) list(APPEND _rmm_args INSTALL_EXPORT_SET cudf-exports) endif() - rapids_cpm_rmm(${_rmm_args} CPM_ARGS OPTIONS "BUILD_SHARED_LIBS ${BUILD_SHARED}") + rapids_cpm_rmm(${_rmm_args} ${_exclude_flag} CPM_ARGS OPTIONS "BUILD_SHARED_LIBS ${BUILD_SHARED}") + + # If rmm was found as a pre-existing shared library (e.g. conda), we need find_dependency(rmm) in + # the installed config even when EXCLUDE_FROM_ALL is set. EXCLUDE_FROM_ALL controls whether CPM- + # built targets are installed, but a pre-existing shared library is not absorbed into libcudf and + # must be findable by downstream consumers. + if(EXCLUDE_FROM_ALL) + get_target_property(_rmm_type rmm::rmm TYPE) + if(NOT _rmm_type STREQUAL "STATIC_LIBRARY") + include("${rapids-cmake-dir}/export/package.cmake") + rapids_export_package(INSTALL rmm cudf-exports VERSION ${rmm_VERSION}) + endif() + endif() + # Propagate rmm source/binary dirs to parent scope for header installation + set(rmm_SOURCE_DIR + "${rmm_SOURCE_DIR}" + PARENT_SCOPE + ) + set(rmm_BINARY_DIR + "${rmm_BINARY_DIR}" + PARENT_SCOPE + ) endfunction() -# The EXCLUDE_FROM_ALL functionality is not leveraged for RMM since it is a public dependency. -# Future work will add more granular handling of exclusion for public dependencies. -find_and_configure_rmm(${CUDF_DEPS_BUILD_SHARED} OFF) +find_and_configure_rmm(${CUDF_DEPS_BUILD_SHARED} ${CUDF_EXCLUDE_DEPS_FROM_ALL}) From f91c272fa9943caa2d8a6298aaf76c0aa8f2be39 Mon Sep 17 00:00:00 2001 From: Vyas Ramasubramani Date: Tue, 5 May 2026 13:43:51 -0700 Subject: [PATCH 11/21] Only apply WHOLE_ARCHIVE when linking a static library WHOLE_ARCHIVE is only meaningful when absorbing a static library into a shared library. Applying it to a shared library target triggers CMake warnings. Gate both WHOLE_ARCHIVE and BUILD_INTERFACE behind the TYPE==STATIC_LIBRARY check so the genex is never generated for pre-installed shared deps (e.g. conda rmm/rapids_logger). --- cpp/CMakeLists.txt | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt index fe040e11365..d2c0176d102 100644 --- a/cpp/CMakeLists.txt +++ b/cpp/CMakeLists.txt @@ -1093,8 +1093,8 @@ target_link_libraries( ) # Public deps with conditional WHOLE_ARCHIVE for shared builds. --whole-archive ensures all symbols -# from static rmm/rapids_logger are exported from shared libcudf. This is a no-op when those deps -# are themselves shared libraries. +# from static rmm/rapids_logger are exported from shared libcudf. WHOLE_ARCHIVE is only applied when +# the dep is actually a static library to avoid CMake warnings for shared library targets. # # When building a shared libcudf with static deps that are absorbed via whole-archive, the deps # should not appear in the installed interface -- consumers link only to libcudf.so. However, if we @@ -1103,17 +1103,15 @@ target_link_libraries( set(_rmm_link rmm::rmm) set(_rapids_logger_link rapids_logger::rapids_logger) if(BUILD_SHARED_LIBS) - set(_rmm_link $) - set(_rapids_logger_link $) - # Only hide from install interface if the dep is actually a static library absorbed into cudf. If - # it's a shared library (found pre-installed), it must remain in the public interface. get_target_property(_rmm_type rmm::rmm TYPE) get_target_property(_rapids_logger_type rapids_logger::rapids_logger TYPE) if(_rmm_type STREQUAL "STATIC_LIBRARY") - set(_rmm_link $) + set(_rmm_link $>) endif() if(_rapids_logger_type STREQUAL "STATIC_LIBRARY") - set(_rapids_logger_link $) + set(_rapids_logger_link + $> + ) endif() endif() From 8621029ae96b3c858673ad6915187ad31e9992c8 Mon Sep 17 00:00:00 2001 From: Vyas Ramasubramani Date: Tue, 5 May 2026 14:36:15 -0700 Subject: [PATCH 12/21] First simplification --- cpp/CMakeLists.txt | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt index d2c0176d102..01250192904 100644 --- a/cpp/CMakeLists.txt +++ b/cpp/CMakeLists.txt @@ -327,9 +327,6 @@ rapids_cpm_init() include(${rapids-cmake-dir}/cpm/rapids_logger.cmake) set(_rapids_logger_args BUILD_EXPORT_SET cudf-exports) -if(CUDF_INSTALL_LIBRARY_DEPS) - list(APPEND _rapids_logger_args INSTALL_EXPORT_SET cudf-exports) -endif() if(NOT CUDF_BUILD_STATIC_DEPS STREQUAL "OFF") list(APPEND _rapids_logger_args ${CUDF_EXCLUDE_DEPS_FROM_ALL_FLAG} CPM_ARGS OPTIONS "BUILD_SHARED_LIBS OFF" @@ -337,14 +334,13 @@ if(NOT CUDF_BUILD_STATIC_DEPS STREQUAL "OFF") endif() rapids_cpm_rapids_logger(${_rapids_logger_args}) -# If rapids_logger was found as a pre-existing shared library (e.g. conda), we need -# find_dependency(rapids_logger) in the installed config even when CUDF_INSTALL_LIBRARY_DEPS is OFF. -if(NOT CUDF_INSTALL_LIBRARY_DEPS) - get_target_property(_rapids_logger_type rapids_logger::rapids_logger TYPE) - if(NOT _rapids_logger_type STREQUAL "STATIC_LIBRARY") - include("${rapids-cmake-dir}/export/package.cmake") - rapids_export_package(INSTALL rapids_logger cudf-exports VERSION ${rapids_logger_VERSION}) - endif() +# If dynamically linking to a preexisting rapids_logger library then find_dependency(rapids_logger) +# must be in the installed config when CUDF_INSTALL_LIBRARY_DEPS is OFF. If it's ON then we always +# export +get_target_property(_rapids_logger_type rapids_logger::rapids_logger TYPE) +if(CUDF_INSTALL_LIBRARY_DEPS OR NOT _rapids_logger_type STREQUAL "STATIC_LIBRARY") + include("${rapids-cmake-dir}/export/package.cmake") + rapids_export_package(INSTALL rapids_logger cudf-exports VERSION ${rapids_logger_VERSION}) endif() create_logger_macros(CUDF "cudf::default_logger()" include/cudf) @@ -352,6 +348,9 @@ create_logger_macros(CUDF "cudf::default_logger()" include/cudf) # find jitify include(cmake/thirdparty/get_jitify.cmake) +# find NVTX +include(cmake/thirdparty/get_nvtx.cmake) + # find nvCOMP include(cmake/thirdparty/get_nvcomp.cmake) @@ -361,9 +360,6 @@ include(cmake/thirdparty/get_cccl.cmake) # find rmm, should come after including CCCL to allow overriding the CCCL version used for testing include(cmake/thirdparty/get_rmm.cmake) -# find NVTX, after rmm so we defer to rmm to decide the interface since nvtx is private for cudf -include(cmake/thirdparty/get_nvtx.cmake) - # find croaring include(cmake/thirdparty/get_croaring.cmake) From 7d6c383b2b5969ceec8d9411f9fc36f7abf298be Mon Sep 17 00:00:00 2001 From: Vyas Ramasubramani Date: Tue, 5 May 2026 15:19:31 -0700 Subject: [PATCH 13/21] Second simplification --- cpp/CMakeLists.txt | 114 ++++++++++++++++----------------------------- 1 file changed, 39 insertions(+), 75 deletions(-) diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt index 01250192904..54e006712c9 100644 --- a/cpp/CMakeLists.txt +++ b/cpp/CMakeLists.txt @@ -1088,88 +1088,52 @@ target_link_libraries( ${CUDF_nvcomp_TARGET} kvikio::kvikio ${CUDF_nanoarrow_TARGET} zstd ) -# Public deps with conditional WHOLE_ARCHIVE for shared builds. --whole-archive ensures all symbols -# from static rmm/rapids_logger are exported from shared libcudf. WHOLE_ARCHIVE is only applied when -# the dep is actually a static library to avoid CMake warnings for shared library targets. -# -# When building a shared libcudf with static deps that are absorbed via whole-archive, the deps -# should not appear in the installed interface -- consumers link only to libcudf.so. However, if we -# found a pre-existing shared library (e.g. in conda), it is NOT absorbed and must remain in the -# installed interface so consumers can link it at runtime. -set(_rmm_link rmm::rmm) -set(_rapids_logger_link rapids_logger::rapids_logger) +# When building a shared libcudf with static deps, we absorb them via whole-archive linking so that +# their symbols are available to downstream users linking to libcudf.so without needing to link +# against them directly. In this scenario, its public transitive dependencies must be promoted into +# cudf's installed interface (consumers still need them at link time), and its export set metadata +# (find_dependency calls, global targets) is merged into cudf-exports. +set(_absorbed_deps rmm rapids_logger) +foreach(_dep IN LISTS _absorbed_deps) + set(_${_dep}_link ${_dep}::${_dep}) +endforeach() if(BUILD_SHARED_LIBS) - get_target_property(_rmm_type rmm::rmm TYPE) - get_target_property(_rapids_logger_type rapids_logger::rapids_logger TYPE) - if(_rmm_type STREQUAL "STATIC_LIBRARY") - set(_rmm_link $>) - endif() - if(_rapids_logger_type STREQUAL "STATIC_LIBRARY") - set(_rapids_logger_link - $> - ) - endif() -endif() + foreach(_dep IN LISTS _absorbed_deps) + get_target_property(_target_type ${_dep}::${_dep} TYPE) + if(NOT _target_type STREQUAL "STATIC_LIBRARY") + continue() + endif() -# When a static library is absorbed into shared libcudf via whole-archive, its own public transitive -# dependencies must be promoted into cudf's installed interface. The absorbed library itself is -# hidden (BUILD_INTERFACE), but consumers still need its deps at link time. For example, rmm's -# public deps include CUDA::cudart, nvtx3, etc. We also merge the absorbed library's export set -# metadata (find_dependency calls, global targets) into cudf-exports so the installed config can -# locate those transitive deps. -foreach(_absorbed_target rmm::rmm rapids_logger::rapids_logger) - get_target_property(_target_type ${_absorbed_target} TYPE) - if(BUILD_SHARED_LIBS AND _target_type STREQUAL "STATIC_LIBRARY") - get_target_property(_iface_libs ${_absorbed_target} INTERFACE_LINK_LIBRARIES) + # Wrap with WHOLE_ARCHIVE + BUILD_INTERFACE so the static lib is absorbed into libcudf.so and + # hidden from the installed interface. + set(_${_dep}_link $>) + + # Promote the absorbed library's public transitive deps into cudf's public interface. + get_target_property(_iface_libs ${_dep}::${_dep} INTERFACE_LINK_LIBRARIES) if(_iface_libs) target_link_libraries(cudf PUBLIC ${_iface_libs}) endif() - endif() -endforeach() -# Merge absorbed libraries' export sets into cudf-exports so installed config has find_dependency() -# calls for all transitive deps (e.g. nvtx3, CUDAToolkit from rmm-exports). -if(BUILD_SHARED_LIBS) - foreach(_src_export_set rmm-exports rapids_logger-exports) - foreach(_mode build install) - set(_src_target rapids_export_${_mode}_${_src_export_set}) - set(_dst_target rapids_export_${_mode}_cudf-exports) - if(TARGET ${_src_target} AND TARGET ${_dst_target}) - get_property( - _pkg_names - TARGET ${_src_target} - PROPERTY "PACKAGE_NAMES" - ) - foreach(_pkg IN LISTS _pkg_names) - # Copy the per-package cmake file into cudf-exports directory - set(_src_file - "${CMAKE_BINARY_DIR}/rapids-cmake/${_src_export_set}/${_mode}/package_${_pkg}.cmake" - ) - set(_dst_file - "${CMAKE_BINARY_DIR}/rapids-cmake/cudf-exports/${_mode}/package_${_pkg}.cmake" - ) - if(EXISTS "${_src_file}" AND NOT EXISTS "${_dst_file}") - configure_file("${_src_file}" "${_dst_file}" COPYONLY) - endif() - set_property( - TARGET ${_dst_target} - APPEND - PROPERTY "PACKAGE_NAMES" "${_pkg}" - ) - endforeach() - get_property( - _global_tgts - TARGET ${_src_target} - PROPERTY "GLOBAL_TARGETS" - ) - if(_global_tgts) - set_property( - TARGET ${_dst_target} - APPEND - PROPERTY "GLOBAL_TARGETS" ${_global_tgts} - ) - endif() + # Merge the absorbed library's export set metadata into cudf-exports so the installed config has + # find_dependency() calls for all transitive deps (e.g. nvtx3, CUDAToolkit from rmm). + foreach(_mode BUILD INSTALL) + set(_src_target rapids_export_${_mode}_${_dep}-exports) + if(NOT TARGET ${_src_target}) + continue() endif() + get_property( + _pkg_names + TARGET ${_src_target} + PROPERTY "PACKAGE_NAMES" + ) + get_property( + _global_tgts + TARGET ${_src_target} + PROPERTY "GLOBAL_TARGETS" + ) + foreach(_pkg IN LISTS _pkg_names) + rapids_export_package(${_mode} ${_pkg} cudf-exports GLOBAL_TARGETS ${_global_tgts}) + endforeach() endforeach() endforeach() endif() From 156ff42fcb6eb7805d5821e81ee06b199ba759cb Mon Sep 17 00:00:00 2001 From: Vyas Ramasubramani Date: Tue, 5 May 2026 17:53:30 -0700 Subject: [PATCH 14/21] Fix nvtx export set and case sensitivity in export merging Two issues caused CI failure: 1. foreach(_mode BUILD INSTALL) used uppercase, but rapids-cmake export targets use lowercase names (rapids_export_build_*, rapids_export_install_*). The if(NOT TARGET) check silently skipped the entire merge block. 2. get_nvtx.cmake was missing BUILD_EXPORT_SET/INSTALL_EXPORT_SET args. When rmm is absorbed into libcudf, its public dep nvtx3-cpp must be in an export set for CMake's install(EXPORT) validation to pass. --- cpp/CMakeLists.txt | 2 +- cpp/cmake/thirdparty/get_nvtx.cmake | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt index 54e006712c9..1b9e97d6239 100644 --- a/cpp/CMakeLists.txt +++ b/cpp/CMakeLists.txt @@ -1116,7 +1116,7 @@ if(BUILD_SHARED_LIBS) # Merge the absorbed library's export set metadata into cudf-exports so the installed config has # find_dependency() calls for all transitive deps (e.g. nvtx3, CUDAToolkit from rmm). - foreach(_mode BUILD INSTALL) + foreach(_mode build install) set(_src_target rapids_export_${_mode}_${_dep}-exports) if(NOT TARGET ${_src_target}) continue() diff --git a/cpp/cmake/thirdparty/get_nvtx.cmake b/cpp/cmake/thirdparty/get_nvtx.cmake index be8c373cc13..181a906ab13 100644 --- a/cpp/cmake/thirdparty/get_nvtx.cmake +++ b/cpp/cmake/thirdparty/get_nvtx.cmake @@ -10,7 +10,13 @@ function(find_and_configure_nvtx) include(${rapids-cmake-dir}/cpm/nvtx3.cmake) - rapids_cpm_nvtx3(${CUDF_EXCLUDE_DEPS_FROM_ALL_FLAG}) + # nvtx3 is private for cudf, but it is a public dependency of rmm. When rmm is absorbed into + # libcudf via whole-archive, rmm's public transitive deps (including nvtx3-cpp) are promoted into + # cudf's public interface. CMake's export validation requires that nvtx3-cpp be in an export set. + rapids_cpm_nvtx3( + BUILD_EXPORT_SET cudf-exports INSTALL_EXPORT_SET cudf-exports + ${CUDF_EXCLUDE_DEPS_FROM_ALL_FLAG} + ) endfunction() From 245e1ce1de34848cc63ba0ae644f4d0f1823bd4c Mon Sep 17 00:00:00 2001 From: Vyas Ramasubramani Date: Tue, 5 May 2026 17:53:43 -0700 Subject: [PATCH 15/21] Filter absorbed deps from install export sets When static deps (rmm, rapids_logger) are absorbed into libcudf.so via whole-archive, they are not installed separately. The export-set merging loop was copying rmm-exports' install packages (including rapids_logger) into cudf-exports, producing a find_dependency(rapids_logger) that would fail for consumers of an installed standalone build. Skip packages matching _absorbed_deps names when merging install-side export set metadata. --- cpp/CMakeLists.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt index 1b9e97d6239..f4badf689c3 100644 --- a/cpp/CMakeLists.txt +++ b/cpp/CMakeLists.txt @@ -1132,6 +1132,11 @@ if(BUILD_SHARED_LIBS) PROPERTY "GLOBAL_TARGETS" ) foreach(_pkg IN LISTS _pkg_names) + # Skip packages that are themselves absorbed into libcudf — they won't be installed or + # findable at install time. + if(_mode STREQUAL "install" AND _pkg IN_LIST _absorbed_deps) + continue() + endif() rapids_export_package(${_mode} ${_pkg} cudf-exports GLOBAL_TARGETS ${_global_tgts}) endforeach() endforeach() From 8774c141710093f2a928b7683c59b50060b71925 Mon Sep 17 00:00:00 2001 From: Vyas Ramasubramani Date: Tue, 5 May 2026 18:35:37 -0700 Subject: [PATCH 16/21] Filter absorbed and private deps from promoted interface libraries When promoting an absorbed library's transitive deps into cudf's public interface, filter out deps that are themselves absorbed (already linked via whole-archive) and LINK_ONLY entries (private link deps already statically linked into the absorbed library). --- cpp/CMakeLists.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt index f4badf689c3..6806db970d5 100644 --- a/cpp/CMakeLists.txt +++ b/cpp/CMakeLists.txt @@ -1109,8 +1109,14 @@ if(BUILD_SHARED_LIBS) set(_${_dep}_link $>) # Promote the absorbed library's public transitive deps into cudf's public interface. + # Filter out deps that are themselves absorbed — they are already linked via whole-archive. + # Also filter LINK_ONLY entries — those are private link deps already statically linked in. get_target_property(_iface_libs ${_dep}::${_dep} INTERFACE_LINK_LIBRARIES) if(_iface_libs) + foreach(_absorbed IN LISTS _absorbed_deps) + list(REMOVE_ITEM _iface_libs ${_absorbed}::${_absorbed}) + endforeach() + list(FILTER _iface_libs EXCLUDE REGEX "\\\$ Date: Tue, 5 May 2026 21:37:26 -0700 Subject: [PATCH 17/21] Style --- cpp/CMakeLists.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt index 6806db970d5..38079e63fd0 100644 --- a/cpp/CMakeLists.txt +++ b/cpp/CMakeLists.txt @@ -1108,9 +1108,9 @@ if(BUILD_SHARED_LIBS) # hidden from the installed interface. set(_${_dep}_link $>) - # Promote the absorbed library's public transitive deps into cudf's public interface. - # Filter out deps that are themselves absorbed — they are already linked via whole-archive. - # Also filter LINK_ONLY entries — those are private link deps already statically linked in. + # Promote the absorbed library's public transitive deps into cudf's public interface. Filter out + # deps that are themselves absorbed — they are already linked via whole-archive. Also filter + # LINK_ONLY entries — those are private link deps already statically linked in. get_target_property(_iface_libs ${_dep}::${_dep} INTERFACE_LINK_LIBRARIES) if(_iface_libs) foreach(_absorbed IN LISTS _absorbed_deps) From 5ec4b0fd179b687fe39590b6124e8721a95f1e30 Mon Sep 17 00:00:00 2001 From: Vyas Ramasubramani Date: Wed, 6 May 2026 08:36:29 -0700 Subject: [PATCH 18/21] feat: bundle nvtx3 headers and remove from install export sets nvtx3 is header-only. By installing its headers directly into cudf's install tree, consumers find them via cudf's include path without needing find_dependency(nvtx3) or any separate nvtx3 package. Changes: - get_nvtx.cmake: remove INSTALL_EXPORT_SET; propagate nvtx3_SOURCE_DIR to parent scope for header installation - get_rmm.cmake: strip nvtx3::nvtx3-cpp from rmm's INTERFACE_LINK_LIBRARIES after fetch, preventing the absorption loop from promoting it into cudf's installed public interface - CMakeLists.txt: filter nvtx3 from install-side export set merging; install nvtx3 headers from nvtx3_SOURCE_DIR in the DSO headers section --- cpp/CMakeLists.txt | 10 +++++++--- cpp/cmake/thirdparty/get_nvtx.cmake | 18 ++++++++++-------- cpp/cmake/thirdparty/get_rmm.cmake | 11 +++++++++++ 3 files changed, 28 insertions(+), 11 deletions(-) diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt index 38079e63fd0..4f5959b486c 100644 --- a/cpp/CMakeLists.txt +++ b/cpp/CMakeLists.txt @@ -1138,9 +1138,9 @@ if(BUILD_SHARED_LIBS) PROPERTY "GLOBAL_TARGETS" ) foreach(_pkg IN LISTS _pkg_names) - # Skip packages that are themselves absorbed into libcudf — they won't be installed or - # findable at install time. - if(_mode STREQUAL "install" AND _pkg IN_LIST _absorbed_deps) + # Skip packages that are themselves absorbed into libcudf or bundled as headers — they won't + # be installed as separate findable packages. + if(_mode STREQUAL "install" AND (_pkg IN_LIST _absorbed_deps OR _pkg STREQUAL "nvtx3")) continue() endif() rapids_export_package(${_mode} ${_pkg} cudf-exports GLOBAL_TARGETS ${_global_tgts}) @@ -1393,6 +1393,10 @@ if(NOT CUDF_INSTALL_LIBRARY_DEPS) DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} ) endif() + # nvtx3 uses SOURCE_SUBDIR c, so headers are at ${nvtx3_SOURCE_DIR}/include/nvtx3/ + if(nvtx3_SOURCE_DIR) + install(DIRECTORY ${nvtx3_SOURCE_DIR}/include/nvtx3 DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) + endif() endif() if(CUDF_BUILD_STREAMS_TEST_UTIL) diff --git a/cpp/cmake/thirdparty/get_nvtx.cmake b/cpp/cmake/thirdparty/get_nvtx.cmake index 181a906ab13..d41d1f816b9 100644 --- a/cpp/cmake/thirdparty/get_nvtx.cmake +++ b/cpp/cmake/thirdparty/get_nvtx.cmake @@ -5,17 +5,19 @@ # cmake-format: on # ============================================================================= -# Need to call rapids_cpm_nvtx3 to get support for an installed version of nvtx3 and to support -# installing it ourselves +# Need to call rapids_cpm_nvtx3 to get the nvtx3 target available at configure time. function(find_and_configure_nvtx) include(${rapids-cmake-dir}/cpm/nvtx3.cmake) - # nvtx3 is private for cudf, but it is a public dependency of rmm. When rmm is absorbed into - # libcudf via whole-archive, rmm's public transitive deps (including nvtx3-cpp) are promoted into - # cudf's public interface. CMake's export validation requires that nvtx3-cpp be in an export set. - rapids_cpm_nvtx3( - BUILD_EXPORT_SET cudf-exports INSTALL_EXPORT_SET cudf-exports - ${CUDF_EXCLUDE_DEPS_FROM_ALL_FLAG} + # nvtx3 headers are bundled directly into cudf's install tree, so we only need the build-side + # export set for configure-time target resolution. No INSTALL_EXPORT_SET — consumers get headers + # from cudf's include directory without needing find_dependency(nvtx3). + rapids_cpm_nvtx3(BUILD_EXPORT_SET cudf-exports ${CUDF_EXCLUDE_DEPS_FROM_ALL_FLAG}) + + # Propagate source dir to parent scope for header installation. + set(nvtx3_SOURCE_DIR + "${nvtx3_SOURCE_DIR}" + PARENT_SCOPE ) endfunction() diff --git a/cpp/cmake/thirdparty/get_rmm.cmake b/cpp/cmake/thirdparty/get_rmm.cmake index 9594b82d820..4040be2db18 100644 --- a/cpp/cmake/thirdparty/get_rmm.cmake +++ b/cpp/cmake/thirdparty/get_rmm.cmake @@ -21,6 +21,17 @@ function(find_and_configure_rmm BUILD_SHARED EXCLUDE_FROM_ALL) list(APPEND _rmm_args INSTALL_EXPORT_SET cudf-exports) endif() rapids_cpm_rmm(${_rmm_args} ${_exclude_flag} CPM_ARGS OPTIONS "BUILD_SHARED_LIBS ${BUILD_SHARED}") + # Remove nvtx3 from rmm's public interface. Since rmm is absorbed into libcudf via whole-archive + # and we bundle nvtx3 headers directly, consumers don't need the nvtx3 target. This prevents the + # absorption loop from promoting nvtx3 into cudf's installed interface. + get_target_property(_rmm_real_target rmm::rmm ALIASED_TARGET) + if(_rmm_real_target) + get_target_property(_rmm_iface_libs ${_rmm_real_target} INTERFACE_LINK_LIBRARIES) + if(_rmm_iface_libs) + list(REMOVE_ITEM _rmm_iface_libs nvtx3::nvtx3-cpp) + set_property(TARGET ${_rmm_real_target} PROPERTY INTERFACE_LINK_LIBRARIES ${_rmm_iface_libs}) + endif() + endif() # If rmm was found as a pre-existing shared library (e.g. conda), we need find_dependency(rmm) in # the installed config even when EXCLUDE_FROM_ALL is set. EXCLUDE_FROM_ALL controls whether CPM- From 2c4938a080f7afa3b1909bb9358efdadabf12931 Mon Sep 17 00:00:00 2001 From: Vyas Ramasubramani Date: Wed, 6 May 2026 09:10:31 -0700 Subject: [PATCH 19/21] fix: make nvtx3 bundling conditional on rmm absorption --- cpp/CMakeLists.txt | 14 ++++++++++++++ cpp/cmake/thirdparty/get_nvtx.cmake | 13 ++++++++----- cpp/cmake/thirdparty/get_rmm.cmake | 11 ----------- 3 files changed, 22 insertions(+), 16 deletions(-) diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt index 4f5959b486c..4a93e265f47 100644 --- a/cpp/CMakeLists.txt +++ b/cpp/CMakeLists.txt @@ -1098,6 +1098,20 @@ foreach(_dep IN LISTS _absorbed_deps) set(_${_dep}_link ${_dep}::${_dep}) endforeach() if(BUILD_SHARED_LIBS) + # When rmm is a static library being absorbed via whole-archive, strip nvtx3 from its public + # interface. We bundle nvtx3 headers directly into cudf's install tree, so consumers get them from + # cudf's include path without needing the nvtx3 target or find_dependency(nvtx3). + get_target_property(_rmm_type rmm::rmm TYPE) + if(_rmm_type STREQUAL "STATIC_LIBRARY") + get_target_property(_rmm_real rmm::rmm ALIASED_TARGET) + if(_rmm_real) + get_target_property(_rmm_libs ${_rmm_real} INTERFACE_LINK_LIBRARIES) + if(_rmm_libs) + list(REMOVE_ITEM _rmm_libs nvtx3::nvtx3-cpp) + set_property(TARGET ${_rmm_real} PROPERTY INTERFACE_LINK_LIBRARIES ${_rmm_libs}) + endif() + endif() + endif() foreach(_dep IN LISTS _absorbed_deps) get_target_property(_target_type ${_dep}::${_dep} TYPE) if(NOT _target_type STREQUAL "STATIC_LIBRARY") diff --git a/cpp/cmake/thirdparty/get_nvtx.cmake b/cpp/cmake/thirdparty/get_nvtx.cmake index d41d1f816b9..63332166ce1 100644 --- a/cpp/cmake/thirdparty/get_nvtx.cmake +++ b/cpp/cmake/thirdparty/get_nvtx.cmake @@ -9,12 +9,15 @@ function(find_and_configure_nvtx) include(${rapids-cmake-dir}/cpm/nvtx3.cmake) - # nvtx3 headers are bundled directly into cudf's install tree, so we only need the build-side - # export set for configure-time target resolution. No INSTALL_EXPORT_SET — consumers get headers - # from cudf's include directory without needing find_dependency(nvtx3). - rapids_cpm_nvtx3(BUILD_EXPORT_SET cudf-exports ${CUDF_EXCLUDE_DEPS_FROM_ALL_FLAG}) + # nvtx3 is private for cudf, but it is a public dependency of rmm. When rmm is absorbed into + # libcudf via whole-archive, rmm's public transitive deps (including nvtx3-cpp) are promoted into + # cudf's public interface. CMake's export validation requires that nvtx3-cpp be in an export set. + rapids_cpm_nvtx3( + BUILD_EXPORT_SET cudf-exports INSTALL_EXPORT_SET cudf-exports + ${CUDF_EXCLUDE_DEPS_FROM_ALL_FLAG} + ) - # Propagate source dir to parent scope for header installation. + # Propagate source dir to parent scope (needed for header installation in standalone builds) set(nvtx3_SOURCE_DIR "${nvtx3_SOURCE_DIR}" PARENT_SCOPE diff --git a/cpp/cmake/thirdparty/get_rmm.cmake b/cpp/cmake/thirdparty/get_rmm.cmake index 4040be2db18..9594b82d820 100644 --- a/cpp/cmake/thirdparty/get_rmm.cmake +++ b/cpp/cmake/thirdparty/get_rmm.cmake @@ -21,17 +21,6 @@ function(find_and_configure_rmm BUILD_SHARED EXCLUDE_FROM_ALL) list(APPEND _rmm_args INSTALL_EXPORT_SET cudf-exports) endif() rapids_cpm_rmm(${_rmm_args} ${_exclude_flag} CPM_ARGS OPTIONS "BUILD_SHARED_LIBS ${BUILD_SHARED}") - # Remove nvtx3 from rmm's public interface. Since rmm is absorbed into libcudf via whole-archive - # and we bundle nvtx3 headers directly, consumers don't need the nvtx3 target. This prevents the - # absorption loop from promoting nvtx3 into cudf's installed interface. - get_target_property(_rmm_real_target rmm::rmm ALIASED_TARGET) - if(_rmm_real_target) - get_target_property(_rmm_iface_libs ${_rmm_real_target} INTERFACE_LINK_LIBRARIES) - if(_rmm_iface_libs) - list(REMOVE_ITEM _rmm_iface_libs nvtx3::nvtx3-cpp) - set_property(TARGET ${_rmm_real_target} PROPERTY INTERFACE_LINK_LIBRARIES ${_rmm_iface_libs}) - endif() - endif() # If rmm was found as a pre-existing shared library (e.g. conda), we need find_dependency(rmm) in # the installed config even when EXCLUDE_FROM_ALL is set. EXCLUDE_FROM_ALL controls whether CPM- From 210b6563500a06319238f9643aa629763d311da7 Mon Sep 17 00:00:00 2001 From: Vyas Ramasubramani Date: Wed, 6 May 2026 10:50:59 -0700 Subject: [PATCH 20/21] fix: conditionally include nvtx3 INSTALL_EXPORT_SET based on absorption mode --- cpp/cmake/thirdparty/get_nvtx.cmake | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/cpp/cmake/thirdparty/get_nvtx.cmake b/cpp/cmake/thirdparty/get_nvtx.cmake index 63332166ce1..88fbab9d22b 100644 --- a/cpp/cmake/thirdparty/get_nvtx.cmake +++ b/cpp/cmake/thirdparty/get_nvtx.cmake @@ -9,13 +9,15 @@ function(find_and_configure_nvtx) include(${rapids-cmake-dir}/cpm/nvtx3.cmake) - # nvtx3 is private for cudf, but it is a public dependency of rmm. When rmm is absorbed into - # libcudf via whole-archive, rmm's public transitive deps (including nvtx3-cpp) are promoted into - # cudf's public interface. CMake's export validation requires that nvtx3-cpp be in an export set. - rapids_cpm_nvtx3( - BUILD_EXPORT_SET cudf-exports INSTALL_EXPORT_SET cudf-exports - ${CUDF_EXCLUDE_DEPS_FROM_ALL_FLAG} - ) + # nvtx3 is part of rmm's public interface. Include it in the build export set so that + # configure-time target resolution works. Only include it in the install export set when rmm is + # NOT being absorbed — when absorbed, we bundle nvtx3 headers directly and consumers don't need + # find_dependency(nvtx3). + set(_nvtx_args BUILD_EXPORT_SET cudf-exports) + if(CUDF_INSTALL_LIBRARY_DEPS) + list(APPEND _nvtx_args INSTALL_EXPORT_SET cudf-exports) + endif() + rapids_cpm_nvtx3(${_nvtx_args} ${CUDF_EXCLUDE_DEPS_FROM_ALL_FLAG}) # Propagate source dir to parent scope (needed for header installation in standalone builds) set(nvtx3_SOURCE_DIR From a0ff4c2524593504cf6b0f476ea3a4b77b80142f Mon Sep 17 00:00:00 2001 From: Vyas Ramasubramani Date: Wed, 6 May 2026 12:08:47 -0700 Subject: [PATCH 21/21] fix: use cache variable for nvtx3_SOURCE_DIR to get correct SOURCE_SUBDIR path --- cpp/CMakeLists.txt | 3 ++- cpp/cmake/thirdparty/get_nvtx.cmake | 7 ------- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt index 4a93e265f47..891a9b202b9 100644 --- a/cpp/CMakeLists.txt +++ b/cpp/CMakeLists.txt @@ -1407,7 +1407,8 @@ if(NOT CUDF_INSTALL_LIBRARY_DEPS) DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} ) endif() - # nvtx3 uses SOURCE_SUBDIR c, so headers are at ${nvtx3_SOURCE_DIR}/include/nvtx3/ + # nvtx3 headers: nvtx3_SOURCE_DIR resolves to the cache variable set by FetchContent, which + # includes the SOURCE_SUBDIR (c/), so the headers are at ${nvtx3_SOURCE_DIR}/include/nvtx3/. if(nvtx3_SOURCE_DIR) install(DIRECTORY ${nvtx3_SOURCE_DIR}/include/nvtx3 DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) endif() diff --git a/cpp/cmake/thirdparty/get_nvtx.cmake b/cpp/cmake/thirdparty/get_nvtx.cmake index 88fbab9d22b..c2c6563839a 100644 --- a/cpp/cmake/thirdparty/get_nvtx.cmake +++ b/cpp/cmake/thirdparty/get_nvtx.cmake @@ -18,13 +18,6 @@ function(find_and_configure_nvtx) list(APPEND _nvtx_args INSTALL_EXPORT_SET cudf-exports) endif() rapids_cpm_nvtx3(${_nvtx_args} ${CUDF_EXCLUDE_DEPS_FROM_ALL_FLAG}) - - # Propagate source dir to parent scope (needed for header installation in standalone builds) - set(nvtx3_SOURCE_DIR - "${nvtx3_SOURCE_DIR}" - PARENT_SCOPE - ) - endfunction() find_and_configure_nvtx()