기타 Lobsters · 2026-10-22

맥북에서 gcc 치면 왜 clang이 뜰까? 바이너리 까본 개발자

핵심 요약
  • macOS의 /usr/bin/gcc는 단순 별칭이 아니라 바이너리 파일이며, 디스어셈블 결과 xcrun을 통해 실제 도구를 호출하는 래퍼 역할을 하고 있었습니다.
  • 실제 도구 경로의 gcc 바이너리 역시 내부적으로 다시 xcrun을 거쳐 최종적으로 clang이나 clang++을 실행하는 다중 래핑 구조를 띠고 있습니다.
  • 이는 macOS의 SIP(시스템 무결성 보호) 제약을 우회해 재부팅 없이 Xcode 개발 도구를 업데이트하고 경로를 유연하게 관리하기 위한 설계로 추정됩니다.
요약 macOS 환경에서 C나 C++ 코딩을 해본 개발자라면 터미널에 `gcc`를 입력했을 때 실제로는 GCC가 아니라 Clang이 실행되는 현상을 흔히 겪어봤을 것입니다. 대다수 사용자는 이를 단순한 셸 별칭(alias)이나 심볼릭 링크 정도로 생각하지만, 실제로 `/usr/bin/gcc`의 정체를 확인해 보면 엄연한 바이너리 파일입니다. 작성자가 이 바이너리를 디스어셈블러로 열어 분석한 결과, 단순히 Clang을 셸 명령어로 호출하는 수준을 넘어선 흥미로운 구조가 드러났습니다. 내부 코드에는 실행 파일 이름을 확인해 `llvm-gcc`나 `c++` 같은 이름으로 호출되었는지 검사하는 분기 로직이 들어 있었으며, 최종적으로는 `libxcselect.dylib`의 `xcselect_invoke_xcrun()` 함수를 호출하고 있었습니다. 이는 사실상 터미널 명령어인 `xcrun`을 실행하는 것과 같은 동작입니다. 실제로 Xcode가 설치하는 대부분의 개발자 도구 바이너리 역시 동일한 방식으로 `xcrun`을 거치도록 설계되어 있습니다. 그렇다면 `xcrun`이 실제로 호출하는 바이너리는 어디에 있을까요? `xcrun --find gcc` 명령어로 추적해 보면 `/Library/Developer/CommandLineTools/usr/bin/gcc`라는 실제 위치가 나옵니다. 해당 디렉터리를 살펴보면 `c++`이나 `llvm-gcc` 등은 아예 존재하지 않아 상위 바이너리에 하드코딩되어 있던 것이며, `cc`나 `clang++`은 `clang`을 가리키는 별칭이었습니다. 더욱 흥미로운 점은 그곳에 있던 실제 `gcc` 바이너리를 다시 디스어셈블해 보았을 때입니다. 이 바이너리는 내부에서 `/usr/bin/xcrun`을 다시 실행하며, 인자에 따라 `clang` 또는 `clang++`을 호출하는 구조를 취하고 있었습니다. 작성자는 애플이 이처럼 번거로운 우회 구조를 만든 이유로 SIP(시스템 무결성 보호)를 꼽았습니다. `/usr/bin`은 시스템 보호 디렉터리여서 재부팅 없이 업데이트하기 어렵기 때문에, 재부팅 없이도 Xcode 개발자 도구를 업데이트할 수 있도록 실제 도구는 별도 디렉터리에 두고 래퍼 바이너리를 통해 호출하도록 만들었다는 분석입니다. 또한 해당 디렉터리를 단순히 PATH 환경변수에 추가하지 않은 이유는 애플이 필요에 따라 개발자 도구 디렉터리 구조를 자유롭게 변경하기 위함일 것이라고 추측했습니다.
Sponsored · 광고