Linux

gcc compiler - 2부 (마지막)

chbae 2023. 4. 18. 17:10
728x90

gcc compile의 1부에 이어 3. gcc 사용하여 원하는 컴파일 하기와 4. gcc를 이용한 최적화 컴파일 5. 기타 알아 두면 좋을 만한 것에 대해 설명한다.

3. gcc를 사용해 원하는 컴파일 하기

1) gcc 옵션 적용 규칙

  • 각 옵션은 대부분 그에 상응하는 gcc 내부 변수가 있다. (gcc/options.h)
  • -[f|W|m][옵션]은 설정이고 -[f/W/m]no-[옵션]은 해제이다.
  • 동일 종류의 옵션은 최종 옵션의 값이 적용된다.
  • 그룹 옵션이 존재한다.
  • -f는 flag, -W는 warning, -m은 아키텍처 종속, 기타 나머지들이다.
  • 하나의 옵션이 반드시 하나의 변수만을 바꾸는 것이 아니다. (ex, 그룹옵션)

2) 가장 단순한 컴파일 명령

gcc -W -Wall -O2 -o like like.c
  • -W: 합벅적이지만 모호한 코딩에 대한 경고
  • -Wall: 모든 모호한 코딩에 대한 경고, -W와 함께 사용하면 사소한 모호성에 대해서도 경고가 발생함
  • -O2: 최적화 레벨 2 설정 -> 레벨 2가 크기와 성능의 trade-off가 없이 최적화 수행

3) 반드시 알아야 할 gcc필수 옵션 및 중요 옵션

자주 사용하여 가능한 암기하면 좋을 옵션 들이다.

  • -E: 전처리 과정의 결과를 화면에 보이는 옵션, save-temps 옵션을 사용해 .i 파일을 보는 것을 더 추천
  • -S: assemble 파일만 생성하고 컴파일 과정 중단
  • -c: object 파일만 생성하고 컴파일 과정 중단
  • -v: 컴파일 과정을 화면에 자세히 출력
  • -save-temps: 컴파일 과정중에 생기는 중판 파일들을 현재 디렉토리에 저장
  • -I: header 파일 탐색 디렉토리 추가 -include: header 파일을 소스내 추가할 때 사용
  • -D[macro]: macro를 외부에서 define 할 때 사용
  • -D[macro]=[macro value]: ex) gcc -DPACKAGE=\"likeU\" -o like like.c
  • -U[macro] undef할 때 사용하지만 거의 사용하지 않음
  • -M,-MM: Make 작성할 때 유용한 종속 항목 리스트 출력
  • -nostdinc: default include 디렉토리 탐색하지 않고, -I에 의해 추가된 디렉토리의 헤더 팡리을 찾음
  • -C: -E 옵션과 함께 사용하며 전처리 과정에서 주석 제거하지 않음
  • -ansi: ANSI C 표준에 부합하는 소스를 작성할 때 사용
  • -std=[C 표준들]: ex) -std=c89 -W와 -Wall: -Wall은 모든 모호한 문법에 대한 경고 출력이고 -W는 합벅적이지만 모호한 코딩에 대한 정보 출력
  • -w: 모든 경고 메시지 제거 (-W, -Wall 보다 우선순위가 높다) - 사용권장 안함
  • -O0: 최적화 수행 안함 (default)
  • -O1: -O옵션과 동일하고, 효과가 큰 기본 최적화 수행
  • -O2: 가장 많이 사용하는 최적화 옵션 (application, kernel 컴파일 시 사용)
  • -O3: 가장 높은 레벨의 최적화 수행 -Os: 사이즈 최적화 수행
  • -g: DWARF2라는 디버깅 정보포맷 추가 (-g0 ~ -g3까지 레벨이 있음)
  • -pg: 프로파일 위한 코드 삽입
  • -L[라이브러리 디렉토리]: 라이브러리 찾을 디렉토리 지정
  • -l[라이브러리 이름]: 같이 링크할 라이브러리 지정 - 소스 뒤에 붙이자.
  • -nostdlib: 표준 C 라이브러리 사용 안함 (OS, bootloader, device driver 컴파일할 때 사용)
  • -nostartfiles: crt1.o와 같은 crt object 파일들을 링크하지 않음 (OS, bootloader 컴파일시 사용)
  • -Wl, [링커 옵션], -Xlinker [f링커 옵션]: 옵션을 링커에 직접 전달. gcc가 옵션을 인식하지 못할 때 주로 사용

4. gcc를 이용한 최적화 컴파일

여기서는 -O[최적화 레벨] 에 포함되지 않은 아키텍처 특성을 타는 옵션들에 대해 설명한다.

1) 머신 종속적인 옵션을 이용한 최적화

-march=cpu-type -mtune=cpu-type -mcpu=cpu-type: march 옵션은 지정 프로세서의 instruction set으로 구성된 코드 생성, mtune과 mcpu는 좀 더 최적화 된 코드를 생성

2) 프로파일 결과를 이용한 최적화

컴파일을 한번 수행 후 프로그램 동작 특성을 파악하고, 그 정보를 바탕으로 다시 컴파일하면 좀 더 최적화하는 기법이다.

  • like.c 파일을 -fprofile-generate 옵션을 주어 컴파일하면 생성되는 바이너리에 프로파일 정보를 출력한느 코드가 추가되어 컴파일 됨
  • like 프로그램을 그냥 한 번 수행하면 추가된 프로파일 코드에 의해 프로파일 결과가 들어있는 파일들 (like.gcda, like.gcno)이 현재 디렉토리에 생성
  • 제일 위의 컴파일 옵션에서 -fprofile-generate 옵션을 빼고, -fprofile-use 옵션을 추가해서 like.c를 다시 컴파일하면 좀 더 최적화해 like 바이너리를 생성

3) 함수 프레임 포인터 제거

-fomit-frame-pointer: 프레임 포인터 설정이 필요 없는 (함수 내에서 다른 함수 호출 안하는) 함수에 대해 프레임 포인터 설정을 제거함

4) prefetch를 이용한 최적화

나중에 프로그램 수행에 필요한 메모리 값을 캐시에 미리 가져다 놓도록 프로세서에게 지시하넌 것을 말한다.

  • -fprefetch-loop-arrays: 루프에 진입하기 전 컴파일러는 루프 내에서 사용할 메모리 영역을 캐시에 미리 가져다 놓는 prefetch instruction 삽입함 (이유는 프로세스는 매우 따른 데 반해 메모리는 느리기 때문임)

5) gcc 컴파일 속도 최적화

-pipe: gcc 컴파일 시 /tmp에 임시 파일 생성하고 각 과정에서 이 입력을 받아 컴파일 하지만, 이를 사용하면 pipe로 전달해 컴파일 속도를 좀 더 빠르게 할 수 있음

5. 기타 알아두면 좋을 만한 것들

1) 환경 변수를 사용한 gcc 설정

  • COMPILER_PATH: 전처리기(cc1 -E), 컴파일러(cc1), 어셈블러(as), 링커(collect,ld) 호출할 때 등록된 환경변수 먼저에서 먼저 처리
  • C_INCLUDE_PATH / CPLUS_INCLUDE_PATH / OBJC_INCLUDE_PATH: 전처리 할 때 헤더 파일 찾는 디렉토리 지정 환경 변수
  • LIBRARY_PATH: 라이브러리 찾을 때 지정하는 환경 변수

2) specs 파일을 이용한 gcc 설정

gcc -dumpspecs > specs 명령어로 내장된 specs 파일 덤프 할 수 있다. 이 파일을 수정하면 컴파일 드라이버의 동작을 아주 세부적으로 수정할 수 있다. (거의 사용할일 없음 :))

'Linux' 카테고리의 다른 글

ELF 바이너리 파일 포맷 구조  (0) 2023.04.18
ld linker (링커)  (0) 2023.04.18
gcc compiler - 1부  (0) 2023.04.18
shell script 색상 변경  (0) 2023.04.18
tmux (terminal multiplexer)  (0) 2023.04.18