Description
Description
Consider a project with the following characteristics:
- uses a
setup.py
runningsetuptools.setup()
- needs to
import {library}
in thatsetup.py
, prior tosetup()
being called {library}
is only distributed via CUDA-suffixed wheels (e.g.{library}-cu11
)
How should such cases be handled? Is it possible to make them work with rapids-build-backend
?
Details
Consider the specific case of ucx-py
.
Its setup.py
includes stuff like this that runs before setuptools.setup()
is executed:
def _find_libucx_libs_and_headers():
import libucx
module_dir = os.path.dirname(libucx.__file__)
libs = glob.glob(f"{module_dir}/**/lib*.so*", recursive=True)
...
return list(lib_dirs), list(header_dirs)
libucx_lib_dirs, libucx_header_dirs = _find_libucx_libs_and_headers()
ext_modules = [
Extension(
...
include_dirs=[libucx_header_dirs],
library_dirs=[libucx_lib_dirs],
),
...
]
setup(
ext_modules=ext_modules,
cmdclass={"build_ext": new_build_ext},
...
)
The key line is that import libucx
.
By the time that line runs, libucx-cu11
or libucx-cu12
needs to have been installed. It that seems pip wheel
ends up running setup.py
before rapids-build-backend
has had a chance to replace the contents of pyproject.toml
.
With libucx==1.15.0
(unsuffixed) in [build-system]
, like this:
[build-system]
build-backend = "rapids_build_backend.build"
requires = [
"cython>=3.0.0",
"libucx==1.15.0",
"rapids-build-backend>=0.3.0,<0.4.0dev0",
"setuptools>=64.0.0",
]
Wheel-building fails like this:
ERROR: Could not find a version that satisfies the requirement libucx==1.15.0 (from versions: none)
ERROR: No matching distribution found for libucx==1.15.0
With it omitted from that table and moved down into [tool.rapids-build-backend]
, wheel building fails like this:
ModuleNotFoundError: No module named 'libucx'
Options I can think of
(in no particular order)
- still use
rapids-build-backend
, but preserve thesed
-replacing of justlibucx
in wheel-building scripts- in other words... solve this case-by-case and not generally
- run
rapids-dependency-file-generator --matrix "cuda=${RAPIDS_CUDA_VERSION%.*}"
in build scripts prior topip wheel
to updatepyproject.toml
in place - install
libucx
at build time by some other mechanism, omit it from[build-system]
table, runpip wheel --no-build-isolation
- in
setup.py
, customize the command run bypython setup.py build_ext
- such that it does all the
import libucx
stuff when it's called to build extensions (instead of whensetuptools.setup()
is called) - for example, I think we could subclass Cython.build_ext and just override the build_extension() method (Cython/distutils/build_ext.py#L82)
- more details in "Extending or Customizing Setuptools" (setuptools docs)
- such that it does all the
Request for comment
Other options?
Any of these that definitely won't work?
How should we proceed?
References
Created after starting rapidsai/ucx-py#1044.