From 6ed7d445c9c76d90886fe87f593523b10c39172d Mon Sep 17 00:00:00 2001 From: Axel Garcia Date: Fri, 31 Jul 2026 22:37:01 +0200 Subject: [PATCH] ENH: Add script to install python packages locally --- INSTALLATION.md | 12 ++++++- utilities/build_rtk_python.sh | 63 +++++++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+), 1 deletion(-) create mode 100755 utilities/build_rtk_python.sh diff --git a/INSTALLATION.md b/INSTALLATION.md index 26e060328..86c43914a 100644 --- a/INSTALLATION.md +++ b/INSTALLATION.md @@ -20,7 +20,17 @@ For RTK developpers, it may be useful to compile RTK independently from ITK. Thi * Manually download RTK's source repository from [GitHub](https://github.com/RTKConsortium/RTK) with `git` (recommended) or as a [zip package](https://codeload.github.com/RTKConsortium/RTK/zip/main). * Configure the project with CMake pointing to RTK's source directory and setting the CMake option `ITK_DIR` to ITK's compilation directory. All CMake options above can be set except `Module_RTK`. -Installation is currently not supported for independent RTK compilations. +A convenience script at `utilities/build_rtk_python.sh` builds and installs RTK as a Python package. It must be run from the RTK source directory. It requires ITK and, when using CUDA, CudaCommon, both built with Python wrapping enabled: + +```bash +ITK_DIR=/path/to/itk-build ./utilities/build_rtk_python.sh # no CUDA +ITK_DIR=/path/to/itk-build RTK_USE_CUDA=ON ./utilities/build_rtk_python.sh # with CUDA +``` +The script installs into the active Python environment (the one used to run the script). +The script uses pip editable which is mainly intended for local development. +Pip configures the environment so that importing the package uses the source code from your working directory. Therefore, changes to your Python files are generally visible immediately, without reinstalling the package. +C++ changes require re-running the script to recompile. + ## Python pre-compiled binaries We only provide pre-compiled binaries for the Python package which depends on ITK. Use the following commands to install the RTK module with `pip`. diff --git a/utilities/build_rtk_python.sh b/utilities/build_rtk_python.sh new file mode 100755 index 000000000..30dd85b84 --- /dev/null +++ b/utilities/build_rtk_python.sh @@ -0,0 +1,63 @@ +# Build and install the RTK Python package via pip (editable mode). +# Must be run from the RTK source directory. +# +# Prerequisites: +# - An ITK build tree with Python wrapping enabled (set ITK_DIR) +# - Optionally CUDA (set RTK_USE_CUDA=ON). +# When CUDA is enabled, CudaCommon must be findable by ITK. +# +# Usage (from the RTK source directory): +# ITK_DIR=/path/to/itk-build ./utilities/build_rtk_python.sh +# ITK_DIR=/path/to/itk-build RTK_USE_CUDA=ON ./utilities/build_rtk_python.sh +# +# All paths below can be overridden via environment variables. + +set -euo pipefail + +RTK_PIP_BUILD_DIR="${RTK_PIP_BUILD_DIR:-build-pip}" +BUILD_TYPE="${BUILD_TYPE:-Release}" +RTK_USE_CUDA="${RTK_USE_CUDA:-OFF}" + +if [ -z "$ITK_DIR" ]; then + echo "ERROR: ITK_DIR must be set to an ITK build tree with Python wrapping." + exit 1 +fi + +# Verify that ITK Python wrapping is installed in site-packages. RTK wrapping +# builds on top of the ITK wrapping infrastructure, so ITK's wrapping shared +# libraries must already be present. +ITK_PYTHON_DIR=$(python -c "import itk; import os; print(os.path.dirname(itk.__file__))") +if ! ls "$ITK_PYTHON_DIR"/_ITKCommonPython*.so >/dev/null 2>&1; then + echo "ERROR: ITK Python wrapping not found in $ITK_PYTHON_DIR." + echo "Install ITK with ITK_WRAP_PYTHON=ON and run: cmake --install --component RuntimeLibraries" + exit 1 +fi + +# CudaCommon is an ITK remote module. When CUDA support is requested, verify +# that its Python wrapping is installed in site-packages. +if [ "$RTK_USE_CUDA" = "ON" ]; then + if ! ls "$ITK_PYTHON_DIR"/_CudaCommonPython*.so >/dev/null 2>&1; then + echo "ERROR: CudaCommon Python wrapping not found in $ITK_PYTHON_DIR." + echo "Install CudaCommon with CudaCommon_WRAP_PYTHON=ON and run: cmake --install --component RuntimeLibraries" + exit 1 + fi +fi + +# Build the RTK Python wrapping via scikit-build-core. +# WRAP_ITK_INSTALL_COMPONENT_IDENTIFIER tells the CMake install (run during wheel assembly) +# which install component to use, so only the files needed for the Python wheel are installed. +PIP_ARGS=( + --no-build-isolation + --no-deps + --config-settings=build-dir="$RTK_PIP_BUILD_DIR" + --config-settings=cmake.build-type="$BUILD_TYPE" + --config-settings=cmake.define.ITK_DIR="$ITK_DIR" + --config-settings=cmake.define.WRAP_ITK_INSTALL_COMPONENT_IDENTIFIER=PythonWheel + --config-settings=cmake.define.RTK_WRAP_PYTHON=ON + --config-settings=cmake.define.RTK_USE_CUDA="$RTK_USE_CUDA" + --config-settings=cmake.define.ITK_USE_PYTHON_LIMITED_API=OFF +) +echo "==> Installing RTK Python package (editable)" +rm -rf "$RTK_PIP_BUILD_DIR" +python -m pip install -e . -vvv "${PIP_ARGS[@]}" +echo "==> Done"