-
Notifications
You must be signed in to change notification settings - Fork 13.1k
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
{i386,x86_64}-apple-ios targets pass too many thousands of arguments to the linker #52699
Comments
Hm yes so incremental means that the maximal number of cgus are used, where if you have a crate with N modules it basically translates to N (ish) cgus (afaik at least). As to why that ends up failing the linker... I'm not sure! I could be that an OS limit for the command line is silently blown and while rustc may handle it something else like clang isn't handling it? |
The crate has ~2500 modules when compiled with |
We should switch the argument file ( (This means we apply |
Actually I think this is one of the reasons that this takes so long to compile, we're actually already falling back to an @-file! Enabling some debug logs I get:
I'm not really sure what's going on here :( Maybe we're blowing some limit in the OSX linker? We probably shouldn't be passing thousands of objects anyway |
Not all |
Interesting. macOS's
|
I wonder, why I am hitting this when using |
@kennytm Good spot. This is a guess from a quick look, but it looks like clang puts the first n contiguous filenames into the filelist (response file in its jargon); the remainder are passed as args as normal. My guess is that the filename in As clang and gcc both pass thru the |
Depending on whether those modules contain generic code too, it might even be ~5000 cgus. In theory it should be possible to limit the number of cgus created by incremental compilation, at the expensive of less accurate cache utilization. |
Triage: lots of changes have happened, not sure if this reproduces or not |
Removing rust/compiler/rustc_codegen_ssa/src/back/command.rs Lines 133 to 137 in 33a2c24
|
Also note macOS bumped the limit a lot a few years ago, but recent versions of ld64 also support passing a params file so if we could rely on users having the newer versions that would be fine too |
Make `#[used]` work when linking with `ld64` To make `#[used]` work in static libraries, we use the `symbols.o` trick introduced in rust-lang#95604. However, the linker shipped with Xcode, ld64, works a bit differently from other linkers; in particular, [it completely ignores undefined symbols by themselves](https://github.com/apple-oss-distributions/ld64/blob/ld64-954.16/src/ld/parsers/macho_relocatable_file.cpp#L2455-L2468), and only consider them if they have relocations (something something atoms something fixups, I don't know the details). So to make the `symbols.o` file work on ld64, we need to actually insert a relocation. That's kinda cumbersome to do though, since the relocation must be valid, and hence must point to a valid piece of machine code, and is hence very architecture-specific. Fixes rust-lang#133491, see that for investigation. --- Another option would be to pass `-u _foo` to the final linker invocation. This has the problem that `-u` causes the linker to not be able to dead-strip the symbol, which is undesirable. (If we did this, we would possibly also want to do it by putting the arguments in a file by itself, and passing that file via ``@`,` e.g. ``@undefined_symbols.txt`,` similar to rust-lang#52699, though that [is only supported since Xcode 12](https://developer.apple.com/documentation/xcode-release-notes/xcode-12-release-notes#Linking), and I'm not sure we wanna bump that). Various other options that are probably all undesirable as they affect link time performance: - Pass `-all_load` to the linker. - Pass `-ObjC` to the linker (the Objective-C support in the linker has different code paths that load more of the binary), and instrument the binaries that contain `#[used]` symbols. - Pass `-force_load` to libraries that contain `#[used]` symbols. Failed attempt: Embed `-u _foo` in the object file with `LC_LINKER_OPTION`, akin to rust-lang#121293. Doesn't work, both because `ld64` doesn't read that from archive members unless it already has a reason to load the member (which is what this PR is trying to make it do), and because `ld64` only support the `-l`, `-needed-l`, `-framework` and `-needed_framework` flags in there. --- TODO: - [x] Support all Apple architectures. - [x] Ensure that this works regardless of the actual type of the symbol. - [x] Write up more docs. - [x] Wire up a few proper tests. `@rustbot` label O-apple
Make `#[used]` work when linking with `ld64` To make `#[used]` work in static libraries, we use the `symbols.o` trick introduced in rust-lang#95604. However, the linker shipped with Xcode, ld64, works a bit differently from other linkers; in particular, [it completely ignores undefined symbols by themselves](https://github.com/apple-oss-distributions/ld64/blob/ld64-954.16/src/ld/parsers/macho_relocatable_file.cpp#L2455-L2468), and only consider them if they have relocations (something something atoms something fixups, I don't know the details). So to make the `symbols.o` file work on ld64, we need to actually insert a relocation. That's kinda cumbersome to do though, since the relocation must be valid, and hence must point to a valid piece of machine code, and is hence very architecture-specific. Fixes rust-lang#133491, see that for investigation. --- Another option would be to pass `-u _foo` to the final linker invocation. This has the problem that `-u` causes the linker to not be able to dead-strip the symbol, which is undesirable. (If we did this, we would possibly also want to do it by putting the arguments in a file by itself, and passing that file via ``@`,` e.g. ``@undefined_symbols.txt`,` similar to rust-lang#52699, though that [is only supported since Xcode 12](https://developer.apple.com/documentation/xcode-release-notes/xcode-12-release-notes#Linking), and I'm not sure we wanna bump that). Various other options that are probably all undesirable as they affect link time performance: - Pass `-all_load` to the linker. - Pass `-ObjC` to the linker (the Objective-C support in the linker has different code paths that load more of the binary), and instrument the binaries that contain `#[used]` symbols. - Pass `-force_load` to libraries that contain `#[used]` symbols. Failed attempt: Embed `-u _foo` in the object file with `LC_LINKER_OPTION`, akin to rust-lang#121293. Doesn't work, both because `ld64` doesn't read that from archive members unless it already has a reason to load the member (which is what this PR is trying to make it do), and because `ld64` only support the `-l`, `-needed-l`, `-framework` and `-needed_framework` flags in there. --- TODO: - [x] Support all Apple architectures. - [x] Ensure that this works regardless of the actual type of the symbol. - [x] Write up more docs. - [x] Wire up a few proper tests. `@rustbot` label O-apple
To reproduce:
Produces this output (too long to put it here, gist: https://gist.github.com/gnzlbg/4ff458a32ebd56e4d8930aaf766178b4). Linking fails. This is rust-lang-nursery/packed_simd issue: rust-lang/packed_simd#26
cc @michaelwoerister @alexcrichton this might be related to incremental compilation, I see a lot of rcgus.
The text was updated successfully, but these errors were encountered: