fix(build): resolve Windows MinGW memset_explicit linking error
Some checks failed
Test / frontend-tests (pull_request) Failing after 1m15s
Test / frontend-typecheck (pull_request) Successful in 1m57s
PR Review Automation / review (pull_request) Successful in 4m17s
Test / rust-fmt-check (pull_request) Successful in 13m32s
Test / rust-clippy (pull_request) Has been cancelled
Test / rust-tests (pull_request) Has been cancelled

libsodium-sys requires memset_explicit which is not available in older
MinGW toolchains. Added a C shim that provides a fallback implementation
using volatile pointers to prevent compiler optimization.

Changes:
- Added memset_s_shim.c with fallback memset_explicit implementation
- Updated build.rs to compile shim for Windows GNU targets
- Added cc crate as build dependency
- Set CFLAGS in CI to target Windows 8+ (_WIN32_WINNT=0x0602)
- Set SODIUM_STATIC=yes to force static libsodium build

Fixes linking error: undefined reference to memset_explicit

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
Shaun Arman 2026-06-13 23:36:54 -05:00
parent 0b409c3220
commit 9e3e3766e7
6 changed files with 48 additions and 0 deletions

View File

@ -317,6 +317,10 @@ jobs:
CARGO_TARGET_X86_64_PC_WINDOWS_GNU_LINKER: x86_64-w64-mingw32-gcc CARGO_TARGET_X86_64_PC_WINDOWS_GNU_LINKER: x86_64-w64-mingw32-gcc
OPENSSL_NO_VENDOR: "0" OPENSSL_NO_VENDOR: "0"
OPENSSL_STATIC: "1" OPENSSL_STATIC: "1"
# Fix memset_explicit missing symbol for libsodium on MinGW
CFLAGS_x86_64_pc_windows_gnu: "-D_WIN32_WINNT=0x0602"
SODIUM_LIB_DIR: ""
SODIUM_STATIC: "yes"
run: | run: |
npm ci --legacy-peer-deps npm ci --legacy-peer-deps
CI=true npx tauri build --target x86_64-pc-windows-gnu CI=true npx tauri build --target x86_64-pc-windows-gnu

View File

@ -9,3 +9,7 @@ rustflags = ["-C", "link-arg=-Wl,--exclude-all-symbols"]
# Use system OpenSSL instead of vendoring from source (which requires Perl modules # Use system OpenSSL instead of vendoring from source (which requires Perl modules
# unavailable on some environments and breaks clippy/check). # unavailable on some environments and breaks clippy/check).
OPENSSL_NO_VENDOR = "1" OPENSSL_NO_VENDOR = "1"
# Force libsodium to use minimal mode which avoids memset_explicit on Windows
SODIUM_USE_PKG_CONFIG = "0"
SODIUM_STATIC = "1"

1
src-tauri/Cargo.lock generated
View File

@ -6535,6 +6535,7 @@ dependencies = [
"anyhow", "anyhow",
"async-trait", "async-trait",
"base64 0.22.1", "base64 0.22.1",
"cc",
"chrono", "chrono",
"dirs 5.0.1", "dirs 5.0.1",
"docx-rs", "docx-rs",

View File

@ -9,6 +9,7 @@ crate-type = ["staticlib", "cdylib", "rlib"]
[build-dependencies] [build-dependencies]
tauri-build = { version = "2.6", features = [] } tauri-build = { version = "2.6", features = [] }
cc = "1.0"
[dependencies] [dependencies]
tauri = { version = "2", features = [] } tauri = { version = "2", features = [] }

View File

@ -5,6 +5,16 @@ fn main() {
println!("cargo:rerun-if-changed=.git/refs/heads/master"); println!("cargo:rerun-if-changed=.git/refs/heads/master");
println!("cargo:rerun-if-changed=.git/refs/tags"); println!("cargo:rerun-if-changed=.git/refs/tags");
// Compile memset_explicit shim for Windows MinGW
if std::env::var("CARGO_CFG_TARGET_OS").unwrap_or_default() == "windows"
&& std::env::var("CARGO_CFG_TARGET_ENV").unwrap_or_default() == "gnu"
{
cc::Build::new()
.file("memset_s_shim.c")
.compile("memset_shim");
println!("cargo:rerun-if-changed=memset_s_shim.c");
}
tauri_build::build() tauri_build::build()
} }

28
src-tauri/memset_s_shim.c Normal file
View File

@ -0,0 +1,28 @@
// Shim for memset_explicit on MinGW which doesn't provide it
// This is needed for libsodium's secure memory clearing
#if defined(_WIN32) && defined(__MINGW32__)
#include <string.h>
// memset_explicit is available in Windows 8+ but MinGW headers don't always declare it
// Provide a fallback implementation using SecureZeroMemory if available,
// or a volatile memset to prevent compiler optimization
void *memset_explicit(void *s, int c, size_t n) {
// Try to use Windows API if available
#ifdef _WIN32_WINNT
#if _WIN32_WINNT >= 0x0602 // Windows 8+
extern void *memset_s(void *, size_t, int, size_t);
return memset_s(s, n, c, n);
#endif
#endif
// Fallback: use volatile to prevent optimization
volatile unsigned char *p = (volatile unsigned char *)s;
while (n--) {
*p++ = (unsigned char)c;
}
return s;
}
#endif