gcc는 C, C++, objective-c, fortran 등 여러 언어를 컴파일 할 수 있다. 1999년부터 gcc는 자유 소프트웨어 재단에서 지원하는 컴파일러의 집합을 의미하기 때문이다. (그 전까지는 GNU C Compiler라고 지정하였었다.) 그 와중에도 우리는 C언어를 컴파일하기 위해 이용한다. 그래서 이 글도 C언어를 기준으로 설명하겠다.
gcc를 컴파일러라고 일반적으로 이야기한다. 그런데 정확히 말하면 gcc는 소스 파일을 이용해 실행 파일을 만들 때까지 필요한 다음과 같은 프로그램을 차례로 실행하는 일종의 툴이다.
cpp | 전처리기
cc1 | 컴파일러
as | 어셈블러
ld |링커
그리고 GCC는 이러한 프로그램을 다음과 같은 순서로 동작시킨다.
gcc는 소스 파일을 cpp로 전처리하고, cc1으로 컴파일하고, as로 어셈블링, ld로 링크해서 실행 파일인 a.out을 만들어낸다. 이 각 단계가 어떤 식인지를 file.c라는 소스코드를 처리한다고 가정하고 진행해 보겠다.
- 전처리 단계
우선 소스파일에 gcc를 동작 시키면 가장 먼저 전처리기인 cpp가 동작한다.
cpp는 소스 파일의 #include와 #define과 같은 전처리기 부분을 처리한다. 즉, 필요한 헤더 파일을 삽입하고 실행 문장의 매크로를 상수로 반환하여둔다. 소스 파일이 전처리기를 거치면 file.i라는 이름의 파일이 생성되지만 디스크에는 저장되지 않는다.
- 컴파일 단계
컴파일러가 전처리된 파일로부터 어셈블리어로 된 파일을 생성한다.
생성된 파일은 file.s이다. 이 파일도 보통은 디스크에 저장되진 않는다.
- 어셈블 단계
어셈블리어로 된 파일을 기계가 직접 이해할 수 있는 오브젝트 파일로 변환한다.
오브젝트 파일(file.o)은 디스크에 생기기도 한다.
- 링크 단계
오브젝트 파일은 기본적으로 라이브러리 함수(printf, scanf 등)에 해당하는 코드가 없다. 그래서 실행을 할수 없다. 또한 여러 파일로 이루어진 프로그램의 경우에도 파일 간의 연결 과정이 이루어져 있지 않기 때문에 실행을 할 수 없다. 이러한 라이브러리 함수나 다른 오브젝트 파일들을 연결해주는 작업이 링크 단계이다.
링크 단계가 진행되어야 실행 가능한 파일이 생성된다.
컴파일을 하는 각각의 단계에 대해서 간단한 설명을 진행하였는데, 각 단계별 옵션을 사용해서 얼마나 진행되었는지 그 상화을 볼 수 있게 수동으로도 제어가 가능하다. 이를 위해서는 gcc의 옵션들을 알아야 하는데, 나중 글에서 다루기로 하겠다.
“103 – GCC의 동작 과정”의 한가지 생각