이전 포스팅에서는 컴파일과 링크에 대해 설명했다. 컴파일이 무엇인지 링크가 무엇인지 그리고 그것들이 무슨 차이가 있는지도 간단하게 살펴봤다. 컴파일은 목적 파일를 만들고 그 목적 파일을 링크는 실행 파일을 만든다고 했다. 설명을 듣다보면, 컴파일과 링크가 일련의 과정임을 쉽게 유추할 수 있다. 그리고 오늘 설명하려는 빌드가 바로 이 두 개의 과정을 모두 포함하는 포괄적인 개념이라고 생각하면 된다.
빌드(Build)
소프트웨어 개발에서 빌드라는 말은 굉장히 많이 들어봤을 것이다. 특히 Visual Studio를 사용해보신 분들이라면 이 빌드라는 것에 익숙할 것이다. 그리고 빌드가 뭔지 잘 모르더라도 아마 빌드의 과정은 개발을 접해보신 분들이라면 알게 모르게 이 과정을 겪어 봤을 것이다. 그렇다면 빌드는 무엇일까?
빌드는 소스 코드를 실행 가능한 프로그램으로 변환하는 전체 과정을 의미한다. 위에서 설명했듯이 컴파일과 링크 과정도 빌드의 핵심 과정 중 하나이다. 사실 개념적으로만 보면 컴파일과 링크만 합쳐서 빌드라고 부르는 사람도 허다하다(사실 틀린 이야기는 아니다). 하지만 사실 빌드는 더욱 다양한 과정이 존재하고 오늘은 잘 알려진 일반적인 과정에 대해 간단하게 알아볼 것이다.
빌드 과정 (1) - 전처리 (Preprocessing) / (C, C++, Objective-C)
전처리는 컴파일러가 소스 코드를 처리하기 전에 수행하는 단계이다. 전처리는 모든 프로그래밍 언어에서 일어나는 것은 아니고 주로 C 언어와 그와 유사한 문법을 가진 언어들에서 사용되는 개념이다. 전처리는 컴파일러의 전 단계에서 코드를 변형하거나 준비하는 과정으로, 전처리를 통해 특정 작업을 수행한다. 하지만 모든 언어가 전처리 과정을 필요로 하거나 지원하지는 않는다.
전처리의 과정을 살펴보면,
// 전처리 하기 전 예시
#define PI 3.14
#include <stdio.h>
int main() { printf("PI: %f\n", PI); return 0; }
전처리 후
int main() { printf("PI: %f\n", 3.14); return 0; }
- 매크로 확장 : #define으로 정의된 매크로를 실제 값으로 대체한다.
- 헤더 파일 포함 : #include로 지정된 파일의 내용을 소스 코드에 삽입한다.
- 조건부 컴파일 : #ifdef, #if 등으로 특정 조건에 따라 코드를 포함하거나 제외한다.
- 주석 제거 : 주석을 제거하여 컴파일러가 읽을 준비를 한다.
예시에서의 코드를 살펴보면 매크로로 설정한 PI값이 실제로 코드에 포함된 것을 볼 수 있고, 예시에서는 생략 되었지만 #include <stdio.h>이 소스코드에 삽입되어 printf 함수가 정상적으로 동작할 수 있게 된다. 또한 전처리 과정으로 주석이 제거된 모습도 확인할 수 있다. 전처리 과정을 통해 소스코드가 더 간결해지고 컴파일러가 효율적으로 처리할 수 있는 형태가 된다.
빌드 과정 (2) - 컴파일
전처리된 코드는 컴파일러에 의해 기계어 코드로 변환된다. 이 때 생성되는 파일은 오브젝트 파일로 아직까지는 실행 가능한 상태는 아니다.
// 예시
main.c => main.o
컴파일(Complie) 이란
우리는 일상속에서 우리의 언어로 소통하고 상호작용한다. 하지만 우리의 언어로 컴퓨터와 소통을 시도한다면 아마 거의 불가능할 것이다. AI가 성행하고 있는 현재, 우리의 언어로 소통할 수
joungdev.tistory.com
컴파일 과정의 자세한 내용은 이전 포스팅을 확인해보면 좋을 것 같다.
빌드 과정 (3) - 어셈블리 (Assembly)
컴파일 과정 중간에는 어셈블리 코드로 변환되는 단계가 포함된다. 현대 컴파일러에서는 이 단계가 내부적으로 처리되지만, 일부 빌드 시스템에서는 아직까지 중간 어셈블리 파일을 생성하기도 한다.
// assembly 코드 예시
MOV AX, 1234h
ADD AX, 5678h
어셈블리에 관한 내용은 추후 기회가 되면 다뤄보기로 하겠다.
빌드 과정 (4) - 링크, 링킹(Linking)
링크 과정에서의 링커는 컴파일된 여러 오브젝트 파일과 필요한 라이브러리를 결합하여 실행 파일을 생성한다.
// 예시
main.o => main.exe
링크(Link), 링킹(Linking)이란
이전 포스팅에서 컴퓨터는 우리의 언어를 이해하지 못하고 그로 인해 우리의 언어를 컴퓨터의 언어로 바꿔주는 과정인 컴파일에 대해 알아보았다. 그리고 컴파일 과정을 통해 목적파일 ( .o, .obj
joungdev.tistory.com
링크 과정의 자세한 내용은 이전 포스팅을 확인해보면 좋을 것 같다.
빌드 과정 (5) - 최적화 (Optimization)
컴파일러와 링커는 실행 성능을 높이기 위해 코드 최적화를 수행한다. 최적화의 주요 목표는 실행 속도 향상, 메모리 사용량 감소 등이다.
최적화 과정에서는 반복문을 최적화 하거나 중복 계산 제거, 함수 인라인화 등 다양한 최적화 작업이 이루어진다.
컴파일러나 링커의 설정에 따라 최적화 수준이 다르며, 간단한 프로젝트에서는 최적화를 건너뛰는 경우도 있다.
빌드 과정 (6) - 로딩 (Loading)
로딩은 컴파일과 링크 과정을 통해 만들어진 실행파일을 운영체제의 로더가 메모리에 적재하는 과정이다. 로더는 실행에 필요한 환경을 설정하고, 프로그램의 진입점에서 실행을 시작한다.
빌드 과정에서 자주 언급되는 로딩은 중요한 주제이지만, 빌드 과정보다는 운영체제의 동작과 더 밀접한 관계를 맺고 있다. 따라서 로딩에 대한 자세한 내용은 운영체제를 다루는 글에서 더욱 자세히 설명하도록 하겠다.
빌드 과정 (7) - 실행 (Execution)
로더가 실행 파일을 메모리에 올리고 환경을 설정하면 프로그램이 실행된다. 이때, 프로세스는 CPU에서 실제로 작업을 수행하며 사용자와 상호작용하게 된다.
사실 현대적인 언어, 기술들이 끊임없이 발전하는 시점에서 빌드 과정을 단일한 흐름으로 정의하는 것은 현실적으로 불가능하다. 언어마다, 그리고 프로젝트의 구조와 사용 기술에 따라 빌드의 단계와 방식은 천차만별로 달라질 수 있기 때문이다. 이번 포스팅에서 소개한 빌드 과정은 가장 기초적인 컴파일과 링크의 개념을 중심으로 한 것이다. 이는 빌드 과정을 처음 배우는 사람들에게 기본 지식을 쌓는데 도움을 줄 것이라고 생각한다. 그리고 이 지식을 통해 다양한 환경에서의 빌드 방식을 이해하고 응용하는 데 활용하는 것이 좋을 것 같다.
'기본 개념' 카테고리의 다른 글
링크(Link), 링킹(Linking)이란 (0) | 2025.01.14 |
---|---|
컴파일(Complie) 이란 (0) | 2025.01.13 |
파싱(Parsing) 이란 (0) | 2025.01.09 |
브라우저란 (0) | 2025.01.08 |