Problem
cuda_bindings/setup.py requires CUDA_HOME/CUDA_PATH at module import time (line 29-31) and imports Cython/pyclibrary at the top level (lines 16-17). This means any tool that needs to read package metadata — including uv lock, uv sync, and pip install --dry-run — must have the CUDA Toolkit installed and CUDA_HOME set, even when no actual build is happening.
This creates friction with modern Python tooling (uv workspaces, lockfile generation, metadata introspection) and prevents patterns like uv sync --package cuda-bindings --group test from working without a full CUDA environment.
Proposed solution
Convert cuda_bindings to use a custom PEP 517 build backend (similar to what cuda_core already does with build_hooks.py):
- Defer
CUDA_HOME check — Move it from module-level into the actual build functions (build_wheel, build_editable). get_requires_for_build_wheel should not need CUDA.
- Defer heavy imports —
Cython, pyclibrary, and other build-only imports should happen inside build functions, not at module import.
- Static metadata in
pyproject.toml — Anything that can be declared statically (package name, deps, classifiers) should stay in pyproject.toml.
- Custom build backend — A
build_hooks.py (or similar) that wraps setuptools.build_meta and only invokes CUDA-dependent logic when actually building.
Context
This came up during the uv migration (#1615). Currently uv lock requires CUDA_HOME=/usr/local/cuda as a workaround. The cuda_core package already follows the deferred pattern via its build_hooks.py.
References
Problem
cuda_bindings/setup.pyrequiresCUDA_HOME/CUDA_PATHat module import time (line 29-31) and imports Cython/pyclibrary at the top level (lines 16-17). This means any tool that needs to read package metadata — includinguv lock,uv sync, andpip install --dry-run— must have the CUDA Toolkit installed andCUDA_HOMEset, even when no actual build is happening.This creates friction with modern Python tooling (uv workspaces, lockfile generation, metadata introspection) and prevents patterns like
uv sync --package cuda-bindings --group testfrom working without a full CUDA environment.Proposed solution
Convert
cuda_bindingsto use a custom PEP 517 build backend (similar to whatcuda_corealready does withbuild_hooks.py):CUDA_HOMEcheck — Move it from module-level into the actual build functions (build_wheel,build_editable).get_requires_for_build_wheelshould not need CUDA.Cython,pyclibrary, and other build-only imports should happen inside build functions, not at module import.pyproject.toml— Anything that can be declared statically (package name, deps, classifiers) should stay inpyproject.toml.build_hooks.py(or similar) that wrapssetuptools.build_metaand only invokes CUDA-dependent logic when actually building.Context
This came up during the uv migration (#1615). Currently
uv lockrequiresCUDA_HOME=/usr/local/cudaas a workaround. Thecuda_corepackage already follows the deferred pattern via itsbuild_hooks.py.References
cuda_core/build_hooks.py— existing example of the deferred patterncuda_bindings/setup.py— current implementation (~400 lines)