본문 바로가기
OS/Linux

리눅스 기초 30강 시리즈 - 18강 C언어코딩(gcc)

by HJ0216 2023. 1. 26.

이 글은 양주종의 코딩스쿨 리눅스(Linux) 기초 강좌 30강 모음 수강하며 정리한 글입니다.

 

18강 C언어코딩(gcc)

(일반 사용자 id: j, pw: j)

(관리자 id: root, pw: r)

 

gcc C언어 complier 설치

[j@hj0216 ~]$ su -
암호:
마지막 로그인: 목  1월 26 01:38:48 KST 2023일시 pts/0
[root@hj0216 ~]# yum -y install gcc
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
 * base: mirror.navercorp.com
 * extras: mirror.navercorp.com
 * updates: mirror.navercorp.com
Resolving Dependencies
--> Running transaction check
---> Package gcc.x86_64 0:4.8.5-44.el7 willbe installed
--> Processing Dependency: libgomp = 4.8.5-44.el7 for package: gcc-4.8.5-44.el7.x86_64
--> Processing Dependency: cpp = 4.8.5-44.el7 for package: gcc-4.8.5-44.el7.x86_64
--> Processing Dependency: libgcc >= 4.8.5-44.el7 for package: gcc-4.8.5-44.el7.x86_64
--> Processing Dependency: glibc-devel >= 2.2.90-12 for package: gcc-4.8.5-44.el7.x86_64
--> Processing Dependency: libmpfr.so.4()(64bit) for package: gcc-4.8.5-44.el7.x86_64
--> Processing Dependency: libmpc.so.3()(64bit) for package: gcc-4.8.5-44.el7.x86_64
--> Running transaction check
---> Package cpp.x86_64 0:4.8.5-44.el7 willbe installed
---> Package glibc-devel.x86_64 0:2.17-326.el7_9 will be installed
--> Processing Dependency: glibc-headers = 2.17-326.el7_9 for package: glibc-devel-2.17-                                  326.el7_9.x86_64
--> Processing Dependency: glibc = 2.17-326.el7_9 for package: glibc-devel-2.17-326.el7_                                  9.x86_64
--> Processing Dependency: glibc-headers for package: glibc-devel-2.17-326.el7_9.x86_64
---> Package libgcc.x86_64 0:4.8.5-36.el7 will be updated
---> Package libgcc.x86_64 0:4.8.5-44.el7 will be an update
---> Package libgomp.x86_64 0:4.8.5-36.el7 will be updated
---> Package libgomp.x86_64 0:4.8.5-44.el7 will be an update
---> Package libmpc.x86_64 0:1.0.1-3.el7 will be installed
---> Package mpfr.x86_64 0:3.1.1-4.el7 will be installed
--> Running transaction check
---> Package glibc.x86_64 0:2.17-260.el7 will be updated
--> Processing Dependency: glibc = 2.17-260.el7 for package: glibc-common-2.17-260.el7.x                                  86_64
---> Package glibc.x86_64 0:2.17-326.el7_9 will be an update
---> Package glibc-headers.x86_64 0:2.17-326.el7_9 will be installed
--> Processing Dependency: kernel-headers >=2.2.1 for package: glibc-headers-2.17-326.e                                  l7_9.x86_64
--> Processing Dependency: kernel-headers for package: glibc-headers-2.17-326.el7_9.x86_                                  64
--> Running transaction check
---> Package glibc-common.x86_64 0:2.17-260.el7 will be updated
---> Package glibc-common.x86_64 0:2.17-326.el7_9 will be an update
---> Package kernel-headers.x86_64 0:3.10.0-1160.81.1.el7 will be installed
--> Finished Dependency Resolution

Dependencies Resolved

============================================
 Package
        Arch   Version        Repository
                                       Size
============================================
Installing:
 gcc    x86_64 4.8.5-44.el7   base     16 M
Installing for dependencies:
 cpp    x86_64 4.8.5-44.el7   base    5.9 M
 glibc-devel
        x86_64 2.17-326.el7_9 updates 1.1 M
 glibc-headers
        x86_64 2.17-326.el7_9 updates 691 k
 kernel-headers
        x86_64 3.10.0-1160.81.1.el7
                              updates 9.1 M
 libmpc x86_64 1.0.1-3.el7    base     51 k
 mpfr   x86_64 3.1.1-4.el7    base    203 k
Updating for dependencies:
 glibc  x86_64 2.17-326.el7_9 updates 3.6 M
 glibc-common
        x86_64 2.17-326.el7_9 updates  12 M
 libgcc x86_64 4.8.5-44.el7   base    103 k
 libgomp
        x86_64 4.8.5-44.el7   base    159 k

Transaction Summary
============================================
Install  1 Package  (+6 Dependent packages)
Upgrade             ( 4 Dependent packages)

Total download size: 49 M
Downloading packages:
Delta RPMs disabled because /usr/bin/applydeltarpm not installed.
(1/11): glibc-devel-2. | 1.1 MB   00:01
(2/11): glibc-2.17-326 | 3.6 MB   00:02
(3/11): glibc-headers- | 691 kB   00:01
(4/11): libgcc-4.8.5-4 | 103 kB   00:00
(5/11): libgomp-4.8.5- | 159 kB   00:00
(6/11): libmpc-1.0.1-3 |  51 kB   00:00
(7/11): mpfr-3.1.1-4.e | 203 kB   00:00
(8/11): cpp-4.8.5-44.e | 5.9 MB   00:04
(9/11): glibc-common-2 |  12 MB   00:04
(10/11): gcc-4.8.5-44. |  16 MB   00:06
(11/11): kernel-header | 9.1 MB   00:04
--------------------------------------------
Total          6.3 MB/s |  49 MB  00:07
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
  Updating   : libgcc-4.8.5-44.el7.    1/15
  Updating   : glibc-common-2.17-32    2/15
  Updating   : glibc-2.17-326.el7_9    3/15
warning: /etc/nsswitch.conf created as /etc/nsswitch.conf.rpmnew
  Installing : mpfr-3.1.1-4.el7.x86    4/15
  Installing : libmpc-1.0.1-3.el7.x    5/15
  Installing : cpp-4.8.5-44.el7.x86    6/15
  Updating   : libgomp-4.8.5-44.el7    7/15
  Installing : kernel-headers-3.10.    8/15
  Installing : glibc-headers-2.17-3    9/15
  Installing : glibc-devel-2.17-326   10/15
  Installing : gcc-4.8.5-44.el7.x86   11/15
  Cleanup    : libgomp-4.8.5-36.el7   12/15
  Cleanup    : glibc-common-2.17-26   13/15
  Cleanup    : glibc-2.17-260.el7.x   14/15
  Cleanup    : libgcc-4.8.5-36.el7.   15/15
  Verifying  : kernel-headers-3.10.    1/15
  Verifying  : glibc-headers-2.17-3    2/15
  Verifying  : glibc-2.17-326.el7_9    3/15
  Verifying  : mpfr-3.1.1-4.el7.x86    4/15
  Verifying  : glibc-devel-2.17-326    5/15
  Verifying  : cpp-4.8.5-44.el7.x86    6/15
  Verifying  : gcc-4.8.5-44.el7.x86    7/15
  Verifying  : libmpc-1.0.1-3.el7.x    8/15
  Verifying  : glibc-common-2.17-32    9/15
  Verifying  : libgcc-4.8.5-44.el7.   10/15
  Verifying  : libgomp-4.8.5-44.el7   11/15
  Verifying  : glibc-2.17-260.el7.x   12/15
  Verifying  : libgomp-4.8.5-36.el7   13/15
  Verifying  : libgcc-4.8.5-36.el7.   14/15
  Verifying  : glibc-common-2.17-26   15/15

Installed:
  gcc.x86_64 0:4.8.5-44.el7

Dependency Installed:
  cpp.x86_64 0:4.8.5-44.el7
  glibc-devel.x86_64 0:2.17-326.el7_9
  glibc-headers.x86_64 0:2.17-326.el7_9
  kernel-headers.x86_64 0:3.10.0-1160.81.1.el7
  libmpc.x86_64 0:1.0.1-3.el7
  mpfr.x86_64 0:3.1.1-4.el7

Dependency Updated:
  glibc.x86_64 0:2.17-326.el7_9
  glibc-common.x86_64 0:2.17-326.el7_9
  libgcc.x86_64 0:4.8.5-44.el7
  libgomp.x86_64 0:4.8.5-44.el7

Complete!
[root@hj0216 ~]# rpm -qa | grep gcc
libgcc-4.8.5-44.el7.x86_64
gcc-4.8.5-44.el7.x86_64

1. root 계정 로그인

2. gcc install

3. gcc pkg 설치 조회

 

 

c언어 파일 만들기 및 실행하기

[j@hj0216 ~]$ vi t.c

On vim editor
	  1 #include <stdio.h>
      2 int main(void)
      3 {
      4         puts("Linux\n");
      5         return 0;
      6 }

[j@hj0216 ~]$ gcc t.c
[j@hj0216 ~]$ ls
a.out  bbb  dd  ddd  t.c
[j@hj0216 ~]$ ./a.out
Linux

gcc 컴파일러로 t.c 파일을 컴파일 → a.out 실행 파일 생성 → 생성된 a.out 파일을 이용하여 파일 실행 
컴파일 과정에서 실행파일의 이름을 지정해 주지 않으면 기본적으로 a.out 이라는 이름으로 실행파일이 생성

 

파일 실행 관련 PATH 지정

[j@hj0216 ~]$ a.out
-bash: a.out: command not found
[j@hj0216 ~]$ echo $PATH
/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/j/.local/bin:/home/j/bin
[j@hj0216 ~]$ PATH=$PATH:. # PATH에 현재 dir 추가
[j@hj0216 ~]$ echo $PATH
/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/j/.local/bin:/home/j/bin:.
[j@hj0216 ~]$ a.out
Linux

파일 경로를 찾을 때, 현재 dir이 PATH에 지정되어있지 않으므로 a.out 파일 실행 시 경로지정이 필요

일반 사용자 계정에서 설정한 PATH는 로그아웃 시 사라짐

 

gcc를 통한 c언어 파일 이름 지정

[j@hj0216 ~]$ gcc t.c -o aa
[j@hj0216 ~]$ ls
a.out  aa  bbb  dd  ddd  t.c
[j@hj0216 ~]$ a.out
Linux

[j@hj0216 ~]$ aa
Linux

-o 실행파일명: a.out이 아닌 새로운 실행파일명 지정

 

 

 

➕ C언어 컴파일 과정

1. C언어 파일 작성(vi hello.c)

#include <stdio.h>

int main(int argc, char **argv)
{
    printf("Hello World!\n");

    return 0;
}

 

2. PreProcessing, PreComplie

 - #으로 시작하는 부분은 C complier가 쉽게 인식할 수 있도록 C언어 소스로 재정리

 - /* ~ */과 같은 주석 제거

 - #include: header file의 내용을 읽고 필요한 내용을 복사

 - #define: 치환 작업 진행

-> gcc compiler: hello.i 파일 내부 생성

# 1 "hello.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "hello.c"

# 1 "/usr/include/stdio.h" 1 3 4
# 28 "/usr/include/stdio.h" 3 4

... 중략 ...

# 211 "/usr/lib/gcc/x86_64-redhat-linux/4.4.7/include/stddef.h" 3 4
typedef long unsigned int size_t;

... 중략 ...

extern int printf (__const char *__restrict __format, ...);

... 중략 ...

int main(int argc, char **argv)
{
    printf("Hello World!\n");

    return 0;
}

 

3. Compile(Assembler 코드 생성)

 - 전처리가 끝난 소스코드(hello.i)를 기반으로 assembler 소스코드 생성

-> hello.s 파일 생성

        .file   "hello.c"
        .section        .rodata
.LC0:
        .string "Hello World!"
        .text
.globl main
        .type   main, @function
main:
.LFB0:
        .cfii_startproc
        pushq   %rbp
        .cfi_def_cfa_offset 16
        .cfi_offset 6, -16
        movq    %rsp, %rbp
        
... 이하 생략 ...

 

4. Assemble(Object 파일 생성)

Assembler source(hello.s)를 바탕으로 목적(Object) 파일 생성(기계어 코드)

^?ELF^B^A^A^@^@^@^@^@^@^@^@^@^@^@^A^@>^ ..... 생략 .....

 

5. Link(실행 파일 생성)

obj 파일은 직접 실행할 수 없으므로 실행 파일로 만들기 위해 Link 작업 실시

C언어는 분할 컴파일이 가능하여, A라는 기능을 하는 파일과 B라는 기능을 하는 파일을 따로 만들어서 컴파일을 해서 링크 작업을 통해 여러 파일의 기능을 합쳐서 실행 파일을 만들 수 있음

실행파일도 분할 컴파일을 이용하여 hello.o와 표준 라이브러리인 a 또는 .so 파일을 합쳐서 만들어짐

^?ELF^B^A^A^@^@^@^@^@^@^@^@^@^@^@^A^@>^ ..... 생략 .....

 

# C언어 Compile 과정
    1). 소스 코딩 →  hello.c 
    2). hello.c → preprocess (전처리)  →  hello.i 
    3). hello.i →  컴파일 →  hello.s
    4). hello.s →  Assemble → hello.o
    5). hello.o + library →  Link → hello

 

참고 자료

📑 [ 리눅스 ] gcc 동작과정

📑 3. C언어의 컴파일 과정

📑 [ Linux ] linux 환경 C 컴파일 과정 & make 의 이해