Apple Silicon에서 컴파일 된 기본 애플리케이션이 때때로 arm64로 빌드되고 때로는 x86_64로 빌드되는 이유는 무엇입니까?
기본 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
:)는 호출 프로세스 의 아키텍처를 기반으로 일종의 내부 검사를 수행 합니다 . 즉, 빌드 시스템이 아직 .NET 용으로 네이티브 컴파일되지 않은 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 "$@"
그런 다음이 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 애플리케이션이 이전 실행 파일을 제거하지 않으면 코드 서명에 실패하는 이유는 무엇입니까?