Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 9d0e1f64d4 |
Vendored
BIN
Binary file not shown.
@@ -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)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user