[英]Why does my native application compiled on Apple Silicon sometimes build as arm64 and sometimes build as x86_64?
I have a basic C program:我有一个基本的 C 程序:
#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:当我在 Apple Silicon 设备上直接使用
cc
编译它时,它会生成一个arm64
可执行文件:
% 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:但是,当我通过诸如 CMake 或 Ninja 之类的构建系统构建它时,它会生成一个 x86_64 二进制文件:
% ./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.
如果我复制并粘贴命令并自己运行它,则生成的可执行文件又是 arm64。
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 .当您的构建命令不包含要构建的架构的特定标志时,Apple 提供的编译器工具(如
cc
根据调用进程的架构执行某种自省。 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!这意味着,如果您的构建系统尚未针对
arm64
进行本机编译,您可能会看到这种行为,因为编译器会假设您要针对 x86_64 进行构建!
You can demonstrate this by using the arch
tool to run the cc
executable in x86_64 mode:您可以通过使用
arch
工具在 x86_64 模式下运行cc
可执行文件来证明这一点:
% 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.作为一种变通方法,您可以引入一个始终重置为本机架构的 shim 编译器。 Save this as
force-arm64-cc
and make it executable:将其保存为
force-arm64-cc
并使其可执行:
#!/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
:
% 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:也可以看看:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.