강좌 & 팁
글 수 2,412
2011.02.26 20:04:02 (*.138.143.120)
48927
정적 라이브러리와 공유 라이브러리
정적 라이브러리
정적 라이브러리(static library) 는 여러개의 프로그램에서 사용되는 함수를 포함하는 오브젝트 파일을
하나의 파일로 다룰수 있도록 정리해 놓은 것이다.
프록램을 작성할때 여러개의 다른 프로그램에서 사용할수 있도록 모듈화된 오브젝트 파일들을
하나로 모아 놓은 것이 바로 아카이브 파일(.a) 파일이다.
간단히 만들어 보자.
foo.c
1 #include <stdio.h>
2
3 void foo_a(void)
4 {
5 printf("foo_a\n");
6 }
bar.c
1 #include <stdio.h>
2
3 void bar_a(void)
4 {
5 printf("bar_a\n");
6 }
아래와 같이 컴파일을 한후에 ar 명령으로 아카이브 파일을 생성한다.
root@boggle70-desktop:tmp# cc -c -o foo.o foo.c
root@boggle70-desktop:tmp# cc -c -o bar.o bar.c
root@boggle70-desktop:tmp# ar ruv libfoo.a foo.o bar.o
ar: creating libfoo.a
a - foo.o
a - bar.o
생성된 파일은 ar 명령으로 어떤 파일들을 모아놓았는지 확인할수 있다.
root@boggle70-desktop:tmp# ar tv libfoo.a
rw-r--r-- 0/0 832 Feb 26 15:01 2011 foo.o
rw-r--r-- 0/0 832 Feb 26 15:01 2011 bar.o
root@boggle70-desktop:tmp#
이제 한번 링크를 시켜 봅니다.
main.c
1 #include <stdio.h>
2
3
4 void main(void)
5 {
6 printf("main run\n");
7
8 foo_a();
9 bar_a();
10 }
main.c 를 컴파일 합니다.
root@boggle70-desktop:tmp# cc -c -o main.o main.c
링크를 위해서 라이브러리를 경로에 복사합니다.
root@boggle70-desktop:tmp# cp libfoo.a /lib/
실행파일을 만들면서 라이브러리를 정적링크시킵니다.
root@boggle70-desktop:tmp# cc -o slink main.o -lfoo
실행 파일을 실행합니다.
root@boggle70-desktop:tmp# ./slink
main run
foo_a
bar_a
만약 bar_a() 를 빼고 컴파일 하면 어떻게 될까???
당연히 bar_a 라는 실행은 볼수 없다.
또하나 중요한 변화는 최종 실행 결과물인 slink 에는 ar로 아카이브한 lbifoo.a 에 포함된
두개의 파일 foo.o bar.o 중에서 사용되지 않은 bar.o 를 제외한 foo.o 만이 복사되어
실행파일 내에 포함 된다는 것이다.
공유 라이브러리.
공유라이브러리는 말그대로 여러개의 프로그램에서 실행할수 있도록 만드는 것이다.
일단 공유 라이브러리를 만들어 보자.
root@boggle70-desktop:tmp# cc -fPIC -c -o foo.o foo.c
root@boggle70-desktop:tmp# cc -fPIC -c -o bar.o bar.c
root@boggle70-desktop:tmp# cc -shared -Wl,-soname,libfoo.so -o libfoo.so foo.o bar.o
이렇게 했을때 libfoo.so 라는 파일이 만들어진다.
/lib 디렉토리에 복사한후 libfoo.so.0 라는 파일로 링크를 생성한다
이제 라이브러리를 사용한다. 사용 방법은 동적링크와 동일하다.
root@boggle70-desktop:tmp# cc -o slink main.o -l foo
와 같이 하면 slink 파일이 만들어진다.
root@boggle70-desktop:tmp# file slink
slink: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.15, not strippe
확인해 보면 공유 라이브러리로 링크된것을 확인할수 있다.
컴파일시 PIC(Position Independent Code) 를 사용하면 코드 부분이 어느 주소에 위치하더라도 변경할 필요가 없게 된다.
따라서 한번 메모리에 로드되면 어디에서 참조하더라도 각각의 실행공간에 있는 프로세스에서
공유라이브러리의 메모리 페이지를 공유할수 있게 된다.
참고 자료 : Binary Hacks - O'REILLY