%global sitk_major 2 %global sitk_minor 5 Name: python-simpleitk Version: 2.5.5 Release: 11%{?dist} Summary: Simplified interface to the Insight Toolkit (ITK) for image analysis License: Apache-2.0 URL: https://simpleitk.org/ Source0: https://github.com/SimpleITK/SimpleITK/archive/refs/tags/v%{version}/SimpleITK-%{version}.tar.gz # Source1 (SimpleITK-%%{version}-R-ExternalData.tar.gz) is retained in # SOURCES/ but unreferenced here — see the WRAP_R comment in %%build for # why the R wrap is disabled in this release. # https://fedoraproject.org/wiki/Changes/EncourageI686LeafRemoval ExcludeArch: %{ix86} BuildRequires: gcc-c++ BuildRequires: cmake >= 3.16 BuildRequires: ninja-build BuildRequires: swig >= 4.0 # Lua interpreter required for filter source code generation (not wrapping) BuildRequires: lua # Doxygen API HTML for the simpleitk-doc subpackage BuildRequires: doxygen BuildRequires: graphviz BuildRequires: InsightToolkit5-devel >= 5.4.6 # ITK VtkGlue is needed for image display support BuildRequires: InsightToolkit5-vtk-devel >= 5.4.6 # Python bindings BuildRequires: python3-devel BuildRequires: python3-numpy # ITK transitive cmake deps BuildRequires: fftw-devel BuildRequires: expat-devel BuildRequires: libtiff-devel BuildRequires: libjpeg-devel BuildRequires: libpng-devel BuildRequires: zlib-devel BuildRequires: hdf5-devel BuildRequires: gdcm-devel BuildRequires: dcmtk-devel BuildRequires: openjpeg2-devel %if 0%{?fedora} BuildRequires: libminc-devel %endif # VTK transitive cmake deps (find_package in VTK's module config) BuildRequires: vtk-devel BuildRequires: freetype-devel BuildRequires: pugixml-devel BuildRequires: fmt-devel BuildRequires: utf8cpp-devel BuildRequires: PEGTL-devel BuildRequires: jsoncpp-devel BuildRequires: nlohmann-json-devel BuildRequires: json-devel BuildRequires: lz4-devel BuildRequires: xz-devel BuildRequires: double-conversion-devel BuildRequires: glew-devel BuildRequires: libxml2-devel BuildRequires: libogg-devel BuildRequires: libtheora-devel BuildRequires: sqlite-devel BuildRequires: libharu-devel BuildRequires: proj-devel BuildRequires: gdal-devel BuildRequires: netcdf-cxx-devel BuildRequires: cgnslib-devel BuildRequires: libarchive-devel BuildRequires: libpq-devel BuildRequires: mariadb-connector-c-devel BuildRequires: openslide-devel BuildRequires: libX11-devel BuildRequires: libXext-devel BuildRequires: libXt-devel BuildRequires: libXcursor-devel BuildRequires: libGL-devel BuildRequires: cmake(Qt6) BuildRequires: cmake(Qt6Quick) BuildRequires: qt5-qtwebkit-devel BuildRequires: qt6-qtdeclarative-devel %global _description %{expand: SimpleITK is a simplified, open-source interface to the Insight Toolkit (ITK), a C++ library for computational medical imaging. SimpleITK wraps ITK's C++ code into Python (and other languages), providing a streamlined API for image filtering, segmentation, registration, and I/O of 2D, 3D, and 4D images.} # No VTK pin here: none of the four packages this spec builds links VTK at all # (zero libvtk sonames in simpleitk, simpleitk-devel, python3-simpleitk, # simpleitk-doc). The pin that used to sit here was also in the preamble, on a # main "python-simpleitk" package this spec never builds, so it shipped on # nothing either way. %description %{_description} %package -n simpleitk Summary: C++ shared libraries Provides: simpleitk = %{version}-%{release} # Pin the ITK this was built against. ITK freezes its sonames across releases # while ADDING symbols: libITKFFT-5.4.so.1 is identical in name in 5.4.7-2 and # 5.4.7-8, but -8 enabled FFTW and exports # _ZN3itk46FFTWFFTImageFilterInitFactoryRegister__PrivateEv. rpm derives # dependencies from sonames, so it cannot tell the two apart: a binary built # against -8 installs cleanly onto -2 and then dies at exit 127 on every # invocation. Measured on c3d, on a real host. # # This subpackage is the one that needs it: 3 of its 49 shipped objects # reference that symbol (ci/check-symbol-exposure.sh, scope derived from # file(1) rather than a filename glob). simpleitk-devel and python3-simpleitk # reach ITK only through this one, via their `Requires: simpleitk%%{?_isa}`. # # A FLOOR, not an equality: the soname is stable and the breakage is additive, # so a newer ITK is always fine and only an older one is wrong. # # %%itk_ver comes from InsightToolkit5-devel's macros.itk (ITK 5.4.7-9+), which # this package already BuildRequires. The %%{?...}%%{!?...:UNSET} expansion is # required rather than stylistic: rpkg parses this spec with NO buildroot, and a # parse-time guard killed every SCM build of every guarded package before a # chroot existed -- this very package, build 10980296, failed in 0 minutes with # "can't parse specfile". The %%build test below is what makes the floor safe. Requires: InsightToolkit5%{?_isa} >= %{?itk_ver}%{!?itk_ver:UNSET} %description -n simpleitk %{_description} This package contains the core SimpleITK C++ shared libraries. %package -n simpleitk-devel Summary: Development files Requires: simpleitk%{?_isa} = %{version}-%{release} Requires: InsightToolkit5-devel >= 5.4.6 %description -n simpleitk-devel Headers and cmake configuration files for developing C++ applications with SimpleITK. %package -n python3-simpleitk Summary: Python 3 bindings Requires: simpleitk%{?_isa} = %{version}-%{release} Requires: python3-numpy %{?python_provide:%python_provide python3-simpleitk} # SimpleITK's Python bindings are generated by its CMake build, not by a # pyproject/setuptools build, so the automatic Python dependency generator never # emits the python3dist() provide that pyproject-built consumers require. Add it # by hand: packages depending on SimpleITK through PyPI metadata (acvl-utils, # nnunetv2 and the rest of the nnInteractive chain) generate a # python3dist(simpleitk) requirement that is otherwise unsatisfiable. Provides: python3dist(simpleitk) = %{version} Provides: python%{python3_version}dist(simpleitk) = %{version} %description -n python3-simpleitk %{_description} This package contains the Python 3 bindings for SimpleITK. %package -n simpleitk-doc Summary: Doxygen-generated API HTML documentation BuildArch: noarch %description -n simpleitk-doc %{_description} This package contains the Doxygen-generated HTML API reference for SimpleITK. After install, browse %{_docdir}/simpleitk-doc/html/index.html. %prep %autosetup -n SimpleITK-%{version} # Lua 5.5 (rawhide / F45+): SimpleITK's FindLuaInterp pins range 5.3...<5.5 # which excludes Lua 5.5.x. SimpleITK uses Lua only as a code-generation tool # at build time (sitkGenerateFilterSource), so a minor-version bump is safe. # Widen the upper bound to <6.0 so future Lua bumps don't break us again. sed -i -E 's|5\.3\.\.\.<5\.5|5.3...<6.0|g' \ CMake/FindLuaInterp.cmake \ CMake/sitkGenerateFilterSource.cmake 2>/dev/null || : # sitkGenerateFilterSource.cmake also has its own redundant version guard # (independent of FindLuaInterp) at line ~55 that rejects anything not # strictly Lua 5.3-5.4 — widen the upper bound there too. sed -i -E 's|VERSION_LESS "5\.5"|VERSION_LESS "6.0"|g' \ CMake/sitkGenerateFilterSource.cmake %build # itk_ver comes from InsightToolkit5-devel's macros.itk. Absent means the ITK in # this buildroot predates 5.4.7-9, and the Requires on the simpleitk subpackage # would ship as the VACUOUS "InsightToolkit5 >= UNSET" -- which rpm SATISFIES, # because it ranks a numeric segment above an alphabetic one. Verified, not # assumed: `rpmdev-vercmp 5.4.7-9.fc44 UNSET` returns "5.4.7-9.fc44 > UNSET". # The floor would silently disappear and the build would go green pinning # nothing, so this test is mandatory rather than defensive. test -n "%{?itk_ver}" || { echo "ERROR: itk_ver undefined - need InsightToolkit5-devel >= 5.4.7-9 in the buildroot" >&2; exit 1; } export CXXFLAGS="%{optflags} -std=c++17 -include cstdint -fpermissive" %cmake -GNinja \ -DCMAKE_BUILD_TYPE=Release \ -DCMAKE_SKIP_INSTALL_RPATH=ON \ -DBUILD_SHARED_LIBS=ON \ -DBUILD_TESTING=OFF \ -DBUILD_EXAMPLES=OFF \ -DBUILD_DOXYGEN=ON \ `# USE_ITK_DOXYGEN_TAGS defaults to ON and fetches ITK's tag file at` \ `# configure time. With SimpleITK_FORBID_DOWNLOADS=ON that fetch is` \ `# blocked; the build aborts. Disable the cross-link tags entirely.` \ -DUSE_ITK_DOXYGEN_TAGS=OFF \ -DSimpleITK_BUILD_DISTRIBUTE=ON \ -DSimpleITK_FORBID_DOWNLOADS=ON \ -DSimpleITK_INT64_PIXELIDS=ON \ -DSimpleITK_EXPLICIT_INSTANTIATION=OFF \ -DSimpleITK_USE_ELASTIX=OFF \ -DSimpleITK_INSTALL_LIBRARY_DIR=%{_lib} \ -DSimpleITK_INSTALL_ARCHIVE_DIR=%{_lib} \ -DSimpleITK_INSTALL_PACKAGE_DIR=%{_lib}/cmake/SimpleITK-%{sitk_major}.%{sitk_minor} \ -DITK_DIR=%{_prefix}/lib/cmake/ITK-5.4 \ -DWRAP_DEFAULT=OFF \ -DWRAP_PYTHON=ON \ -DSimpleITK_PYTHON_USE_LIMITED_API=OFF \ `# WRAP_R deferred: SimpleITK 2.5.5 PR #2587 patched their bundled` \ `# SWIG for R 4.6.0 API removals, but we use Fedora's system SWIG` \ `# (no equivalent patch), so the SWIG-generated SimpleITKR_wrap.cxx` \ `# fails to compile against R 4.6 (read-only CHARACTER_POINTER on` \ `# STRING_PTR_RO). Reinstate WRAP_R=ON once Fedora's swig package` \ `# carries the upstream PR #2587 backport or SimpleITK 2.5.6 ships a` \ `# system-SWIG-compatible workaround.` \ -DWRAP_R=OFF \ -DWRAP_LUA=OFF \ -DWRAP_JAVA=OFF \ -DWRAP_CSHARP=OFF \ -DWRAP_TCL=OFF \ -DWRAP_RUBY=OFF %cmake_build %install %cmake_install # SimpleITK's cmake LegacyPackaging path (non-SKBUILD) does not install the # Python module. Manually install the SWIG-generated extension and Python # package from the build tree into site-packages. sitk_builddir=%{__cmake_builddir} install -d %{buildroot}%{python3_sitearch}/SimpleITK # SWIG-generated C extension (.so) install -m 0755 ${sitk_builddir}/Wrapping/Python/SimpleITK/_SimpleITK*.so \ %{buildroot}%{python3_sitearch}/SimpleITK/ # SWIG-generated Python wrapper install -m 0644 ${sitk_builddir}/Wrapping/Python/SimpleITK/SimpleITK.py \ %{buildroot}%{python3_sitearch}/SimpleITK/ # Python package files for f in __init__.py extra.py py.typed; do install -m 0644 ${sitk_builddir}/Wrapping/Python/SimpleITK/${f} \ %{buildroot}%{python3_sitearch}/SimpleITK/ done # Version file (generated by cmake from _version.py.in) install -m 0644 ${sitk_builddir}/Wrapping/Python/SimpleITK/_version.py \ %{buildroot}%{python3_sitearch}/SimpleITK/ # R bindings install step removed — WRAP_R=OFF in this release. # Move the Doxygen HTML output into the doc subpackage's docdir. Upstream # emits it to a sibling `Documentation/html/` under the build tree. install -d %{buildroot}%{_docdir}/simpleitk-doc if [ -d ${sitk_builddir}/Documentation/html ]; then cp -a ${sitk_builddir}/Documentation/html %{buildroot}%{_docdir}/simpleitk-doc/ fi # Remove bundled docs installed by cmake (we use %doc/%license). # Note: this strips the cmake-installed doc dir but the doxygen output we # just placed under %%{_docdir}/simpleitk-doc/ is intentional and stays. rm -rf %{buildroot}%{_datadir}/doc/SimpleITK-%{sitk_major}.%{sitk_minor} %check # Minimal import + version check. Runs against the just-installed Python # module in %%{buildroot}; uses PYTHONPATH because the module isn't on the # system path yet at %%check time. PYTHONPATH=%{buildroot}%{python3_sitearch} \ LD_LIBRARY_PATH=%{buildroot}%{_libdir} \ %{python3} -c " import SimpleITK as sitk print('SimpleITK', sitk.Version_VersionString()) print('ITK', sitk.Version_ITKVersionString()) assert sitk.Version_MajorVersion() == %{sitk_major}, 'wrong major' assert sitk.Version_MinorVersion() == %{sitk_minor}, 'wrong minor' # Touch a representative filter to confirm the C++ symbols resolve at runtime img = sitk.Image(64, 64, sitk.sitkUInt8) img = sitk.SmoothingRecursiveGaussian(img, 1.0) print('SmoothingRecursiveGaussian ok') " %ldconfig_scriptlets -n simpleitk %files -n simpleitk %license LICENSE %doc NOTICE Readme.md # 48 shared libraries: 5 core + 42 ITK module wrappers + 1 SimpleITKFilters %{_libdir}/libSimpleITK*-%{sitk_major}.%{sitk_minor}.so.1 %files -n simpleitk-devel %doc NOTICE Readme.md %{_includedir}/SimpleITK-%{sitk_major}.%{sitk_minor}/ %{_libdir}/libSimpleITK*-%{sitk_major}.%{sitk_minor}.so %{_libdir}/cmake/SimpleITK-%{sitk_major}.%{sitk_minor}/ %files -n python3-simpleitk %doc NOTICE Readme.md # Python package with SWIG extension, wrapper, and supporting files %{python3_sitearch}/SimpleITK/ %files -n simpleitk-doc %license LICENSE %doc NOTICE Readme.md %{_docdir}/simpleitk-doc/html/ %changelog * Sat Oct 03 2026 Morgan Hough - 2.5.5-11 - Rebuild against InsightToolkit5 5.4.7-19, because `import SimpleITK` has been DEAD on this chroot since 2026-09-28. Measured again today, in a chroot with ITK 5.4.7-19 and python3-simpleitk-2.5.5-9 installed from the repo: ImportError: /lib64/libSimpleITKRegistration-2.5.so.1: undefined symbol: _ZN3itk35ObjectToObjectOptimizerBaseTemplateIdE18SetNumberOfThreadsEj _SimpleITK.cpython-*.so links libSimpleITKRegistration directly, so the whole module fails, not only the registration part. - WHY A REBUILD IS THE FIX AND WHY IT HAD TO WAIT. Those two symbols are vtable slots inherited from ITK's headers, not call sites -- nothing in SimpleITK calls them. They appear when the package is built against an ITK whose headers still declare the legacy API and vanish when it is built against one that does not. On 2026-09-28 ITK was inconsistent across chroots (-13 and -17 had the legacy API removed, -18 had it back), so rebuilding was a bet on which way ITK would land and the rebuild was deliberately held. ITK has settled: -19 is uniform across all six chroots and does not export the symbol, confirmed with nm. - The %%itk_ver floor was already here, and it would not have caught this. A floor rejects an ITK that is too OLD; this was an ITK differently CONFIGURED at the same version and the same soname. - Submitted straight to COPR rather than local mock first. ci/PROCEDURES.md gate 0 covers source changes; this is a dependency-driven rebuild of code already known to compile, and a local pass would cost ~6.8 h before COPR saw it. * Fri Sep 25 2026 Morgan Hough - 2.5.5-10 - Pin the ITK this was built against on the simpleitk subpackage: Requires InsightToolkit5 >= %%{itk_ver}, with a %%build guard. ITK freezes sonames across releases while adding symbols -- libITKFFT-5.4.so.1 is identical in name in 5.4.7-2 and 5.4.7-8, but -8 enabled FFTW and exports a registration symbol -2 does not. rpm derives dependencies from sonames, so a binary built against -8 installs cleanly onto -2 and dies at exit 127 on every invocation. Measured on c3d, on a real host. - 3 of the simpleitk subpackage's 49 shipped objects reference that symbol (ci/check-symbol-exposure.sh, scope from file(1) rather than a glob). simpleitk-devel and python3-simpleitk inherit the floor through their existing `Requires: simpleitk%%{?_isa}`, so the pin belongs on the base package only. - A floor rather than an equality: the breakage is additive, so a newer ITK is always fine and only an older one is wrong. - The %%build guard is mandatory, not defensive: ">= UNSET" is SATISFIED, since rpm ranks a numeric segment above an alphabetic one (rpmdev-vercmp 5.4.7-9.fc44 UNSET -> "5.4.7-9.fc44 > UNSET"), so an undefined macro would make the floor vacuous and the build would go green pinning nothing. * Sat Sep 19 2026 Morgan Hough - 2.5.5-9 - Rebuild against InsightToolkit5 5.4.7-8, which unbundles Eigen3, VXL and double-conversion. No source or spec change; the Release bump is what makes the rebuild reach anyone. COPR adds a sibling at an already-published NVR rather than replacing it, and dnf then serves the older copy -- so a rebuild at the same NVR would leave this package linked against the bundled ITK while appearing to succeed. - Validated against -8 in mhough/neurofedora-itk5-test before this bump. * Tue Sep 15 2026 Morgan Hough - 2.5.5-8 - Dropped the vtk(abi) pin and its %%build guard entirely. None of the four packages this spec builds links VTK -- zero libvtk sonames across simpleitk, simpleitk-devel, python3-simpleitk and simpleitk-doc. The pin was also in the preamble, on a main "python-simpleitk" package this spec never builds, so it had never shipped on anything regardless. * Sun Aug 23 2026 Morgan Hough - 2.5.5-7 - Rebuild against VTK 9.7.0. VTK here installs unversioned sonames (libvtk*.so.1), so 9.7 replaces 9.6 in place and every consumer must be rebuilt or it fails at runtime with undefined symbols. * Sat Jul 18 2026 Morgan Hough - 2.5.5-6 - Provide python3dist(simpleitk). The bindings are built by CMake rather than a pyproject build, so the automatic generator emits no python3dist() provide and every pyproject-built consumer that declares a SimpleITK dependency (acvl-utils, nnunetv2, the nnInteractive chain) failed to resolve it. * Mon May 25 2026 Morgan Hough - 2.5.5-5 - Fix second Lua version guard at sitkGenerateFilterSource.cmake:55 that independently rejected Lua 5.5 even after FindLuaInterp range bump. * Mon May 25 2026 Morgan Hough - 2.5.5-4 - Widen FindLuaInterp version range from 5.3...<5.5 to 5.3...<6.0 in %%prep to accommodate Lua 5.5 on rawhide / F45+. SimpleITK uses Lua only at build time for filter codegen, so the bump is safe. * Wed May 20 2026 Morgan Hough - 2.5.5-3 - Six Fedora-review-prep fixes: 1. Drop `%%define debug_package %%{nil}` so the standard Fedora strip+debuginfo flow runs. Produces a proper simpleitk-debuginfo subpackage; shrinks the simpleitk binary RPM by ~75%%. 2. Add %%check stanza that imports SimpleITK and exercises one representative filter against the just-built tree. 3. Enable BUILD_DOXYGEN=ON + new simpleitk-doc noarch subpackage shipping HTML API reference under %%{_docdir}/simpleitk-doc/html/. USE_ITK_DOXYGEN_TAGS=OFF to keep SimpleITK_FORBID_DOWNLOADS=ON. 4. Add %%doc NOTICE Readme.md to simpleitk-devel and python3-simpleitk subpackages (rpmlint no-documentation). 5. Bump simpleitk-devel's transitive Requires: InsightToolkit5-devel to >= 5.4.6 (was >= 5.4.5, stale). 6. Drop "SimpleITK"/"for SimpleITK" from subpackage Summary: tags (rpmlint name-repeated-in-summary). * Tue May 19 2026 Morgan Hough - 2.5.5-2 - Disable WRAP_R for now. Build #10480856 failed at step 1057/1058 compiling SimpleITKR_wrap.cxx — the SWIG-generated R wrapper writes through CHARACTER_POINTER(VECTOR_ELT(result, pos))[vpos] which R 4.6 made read-only (STRING_PTR_RO). SimpleITK 2.5.5's PR #2587 patched their bundled SWIG to emit Rf_SET_STRING_ELT-style code, but the patch lives in SuperBuild/External_SWIG.cmake — irrelevant when we build against Fedora's system SWIG. Reinstate WRAP_R=ON when Fedora's swig backports the fix or SimpleITK 2.5.6 finds a system-SWIG-compatible workaround. Drop the R-SimpleITK subpackage and the R install glue for now. * Mon May 18 2026 Morgan Hough - 2.5.5-1 - Update to SimpleITK 2.5.5 (upstream 2026-05-13) - Enable WRAP_R=ON: SimpleITK 2.5.5 includes the R 4.6.0 API-removal fixes (PR #2585 R CLOENV, PR #2587 SWIG superbuild patch) needed against Fedora 44's R 4.6.0 - Add R-SimpleITK subpackage with R bindings installed under %%{_libdir}/R/library/SimpleITK - Require InsightToolkit5 5.4.6 (upstream 2026-05-01, GDCM CVE-2026-3650) * Sun Mar 15 2026 Morgan Hough - 2.5.3-2 - Add lua BuildRequires: needed for filter source code generation * Sun Mar 15 2026 Morgan Hough - 2.5.3-1 - Initial package for SimpleITK 2.5.3 - Python 3 bindings via SWIG - Requires ITK 5.4.5 with SimpleITKFilters and LabelErodeDilate modules