Embed runtime source so a self-contained joltc can build apps
`joltc build` inlines the runtime (host/chez/rt.ss and everything it loads, the seed, compile-eval, loader, ffi, the vendored irregex) into each app binary by reading those files off disk. That works from a jolt checkout but not from the installed self-contained binary, which has no source tree: joltc build -m app.core => Exception in call-with-input-file: failed for host/chez/rt.ss: no such file build-joltc now bakes the exact transitive closure of files the build inlines into the binary as embedded resources (keyed by the path the `(load "…")` forms use), and build.ss/dce.ss read runtime source through bld-source-string, which takes the embedded copy when present and falls back to disk otherwise. So the same joltc builds apps both from a checkout and standalone. The release workflow now smoke-tests a self-contained build (compile a tiny app from an isolated dir, run it) — this is exactly what shipped broken, so it now gates the release. buildsmoke/shakesmoke/staticnativesmoke unchanged and green. Build tooling only — no re-mint, no runtime change.
This commit is contained in:
parent
f6bd2c6de5
commit
db08ecc1bc
4 changed files with 65 additions and 7 deletions
|
|
@ -80,6 +80,32 @@
|
|||
(bld-walk-files root "" '())))
|
||||
(list "jolt-core" "stdlib")))
|
||||
|
||||
;; Embed every runtime .ss the build inlines into an app (the transitive closure of
|
||||
;; the manifest's loads: rt.ss + all it loads, the seed, compile-eval, loader, ffi,
|
||||
;; png, vendored irregex). Keyed by the exact path the (load "…") forms use, so
|
||||
;; build.ss's bld-source-string reads them from the binary with no jolt source on
|
||||
;; disk. Traversal mirrors bld-emit-runtime/bld-inline-line via the same
|
||||
;; bld-file-lines + bld-load-path, so the embedded set is exactly what build reads.
|
||||
(define (jb-collect-load-paths)
|
||||
(let ((seen (make-hashtable string-hash string=?)) (order '()))
|
||||
(define (walk path)
|
||||
(when (and path (not (hashtable-ref seen path #f)))
|
||||
(hashtable-set! seen path #t)
|
||||
(set! order (cons path order))
|
||||
(for-each (lambda (l) (walk (bld-load-path l))) (bld-file-lines path))))
|
||||
(for-each (lambda (entry) (when (string? entry) (walk (bld-load-path entry))))
|
||||
bld-runtime-manifest)
|
||||
(for-each (lambda (kv) (walk (bld-load-path (cdr kv)))) bld-tagged-loads)
|
||||
(reverse order)))
|
||||
|
||||
(define (jb-emit-runtime-embeds out)
|
||||
(for-each
|
||||
(lambda (path)
|
||||
(put-string out (string-append
|
||||
"(register-embedded-resource! " (ei-str-lit path) " "
|
||||
(ei-str-lit (read-file-string path)) ")\n")))
|
||||
(jb-collect-load-paths)))
|
||||
|
||||
;; The launcher (Chez scheme-start): replicates host/chez/cli.ss but reads argv
|
||||
;; from the scheme-start lambda and has no repo root to cd into (all source is
|
||||
;; embedded; JOLT_PWD defaults to cwd via io/jolt.main). build.ss is already
|
||||
|
|
@ -134,6 +160,8 @@
|
|||
(bld-emit-runtime out #f #f)
|
||||
(put-string out "\n;; === build driver (inlined for self-contained `jolt build`) ===\n")
|
||||
(bld-inline-line "(load \"host/chez/build.ss\")" out 0)
|
||||
(put-string out "\n;; === embedded runtime source (self-contained `build` reads these) ===\n")
|
||||
(jb-emit-runtime-embeds out)
|
||||
(put-string out "\n;; === embedded jolt-core + stdlib source ===\n")
|
||||
(jb-emit-source-embeds out)
|
||||
(put-string out "\n;; === joltc launcher ===\n")
|
||||
|
|
|
|||
|
|
@ -141,12 +141,23 @@
|
|||
(q2 (let scan ((i (+ q1 1))) (if (char=? (string-ref s i) #\") i (scan (+ i 1))))))
|
||||
(substring s (+ q1 1) q2)))))
|
||||
|
||||
(define (bld-file-lines path)
|
||||
(call-with-input-file path
|
||||
(lambda (p)
|
||||
(let loop ((acc '()))
|
||||
(let ((l (get-line p)))
|
||||
(if (eof-object? l) (reverse acc) (loop (cons l acc))))))))
|
||||
;; runtime source for PATH: from the binary's embedded store if present (a
|
||||
;; self-contained joltc building an app, with no jolt checkout on disk), else read
|
||||
;; from disk (running from a source checkout). build-joltc embeds every runtime
|
||||
;; .ss the manifest inlines, so `build` never touches the filesystem for them.
|
||||
(define (bld-source-string path)
|
||||
(let ((emb (hashtable-ref embedded-resources path #f)))
|
||||
(if (string? emb) emb (read-file-string path))))
|
||||
|
||||
(define (bld-string-lines s)
|
||||
(let ((n (string-length s)))
|
||||
(let loop ((i 0) (start 0) (acc '()))
|
||||
(cond ((>= i n) (reverse (if (> i start) (cons (substring s start i) acc) acc)))
|
||||
((char=? (string-ref s i) #\newline)
|
||||
(loop (+ i 1) (+ i 1) (cons (substring s start i) acc)))
|
||||
(else (loop (+ i 1) start acc))))))
|
||||
|
||||
(define (bld-file-lines path) (bld-string-lines (bld-source-string path)))
|
||||
|
||||
;; Emit one line to OUT, recursively inlining a `(load ...)` of a repo file.
|
||||
(define (bld-inline-line line out depth)
|
||||
|
|
|
|||
|
|
@ -90,7 +90,10 @@
|
|||
;; str re-serializes the read form (compiled identically; comments/whitespace are
|
||||
;; irrelevant).
|
||||
(define (dce-blob-records path)
|
||||
(call-with-input-file path
|
||||
;; bld-source-string (build.ss) reads the embedded copy when running from a
|
||||
;; self-contained joltc, else the file on disk — so tree-shake works with no
|
||||
;; jolt checkout present. Forward ref: build.ss loads after this file.
|
||||
(call-with-port (open-input-string (bld-source-string path))
|
||||
(lambda (p)
|
||||
(let loop ((acc '()))
|
||||
(let ((form (read p)))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue