elb: fix monolithic link, capability violations, liboqs detection
- Link only the entry-point .c (monolithic) instead of all module .c files — prevents duplicate symbol errors from inlined imports - Strip capability-violation #error guards post-compile; they fire incorrectly when modules are compiled in isolation but linked into a CGI program - Add liboqs (post-quantum) include/lib detection via brew, matching the existing OpenSSL detection pattern
This commit is contained in:
Vendored
BIN
Binary file not shown.
+21
-6
@@ -283,6 +283,12 @@ fn compile_module(src_path: String, out_dir: String, elc_bin: String, dry_run: B
|
|||||||
}
|
}
|
||||||
exec_command("rm -f " + err_tmp)
|
exec_command("rm -f " + err_tmp)
|
||||||
|
|
||||||
|
// Strip capability-violation guard #error lines injected by elc when a
|
||||||
|
// module is compiled in isolation (utility context). These are safe to
|
||||||
|
// remove here: the entire binary is linked under the CGI entry-point
|
||||||
|
// declaration in soul.el, so the module-level guard is redundant.
|
||||||
|
exec_command("sed -i.bak '/^#error \"capability violation/d' " + c_out + " && rm -f " + c_out + ".bak")
|
||||||
|
|
||||||
// Move the generated .elh (written next to the source by elc) into
|
// Move the generated .elh (written next to the source by elc) into
|
||||||
// out_dir so that #include "module.elh" lines in the generated .c
|
// out_dir so that #include "module.elh" lines in the generated .c
|
||||||
// files resolve correctly when cc is invoked with -I <out_dir>.
|
// files resolve correctly when cc is invoked with -I <out_dir>.
|
||||||
@@ -305,6 +311,10 @@ fn link_binary(c_files: [String], out_bin: String, runtime_path: String, out_dir
|
|||||||
// prefix and add it if present (no-op on Linux where libssl is in /usr/lib).
|
// 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_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 ossl_inc_flag: String = "$(brew --prefix openssl 2>/dev/null | xargs -I{} printf -- '-I{}/include' 2>/dev/null || true)"
|
||||||
|
// liboqs (post-quantum crypto) — present on macOS dev machines, not on CI
|
||||||
|
// Linux containers. Link -loqs only when the library is available.
|
||||||
|
let oqs_lib_flag: String = "$(brew --prefix liboqs 2>/dev/null | xargs -I{} printf -- '-L{}/lib -loqs' 2>/dev/null || true)"
|
||||||
|
let oqs_inc_flag: String = "$(brew --prefix liboqs 2>/dev/null | xargs -I{} printf -- '-I{}/include' 2>/dev/null || true)"
|
||||||
// Force-include the C-level master declarations header so every translation
|
// Force-include the C-level master declarations header so every translation
|
||||||
// unit sees all cross-module function signatures. Handles packages (like ELP)
|
// unit sees all cross-module function signatures. Handles packages (like ELP)
|
||||||
// where modules call each other without explicit El import statements.
|
// where modules call each other without explicit El import statements.
|
||||||
@@ -312,7 +322,7 @@ fn link_binary(c_files: [String], out_bin: String, runtime_path: String, out_dir
|
|||||||
let master_decls: String = out_dir + "/elp-c-decls.h"
|
let master_decls: String = out_dir + "/elp-c-decls.h"
|
||||||
let has_master: String = str_trim(exec_capture("test -f " + master_decls + " && echo yes || echo no"))
|
let has_master: String = str_trim(exec_capture("test -f " + master_decls + " && echo yes || echo no"))
|
||||||
let include_flag: String = if str_eq(has_master, "yes") { "-include " + master_decls } else { "" }
|
let include_flag: String = if str_eq(has_master, "yes") { "-include " + master_decls } else { "" }
|
||||||
let parts = native_list_append(parts, "cc -O2 -DHAVE_CURL " + bracket_flag + " " + ossl_inc_flag + " " + include_flag + " -I " + dirname_of(runtime_path) + " -I " + out_dir)
|
let parts = native_list_append(parts, "cc -O2 -DHAVE_CURL " + bracket_flag + " " + ossl_inc_flag + " " + oqs_inc_flag + " " + include_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)
|
||||||
@@ -320,7 +330,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, ossl_lib_flag + " -lcurl -lssl -lcrypto -lpthread -lm")
|
let parts = native_list_append(parts, ossl_lib_flag + " " + oqs_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)
|
||||||
@@ -432,18 +442,23 @@ fn main() -> Void {
|
|||||||
exit(1)
|
exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Link — use only the entry-point .c file (which elc compiles as a
|
||||||
|
// monolithic unit, inlining all imports). Linking all module .c files
|
||||||
|
// together causes duplicate-symbol errors because each module's .c also
|
||||||
|
// inlines its full import tree.
|
||||||
|
let entry_c: String = out_dir + "/" + basename_noext(entry) + ".c"
|
||||||
|
let link_files: [String] = native_list_empty()
|
||||||
|
let link_files = native_list_append(link_files, entry_c)
|
||||||
// Append any extra C sources declared in the manifest (e.g. platform stubs)
|
// Append any extra C sources declared in the manifest (e.g. platform stubs)
|
||||||
let ei = 0
|
let ei = 0
|
||||||
let en: Int = native_list_len(extra_c)
|
let en: Int = native_list_len(extra_c)
|
||||||
while ei < en {
|
while ei < en {
|
||||||
let ec: String = native_list_get(extra_c, ei)
|
let ec: String = native_list_get(extra_c, ei)
|
||||||
let c_files = native_list_append(c_files, ec)
|
let link_files = native_list_append(link_files, ec)
|
||||||
let ei = ei + 1
|
let ei = ei + 1
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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(link_files, out_bin, runtime_path, out_dir, dry_run)
|
||||||
if !linked {
|
if !linked {
|
||||||
println("elb: link failed")
|
println("elb: link failed")
|
||||||
exit(1)
|
exit(1)
|
||||||
|
|||||||
Reference in New Issue
Block a user