cc 명령어?
다수의 42 과제에서 C 소스 파일을 컴파일할 때 cc 명령어를 사용할 것을 요구합니다.
cc는 POSIX에서 정의한, C를 컴파일하는 명령어입니다.
우리가 자주 쓰는 C 컴파일러
대표적인 C 컴파일러로는 GCC와 Clang이 있습니다.
윈도우는 MinGW와 마이크로소프트의 MSVC도 있지만, MinGW는 GCC로 보고, POSIX를 따르지 않는 마이크로소프트의 MSVC는 논외로 치겠습니다.
GCC와 Clang을 모두 써 보셨다면, 둘의 사용법이 놀랍도록 비슷한 것을 알 수 있습니다.
Clang이 사실상의 표준처럼 쓰여서 GCC처럼 만들려고 했던 것도 있지만, 다른 이유도 있습니다.
필수로 반드시 사용하는 컴파일러 옵션
•
출력 파일 이름을 지정할 때 -o 옵션을 사용하고,
•
소스 파일을 목적 파일로 만들 때 -c 옵션을 사용하고,
•
헤더/라이브러리 디렉터리를 지정하는 데 -I/-L 옵션을 사용하고,
•
링킹할 라이브러리/매크로 상수를 추가할 때 -l/-D 옵션을 사용하고,
•
디버깅용 정보 생성/컴파일러 최적화에는 -g/-O 옵션을 사용하고,
•
... 등등
이런 필수 옵션들이 컴파일러마다 다르다면 컴파일러마다 사용법을 따로 익혀야 할 것입니다.
다행히도 그럴 필요가 없도록 이런 필수 옵션들을 POSIX에서 정의했습니다!
덕분에 어떤 플랫폼이라도 POSIX 환경이라면 실제로 어떤 컴파일러가 쓰일지 모르더라도 안심하고 cc 명령어를 사용해 컴파일할 수 있습니다.
실제로 cc는 어떤 컴파일러일까?
cc라는 컴파일러가 따로 있는 것은 아니고, 단지 규격일 뿐입니다.
보통 macOS에서는 Apple Clang으로, 리눅스에는 GCC를 설치했다면 GCC로 연결됩니다.
물론 POSIX 규격을 따르는 컴파일러이기만 하면 되기 때문에 둘 모두 아닐 수도 있긴 합니다.
cc 명령어 사용 시 알아두면 좋은 것
gcc나 clang과 달리, cc 명령어는 어떤 컴파일러가 실행될지 알 수 없습니다.
알 수 있다면 명시적으로 그 컴파일러를 사용하는 것이 바람직합니다. (gcc나 clang 등)
cc 명령어를 사용할 때는 POSIX에서 정의하지 않은 옵션은 사용하지 않는 것이 바람직합니다.
그런 옵션 중 자주 쓰는 것으로는 -Wall, -fsanitize=address, -g3 등이 있습니다.
대안
-Wall 등은 그 옵션을 지원하는 특정 컴파일러를 사용한다는 것을 명확히 하는 것이 좋습니다.
# POSIX cc에 정의된 옵션만 사용 (O)
cc -c main.c $(CFLAGS)
# POSIX cc에 정의되지 않은 옵션도 사용 (X)
cc -Wall -fsanitize=address -c main.c -o main.o $(CFLAGS)
# 해당 옵션을 지원하는 것이 명확한 컴파일러 지정 (O)
clang -Wall -fsanitize=address -c main.c -o main.o $(CFLAGS)
Shell
복사
그래도... 과제가 요구한다면 어쩔 수 없겠죠...?
c89, c99 명령어
C 표준의 버전이 고정된 c89, c99 명령어도 POSIX에서 정의하고 있습니다.
cc 명령어보다는 c89나 c99 명령어를 쓰는 것이 더 바람직합니다.