Compare commits

..

1 Commits

Author SHA1 Message Date
Will Anderson 9d0e1f64d4 fix elb: cp instead of mv for .elh files, preserves headers for downstream modules 2026-05-03 01:19:58 -05:00
2 changed files with 24 additions and 14 deletions
BIN
View File
Binary file not shown.
+24 -14
View File
@@ -1,4 +1,4 @@
// elb.el El Build Coordinator
// elb.el - El Build Coordinator
//
// The build system for El programs. Written in El. Builds El.
//
@@ -16,11 +16,11 @@
// 3. For each file: if .el is newer than .elh/.c, compile with elc --emit-header
// 4. Link all .c files + el_runtime.c into the final binary
//
// Each module compiles independently no 128K-line blobs.
// Each module compiles independently - no 128K-line blobs.
// Downstream compilations read .elh headers (function signatures only),
// not source. Incremental: only recompile what changed.
// Flags
// -- Flags ---------------------------------------------------------------------
fn flag_bool(argv: [String], name: String) -> Bool {
let n: Int = native_list_len(argv)
@@ -47,7 +47,7 @@ fn flag_val(argv: [String], name: String, default_val: String) -> String {
return default_val
}
// Manifest parsing
// -- Manifest parsing ----------------------------------------------------------
//
// Read the entry file from manifest.el:
// build { entry "soul.el" }
@@ -100,7 +100,7 @@ fn parse_manifest_name(src: String) -> String {
return "out"
}
// Path helpers
// -- Path helpers ---------------------------------------------------------------
fn dirname_of(path: String) -> String {
let n: Int = str_len(path)
@@ -148,14 +148,14 @@ fn file_is_newer(a: String, b: String) -> Bool {
let cmd: String = "test -f " + b + " && test " + a + " -nt " + b + " && echo yes || echo no"
let result: String = str_trim(exec_capture(cmd))
if str_eq(result, "yes") { return true }
// b doesn't exist check with test -f
// b doesn't exist - check with test -f
let exist_cmd: String = "test -f " + b + " && echo exists || echo missing"
let exist: String = str_trim(exec_capture(exist_cmd))
if str_eq(exist, "missing") { return true }
return false
}
// Import graph walker
// -- Import graph walker --------------------------------------------------------
//
// Walk import statements in each .el file to build the dependency graph.
// Returns a list of absolute paths in topological order (deps before dependents).
@@ -219,7 +219,7 @@ fn walk_imports(src_path: String, visited: [String], order: [String]) -> Map<Str
return { "visited": visited, "order": order }
}
// Build
// -- Build ----------------------------------------------------------------------
fn compile_module(src_path: String, out_dir: String, elc_bin: String, dry_run: Bool, verbose: Bool) -> Bool {
let bname: String = basename_noext(src_path)
@@ -246,13 +246,23 @@ fn compile_module(src_path: String, out_dir: String, elc_bin: String, dry_run: B
println("elb: compile failed: " + src_path)
return false
}
// Move the generated .elh (written next to the source by elc) into
// out_dir so that #include "module.elh" lines in the generated .c
// files resolve correctly when cc is invoked with -I <out_dir>.
let src_elh: String = path_with_ext(src_path, ".elh")
let mv_cmd: String = "cp " + src_elh + " " + elh_out + " 2>/dev/null || true"
exec_command(mv_cmd)
return true
}
fn link_binary(c_files: [String], out_bin: String, runtime_path: String, dry_run: Bool) -> Bool {
fn link_binary(c_files: [String], out_bin: String, runtime_path: String, out_dir: String, dry_run: Bool) -> Bool {
let n: Int = native_list_len(c_files)
let parts: [String] = native_list_empty()
let parts = native_list_append(parts, "cc -O2 -I " + dirname_of(runtime_path))
// Include both the runtime dir (for el_runtime.h) and the output dir
// (for module.elh cross-module forward declarations).
let parts = native_list_append(parts, "cc -O2 -I " + dirname_of(runtime_path) + " -I " + out_dir)
let i = 0
while i < n {
let f: String = native_list_get(c_files, i)
@@ -273,7 +283,7 @@ fn link_binary(c_files: [String], out_bin: String, runtime_path: String, dry_run
return true
}
// Main
// -- Main -----------------------------------------------------------------------
fn main() -> Void {
let argv: [String] = args()
@@ -311,7 +321,7 @@ fn main() -> Void {
}
}
if str_eq(runtime_path, "") {
println("elb: cannot locate el_runtime.c use --runtime=PATH")
println("elb: cannot locate el_runtime.c - use --runtime=PATH")
exit(1)
}
@@ -359,11 +369,11 @@ fn main() -> Void {
// Link
let out_bin: String = out_dir + "/" + pkg_name
let linked: Bool = link_binary(c_files, out_bin, runtime_path, dry_run)
let linked: Bool = link_binary(c_files, out_bin, runtime_path, out_dir, dry_run)
if !linked {
println("elb: link failed")
exit(1)
}
println("elb: done " + out_bin)
println("elb: done -> " + out_bin)
}