728x90
라이브러리
라이브러리는 프로그램을 개발하기 위해 사용되는 함수, 데이터, 자료형 등을 하나로 묶어 놓은 것으로 다른 프로그램드로가 링크되기 위해 존재하며 코드 재사용 및 개발시간 단축을 위해 사용된다.
정적 VS 동적 라이브러리
두 라이브러리의 가장 큰 차이점은 실행 파일에 **링킹**되는 시점입니다.
**링킹** : **Linking(링킹)**은 ***여러 개의 코드와 데이터를 모아서 연결***하여 메모리에 로드될 수도 있고 실행될 수도 있는 한 개의 파일로 만드는 작업이다.
이 파일이 메모리에 로딩되어 실행되낟.
링크는 1. 컴파일 시에 수행되는 경우도 있고, 2. 로딩시에 수행되는 경우도 있고, 3. 실행시에 수행되는 경우도 있다.
**링커** : **Linker(링커)**란 링킹을 담당하는 프로그램이다. 링커는 소프트웨어 개발에서 ***독립적인 컴파일을 가능하게 하는*** 아주 중요한 역할을 담당한다.
링커 덕분에 큰 규모의 응용 프로그램을 한 개의 소스 파일로 구성하는 대신 별도로 수정할 수 있고, 컴파일할 수 있는 보다 관리할 만한 규모의 더 작은 모듈들로 나눌 수 있다.
즉 거대한 프로그램을 하나의 소스 파일이 아니라 수 많은 소스 파일로 모듈화하여 개발을 진행할 수 있는 것이다.
링커 덕분에 우리는 ***모듈 중에 한개를 변경할 때, 다른 파일들을 재컴파일할 필요 없이 이 파일만을 간단히 재컴파일하고 이를 다시 링크하여 변경사항을 적용할 수 있다.***
정적 라이브러리(Static Library)
정적 라이브러리는 실행 파일(프로그램)에 라이브러리의 내용이 포함되는 형식
정적 라이브러리를 사용하는 경우 프로그램을 실행할 때 **별도의 파일들 없이 실행 파일만을 사용하여 프로그램을 실행**할 수 있다.
하지만 실행 파일에 라이브러리의 내용들이 포함되어 **실행 파일의 사이즈가 커지기 때문에 프로그램이 사용하는 메모리의 양도 커진다.** 또한 라이브러리 파일을 다시 만들었다면 이 **라이브러리를 사용하는 모든 실행 파일은 새로 만든 라이브러리 파일을 사용해서 다시 빌드(컴파일)해야한다.**
응용 프로그램에서 정적 라이브러리를 사용하기 위해서는 해당 라이브러리를 링크하여 사용하며, 링크된 라이브러리에 포함된 함수들을 사용할 수 있다.
프로그램을 컴파일하면 링크된 라이브러리의 코드를 링크하여 하나의 실행 파일을 만들어낸다.
정적 링킹은 실행파일을 만들 때 프로그램에서 사용하는 모든 라이브러리 모듈을 복사하는 방식을 말하며 링커에 의해 이루진다. **즉 자신이 작성한 프로그램에서 A라는 외부 함수를 사용했다면, A라는 외부 함수에 대한 정보를 자신이 작성한 프로그램의 실행파일을 만들 때 복사해온다.**
이렇게 모든 라이브러리 모듈을 복사하기 때문에 실행시 별도의 라이브러리 파일이 필요하지 않다. 하지만 실행파일 내에 라이브러리 코드가 저장되기 때문에 프로그램의 크기가 커지고 메모리 효율이 좋지 않다.
한번 실행파일을 생성하면, **정적 라이브러리가 추후 제거되더라도 이미 생성된 실행파일을 실행하는 데는 아무런 문제가 없다는 장점**으로 많은 단점에도 불구하고 아직까지 사용되고 있다.
동적 라이브러리(Dynamic Library)
정적 라이브러리는 응용 프로그램에서 링크하여 컴파일하기 때문에 사용하지 않는 내용들도 모두 실행 파일에 포함되지만 동적 라이브러리는 실행 파일에서 **사용하고자 하는 경우에만 필요한 DLL(동적 라이브러리)를 선택적으로 사용할 수 있다. 즉, DLL에 포함되어 있는 함수들은 실행 파일에 포함되지 않고, 별도의 파일로 존재한다.**
LIB(정적 라이브러리) 파일은 반드시 실행 파일에 포함되지만, DLL 파일은 프로그램이 실행될 때 실행 파일에 포함된다. 따라서 **DLL은 LIB와 달리 새로 만들었더라도 해당 DLL을 사용하는 실행 파일을 수정하지 않아도된다.**
단, DLL 파일에 함수가 추가/삭제 되거나 파라미터가 변경된 경우에는 실행파일의 수정이 필요할 수 있다.
응용 프로그램에서 DLL을 링크하는 방법은 암시적(lmplict) 링크와 명시적(Explicit) 링크 방식이 존재한다.
여러 명령어에서 사용되는 동일한 부분을 특정 디렉터리를 만들어 모아 놓고 명령어와 링크를 걸어둡니다.
이후 명령어를 사용한다면 디렉터리(공유 라이브러리)에 있는 파일을 가져와 메모리에 올려 사용하는 것이다.
이러한 점 때문에 운영체제에서는 동적 공유 라이브러리를 주로 사용한다.
암시적 링크
응용 프로그램의 코드에서는 아무런 작업을 하지 않고, 프로젝트에 DLL을 링크하는 내용들을 기술하여 실행 파일을 빌드하는 방식이다.
**실행 파일이 실행되면 자동으로 DLL을 로드하기 때문에 프로그래머가 DLL을 사용하기 위해 별도의 작업(DLL 파일을 읽고 로드하는 작업)을 하지 않아도 된다.**
하지만 해당 경로에 DLL이 존재하지 않으면 응용 프로그램도 동작하지 않는다는 단점이 있다.
명시적 링크
응용 프로그램을 작성할 때 DLL의 로드가 필요한 부분에서 DLL을 로드하여 사용하도록 하는 방식
프로그래머가 DLL을 로딩하고 DLL에서 제공하는 함수들의 주소를 획득하여 사용해야한다는 단점이 있따. 하지만 **필요한 시점에만 DLL을 로드해서 사용할 수 있고, 사용이 끝나면 DLL을 언로드하기 때문에 메모리를 효율적으로 사용할 수 있다.**
공유 라이브러리 vs 동적 라이브러리
공유 라이브러리와 동적 라이브러리는 비슷한 의미를 가지지만 다른 것이다.
**공유 라이브러리(Shared) Library)**
여러 프로그램에서 사용되는 라이브러리의 단일 인스턴스를 메모리에 로드하여 공유하는 라이브러리
여러 응용 프로그램이 하나의 라이브러리를 사용하면 시스템 자원을 효율적으로 활용할 수 있다.
**동적으로 로드되어 여러 프로세스 간에 공유되기 때문에 공유 라이브러리라고 불린다.
파일 확장자로는 주로 '.so(shared object)가 사용됨
동적 라이브러리**
런타임에 프로그램에 의해 필요할 때 로드되는 라이브러리를 가르킨다.
정적 라이브러리와 대조적으로, 동적 라이브러리는 실행 중에 필요한 부분만을 로드한다.
이는 메모리를 절약하고 여러 프로그램 간에 코드를 공유할 수 있게 한다.
**공유 라이브러리와 유사한 개념이지만, 동적 라이브러리는 반드시 공유되어야할 필요는 없다.
공유 라이브러리는 여러 프로세스 간에 메모리를 공유하는 라이브러리!
동적 라이브러리는 런타임에 필요할 때 로드되는 라이브러리!
때로는 두 용어가 혼용되어 사용되긴하지만 엄밀한 의미에서는 차이가 있다.**
동적 공유 라이브러리
리눅스에서는 많은 명령어와 프로그램이 동적 공유 라이브러리를 이용한다.
리눅스에서 ls, cd, gcc 컴파일러, yum 등 여러 명령어 중에는 공통적으로 실행되어야하는 부분이 몇 가지 존재한다. 이런 프로그램들의 공통적인 부분들을 한 디렉터리에 모아 동적 공유 라이브러리라고 부른다.
이후 관련된 프로그램이나 명령어를 실행했을 때 동적 공유 라이브러리 안에 파일이 링크되어 같이 실행된다. 따라서 동적 공유 라이브러리를 사용하면 실행파일이나 프로그램의 크기를 작게 만들어 사용할 수 있게 된다.
관련 디렉터리로는 /lib64 , /usr/lib 등이 있다.
1. 의존성
동적으로 링크된 프로그램은 적어도 하나 이상의 공유 라이브러리가 필요하다. 만일 프로그램을 실행할 때 필요한 라이브러리를 찾지 못하면 프로그램이 실행되지 않는다.
EX)
GNOME 그래픽 환경에서 동작하는 응용 프로그램을 실행하려고 할 때 관련된 라이브러리인 GTK+가 설치되어 있지 않으면 실행되지 않는다.
2. 링크
동적 링크가 이루어진 실행 파일과 공유 라이브러리의 파일은 ld.so에 의해 검사된다.
ld.so는 링커 역할을 하면서 실행파일을 점검하기도 하는데, 만약 ld.so가 링크된 라이브러리를 찾지 못하면 파일을 실행할 수 없다.
동적 라이브러리 관련 디렉터리
리눅스 운영체제에서 사용되는 고유 라이브러리는 공유물(shared object)라는 의미로 파일명 뒤에 **.so** 가 붙는다.
공유 라이브러리 파일들의 위치는 대부분 /lib64 와 /usr/lib에 나뉘어져 있다.
/lib, /lib64
cp나 mv 등과 같은 기본 명령어 및 시스템 연관된 라이브러리
/usrlib
응용 프로그램과 관련된 라이브러리
예시) rm 명령어의 공유 라이브러리
- ldd 명령을 통해 rm 명령에서 사용되는 공유 라이브러리를 확인한 뒤, lib64 디렉터리에 가면 rm 명령어가 사용하는 파일을 확인할 수 있다.
/lib64, /usr/lib 이외에 다른 디렉터리를 공유 라이브러리로 등록하기 위해서는 주로 ld.so.conf 나 ld.so.cache 파일을 사용한다.
/etc/ld.so.conf
다른 디렉터리를 공유 라이브러리로 등록
/etc/ld.so.cache
라이브러리 파일 목록 정보
ld.so.conf 파일은 기본적인 공유 라이브러리를 제외한 다른 디렉터리를 추가적으로 만들어 공유 라이브러리로 등록하기 위해 사용하는 환경 설정 파일이다.
추가로 파일을 등록할 때는 한 줄에 하나씩 작성해서 **ldconfig** 명령으로 정보를 갱신해야한다.
ld.so.cache 파일은 /lib, /usr/lib 파일이나 환경설정(ld.so.conf) 파일에 등록된 라이브러리 파일 목록정보를 가지고 있다.
공유 라이브러리 관련 명령어
ldconfig
# ldconfig [라이브러리]
-p : 현재 캐시에 저장된 라이브러리 목록 출력
-f : 기본 파일(ld.so.conf) 이외에 다른 환경 설정 파일 설정
기본적으로 공유 라이브러리로 설정된 /etc/ld.so.conf 파일을 수정 후 갱신할 때 사용된다.
다른 옵션 없이 ldconfig 명령만 입력해도 내용이 갱신된다.
만일 다른 라이브러리를 공유로 지정하고 싶을 때는 /etc/ld.so.conf 파일을 먼저 수정하고, ldconfig 명령을 통해 읽어들여 갱신되어야 정상적으로 이용할 수 있다.
ldd
# ldd [파일]
-v : 자세히 출력
-f : 기본 파일(ld.so.conf) 이외에 다른 환경 설정 파일 지정
특정 파일이나 프로그램에 링크되거나 의존하고 있는 공유 라이브러리 정보를 확인할 수 있는 명령어
ldd를 사용할 때는 일반적인 명령어를 그대로 쓰면 제대로 출력되지 않는다.
명령어를 사용할 때는 환경변수에 의해서 인식되서 어디에서든지 사용할 수 있다.
하지만 ld**d를 통해 관련 라이브러리를 확인하고 싶을 때는 해당 명령어나 파일이 위치한 경로를 정확하게 입력해야한다.
----------------------------------------------------------------------------------------
ex**
[root@master ~]# ldd mkdir
ldd: ./mkdir: No such file or directory
[root@master ~]#
[root@master ~]# ldd /bin/mkdir
linux-vdso.so.1 (0x00007ffc4a791000)
libselinux.so.1 => /lib64/libselinux.so.1 (0x0000155547544000)
libc.so.6 => /lib64/libc.so.6 (0x000015554717f000)
libpcre2-8.so.0 => /lib64/libpcre2-8.so.0 (0x0000155546efb000)
libdl.so.2 => /lib64/libdl.so.2 (0x0000155546cf7000)
/lib64/ld-linux-x86-64.so.2 (0x0000155547982000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x0000155546ad7000)
[root@master ~]#
[root@master ~]# ldd /bin/rm
linux-vdso.so.1 (0x00007ffcd95a3000)
libc.so.6 => /lib64/libc.so.6 (0x000014ac34c9f000)
/lib64/ld-linux-x86-64.so.2 (0x000014ac35275000)
mkdir , rm 명령의 공유 라이브러리 확인 결과 3개의 공유 라이브러리가 있다는 것을 알 수 있다.
만약 명령어 마다 이렇게 겹치는 라이브러리를 각자 갖게 된다면 그것만해도 디스크 용량을 상당히 차지할 것이다.
확장자별 라이브러리 구분
확장자 | OS | (동적/정적) 라이브러리 |
.a | 리눅스 | 정적 라이브러리 |
.so | 리눅스 | 동적 라이브러리 |
.lib | 윈도우 | 정적 라이브러리 |
.dll | 윈도우 | 동적 라이브러리 |
*.so 파일 경로 설정
*.so 파일 찾는 순서
1. LD_LIBRARY_PATH
2. system default 경로
3. /lib
4. /usr/lib
*.so 파일 경로 설정 방법
1. LD_LIBRARY_PATH
2. system default 경로
3. binary code에 hard-coding된 경로
LD_LIBRARY_PATH
리눅스 유닉스 계열의 운영체제에서 동적 라이브러리를 찾는 데 사용되는 환경변수
프로그램이 실행될 때, 필요한 동적 라이브러리들은 라이브러리를 찾기 위해 시스템의 여러 디렉토리
를 검색하는데 이 때 LD_LIBRARY_PATH라는 라이브러리의 위치를 지정하는 역할을 한다.
즉 LD_LIBRARY_PATH에 포함된 디렉토리들은 프로그램이 동적 라이브러리를 찾을 때 검색 대상이 된다.
'Dev' 카테고리의 다른 글
[Blog] 블로그 꾸미기 맥 터미널 (0) | 2025.01.15 |
---|---|
HAProxy VS NginX (0) | 2024.05.04 |
파이썬 VS 자바 (0) | 2024.02.17 |
장고 vs 플라스크 (0) | 2024.02.17 |
환경변수 (0) | 2024.01.22 |