Add Fedora/RHEL RPM packaging support - #9366
Conversation
- cmake: enable CPack RPM generator (guarded by rpmbuild availability so DEB-only hosts still work) with a CPACK_RPM_* metadata block mirroring the existing Debian config; fold EXTRA_VERSION into the RPM release field since RPM versions may not contain hyphens. - fedora/build-rpm.sh: build script resolving Fedora paths and deps, producing an .rpm via `make package`. - fedora/readme.md: usage and dependency documentation. - CI: build_fedora_rpm.yml builds the RPM in a fedora container. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
FindHDF5.cmake resolves to static .a library names when HDF5_LIBRARY_DIR is set, but Fedora's hdf5-devel ships only shared libraries (the static archives are in the separate hdf5-static package). Dropping the flag lets the finder fall through to CMake's HDF5 module (via h5c++), which locates the shared libs -- matching how the Debian Docker CI configures HDF5. Verified end-to-end on Fedora 43: produces a valid IfcOpenShell RPM with correctly auto-detected OCCT/Boost/HDF5/libxml2 dependencies. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
When BUILD_PACKAGE is set, ifcwrap hard-coded a Debian dist-packages layout, which is not on Fedora/RHEL's default sys.path, so the packaged ifcopenshell module could not be imported without PYTHONPATH. Add a PACKAGE_PYTHON_SUBDIR override (relative, defaulting to the existing Debian path so the Debian package is unchanged) and have the Fedora build script pass lib64/pythonX.Y/site-packages. Verified: the RPM now installs to /usr/lib64/python3.14/site-packages and imports without PYTHONPATH. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The explicit "opencascade" Requires does not exist as a package on Fedora (OCCT ships as opencascade-foundation/-modeling/-visualization/-ocaf), so dnf failed with "nothing provides opencascade". The other high-level names (libxml2, hdf5, boost) were redundant with RPM's soname dependency generator, which already records the exact libTK*.so / libboost*.so / libhdf5*.so / libxml2.so dependencies and maps them to the correct distro subpackages. Reduce CPACK_RPM_PACKAGE_REQUIRES to just python3 (the interpreter is not linked as a shared library, so it cannot be auto-detected) and let AUTOREQ handle everything else. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The ifcopenshell Python module imports shapely, numpy, isodate, python-dateutil, lark, pyparsing and typing-extensions (see src/ifcopenshell-python/pyproject.toml). Without them `import ifcopenshell.util.*` fails on a clean system with ModuleNotFoundError. Add them to CPACK_RPM_PACKAGE_REQUIRES using Fedora's python3-* package names (all available in the standard repositories) so a plain `dnf install` of the RPM yields a fully importable Python package. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Many thanks. We also have this https://copr.fedorainfracloud.org/coprs/bpostle/IfcOpenShell/ Let's see if @brunopostle is available to weigh in on what to do here. We also have this (which we dont trigger as often as we should) but which would give us the .DEB https://github.com/IfcOpenShell/IfcOpenShell/blob/v0.9.0/.github/workflows/release.yml I think ideally your approach is merged with the release.yml using a build matrix and a similar structure where possible. It would be nice if - as a community - we form a bit of an opinion on how we want to do builds, releases, version numbers, branches. etc. We're nearing 1.0 and I think we should aim for making things a bit easier on packagers - people have frequently given up trying to understand our idiosyncrasies and complex interactions between dependencies. |
|
@jameshickman thanks, there are some things here that will make packaging easier. Ultimately I think the aim is to have IfcOpenShell as part of the distributions themselves. Some thoughts off the top of my head: It isn't just ifcopenshell, in the copr repo there are 14 other ifcopenshell python models, the bonsai add-on (which works with the system fedora blender), and the new bonsai viewer. These all need to be packaged as otherwise people will be installing them some other way and potentially causing conflicts. I don't think that users will be well served by a simple rpm download, fedora packages should be able to auto-update via dnf/yum, this means creating a repository (not impossible) or using the fedora copr infrastructure. The ifcopenshell modules depend on some packages that are not provided by fedora (pystache cjio xsdata bpypolyskel wgpu), so these need to be provided in parallel (or somebody needs to persuade a fedora packager to maintain them in fedora, not practical for wgpu), this basically mandates the dnf repo approach. As a result, the current IfcOpenShell.spec file is quite elaborate: https://download.copr.fedorainfracloud.org/results/bpostle/IfcOpenShell/fedora-44-x86_64/10915046-IfcOpenShell/IfcOpenShell.spec I should automate the copr builds to create nightlies, but haven't got around to this yet. |
Summary
Adds Fedora/RHEL RPM packaging, alongside the existing Debian/TGZ CPack setup. The goal is that
dnf installof the produced RPM yields a working, importableifcopenshellPython module with correct distro dependencies.What's in here
cmake/CMakeLists.txt— enables the CPackRPMgenerator and adds aCPACK_RPM_*metadata block mirroring the existing Debian one. The generator is appended only whenrpmbuildis found, so DEB-only hosts (the existing Debian CI) are unaffected bymake package.EXTRA_VERSIONis folded into the RPM release field, since RPM versions may not contain hyphens.src/ifcwrap/CMakeLists.txt— theBUILD_PACKAGEpath hard-coded a Debiandist-packageslayout, which is not on Fedora/RHEL's defaultsys.path. Adds aPACKAGE_PYTHON_SUBDIRoverride, defaulting to the exact existing Debian value, so the Debian package is byte-for-byte unchanged.fedora/build-rpm.sh,fedora/readme.md— build script and dependency/usage docs..github/workflows/build_fedora_rpm.yml— builds the RPM in a Fedora container.Two things worth reviewing
Dependency handling. An earlier iteration hard-coded
Requires: opencascade, which does not exist as a package on Fedora — OCCT ships split asopencascade-foundation/-modeling/-visualization/-ocaf— sodnffailed with nothing provides opencascade. The other high-level names (libxml2, hdf5, boost) were redundant with RPM's soname dependency generator, which already records the exactlibTK*.so/libboost*.so/libhdf5*.so/libxml2.sodeps and maps them to the right subpackages. SoCPACK_RPM_PACKAGE_REQUIRESis now only whatAUTOREQcannot infer: the Python interpreter (not linked as a shared library) and the module's third-party Python imports (shapely, numpy, isodate, python-dateutil, lark, pyparsing, typing-extensions — persrc/ifcopenshell-python/pyproject.toml). Happy to adjust if you'd rather pin these differently.HDF5 linkage.
FindHDF5.cmakeresolves to static.anames whenHDF5_LIBRARY_DIRis set, but Fedora'shdf5-develships only shared libraries (static archives live in the separatehdf5-staticpackage). The Fedora script leaves that flag unset so the finder falls through to CMake's HDF5 module viah5c++and locates the shared libs — matching how the Debian Docker CI already configures HDF5.Testing
Verified end-to-end on Fedora 43: the build produces a valid RPM that installs cleanly, resolves OCCT/Boost/HDF5/libxml2 automatically, installs to
/usr/lib64/python3.14/site-packages, and imports without needingPYTHONPATH.One caveat, stated plainly: that verification was performed with these commits based on
v0.8.0. They have been rebased ontov0.9.0here, with two small conflicts resolved (a.gitignoreentry, and CMake keyword casing around theBUILD_PACKAGEblock). The resulting net diff is identical in content to the verified version, but I have not re-run a full end-to-end Fedora build on top ofv0.9.0— the included CI workflow should confirm it, and I'm glad to chase down anything it turns up.Also happy to retarget this at a different branch if
v0.9.0isn't where you'd want packaging changes to land.