Skip to content

gtsam: Add version 4.3.0 - #3261

Draft
luhenry wants to merge 14 commits into
mainfrom
gtsam
Draft

luhenry wants to merge 14 commits into
mainfrom
gtsam

Conversation

@luhenry

@luhenry luhenry commented Oct 15, 2026 •

Copy link
Copy Markdown
Member

Compiles GTSAM's C++ core (factor graphs, Eigen/CCOLAMD/SuiteSparse_config/METIS/Spectra/cephes vendored under gtsam/3rdparty) and its pybind11 bindings into one wheel per interpreter. Upstream publishes no riscv64 wheel.

Mirrors upstream's prod-cibw.yml and cibw_before_all.sh.

Differs from upstream

  • Boost comes from dnf (1.83) instead of a from-source 1.87 build - above GTSAM's 1.70 floor, saves most of the build time.
  • libgtsam/libgtsam_unstable build once and are reused across cp311-cp314, instead of the whole ~1450-file core rebuilding per interpreter.
  • GTSAM_BUILD_WITH_WERROR is not set - it isn't actually part of upstream's own wheel recipe either.

Matrix: cp311-cp314, not the default cp312/cp313/cp314/cp314t - matches upstream's own PyPI wheels, which don't build cp314t.

Testing

  • Runs the full python/gtsam and python/gtsam_unstable pytest suites (~116 files) rather than upstream's wheel-test import gtsam smoke check alone.

License: Wheel bundles CCOLAMD/SuiteSparse_config (BSD-3), METIS (Apache-2.0), cephes (MIT), Eigen (MPL2) and pybind11 (BSD-3) alongside GTSAM's own BSD-3; upstream ships no licence text for any of them, so the build adds it.

Patches

  • 0001-python-ship-the-vendored-licences-in-the-wheel.patch - To upstream, not yet submitted. Without it the wheel carries no licence text at all; reproduces on x86/aarch64 too, not riscv64-only.

Draft: first CI run in progress, a multi-hour heavy C++ build.

Mirrors prod-cibw.yml/cibw_before_all.sh at the 4.3.0 tag: host-side CMake
generates build/python, then the wrapper module is built per interpreter.
Boost comes from dnf (1.83, above GTSAM's 1.70 floor) instead of building
1.87 from source, and libgtsam/libgtsam_unstable's ~1450 translation units
are built once and reused across cp311-cp314 (gotcha 15's shape) instead of
rebuilding them per interpreter the way CIBW_BEFORE_ALL does upstream.

GTSAM_BUILD_WITH_WERROR is not actually part of upstream's wheel recipe, so
it is left unset. FindMKL/FindMOSEK have no riscv64-specific code and are
expected to resolve to "not found", matching upstream's own Linux wheels
(MKL and MOSEK are both optional).

Includes a patch to ship GTSAM's own BSD-3 licence and the vendored
CCOLAMD/SuiteSparse_config (BSD-3), METIS (Apache-2.0), cephes (MIT), Eigen
(MPL2) and pybind11 (BSD-3) licences in the wheel, none of which the
upstream-published wheel currently carries.
GTSAM_BUILD_WITH_WERROR defaults ON for a standalone GTSAM build, and
upstream's own cibw recipe never overrides it either - it just never bites
them because their CI compilers are covered by Gal3.cpp's own GCC 15/16
-Wmaybe-uninitialized workaround. manylinux_2_39_riscv64 is Rocky 10 (GCC 14),
which that guard doesn't cover, so the same upstream-acknowledged false
positive turns into a hard build failure here.
…nfigure

The per-interpreter loop reconfigures into the same build dir; FindPython3's
cached include/library/SOABI entries from the previous interpreter survive
the reconfigure even though -DPYTHON_EXECUTABLE= is honored, so the pybind11
extension module keeps getting built (and named) one interpreter behind.
cp311's run built gtsam.cpython-312-riscv64-linux-gnu.so (left over from the
earlier cp312-only library configure), so pybind11_stubgen's import gtsam
hit a circular-import-looking ImportError against the mismatched module.
-U clears just the stale Python cache entries, forcing re-detection each
iteration without rm -rf'ing the whole build dir (which would also discard
the already-built gtsam/gtsam_unstable libraries).
WRAP_PYTHON_VERSION and FindPython's internal _Python_* cache survived the per-interpreter reconfigure, so the cp311 pybind11 module was still built with the cpython-312 suffix while pybind11_stubgen ran under 3.11 and failed to import it.
test_LandmarkLocalizationDataset.py::test_committed_datasets_are_reproducible
resolves its committed g2o fixtures via Path(__file__).parents[3] /
"examples" / "Data", which assumes the checkout's python/<pkg>/tests
depth. Flattening the staged copy to /tmp/gtsam-tests (added to dodge
the gtsam_unstable/tests rootdir-shadowing issue, gotcha 25) left too
few ancestors, so parents[3] raised IndexError instead of finding the
fixture.

Nest the staged tests back under a python/gtsam(_unstable) prefix with
no __init__.py of their own - restoring the original depth without
reintroducing any real package there to shadow the installed wheel -
and copy examples/ alongside so the fixture lookup succeeds.

This branch has not been deployed

No deployments
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.

1 participant