【问题标题】:Why does my native application compiled on Apple Silicon sometimes build as arm64 and sometimes build as x86_64?为什么我在 Apple Silicon 上编译的本机应用程序有时构建为 arm64,有时构建为 x86_64?
【发布时间】:2021-02-26 00:50:46
【问题描述】:

我有一个基本的 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。

【问题讨论】:

    标签: c++ c macos native apple-silicon


    【解决方案1】:

    当您的构建命令不包含要构建的架构的特定标志时,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 "$@"
    

    然后您可以使用此 shim 代替 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
    

    另见:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-06-15
      • 2021-01-03
      • 2021-12-29
      • 2015-03-18
      • 2022-01-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多