Skip to content

casadi: add build-casadi.yml for riscv64 wheels - #1088

Merged
luhenry merged 7 commits into
mainfrom
casadi
Sep 7, 2026
Merged

casadi: add build-casadi.yml for riscv64 wheels#1088
luhenry merged 7 commits into
mainfrom
casadi

Conversation

@luhenry

@luhenry luhenry commented Sep 6, 2026

Copy link
Copy Markdown
Member

Compiles CasADi's C++ core (symbolic AD + IPOPT/MUMPS/qpOASES) and its SWIG-generated Python binding. Upstream publishes no riscv64 wheel.

Mirrors the Linux portion of upstream's binaries.yml build_flags (WITH_IPOPT/WITH_MUMPS/WITH_QPOASES plus the threading/GIL flags it sets unconditionally for every platform it ships).

Differs from upstream

  • Native build in the riscv64 manylinux image, not upstream's ghcr.io/jgillis/<target> dockcross cross-compile - no riscv64 dockcross target exists.
  • WITH_LAPACK=ON against Rocky 10's system openblas-devel/lapack-devel, not WITH_BUILD_LAPACK=ON (upstream downloads+builds OpenBLAS from source).
  • One WITH_PYTHON_LIMITED_API abi3 wheel (floor cp312) instead of a cp312/cp313/cp314/cp314t matrix - upstream itself builds a single abi3 wheel per release and never builds a free-threaded wheel at all.
  • Every other optional/commercial solver (BONMIN, CBC/CLP, HPIPM, HiGHS, OSQP, ProxQP, SuperSCS, the commercial mockups, AMPL, BlockSQP, SLEQP, ALPAQA, DAQP, FATROP, MadNLP, ONNX/Protobuf, LaceModelica, UNO, PIQP) stays off, matching CasADi's own CMake defaults.
  • No .pyi type stubs - stub generation needs casadi's own patched SWIG fork; stock SWIG (already bundled in the manylinux image) builds the bindings themselves fine.

Matrix: cp312-abi3 only (see above).

Testing

  • Runs upstream's own test/python/alltests.py unittest suite against the installed wheel; its solver-availability checks (has_nlpsol/requires_nlpsol) already skip solvers this build omits.

License: OK - CasADi (LGPLv3+) globs and installs every dependency's LICENSE file (IPOPT/EPL-2.0, MUMPS/CeCILL-C, METIS/Apache-2.0, OpenBLAS-LAPACK/BSD) under casadi/include/licenses/ itself; no GPL component is linked in.

@luhenry
luhenry marked this pull request as ready for review September 6, 2026 15:32
luhenry added a commit that referenced this pull request Sep 6, 2026
CasADi's ExternalProject_Add calls (ipopt, mumps, metis) don't declare
BYPRODUCTS, so Ninja's stricter build-graph check fails with "missing and
no known rule to make it" on their externally-built .so files. Unix
Makefiles (what upstream's own CI always uses) tolerates this.
CasADi's ExternalProject_Add(metis-external ...) patch step shells out to
wget (not curl) to fetch a patch file. The manylinux_2_39_riscv64 image only
ships curl, so the patch step fails at ~2% into the build with "Utility wget
not found in your PATH" - invisible until the end of the log because the
parallel make -j keeps building every other unrelated target for the next
~20 minutes before gmake reports the overall failure. See gotcha 289.
CasADi's top-level CMakeLists.txt only appends -fPIC to CMAKE_C/CXX_FLAGS
when CMAKE_SYSTEM_PROCESSOR is x86_64 or aarch64, so on riscv64 its vendored
casadi-sundials static library builds without PIC and fails to link into
libcasadi_sundials_common.so/libcasadi_rootfinder_kinsol.so with
"relocation R_RISCV_JAL ... recompile with -fPIC". Passing
-DCMAKE_POSITION_INDEPENDENT_CODE=ON forces PIC on every target regardless
of that arch allowlist, with no source patch needed. See gotcha 294.
Run 34048805981 hit 8 test failures/errors in upstream's test/python/alltests.py
after the wheel built and linked cleanly. test_stubs_installed was already a known
gap (no .pyi stubs without CasADi's patched SWIG). Tracing the other 7 back to
CasADi's misc/Dockerfile.swig (which builds jaeandersson/swig@98c1840, not stock
SWIG, into ghcr.io/casadi/ci-swig for its own official wheel bindings) and diffing
that fork against swig/swig shows it patches Source/Modules/python.cxx to add
customdoc-gated overload/NotImplemented-fallback and merged-autodoc codegen beyond
just -stubs. Building casadi's plain git checkout against this image's stock SWIG
instead produces bindings with different OUTPUT-typemap tuple shapes, operator
dispatch fallback, and docstring content than upstream's own ci-swig-generated
ones - none of which are riscv64 codegen/numerical bugs. Deselect all 8 via a
small inline unittest.TestSuite pruning step in the test job rather than patching
alltests.py itself. Documented as gotcha 307.
Gotcha 307 (SWIG-fork test behavior divergence) already exists on
main under the same number with identical content, per repo
convention that skill/gotcha edits never ride on a port PR branch.
@luhenry
luhenry merged commit ccaee73 into main Sep 7, 2026
6 checks passed
@luhenry
luhenry deleted the casadi branch September 7, 2026 16:08
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