Skip to content

itk: add build-itk.yml for riscv64 wheels - #4798

Open
luhenry wants to merge 4 commits into
mainfrom
itk
Open

luhenry wants to merge 4 commits into
mainfrom
itk

Conversation

@luhenry

@luhenry luhenry commented Nov 9, 2026 •

Copy link
Copy Markdown
Member

ITK's image-processing/computer-vision toolkit, split across 7 PyPI wheels upstream carves from one Python-wrapping build. Upstream publishes no riscv64 wheel for any of them.

Mirrors upstream's manylinux-build-wheels.sh "multiple wheels" path directly (one ITK configure/build per interpreter, then all 7 wheels carved from it with ITKPythonPackage_ITK_BINARY_REUSE=ON), since that script has no riscv64 case for uname -m/doxygen.

Differs from upstream

  • -DWITH_RVV=OFF - vendored zlib-ng's RVV probe SIGILLs on this runner hardware.
  • cmake pinned to /usr/bin/cmake for the ITK build - the image's newer cmake rejects old cmake_minimum_required in ITK's vendored third-party trees.
  • doxygen installed from Rocky 10's CRB repo - upstream's prebuilt tarball is x86_64/aarch64 only.
  • Module_ITKTBB left off - oneTBB has no verified riscv64 support; ITK's default Pool threader covers it.
  • No CastXML override - its CMakeLists.txt already falls back to building CastXML+LLVM/Clang from source for any platform without a prebuilt binary, which riscv64 hits automatically.

Matrix: cp310/cp311-abi3 only - upstream itself only targets cp39/cp310/cp311 (not riscv64-specific).

Testing

  • same as upstream (install + import checks, docs/code/test.py)

License: OK. Apache-2.0; CastXML/LLVM and doxygen are build-time-only tools, not shipped in any wheel.

Not rehearsed locally - no riscv64/docker toolchain in this sandbox, and the full wrap build (plus CastXML/LLVM built from source) is expected to take the better part of this repo's self-hosted job timeout; first real signal comes from CI.

…segmentation, itk: add version 5.4.7

ITKPythonPackage (InsightSoftwareConsortium/ITKPythonPackage v5.4.7) builds ITK's
full Python wrapping once per interpreter and carves all 7 PyPI wheels out of
that same tree with -DITKPythonPackage_ITK_BINARY_REUSE=ON; its CMakeLists.txt
decides which module goes in which wheel from the whole module graph, so the
split cannot be reproduced per wheel (gotcha 382, same shape as
pyside6/pyside6-essentials/pyside6-addons). One combined build-itk.yml builds
all 7 from a single standalone ITK configure+build per interpreter and 7
disjoint _publish-wheel.yml jobs, with docs/packages/itk.yaml,
itk-numerics.yaml, itk-io.yaml, itk-filtering.yaml, itk-registration.yaml and
itk-segmentation.yaml kept in lockstep with itk-core.yaml's versions (one
`setup` job, keyed on itk-core, the same way build-mlx.yml keeps
docs/packages/mlx-cpu.yaml in lockstep with mlx.yaml).

riscv64-specific adjustments from upstream's own
scripts/internal/manylinux-build-wheels.sh "multiple wheels" path:
- WITH_RVV=OFF reaches ITK's vendored zlib-ng directly (no patch needed here,
  unlike build-simpleitk.yml's SuperBuild layer, since this configures ITK's
  own CMakeLists.txt directly).
- cmake pinned to /usr/bin/cmake for the standalone ITK configure/build only
  (gotcha 358); the per-wheel scikit-build-core carve never reconfigures the
  vendored third-party trees that conflict with the image's newer cmake.
- doxygen installed from Rocky 10's CRB repo (enabled by default on this
  image) instead of upstream's x86_64/aarch64-only prebuilt tarball.
- No riscv64 CastXML prebuilt binary exists upstream
  (Wrapping/Generators/CastXML/CMakeLists.txt only lists Linux x86_64/aarch64,
  Windows, macOS), so this relies on that same CMakeLists.txt's existing
  generic fallback: ITK_USE_SYSTEM_CASTXML defaults OFF, and CastXML 0.6.5 is
  built from source together with LLVM/Clang 18.1.3 as an ExternalProject
  exactly as it would be on any other platform without a prebuilt binary - no
  override needed, just more build time.
- Module_ITKTBB left OFF: oneTBB 2021.9.0 has no verified riscv64 support and
  is itself another from-source dependency; ITK's default Pool threader
  covers it.
- timeout-minutes: 7000, close to the 5-day ceiling GitHub enforces on
  self-hosted runners rather than the 48h build-vtk.yml uses: ITK's own Azure
  CI (default wrap only) is already ~2h35-2h50 on 2 cores, this build adds
  unsigned_short/double/complex_double pixel types and 4-D wrapping plus the
  CastXML/LLVM from-source build on top, and build-vtk.yml's comparable
  full-module build already needed most of its 48h on these 4-core runners.
luhenry added a commit that referenced this pull request Nov 9, 2026
…ration, itk-segmentation and itk as ci-running (PR #4798)
This image's glibc declares _Float128 math functions unconditionally
once it sees a Clang new enough, but the ExternalProject-built
CastXML/Clang 18.1.3 toolchain doesn't recognize _Float128 as a type
on riscv64, so parsing ITKCommonBase.cxx (via <cmath> -> math.h) dies
with 'unknown type name _Float128' before any ITK-specific wrapping
happens. long double is already IEEE binary128 on riscv64, so
-D_Float128=long double in CMAKE_CXX_FLAGS (forwarded to castxml's
--castxml-cc-gnu invocation) resolves it exactly, touching only
glibc's distinctly-named _Float128 declarations.
CMAKE_CXX_FLAGS is a flat string that CMake writes verbatim into the
generated ninja build command, which ninja then hands to /bin/sh -c.
The previous commit's -D_Float128=long double therefore split into
two shell words at the unescaped space ("-D_Float128=long" and
"double"), so every compile - including CMake's own compiler-ABI
check - failed immediately with "double: linker input file not
found", before CastXML/LLVM was ever reached. Escaping the space
(long\ double) keeps it one shell word, giving the compiler the
intended single macro definition.
The previous commit's -D_Float128=long\ double still failed: the
backslash-escaped space is meant to survive bash -> cmake -> ninja's
build.ninja -> sh -c as a single shell word, but CMake re-emits
CMAKE_CXX_FLAGS into the generated ninja rule without preserving the
backslash, so sh -c re-splits it into "long" and "double" and the
compiler rejects "double" as a bogus input file - exactly the same
symptom as before, confirmed in the real cp311 CI log (c++: error:
double: linker input file not found).

Writing the #define into its own header and pulling it in with
-include /work/float128-workaround.h avoids the whole quoting chain:
a path has no embedded space to lose, so there is nothing left for
any of those layers to re-split.

This branch has not been deployed

No deployments
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