본문 바로가기
C Programming

[Linux] C 프로그램의 빌드 과정 살펴보기

by TYB 2024. 2. 8.
반응형

우리는 그냥 gcc main.cpp -o main만 하면 gcc가 cpp파일을 실행파일로 바꿔준다.

 

gcc 컴파일러는 어떤 일을 뒤에서 하고 있는 걸까?

 

4가지 과정이 있다.

 

preprocessing, compile, assmble, linking

 

그 과정을 수행하는 장치를 preprocessor, compiler, assembler, linker 라고하는 것이고

 

preprocessor가 c, cpp입력을 받아서 include 헤더를 풀어서 코드안에 다시 넣어주고 i파일로 생성

compiler가 i파일을 입력받아서 어셈블리어로 바꿔주고 s파일을 생성

assembler가 s파일을 입력받아서 기계어(2진수)로 바꿔주고 o파일을 생성

linker가 o파일을 입력받아서 실행파일을 생성

 

 

듣기만 해서는 잘 모르겠으니, 직접 해보자.

 

ubuntu@ubuntu8:~/gcc$ cat main.c
#include <stdio.h>
#define BUFFSIZE 100

int main (int argc,char *argv[])
{
        char buf[BUFFSIZE];
        int i=0;
        while(1)
        {
                printf("Hello World!\n");
        }
        return 0;
}

 

gcc에 해당 옵션을 주면 과정별로 생성되는 temp 파일을 모두 생성해서 보여준다.

ubuntu@ubuntu8:~/gcc$ gcc main.c -o main -save-temps
ubuntu@ubuntu8:~/gcc$ ls -l
total 52
-rwxrwxr-x 1 ubuntu ubuntu 16696  2월  8 10:41 main
-rw-rw-r-- 1 ubuntu ubuntu   165  2월  8 10:41 main.c
-rw-rw-r-- 1 ubuntu ubuntu 16390  2월  8 10:41 main.i
-rw-rw-r-- 1 ubuntu ubuntu  1720  2월  8 10:41 main.o
-rw-rw-r-- 1 ubuntu ubuntu   759  2월  8 10:41 main.s

 

main.i 파일은 preprocessor에서 include된 헤더파일을 모두 main.c의 윗부분에 추가해주는 과정임.

여기서는 정적라이브러리를  사용하고 있기 때문에 파일 안에 라이브러리의 내용을 모두 추가하는거임.

 

정적라이브러리는 실행파일 안에 라이브러리가 있으므로 실행속도가 빠르나, 파일 사이즈가 올라감

동적라이브러리는 실행파일 안에 라이브러리가 없으므로 실행속도는 다소 떨어지나, 파일 사이즈는 줄어듬.

 

main.i 길이가 739line 으로 늘어남

 

다음은 컴파일러(cc1)이 컴파일을 해주면 어셈블리어가 나옴.

main.s가 컴파일을 통해 나온 파일임. x86 계열의 어셈블리어

 

 

 

그 다음에 어셈블러가 어셈블리어를 binary 코드로 바꿔줌.

그 결과가 main.o이고 binary값은 우리가 알아볼 수가 없음.

 

 

hexdump라는 명령어를 쓰면 바이너리 기계어를 16비트로 확인가능함.

ubuntu@ubuntu8:~/gcc$ hexdump main.o
0000000 457f 464c 0102 0001 0000 0000 0000 0000
0000010 0001 003e 0001 0000 0000 0000 0000 0000
0000020 0000 0000 0000 0000 0338 0000 0000 0000
0000030 0000 0000 0040 0000 0000 0040 000e 000d
0000040 0ff3 fa1e 4855 e589 8148 90ec 0000 8900
0000050 7cbd ffff 48ff b589 ff70 ffff 4864 048b
0000060 2825 0000 4800 4589 31f8 c7c0 8c45 0000
0000070 0000 8d48 003d 0000 e800 0000 0000 f2eb
0000080 6548 6c6c 206f 6f57 6c72 2164 0000 4347
0000090 3a43 2820 6255 6e75 7574 3920 342e 302e
00000a0 312d 6275 6e75 7574 7e31 3032 302e 2e34
00000b0 2932 3920 342e 302e 0000 0000 0000 0000
00000c0 0004 0000 0010 0000 0005 0000 4e47 0055
00000d0 0002 c000 0004 0000 0003 0000 0000 0000
00000e0 0014 0000 0000 0000 7a01 0052 7801 0110
00000f0 0c1b 0807 0190 0000 001c 0000 001c 0000
0000100 0000 0000 0040 0000 4500 100e 0286 0d43
0000110 0006 0000 0000 0000 0000 0000 0000 0000
0000120 0000 0000 0000 0000 0000 0000 0000 0000
0000130 0001 0000 0004 fff1 0000 0000 0000 0000
0000140 0000 0000 0000 0000 0000 0000 0003 0001
0000150 0000 0000 0000 0000 0000 0000 0000 0000
0000160 0000 0000 0003 0003 0000 0000 0000 0000
0000170 0000 0000 0000 0000 0000 0000 0003 0004
0000180 0000 0000 0000 0000 0000 0000 0000 0000
0000190 0000 0000 0003 0005 0000 0000 0000 0000
00001a0 0000 0000 0000 0000 0000 0000 0003 0007
00001b0 0000 0000 0000 0000 0000 0000 0000 0000
00001c0 0000 0000 0003 0008 0000 0000 0000 0000
00001d0 0000 0000 0000 0000 0000 0000 0003 0009
00001e0 0000 0000 0000 0000 0000 0000 0000 0000
00001f0 0000 0000 0003 0006 0000 0000 0000 0000
0000200 0000 0000 0000 0000 0008 0000 0012 0001
0000210 0000 0000 0000 0000 0040 0000 0000 0000
0000220 000d 0000 0010 0000 0000 0000 0000 0000
0000230 0000 0000 0000 0000 0023 0000 0010 0000
0000240 0000 0000 0000 0000 0000 0000 0000 0000
0000250 6d00 6961 2e6e 0063 616d 6e69 5f00 4c47
0000260 424f 4c41 4f5f 4646 4553 5f54 4154 4c42
0000270 5f45 7000 7475 0073 0035 0000 0000 0000
0000280 0002 0000 0005 0000 fffc ffff ffff ffff
0000290 003a 0000 0000 0000 0004 0000 000c 0000
00002a0 fffc ffff ffff ffff 0020 0000 0000 0000
00002b0 0002 0000 0002 0000 0000 0000 0000 0000
00002c0 2e00 7973 746d 6261 2e00 7473 7472 6261
00002d0 2e00 6873 7473 7472 6261 2e00 6572 616c
00002e0 742e 7865 0074 642e 7461 0061 622e 7373
00002f0 2e00 6f72 6164 6174 2e00 6f63 6d6d 6e65
0000300 0074 6e2e 746f 2e65 4e47 2d55 7473 6361
0000310 006b 6e2e 746f 2e65 6e67 2e75 7270 706f
0000320 7265 7974 2e00 6572 616c 652e 5f68 7266
0000330 6d61 0065 0000 0000 0000 0000 0000 0000
0000340 0000 0000 0000 0000 0000 0000 0000 0000
*
0000370 0000 0000 0000 0000 0020 0000 0001 0000
0000380 0006 0000 0000 0000 0000 0000 0000 0000
0000390 0040 0000 0000 0000 0040 0000 0000 0000
00003a0 0000 0000 0000 0000 0001 0000 0000 0000
00003b0 0000 0000 0000 0000 001b 0000 0004 0000
00003c0 0040 0000 0000 0000 0000 0000 0000 0000
00003d0 0278 0000 0000 0000 0030 0000 0000 0000
00003e0 000b 0000 0001 0000 0008 0000 0000 0000
00003f0 0018 0000 0000 0000 0026 0000 0001 0000
0000400 0003 0000 0000 0000 0000 0000 0000 0000
0000410 0080 0000 0000 0000 0000 0000 0000 0000
0000420 0000 0000 0000 0000 0001 0000 0000 0000
0000430 0000 0000 0000 0000 002c 0000 0008 0000
0000440 0003 0000 0000 0000 0000 0000 0000 0000
0000450 0080 0000 0000 0000 0000 0000 0000 0000
0000460 0000 0000 0000 0000 0001 0000 0000 0000
0000470 0000 0000 0000 0000 0031 0000 0001 0000
0000480 0002 0000 0000 0000 0000 0000 0000 0000
0000490 0080 0000 0000 0000 000d 0000 0000 0000
00004a0 0000 0000 0000 0000 0001 0000 0000 0000
00004b0 0000 0000 0000 0000 0039 0000 0001 0000
00004c0 0030 0000 0000 0000 0000 0000 0000 0000
00004d0 008d 0000 0000 0000 002c 0000 0000 0000
00004e0 0000 0000 0000 0000 0001 0000 0000 0000
00004f0 0001 0000 0000 0000 0042 0000 0001 0000
0000500 0000 0000 0000 0000 0000 0000 0000 0000
0000510 00b9 0000 0000 0000 0000 0000 0000 0000
0000520 0000 0000 0000 0000 0001 0000 0000 0000
0000530 0000 0000 0000 0000 0052 0000 0007 0000
0000540 0002 0000 0000 0000 0000 0000 0000 0000
0000550 00c0 0000 0000 0000 0020 0000 0000 0000
0000560 0000 0000 0000 0000 0008 0000 0000 0000
0000570 0000 0000 0000 0000 006a 0000 0001 0000
0000580 0002 0000 0000 0000 0000 0000 0000 0000
0000590 00e0 0000 0000 0000 0038 0000 0000 0000
00005a0 0000 0000 0000 0000 0008 0000 0000 0000
00005b0 0000 0000 0000 0000 0065 0000 0004 0000
00005c0 0040 0000 0000 0000 0000 0000 0000 0000
00005d0 02a8 0000 0000 0000 0018 0000 0000 0000
00005e0 000b 0000 0009 0000 0008 0000 0000 0000
00005f0 0018 0000 0000 0000 0001 0000 0002 0000
0000600 0000 0000 0000 0000 0000 0000 0000 0000
0000610 0118 0000 0000 0000 0138 0000 0000 0000
0000620 000c 0000 000a 0000 0008 0000 0000 0000
0000630 0018 0000 0000 0000 0009 0000 0003 0000
0000640 0000 0000 0000 0000 0000 0000 0000 0000
0000650 0250 0000 0000 0000 0028 0000 0000 0000
0000660 0000 0000 0000 0000 0001 0000 0000 0000
0000670 0000 0000 0000 0000 0011 0000 0003 0000
0000680 0000 0000 0000 0000 0000 0000 0000 0000
0000690 02c0 0000 0000 0000 0074 0000 0000 0000
00006a0 0000 0000 0000 0000 0001 0000 0000 0000
*
00006b8

 

xxd라는 명령어를 쓰면 옆에 ascii 코드 값도 같이 나옴.

ubuntu@ubuntu8:~/gcc$ xxd main
00000000: 7f45 4c46 0201 0100 0000 0000 0000 0000  .ELF............
00000010: 0300 3e00 0100 0000 6010 0000 0000 0000  ..>.....`.......
00000020: 4000 0000 0000 0000 7839 0000 0000 0000  @.......x9......
00000030: 0000 0000 4000 3800 0d00 4000 1f00 1e00  ....@.8...@.....
00000040: 0600 0000 0400 0000 4000 0000 0000 0000  ........@.......
00000050: 4000 0000 0000 0000 4000 0000 0000 0000  @.......@.......

 

 

 

0000000 457f 464c 0102 0001 0000 0000 0000 0000

457f 464c   읽을 때 어떻게 읽냐면 little endian이기 때문에 MSB 중 첫번째 바이트부터 LSB까지 바이트 단위로

즉 0x4c 46 7f 45라고 읽어야 되는거임. 

 

 

자 그러면 목적코드인 main.o까지 나왔으니 링커를 통해 실행파일로 바꿔주면 우리가 실행 할 수 있는 실행파일이 나오겠죠?

 

그렇게 나온게 실행파일 main이고 

 

./main 을 통해 실행하는 거임.

반응형