Skip to content

Add Fedora/RHEL RPM packaging support - #9366

Open
jameshickman wants to merge 5 commits into
IfcOpenShell:v0.9.0from
jameshickman:fedora-rpm-packaging-v090
Open

Add Fedora/RHEL RPM packaging support#9366
jameshickman wants to merge 5 commits into
IfcOpenShell:v0.9.0from
jameshickman:fedora-rpm-packaging-v090

Conversation

@jameshickman

Copy link
Copy Markdown

Summary

Adds Fedora/RHEL RPM packaging, alongside the existing Debian/TGZ CPack setup. The goal is that dnf install of the produced RPM yields a working, importable ifcopenshell Python module with correct distro dependencies.

What's in here

  • cmake/CMakeLists.txt — enables the CPack RPM generator and adds a CPACK_RPM_* metadata block mirroring the existing Debian one. The generator is appended only when rpmbuild is found, so DEB-only hosts (the existing Debian CI) are unaffected by make package. EXTRA_VERSION is folded into the RPM release field, since RPM versions may not contain hyphens.
  • src/ifcwrap/CMakeLists.txt — the BUILD_PACKAGE path hard-coded a Debian dist-packages layout, which is not on Fedora/RHEL's default sys.path. Adds a PACKAGE_PYTHON_SUBDIR override, 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 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 deps and maps them to the right subpackages. So CPACK_RPM_PACKAGE_REQUIRES is now only what AUTOREQ cannot 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 — per src/ifcopenshell-python/pyproject.toml). Happy to adjust if you'd rather pin these differently.

HDF5 linkage. FindHDF5.cmake resolves to static .a names when HDF5_LIBRARY_DIR is set, but Fedora's hdf5-devel ships only shared libraries (static archives live in the separate hdf5-static package). The Fedora script leaves that flag unset so the finder falls through to CMake's HDF5 module via h5c++ 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 needing PYTHONPATH.

One caveat, stated plainly: that verification was performed with these commits based on v0.8.0. They have been rebased onto v0.9.0 here, with two small conflicts resolved (a .gitignore entry, and CMake keyword casing around the BUILD_PACKAGE block). 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 of v0.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.0 isn't where you'd want packaging changes to land.

James Hickman and others added 5 commits August 27, 2026 10:27
- 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>
@aothms

aothms commented Aug 28, 2026

Copy link
Copy Markdown
Member

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.

@brunopostle

Copy link
Copy Markdown
Contributor

@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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants