# Disable LTO. Must sit above the first use of %%{optflags} (the export CXXFLAGS # below) or it silently does nothing -- %%global takes effect from where it is # parsed, and a later definition cannot un-expand a flag already substituted. %global _lto_cflags %{nil} # itksnap-alpha — a local, co-installable snapshot of the ITK-SNAP master # branch (self-identifies as 4.6.0-alpha.0). ITK-SNAP has no source release # or git tag for stable 4.4.0 (SourceForge ships 4.4.0 binaries only; the # newest git tag is v4.4.0-beta2), so master is the closest buildable source # newer than beta2. Entry points are suffixed -alpha so this installs next # to the stable "itksnap" package. %global commit b107ab02ef488a16f1b9c914e8ed8283a91ba197 %global shortcommit %(c=%{commit}; echo ${c:0:7}) %global snapdate 20260513 # SNAP_VERSION_FULL from CMakeLists.txt (MAJOR.MINOR.PATCH+QUALIFIER) — this # is the suffix upstream uses for the install dir %%{_prefix}/lib/snap-VERSION. %global snap_ver 4.6.0-alpha.0 # Submodule commits pinned by the itksnap tree at %%{commit} (unchanged from # v4.4.0-beta2 through current master — same three SHAs). %global c3d_commit d4d963629d7dfdca4b0607907f0e91827c22ea2a %global greedy_commit 2d5dfa1891ac726524495d4ca8a3461be86c12f5 %global digestible_commit 1b66709e99c43d280bb472e1a0e36185ef2ea412 # No shared libs installed (BUILD_SHARED_LIBS=OFF); suppress empty debug pkg %define debug_package %{nil} Name: itksnap-alpha Version: 4.6.0~alpha0 Release: 12.%{snapdate}git%{shortcommit}%{?dist} Summary: Medical image segmentation tool (development snapshot) License: GPL-3.0-or-later URL: http://www.itksnap.org # Main source — a pinned master commit. GitHub does not include submodules in # the archive; they are handled separately below via Sources 1-3. Source0: https://github.com/pyushkevich/itksnap/archive/%{commit}/itksnap-%{commit}.tar.gz Source1: https://github.com/pyushkevich/c3d/archive/%{c3d_commit}/c3d-%{c3d_commit}.tar.gz Source2: https://github.com/pyushkevich/greedy/archive/%{greedy_commit}/greedy-%{greedy_commit}.tar.gz Source3: https://github.com/pyushkevich/digestible/archive/%{digestible_commit}/digestible-%{digestible_commit}.tar.gz # Desktop entry — upstream installs neither a .desktop file nor an icon. Source4: itksnap-alpha.desktop # Migrate the main application away from APIs removed by ITK_LEGACY_REMOVE. Patch0: itksnap-alpha-itk-events-orientation.patch BuildRequires: cmake >= 3.16 BuildRequires: ninja-build BuildRequires: gcc-c++ BuildRequires: desktop-file-utils # ITK 5.4+ from our COPR; ITK_DIR is set explicitly in %%build because ITK # installs to a versioned cmake path. BuildRequires: InsightToolkit5-devel >= 5.4.6 # VTK 9.3.1+ required; Fedora ships 9.2.6 so this comes from our COPR. BuildRequires: vtk-devel # Qt6 — use cmake() virtual BRs so RPM pulls the right subpackage automatically BuildRequires: cmake(Qt6Widgets) BuildRequires: cmake(Qt6OpenGL) BuildRequires: cmake(Qt6OpenGLWidgets) BuildRequires: cmake(Qt6Concurrent) BuildRequires: cmake(Qt6Qml) BuildRequires: cmake(Qt6LinguistTools) # Networking (libssh is REQUIRED; CURL is optional but requested by upstream) BuildRequires: libssh-devel BuildRequires: libcurl-devel # FFTW3 — used by the Greedy registration submodule BuildRequires: fftw-devel # OpenGL / X11 BuildRequires: mesa-libGL-devel BuildRequires: libX11-devel # VTK transitive dependencies: VTK's cmake config propagates these as required # link targets (nlohmann_json::nlohmann_json, Freetype::Freetype, JsonCpp::JsonCpp, # etc.) so they must be present in any chroot that builds against vtk-devel. BuildRequires: json-devel BuildRequires: freetype-devel BuildRequires: jsoncpp-devel BuildRequires: utf8cpp-devel BuildRequires: PEGTL-devel BuildRequires: lz4-devel BuildRequires: double-conversion-devel # Pin the exact VTK ABI this package was built against. VTK freezes its soname at # libvtk*.so.1 across all of 9.x, so rpm cannot tell 9.5 from 9.6 from 9.7: a consumer # built against one installs cleanly against another and fails at LOAD with undefined # symbols. A >= floor does not help -- 9.7.0 satisfies >= 9.6.2 -- so this is an exact # match. %%vtk_abi comes from vtk-devel's macros.vtk, so it re-pins on every rebuild. # # The missing-macro check lives in %%build, deliberately, NOT at parse time. A # parse-time %%error cannot distinguish "COPR is generating the SRPM" from "this is a # real buildroot": rpkg srpm parses the spec with no buildroot and therefore no # vtk-devel, so a parse-time guard killed every SCM build of every guarded package # before any chroot existed (python-simpleitk 10980296 failed in 0 minutes with # "can't parse specfile"). Expanding to UNSET keeps the SRPM parse alive, and the # %%build test still fails loudly in a buildroot lacking vtk-devel, so no RPM carrying # the placeholder can ever be produced. Requires: vtk(abi) = %{?vtk_abi}%{!?vtk_abi:UNSET} # ITK floor, same mechanism as the vtk(abi) pin above and for the same reason: # a version this package was built against that rpm cannot otherwise see. # # ITK freezes its sonames across releases while ADDING symbols. # libITKFFT-5.4.so.1 is byte-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 them apart: a binary built # against -8 installs cleanly onto -2 and then dies at exit 127 on every # invocation. Measured on this package: 1 of its 3 shipped objects references # that symbol (ci/check-symbol-exposure.sh, scope derived from file(1)). # # A FLOOR, not an equality like vtk(abi): the soname is stable and the breakage # is additive, so a NEWER ITK is always fine and only an older one is wrong. An # equality would force a rebuild on every ITK release for nothing. # # %%itk_ver comes from InsightToolkit5-devel's macros.itk (ITK 5.4.7-9+). The # %%{?...}%%{!?...:UNSET} expansion is required, not stylistic -- see the note # above on vtk_abi: rpkg parses this spec with no buildroot, so a parse-time # guard kills the SRPM build before any chroot exists. The %%build test below is # what makes the floor safe. Requires: InsightToolkit5%{?_isa} >= %{?itk_ver}%{!?itk_ver:UNSET} # itk(abi): ITK_LEGACY_REMOVE changes class layouts at unchanged sonames, so the itk_ver floor alone let a # consumer built against the removed state install over the present one (python3-simpleitk -11 on ITK -23 # returned all-zero images). Equality on the legacy-state token; see InsightToolkit5.spec. Requires: itk(abi) = %{?itk_abi}%{!?itk_abi:UNSET} BuildRequires: dcmtk-devel # Pin the exact DCMTK snapshot this package was built against. dcmtk is packaged from git # HEAD and upstream's DCMTK_ABI_VERSION stays 20 across snapshots, so every snapshot installs # libdcm*.so.20 and rpm cannot tell them apart: a consumer built against one installs cleanly # against another and fails at load with undefined symbols (dcmqi on f45, with OverlapUtil). # %%dcmtk_abi comes from dcmtk-devel's macros.dcmtk, so it re-pins on every rebuild. The # missing-macro check is in %%build, not at parse time, for the reason spelled out at the vtk # pin in 3dslicer.spec: an SRPM parse has no buildroot. Requires: dcmtk(abi) = %{?dcmtk_abi}%{!?dcmtk_abi:UNSET} %description ITK-SNAP is a software application used to segment structures in 3D and 4D biomedical images such as MRI, CT, and PET scans. It provides: * Semi-automatic segmentation using active contour methods * AI-assisted segmentation (nnInteractive: point, scribble, lasso modes) * Manual delineation and label editing tools * High-performance OpenGL2-based 2D slice rendering * External 3D/4D mesh visualization This is a co-installable snapshot of the upstream master branch (4.6.0-alpha.0). Its entry points are suffixed -alpha (itksnap-alpha, itksnap-wt-alpha) so it can be installed next to the stable "itksnap" package; the GUI binary itself lives in a version-specific directory. This snapshot ships the ITK-SNAP GUI only — not the bundled Convert3D / Greedy command-line tools. %prep # The GitHub commit archive expands to itksnap-. %autosetup -p1 -n itksnap-%{commit} # Populate git submodule directories from the pinned tarballs. # The upstream CMakeLists hard-codes ADD_SUBDIRECTORY into Submodules/{c3d,greedy}; # both directories must exist and contain the unpacked source. tar -xf %{SOURCE1} -C Submodules/c3d --strip-components=1 tar -xf %{SOURCE2} -C Submodules/greedy --strip-components=1 tar -xf %{SOURCE3} -C Submodules/digestible --strip-components=1 # The c3d submodule does not compile, and then does not run, against an ITK # built with ITK_LEGACY_REMOVE -- which Fedora's InsightToolkit5 is, because # ITK's CMake forces it on whenever ITK_WRAP_PYTHON is enabled. # # This is the SAME source as the standalone c3d package (both pin a # pyushkevich/c3d commit; the two trees are identical for these constructs -- # 5 files, 106 occurrences, verified). The three blocks below are therefore # kept deliberately IDENTICAL to c3d.spec's %%prep, so that one source has one # recognisable fix in both packages. If you change one, change the other. # # They must run here rather than as a Patch, because Submodules/c3d does not # exist until the tarball above is unpacked. cd Submodules/c3d # 1. A call to a method ITK no longer declares. ITK's own header says "the # implementation of this method is now empty", so deleting the call is # correct rather than expedient. grep -q 'ResetFilterProgressAndKeepAccumulatedProgress' \ itkextras/itkMultiScaleHessianBasedMeasureImageFilter.hxx \ || { echo "ERROR: the legacy ITK call is gone -- drop this block" >&2; exit 1; } sed -i '/progress->ResetFilterProgressAndKeepAccumulatedProgress();/d' \ itkextras/itkMultiScaleHessianBasedMeasureImageFilter.hxx ! grep -rq 'ResetFilterProgressAndKeepAccumulatedProgress' . \ || { echo "ERROR: a call to the removed ITK method survives:" >&2 grep -rn 'ResetFilterProgressAndKeepAccumulatedProgress' . >&2; exit 1; } # 2. itk::SpatialOrientation is a compatibility namespace of `using` aliases # living entirely inside #ifndef ITK_LEGACY_REMOVE, so the name does not # exist and PrintImageInfo.cxx:52 fails to compile. The ORIENTATION_ rewrite # must run FIRST or the general form would swallow it. grep -rq 'SpatialOrientation::ITK_COORDINATE_ORIENTATION_' . \ || { echo "ERROR: the legacy SpatialOrientation aliases are gone -- drop this block" >&2; exit 1; } grep -rl 'SpatialOrientation' --include=*.cxx --include=*.h --include=*.hxx . \ | xargs sed -i \ -e 's/SpatialOrientation::ITK_COORDINATE_ORIENTATION_/SpatialOrientationEnums::ValidCoordinateOrientations::ITK_COORDINATE_ORIENTATION_/g' \ -e 's/SpatialOrientation::ValidCoordinateOrientationFlags/SpatialOrientationEnums::ValidCoordinateOrientations/g' if grep -ro 'SpatialOrientation::[A-Za-z_]*' . | grep -v SpatialOrientationEnums | grep -q .; then echo "ERROR: legacy SpatialOrientation references survive:" >&2 grep -rno 'SpatialOrientation::[A-Za-z_]*' . | grep -v SpatialOrientationEnums >&2 exit 1 fi # 3. SwapDimensions.cxx resists the rewrite above: it pulls the whole legacy # namespace in with a using-directive and names the enumerators bare. # `using namespace` cannot work against the replacement, because # SpatialOrientationEnums is a CLASS, not a namespace, and the enumerators # now live in an `enum class` so each must be qualified. grep -q '^using namespace itk::SpatialOrientation;$' adapters/SwapDimensions.cxx \ || { echo "ERROR: the using-directive is gone -- drop this block" >&2; exit 1; } sed -i \ -e 's|^using namespace itk::SpatialOrientation;$|using ValidCoordinateOrientationFlags = itk::SpatialOrientationEnums::ValidCoordinateOrientations;|' \ -e 's/\([^:A-Za-z0-9_]\)ITK_COORDINATE_ORIENTATION_/\1ValidCoordinateOrientationFlags::ITK_COORDINATE_ORIENTATION_/g' \ -e 's/^ITK_COORDINATE_ORIENTATION_/ValidCoordinateOrientationFlags::ITK_COORDINATE_ORIENTATION_/' \ adapters/SwapDimensions.cxx if grep -qE '(^|[^:A-Za-z0-9_])ITK_COORDINATE_ORIENTATION_' adapters/SwapDimensions.cxx; then echo "ERROR: unqualified ITK_COORDINATE_ORIENTATION_ enumerators survive:" >&2 grep -nE '(^|[^:A-Za-z0-9_])ITK_COORDINATE_ORIENTATION_' adapters/SwapDimensions.cxx >&2 exit 1 fi cd ../.. # get_git_commit_date() fails when building from a tarball (SNAP_VERSION_GIT_BRANCH # is empty, making the call have only 1 argument instead of 2). Set timestamp directly. sed -i 's|get_git_commit_date.*SNAP_VERSION_GIT_TIMESTAMP.*|set(SNAP_VERSION_GIT_TIMESTAMP "")|' CMakeLists.txt %build # dcmtk_abi comes from dcmtk-devel's macros.dcmtk. Absent means the buildroot has a dcmtk-devel # that predates the snapshot, and the Requires above would carry the UNSET placeholder. test -n "%{?dcmtk_abi}" || { echo "ERROR: dcmtk_abi undefined - needs the dcmtk-devel that ships macros.dcmtk" >&2; exit 1; } # vtk_abi comes from vtk-devel's macros.vtk. Absent means BuildRequires: vtk-devel is # missing, and the Requires above would ship as the vacuous "vtk(abi) = UNSET". test -n "%{?vtk_abi}" || { echo "ERROR: vtk_abi undefined - add 'BuildRequires: vtk-devel'" >&2; exit 1; } # itk_ver comes from InsightToolkit5-devel's macros.itk. Absent means the ITK in # this buildroot predates 5.4.7-9, and the Requires above would ship as the # VACUOUS "InsightToolkit5 >= UNSET" -- which rpm SATISFIES, because it ranks a # numeric segment above an alphabetic one (verified: rpmdev-vercmp 5.4.7-9.fc44 # UNSET -> "5.4.7-9.fc44 > UNSET"). The floor would silently disappear and the # build would go green pinning nothing. This test is the only thing preventing # that, so it 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; } test -n "%{?itk_abi}" || { echo "ERROR: itk_abi undefined - needs InsightToolkit5-devel >= 5.4.7-24 (macros.itk)" >&2; exit 1; } # C++17 is required; -include cstdint guards against GCC 15 missing-header errors # seen in ITK-internal headers on Fedora 43+. export CXXFLAGS="%{optflags} -std=c++17 -include cstdint" # ITK-SNAP bundles jsoncpp 0.10.6 (Common/JSon/jsoncpp.cpp), compiled into the # static libitksnaplogic.a. Linking that archive into the ITK-SNAP executable # re-exports jsoncpp's ~567 symbols into the exe's dynamic symbol table, where # they interpose the system libjsoncpp.so.26 (1.9.6) that VTK pulls in. When # libjsoncpp.so.26 runs its static initializer it then calls into the bundled # 0.10.6 code with mismatched ABI, segfaulting before main(). --exclude-libs # keeps static-archive symbols out of .dynsym, so each jsoncpp copy stays # self-contained. (Unbundling to system jsoncpp is the longer-term fix.) export LDFLAGS="%{build_ldflags} -Wl,--exclude-libs,ALL" %cmake -GNinja \ -DCMAKE_BUILD_TYPE=Release \ \ -DITK_DIR=%{_prefix}/lib/cmake/ITK-5.4 \ \ -DBUILD_SHARED_LIBS=OFF \ -DSNAP_USE_GPU=OFF \ -DSNAP_USE_OSMESA=OFF \ -DSNAP_USE_IWYU=OFF \ \ -DCMAKE_SKIP_INSTALL_RPATH=ON %cmake_build %install %cmake_install # qt.conf is written by qt_generate_deploy_app_script(); not needed for a # system-installed Qt application where plugins are found via standard paths. rm -f %{buildroot}%{_bindir}/qt.conf # Rename the entry points with an -alpha suffix so this snapshot installs # alongside the stable itksnap package. The real GUI binary already lives in # a version-specific dir (snap-%%{snap_ver}/) and needs no rename. mv %{buildroot}%{_bindir}/itksnap %{buildroot}%{_bindir}/itksnap-alpha mv %{buildroot}%{_bindir}/itksnap-wt %{buildroot}%{_bindir}/itksnap-wt-alpha # The bundled Convert3D / Greedy CLI tools are not newer than the stable # itksnap or the standalone c3d/greedy packages and would collide with them; # this alpha snapshot ships the ITK-SNAP GUI only. rm %{buildroot}%{_bindir}/c2d rm %{buildroot}%{_bindir}/c3d rm %{buildroot}%{_bindir}/c3d_affine_tool rm %{buildroot}%{_bindir}/c4d rm %{buildroot}%{_bindir}/greedy rm %{buildroot}%{_bindir}/greedy_propagation rm %{buildroot}%{_bindir}/greedy_template_average rm %{buildroot}%{_bindir}/multi_chunk_greedy # Desktop entry + application icon (upstream installs neither). The icon is # 114x114 — a non-standard size — so it goes to pixmaps rather than a # hicolor theme directory. desktop-file-install --dir=%{buildroot}%{_datadir}/applications %{SOURCE4} install -Dpm 0644 GUI/Qt/Resources/logo_square.png \ %{buildroot}%{_datadir}/pixmaps/%{name}.png %check desktop-file-validate %{buildroot}%{_datadir}/applications/%{name}.desktop # ITK-SNAP's usage banner takes ONE image: "ITK-SNAP [options] [main_image]". # %%F would hand it several paths for a multi-selection, which it does not accept. grep -q '^Exec=itksnap-alpha %%f$' %{buildroot}%{_datadir}/applications/%{name}.desktop %files %license COPYING # Main application — the -alpha-suffixed wrapper and the real binary. Upstream # installs the real binary under %%{_prefix}/lib/snap-${SNAP_VERSION_FULL}/. %{_bindir}/itksnap-alpha %dir %{_prefix}/lib/snap-%{snap_ver} %{_prefix}/lib/snap-%{snap_ver}/ITK-SNAP # Desktop integration %{_datadir}/applications/%{name}.desktop %{_datadir}/pixmaps/%{name}.png # Workspace tool (CLI for managing ITK-SNAP workspaces) %{_bindir}/itksnap-wt-alpha %changelog * Tue Oct 06 2026 Morgan Hough - 4.6.0~alpha0-12.20260513gitb107ab0 - Pin the ITK layout state: Requires: itk(abi) = %%{itk_abi}, from InsightToolkit5-devel's macros.itk, plus a %%build guard. ITK -23 flipped ITK_LEGACY_REMOVE back off, which changes class layouts at unchanged sonames; this package was built against -10..-21 (legacy removed) and the itk_ver floor let it install over -23, giving silent wrong results or crashes. Rebuild against ITK >= 5.4.7-24. * Mon Oct 05 2026 Morgan Hough - 4.6.0~alpha0-11.20260513gitb107ab0 - Pin the exact DCMTK snapshot: Requires: dcmtk(abi) = %%{dcmtk_abi}, from dcmtk-devel's macros.dcmtk, plus a %%build guard against the UNSET placeholder. dcmtk is now packaged from git HEAD (policy in dcmtk.spec) and upstream's DCMTK_ABI_VERSION stays 20 across snapshots, so rpm cannot tell snapshots apart by soname. Without a rebuild against the snapshot this package would install cleanly and fail at load. * Sat Oct 03 2026 Morgan Hough - 4.6.0~alpha0-10.git - Desktop entry: Exec= takes %%f, not %%F. The binary's own usage banner is "ITK-SNAP [options] [main_image]" -- one image -- so %%F would pass a multi-selection it cannot take. Asserted in %%check. Desktop-only change; the built binaries are unchanged from -9, which was verified on f44 and f45 (3 ELF objects, 0 undefined symbols, launches offscreen). * Wed Sep 30 2026 Morgan Hough - 4.6.0~alpha0-9.git - Replace removed itkEventMacro with application-owned inline event classes, preserving nested events and header-only definitions. - Migrate orientation aliases in the main application and VoxBo image IO, in addition to the existing c3d submodule rewrites. - Replace removed image IO aliases and preserve the accumulator's silent progress updates with an application-owned value and GetProgress override. * Tue Sep 29 2026 Morgan Hough - 4.6.0~alpha0-8.git - ITK-SNAP did not start AT ALL. Installed from the COPR into a clean f44 chroot it exits 127: undefined symbol itk::ProgressAccumulator::ResetFilterProgressAndKeepAccumulatedProgress(). Found while auditing this package's desktop entry, which is worth noting -- the desktop work was cosmetic and the package underneath was dead. - This is the ITK_LEGACY_REMOVE regression (docs/reports/), reached by a different API than the ANTs/SimpleITK/charm_gems cases already recorded there, which are all the optimizer SetNumberOfThreads family. The method is declared inside "#if !defined(ITK_LEGACY_REMOVE)" (itkProgressAccumulator.h:113) and the installed itkConfigure.h:75 has "#define ITK_LEGACY_REMOVE", so the declaration is compiled out and the definition is exported by NONE of the 82 shipped ITK libraries. Control: 30 other ProgressAccumulator symbols ARE defined, so the class is fine and this is one removed member. - Unlike ANTs, a rebuild is NOT the whole fix -- confirmed rather than predicted. The first attempt at this release deleted only the progress call and still failed to COMPILE, on Submodules/c3d/adapters/PrintImageInfo.cxx. - TWO removed constructs, and they surface in SEQUENCE: fixing the first is what exposes the second. (a) the ProgressAccumulator call, 1 site, which ITK's own docs describe as having an implementation that "is now empty", so deleting it restores the intent rather than changing it. (b) the whole itk::SpatialOrientation namespace -- `using` aliases living inside #ifndef ITK_LEGACY_REMOVE -- 5 files, 106 occurrences. - An earlier sweep here reported construct (b) as 2 files. That was wrong: it anchored the pattern on "itk::SpatialOrientation" and missed three files that reference it bare. Patching from that count would have shipped a third partial fix. - adapters/SwapDimensions.cxx needs a different rewrite from the other four: it pulls the namespace in with a using-directive and names 48 enumerators bare. `using namespace` cannot be pointed at the replacement, because SpatialOrientationEnums is a CLASS, not a namespace, and the enumerators now live in an `enum class`, so each has to be qualified. - The %%prep blocks are deliberately IDENTICAL to c3d.spec's, because this is the SAME upstream source: the submodule pin and the standalone c3d pin carry the same 5 files and 106 occurrences. One source, one recognisable fix, in both packages. Change one, change the other. This replaces the Patch0 of the first -8 attempt, which covered only construct (a). - CORRECTION to that first -8 attempt, which claimed "standalone c3d is NOT affected and needs nothing". That was wrong and is worth stating plainly, because the wrong version was published. c3d IS affected, in the same two places: its binaries show 0 undefined symbols only BECAUSE c3d.spec has rewritten the same source in %%prep since 1.4.6-5. The evidence that misled me -- 0 undefined symbols, c3d -h exits 0, built after ITK 5.4.7-19 -- was a measurement of the fixed package, not of unaffected source. c3d is safe only for as long as those %%prep blocks remain. - Neither construct appears to have been reported upstream, though the workaround has shipped in c3d since 1.4.6-5. Report covers both: docs/upstream/c3d-itk-legacy-progress-accumulator.md. * Thu Sep 24 2026 Morgan Hough - 4.6.0~alpha0-7.git - Pin the ITK this was built against: 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. - 1 of this package's 3 shipped objects references that symbol (ci/check-symbol-exposure.sh, scope derived from file(1) rather than a glob). - A floor rather than a vtk(abi)-style 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. - %%itk_ver ships in InsightToolkit5-devel >= 5.4.7-9, which is built, published and verified fetchable on f44 and f45, both arches. * Sat Sep 19 2026 Morgan Hough - 4.6.0~alpha0-6.git - 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. * Wed Sep 16 2026 Morgan Hough - 4.6.0~alpha0-5.20260513gitb107ab0 - Rebuild against InsightToolkit5 5.4.7-2. The published -4 links 46 libITK* sonames but was built 2026-09-13, before 5.4.7 existed on either arch; ITK's soname encodes only the 5.4 series, so rpm cannot see the difference and nothing upgrades on its own. - The bump is also required for aarch64: -4 is published there twice at one NVR (10981745 and the tier rebuild), and dnf serves the older copy, so a rebuild at -4 would have reached nobody. * Sun Sep 13 2026 Morgan Hough - 4.6.0~alpha0-4.20260513gitb107ab0 - Rebuild to ship the vtk(abi) exact-match pin added in 4fc6a29. The published -3 carries only a floor: "vtk >= 9.7.0" on x86_64 and "vtk >= 9.6.2" on aarch64, the latter built against VTK 9.6.2 and so exposed to a runtime break now that aarch64 has 9.7 (the .so.1 soname does not change). Bumped because the same NVR would not supersede -3. * Wed Sep 09 2026 Morgan Hough - 4.6.0~alpha0-3.20260513gitb107ab0 - Actually apply the LTO override. In -2 it was placed inside %%build, below "export CXXFLAGS=%%{optflags} ...", so %%{optflags} had already expanded with -flto=auto and the %%global did nothing. Build 10966206 therefore failed identically to 10965737, which looked like the LTO theory being disproved when in fact it had never been tested. Moved to the top of the spec, above the first use of %%{optflags}; the expanded spec now contains no -flto. * Wed Sep 09 2026 Morgan Hough - 4.6.0~alpha0-2.20260513gitb107ab0 - Disable LTO. First-ever chroot build (COPR 10965737) got to object 750 of 772 and then failed linking Test_OrientationWidget with undefined references to std::__cxx11::basic_string's (char const*, allocator const&) constructor, emitted from jsoncpp.cpp.o inside the static libitksnaplogic.a. The main ITK-SNAP executable links that same archive and links fine, so this is not a missing library -- it has the shape of an LTO/static-archive interaction. mitk.spec disables LTO against this same system ITK/VTK stack for the same class of failure. - Note for whoever picks this up if LTO is not the cause: upstream declares the test targets with bare ADD_EXECUTABLE and no IF(BUILD_TESTING) guard (CMakeLists.txt:1344-1506), so -DBUILD_TESTING=OFF does not skip them. The remaining levers would be a patch guarding those targets, or narrowing -Wl,--exclude-libs,ALL to the main executable -- but that flag is load-bearing (it prevents a jsoncpp startup segfault) and must not simply be dropped. * Fri May 22 2026 Morgan Hough - 4.6.0~alpha0-1.20260513gitb107ab0 - New package: a local, co-installable snapshot of the ITK-SNAP master branch (4.6.0-alpha.0, commit b107ab0, 2026-05-13). ITK-SNAP publishes no source release and no git tag for stable 4.4.0, so master is the closest buildable source newer than v4.4.0-beta2. - Entry points suffixed -alpha (itksnap-alpha, itksnap-wt-alpha); the GUI binary stays in the version-specific /usr/lib/snap-4.6.0-alpha.0/ dir, so this package installs alongside the stable "itksnap" package. - GUI only: the bundled Convert3D/Greedy CLI tools are dropped (not newer than the stable itksnap or standalone c3d/greedy packages, and would collide with them). - Includes the -Wl,--exclude-libs,ALL jsoncpp startup-segfault fix and a desktop entry + icon.