Found by:claude-jitfields-to-fastfields, while adding -Wl,--no-undefined in #87.
#87 made the hub link strict and verified it with ldd -r, but that gate only runs on the CUDA path. Two holes remain, and the second is the serious one.
1. The CPU-side --no-undefined has no gate
build-cuda links libfastfields.so against libfastfields-cuda.so, so a CUDA-triggering change is checked. A hub-only change never links libfastfields.so in CI at all, so the strict-link guarantee on the CPU path is asserted by the Makefile and verified by nothing.
2. make / make lib is built by no CI job whatsoever
This is the wider problem. The default target — the one fastfields-dlpack's setup.py actually invokes — is not built anywhere in CI:
Nothing exercises a plain make producing libfastfields.so + libfastfields-cpu.so in the default configuration. That is precisely the configuration every downstream consumer builds, and it is how the .DEFAULT_GOAL regression during the consolidation reached fastfields-dlpack — a bare make created build/ and exited 0 having compiled nothing, surfacing downstream as a misleading "did not produce the expected .so files".
Why this is not a drive-by fix
Folding a CPU hub link into test-hub means giving a job that currently finishes in ~10 seconds a full CPU library build. libfastfields-cpu.so is ~166 MB and its build is not cheap. It would also put test-hub back on apt, which matters: test-hub survived the 2026-08-19 Ubuntu mirror stall precisely because it installs nothing, while four other jobs were killed at their timeout-minutes inside apt-get (see #89's related discussion — GitHub reports such kills as cancelled, not failure).
So this is a deliberate sizing decision, not a one-line addition. Options worth weighing:
- A separate
build-default job that runs a bare make and ldd -rs the result — closest to what downstream does, but adds a full CPU build to every run. - Path-filter it so it only runs when
src/lib/, make/ or the Makefiles change. - Reuse an existing
test-cpu leg's artifacts rather than rebuilding.
Acceptance
Whatever shape it takes, it should fail if:
libfastfields.so has undefined symbols on the CPU-only path, and- a bare
make produces no .so (the .DEFAULT_GOAL class of regression).
Related
Found by:
claude-jitfields-to-fastfields, while adding-Wl,--no-undefinedin #87.#87 made the hub link strict and verified it with
ldd -r, but that gate only runs on the CUDA path. Two holes remain, and the second is the serious one.1. The CPU-side
--no-undefinedhas no gatebuild-cudalinkslibfastfields.soagainstlibfastfields-cuda.so, so a CUDA-triggering change is checked. A hub-only change never linkslibfastfields.soin CI at all, so the strict-link guarantee on the CPU path is asserted by the Makefile and verified by nothing.2.
make/make libis built by no CI job whatsoeverThis is the wider problem. The default target — the one
fastfields-dlpack'ssetup.pyactually invokes — is not built anywhere in CI:test-cpubuilds and runs the CPU test binaries.test-hubbuilds the header-only hub argument-validation tests. It is deliberately seconds-long and apt-free.build-cudabuildslibfastfields-cuda.soand, since fix(cuda): compile posdef/resize/restrict/splinc, and make the hub link strict #87, links the hub with CUDA.Nothing exercises a plain
makeproducinglibfastfields.so+libfastfields-cpu.soin the default configuration. That is precisely the configuration every downstream consumer builds, and it is how the.DEFAULT_GOALregression during the consolidation reachedfastfields-dlpack— a baremakecreatedbuild/and exited 0 having compiled nothing, surfacing downstream as a misleading "did not produce the expected .so files".Why this is not a drive-by fix
Folding a CPU hub link into
test-hubmeans giving a job that currently finishes in ~10 seconds a full CPU library build.libfastfields-cpu.sois ~166 MB and its build is not cheap. It would also puttest-hubback onapt, which matters:test-hubsurvived the 2026-08-19 Ubuntu mirror stall precisely because it installs nothing, while four other jobs were killed at theirtimeout-minutesinsideapt-get(see #89's related discussion — GitHub reports such kills ascancelled, notfailure).So this is a deliberate sizing decision, not a one-line addition. Options worth weighing:
build-defaultjob that runs a baremakeandldd -rs the result — closest to what downstream does, but adds a full CPU build to every run.src/lib/,make/or the Makefiles change.test-cpuleg's artifacts rather than rebuilding.Acceptance
Whatever shape it takes, it should fail if:
libfastfields.sohas undefined symbols on the CPU-only path, andmakeproduces no.so(the.DEFAULT_GOALclass of regression).Related
-Wl,--no-undefinedand theldd -rcheck on the CUDA path.clang-formatjob cannot print its findings; same theme of a check that reports nothing useful.