u/StatisticianNo5402

Image 1 — I waited all these years to finish the game
Image 2 — I waited all these years to finish the game
Image 3 — I waited all these years to finish the game
▲ 90 r/GTAV

I waited all these years to finish the game

What a fucking journey.
Saved everyone and loved every minute.

As the next chapter of this awesome American saga is on the horizon.

Would you recommend playing online to get the rest of the story?
I will play solo.

Can I fully play the online storylines by myself?

u/StatisticianNo5402 — 9 days ago
▲ 30 r/CodingHelp+1 crossposts

Two crates each bundle a different libcrypto (OpenSSL vs BoringSSL) → same symbol names, heap corruption. Is there a cleaner fix than /FORCE:MULTIPLE?

I have a Rust desktop app (Slint UI) that links two things which each bring their own C crypto:
- rusqlite with bundled-sqlcipher: SQLCipher for the encrypted local DB, built against OpenSSL.
- livekit → webrtc-sys: WebRTC for calls, which statically bundles BoringSSL.

BoringSSL is a fork of OpenSSL, so both export the same symbol names (EVP_*, HMAC, PKCS5_PBKDF2_HMAC, AES_*, …) but with incompatible internals (different struct layouts/behavior).

Linking both into one binary gives duplicate-symbol errors:
- MSVC: LNK1169
- Linux (mold/lld): multiple definition

The current workaround is to force it through:

# .cargo/config.toml

[target.x86_64-pc-windows-msvc]

rustflags = ["-C", "link-arg=/FORCE:MULTIPLE"]

[target.x86_64-unknown-linux-gnu]

rustflags = ["-C", "link-arg=-Wl,--allow-multiple-definition"]

This link, however, causes the linker to retain the first definition and discard the rest — so the entire binary uses one implementation for those symbols, chosen by the link order. SQLCipher (compiled against OpenSSL's headers) ended up calling BoringSSL's implementation → struct layout mismatch → heap corruption on the first real crypto call (PRAGMA key / PBKDF2 when opening the DB). Native crash (0xC0000005), no Rust panic.

What I've found so far:

  1. Unify on one libcrypto — point SQLCipher's OPENSSL_LIB_DIR/OPENSSL_INCLUDE_DIR at the BoringSSL that webrtc already bundles, so the whole binary has exactly one libcrypto. Works (SQLCipher 4.5.x is BoringSSL-compatible), but feels fragile — I'm depending on webrtc-sys's prebuilt BoringSSL headers/libs being present and ABI-stable, and it needed a Windows-specific -DNOCRYPT hack to stop windows.h/wincrypt.h macros from colliding with BoringSSL typedefs.

  2. Drop one of them — build without LiveKit when I don't need calls → no BoringSSL → no collision. Fine as a fallback, but I want calls and an encrypted DB in the same binary.

My questions:

- Is there a way to make these two C libs coexist properly — e.g. symbol prefixing/localizing one libcrypto (objcopy --redefine-syms / a version script / --localize-symbols) so SQLCipher and WebRTC each call their own crypto without /FORCE:MULTIPLE roulette? Has anyone done this with prebuilt static libs (no source rebuild of webrtc)?

- Is unifying everything on BoringSSL the accepted answer here, or do people regret it?

- Any -sys crate convention I'm missing for "I bring my own crypto, don't let it leak into the global symbol namespace"?

Stack: Rust stable, MSVC + Linux targets, rusqlite (bundled-sqlcipher), livekit/webrtc-sys. Happy to share the exact link flags.

reddit.com
u/StatisticianNo5402 — 12 days ago