링커
덤프버전 :
분류
비주얼 노벨에 대한 내용은 링커(비주얼 노벨) 문서 참고하십시오.
1. 개요[편집]
Linker
컴파일러가 생성한 기계어(목적 코드)들을 서로 연결시켜주는 프로그램. 컴파일러가 프로그래밍 언어를 해석해서 기계어로 번역하는 작업(컴파일)을 수행한다면 링커는 이렇게 나온 결과물들을 하나로 연결시켜 실행 파일을 만드는 작업(링킹, Linking)을 수행한다.
2. 상세[편집]
컴파일이란 프로그래밍 언어를 해석하여 기계어를 생성하는 작업을 말하며 이것을 자동으로 수행해주는 프로그램을 컴파일러라 한다. 그러나 컴파일러는 기계어(목적 코드)만 생성시켜주기만 할 뿐, 이걸로는 우리가 만든 프로그램을 실행할 수 없다. 컴파일러가 만든 결과물들을 하나로 합쳐 실행이 가능한 파일을 만드는 작업을 거쳐야 하는데 이를 링킹라고 하며, 이것을 자동으로 수행해주는 프로그램이 바로 링커이다.
일반적으로 프로그램을 만드는 과정은 다음과 같다.
- 소스 코드를 작성한다.
- 컴파일을 한다. 그러면 컴파일러가 소스 코드를 해석하여 기계어를 생성하고 오브젝트(obj) 파일을 만들어서 저장한다.
- 이후 링커가 컴파일러가 만들어낸 결과물(오브젝트 파일)들을 하나로 합친다.
- 이로써 실행할 수 있는 프로그램이 만들어진다.
과거에는 컴파일 후 링킹을 별도로 수행해야 했으나 요즘은 링킹 과정 자체가 빌드 프로세스의 일부로 들어가 있어 직접 링커를 실행할 일은 드물다. 하지만 그렇다고 링킹 과정이 겉으로 드러나지 않을 뿐 아예 없는 것은 아니며, 사용자가 직접 수동으로 링킹을 수행하고자 한다면 얼마든지 할 수 있다. 특히 크로스 컴파일링을 진행할 때 플랫폼별로 링커가 달라 일일히 설정하게 될 수도 있다.
3. ODR (One Definition Rule)[편집]
프로그래밍 언어에서 주의해야 하는 점은 2개 이상의 같은 이름의 심볼이 존재해서는 안된다는 것이다. 이를 ODR (One Definition Rule)라고 부른다.
예를 들어 한 소스 코드에 NamuWiki라는 심볼을 정의하고 또 다른 소스 코드에서 NamuWiki라는 심볼을 정의하면 컴파일에서는 문제가 없지만 링킹 단계에서 에러가 발생하게 된다. 이는 링커가 여러 소스 코드의 결과물을 하나로 합치는 과정에서 각 소스 코드에 있는 똑같은 이름의 심볼이 중복되었기 때문이다.
C/C++ 초보자가 흔히 자주 애를 먹게 되는 문제. 한 헤더 파일을 만들고 2개 이상의 소스코드에서 사용할 경우 발생하기 쉽다. 그래서 헤더 파일을 만들 때 아래와 같이 Include Guard를 작성하면 좋다.
#ifndef HEADER_FILE_NAME_H
#define HEADER_FILE_NAME_H
// 헤더 파일 내용 작성...
#endif
이것 외에는 #pragma once도 있는데 위와 다르게 한줄만 쓰면 되므로 편리해진다. 다만 비표준 문법이라 일부 컴파일러에서 지원하지 않는 경우가 있으므로 주의해야 한다.
#pragma once
// 헤더 파일 내용 작성...
참고로 비주얼 스튜디오에서 헤더 파일을 만들면 자동으로 맨 윗줄에 붙여있다.
또한 헤더 파일 안에 심볼을 정의만 해줘야 한다. 즉 int NamuWiki; 처럼 정의만 하고 int NamuWiki = 0; 처럼 정의와 동시에 초기화하면 안된다는 말이다. 이렇게 되면 링커 단계에서 에러가 발생한다. 따라서 헤더 파일에 정의만 하고 한 개의 소스 코드에서 값을 초기화시켜 주거나 static Storage class를 지정해 심볼이 노출되지 않도록 해 줘야 한다.
다만 인라인 함수는 ODR 문제에서 자유롭다. 인라인 함수을 헤더 파일에서 작성하고 여러 소스 코드에서 사용하더라도 컴파일러 단계에서 내부적으로 치환이 완료되고 심볼은 노출되지 않기 때문에 문제 없이 링킹을 해준다. 물론 같은 이름의 인라인 함수를 한 소스 코드에서 중복해서 작성하거나 이름만 같을 뿐 내용을 다르게 작성할 경우 링킹 단계 이전의 컴파일러 단계에서 에러가 난다.
4. 링커 소프트웨어 목록[편집]
- ld
- gold
- bfd
- lld
- mold
[각주]
이 문서의 내용 중 전체 또는 일부는 2023-11-26 13:24:56에 나무위키 링커 문서에서 가져왔습니다.