rust-lang/rust

build an empty project failed (undefined reference to `__onexitbegin')

bitbegin opened this issue · 20 comments

toolchain:

nightly-x86_64-pc-windows-msvc (default)
rustc 1.26.0-nightly (521d91c6b 2018-03-14)

build command: cargo run --target x86_64-pc-windows-gnu

error message:

.rustup\toolchains\nightly-x86_64-pc-windows-msvc\lib\rustlib\x86_64-pc-windows-gnu\lib\crt2.o:crtexe.c:(.rdata$.refptr.__onexitbegin[.refptr.__onexitbegin]+0x0): undefined reference to `__onexitbegin'

.rustup\toolchains\nightly-x86_64-pc-windows-msvc\lib\rustlib\x86_64-pc-windows-gnu\lib\crt2.o:crtexe.c:(.rdata$.refptr.__onexitend[.refptr.__onexitend]+0x0): undefined reference to `__onexitend'
          collect2.exe: error: ld returned 1 exit status

possible reason:

  1. rustc bug?

  2. rustlib bug?

  3. msys2 gcc issues?

I also have this issue. I'd bet the cause is the same as #48272, the version of crt2.o included with the -gnu target isn't the same as the one installed by MSYS2. When I switched to using the gnu compiler rather than the gnu target of an msvc compiler, it worked fine. Perhaps there's something different there?

Much simpler to just copy c:\msys64\mingw64\x86_64-w64-mingw32\lib\crt2.0 to c:\Users%USER%.rustup\toolchains\nightly-x86_64-pc-windows-msvc\lib\rustlib\x86_64-pc-windows-gnu\lib\

As far as I can tell, this happens because x86_64-pc-windows-gnu target for x86_64-pc-windows-msvc toolchain is missing a dependency on rust-mingw-x86_64-pc-windows-gnu component. So when rustc invokes gcc for linking, it either cannot find the linker, or invokes whatever other version of gcc is on the path.

@vadimcn even if rust-mingw component wil be installed it will ship incompatible libraries and cause build errors. To fix them user have to copy libs from their MinGW toolchain anyway, cc #47048

@mati865: compatible with what? The -gnu target is supposed to use the bits of mingw bundled with it, not mingw toolchain installed on your machine.
You might be right if there were some C/C++ code linked into the project that gets compiled with a different version of mingw, but an empty Rust project wouldn't have any FFI code in it.

Also, consider that x86_64-pc-windows-gnu toolchain works just fine, and the only difference is that it does contain the rust-mingw- component.

@alexcrichton: Could rust-mingw- dependency be added to x86_64-pc-windows-gnu target?

@vadimcn windows-gnu toolchain not only picks headers from the system but also various other libs. Neither of them is guaranteed to be compatible with old crt libs shipped with Rust and it causes real issues like #47048 mentioned earlier.

As I said, I don't deny that it's possible to run into compatibility problems when external C/C++ is involved. However, I think it's still perfectly fair to expect x86_64-pc-windows-gnu target to work at least as well as the x86_64-pc-windows-gnu toolchain, i.e. to be able to compile a pure-Rust program.

It would probably be pretty easy to add dependencies to wire this up but I would be wary to do so. Linking with our MinGW target is extremly fiddly and any change tends to have rippling effects causing regressions. I don't really personally want to lead the charge to do this, and unless we have someone willing to help handle the fallout I would discourage a change to the distribution strategy.

Right now that target doesn't work at all, how could it get worse?

At least in my experience it tends to not be that cut and dry, but again I'm not against doing this I just do not personally want to lead the charge to do so. Someone else is always more than welcome to do so.

I'm having the same (or similar) issue when cross-compiling from Linux to Windows:

/usr/lib/gcc/x86_64-w64-mingw32/9.1.0/../../../../x86_64-w64-mingw32/bin/ld: /home/azymohliad/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-pc-windows-gnu/lib/crt2.o:crtexe.c:(.rdata$.refptr.__onexitbegin[.refptr.__onexitbegin]+0x0): undefined reference to `__onexitbegin'
/usr/lib/gcc/x86_64-w64-mingw32/9.1.0/../../../../x86_64-w64-mingw32/bin/ld: /home/azymohliad/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-pc-windows-gnu/lib/crt2.o:crtexe.c:(.rdata$.refptr.__onexitend[.refptr.__onexitend]+0x0): undefined reference to `__onexitend'
collect2: error: ld returned 1 exit status

I'm on ArchLinux and followed the cross-compilation guide from gtk-rs

@rustbot modify labels: -O-windows +O-windows-gnu

@azymohliad you can use workaround from #47048 but change paths for Linux.

@mati865 Could you link to the exact comment which has the work around? And what exactly needs to be changed for cross compiling from Linux? I can't seem to figure it out.

@ChristopherRabotin #47048 (comment) but for me copying the libs is enough (crt2.o, dllcrt2.o and libmsvcrt.a).
For i686 most distributions provide SJLJ based toolchain so you will have to get toolchain with DWARF2 or set panic = abort in https://doc.rust-lang.org/cargo/reference/manifest.html#the-profile-sections

Probably a duplicate of #53454.

Getting this trying to cross-compile from current Arch packages. Tried panic=abort but it doesn't seem to fix the issue. What needs to change for this to work out of the box for people?

I did take a look at the workaround, but I'm not running on Windows. So I don't have a C: apart from wine :). And I won't get to running this until I can build it.

@spease for this issue the workaround is copying libs like I said 2 comments above.
panic=abort is for i686 toolchain only because Rust is using Dwarf exception handling but Linux distributions mostly ship i686 with SJLJ exceptions.

These have to be copied from mingw installed on Windows though.

No, you can use mingw from AUR. See the Arch wiki: https://wiki.archlinux.org/index.php/Rust#Windows

Much simpler to just copy c:\msys64\mingw64\x86_64-w64-mingw32\lib\crt2.0 to c:\Users%USER%.rustup\toolchains\nightly-x86_64-pc-windows-msvc\lib\rustlib\x86_64-pc-windows-gnu\lib\

crt2.o and dllcrt2.o have to be copied over.