[C] gcc 기본 옵션 정리

Yongjun Park·2022년 1월 24일
0

man gcc 중 일부를 발췌하여 번역하였습니다.
위 링크에 들어가셔서 아래에 있는 영어를 Ctrl+F로 찾으면 쉽게 원문을 읽으실 수 있습니다.


-o file

Place the primary output in file file. This applies to whatever sort of output is being produced, whether it be an executable file, an object file, an assembler file or preprocessed C code.

산출물이 file이라는 이름으로 나온다. 산출물이 실행 파일, 목적 파일, 어셈블리어 파일, 전처리된 파일이든 상관 없다.

If -o is not specified, the default is to put an executable file in a.out, the object file for source.suffix in source.o, its assembler file in source.s, a precompiled header file in source.suffix.gch, and all preprocessed C source on standard output.

-o 옵션이 지정되지 않으면, 디폴트값은 다음과 같다.

  • 실행파일인 경우 a.out
  • 목적파일인 경우 source.o
  • 어셈블리어 파일인 경우 source.s
  • 전처리된 헤더 파일의 경우 source.suffix.gch
    • ex) 헤더 파일 이름이 source.h라면 source.h.gch

탐색할 폴더 지정

-Idir (대문자 아이)

Add the directory dir to the list of directories to be searched for header files during preprocessing.

전처리 과정에서 사용할 헤더 파일이 들어있는 폴더를 추가한다.

-Ldir

Add directory dir to the list of directories to be searched for -l.

라이브러리를 찾는 -l(소문자 엘) 옵션에게 탐색할 폴더를 추가한다.


컴파일 과정에 대한 옵션

-c

Compile or assemble the source files, but do not link. The linking stage simply is not done. The ultimate output is in the form of an object file for each source file.

컴파일하거나 어셈블하기까지 하지만, 링크는 하지 않는다. 산출물은 각 소스 파일의 목적 파일이다.

By default, the object file name for a source file is made by replacing the suffix ‘.c’, ‘.i’, ‘.s’, etc., with ‘.o’.

  • .c의 경우 전처리, 컴파일, 어셈블이 수행된다.
  • .i의 경우 컴파일, 어셈블이 수행된다.
  • .s의 경우 어셈블이 수행된다.

결국 산출물은 .o 확장자를 가진다.

-S

Stop after the stage of compilation proper; do not assemble. The output is in the form of an assembler code file for each non-assembler input file specified.

컴파일 단계까지만 하고 어셈블은 하지 않는다. 산출물은 각 소스 파일의 어셈블리어 코드 파일이다.

By default, the assembler file name for a source file is made by replacing the suffix ‘.c’, ‘.i’, etc., with ‘.s’.

  • .c의 경우 전처리, 컴파일이 수행된다.
  • .i의 경우 컴파일이 수행된다.

결국 산출물은 .s 확장자를 가진다.

-E

Stop after the preprocessing stage; do not run the compiler proper. The output is in the form of preprocessed source code, which is sent to the standard output.

전처리 단계까지만 하고 컴파일은 하지 않는다. 산출물은 각 소스 파일에 전처리만 진행한 파일이다.


최적화 정도에 관한 옵션

-O0, -O1, -O2, -O3

(출처: KLDP Wiki - Gcc Optimization Options)

  • -O0: 디폴트 옵션, 즉 -O[Level] 옵션이 없는 것과 같다. 최적화하지 않는다.
  • -O1: -O와 같다. 목적파일의 수행 시간과 크기 둘 다 적당히 최적화한다.
  • -O2: 목적파일의 크기가 너무 커지지 않는 범위에서 수행 시간을 빠르게.
  • -Os: size에 신경 씀. -O2와 같지만, 목적파일의 크기를 증가시키는 최적화 기능은 제외.
  • -O3: 목적파일의 크기는 신경 쓰지 않고, 오로지 수행 시간만 빠르게.

꼭 생각해 두어야 할 점은, '-O3'로 만들어낸 코드가 반드시 '-O2'를 써서 만들어낸 코드보다 빠르다는 보장은 없다는 것입니다. 왜냐하면, 보통 CPU가 기계어를 수행할 때, 일정한 분량만큼 먼저 CPU 내부의 캐시에 불러와서 수행하는데, '-O3'를 써서 만든 코드는 대개 크기가 커서, 이 캐시에 들어갈 수 있는 명령의 양이 상대적으로 적어지기 때문에, 오히려 느려질 가능성도 있습니다.

-Og

Optimize debugging experience. -Og should be the optimization level of choice for the standard edit-compile-debug cycle, offering a reasonable level of optimization while maintaining fast compilation and a good debugging experience. It is a better choice than -O0 for producing debuggable code because some compiler passes that collect debug information are disabled at -O0.

디버깅 환경이 되도록 최적화. 빠른 컴파일과 좋은 디버깅 환경을 유지하면서 합리적인 수준의 최적화를 제공한다.

Like -O0, -Og completely disables a number of optimization passes so that individual options controlling them have no effect. Otherwise -Og enables all -O1 optimization flags except for those that may interfere with debugging:

-Og는 디버깅을 방해할 수 있는 플래그를 제외한 모든 -O1 최적화 플래그를 활성화한다.


링킹과 관련된 옵션

-l(소문자 엘)

-llibrary
-l library

Search the library named library when linking.

링킹 과정에서 library라는 이름의 라이브러리를 찾는다.

The linker searches a standard list of directories for the library. The directories searched include several standard system directories plus any that you specify with -L.

-Ldir 옵션을 사용하여, 링커로 하여금 라이브러리가 있는지 탐색할 폴더를 추가할 수 있다.

Static libraries are archives of object files, and have file names like liblibrary.a. Some targets also support shared libraries, which typically have names like liblibrary.so.

  • 정적 라이브러리는 lib[name].a
  • 공유 라이브러리는 lib[name].so
$ gcc main.o ./tools/libvector.a
$ gcc main.o -Ltools -lvector

위와 같은 명령어로 라이브러리 추가가 가능하다.

If both static and shared libraries are found, the linker gives preference to linking with the shared library unless the -static option is used.

정적 라이브러리와 공유 라이브러리가 함께 있는 경우, 공유 라이브러리를 먼저 링크한다.

하지만 -static 옵션을 사용한 경우에는 정적 라이브러리를 먼저 링크한다.

라이브러리 링킹 순서에 관한 글

-static

On systems that support dynamic linking, this overrides -pie and prevents linking with the shared libraries. On other systems, this option has no effect.

동적 링킹을 지원하는 시스템에서는, -pie 기능을 오버라이드할 뿐만 아니라 공유 라이브러리와의 링킹을 억제하는 역할도 한다.

-shared

Produce a shared object which can then be linked with other objects to form an executable.

공유 목적파일을 생성한다.

For predictable results, you must also specify the same set of options used for compilation (-fpic, -fPIC, or model suboptions) when you specify this linker option.

예측 가능한 결과를 얻으려면, -fpic 옵션도 함께 써야 한다.

공유 라이브러리를 만드는 명령어는 다음과 같다.

$ gcc -shared -fpic -o libvector.so addvec.c multvec.c
$ gcc main.c ./libvector.so

정적 라이브러리와 공유 라이브러리
pie와 pic에 대해서

profile
추상화되었던 기술을 밑단까지 이해했을 때의 쾌감을 잊지 못합니다

0개의 댓글