How can I statically link libstdc++-6 when cross compilint to x86_64-pc-windows-gnu from Linux?

cargo build --target x86_64-pc-windows-gnu is supposed to make binaries that work on windows, but the binaries that it produces depend on libstdc++-6.dll and will not run on stock windows. I could distribute this DLL with my program (from /usr/lib/gcc/x86_64-w64-mingw32/12-win32), but I want a self-contained exe that does not require additional files. A such, I want to statically link this library. But, I have become exceedingly frustrated trying to find the incantation to make Cargo make rustc make mingw do this.

When cross-compiling a C++ program I can accomplish what is needed fairly easily:

x86_64-w64-mingw32-g++ -static-libgstdc++ -static *.cpp -o myprogram.exe

So, I thought that passing these same arguments to this linker is all that I'd need. To that end, I wrote this ~/.cargo/config file:

rustflags = [
	"-C", "link-arg=-static-libstdc++",
	"-C", "link-arg=-static",
	"-C", "linker=x86_64-w64-mingw32-g++"

But, .exe files compiled with this still dynamically link to libstdc++-6.dll, as if Cargo is uncooperatively ignoring my instructions.

I also found this "solution" by web search, but Cargo also seemed to ignore this (libstdc++-6.dll is still required by resulting .exes).

My compile command is cargo build --target=x86_64-pc-windows-gnu --release.

1 Like

Which crate are you using that depends on libstdc++? It likely tells the linker that the dynamically linked libstdc++ needs to be used to work even when using gcc rather than g++ as linker (as is the default) You may need to add an option to it to instead tell the linker to statically link libstdc++.

I am also in the same predicament.

I've even tried building more minimal STD by hand (w/ abort panic handling)

RUSTFLAGS="-C panic=abort -Zpanic_abort_tests -Ctarget-feature=+crt-static -Clink-arg=-static -Clink-arg=-static-libgcc -Clink-arg=-static-libstdc++" cargo +nightly test -Z build-std=std,panic_abort -Z build-std-features=panic_immediate_abort --target x86_64-pc-windows-gnu

But unfortunately, I was not so fortunate.

In my case I was trying to validate that a low level Windows library worked fine under Wine, but it turned out to be very difficult.

I can't simply just 'copy libgcc_s_dw2-1.dll from my mingw folder' because (unfortunately), there's no telling what version of mingw someone in the future will be building with; these dynamic libraries may end up incompatible.

Note that this is almost certainly a consequence of a crate you depend upon; I can build a binary from pure Rust code with cargo build --target=x86-64-pc-windows-gnu --release which does not dynamically link libstdc++-6.dll.

1 Like