-
Notifications
You must be signed in to change notification settings - Fork 12.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Cannot link to Apple universal (fat) libraries #55235
Labels
O-macos
Operating system: macOS
Comments
11 tasks
I spent some time digging into this: An important note is that the error only reproduces if you are linking a fat The full relevant places in the code are:
|
This was referenced Jun 26, 2022
bors
added a commit
to rust-lang-ci/rust
that referenced
this issue
Oct 5, 2022
resolve error when attempting to link a universal library on macOS Previously attempting to link universal libraries into libraries (but not binaries) would produce an error that "File too small to be an archive". This works around this by invoking `lipo -thin` to extract a library for the target platform when passed a univeral library. Fixes rust-lang#55235 It's worth acknowledging that this implementation is kind of a horrible hack. Unfortunately I don't know how to do anything better, hopefully this PR will be a jumping off point.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I have started modifying a few Rust "-sys" crates to point to some prebuilt C libraries that I currently share between my C and Rust code. For macOS and iOS, my prebuilt libraries are merged into universal libraries, with multiple architectures contained in the same .a static libraries.
For instance, when trying to link against a universal libcurl.a library for iOS, I get the following error:
failed to add native library /opt/wayk/sdk/iOS/curl/lib/libcurl.a: File too small to be an archive
The only other mention of such an issue is #50220 but it was meant to fix an issue with compiling Rust, not adding proper support for linking to universal binaries from Rust crates.
For macOS, I could "fix" the issue because we have recently deprecated support for i386 in our prebuilt libraries, and managed to make single-arch x86_64 libraries. Only non-universal binaries work, a universal binary with a single architecture won't work. I had to modify my scripts to avoid calling lipo to merge multiple libraries if there was only one architecture to "merge" and end up with non-universal binaries.
One possible workaround would be to process libraries to be linked such that "lipo -thin" is called to extract single-arch non-universal libraries to a temporary location and then pass those libraries to the linker. It may not be the cleanest patch, but it could work well without much changes.
The exact line throwing the error can be found here:
https://github.com/rust-lang/llvm/blob/caddcd9b9dc9479a20908d93c3e47c49b021379e/lib/Object/Archive.cpp#L554
For reference, I took a screenshot of the first few bytes of a thin library and a fat library. The macOS thin library can be seen on the left with the magic number "CAFEBABE". The iOS fat library can be seen on the right the with magic string "
!<arch>
". The code throwing the error checks for the "!<arch>
" magic string, so the first step to try to add code specific to universal binaries would be to handle files with the "CAFEBABE" magic number differently.The relevant documentation for the universal binary format can be found here:
http://math-atlas.sourceforge.net/devel/assembly/MachORuntime.pdf#//apple_ref/doc/uid/20001298/TPXREF130
The text was updated successfully, but these errors were encountered: