본문 바로가기

별걸다하는 IT/운영체제 OS

[OS]링킹(Linking)이란? 링커(Linker)란? 컴파일 과정,목적파일, 빌드과정

운영체제 목차

 

메모리 관리를 시작하기 앞서 

메모리 관리와 관련된 몇 가지 단어들이 나오는데 이런 단어들을 이해를 못하고 있으면 안됩니다.

 

Linking에 대해서는 프로그램 컴파일에 대해서 배웠으면 당연히 알고 있어야 해요!! 

Dynamic Linking 과 Static Linking 또한 알고 있어야합니다.

 

아시는 분들은 이번 포스팅은 그냥 가볍게 읽고 넘기면 되겠숩니다

모르는 분들이나 다시 상기시키기 위해서 가볍게 포스팅하고 넘어갈게요 

 

이번 포스팅은 Linking에 대해서 (사실 운영체제 과목 내용은 아니지만 이해를 돕기 위해 진행하는 포스팅)

다음 포스팅은 Dynamic Linking과 Static Linking에 대해서 살펴볼게요 

 

프로그램 빌드 과정- 컴파일 과정

링킹은 프로그램을 빌드 하는 과정에서 (즉 컴파일 과정에서 거치는 단계이죠) 이뤄지는 말그대로 링크하는 과정입니다.

 

[그림1]

이 전체를 크게 컴파일 과정이라고 해요.

작은의미의 컴파일로써는 저기 적혀있는 Compile 있죠? 저 구간을 컴파일이라고 합니다.

즉 Compiling + Linking 이 전 구간을 큰 의미의 컴파일, 저 Linking 구간을 제외한 Compiling 부문을 작은 의미의 컴파일이라고 지칭합니다.

 

운영체제는 C/C++언어와 그래도 연관이 깊으므로 C언어로 예를 들어볼게요 

대략 이렇게 우리가 코드를 짰다고 합시다. 그럼 이게 소스파일이예요. Source.cpp (이름.cpp)이렇게 저장되는 파일!

소스파일은 C언어나 java 등 이렇게 우리 인간들, 프로그래머들이 이해하기 쉽게 고급언어로 작성된 파일을 말합니다.

 

그리고 빌드하면! (비쥬얼 스튜디오에서는 Ctrl + shift + b) 

실제로 저런 과정(컴파일링 후 링킹 과정)을 얘네가 내부에서 진행한 후에 .exe파일을 딱 내보내주는거예요.

int x = 10;

int y = 20;

int result;

int add (int x, int y)

{

return x+y;

}

void main()

{

int sum = x+y;

result = add(x,y);

}

[소스파일]

저는 test라는 프로젝트를 생성해서 이와 같이 작성 후 빌드를 시켜줬는데요 

폴더에 들어가서 확인해보면

 

 

 

 

 

 

Test폴더 안 Debug 폴더에 Source.obj라는 파일은 작은 의미의 Compiling을 거친 후 생성된 Object code를 의미하고

Debug폴더 안에 보면 test.exe파일은 링킹 과정 후에 생기는 실행 파일을 의미해요

실행파일은 익숙하죠?! 실행파일이 만들어지는 과정은 이와 같습니다.

 

지금 현재는 source파일이 하나밖에 없어서 컴파일 과정을 거친 .O(오브젝트 파일=목적파일)은 Source.obj하나밖에 없네요 

하지만 실제로 컴파일 과정을 거치면 [그림1]처럼 .O파일이 여러개 각 소스파일 당 한개씩 생깁니다.

 

 

목적 파일 (Object File) 오브젝트 파일

 

소스파일은 우리가 이해하기 쉬운 언어들이지 컴퓨터가 이해할 수 있는 언어는 아니예요.

그렇기 때문에 컴퓨터가 실제로 이해하고 실행하기 위해서 Low Level언어, 이진수 파일로 변환해줘야 하는 과정을 거쳐야합니다. 이렇게 변환하는 것을 과정을 Compiling이라하고 변환해주는 애를 Compiler라고 해요 

이렇게 컴파일 과정 뒤에 생긴 Low level언어의 파일이 목적파일입니다. 

목적파일은 기계어로 작성된 로직과 실행하는데 필요한 부가 정보들 (디버깅 정보나 Symbol 정보등등)들로 이루어져있습니다.

목적파일은 실행파일과 소스의 중간단계인거죠.

 

Text segment, Data segment 뭔가 익숙하죠?

이 포스팅에서 우리 배웠었어요. 우리 작성한 코드들(명령어)의 이진정보가 Text segment로 들어갑니다. 

 

Data segment contains binary representation of data in assembly file

- Data section은 전역변수나 static 변수들이 저장되는데 좀 더 자세하게는 안에 Data section과 BSS Section을 나눠서 BSS에는 초기화되지 않은 전역변수와 static 변수들이 들어갑니다. .오브젝트 파일이 링킹 과정을 거쳐서 실행파일이 되는거니까

목적파일에도, 실행파일에도 이 데이터들이 포함됩니다.

 

Symbolic table은 컴퓨터 구조시간에 배웠던 그 symbol이 맞습니다. Symbol들의 주소와 정보들을 쉽게 찾을 수 있도록 한 곳에 모아둔 테이블이 Symbol 테이블이예요.

Relocation 정보 또한 symbol 심볼 정의와 심볼 참조를 연결하기 위한 테이블이예요. (symbol주소와 PC 상대 주소의 매칭 테이블임) 이부분은 컴퓨터 구조의 어셈블리어에서 배우니까 나중에 시간되시면 추가적으로 찾아서 공부하시길 권해드려요. :)

 

그리고 실제 오브젝트 파일을 열어보면 이와 같이 보여요 우리가 알아볼수없는건 당연합니다. 컴퓨터가 알아볼 수 있도록 바꾼거니까요 ~ㅎㅎ

 

링커(Linker)의 링킹(Linking) 과정

 

 

출처: https://www.webopedia.com/definitions/link/

이렇게 만들어진 Object file들을 링커가 링킹해서 실행파일로 만듭니다!

 

그림을 보니까 대략 목적파일과 라이브러리 파일들을 링크(더한게)한게 실행파일이라는 거 같죠? 맞습니다 ㅎㅎ

 

컴퓨터가 점점 발전함에 따라 디스크의 욕량도 늘어나고~ 램의 성능도 늘어나구~ 그러다보니 프로그램의 크기도 늘어나구~

소스코드 양이 그만큼 늘어남에 따라 한 파일에 모든 소스코드를 작성할 수 없게 됐어요 100000줄이나 넘는걸 어떻게 한 파일에서 관리하겠어요 

 

그래서 파일들을 분리해서 관리하죠.

링커라는 프로그램은

1. 이런 여러 소스코드 파일들을 하나로 합쳐요 즉 Object 파일들을 하나로 합칩니다.

2. 여기에 Library를 합쳐요 

라는 작업을 해서 실행파일을 만들어줘요 

출처: http://yimoyimo.tk/Linker-and-Loader/

1번째 과정이예요 여러 오브젝트 파일에 있는 동일한 섹션들을 하나의 덩어리로 합칩니다.

 

두 번째 링커가 하는 일은 라이브러리를 합치는 일이랬죠?

 

소스파일 그림에 cout는 cout이라는 클래스 라이브러리를 쓰기 때문에 사용할 수 있는거잖아요 #Include <iostream>이런거~

그 .exe파일 만들기 위해서 오브젝트 파일들 하나로 다 링크하고 이 exe파일에다가 라이브러리를 집어넣어서 실행파일을 완성하는 작업이 linking입니다 정확히는 static linking이예요 

 

Static linking이 있다면 Dynamic linking 이 있다는 말ㅎ

정적 링킹과 동적 링킹의 정의와 차이점에 대해서는 다음 포스팅에서 얘기할게요

 

  • WhiskeySierra 2019.10.01 21:25 신고

    설명이 정말 기가 막힙니다. 최고에요. 너무 감사드립니다. 이 나라의 별이 되어주세요.

  • nanai 2020.01.17 10:26 신고

    와 설명 진짜 잘하신다.....
    IT 꿈나무들의 빛줄기가 되어주세요

  • 고통의노예 2020.01.18 21:53

    잘 읽고 갑니다 이제 이런 글들에 댓글 남기는 습관도 좀 들여야 겠네요 ㅎ

  • 다람쥐가멍멍 2020.03.17 16:24

    선생님 설명 정말 정말 잘봤습니다...!!!!! 그런데 혹시 실례가 되지 않는다면 질문 하나만 드려도 될까요? 첫번째 그림에 a:x1000 이런건 무슨 뜻인가요? 어느 부분에서 공부하나요..?

    • IT 양햄찌(jhnyang) 2020.03.17 22:03 신고

      안녕하세요. 주소값을 의미합니다. 변수 a공간을 x1000에다가 잡았다고 생각하시면 됩니다. 함수의 경우도 함수포인터로 구현이 되어있기 때문에 결국 주소지에 저장됩니다.

  • 고양이는냐옹 2020.03.25 17:40

    선생님 감사합니다. 좋은 글 보고 갑니다~
    혹시 질문이 하나 있는데 질문드려도 될까용?
    컴파일러와 링커는 무슨파일을 생성하는 지 알 수 있을까요?
    컴파일러는 obj 파일을 만들고, 링커는 exe 파일을 만든다고 생각하면 되는건가요?

    • IT 양햄찌(jhnyang) 2020.03.25 19:42 신고

      넵 그렇습니다 컴파일러는 하나의 소스에 하나의 오브젝트 파일을 만든다면, 링커는 이들과 동적 라이브러리 등등을 묶어서 지지고볶고해서 실행파일로 만들어준다 생각하셔도 됩니다.

  • Hyom 2020.07.19 19:24

    안녕하세요 선생님!!
    저는 어떤 언어를 공부해야할지 고민하다가 여기까지 오게되었는데요. (현재 자바와 자바스트립트 디비 등 조금씩 공부하고 작은 프로그램도 만들어본 입문자입니다!)

    언매니지드 언어를 배워놔야 다른 언어를 쓰더라도
    메모리, cpu, 네트워크? 에 대해서 생각하게 되어서
    좀더 깊은 이해와 프로그래밍이 가능하다고 하다고
    c와 c++을 배워야한다고 하던데

    선생님이 올려놓으신 자료들을 보며
    메모리에 대해서 공부하면
    c나 c++을 배우지 않고도
    메모리구조같은 것들을 이해하고
    다른 언어를 사용하며 활용할수있을까요?

    제가 어떤 언어를 쓰던
    꼭 프로그램의 깊은 이해와 설계를 위해서
    언매니지드 언어를 배워야 하는 것인지
    아니면 이렇게 개념들을 찾아 공부하는 것으로 충분한것인지 궁금합니다.!!

    (C++을 쓰지 않더라도 이런것들을 공부하면 도움이 되는것인지.. 어렵네요 ㅠㅜ)

    • IT 양햄찌(jhnyang) 2020.07.20 10:15 신고

      안녕하세요 :)
      Hyom님이 생각하시는 진로 방향에 따라 답변은 달라지지 않을까 싶습니다. 자바, 자바스크립트 쪽을 주력으로 하셨으면 web쪽으로 생각하고 계신가 싶은데, 웹쪽으로 나아갈거면 C언어를 따로 공부할 필요 없이 개념적인 부분을 찾아 학습하는 것으로 충분합니다. 하지만 만약 직무를 좀 더 코어단으로 생각하고 계시다면 C언어를 통해 원리 이해는 필수적이 되겠죠. (대부분의 운영체제나 로우레벨 프로그램 단은 C언어로 구성되어 있으니까요).
      네트워크의 경우 자바로 많이 바뀌는 추세이고 netty같은 지원API도 많기 때문에 굳이 C언어를 필수적으로 택할 필요는 없습니다.
      개인적으로 생각하기에 저는 C/C++을 먼저 주력으로 배워서 그런가, 메모리개념에 대한 이론에는 확실히 도움이 되긴 했네요. 목적에 따라 정하시면 될 것 같아요 개인적인 답변이 도움이 되셨길 바랍니다

    • Hyom 2020.08.09 16:44

      조언 감사합니다!!

  • 전자계산기 2020.09.22 01:17

    설명이 진짜 기가 막히십니다 감사합니다!

  • 햄루룰루 2020.10.10 00:07 신고

    좋은 글 감사합니다! 제 개인 블로그에 출처 남기고 써도 될까요????

  • 생각하는혀두 2021.01.07 17:29

    설명 잘 보았습니다!! 구웄!! 설명하실때 직접 작업한 이미지가 맘에 들어서 그런데 혹시 이미지 그리는 툴 알려주실 수 있나요?

  • return Value 2021.03.08 23:33 신고

    내용 정리가 잘됐네욥!
    덕분에 잘 정리하고 갑니당