Make direct-linking opt-in, not a release default

Release builds can legitimately want runtime dynamism (redefinition, eval,
load-string), so closed-world direct-linking shouldn't be forced on them. Gate it
behind an explicit --direct-link flag (or deps.edn :jolt/build {:direct-link
true}); off by default in every mode, including release and --opt.

build-binary takes an explicit direct-link? arg instead of deriving it from the
mode. build-smoke now covers the --direct-link path and asserts the cross-ns call
actually lowers to a jv$ binding; default release stays dynamically linked.
This commit is contained in:
Yogthos 2026-06-23 16:02:18 -04:00
parent c908e996c3
commit 2c18fcdc61
4 changed files with 50 additions and 23 deletions

View file

@ -63,4 +63,19 @@ if [ "$got_opt" != "$want" ]; then
echo "--- got ----"; echo "$got_opt"
exit 1
fi
echo "build smoke: passed (release + optimized)"
# Closed-world direct-linking (opt-in): same result, and the cross-namespace call
# (app.core -> app.util/shout) must lower to a direct jv$ binding, not var-deref.
if ! JOLT_PWD="$app" bin/joltc build -m app.core -o "$out" --direct-link >/dev/null 2>&1; then
echo " FAIL: jolt build --direct-link exited non-zero"; exit 1
fi
got_dl="$(cd / && "$out" alpha bb ccc 2>&1)"
if [ "$got_dl" != "$want" ]; then
echo " FAIL: --direct-link binary output mismatch"
echo "--- got ----"; echo "$got_dl"
exit 1
fi
if ! grep -q '(jv\$app.util\$shout' "$out.build/flat.ss"; then
echo " FAIL: --direct-link did not emit a direct app->app call"; exit 1
fi
echo "build smoke: passed (release + optimized + direct-link)"