diff --git a/dist/platform/elb b/dist/platform/elb index 003dd19..5d62fdd 100755 Binary files a/dist/platform/elb and b/dist/platform/elb differ diff --git a/elb.el b/elb.el index 76851b8..900dc43 100644 --- a/elb.el +++ b/elb.el @@ -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 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 . + 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) }