我有一个基本的 C 程序:
#include <stdio.h>
int main() {
printf("Hello, world!\n");
}
当我直接使用它编译时cc
在 Apple Silicon 设备上,它会产生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
工具来运行cc
在 x86_64 模式下可执行:
% 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
但是,当前,当您rebuild二进制文件,这在编辑-编译-运行周期中很常见:
% ./hello
zsh: killed ./hello
也可以看看:
- 为什么使用 x86_64 构建系统构建的本机 arm64 应用程序无法进行代码签名,除非我删除以前的可执行文件? https://stackoverflow.com/q/64830671/155423
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)