TIL/C언어

[TIL] GCC, GNU Complier Collection

아람2 2024. 10. 4. 12:38
반응형

GCC, GNU Complier Collection

GNU 프로젝트의 오픈 소스 컴파일러 모음집 

 

단순한 컴파일 과정을 넘어 전처리 동작, 어셈블 동작, 링킹 동작을 같이 수행해 Binary file, 실행 가능한 파일을 만드는 역할을 한다 

GCC 는 Front-End 부터 Back-End 까지 모두 자체적으로 개발해 제공되고 있으며, GPLv3 인증으로 모든 소스가 공개되어져 있다 

해당 컴파일러 모음집을 사용할 경우 사용된 소스를 무조건 공개해야 하는 의무를 가지게 된다 

 

GCC 동작 과정

https://helloahram.tistory.com/29

1. 전처리 과정 - 전처리기인 cpp0 에 의해 .i 파일 생성

2. 컴파일 과정 - C 컴파일러인 cc1 를 통해 .s 파일 생성 

3. 어셈블 과정 - 어셈블러인 as 에 의해서 .o 파일 생성 

4. 링킹 과정 - 링커인 collect2 를 통해서 실행 파일 생성 

1. 전처리 과정

a) 헤더 파일 삽입

b) 매크로 치환 및 적용 

전처리기는 #include 구문을 만나면 해당되는 헤더 파일을 찾아 그 파일의 내용을 삽입한다

헤더 파일 삽입이 끝난 후 매크로 치환 작업이 시작된다, #define 된 부분은 심볼 테이블에 저장되고 심볼 테이블에 들어있는 문자열과 같은 문자열을 만나면 치환한다. 그 외 다른 전처리기 매크로들도 함께 처리된다


2. 컴파일 과정

컴파일 과정은 중간 단계인 Middle-End 단계가 있지만 Web Server와 유사하게 Front-End 와 Back-End 로 나뉘어져 있다

https://0xd00d00.github.io/2022/05/29/gcc_clang.html

 

a) 컴파일 과정 Front-End

Front-End 같은 경우 전처리기 동작을 통해 변환된 소스 코드가 올바르게 작성되었는지 확인하는 과정이다 

총 4가지 과정을 거치게 되고, 올바르다고 판단한 소스 코드를 트리 형태로 (GIMPLE) 로 변환한다 

어휘 분석 - 소스 코드를 의미 있는 최소 단위인 토큰 단위로 나눈다

구문 분석 - 문법적 오류를 검출하기 위해, 토큰을 파스 트리 형태로 변환한다 

의미 분석 - 파스 트리를 순회하며 의미 상 오류를 검출한다, 보통 함수의 매개 변수를 잘못 사용하거나 자료형 타입을 잘못 사용하는 것들이 검출된다

중간 표현 생성 - 언어의 독립 특성을 제공하는 GIMPLE Tree 를 생성한다 

 

b) 컴파일 과정 Middle-End

Middle-End 부분에서는 Front-End 단에서 도출된 GIMPLE Tree 를 SSA 형태로 변환한 후 아키텍쳐 의존성을 없애는 작업을 시작한다, 이후 고급 언어와 어셈블리어의 중간 단계인 RTL, Register Transfer Language 를 생성한다 

해당 단계에서 Optimization 이 일어나며, 컴파일러 모음집에 따라 성능 차이가 발생할 수 있다 

* SSA, Static Single-Assignment - 데이터 흐름 분석과 코드 최적화를 위해 사용되는 중간 표현, 보통 정적으로 값과 데이터 타입을 결정하기 위해 변수의 배정 또는 흐름을 분리하는 형태에 사용된다 

c) 컴파일 과정 Back-End 

Back-end 에서는 2가지 최적화가 일어난다

1. RTL Optimization 에 의한 RTL 최적화 (아키텍쳐 의존성 없음)

2. 아키텍쳐 별 코드 최적화 

최적화가 완료되면 Code Generation 을 통해 .s 확장자를 가진 어셈블리 코드를 만든다 

 

 

LLVM 

GCC 를 사용하고 있는 모든 Software 들은 소스 코드를 공개해야 되기 때문에 

대형 SW 회사에서 상업적 손해를 피하게 위해 GCC 대체제로 LLVM 를 개발했다 

LLVM 은 상업적으로 사용하더라도 소스 코드를 공개할 필요는 없으며 사용에 대한 출처 표기만 하면 된다 

 

GCC 컴파일러와 내부적 최적화 등에서는 차이가 있을 수 있지만, 기본 골격 구조는 동일하다 

내부적으로 LLVM 같은 경우 컴파일 단계마다 서브 프로젝트를 두고 운영한다 

1) Front-End ;Clang 프로젝트 

2) Middle-End ; IR (고급 언어와 어셈블러의 중간 단계)

3) Back-End ; LLVM-core 프로젝트 

 

CLANG

LLVM 의 Front-End 를 담당하는 프로젝트 

다양한 언어 (C++, Swift 등) 의 소스 코드를 처리하기 위해 노력하고 있다 

사용 방법도 GCC 와 비슷하며 아래의 명령어를 통해 컴파일이 가능하다 

# clang compiler
$ clang <source file> [-o output path]
반응형

'TIL > C언어' 카테고리의 다른 글

[TIL] Red-Black Tree 구현하기 #1  (1) 2024.10.13
[TIL] qsort 정렬 C언어  (1) 2024.10.05
[TIL] 포인터 Pointer  (0) 2024.10.03
[TIL] 분할 정복  (1) 2024.09.09
[TIL] 복잡도  (3) 2024.09.09