From d0a985a53bba0e8b830b521f1f4fae2344927761 Mon Sep 17 00:00:00 2001 From: Shaun Arman Date: Fri, 19 Jun 2026 15:21:58 -0500 Subject: [PATCH] fix(windows): compile memset_shim to real .o via get_compiler() to fix MinGW link compile("memset_shim") produces libmemset_shim.a, not memset_shim.o, so the previous cargo:rustc-link-arg pointed at a file that never exists. Switching to get_compiler().to_command() compiles memset_s_shim.c directly to a .o file at a known OUT_DIR path and passes it as a positional linker arg. A positional .o is always included unconditionally, which also resolves the archive-extraction ordering issue where -l flags only pull symbols that are already undefined at that point in the link command. --- src-tauri/build.rs | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/src-tauri/build.rs b/src-tauri/build.rs index 5f3480f0..5439d8cf 100644 --- a/src-tauri/build.rs +++ b/src-tauri/build.rs @@ -11,20 +11,27 @@ fn main() { let target_env = std::env::var("CARGO_CFG_TARGET_ENV").unwrap_or_default(); if target_os == "windows" && target_env == "gnu" { - let out_dir = std::env::var("OUT_DIR").unwrap(); - let obj_path = format!("{}/memset_shim.o", out_dir); + let out_dir = std::env::var("OUT_DIR").expect("OUT_DIR not set"); + let obj_path = format!("{out_dir}/memset_s_shim.o"); - cc::Build::new() - .file("memset_s_shim.c") - .define("WIN32", None) - .define("__WIN32__", None) - .out_dir(&out_dir) - .compile("memset_shim"); + // Compile directly to a .o file and link it as a positional linker arg. + // This sidesteps the static-archive ordering problem: a bare -l flag only + // pulls symbols that are already undefined at that point in the link, + // but libsodium's reference to memset_explicit comes later. A positional + // object file is always included unconditionally. + let compiler = cc::Build::new().get_compiler(); + let status = compiler + .to_command() + .args(["-DWIN32", "-D__WIN32__", "-c"]) + .arg("-o") + .arg(&obj_path) + .arg("memset_s_shim.c") + .status() + .expect("failed to invoke C compiler for memset_s_shim.c"); + assert!(status.success(), "failed to compile memset_s_shim.c"); println!("cargo:rerun-if-changed=memset_s_shim.c"); - // Directly link the object file instead of using -l flag - // This ensures the symbol is available regardless of link order - println!("cargo:rustc-link-arg={}", obj_path); + println!("cargo:rustc-link-arg={obj_path}"); } tauri_build::build()