feat(elb): c_source manifest directive + macOS OpenSSL path detection
Add `c_source "path"` in manifest.el build block — lets packages link extra C files (platform stubs, native glue) without touching elb source. On macOS, homebrew OpenSSL isn't on the default linker path. Detect it via `brew --prefix` and inject -L/-I flags; no-op on Linux. Rebuild elb binary; remove elc-new binary (elc is now canonical).
This commit is contained in:
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
+43
-2
@@ -77,6 +77,33 @@ fn parse_manifest_entry(src: String) -> String {
|
|||||||
return ""
|
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 {
|
fn parse_manifest_name(src: String) -> String {
|
||||||
let lines: [String] = str_split(src, "\n")
|
let lines: [String] = str_split(src, "\n")
|
||||||
let n: Int = native_list_len(lines)
|
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
|
// Detect clang vs gcc: -fbracket-depth is clang-only; silently ignored
|
||||||
// if unsupported but gcc rejects it with an error.
|
// 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 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
|
let i = 0
|
||||||
while i < n {
|
while i < n {
|
||||||
let f: String = native_list_get(c_files, i)
|
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 i = i + 1
|
||||||
}
|
}
|
||||||
let parts = native_list_append(parts, runtime_path)
|
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 parts = native_list_append(parts, "-o " + out_bin)
|
||||||
let cmd: String = str_join(parts, " ")
|
let cmd: String = str_join(parts, " ")
|
||||||
println(" link " + out_bin)
|
println(" link " + out_bin)
|
||||||
@@ -315,6 +346,7 @@ fn main() -> Void {
|
|||||||
|
|
||||||
let pkg_name: String = parse_manifest_name(manifest_src)
|
let pkg_name: String = parse_manifest_name(manifest_src)
|
||||||
let entry: String = parse_manifest_entry(manifest_src)
|
let entry: String = parse_manifest_entry(manifest_src)
|
||||||
|
let extra_c: [String] = parse_manifest_c_sources(manifest_src)
|
||||||
if str_eq(entry, "") {
|
if str_eq(entry, "") {
|
||||||
println("elb: manifest.el has no 'entry' declaration")
|
println("elb: manifest.el has no 'entry' declaration")
|
||||||
exit(1)
|
exit(1)
|
||||||
@@ -393,6 +425,15 @@ fn main() -> Void {
|
|||||||
exit(1)
|
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
|
// Link
|
||||||
let out_bin: String = out_dir + "/" + pkg_name
|
let out_bin: String = out_dir + "/" + pkg_name
|
||||||
let linked: Bool = link_binary(c_files, out_bin, runtime_path, out_dir, dry_run)
|
let linked: Bool = link_binary(c_files, out_bin, runtime_path, out_dir, dry_run)
|
||||||
|
|||||||
Reference in New Issue
Block a user