Skip to content

build(cmake): give each component its own CMake export - #1963

Closed
ramakrishnap-nv wants to merge 1 commit into
mainfrom
feat/per-component-cmake-export
Closed

ramakrishnap-nv wants to merge 1 commit into
mainfrom
feat/per-component-cmake-export

Conversation

@ramakrishnap-nv

Copy link
Copy Markdown
Collaborator

Draft — does not configure yet. Opened to track the design and the evidence; see the open problem at the bottom.

cuopt-config.cmake exports a single _IMPORT_PREFIX for all three component libraries:

IMPORTED_LOCATION_RELEASE "${_IMPORT_PREFIX}/lib/libcuopt_mathopt.so"

_IMPORT_PREFIX is derived from where the config sits, so it only resolves while the libraries share a prefix. That blocks #1635: once they live in sibling wheels, find_package(cuopt) defines none of cuopt::client / ::mathopt / ::routing, and python/cuopt links against them. #1929 hit this as:

Target "data_model_wrapper" links to cuopt::mathopt but the target was not found

so that PR had to keep every library in the libcuopt wheel, which leaves the split delivering no size win.

Approach

  • each component installs to its own export set, so install(EXPORT) writes one targets file per component and each computes _IMPORT_PREFIX from its own install location
  • the umbrella config includes whichever component targets files it finds, beside itself when they share a prefix or through CMAKE_PREFIX_PATH when they do not
  • cuopt::cuopt is synthesised in the config rather than exported, because CMake requires everything an exported target references to be in the same export set

Open problem

rapids_export(BUILD cuopt ...) exports the build tree, where the umbrella's BUILD_INTERFACE links to the components are live and they are no longer members of cuopt-exports:

export called with target "cuopt" which requires target "cuopt_routing"
that is not in any export set

The build export needs the components in its set while the install export needs them separate.

Also in scope

rapids-cmake writes its helper find-modules to lib64/rapids/cmake/ with no COMPONENT, so they vanish from any --component install. #1929 hit that too, as CMake falling back to the CUDA toolkit's libcudacxx and failing with Unknown CMake command "libcudacxx_update_language_compat_flags".

Affects conda and system installs as well as wheels, so it needs verifying on all three.

🤖 Generated with Claude Code

Splitting libcuopt across wheels breaks find_package(cuopt): cuopt-config.cmake
exports a single _IMPORT_PREFIX for all three libraries, derived from where the
config sits, so with the libraries in sibling wheel directories none of
cuopt::client / ::mathopt / ::routing resolve. python/cuopt links those, and
wheel-build-cuopt fails with 'Target "data_model_wrapper" links to
cuopt::mathopt but the target was not found'.

So far:

- each component installs to its own export set, so install(EXPORT) writes one
  targets file per component and each computes _IMPORT_PREFIX from its own
  install location
- the umbrella config includes whichever component targets files it finds,
  beside itself or through CMAKE_PREFIX_PATH
- cuopt::cuopt is synthesised in the config rather than exported, since an
  exported target may not reference targets outside its own export set

Does not configure yet: rapids_export(BUILD) still exports the build tree,
where the umbrella's BUILD_INTERFACE links to the components are live and they
are no longer members of cuopt-exports.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@copy-pr-bot

copy-pr-bot Bot commented Sep 21, 2026

Copy link
Copy Markdown

Auto-sync is disabled for draft pull requests in this repository. Workflows must be run manually.

Contributors can view more details about this message here.

@ramakrishnap-nv

Copy link
Copy Markdown
Collaborator Author

Folded into #1929, which now carries the export restructure alongside the wheel split -- the two changes only work together, so reviewing them separately meant reviewing a state that never ships.

rapids-bot Bot pushed a commit that referenced this pull request Sep 22, 2026
Adds a wheel per component, using the install components from #1926 via scikit-build-core's `install.components`.

| Wheel | Contents | Dependencies beyond rmm / rapids-logger |
|---|---|---|
| `libcuopt-client` | `libcuopt_client.so` | none — no CUDA wheels at all |
| `libcuopt-mathopt` | `libcuopt_mathopt.so`, `cuopt_cli` | cuda-toolkit, cudss, nccl, nvjitlink |
| `libcuopt-routing` | `libcuopt_routing.so` | `cuda-toolkit[cublas,cudart]` only |
| `libcuopt` | ld script, `cuopt_grpc_server` | depends on the three above |

A routing-only install no longer pulls cudss, nccl or nvjitlink. Dependencies were split from each library's measured `DT_NEEDED` rather than by dividing the existing list.

`libcuopt` no longer bundles the libraries; it depends on them, and its `load_library` delegates to the component packages, client first since mathopt and routing both have a `DT_NEEDED` on it. `pip install libcuopt` is unchanged for users.

Also folds in the CMake export restructure that was #1963: each component gets its own export set, since CMake will not export a target that references targets outside its own export set, and a single umbrella export left every component's targets file computing the wrong `_IMPORT_PREFIX`. The installed config rebuilds the umbrella's links from whichever components are present. The two changes only work together -- without it the component wheels cannot resolve each other -- so they are reviewed as one.

Each wheel configures the whole C++ tree, so this trades CI build time for install size, with sccache absorbing the repeats. Building once and packaging three times would need `build_wheel.sh` restructured — worth doing separately if the cost shows up.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Authors:
  - Ramakrishna Prabhu (https://github.com/ramakrishnap-nv)

Approvers:
  - Kyle Edwards (https://github.com/KyleFromNVIDIA)
  - Ishika Roy (https://github.com/Iroy30)

URL: #1929
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant