Apple Silicon에서 컴파일 된 기본 애플리케이션이 때때로 arm64로 빌드되고 때로는 x86_64로 빌드되는 이유는 무엇입니까?

Nov 14 2020

기본 C 프로그램이 있습니다.

#include <stdio.h>

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

ccApple 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입니다.

답변

3 Shepmaster Nov 14 2020 at 10:22

빌드 명령에 빌드 할 아키텍처에 대한 특정 플래그가 포함되지 않은 경우 Apple에서 제공하는 컴파일러 도구 (예 cc:)는 호출 프로세스 의 아키텍처를 기반으로 일종의 내부 검사를 수행 합니다 . 즉, 빌드 시스템이 아직 .NET 용으로 네이티브 컴파일되지 않은 arm64경우 컴파일러가 x86_64 용으로 빌드하려고한다고 가정하므로이 동작을 볼 수 있습니다!

arch도구를 사용하여 ccx86_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 "$@"

그런 다음이 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

또한보십시오:

  • x86_64 빌드 시스템을 사용하여 빌드 된 기본 arm64 애플리케이션이 이전 실행 파일을 제거하지 않으면 코드 서명에 실패하는 이유는 무엇입니까?