rust-lang / cc-rs

Rust library for build scripts to compile C/C++ code into a Rust library
https://docs.rs/cc
Apache License 2.0
1.84k stars 442 forks source link

cc 0.89 causes build failures, when building rustls on macos arm #989

Closed TimotheeIsnard closed 1 month ago

TimotheeIsnard commented 7 months ago

Hello,

We're building a small rust crate for ios, for the aarch64-apple-ios-sim and x86_64-apple-ios targets, on a macos arm host.

Because this is for iOS, we create a "fat" static library using macOS's lipo tool, like so:

lipo -create -output myrustlib.a target/aarch64-apple-ios-sim/debug/myrustlib.a target/x86_64-apple-ios/debug/myrustlib.a

This works with rustls v0.21.10 and cc 1.0.88, but started failing with cc 1.0.89 with the following error:

fatal error: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/lipo: archive member target/x86_64-apple-ios/debug/myrustlib.a(fad98b632b8ce3cc-curve25519.o) cputype (16777228) and cpusubtype (0) does not match previous archive members cputype (16777223) and cpusubtype (3) (all members must match)

Looking at the last few cc commits, it's not clear to me what could have caused this change in behavior, but the problem evidently disappears when we pin cc = "=1.0.88" in Cargo.toml.

Unfortunately I don't have a minimal repro I can submit at the moment, but submitting for your consideration, and in case someone else runs into the same issue.

NobodyXu commented 7 months ago

I suspect it is #873 that caused this.

Can you do a bisect on cc please?

TimotheeIsnard commented 7 months ago

Bisect seems to agree

git bisect start
# status: waiting for both good and bad commits
# bad: [b1c53ad938003c03ba72bdfe8e5aa93d00231a99] Release cc 1.0.89 (#988)
git bisect bad b1c53ad938003c03ba72bdfe8e5aa93d00231a99
# status: waiting for good commit(s), bad commit known
# good: [561543c5f0f3f4efed4e97844f89c8b424e19d3e] Release cc 1.0.88 (#977)
git bisect good 561543c5f0f3f4efed4e97844f89c8b424e19d3e
# bad: [2f587f5561fb9c3c02e5c9e186b2bea98691608a] Also support finding Windows tools on non-Windows host (#907)
git bisect bad 2f587f5561fb9c3c02e5c9e186b2bea98691608a
# bad: [59581e55a40678494e5b52b08fe2677a717bf8d8] Update windows-bindgen requirement from 0.53 to 0.54 (#982)
git bisect bad 59581e55a40678494e5b52b08fe2677a717bf8d8
# bad: [f0153a49733a83074d3df9984705f8a346e1b381] refactor target flags (#873)
git bisect bad f0153a49733a83074d3df9984705f8a346e1b381
# first bad commit: [f0153a49733a83074d3df9984705f8a346e1b381] refactor target flags (#873)
NobodyXu commented 7 months ago

Opened #992 , can you test that please?

NobodyXu commented 7 months ago

Also, it would be great if you have a minimal reproduction, so that I can add a regression test to prevent it from happening again

TimotheeIsnard commented 7 months ago

992 works, thank you. Looking into a repro.

TimotheeIsnard commented 7 months ago

Here's a repro tested on a mac M1, running Sonoma 14.3.1, latest XCode, cargo 1.76.0 (stable).

Cargo.toml:

[package]
name = "cc-rs-repro"
version = "0.1.0"
edition = "2021"

[dependencies]
reqwest = { version = "0.11", features = ["rustls-tls"], default-features = false }
tokio = "1"
cc = "=1.0.89"

[lib]
name = "repro"
crate-type = ["staticlib"]

lib.rs

pub extern "C" fn repro() {
    let rt = tokio::runtime::Builder::new_current_thread()
        .enable_all()
        .build()
        .unwrap();
    rt.block_on(async {
        reqwest::Client::new()
            .post("example.org")
            .send()
            .await
            .unwrap();
    })
}

Steps:

rustup target add x86_64-apple-ios aarch64-apple-ios-sim
cargo build --target x86_64-apple-ios
cargo build --target aarch64-apple-ios-sim
lipo -create -output librepro.a target/aarch64-apple-ios-sim/debug/librepro.a target/x86_64-apple-ios/debug/librepro.a

Result when repro successful:

fatal error: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/lipo: archive member target/x86_64-apple-ios/debug/librepro.a(fad98b632b8ce3cc-curve25519.o) cputype (16777228) and cpusubtype (0) does not match previous archive members cputype (16777223) and cpusubtype (3) (all members must match)
NobodyXu commented 7 months ago

Thanks, I will look into to it to see if it can be further simplified.

TimotheeIsnard commented 7 months ago

I've managed to simplify it further (if you haven't already, in case that might saves you some time)

pub extern "C" fn repro() {
    use ring::agreement;
    let rng = ring::rand::SystemRandom::new();
    agreement::EphemeralPrivateKey::generate(&agreement::X25519, &rng).unwrap();
}
cargo build --target x86_64-apple-ios
objdump target/x86_64-apple-ios/debug/librepro.a -h | grep arm64

On 1.0.88, this gives no output. A successful repro looks like:

target/x86_64-apple-ios/debug/librepro.a(fad98b632b8ce3cc-curve25519.o):    file format mach-o arm64
target/x86_64-apple-ios/debug/librepro.a(ca4b6ef5433f5aeb-aes_nohw.o):  file format mach-o arm64
[...]

I haven't looked what in ring exactly triggers the issue, but at least no need to pull all of reqwest and rusttls, I suppose.

NobodyXu commented 7 months ago

Thanks, that will help a lot!

stormshield-gt commented 1 month ago

Which version of ring are you using, the 0.16 or the 0.17 ?

stormshield-gt commented 1 month ago

For what it's worth, I've created a minimum repo where I can reproduce the bug in CI here.

Note: I confirm it also happen in ring 0.17

NobodyXu commented 1 month ago

Thanks, does it reproduce on latest cc?

stormshield-gt commented 1 month ago

No it works with latest cc

NobodyXu commented 1 month ago

That's good to hear!

Since it works with latest cc, I will close this issue then