Skip to content

koga: depend the generated lisp-info on libclasp, not just iclasp - #1829

Closed
dg1sbg wants to merge 1 commit into
clasp-developers:mainfrom
dg1sbg:fix/generate-lisp-info-deps
Closed

koga: depend the generated lisp-info on libclasp, not just iclasp#1829
dg1sbg wants to merge 1 commit into
clasp-developers:mainfrom
dg1sbg:fix/generate-lisp-info-deps

Conversation

@dg1sbg

@dg1sbg dg1sbg commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

The generated lisp-info files never regenerate when the Lisp or C++ content changes, so a build can silently use package, symbol and class data belonging to a different tree state.

The broken chain

build …/generated/features.sexp …/runtime-packages.lisp …/cxx-classes.lisp …:
    generate-lisp-info | boehmprecise/iclasp             <- implicit dep: iclasp only

build boehmprecise/iclasp: link …/main.o || boehmprecise/lib/libclasp.so
                                                         <- ORDER-ONLY dep (||)

generate-lisp-info runs iclasp, which loads libclasp.so at runtime via rpath and dumps the packages, functions, variables, classes and type map it finds there. Its output therefore depends on libclasp.so's contents. But the only path from the generator to that library runs through iclasp, which depends on it order-only — in ninja that means "build it first if missing, but changes to it do not make me dirty". And iclasp is just main.o plus a link, so it rarely changes on its own.

The declaration of iclasp as an implicit input shows the dependency was intended; it just names the wrong artifact. All the content the generator reads lives in the library, not in the executable.

Reproduction, before the fix

generated stamp: 2026-08-03 23:42:47
libclasp.so:     2026-08-04 00:05:50        <- newer
$ touch build/boehmprecise/lib/libclasp.so && ninja -C build
ninja rc=0   generated stamp: 2026-08-03 23:42:47    <- unchanged
$ ninja -C build -n boehmprecise/generated/runtime-packages.lisp
ninja: no work to do.

Worse in practice: walking a single build tree through eight branches in sequence, rebuilding at each, left the generated files at their original timestamp and byte sizes the whole way — including across a branch that adds new C++ sources and therefore new scraped symbols. Eight images, each built from another branch's lisp-info, with nothing to indicate it.

The change

lib-filename already returns .a under --static-linking, so a single call is correct for both linkage modes.

Verification, x86-64 Linux / LLVM 18

edge now reads: generate-lisp-info | boehmprecise/iclasp boehmprecise/lib/libclasp.so
$ touch build/boehmprecise/lib/libclasp.so
ninja sees generator dirty?  YES
generated stamp before: 2026-08-04 00:21:25
generated stamp after:  2026-08-04 00:25:23     <- regenerated

Full build and regression suite unaffected.

Relationship to #1823 / #1826

Separate bugs, similar damage, and they interact: #1823 is the generator leaving a stale tail when it runs; this is the generator not running when it should. Fixing #1823 alone is insufficient, since the regeneration that would apply that fix never happens.

generate-lisp-info runs iclasp, which loads libclasp at runtime via
rpath and dumps the packages, functions, variables, classes and type
map it finds there.  Its output therefore depends on libclasp's
contents.  The edge declared only iclasp as an implicit input, and
iclasp depends on libclasp order-only -- in ninja that means "build it
first if missing, but changes to it do not make me dirty".  Since
iclasp is just main.o plus a link, it rarely changes on its own, so
editing any Lisp or C++ source never refreshed the generated files.

Before this change, touching libclasp.so and rebuilding left the
generated files untouched and ninja reported "no work to do".  Walking
one build tree through eight branches in sequence left them at their
original timestamp and byte sizes throughout, including across a branch
that adds C++ sources and therefore new scraped symbols -- eight images
built from another branch's lisp-info, with nothing to indicate it.

Naming libclasp as an implicit input restores the dependency.
lib-filename already returns the static archive under --static-linking,
so one call covers both linkage modes.

Verified on x86-64 Linux: the edge now lists libclasp.so, touching it
marks the generator dirty, the files regenerate, and the regression
suite is unchanged at 1963.
@dg1sbg

dg1sbg commented Aug 4, 2026

Copy link
Copy Markdown
Contributor Author

CI summary: all three macOS jobs pass; all three Linux jobs failed on known pre-existing flakes. Every one of them built successfully — the failures are in test steps, not compilation.

job step result
clasp/ubuntu bytecode regression Successes: 1962, sole failure WEAK-KEY-AND-VALUE-WEAKNESS (#1814)
cando/ubuntu native regression Successes: 1962, sole failure WEAK-KEY-AND-VALUE-WEAKNESS (#1814)
clasp/ubuntu native ANSI regression suite passed at 1963 = baseline; ANSI gave 28 failures with 1 unexpected, that one being PRINT.DOUBLE-FLOAT.RANDOM (#1816)

The checks that matter for this change specifically: no test loss anywhere (1962 is baseline minus the single flaky test; 1963 is baseline exactly), zero CMPLTV::%INDEX errors, and 2 aborted compilation units on both regression jobs, which is the normal count. If making the generator run more often were corrupting generated files, those are the numbers that would move, and they did not.

A correction to my note on #1826

I said there that this PR "makes the generator run constantly, so every run is an opportunity for the truncation bug in #1826 to corrupt a file" and that #1826 should therefore land first. That is right for a reused build tree — local development, a CI cache, git bisect — where a longer file from a previous state is already sitting on disk for the new shorter output to be written over.

It is not a risk for CI as configured here, which builds from scratch in a fresh runner, so there is no pre-existing longer file to leave a tail. That is consistent with what these runs show: three clean builds and no sign of generated-file corruption.

So the ordering preference stands for the benefit of everyone reusing a tree, but it is not a blocker for merging this on CI evidence, and I should have drawn that distinction the first time.

@dg1sbg

dg1sbg commented Aug 4, 2026

Copy link
Copy Markdown
Contributor Author

Superseded by #1826, which now carries both this change and the :supersede+close truncation fix.

They are opposite halves of the same failure and have to land together: today the truncation bug is rare because the generator seldom runs, so fixing this dependency alone would make it fire constantly, while fixing the truncation alone leaves the generated files stale. Combining them at review request.

The commit here is preserved unchanged in #1826 (Depend the generated lisp-info on libclasp, not just on iclasp), ordered after the truncation fix. Issue #1828 remains open and is referenced from #1826.

@dg1sbg dg1sbg closed this Aug 4, 2026
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