C언어 컴파일 과정: 두 판 사이의 차이
기술노트
편집 요약 없음 |
편집 요약 없음 |
||
1번째 줄: | 1번째 줄: | ||
==== C언어 컴파일 과정 ==== | ==== C언어 컴파일 과정 ==== | ||
C언어로 작성된 소스 코드가 실제 실행 가능한 프로그램이 되기까지 과정을 알아보자. | C언어로 작성된 소스 코드가 실제 실행 가능한 프로그램이 되기까지 과정을 알아보자.<br> | ||
[[파일:Compilation_process.png|center|500px]] | |||
이러한 일련의 과정을 거치면서 '''결과물은 컴퓨터가 이해할 수 있는 바이너리 파일'''로 만들어진다. | |||
이 바이너리 파일은 메모리(RAM)에 적재되어 시스템에서 실행된다. | 이 바이너리 파일은 메모리(RAM)에 적재되어 시스템에서 실행된다. | ||
=== 1. 전처리(Preprocessing) 과정 === | === 1. 전처리(Preprocessing) 과정 === | ||
20번째 줄: | 18번째 줄: | ||
* `#define`, `#ifdef` 등 매크로 명령어를 처리하거나 조건부 컴파일을 수행한다. | * `#define`, `#ifdef` 등 매크로 명령어를 처리하거나 조건부 컴파일을 수행한다. | ||
→ | → '''완성된 소스 코드가 준비되는 단계'''이다.<br> | ||
=== 2. 컴파일(Compilation) 과정 === | |||
전처리가 끝난 소스 파일을 '''기계어로 변환하기 위한 중간 코드'''로 바꾸는 과정이다. | |||
보통 컴파일 과정은 내부적으로 세 단계로 나뉜다. | 보통 컴파일 과정은 내부적으로 세 단계로 나뉜다. | ||
42번째 줄: | 39번째 줄: | ||
→ 이 과정을 거쳐 '''어셈블리 코드'''가 생성된다. | → 이 과정을 거쳐 '''어셈블리 코드'''가 생성된다. | ||
=== 3. 어셈블(Assembling) 과정 === | === 3. 어셈블(Assembling) 과정 === | ||
* 어셈블러(Assembler)가 어셈블리 코드를 읽어 | * 어셈블러(Assembler)가 어셈블리 코드를 읽어 '''기계어(Object 파일)'''로 변환한다. | ||
* 생성된 오브젝트 파일은 보통 '''ELF 포맷'''(Executable and Linkable Format) 구조를 가진다. | * 생성된 오브젝트 파일은 보통 '''ELF 포맷'''(Executable and Linkable Format) 구조를 가진다. | ||
> ELF 포맷: | > ELF 포맷: | ||
> - 명령어 코드 영역과 데이터 영역을 명확하게 구분해 놓은 파일 구조 | > - 명령어 코드 영역과 데이터 영역을 명확하게 구분해 놓은 파일 구조 | ||
> - 나중에 링커가 여러 오브젝트 파일을 쉽게 연결할 수 있게 도와준다. | > - 나중에 링커가 여러 오브젝트 파일을 쉽게 연결할 수 있게 도와준다. | ||
=== 4. 링킹(Linking) 과정 === | === 4. 링킹(Linking) 과정 === | ||
* 여러 오브젝트 파일(.o)과 프로그램에서 사용된 라이브러리 파일을 | * 여러 오브젝트 파일(.o)과 프로그램에서 사용된 라이브러리 파일을 '''하나로 묶는 작업'''이다. | ||
* 링커가 심볼(함수나 변수 이름)을 연결해서 최종 실행 파일을 만든다. | * 링커가 심볼(함수나 변수 이름)을 연결해서 최종 실행 파일을 만든다. | ||
> 링킹 결과: | > 링킹 결과: | ||
> - 완성된 실행파일 (.out, .exe 등)이 만들어진다. | > - 완성된 실행파일 (.out, .exe 등)이 만들어진다. | ||
> - 이제 이 파일은 운영체제에서 실행할 수 있다. | > - 이제 이 파일은 운영체제에서 실행할 수 있다. | ||
2025년 4월 26일 (토) 13:24 기준 최신판
C언어 컴파일 과정
C언어로 작성된 소스 코드가 실제 실행 가능한 프로그램이 되기까지 과정을 알아보자.
이러한 일련의 과정을 거치면서 결과물은 컴퓨터가 이해할 수 있는 바이너리 파일로 만들어진다.
이 바이너리 파일은 메모리(RAM)에 적재되어 시스템에서 실행된다.
1. 전처리(Preprocessing) 과정
전처리기는 소스 코드를 컴파일하기 전에 코드를 확장하고 정리하는 작업을 한다.
- `#include` 구문을 만나면, 헤더 파일의 내용을 소스 코드에 그대로 삽입한다.
- `#define`, `#ifdef` 등 매크로 명령어를 처리하거나 조건부 컴파일을 수행한다.
→ 완성된 소스 코드가 준비되는 단계이다.
2. 컴파일(Compilation) 과정
전처리가 끝난 소스 파일을 기계어로 변환하기 위한 중간 코드로 바꾸는 과정이다.
보통 컴파일 과정은 내부적으로 세 단계로 나뉜다.
- 전단부 (Front-end):
- 문법 검사 (어휘 분석, 구문 분석, 의미 분석) - 오류가 있을 경우 이 단계에서 컴파일 에러 발생
- 중단부 (Middle-end):
- 프로그램을 최적화 (SSA 기반 최적화) - 코드 실행 속도를 빠르게 하기 위해 불필요한 연산 제거 등 처리
- 후단부 (Back-end):
- 타겟 CPU 구조에 맞춰 아키텍처 최적화 - 실제 명령어 세트로 변환 (x86, ARM 등)
→ 이 과정을 거쳐 어셈블리 코드가 생성된다.
3. 어셈블(Assembling) 과정
- 어셈블러(Assembler)가 어셈블리 코드를 읽어 기계어(Object 파일)로 변환한다.
- 생성된 오브젝트 파일은 보통 ELF 포맷(Executable and Linkable Format) 구조를 가진다.
> ELF 포맷:
> - 명령어 코드 영역과 데이터 영역을 명확하게 구분해 놓은 파일 구조
> - 나중에 링커가 여러 오브젝트 파일을 쉽게 연결할 수 있게 도와준다.
4. 링킹(Linking) 과정
- 여러 오브젝트 파일(.o)과 프로그램에서 사용된 라이브러리 파일을 하나로 묶는 작업이다.
- 링커가 심볼(함수나 변수 이름)을 연결해서 최종 실행 파일을 만든다.
> 링킹 결과:
> - 완성된 실행파일 (.out, .exe 등)이 만들어진다.
> - 이제 이 파일은 운영체제에서 실행할 수 있다.
요약
- 전처리(Preprocessing): 소스 확장 및 정리
- 컴파일(Compilation): 기계어로 변환 준비
- 어셈블(Assembling): 오브젝트 파일 생성
- 링킹(Linking): 실행 파일 완성
→ 이 4단계를 통해 C 프로그램은 실제로 동작하는 실행파일이 된다.