为什么在Apple Silicon上编译的本机应用程序有时会生成为arm64,有时会生成为x86_64? [英] Why does my native application compiled on Apple Silicon sometimes build as arm64 and sometimes build as x86_64?
问题描述
我有一个基本的C程序:
I have a basic C program:
#include <stdio.h>
int main() {
printf("Hello, world!\n");
}
当我在Apple Silicon设备上直接使用 cc
进行编译时,它会生成一个 arm64
可执行文件:
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!
但是,当我通过CMake或Ninja之类的构建系统对其进行构建时,它会生成x86_64二进制文件:
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
我已经验证了构建脚本正在运行的命令与我自己运行的命令相同.如果我复制并粘贴命令并自己运行,则生成的可执行文件还是arm64.
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.
推荐答案
当您的构建命令不包含要为其构建体系结构的特定标志时,Apple提供的编译器工具,例如 cc
,根据调用过程的体系结构进行某种自省.这意味着,如果尚未为 arm64
进行本机编译,则可能会看到此行为,因为编译器会假定您要针对x86_64进行编译!
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!
您可以通过使用 arch
工具在x86_64模式下运行 cc
可执行文件来进行演示:
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
作为一种变通办法,您可以引入一个总是重置为本机体系结构的填充程序编译器.将其另存为 force-arm64-cc
并使其可执行:
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 "$@"
然后您可以使用此垫片代替 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
另请参阅:
这篇关于为什么在Apple Silicon上编译的本机应用程序有时会生成为arm64,有时会生成为x86_64?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!