오브젝트 파일
정적 라이브러리
- 여러 오브젝트 파일을 하나의 파일로 다룰 수 있도록 묶어 놓은 라이브러리
- 정적 라이브러리를 링크할 경우, 링커는 다른 오브젝트 파일에서 정의되지 않은 심볼을 찾아 지정된 정적 라이브러리에서 해당 심볼을 정의하고 있는 오브젝트 파일의 사본을 추출해서 실행 파일 내에 포함시킨다.
- 라이브러리 내 오브젝트 파일 단위로 처리된다.
- 링크 시에는 실행파일 내에 오브젝트 파일의 사본이 포함된다.
# 컴파일하여 오브젝트 파일 생성
$ cc -c -o foo.o foo.c
$ cc -c -o bar.o bar.c
# 하나의 정적 라이브러리로 아카이빙
$ ar ruv libfoo.a foo.o bar.o
# 아카이빙 파일 확인
$ ar tv libfoo.a
# baz.o 내에 정의되어있지 않은 심볼이 libfoo.a에 정의되어 있다면 오브젝트를 포함하여 링크
$ cc -o baz baz.o -lfoo
공유 라이브러리
- 하나의 파일을
mmap 등을 이용해 여러 프로세스에서 메모리를 공유해서 참조할수 있다는 점을 활용
- 정적 라이브러리의 경우는 오브젝트 파일의 아카이빙 형태이지만, 공유 라이브러리는 여러 오브젝트 파일을 하나의 거대한 오브젝트 파일로 만들어 이를 공유할 수 있도록 한것.
# 위치 독립코드 옵션을 사용하여(-fPIC) 오브젝트 파일 생성
$ cc -fPIC -c -o foo.o foo.c
$ cc -fPIC -c -o bar.o bar.c
# 공유 오브젝트 생성 옵션(-shared)과 링커에게(-Wl) libfoo.so.0 이라는 SONAME(-soname) 파라미터를 전달
$ cc -shared -Wl,-soname,libfoo.so.0 -o libfoo.so foo.o bar.o
# baz.o 내에 정의되어있지 않은 심볼이 libfoo.a에 정의되어 있다면 오브젝트를 포함하여 링크 (정적라이브러리와 같은 방법으로 링킹)
$ cc -o baz baz.o -lfoo
공유 라이브러리 실제 내부 처리
- baz.o 에 정의되지 않은 심볼이 공유 라이브러리에 정의 되어있다면, 해당 공유 오브젝트의
SONAME을 실행파일의 NEEDED 에 설정함
- 공유 오브젝트에 포함되어있는 코드 자체를 복사하지 않음
- 공유 라이브러리를 링크한 실행 파일을 실행 할 경우,
- 동적 링커 로더(ld.so)가
NEEDED의 정보를 이용해 필요한 공유 라이브러리를 찾음
- 실행 시에 해당 프로세스의 메모리맵을 조작하여 공유 라이브러리와 실행 바이너리가 같은 프로세스 공간을 사용하도록 함