Skip to content

Conversation

@hjmjohnson
Copy link
Member

@hjmjohnson hjmjohnson commented Jan 17, 2026

  • TODO FIX DOCUMENTATION: https://itkpythonpackage.readthedocs.io/en/latest/Build_ITK_Python_packages.html

  • How to use the tarball/zipfile cache from ITKPythonBuilds needed for dockcross-manylinux-download-cache.sh? What needs to be included?

  • Remove SKBUILD cmake items that are unused (perhaps this needs to be fixed? unknown use case for this)

  • The entire process for creating python modules should be driven by a consistent selection of build options. The previous Python package generation infrastructure had many default values configured at various locations across several scripts. The values used to make the Python packages required that default values (i.e., the ITK TAG) was hard-coded in several places so that matching values existed during the various phases of processing (in different container/host environments and in different scripts.

  • This PR employs an overall strategy where all the candidate configuration choices are defaulted to previous behavior.

  • The virtual environments use PIXI to consolidate and manage the environments needed to create the packages consistently across all the platforms with similar tooling.

  • A secondary strategy is to prefer early failure to continued processing with defaults. Each stage of the process should be explicitly and completely defined.

# This is documenting the original bash script system, and some intermediate refactorings that were needed to understand what was happening.  These notes are not complete in the final version and need to be rewritten
ITKPythonPackage/ITK-source                   <- This is where superbuilds occur against ITKPythonPackage/CMakeLists.txt
ITKPythonPackage/ITK-source/ITK               <- This is where the ITK source at the proper branch is checked out during superbuild if requested (Default value for ITK_SOURCE_DIR)
ITKPythonPackage/ITK-source/oneTBB-prefix     <- This is where oneTBB is built during Superbuild
ITKPythonPackage/dist                         <- This is where wheels are written
ITKPythonPackage/build                        <- This is where the package.env file is written for building
ITKPythonPackage/itkVersion.py                <- A temporary file generated by scripts/pyproject_configure.py, needed for Python package building
ITKPythonPackage/ITK-${PYVER}-${plat}_${arch} <- The build output directory generated during "python -m build ...." based on the current pyproject.toml configuration
ITKPythonPackage/build/cp39-cp39-linux_x86_64 <- Docker cross build directory of ITKPythonPackage/CMakeLists.txt when 

ITKPythonPackage/CMakeLists.txt is called from an environment where the following variables exist:

        ITK_GIT_TAG = ONLY used to represent the version of ITK to checkout.  "HEAD" could be used THIS CONCEPT IS CONFOUNDED WITH ITK_PACAKAGE_VERSION (which should be pep-440 compliant, but v6.0b01 is not conformant).
        ITK_PACKAGE_VERSION  (set from ITKRemoteModuleBuildTestPackageAction:itk-wheel-tag) 
        ITKPYTHONPACKAGE_TAG (set from ITKRemoteModuleBuildTestPackageAction:itk-python-package-tag)
        ITKPYTHONPACKAGE_ORG (set from ITKRemoteModuleBuildTestPackageAction:itk-python-package-org)
        ITK_MODULE_PREQ      (set ITKRemoteModuleBuildTestPackageAction:itk-module-deps)

Some useful command lines at the heart of building packages

# Make tar.zst for upload to ITKPythonBuilds
# - build manylinux
MANYLINUX_VERSION=_2_28 ITK_GIT_TAG=v6.0b02 bash scripts/make_tarballs.sh
#  - build native linux or mac
MANYLINUX_VERSION=             ITK_GIT_TAG=v6.0b02 bash scripts/make_tarballs.sh
# - build Windows
ITK_GIT_TAG=v6.0b02  scripts\make_windows_zip.ps1

cd ~/Dashboard/src/ITKPythonPackage
pixi run -e macos-py311  ~/Dashboard/src/ITKPythonPackage/scripts/build_wheels.py --platform-env macos-py311 --build-dir-root /Users/johnsonhj/Dashboard/src/ITKPP-bld --build-itk-tarball-cache --itk-git-tag v6.0b02

python3 ITKPythonPackage/scripts/build_wheels.py --py-envs 3.9 3.10 3.11 --build-dir-root ${HOME}/Dashboard/src/ITKPP-bld --module-source-dir /Users/johnsonhj/Dashboard/src/REMOTE_MODULES/ITKStrain --module-dependancies-root-dir /Users/johnsonhj/Dashboard/src/REMOTE_MODULES --itk-module-deps "InsightSoftwareConsortium/ITKMeshToPolyData@43338b428:InsightSoftwareConsortium/ITKBSplineGradient@main:InsightSoftwareConsortium/ITKHigherOrderAccurateGradient@main:InsightSoftwareConsortium/ITKSplitComponents@main:KitwareMedical/ITKStrain@main"

python3 ~/Dashboard/src/ITKPythonPackage/scripts/build_wheels.py --py-envs 3.9 3.10 3.11 --build-dir-root ${HOME}/Dashboard/src/ITKPP-bld --module-source-dir ${HOME}/Dashboard/src/REMOTE_MODULES/MorphologicalContourInterpolation --module-dependancies-root-dir ${HOME}/Dashboard/src/REMOTE_MODULES --itk-module-deps "InsightSoftwareConsortium/RLEImage@v1.0.2"

IPP_DOWNLOAD_GIT_TAG=${IPP_DOWNLOAD_GIT_TAG} IPP_DOWNLOAD_ORG=${IPP_DOWNLOAD_ORG} ./dockcross-manylinux-download-cache-and-build-module-wheels.sh cp3${{ matrix.python3-minor-version }} $CMAKE_OPTIONS"
  • remove hard coded SINGLE_WHEEL=0 conditionsls (at least in mac-build-wheels.sh
  • remove if test -e setup.py; then use_skbuild_classic=true that is no longer available
  • remove documentation related to running modules with setup.py (which was not removed in march of 2024 in favor of pyproject.toml)
  • Install pip package "${Python3_EXECUTABLE} -m pip install --no-cache-dir delocate" early. (added to pixi)
  • Add delocate to pyproject.toml as mac required package
  • purge use of osx_target in favor of conventional "MACOSX_DEPLOYMENT_TARGET"
  • Quick_start_guide.rst
  • oci_exe -> OCI_EXE All caps version is what the dynamically created dockcross runner uses.
  • Add note about why rustup updates are needed on macos to reduce noisy diagnostics unrelated to packaging
  • Remove unused script scripts/update_python_version.py (last updated in 2017, and not used in this source tree)
  • Remove single_wheel target (Was unusable on mac/linux and untested on windows
  • make "Remove unnecessary files for building against ITK" a separate function call during making tarball
  • scripts/internal/manylinux-build-common.sh use pixi instead to install doxygen and ninja
    SDKROOT CXX CC
  • autobuild linux virtual environments
  • Allow _module_dir="$(pwd -P)" specifying path to module source code on the command line
  • autoresolve dependance on dotenv, or remove as a dependancy. (stopgap eventually removed)
  • itk windows teaching box initial test.
  • Make separate build directories for SuperBuild and BuildWheels phases. Remove CMakeLists.txt from root of IPP dir
  • change "macos" to "macosx" for naming consistency with github CI
  • itk linux ubuntu 24.04 works intial test! f77a486
    cd Dashboard/src/ITKPythonPackage
    bash scripts/dockcross-manylinux-build-wheels.sh
  • Fix spelling dependancies -> dependencies DEPENDANCIES -> DEPENDENCIES
  • Build on Mac itk wheels
  • Build on Mac itk tarball python3 ITKPythonPackage/scripts/build_wheels.py --py-envs 3.9 3.10 3.11 --build-dir-root /Users/johnsonhj/Dashboard/src/ITKPP-bld --build-itk-tarball-cache
  • Build on Mac itk simple module
  • Build on Mac itk module with dependancies
  • Build on Windows itk wheels
  • Build on Windows itk zip compile cache
  • Build on Windows itk simple module
  • Build on Windows itk module with dependancies
  • Build on Linux itk wheels
  • Build on Linux itk tarball
  • Build on Linux itk simple module
  • Build on Linux itk module with dependancies
  • Figure out what to do with itkVersion.py file for auto-update. Move to build directory and auto-generate
  • itk mac laptop works initial test! f77a486
  • Allow for out-of-source-builds. Do not put these files in the source IPPP directory

Dashboard/src/ITKPythonPackage
cd Dashboard/src/ITKPythonPackage
TODO: setup CXX CC to be the pixi compilers for XCode 16 rather than XCode 17.
bash scripts/macpython-build-wheels.sh
python3 scripts/build_wheels.py --py-envs 3.13 --build-dir-root /Users/johnsonhj/Dashboard/src/IP-bld
/Users/johnsonhj/Dashboard/src/ITKPythonPackage/scripts/build_wheels.py --py-envs 3.9 3.10 3.11 --build-dir-root /Users/johnsonhj/Dashboard/src/ITKPP-bld --build-itk-tarball-cache --itk-git-tag v6.0b02

  • python3 scripts/build_wheels.py --py-env 3.10 --module-source-dir /Users/johnsonhj/Dashboard/src/REMOTE_MODULES/Cuberille
  • python3 scripts/build_wheels.py --py-env 3.10 --module-source-dir /Users/johnsonhj/Dashboard/src/REMOTE_MODULES/Ultrasound --module-dependancies-root-dir /Users/johnsonhj/Dashboard/src/TEST_REMOTE_MODULES --itk-module-deps "InsightSoftwareConsortium/ITKMeshToPolyData@43338b428:InsightSoftwareConsortium/ITKBSplineGradient@main:InsightSoftwareConsortium/ITKHigherOrderAccurateGradient@main:InsightSoftwareConsortium/ITKSplitComponents@main:KitwareMedical/ITKStrain@main"
PSUEDO_CODE
        ./scripts/dockcross-manylinux-build-wheels.sh
                - Set environmental variables from build/package.env
                - run container that generates dockcross runner script build/runner_dockcross-*-*.sh
                - run build/runner_dockcross-*-*.sh from the directory that is to be manipulated in the cross env (i.e. source directory)
                      run container where 
                         HOST_PWD is mounted inside the running container at /work
                         HOST ~/.ssh is mounted to the  inside running container at ~/.ssh
                         HOST UserID & GroupID's are mapped inside the running container (i.e., files generated will have host users' permissions)
                         FINAL_ARGS (usually other for alternate mount points)
                         <usually a script to be run inside the running container to do the payload of work>
Mac Standard Environmental Variables
Variable                    Purpose              Applies To
MACOSX_DEPLOYMENT_TARGET    Min OS version       Clang, linker, Python
SDKROOT                     SDK/sysroot          Clang, Xcode, CMake
ARCHFLAGS                   Arch flags           Python/Makefile builds
CMAKE_OSX_SYSROOT           Sysroot for          CMake CMake projects
CMAKE_OSX_ARCHITECTURES     Target arch          CMake
CMAKE_OSX_DEPLOYMENT_TARGET Deployment target    CMake
DEVELOPER_DIR               Xcode selection      All Xcode toolchains
CC, CXX                     Compiler override    All builds
DYLD_LIBRARY_PATH           Runtime dylib search macOS runtime loader

CMAKE Respected Environmental Variables
CC         – C compiler
CXX        – C++ compiler
FC         – Fortran compiler
CUDAHOSTCXX – Host compiler for CUDA


CFLAGS           – baseline C flags
CXXFLAGS         – baseline C++ flags
FFLAGS           – Fortran flags
CPPFLAGS         – preprocessor flags (added to all languages)
LDFLAGS          – link flags for all languages

Toolchain hints
AR               – Archiver
NM               – Symbol dump tool
OBJDUMP
OBJCOPY
RANLIB
STRIP
.pixi
BuildWheelsSupport/build/cp310-cp310-linux_x86_64
BuildWheelsSupport/pyproject.toml
ITK-3.10-manylinux_2_28_x64
ITK-source/ITK/
build/ITK-support-bld
build/ITKPythonBuilds-linux-x64.tar
build/ITKPythonBuilds-linux-x64.tar.zst
build/oneTBB-prefix/include/oneapi/tbb.h
build/runner_dockcross-_2_28-x64_20250913-6ea98ba.sh
dist/build_log_3.13.json
dist/itk-6.0.0b2-itk-6.0.0b2-cp39.whl
itkVersion.py
pixi_install.sh
scripts/__pycache__/BuildManager.cpython-312.pyc
scripts/build/package.env
venvs/

docker run -i -t -v pwd:/io dockerio.io/pypa/manylinux_2_28_x86_64:20250913-6ea98ba

dockcross/manylinux_2_28-x64:20250913-6ea98ba

docker run -ti --name dockcross_22377 -v /home/johnsonhj/Dashboard/src/IPPP:/work -v /home/johnsonhj/.ssh:/home/johnsonhj/.ssh -e BUILDER_UID=1218096 -e BUILDER_GID=100 -e BUILDER_USER=johnsonhj -e BUILDER_GROUP=users -v /home/johnsonhj/Dashboard/src/IPPP/dist:/work/dist/ -v/home/johnsonhj/Dashboard/src/ITK:/work/ITK-source/ITK --env-file /home/johnsonhj/Dashboard/src/IPPP/build/package.env dockcross/manylinux_2_28-x64:20250913-6ea98ba /bin/bash

hjmjohnson and others added 30 commits November 26, 2025 13:56
Content from docs/Quick_start_guide.rst was moved
to ITK respository under Documentation/docs/learn/python_quick_start.md
- Addresses issue #282 by silencing non-critical warnings that obscure error identification during developer reviews.
This is the initial refactoring of bash script to python
to support windows builds consistently.
```bash
black $(git ls-files "*.py")
pyupgrade --py39-plus $(git ls-files "*.py")
flynt $(git ls-files "*.py")
black $(git ls-files "*.py")
```
venv is a common name for the directory or the current
environment.  Use virtualenv_exe to more clearly indicate
the program used to create the environment.
More clearly differentiate between the python packaging dir
and the resulting checked out ITK source code
Linux, Macos, and Windows have similar arguments for
configuring each phase of the builds.

This is an initial stage for drying (donot repeat yourself)
out the code.  Preparing to re-use common implementations
for all 3 platforms.
Give a name to the location where files are
are generated and built.
Refactor Windows build scripts to use `dotenv` and update f-string path handling for consistency"
Single wheel was hard-coded as disabled in mac and linux.
It was defaulted to false and un-modified since 2017.

Removing makes windows match mac and linux.
…y, and consistency

Refactored build scripts to replace `os` and `shutil` with `pathlib`. Improved path handling with clean, consistent usage of `Path`. Encapsulated repetitive logic and introduced utility functions like `_which` and `_remove_tree`. Enhanced readability, modularity, and maintainability while maintaining previous functionality.
…e consistency

Simplified `build_wheels` method by removing `cleanup` argument and improving default handling for `cmake_options`. Standardized `itk_source_dir` variable naming and removed unused `env_file` reference. Adjusted type handling for path checks across scripts.
…ipts

Refactored all instances of `check_call` to use the new `echo_check_call` utility function for improved command visibility and debugging. Updated imports across scripts and added the implementation of `echo_check_call` in `wheel_builder_utils`.
Refactored `CMakeLists.txt` by extracting repeated logic into new modular scripts: `ITKPythonPackage_common.cmake`, `ITKPythonPackage_SuperBuild.cmake`, and `ITKPythonPackage_BuildWheels.cmake`. Consolidated logic and improved readability while maintaining existing functionality.

Breaking the very large CMakeLists.txt file into smaller files
makes deciphering the different build phases easier.
- Moved `detect_platform` and `which_required` to `wheel_builder_utils.py` for reuse.
- Updated imports in `generate_build_environment.py` to reference the shared utility functions.
hjmjohnson and others added 29 commits January 9, 2026 11:20
Pixi is now used to install relevant versions of python
needed for making wheels.
This script automates paths and configurations for building Python wheels, including validations and environment-specific builds.
@hjmjohnson
Copy link
Member Author

@thewtex This is what I have been working on as I try to understand the process for building and maintaining python packages.

My goal is to be able to build private Python wheels that are constructed ONLY FOR MY MACHINE with "-mtune=native -march=native" from the HEAD of a private ITK branch. The refactorings are made with the hope that the eventually inside of ITK we can do the following:

git clone ITK
cd ITK
# optional pixi run build-python
pixi run build-python-macosx-py311
pixi run build-python-manylinux-py39

I am also trying to be backwards compatible for supporting external module builds.

I have most of the core components working, but have been struggling to ensure backwards compatibility because there are so many intermediate layers that depend on implicit values (i.e. matching tags an release names across different repos).

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.

2 participants