From a67c52d8faad5cf001cdf570192b04168945ab2f Mon Sep 17 00:00:00 2001 From: Filip Leonarski Date: Wed, 26 Aug 2026 15:15:44 +0200 Subject: [PATCH] Package rugnux as its own rpm and deb rugnux was a component of the jfjoch-viewer package, so getting the offline analysis CLI meant installing the desktop viewer, Qt and the XDS plugin with it. It links none of the hardware libraries and talks to no service, so a machine that only processes data should be able to install it alone. It is packaged as "rugnux", not "jfjoch-rugnux": the binary, the release tarball and docs/NAMING.md all call it that, and it is what a user types. Overriding the component's package name is the only way to drop the CPACK_PACKAGE_NAME prefix. /usr/bin/rugnux moves between two packages that both continue to exist, so the declaration has to be a bound on the OLD viewer rather than an Obsoletes - obsoleting jfjoch-viewer would uninstall the viewer. rpm gets Conflicts, deb gets Breaks+Replaces so the two stay co-installable from here on. rpm rewrites "-" to "_" in a package version (an installed release reads 1.0.0_rc.160), so the bound is built with the same substitution; spelled 1.0.0-rc.164 the comparison would silently never match, which is the failure mode this kind of guard usually has. Verified by building rpms from a project mirroring these settings: the package comes out named rugnux at 1.0.0_rc.164 carrying /usr/bin/rugnux and its notices, the jfjoch package no longer carries rugnux, and "rpm -i --test" against the rc.160 viewer installed on this workstation reports the intended dependency conflict rather than a raw file collision - which is what lets dnf resolve it by upgrading the viewer in the same transaction. The deb side is checked against CPackDeb.cmake, which supports NAME, BREAKS and REPLACES per component, but no .deb was built: this host is RHEL. CI needs no change; the upload step globs *.rpm and *.deb. --- CMakeLists.txt | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a3795b3e..16c6e80c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -484,7 +484,12 @@ if (JFJOCH_RUGNUX_ONLY) elseif (JFJOCH_VIEWER_ONLY) set(CPACK_COMPONENTS_ALL viewer) else() - set(CPACK_COMPONENTS_ALL jfjoch writer) + # rugnux is packaged separately from everything else, as "rugnux" rather than "jfjoch-rugnux" + # (see the DEB/RPM branches below). It is the offline analysis CLI: it links none of the + # hardware libraries and talks to no service, so a machine that only processes data can install + # it alone. Up to 1.0.0-rc.163 it rode inside the jfjoch-viewer package, which is why both + # branches below declare the file move. + set(CPACK_COMPONENTS_ALL jfjoch writer rugnux) if (JFJOCH_INSTALL_DRIVER_SOURCE) list(APPEND CPACK_COMPONENTS_ALL driver-dkms) endif() @@ -605,6 +610,18 @@ elseif (EXISTS "/etc/debian_version") set(CPACK_DEBIAN_JFJOCH_PACKAGE_REPLACES "jfjoch-jfjoch") set(CPACK_DEBIAN_JFJOCH_PACKAGE_CONFLICTS "jfjoch-jfjoch") + # rugnux ships as plain "rugnux", not "jfjoch-rugnux": it is a separately named product (see + # docs/NAMING.md), the released tarball is called rugnux--..., and it is what a user + # types. Overriding the name is the only way to drop the CPACK_PACKAGE_NAME prefix. + set(CPACK_DEBIAN_RUGNUX_PACKAGE_NAME "rugnux") + + # /usr/bin/rugnux moved out of jfjoch-viewer into this package. Breaks+Replaces, NOT Conflicts: + # the two packages are meant to be co-installable from 1.0.0-rc.164 on, and this only has to + # stop an OLD viewer (which still owns the file) from being unpacked alongside. Without it dpkg + # refuses with "trying to overwrite '/usr/bin/rugnux', which is also in package jfjoch-viewer". + set(CPACK_DEBIAN_RUGNUX_PACKAGE_BREAKS "jfjoch-viewer (<< ${JFJOCH_VERSION})") + set(CPACK_DEBIAN_RUGNUX_PACKAGE_REPLACES "jfjoch-viewer (<< ${JFJOCH_VERSION})") + # Enable automatic shlib dependency discovery set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON) @@ -646,6 +663,22 @@ elseif (EXISTS "/etc/redhat-release") set(CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST_ADDITION /usr/src /usr/share /usr/share/dbus-1 /usr/share/dbus-1/services /usr/share/pixmaps /usr/share/applications) + # rugnux ships as plain "rugnux", not "jfjoch-rugnux" -- see the DEB branch above for why. + set(CPACK_RPM_RUGNUX_PACKAGE_NAME "rugnux") + set(CPACK_RPM_RUGNUX_PACKAGE_SUMMARY "Offline crystallographic data analysis for Jungfraujoch") + set(CPACK_RPM_RUGNUX_PACKAGE_DESCRIPTION + "rugnux processes a stored Jungfraujoch HDF5 dataset: spot finding, indexing, geometry +refinement, Bragg integration, scaling and merging. It needs none of the acquisition stack -- no +broker, no detector, no FPGA card -- so it can be installed on a machine that only processes data.") + + # /usr/bin/rugnux moved out of the jfjoch-viewer package into this one. Conflicts against the + # OLD viewer only, and deliberately NOT Obsoletes: obsoleting jfjoch-viewer would uninstall the + # viewer, which still exists and is still wanted. rpm turns "-" into "_" in a package version + # (an installed release reads 1.0.0_rc.160), so the bound has to be spelled the same way or the + # comparison silently never matches. + string(REPLACE "-" "_" _jfjoch_rpm_version "${JFJOCH_VERSION}") + set(CPACK_RPM_RUGNUX_PACKAGE_CONFLICTS "jfjoch-viewer < ${_jfjoch_rpm_version}") + # DKMS component scripts and requirements for RPM if (JFJOCH_INSTALL_DRIVER_SOURCE) set(CPACK_RPM_DRIVER-DKMS_PACKAGE_REQUIRES "dkms, gcc, bash, sed")