게임 개발/C++

[C++] 컴파일 과정 - 3. 링크 단계

유행성바코드 2025. 2. 21. 23:37

목차

  • 01. Intro
  • 02. 링크 단계
    • 오브젝트 파일 병합
    • 심볼 해석
    • 주소 할당
    • 재배치
    • 라이브러리 연결
  • 03. 마무리
  • 04. 연관 내용

01. Intro

어제 컴파일 과정 중 두 번째 단계인 '컴파일 단계'를 알아봤습니다.

오늘은 컴파일 과정의 마지막 단계인 '링크 단계'에 대해 알아보겠습니다.

 


02. 링크 단계

링크 단계링커가 여러 개의 오브젝트 파일과 라이브러리를 연결해 최종 실행 파일을 생성하는 과정입니다.

이러한 과정에서 각 오브젝트 파일에서 참조된 심볼을 해결하고 필요한 주소를 할당합니다.

또한, 실행에 필요한 모든 코드와 데이터를 결합해 최종적으로 실행 가능한 프로그램(.exe, .out)을 만듭니다.

따라서, 링크 단계에서 링커가 수행하는 기능(역할)을 요약하면 5가지로 볼 수 있습니다.

 

1. 오브젝트 파일 병합

2. 심볼 해석

3. 주소 할당 및 재배치

4. 라이브러리 연결

5. 디버깅 정보 포함 및 최적화

 

링커가 수행하는 기능(역할)을 하나씩 살펴보겠습니다.

 

오브젝트 파일 병합

컴파일 과정에서 마지막 단계에서는 기계어로 변환된 각 오브젝트 파일들을 서로 연결해야 합니다.

하지만, 각 오브젝트 파일은 프로그램의 일부만 포함하고 있습니다. 

다른 소스 파일에서 호출한 함수나 변수의 위치를 찾고 연결하기 위해서는

먼저 심볼 해석(Symbol Resolution)이 필요합니다.

 

심볼 해석

심볼 해석은 현재 오브젝트 파일의 심볼이 어디에 있는지 찾는 과정입니다.

먼저, 다른 소스 파일에서 호출한 함수나 전역 변수를 찾기 위해 해당 오브젝트 파일의 심볼 테이블을 참조해야 합니다.

그 후, 컴파일 단계에서 심볼 테이블에 등록되어 있는 심볼을 찾습니다. 

 

따라서, 링크 단계 초기에서는 현재 외부 함수나 변수가 어느 오브젝트 파일에 있는지는 찾았습니다.

하지만, 아직 심볼에 있는 함수나 변수에 대한 실제 메모리 주소는 결정되지 않을 수도 있습니다.

이는 추후 과정인 주소 할당 및 재배치를 통해서 실제 메모리 주소가 결정됩니다.

 

즉, 해당 심볼(함수, 전역 변수 등)이 어디에 있는지는 정확하게 모르지만, 참조가 존재한다는 것만 확인했습니다.

 

주소 할당

주소 할당은 각 심볼의 주소를 결정하는 과정입니다.

링커가 먼저 심볼 해석을 진행하고 주소 할당이 진행됩니다.

 

링커가 각 심볼의 주소를 결정하는 이유는 다음과 같습니다.

먼저 컴파일 시, 각 오브젝트 파일은 독립적으로 생성됩니다.

그러므로, 각 오브젝트 파일 내에서 참조되는 변수나 함수의 주소는 상대적이거나 임시 주소일 수 있습니다.

따라서, 링커는 각각의 참조되는 변수나 함수의 주소에 대한 절대 주소를 할당합니다.

이러한 이유로 링커는 각 심볼에 대해서 절대 주소를 할당합니다.

 

따라서, 주소 할당 과정에서는 각 오브젝트 파일을 하나의 실행 파일로 합치면서

각 심볼에 대한 메모리 주소를 배정하는 작업만 진행됩니다.

 

재배치

정적 & 동적 라이브러리에 따라 다르게 작동

먼저, 주소 할당 과정에서 각 심볼에 대해서 절대 주소가 할당되지만, 프로그램이 실행될 때, 그 주소가 변경될 수 있습니다.

이는 정적 라이브러리와 동적 라이브러리가 실행 파일에 포함되거나 로딩되는 시점이 다르기 때문입니다.

 

정적 라이브러리는 컴파일 타임에 실행 파일에 포함되므로 주소 할당 과정에서 절대 주소가 바로 결정됩니다.

하지만, 동적 라이브러리는 실행 중에 로드되므로 실행할 때, 주소가 결정됩니다.

 

그래서, 정적 라이브러리인 경우에는 주소 할당과 재배치가 같은 개념으로 사용됩니다.

하지만, 동적 라이브러리는 프로그램 생성이 완료된 이후인 프로그램 실행에서 별도의 재배치가 이루어집니다.

그렇기에 동적 라이브러리는 주소 할당과 재배치 과정이 분리가 됩니다.

 

그러므로 정적 라이브러리는 링크 단계에서 재배치(주소 할당)가 진행되고 동적 라이브러리는 프로그램 실행 단계에서 진행됩니다.

 

동적 라이브러리는 링크 단계에서 어떤 상태를 유지하고 있을까?

동적 라이브러리는 링크 단계의 주소 할당 과정에서 Placeholder(임시 주소)로 존재합니다.

그래서, 링커는 동적 라이브러리를 참조하는 실행 파일을 만들지만, 실제 메모리 주소가 아직 확정되지 않았으므로

실행 파일에는 해당 함수 또는 전역 변수가 동적 라이브러리로부터 로드될 것이라는 정보만 Placeholder에 포함시킵니다.

 

즉, 이 함수나 전역 변수는 어딘가에 있다고만 표시하고 나중에 실행할 때, 결정합니다.

 

 

그렇다면, 누가 동적 라이브러리 재배치를 수행할까?

정답은 OS 로더입니다. OS 로더가 동적 라이브러리의 심볼에 대한 재배치를 수행합니다.

링커는 링크 단계에서 모든 역할을 마쳤기에 동적 라이브러리 재배치에 관여할 수 없습니다.

 

컴파일 과정을 모두 마친 프로그램을 실행할 때, OS 로더가 동적 라이브러리를

적절한 위치에 로드하고 전역 변수 및 함수의 실제 주소를 결정합니다.

 

따라서, 실행 단계에서 동적 라이브러리의 Placeholder가 모두 처리됩니다.

 

 

라이브러리 연결

라이브러리 연결은 앞에서 이미 다 설명했으므로 대략적으로 다시 설명해고 각 라이브러리 특징에 대해서 설명하겠습니다.

 

이전 내용 요약

  • 정적 라이브러리 링킹 = 정적 링크(Static Linking)

링커가 라이브러리 파일을 직접 포함시켜 실행 파일을 만들 때, 함께 결합합니다.

 

  • 동적 라이브러리 링킹 = 동적 링크(Dynamic Linking)

실행 시, 런타임에 로드되며 로드는 OS 로더가 진행합니다.

단, 링크 단계에서 링커는 라이브러리에서 필요한 심볼을 찾아 실행 파일에 대한 참조만 추가합니다.

 

 

정적 라이브러리 특징

  • 파일 확장자

Linux/macOS : .a (Archive)

Windows : .lib (Library)

 

  • 장점

1. 실행 파일에 라이브러리가 포함되어 있어 실행 시, 별도의 라이브러리 파일이 필요 없음

2. 위와 같은 이유로 배포 시, 실행 파일만 제공하면 되므로 배포가 간편

  • 단점

1. 라이브러리가 실행 파일에 포함되어 있어 실행 파일 크기가 큼

2. 라이브러리 업데이트 시, 프로그램 전체 컴파일을 다시 진행 필요

 

 

동적 라이브러리 특징

  • 파일 확장자

Linux/macOS : .so (Shared Object)

Windows : .dll (Dynamic Link Library)

 

  • 장점

1. 실행 파일에 라이브러리가 포함되지 않아 실행 파일 크기가 작음

2. 여러 프로그램이 동일한 라이브러리 공유 가능

3. 라이브러리 업데이트 시, 프로그램 전체 컴파일이 필요 없음

  • 단점

1. 실행할 때, 라이브러리 파일이 없으면, 실행 불가능

2. 위와 같은 이유로 배포 시, 라이브러리 파일을 실행 파일과 함께 배포

 

 


03. 마무리

컴파일 과정에 대해서 3단계로 나눠 글을 작성했는데, 내용이 많아 설명이 부족한 부분도 보였습니다.

그래서, 다음 번에는 심볼과 심볼 테이블에 대한 내용을 조금 더 알아본 뒤에 다음 주제로 넘어가도록 하겠습니다.

 


04. 연관 내용

  • [C++] 컴파일 과정 - 1. 전처리 단계
 

[C++] 컴파일 과정 - 1. 전처리 단계

목차Intro01. '컴파일 과정' 이란?02. 컴파일 과정 - 1. 전처리 단계#include : 헤더 파일 포함 지시어#ifdef, #endif .. 등 : 조건부 컴파일 지시어#define : 매크로 정의 지시어전처리 단계 후, 결과03. 연관 내

epidemic-barcode.tistory.com

  • [C++] 컴파일 과정 - 2. 컴파일 단계
 

[C++] 컴파일 과정 - 2. 컴파일 단계

목차Intro01. 컴파일 단계오브젝트 파일기계어로 변환 과정심볼 생성 및 심볼 테이블 등록02. 연관 내용Intro어제 컴파일 과정 중 첫 번째 단계인 '전처리 단계'를 알아봤습니다.오늘은 전처리 다음

epidemic-barcode.tistory.com

 

 


 

읽어주셔서 감사합니다.

틀린 내용 지적은 언제나 환영입니다!