问题
I have a basic C program:
#include <stdio.h>
int main() {
printf("Hello, world!\n");
}
When I compile this directly using cc
on an Apple Silicon device, it produces an arm64
executable:
% cc hello.c -o hello
% file hello
hello: Mach-O 64-bit executable arm64
% ./hello
Hello, world!
However, when I build it through a build system such as CMake or Ninja, it produces an x86_64 binary:
% ./my-build-system
% file hello
hello: Mach-O 64-bit executable x86_64
I've verified that the command that the build script is running is identical to the one that I run myself. If I copy and paste the command and run it myself, the produced executable is again arm64.
回答1:
When your build command doesn't include specific flags for which architecture to build for, the compiler tools provided by Apple, like cc
, perform some kind of introspection based on the architecture of the calling process. That means that if your build system has yet to be natively compiled for arm64
, you might see this behavior as the compiler will assume you want to build for x86_64!
You can demonstrate this by using the arch
tool to run the cc
executable in x86_64 mode:
% arch -x86_64 cc hello.c -o hello
% file hello
hello: Mach-O 64-bit executable x86_64
As a work-around, you can introduce a shim compiler that always resets to the native architecture. Save this as force-arm64-cc
and make it executable:
#!/usr/bin/env bash
# Note we are using arm64e because `cc` does not have an arm64 binary!
exec arch -arm64e cc "$@"
You can then use this shim in place of cc
:
% CC=$PWD/force-arm64-cc ./my-build-system
% file hello
hello: Mach-O 64-bit executable arm64
The correct long term solution is to specify the target architecture when compiling:
% arch -x86_64 cc -arch arm64 hello.c -o hello
% file hello
hello: Mach-O 64-bit executable arm64
However, this currently produces a bogus executable when you rebuild the binary, which is quite common in an edit-compile-run cycle:
% ./hello
zsh: killed ./hello
See also:
- Why does my native arm64 application built using an x86_64 build system fail to be code signed unless I remove the previous executable?
来源:https://stackoverflow.com/questions/64830635/why-does-my-native-application-compiled-on-apple-silicon-sometimes-build-as-arm6