Skip to content
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

Closed
awakecoding opened this issue Oct 20, 2018 · 1 comment · Fixed by #98736
Closed

Cannot link to Apple universal (fat) libraries #55235

awakecoding opened this issue Oct 20, 2018 · 1 comment · Fixed by #98736
Labels
O-macos Operating system: macOS

Comments

@awakecoding
Copy link

awakecoding commented Oct 20, 2018

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.

libcurl_fat_thin

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

@alex
Copy link
Member

alex commented Jun 26, 2022

I spent some time digging into this:

An important note is that the error only reproduces if you are linking a fat .a into a Rust library. If you like it into a Rust binary it'll actually work fine. I assume (without evidence) this is because the former need to get embedded into an rlib while the latter are passed directly to the system linker.

The full relevant places in the code are:

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.
@bors bors closed this as completed in c65c362 Oct 5, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
O-macos Operating system: macOS
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants