Skip to content

COMP: Use pixi-supplied SWIG 4.3.x and CastXML for Python wrapping (intermediary toward SWIG 4.4.1)#6480

Closed
hjmjohnson wants to merge 3 commits into
InsightSoftwareConsortium:mainfrom
hjmjohnson:swig-system-version-floor
Closed

COMP: Use pixi-supplied SWIG 4.3.x and CastXML for Python wrapping (intermediary toward SWIG 4.4.1)#6480
hjmjohnson wants to merge 3 commits into
InsightSoftwareConsortium:mainfrom
hjmjohnson:swig-system-version-floor

Conversation

@hjmjohnson

Copy link
Copy Markdown
Member

Enable ITK Python wrapping to use the pixi/conda-forge-supplied SWIG and CastXML (via the existing ITK_USE_SYSTEM_SWIG/ITK_USE_SYSTEM_CASTXML options) and correct the system-SWIG version floor to match what actually compiles.

This is a deliberately temporary, intermediary reference point. It pins system SWIG to the 4.3.x window that works today with ITK's current Limited-API (abi3) wrapping. The larger goal is to support SWIG 4.4.1, the way SimpleITK already does (SimpleITK/SuperBuild/External_SWIG.cmakeSWIG_TARGET_VERSION 4.4.1, with Limited API ON). 4.4.1 currently builds/links but fails at import under Limited API — tracked in #6479. This PR establishes a green, reproducible 4.3.x baseline so the 4.4.1 wrapping-template work can be done and compared against a known-good reference.

What changed
  • Wrapping/Generators/SwigInterface/CMakeLists.txt
    • swig_version_min 4.2.0 → 4.3.0 (4.2.x cannot compile — see matrix).
    • System-SWIG version check WARNINGFATAL_ERROR so a too-old system SWIG fails at configure time instead of a confusing SWIG_Py_DECREF compile error thousands of lines into the build.
  • pyproject.toml
    • Add swig = ">=4.3.1,<4.4" and castxml = ">=0.7.0,<0.8" to the python pixi feature.
    • configure-python passes -DITK_USE_SYSTEM_SWIG=ON -DITK_USE_SYSTEM_CASTXML=ON.
  • pixi.lock regenerated for the above.
Verified system-SWIG matrix (ITK main 6.0.0, macOS arm64, Limited API on, CastXML 0.7.0 from conda)
System SWIG Result Cause
4.2.1 compile fails use of undeclared identifier 'SWIG_Py_DECREF' in ITKCommonPython.cpp (macro absent before the 4.3 runtime)
2024-03-26-master (vendored) works the snapshot ITK CI is tuned to
4.3.1 works — imports and runs itk.median_image_filter descends from the vendored master, has SWIG_Py_DECREF, pre-4.4 ABI codegen
4.4.1 import fails 4.4 Limited-API moduledef / delete_SwigPyIterator codegen change (#6479)

The vendored 2024-03-26-master is plain upstream SWIG master (no ITK fork/patches), so 4.3.x is the natural release lineage of the snapshot ITK already targets.

Test plan

Locally on macOS arm64: pixi run build-python with system SWIG 4.3.1 + CastXML 0.7.0 builds all wrapping targets (8462/8462), import itk succeeds, and a real filter runs. 4.2.1 and 4.4.1 were confirmed to fail as tabled above. pre-commit run --all-files passes on the branch tip.

Not yet exercised: Linux and Windows confirmation of the 4.3.x window — relying on CI for cross-platform validation.

The generated SWIG wrappers reference the SWIG_Py_DECREF runtime macro,
first shipped in SWIG 4.3.0 (the release line descending from the vendored
2024-03-26-master snapshot). System SWIG 4.2.x lacks the macro and fails to
compile ITKCommonPython.cpp with "use of undeclared identifier
'SWIG_Py_DECREF'", so the previous 4.2.0 floor was never viable.

Assisted-by: Claude Code — bisected the working SWIG range via clean pixi system-SWIG builds
A system SWIG below swig_version_min cannot produce compilable wrappers
(missing the SWIG_Py_DECREF runtime macro), yet the prior WARNING let
configuration proceed to a confusing 'undeclared identifier' compile error
thousands of lines into the build. Promote it to FATAL_ERROR so the
version mismatch is reported at configure time with an actionable hint.
Add swig and castxml to the python pixi feature and pass
ITK_USE_SYSTEM_SWIG/ITK_USE_SYSTEM_CASTXML in configure-python so wrapping
uses the conda-forge toolchain instead of the internal download/build.

SWIG is pinned to 4.3.x because that is the verified working window for
ITK's Limited-API (abi3) wrapping on main:
- 4.2.x fails to compile (the generated wrappers need the SWIG_Py_DECREF
  runtime macro, absent before the 4.3 line).
- 4.3.1 builds, imports, and runs filters cleanly.
- 4.4.1 compiles and links but fails at import with
  'moduledef' object has no attribute 'delete_SwigPyIterator' under
  Limited API; see InsightSoftwareConsortium#6479.
4.3.x is the lineage descending from the vendored 2024-03-26-master
snapshot, so it matches the codegen ITK is currently tuned to. CastXML
0.7.0 has no such constraint and is used unpinned within 0.7.

Assisted-by: Claude Code — bisected the SWIG range via clean pixi system-toolchain builds
@github-actions github-actions Bot added type:Compiler Compiler support or related warnings type:Infrastructure Infrastructure/ecosystem related changes, such as CMake or buildbots labels Jun 20, 2026
@hjmjohnson hjmjohnson marked this pull request as ready for review June 20, 2026 15:18
@greptile-apps

greptile-apps Bot commented Jun 20, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR pins the minimum system SWIG version to 4.3.0 in CMake (up from 4.2.0) and upgrades the too-old-version diagnostic from WARNING to FATAL_ERROR. It simultaneously wires the pixi python environment to supply SWIG 4.3.1 and CastXML 0.7.0 from conda-forge, enabling ITK_USE_SYSTEM_SWIG=ON / ITK_USE_SYSTEM_CASTXML=ON for reproducible Python wrapping builds.

  • CMakeLists.txt: swig_version_min raised to 4.3.0 (4.2.x lacks SWIG_Py_DECREF); WARNINGFATAL_ERROR with a remediation hint so bad installs fail at configure time instead of deep in compilation.
  • pyproject.toml: swig >=4.3.1,<4.4 and castxml >=0.7.0,<0.8 added to the python feature; configure-python gains -DITK_USE_SYSTEM_SWIG:BOOL=ON -DITK_USE_SYSTEM_CASTXML:BOOL=ON; configure-debug-python is missing those same flags (see inline comment).
  • pixi.lock: Regenerated to add swig 4.3.1, castxml 0.7.0, and all transitive deps (libllvm20, libclang-cpp20.1, libxml2, pcre2, etc.) across all five supported platforms.

Confidence Score: 4/5

Safe to merge; the release Python build path is correct and the CMake FATAL_ERROR improves the user experience for bad system SWIG installs.

The CMakeLists.txt and lock-file changes are clean and well-reasoned. The only gap is that configure-debug-python does not pass the system SWIG/CastXML flags, so debug Python builds silently fall back to the vendored SWIG download, making the newly installed pixi packages inert in that workflow. No breakage today, but the inconsistency will likely confuse the next person debugging a Python wrapping issue in a debug build.

pyproject.toml — configure-debug-python task is missing -DITK_USE_SYSTEM_SWIG:BOOL=ON and -DITK_USE_SYSTEM_CASTXML:BOOL=ON

Important Files Changed

Filename Overview
Wrapping/Generators/SwigInterface/CMakeLists.txt Raises swig_version_min from 4.2.0 to 4.3.0 and promotes the too-old-SWIG diagnostic from WARNING to FATAL_ERROR with a clear remediation hint. Both changes are straightforward and correct.
pyproject.toml Adds swig/castxml to the python feature and enables ITK_USE_SYSTEM_SWIG/CASTXML in configure-python; configure-debug-python is missing the same flags, creating a silent inconsistency between release and debug Python workflows.
pixi.lock Regenerated lock file adds swig 4.3.1, castxml 0.7.0, and transitive deps (libllvm20, libclang-cpp20.1, libxml2, pcre2, etc.) for all five target platforms (linux-64, linux-aarch64, osx-64, osx-arm64, win-64).

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A["pixi run build-python\n(python environment)"] --> B["configure-python task\nITK_USE_SYSTEM_SWIG=ON\nITK_USE_SYSTEM_CASTXML=ON"]
    B --> C{CMakeLists.txt\nITK_USE_SYSTEM_SWIG?}
    C -->|ON| D["find_package(SWIG REQUIRED)"]
    D --> E{SWIG_VERSION\n>= 4.3.0?}
    E -->|YES| F["Use pixi swig 4.3.1\n✅ Build succeeds"]
    E -->|NO| G["FATAL_ERROR\n❌ Configure fails with hint"]
    A2["pixi run build-debug-python\n(python environment)"] --> B2["configure-debug-python task\n⚠️ NO SYSTEM_SWIG flag"]
    B2 --> C2{CMakeLists.txt\nITK_USE_SYSTEM_SWIG?}
    C2 -->|OFF default| H["Download vendored\nswig 2024-03-26-master\n(pixi swig 4.3.1 unused)"]
    style G fill:#f88,stroke:#c00
    style H fill:#ffc,stroke:#aa0
    style F fill:#8f8,stroke:#080
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
flowchart TD
    A["pixi run build-python\n(python environment)"] --> B["configure-python task\nITK_USE_SYSTEM_SWIG=ON\nITK_USE_SYSTEM_CASTXML=ON"]
    B --> C{CMakeLists.txt\nITK_USE_SYSTEM_SWIG?}
    C -->|ON| D["find_package(SWIG REQUIRED)"]
    D --> E{SWIG_VERSION\n>= 4.3.0?}
    E -->|YES| F["Use pixi swig 4.3.1\n✅ Build succeeds"]
    E -->|NO| G["FATAL_ERROR\n❌ Configure fails with hint"]
    A2["pixi run build-debug-python\n(python environment)"] --> B2["configure-debug-python task\n⚠️ NO SYSTEM_SWIG flag"]
    B2 --> C2{CMakeLists.txt\nITK_USE_SYSTEM_SWIG?}
    C2 -->|OFF default| H["Download vendored\nswig 2024-03-26-master\n(pixi swig 4.3.1 unused)"]
    style G fill:#f88,stroke:#c00
    style H fill:#ffc,stroke:#aa0
    style F fill:#8f8,stroke:#080
Loading

Comments Outside Diff (1)

  1. pyproject.toml, line 259-268 (link)

    P2 Debug Python builds will silently ignore pixi-supplied SWIG/CastXML

    configure-debug-python is missing -DITK_USE_SYSTEM_SWIG:BOOL=ON and -DITK_USE_SYSTEM_CASTXML:BOOL=ON. When a user in the python environment runs pixi run build-debug-python, CMake falls through to the vendored SWIG download path, leaving the pixi-supplied swig and castxml packages unused. The release and debug Python workflows are now silently inconsistent: one uses system tools, the other fetches a different binary.

Reviews (1): Last reviewed commit: "COMP: Use pixi-supplied SWIG 4.3.x and C..." | Re-trigger Greptile

@hjmjohnson

Copy link
Copy Markdown
Member Author

Superseded by #6484, which makes SWIG 4.4.1 work directly (multi-phase-init fix + vendored 4.4.1 binaries), so the 4.3.x intermediary is no longer needed. Closing in favor of #6484.

@hjmjohnson hjmjohnson closed this Jun 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

type:Compiler Compiler support or related warnings type:Infrastructure Infrastructure/ecosystem related changes, such as CMake or buildbots

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant