繁体   English   中英

为什么我在 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 程序:

#include <stdio.h>

int main() {
  printf("Hello, world!\n");
}

当我在 Apple Silicon 设备上直接使用cc编译它时,它会生成一个arm64可执行文件:

% cc hello.c -o hello

% file hello
hello: Mach-O 64-bit executable arm64

% ./hello
Hello, world!

但是,当我通过诸如 CMake 或 Ninja 之类的构建系统构建它时,它会生成一个 x86_64 二进制文件:

% ./my-build-system

% file hello
hello: Mach-O 64-bit executable x86_64

我已经验证构建脚本运行的命令与我自己运行的命令相同。 如果我复制并粘贴命令并自己运行它,则生成的可执行文件又是 arm64。

当您的构建命令不包含要构建的架构的特定标志时,Apple 提供的编译器工具(如cc根据调用进程的架构执行某种自省。 这意味着,如果您的构建系统尚未针对arm64进行本机编译,您可能会看到这种行为,因为编译器会假设您要针对 x86_64 进行构建!

您可以通过使用arch工具在 x86_64 模式下运行cc可执行文件来证明这一点:

% arch -x86_64 cc hello.c -o hello

% file hello
hello: Mach-O 64-bit executable x86_64

作为一种变通方法,您可以引入一个始终重置为本机架构的 shim 编译器。 将其保存为force-arm64-cc并使其可执行:

#!/usr/bin/env bash

# Note we are using arm64e because `cc` does not have an arm64 binary!
exec arch -arm64e cc "$@"

然后,您可以使用此垫片代替cc

% CC=$PWD/force-arm64-cc ./my-build-system

% file hello
hello: Mach-O 64-bit executable arm64

正确的长期解决方案是在编译时指定目标架构:

% arch -x86_64 cc -arch arm64 hello.c -o hello

% file hello
hello: Mach-O 64-bit executable arm64

但是,当您重建二进制文件时,这当前会生成一个伪造的可执行文件,这在编辑-编译-运行循环中很常见:

% ./hello
zsh: killed     ./hello

也可以看看:

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM