인간이 이해할 수 있는 고수준 언어(C, C++, Java 등)로 작성된 소스 코드를 컴파일러를 통해 CPU가 이해할 수 있는 저수준 언어(기계어)로 변환하는 과정이다.
C언어 실행 환경을 세팅하기 위해 Visual Studio Code에서 익스텐션을 설치해서 GCC로 컴파일을 할 수 있게 되었다.
GCC는 처음에는 C 컴파일러 GNU C Compiler
였으나 이후에 C++ 등 다른 언어도 지원하게 되면서 GNU Compiler Collection
으로 이름이 변경되었다.
GCC의 컴파일 과정은 전처리
- 컴파일
- 어셈블
- 링크
4단계로 이루어진다.
간단한 .c
파일을 하나 생성해서 어떻게 컴파일되는지 살펴보자!
#include <stdio.h>
int main(void)
{
printf("Hello, World!\n");
return 0;
}
전처리 지시자(#include
)에 따라 소스 파일을 가공한다. 프로그램에 필요한 헤더 파일을 소스 코드로 복사하고, 주석을 삭제하고, #define
매크로를 실행하는 등 소스 파일을 컴퓨터에 맞게 편집한다.
$ gcc -E main.c -o main.i
전처리기를 실행하고 생성된 .i
파일을 열어보면...
#include
로 stdio.h
헤더 파일이 쭉 복사되어 무려 551줄이나 main
함수 위에 들어가 있는 걸 확인할 수 있다.
고수준 언어를 저수준 언어로 나타내는 역할이다. 전처리된 파일을 어셈블리어로 바꿔준다. 어셈블리어는 기계어를 사람이 이해할 수 있게 부호화한 것이다.
$ gcc -S main.i -o main.s
어셈블리어로 변환된 .s
파일이다. 사람이 이해할 수 있는 언어지만 나는 이해할 수 없다...
컴파일 과정에서 최적화를 수행하기 때문에 .i
파일보다 훨씬 코드가 짧아졌다.
어셈블리어를 기계어로 바꾸는 과정을 수행한다. 어셈블 과정을 거치면 오브젝트 파일(Object File)로 변환된다. 오브젝트 파일은 CPU가 해석할 수 있는 명령어(기계어)로 이루어져 있어서 사람이 읽을 수 없다.
$ gcc -c main.s -o main.o
말 그대로 진짜 읽을 수 없게 되었다.
오브젝트 파일들과 프로그램 실행에 필요한 라이브러리 파일들을 결합해서 하나의 실행 파일로 만든다. 이 실행 파일은 이제 운영체제가 인식하고 실행할 수 있는 파일이다.
$ gcc main.o -o main.exe
우리가 흔히 보던 .exe
실행 파일이다.
컴파일을 수행하는 프로그램으로는 컴파일러와 인터프리터가 있다.
컴파일러 (Compiler) | 인터프리터 (Interpreter) |
---|---|
런타임 전에 전체 소스 코드를 컴파일해서 기계어로 변환 | 런타임에 한 번에 한 문장씩 변환 |
컴파일 시간이 걸리지만 실행은 빠름 | 시작은 빠르지만 한 문장씩 변환하면서 실행하기 때문에 실행이 느림 |
링킹(Linking)이 필요한 Object Code를 생성하여 더 많은 메모리가 필요함 | Object Code가 만들어지지 않아 메모리 효율이 높음 |
컴파일 과정에서 전체 코드를 검사하고 에러를 감지하므로 실행 전에 에러 발견 가능함 | 첫 에러를 만날 때까지 프로그램을 계속 번역하고 에러를 만나면 중지하는 방식으로, 실행 전에 에러 발견하기 어려움 |
컴파일 언어: C, C++, Java, TypeScript 등 | 인터프리터 언어: JavaScript, Python, Ruby 등 |
컴파일 언어는 바로 기계어로 변환되지만, 인터프리터 언어는 인터프리터가 해석할 수 있는 이진 표현법인 Byte Code로 먼저 변환된 후에 기계어로 변환된다.
그래서 파이썬 같은 인터프리터 언어가 C나 C++와 같은 컴파일 언어보다 상대적으로 느린 것!
자바스크립트는 인터프리터 언어이지만 꼭 인터프리터로만 처리되는 것은 아니다.
크롬 브라우저(또는 Node.js)의 V8 엔진에서는 JIT (Just-In-Time) Compiler 방식으로 자바스크립트를 처리한다. 인터프리터로 컴파일해서 Byte Code로 만들고 이 Byte Code를 캐싱하는 등 최적화해서 컴파일할 때 다시 참조하는 방식으로, 인터프리터보다 더 빠른 속도로 실행 가능하다.
참고
컴파일(Compile)에 대한 이해
[C/C++] GCC가 무엇인가요? GCC의 컴파일 과정 4단계
[C언어] 컴파일 과정(COMPILE PROCESS) 4단계 자세한 설명
컴파일이란 무엇이며, 자바스크립트는 인터프리터 언어인가?
(Term) Compiler VS Interpreter
V8 에서 Javascript 코드를 실행하는 방법 정리해보기