정적 라이브러리와 공유 라이브러리

앞선 게시물에서 libc.so.6가 libc의 중심이 되는 파일이라고 소개했다.
libc.so.6 파일이 심볼링 링크되어 있길래
어떤 파일과 링크되어 있는지 추적해 보았다.
libc_link libc-2.27.so라는 파일로 링크되어 있다.
실행파일이기에 실행해보았다.
libc_execute 라이브러리에 대한 정보가 출력된다.

이 라이브러리 파일명에서 .so가 의미하는 바는 무엇일까?

그래서 공부해보았다.
static/shared_library
위 그림이 정적/공유 라이브러리 개념의 차이를 잘 보여준다.

정적 라이브러리 Static Library *.a (archive)

프로그램 빌드 과정 중,
링크 과정에서 프로그램 코드에 삽입되는 라이브러리 파일이 바로 정적 라이브러리다.
라이브러리 파일의 내용이 빌드가 완료된 프로그램 바이너리 파일에 포함되기 때문에
라이브러리의 내용을 별도의 추가 작업 없이 바로 사용할 수 있다.
같은 정적 라이브러리를 사용하는 다수의 프로그램이 동시에 실행될 경우,
메모리 낭비가 발생하는 단점이 있다.

공유 라이브러리 Shared Library *.so (shared object)

공유 라이브러리는 정적 라이브러리와 달리 프로그램이 실행될 때
라이브러리가 메인 메모리에 올려지게 된다.
따라서 같은 공유 라이브러리를 사용하는 다수의 프로그램이 동시에 실행될 경우,
메모리에 올려진 라이브러리를 공유하기 때문에 효율적인 메모리 활용이 가능하다.
그렇다면 공유 라이브러리가 메모리에 올려지는 과정을 알아보자.
응용 프로그램이 실행되면 내부적으로 dynamic loader라는 프로그램이 실행된다.
이 프로그램이 dynamic link된 공유 라이브러리를 찾아 메모리에 올려주게 된다.


리눅스에서의 dynamic loader는 ld.so이다.
/lib에서 ld.so파일을 찾아 실행시켜보았다.
ld.so 자기는 dynamic loader임을 주장하고 있다.
맞는 거 같다.

ld.so는 공유 라이브러리를 어떻게 찾는걸까?

이를 설명하기 전에 linker name과 soname에 대해 설명하겠다.
가상의 공유 라이브러리 파일 myLib.so.1.2.6이 있다고 가정하자.

이 때, myLib 라이브러리의 linker name은 myLib.so이고 soname은 myLib.so.1이다.

이 라이브러리를 사용하는 프로그램을 빌드할 때,
링커가 linker name을 가진 라이브러리를 찾아 라이브러리의 soname을 읽어오게 된다.
그리고 프로그램이 실행될 때 ld.so가 /lib와 /usr/lib,
그리고 유저가 환경 변수 LD_LIBRARY_PATH에 입력한 경로에서
soname을 가진 라이브러리를 찾는다.
통상적으로 linker name을 가진 파일(myLib.so)을
특정 버전 라이브러리(myLib.so.1.2.6)의 심볼릭 링크로 만들게 되는데
이는 개발 환경에 myLib.so.1.2.6뿐만 아니라 다른 버전의 myLib 또한 존재할 수 있기 때문이다.

피드백은 이메일로 받겠습니다.
yongseokj2@gmail.com