diff --git a/lang/dist/platform/elb b/lang/dist/platform/elb index 2df99e2..a397f4b 100755 Binary files a/lang/dist/platform/elb and b/lang/dist/platform/elb differ diff --git a/lang/dist/platform/elc-new b/lang/dist/platform/elc-new deleted file mode 100755 index f1cba65..0000000 Binary files a/lang/dist/platform/elc-new and /dev/null differ diff --git a/lang/elb.el b/lang/elb.el index 9dcd731..21a0676 100644 --- a/lang/elb.el +++ b/lang/elb.el @@ -77,6 +77,33 @@ fn parse_manifest_entry(src: String) -> String { return "" } +// parse_manifest_c_sources - collect all `c_source "path"` lines from the +// build block. Returns a flat list of path strings. +fn parse_manifest_c_sources(src: String) -> [String] { + let result: [String] = native_list_empty() + let lines: [String] = str_split(src, "\n") + let n: Int = native_list_len(lines) + let i = 0 + while i < n { + let line: String = native_list_get(lines, i) + let t: String = str_trim(line) + if str_starts_with(t, "c_source ") { + let after: String = str_slice(t, 9, str_len(t)) + let trimmed: String = str_trim(after) + if str_starts_with(trimmed, "\"") { + let inner: String = str_slice(trimmed, 1, str_len(trimmed)) + let q: Int = str_index_of(inner, "\"") + if q >= 0 { + let path: String = str_slice(inner, 0, q) + let result = native_list_append(result, path) + } + } + } + let i = i + 1 + } + return result +} + fn parse_manifest_name(src: String) -> String { let lines: [String] = str_split(src, "\n") let n: Int = native_list_len(lines) @@ -274,7 +301,11 @@ fn link_binary(c_files: [String], out_bin: String, runtime_path: String, out_dir // Detect clang vs gcc: -fbracket-depth is clang-only; silently ignored // if unsupported but gcc rejects it with an error. let bracket_flag: String = "$(cc --version 2>&1 | grep -q clang && printf -- '-fbracket-depth=1024' || true)" - let parts = native_list_append(parts, "cc -O2 " + bracket_flag + " -I " + dirname_of(runtime_path) + " -I " + out_dir) + // On macOS, OpenSSL is not on the default linker path. Detect homebrew + // prefix and add it if present (no-op on Linux where libssl is in /usr/lib). + let ossl_lib_flag: String = "$(brew --prefix openssl 2>/dev/null | xargs -I{} printf -- '-L{}/lib' 2>/dev/null || true)" + let ossl_inc_flag: String = "$(brew --prefix openssl 2>/dev/null | xargs -I{} printf -- '-I{}/include' 2>/dev/null || true)" + let parts = native_list_append(parts, "cc -O2 " + bracket_flag + " " + ossl_inc_flag + " -I " + dirname_of(runtime_path) + " -I " + out_dir) let i = 0 while i < n { let f: String = native_list_get(c_files, i) @@ -282,7 +313,7 @@ fn link_binary(c_files: [String], out_bin: String, runtime_path: String, out_dir let i = i + 1 } let parts = native_list_append(parts, runtime_path) - let parts = native_list_append(parts, "-lcurl -lssl -lcrypto -lpthread -lm") + let parts = native_list_append(parts, ossl_lib_flag + " -lcurl -lssl -lcrypto -lpthread -lm") let parts = native_list_append(parts, "-o " + out_bin) let cmd: String = str_join(parts, " ") println(" link " + out_bin) @@ -315,6 +346,7 @@ fn main() -> Void { let pkg_name: String = parse_manifest_name(manifest_src) let entry: String = parse_manifest_entry(manifest_src) + let extra_c: [String] = parse_manifest_c_sources(manifest_src) if str_eq(entry, "") { println("elb: manifest.el has no 'entry' declaration") exit(1) @@ -393,6 +425,15 @@ fn main() -> Void { exit(1) } + // Append any extra C sources declared in the manifest (e.g. platform stubs) + let ei = 0 + let en: Int = native_list_len(extra_c) + while ei < en { + let ec: String = native_list_get(extra_c, ei) + let c_files = native_list_append(c_files, ec) + let ei = ei + 1 + } + // Link let out_bin: String = out_dir + "/" + pkg_name let linked: Bool = link_binary(c_files, out_bin, runtime_path, out_dir, dry_run)