Why does my native application compiled on Apple Silicon sometimes build as arm64 and sometimes build as x86_64?

孤街浪徒 提交于 2020-12-06 06:48:25

问题


I have a basic C program:

#include <stdio.h>

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

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!

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

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.


回答1:


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!

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

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 "$@"

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

See also:

  • Why does my native arm64 application built using an x86_64 build system fail to be code signed unless I remove the previous executable?


来源:https://stackoverflow.com/questions/64830635/why-does-my-native-application-compiled-on-apple-silicon-sometimes-build-as-arm6

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!