[Linux] 리눅스 gcc란? gcc로 C언어 컴파일하기

GCC란?

GCC는 GNU 컴파일러 모음(GNU Compiler Collection)이다. GNU는 운영 체제의 하나이자 컴퓨터 소프트웨어의 모음집이다.(참고1) 현재 대부분 GNU와 LINUX를 결합하여 사용하기 때문에 이 조합을 짧게 "Linux"라고 부르는 경우가 많다. 

 

즉, GCC는 리눅스에서 사용하는 컴파일러 모음이라고 생각해도 무방하겠다. GCC는 한때 C언어만을 지원했지만 현재는 C++, JAVA, 포트란 등 다양한 언어를 컴파일 할 수 있도록 지원한다.

 

컴파일러에 대해 잘 모른다면 다음을 참고하자.

 

참고) 

 

[프로그래밍 언어론] 컴파일러와 인터프리터의 차이점

컴파일러(Compiler)란? 컴파일러는 특정 프로그래밍 언어로 쓰여 있는 문서를 다른 프로그래밍 언어로 옮기는 언어 번역 프로그램을 말한다. (출처:https://ko.wikipedia.org/wiki/%EC%BB%B4%ED%8C%8C%EC%9D%BC%EB%9F%

code-lab1.tistory.com

 

 

 

컴파일 과정

소스 코드가 실행 파일로 변환되는 과정을 흔히 컴파일 과정이라고 한다. 정확히 말하자면 컴파일 단계는 소스코드가 실행 파일이 되는 과정 중 하나지만 축약해서 컴파일한다고 표현하는 듯하다.

 

컴파일 과정은 아래와 같은 네 가지 단계로 이루어져 있다.

 

컴파일 과정
[그림 1] 컴파일 과정

 

  • 전처리 단계 : 전처리기(Preprocessor)를 통해 소스 코드 파일(*.c)과 헤더 파일(*.h)을 합쳐 전처리된 소스코드 파일(*.i)로 변환한다. 
  • 컴파일 단계 : 컴파일러(Compiler)를 통해 전처리된 소스코드 파일(*.i)을 어셈블리어 파일(*.s)로 변환한다.
  • 어셈블리 단계 : 어셈블러(Assembler)를 통해 어셈블리어 파일(*.s)을 오브젝트 파일(*.o)로 변환한다.
  • 링킹 단계 : 링커(Linker)를 통해 오브젝트 파일(*.o)들과 라이브러리 파일들을 링크하여(묶어) 하나의 실행 파일로 변환한다.

 

더 자세한 내용은 컴파일 과정에 대한 글을 참고하자(참고 2)

 

 

 

GCC 옵션

GCC를 사용할 때 자주 사용하는 옵션은 다음과 같다.

 

  • -o <file> : <file>에 실행 결과를 저장한다. 이 옵션을 주지 않으면 a.out이 기본 이름으로 적용된다.
  • -E : 전처리 단계만 실행하고 결과를 화면에 출력한다. 파일(*.i)로 저장하려면 -o 옵션과 함께 사용해야 한다.
  • -S : 컴파일 단계까지만 실행하고 어셈블리어 파일(*.s)을 저장한다. (어셈블리X 링킹 X)
  • -c : 어셈블리 단계까지만 실행하고 오브젝트 파일(*.o)을 저장한다. (링킹 X)
  •  -l : 라이브러리 파일을 링크한다.

 

 

GCC 사용 예시

hello.c
[그림 2] hello.c

 

위와 같이 간단한 hello.c라는 소스코드를 작성했다.

 

a.out
[그림 3] a.out

gcc [소스코드 파일] 명령어를 통해 a.out이라는 실행파일이 컴파일되었다.

-o 옵션으로 따로 실행파일 이름을 지정하지 않았기 때문에 기본 이름인 a.out이 적용되었다.

 

실행 파일은 ./[파일명] 와 같이 실행시킬 수 있다.

 

-E 옵션

gcc -E
[그림 4] -E 옵션

 

-E 옵션을 주면 전처리 단계를 실행한다. 이때 -o 옵션을 주지 않으면 화면에 결과가 출력된다

-o 옵션을 이용해 전처리된 소스 코드 파일(*.i)을 저장했다.

 

-S 옵션

gcc -S
[그림 5] -S 옵션

 

-S 옵션을 주면 hello.s 라는 어셈블리어 파일이 생성된 것을 확인할 수 있다.

 

 

-c 옵션

gcc -c
[그림 6] -c 옵션

 

-c 옵션을 주면 hello.o 라는 오브젝트 파일이 생성된 것을 확인할 수 있다.

 

 

 

여러 소스코드를 하나의 실행파일로 만들기

소스코드 하나만을 컴파일하는 경우는 별로 없을 것이다.

보통은 소스코드 여러 개와 헤더 파일까지 같이 컴파일할 것이다.

 

여러 파일 컴파일
[그림 7] 여러 파일 컴파일

 

예를 들어 위와 같이 여러 개의 소스 코드 파일과 헤더파일을 하나의 실행파일로 변환한다고 하자.

 

이는 아래와 같이 할 수 있다.

오브젝트 파일 만들기
[그림 8] 오브젝트 파일 만들기

우선 각각의 소스코드 파일들을 오브젝트 파일로 변환한다. 이때 전처리 과정에서 헤더 파일은 합쳐지게 된다.

 

실행파일 실행
[그림 9] 실행

이후 여러 개의 오브젝트 파일을 링크하여 main.out이라는 실행파일로 변환한다. 

실행해 보면 정상적으로 동작하는 것을 확인할 수 있다.

 

하지만 이렇게 하는 것은 매우 번거롭다. 쉘 스크립트를 작성하여 좀 더 편하게 할 수도 있겠지만 여러 개의 소스코드 파일 중 하나만 변경해도 전부 다시 컴파일해야 한다는 비효율성이 존재한다.

 

이를 해결할 수 있는 방법이 바로 Makefile이다.

추후 이에 대하여 포스팅해 보겠다.

 

 


 

참고

 

1. https://ko.wikipedia.org/wiki/GNU

2. https://bradbury.tistory.com/226

 

반응형

댓글

Designed by JB FACTORY