라이브러리(1)

Language/C 2011. 9. 8. 10:05

정적 라이브러리

정적 라이브러리란 여러 프로그램에서 사용 되는 함수를 포함하는 오브젝트 파일을 하나의 파일로 다룰 수 있도록 정리해 놓은 것이다. 프로그램을 작성할 때 각각의 소소파일을 컴파일하고 링크해서 하나의 실행 가능한 파일을 생성한다. 이때 다른 프로그램에서도 사용될 만한 모듈이 여러 개의 오브젝트 파일로 나뉘어 있으면 이것들을 한 덩어리로 다루기가 번거로워 진다. 그래서 생각해낸 것이 아카이브 파일이다. 여러개의 오브젝트 파일을 하나의 파일로 모아놓은 것이다. ar 명령어를 사용해 여러 개의 오브젝트 파일을 하나의 아카이브 파일로 합칠 수 있다. OS 따라 ranlib 를 사용하면 이 아카이브 파일 내의 오브젝트가 제공하는 심볼 정보를 해시화해서, 심볼을 제공하는 오브젝트 파일을 효율적으로 검색할 수 있게 된다. 이와 같은 아카이브 파일을 정적 라이브러리라 한다.

# gcc -c -o foo.o foo.c 
# gcc -c -o bar.o bar.c 
# ar ruv libfoo.a foo.o bar.o

라이브러리 내용은 ar 명령어로 확인 가능

 libfoo.a 가 생성 되면 아카이브 파일이 생성된 것이다. 정적 라이브러리를 링크할 경우, 링커는 다른 오브젝트 파일에서 정의되지 않은 심볼을 찾아 지정된 정적 라이브러리에서 해당 심볼을 정의하고 있는 오브젝트 파일의 사본을 추출해서 실행 파일 내에 포함 시킨다.

# gcc -L./ -o main main.o -lfoo

 정적 라이브러리를 링크해서 생성된 실행 바이너리를 실행할 경우에는 정적 라이브러리가 없어도 관계 없다. 필요한 코드는 실행 바이너리에 복사되어 포함되어 있기 때문이다.

사용자 삽입 이미지

클릭해서 보세요

위 화면은 main.c 에서 아카이브 파일 내에 있는 SUM 함수를 호출하고 컴파일한 결과이다. 라이브러리를 지정해 주지 않으면 SUM 은 정의되지 않은 심볼이라고 해서 에러가 난다. 라이브러리 경로를 지정해주고 사용할 라이브러리를 적어주면 컴파일 완료

공유 라이브러리

 공유 라이브러리는 공유 된다는 점에서 정적 라이브러리와 다르다. OS 의 가상 메모리 관리 시스템이 진보함에 따라, 하나의 파일을 mmap, semget 등을 이용해 여러 프로세스에서 메모리를 공유, 참조 할 수 있게 되었다. 이를 활용할 수 있도록 한 것이 공유 라이브러리이다. 과거 OS 는 이 공유 메모리가 거대하게 클 경우에도 프로그램이 실행하기전 로드해야 했기 때문에 비효율적이었지만 현재 OS 는 일단 메모리맵을 설정해 두고 그 메모리 내용이 참조 되었을 때 로드하는 형태를 띄고 있다.

gcc -fPIC -c -o foo.o foo.c 
gcc -fPIC -c -o bar.o bar.c 
gcc -shared -Wl, -soname, libfoo.so.0 -o libfoo.so foo.o bar.o

일반적으로 -shared -Wl, -soname 옵션을 사용해 SONAME을 지정한다.

공유 라이브러리도 정적 라이브러리와 똑같이 링크 시킨다.

gcc -L./ -o main main.o -lfoo

실질적인 내부 처리는 main.o 내에 정의 되지 않은 심볼이 공유 오브젝트에 정의 되어 있다면 정적 라이브러리와 같이 코드를 복사 하는 것이 아니라. 공유 오브젝트의 SONAME 을 실행 파일의 NEEDED 의 설정할 뿐이다. 공유 라이브러리를 사용하는 실행파일을 실행한 경우에는 동적 링커 로더(ld.so) 가 NEEDED 의 정보를 이용해 공유 라이브러리를 찾아내어, 실행 시에 해당 프로세스의 메모리맵을 조작해서 공유 라이브러리와 실행 바이너리가 같은 프로세스 공간을 사용하도록 한다.

이러한 공유 메모리는 실행파일의 크기, 메모리 사용공간에 대해서도 매우 유리하다. PIC 코드로 생성해 두면 코드 부분이 어느 주소에 위치하더라도 변경할 필요가 없기 때문에, 공유 라이브러리를 하나의 물리적인 메모리 페이지에 읽어들이는 것만으로 각각의 메모리 공간에 있는 프로세스에서 공유 라이브러리의 메모리 페이지를 공유할 수 있게 된다. 이러한 공유 메모리의 사용은 라이브러리 패치 시에도 굉장히 유용하다. 데몬과 같이 장시간 실행 하고 있는 프로그램의 경우에는 이전의 공유 라이브러리가 이미 메모리에 로드 되어있으므로 다시 실행 시키는 것이다.

Creative Commons License

'Language > C' 카테고리의 다른 글

라이브러리 공격  (0) 2011.09.08
라이브러리(2)  (0) 2011.09.08
library 의 사용  (0) 2011.09.08
gcc 컴파일 과정 요약  (0) 2011.09.07
gcc  (0) 2011.09.07
: