C언어 컴파일 과정

기술노트
Admin (토론 | 기여)님의 2025년 4월 21일 (월) 14:03 판

C 언어 컴파일 과정

C 언어로 작성된 소스 코드는 여러 단계를 거쳐 컴퓨터가 이해할 수 있는 실행 가능한 바이너리 파일로 변환됩니다. 이 과정은 일반적으로 다음과 같은 4단계로 나뉘며, 대표적인 컴파일러인 `gcc`를 기준으로 설명합니다.


위와 같은 단계를 통해 생성된 실행 파일은 메모리(RAM)에 적재되어 운영체제 상에서 실제로 동작하게 됩니다.


1. 전처리 (Preprocessing)

- `#include` 지시문에 따라 헤더 파일의 내용을 삽입합니다. - `#define`, `#ifdef`, `#ifndef` 등 매크로를 해석하고 코드에 적용합니다. - 주석 제거 및 조건부 컴파일 처리도 이 과정에서 수행됩니다.

→ 전처리 결과는 확장자가 `.i`인 중간 코드로 저장됩니다.


2. 컴파일 (Compilation)

전처리된 코드를 기반으로 어셈블리 코드로 변환하는 단계이며, 내부적으로는 세부적인 세 단계로 구성됩니다:

  • 전단부 (Front-end):
 - 어휘 분석(Lexical Analysis), 구문 분석(Syntax Analysis), 의미 분석(Semantic Analysis)을 수행합니다.  
 - 주로 문법 오류를 탐지하는 역할을 합니다.
  • 중단부 (Middle-end):
 - SSA(Static Single Assignment) 형태로 변환 후 다양한 최적화를 수행합니다.  
 - 실행 성능을 개선하기 위한 중간 코드 최적화가 이루어집니다.
  • 후단부 (Back-end):
 - 대상 시스템 아키텍처에 맞게 최적화된 어셈블리 코드로 변환합니다.  
 - 불필요한 연산 제거, 명령어 재배치 등을 통해 실행 효율을 극대화합니다.

→ 결과는 `.s` 확장자의 어셈블리 코드 파일입니다.


3. 어셈블 (Assembling)

어셈블리 코드를 기계어(Object Code)로 번역하는 단계입니다.

- 어셈블러는 `.s` 파일을 받아 `.o` 확장자의 오브젝트 파일(Object File)로 변환합니다. - 생성된 오브젝트 파일은 **ELF(Executable and Linkable Format)** 구조를 따르며, 명령어와 데이터가 일정한 규칙으로 정렬되어 있습니다. - 이 구조는 나중에 링커가 여러 오브젝트 파일과 라이브러리를 효과적으로 결합할 수 있도록 돕습니다.


4. 링킹 (Linking)

- 여러 개의 오브젝트 파일(.o)과 라이브러리(.lib/.a)를 결합하여 하나의 실행 파일을 만듭니다. - 함수 호출, 전역 변수 참조 등 서로 연결되지 않은 심볼(Symbol)을 해결합니다. - 동적 라이브러리를 사용하는 경우 해당 정보를 실행 파일에 포함시킵니다.

→ 최종 결과물은 확장자가 `.out`, `.exe`, 또는 사용자 정의 이름의 실행 파일입니다.


요약

단계 입력 파일 출력 파일 주요 도구
전처리 hello.c hello.i cpp
컴파일 hello.i hello.s cc1
어셈블 hello.s hello.o as
링킹 hello.o a.out (또는 지정 이름) ld


관련 링크