-
Notifications
You must be signed in to change notification settings - Fork 4.4k
Objc transition can swap architecture, leading to link failure #19204
Description
Description of the bug:
Hi wonderful Bazelers,
I stumbled across an edge case where Bazel gets confused about the target architecture on macOS, causing linking to fail.
More explicitly (and for searchability), one ends up with a link line that mixes arm64 and x86_64 archives, leading to errors like the following
ld: warning: ignoring file bazel-out/applebin_macos-darwin_**x86_64**-fastbuild-ST-79db1517e854/bin/lib.a, building for macOS-arm64 but attempting to link with file built for macOS-x86_64
Which turns into an undefined symbols error, breaking the build:
Undefined symbols for architecture arm64: for whatever was in the mistakenly x86_64 archive.
Which category does this issue belong to?
Objc (but I didn't see that in the dropdown--maybe C++ if the ObjC<>C++ intersection is considered a subset.)
What's the simplest, easiest way to reproduce this bug? Please provide a minimal example if possible.
The easiest way to reproduce the problem is to point a cc_binary -> cc_library -> objc_library, having set up compilation for Apple platforms per rules_apple, and passing in the right ordering of architectures to --macos_cpus
Here's a minimal reproduction for Apple Silicon Macs:
linkingArchIssue.zip
Just grab it and bazel build :main to reproduce the linking issue.
If you're on Intel, I suspect you can reproduce by passing --macos_cpus=arm64,x86_64 instead of --macos_cpus=x86_64,arm64.
Note that this isn't a particularly contrived case, just a minimized one. It's easy to run into it this way creating test binaries.
Which operating system are you running Bazel on?
macOS 13.4.1
What is the output of bazel info release?
release 7.0.0-pre.20230724.1 (latest rolling)
Regression, Cross References
Since it's dependent on passing --macos_cpus in the right order and has to do with the the cc -> objc transition, I'm guessing this issue has to do with selecting the first macOS CPU in //src/main/starlark/builtins_bzl/common/objc/transitions.bzl
See https://github.com/bazelbuild/bazel/pull/14816/files, where that line return macos_cpus[0] was introduced, fixing the related #14803 -- and I suspect narrowing it down to this one.
@keith, sorry to tag you, but since you've been working in there, does that seem like the right source of the issue? I think you're better positioned than me: Do you know how to correctly get the CPU corresponding to the top level platform from there?
(And do you think the other, similar cases *_cpus[0] cases for other platforms might case similar issues in tests?)
Thanks so much, all.
Chris