diff --git a/lang/dist/platform/elb b/lang/dist/platform/elb index 187092f..b412a6c 100755 Binary files a/lang/dist/platform/elb and b/lang/dist/platform/elb differ diff --git a/lang/elb.el b/lang/elb.el index b721aff..4017f51 100644 --- a/lang/elb.el +++ b/lang/elb.el @@ -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) + // 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 // out_dir so that #include "module.elh" lines in the generated .c // files resolve correctly when cc is invoked with -I . @@ -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). 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)" + // 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 // unit sees all cross-module function signatures. Handles packages (like ELP) // 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 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 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 while i < n { 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 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 cmd: String = str_join(parts, " ") println(" link " + out_bin) @@ -432,18 +442,23 @@ fn main() -> Void { 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) 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 link_files = native_list_append(link_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) + let linked: Bool = link_binary(link_files, out_bin, runtime_path, out_dir, dry_run) if !linked { println("elb: link failed") exit(1)