Rustc 1.70.0: In windows to build a target x86_64-unknown-linux-gnu get error like unrecognized option '--eh-frame-hdr'

  1. to build command:
cargo build --release --target x86_64-unknown-linux-gnu -p rmaker
  1. then i get like
error: linking with `cc` failed: exit code: 1
  = note: "cc" "-m64" "C:\\Users\\x\\AppData\\Local\\Temp\\rustc2cUKcS\\symbols.o" "~\\target\\x86_64-unknown-linux-gnu\\release\\deps\\rmaker-22b7e16c5185da64.rmaker.04359c71-cgu.7.rcgu.o" "-Wl,--as-needed" "-L" "~\\target\\x86_64-unknown-linux-gnu\\release\\deps" "-L" "~\\target\\release\\deps" "-L" "D:\\AppData\\rust\\.rustup\\toolchains\\stable-x86_64-pc-windows-gnu\\lib\\rustlib\\x86_64-unknown-linux-gnu\\lib" "-Wl,-Bstatic" "D:\\AppData\\rust\\.rustup\\toolchains\\stable-x86_64-pc-windows-gnu\\lib\\rustlib\\x86_64-unknown-linux-gnu\\lib\\libcompiler_builtins-919e055b306699ae.rlib" "-Wl,-Bdynamic" "-lgcc_s" "-lutil" "-lrt" "-lpthread" "-lm" "-ldl" "-lc" "-Wl,--eh-frame-hdr" "-Wl,-z,noexecstack" "-L" "D:\\AppData\\rust\\.rustup\\toolchains\\stable-x86_64-pc-windows-gnu\\lib\\rustlib\\x86_64-unknown-linux-gnu\\lib" "-o" "~\\target\\x86_64-unknown-linux-gnu\\release\\deps\\rmaker-22b7e16c5185da64" "-Wl,--gc-sections" "-pie" "-Wl,-z,relro,-z,now" "-Wl,--strip-all" "-nodefaultlibs"
  = note: D:/Program Files/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/12.1.0/../../../../x86_64-w64-mingw32/bin/ld.exe: unrecognized option '--eh-frame-hdr'
          D:/Program Files/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/12.1.0/../../../../x86_64-w64-mingw32/bin/ld.exe: use the --help option for usage information
          collect2.exe: error: ld returned 1 exit status
  1. I have checked the issue in Github again but have not found a relevant solution. Some answers are somewhat vague and I have tried, but still cannot overcome it. I have also checked the documents on the website, but I still cannot find a solution.

I try a way follow example /usr/bin/avr-ld: unrecognized option '--eh-frame-hdr', and make set like that:

eh-frame-header = false

but don't work.

  1. I suddenly feel that cross compilation is so difficult (complex), and I am very grateful if you can provide guidance.

  2. my rust env

rustup target list --installed
# x86_64-pc-windows-gnu

the reason for the error is you are using an linker for x86_64-w64, but you need x86_64-linux-gnu.

cross compiling in rust is generally not a trivial task, except for very simple targets including many embedded platforms. the reason being, the rust toolchains aren't fully self contained: for one thing, rust doesn't have a "portable" linker (well, rust-lld is close, but not quite there yet) and relies on a system linker to generate the final program binary; the other one reason, some of the standard library are implemented on top of C runtime.

so, it's not enough to have a cross compiling rustc and rust-std, you also need a cross compiling linker and C library. to compile for Linux on Windows, it's actually not difficult to get an ELF capable linker (e.g. rust-lld), but it not easy to get all the libraries for the target Linux system, you need at least glibc, libgcc, maybe libpthread, etc.

the recommended way to cross compile rust projects is use cross:

it generally works out of the box (as they said, zero setup), but it is container based so you must have a container engine on your system. for windows host, docker desktop works fine.

a side note, cross compiling static libraries (crate-type = ["lib"]) should work fine, since static libraries don't need to be linked.

ps: I really like the way how zig supports cross compiling: it comes with an portable linker for all supported targets; the zig standard library is implemented directly on top of system calls of the target operating systems (as opposed to libc); and for FFI purpose, zig even ships its own libc for certain target platforms (libc can be implemented on top of zig std, not the other way around like most languages including rust)

@nerditation Thank you for your detailed answer. Thank you very much.

I still have many blind spots about linkers, so I probably know what you said, on the surface. But in terms of convenience (user friendliness), I think rust can do more. I often write go code, and its cross compilation feels so easy. I can easily compile go code from Windows to Linux and run it easily (only representing my feelings, of course, this may not be so precise). Of course, for beginners (novice developers), the rust we expect can also be like this. When executing rustup target add x86_64-unknown-linux-gnu, I imagine it can be executed quickly, but in reality, it is a bit frustrating and there are still many hidden things, And I really didn't see the clear guidance from the official website of the source; I simply thought that x86_64-pc-windows-gnu, the same "*-gnu" should be easier. There are many requirements for compiling from Windows to Linux. Our web servers are generally deployed on Linux, but development is generally done on Windows.

Cross sounds like a great solution, and I hope it brings better convenience to cross writing for rust. However, for now, Docker is a bit heavy on my environment because there are too many things installed on my Windows system, which are too complicated; Wsl2, mingw-w64 are equivalent to something related to Linux.


although the zig lead developer says that zig is going to deprecate these features

i hope rust can implement something like this

1 Like

I tried using cross for cross compilation, using podman. However, due to network issues, one may not be able to enjoy "zero configuration" to run, making network issues uncomfortable.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.