Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

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

Closed
bitbegin opened this issue Mar 16, 2018 · 20 comments · Fixed by #67429
Closed

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

bitbegin opened this issue Mar 16, 2018 · 20 comments · Fixed by #67429
Labels
A-linkage Area: linking into static, shared libraries and binaries C-bug Category: This is a bug. O-windows-gnu Toolchain: GNU, Operating system: Windows T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@bitbegin
Copy link

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?

@pietroalbini pietroalbini added A-linkage Area: linking into static, shared libraries and binaries O-windows Operating system: Windows T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. C-bug Category: This is a bug. labels Mar 20, 2018
@mattico
Copy link
Contributor

mattico commented Mar 25, 2018

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?

@ghost
Copy link

ghost commented Dec 22, 2018

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\

@vadimcn
Copy link
Contributor

vadimcn commented Apr 21, 2019

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.

@mati865
Copy link
Contributor

mati865 commented Apr 21, 2019

@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

@vadimcn
Copy link
Contributor

vadimcn commented Apr 21, 2019

@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?

@mati865
Copy link
Contributor

mati865 commented Apr 21, 2019

@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.

@vadimcn
Copy link
Contributor

vadimcn commented Apr 21, 2019

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.

@alexcrichton
Copy link
Member

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.

@vadimcn
Copy link
Contributor

vadimcn commented Apr 22, 2019

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

@alexcrichton
Copy link
Member

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.

@azymohliad
Copy link

azymohliad commented May 21, 2019

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

@mati865
Copy link
Contributor

mati865 commented May 21, 2019

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

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

@rustbot rustbot added O-windows-gnu Toolchain: GNU, Operating system: Windows and removed O-windows Operating system: Windows labels May 21, 2019
@ChristopherRabotin
Copy link

@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.

@mati865
Copy link
Contributor

mati865 commented Jun 11, 2019

@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

@marmistrz
Copy link
Contributor

Probably a duplicate of #53454.

@spease
Copy link

spease commented Aug 25, 2019

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.

@mati865
Copy link
Contributor

mati865 commented Aug 26, 2019

@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.

@spease
Copy link

spease commented Aug 26, 2019

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

@marmistrz
Copy link
Contributor

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

@snuk182
Copy link

snuk182 commented Jan 17, 2020

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.

bors added a commit that referenced this issue Jan 31, 2020
windows-gnu: prefer system crt libraries if they are available

This is my proposal (based on `Amanieu`'s idea) on how to fix #47048 and related issues.

The origin of the issue is the fact Rust ships mingw-w64 libraries but no headers and prefers own libraries over the system ones.
This leads to situation when headers aren't compatible with libraries (mingw-w64 doesn't provide any forward compatibility and AFAIK backwards compatibility is guaranteed only within major release series).

It's easier to understand how this PR works when looking at the linker invocation before and with this PR: https://www.diffchecker.com/GEuYFmzo
It adds system libraries path before Rust libraries so the linker will prefer them.
It has potential issue when system has files with the same names as Rust but that could be avoided by moving Rust shipped mingw-w64 libraries from `lib/rustlib/x86_64-pc-windows-gnu/lib` to say `lib/rustlib/x86_64-pc-windows-gnu/lib/mingw`. Then adding linker paths in this order: Rust libraries, system libraries, Rust shipped mingw-w64 libraries.

I don't know if it's worth to cache system libraries path. You can look for `cache: ` string during build Rust: https://pastebin.com/kGEQZGWP
I think there are enough calls to justify caching.

Fixes #47048
Fixes #49078
Fixes #53454
Fixes #60912
@bors bors closed this as completed in 58b8343 Feb 5, 2020
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
A-linkage Area: linking into static, shared libraries and binaries C-bug Category: This is a bug. O-windows-gnu Toolchain: GNU, Operating system: Windows T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.