为什么在Apple Silicon上编译的本机应用程序有时会生成为arm64,有时会生成为x86_64? [英] Why does my native application compiled on Apple Silicon sometimes build as arm64 and sometimes build as x86_64?

查看:96
本文介绍了为什么在Apple Silicon上编译的本机应用程序有时会生成为arm64,有时会生成为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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆