gcc options
gcc
공유 라이브러리 제작 / 사용 옵션
1
-fPIC
PIC : Position-Independent Code를 생성한다. shared library같은 경우 메모리의 어느 위치에 로딩되는지가 컴파일 타임에 결정되지 않기 때문에 절대주소 대신 상대주소(offset)를 사용하도록 컴파일하는 옵션이다. 즉, 다른 바이너리에서 이 라이브러리의 함수를 호출할 때 PLT와 GOT를 사용하도록 하는 옵션 이라고 생각하면 된다. library의 mapping 주소 + offset이 해당 symbol의 주소가 된다. mapping 주소는 ldd로, offset은 nm으로 확인 가능하다.
1
-shared
shared library(.so)를 생성하겠다는 의미.
1
-llibrary
library는 함수 이름이 아니라 파일 이름이다. 파일 이름이 liblibrary.so 이면, 앞의 lib와 뒤의 .so를 제거하고 -llibrary
와 같이 사용한다. Search the library named library when linking. It makes a difference where in the command you write this option; the linker searches and processes libraries and object files in the order they are specified. -l
옵션은 해당 라이브러리를 호출하는 파일 뒤에 위치해야 하며 -L
옵션 앞에 위치해야 한다. 그래야 library를 찾을 dir을 먼저 읽고, library를 읽은 다음 파일에서 라이브러리를 호출하게 된다.
1
-Ldir
Add directory dir to the list of directories to be searched for -l.
standard system directories 이외에 추가로 -l
옵션의 library를 찾을 directory를 지정하기 위해 사용한다.
동적 라이브러리를 사용하기 위한 옵션
1
-ldl
사실 -llibrary
옵션인데, library
에 dl
이 들어간 것. dlopen()
사용하려면 꼭 써줘야한다. -ldl
옵션이 로딩하는 libdl.so
에 dlopen()
이 있기 때문.
1
-rdynamic
Pass the flag -export-dynamic to the ELF linker, on targets that support it. 링커에게 -export-dynamic
을 넘기는 것이므로 -Wl,-export-dynamic
과 동일하다. 링커가 dynamic symbol table에 모든 symbol을 추가하도록 하는 옵션이다. dlopen man page에는 쓰라고 나오던데, -ldl
만 써도 되길래 그냥 안썼다. 써본 적이 없다.
공유 라이브러리 컴파일 command
공유 라이브러리를 컴파일
1
gcc -shared -fPIC -o lib.o lib.c [-llibrary -Ldir]
라이브러리를 사용할 파일과 라이브러리 파일 모두 header파일을 include해야하며, header파일 없으면 컴파일 시 오류난다.
공유 라이브러리를 사용하는 실행파일 컴파일
1
gcc -o out out.c -llibrary -Ldir
동적 라이브러리를 사용하는 실행파일 컴파일
1
gcc -o out out.c -ldl
쉘코드 관련 옵션
-S
Compile only; do not assemble or link 어셈블리 파일(.s)을 생성하는 옵션.2016/12/10 - [System/etc] - .s 파일 수정 \_\_volatile\__
을 사용했다면 어셈블리야 굳이 .s 생성할 필요 없이 gdb로 확인해도 된다. -static
static으로 컴파일하면 PLT, GOT 사용 안하고 바로 call libcaddr한다. dynamic linking 사용 안하기 때문에 라이브러리 종속성을 제거할 수 있다.
1
gcc -c -o sum.o sum.cpp
컴파일만 하고 링크는 진행하지 말라고 알려주는 옵션이 -c
object 파일(.o)이 생성된다. object 파일을 생성하고 링크를 나중에 진행하는 경우는 프로그램이 여러 소스파일로 이루어진 경우다. 그냥 컴파일 하게 되면 gcc -o main main.c f2.c f3.c
같이 입력하게 될텐데, ` main, f2, f3이 한꺼번에 컴파일된다. 따라서 그 중 한 파일이라도 소스코드가 변경되었다면 이런 방법으로는 모두 재컴파일 해야한다. 그러나
-c옵션을 이용해
gcc -c main; gcc -c f2; gcc -c f2` 해서 object파일을 만들어 놓으면 소스코드가 변경되는 경우 변경된 파일만 재컴파일 후 링크만 진행하면 된다.
gcc compile process
-c
옵션으로 생성되는 Object 파일은 .s파일을 어셈블러가 해석해서 만든 기계어 코드다. linking이 안되어 있기 때문에 주소 정보가 확정되어있지 않은 상태다.
object 파일을 실행 파일로 링크할 때 symbol 정보를 사용한다. 따라서 symbol 정보는 링크가 끝나면 필요없어진다. 디버거에게 추가적인 정보를 제공하지 않기 위해 링커에 옵션을 지정해 빌드 시 symbol information을 삭제할 수 있다. 또는 빌드 이후 strip tool을 이용해 삭제하는 방법도 있다.