728x90
출처:https://csj000714.tistory.com/491
2022. 7. 23. 13:24
반응형
💡 본 문서는 '동적 라이브러리 링킹하는 방법'에 대해 정리해놓은 글입니다.
리눅스에서 간혹 어떠한 프로그램을 설치하거나 실행할 때, 무슨무슨 so 파일(*.so), 가령 libX11.so.6 파일(*.so.*)이 없다고 할 때가 발생합니다. 이 문제에 대한 개념 및 원인과 해결책에 대해 정리하였으니 참고하시기 바랍니다.
1. 동적 라이브러리
1.1 정적 VS 동적 라이브러리
- 정적 라이브러리의 경우: 프로그램을 컴파일할 때 실행파일에 포함되어 배포됩니다.
- 속도가 빠르다는 장점을 가지고 있지만,
- 실행파일의 크기가 커지고 메모리를 상당히 차지하게 됩니다.
- 동적 라이브러리의 경우: 실행 프로그램에서 필요할 때만 라이브러리를 메모리에 올립니다.
- 여러 명령어에서 사용되는 동일한 부분을 특정 디렉터리를 만들어 모아놓고 명령어와 링크를 걸어둡니다.
- 이후 명령어를 사용하면 디렉터리(공유 라이브러리)에 있는 파일을 가져와 메모리에 올려 사용하는 것입니다.
- 따라서 정적 라이브러리 보다는 디스크의 공간을 절약하며 효율적으로 사용할 수 있게 됩니다.
- 이러한 점 때문에 운영체제에서는 동적 공유 라이브러리를 주로 사용합니다.
1.2 동적 공유 라이브러리란?
프로그램들의 공통적인 부분들을 한 디렉터리에 모아 '동적 공유 라이브러리'라 합니다.
1.2.1 의존성
- 동적으로 링크된 프로그램은 적어도 하나 이상의 공유 라이브러리가 필요합니다.
- 만일 프로그램을 실행할 때 필요한 라이브러리를 찾지 못하면 프로그램이 실행되지 않습니다(라이브러리를 찾는 방법은 하단에서 언급하였습니다!).
- ex) GNOME 그래픽 환경에서 동작하는 응용 프로그램을 실행하려고 할 때 관련된 라이브러리인 GTK+가 설치되어 있지 않으면 실행되지 않는다.
1.2.2 링크
- 동적 링크가 이루어진 실행파일과 공유 라이브러리의 파일은 ld.so 에 의해 검사됩니다.
- ld.so 는 링커 역할을 하면서 실행파일을 점검하기도 하는데, 만약 ld.so 가 링크된 라이브러리를 찾지 못하면 파일을 실행할 수 없습니다.
1.3 동적 공유 라이브러리 관련 디렉터리
- 리눅스 운영체제에서 사용되는 공유 라이브러리는 공유물(shared object) 라는 의미로 파일명 뒤에 .so 가 붙는다(*.dll이 붙는 경우도 있습니다).
- 공유 라이브러리 파일들의 위치는 대부분 /lib64 와 /usr/lib 에 나뉘어져 있다.
- /lib, /lib64 = cp나 mv 등과 같은 기본 명령어 및 시스템과 연관된 라이브러리
- /usr/lib = 응용 프로그램과 관련된 라이브러리
- 또한 /lib64, /usr/lib 이외에 다른 디렉터리를 공유 라이브러리로 등록하기 위해서는 ld.so.conf 나 ld.so.cache 파일을 사용합니다.
- /etc/ld.so.cache = 라이브러리 파일 목록정보
- /lib, /usr/lib 파일이나 환경설정(ld.so.conf)파일에 등록된 라이브러리 파일 목록정보를 가지고 있습니다.
- /etc/ld.so.conf = 다른 디렉터리를 공유라이브러리로 등록
- ld.so.conf 파일: 기본적인 공유 라이브러리를 제외한 다른 디렉터리를 추가적으로 만들어 공유 라이브러리로 등록하기 위해 사용하는 환경설정 파일입니다.
- /etc/ld.so.cache = 라이브러리 파일 목록정보
- 추가로 파일을 등록할 때는 한 줄에 하나씩 작성해서 ldconfig 명령으로 정보를 갱신해야 합니다.
- 기본적으로 공유 라이브러리로 설정된 /etc/ld.so.conf 파일을 수정 후 갱신할 때 사용됩니다.
- 다른옵션 없이 ldconfig 명령만 입력해도 내용이 갱신됩니다.
2. 동적 라이브러리 파일(*.so, *.dll)
2.1 *.so 파일이란?
- so 파일은 shared object 파일이란 뜻으로 특정한 기능을 구현해 놓은 파일을 의미합니다.
- 한 프로그램이라 하더라도 일반적으로 사용되는 여러 기능이 내부에서 다른 so 파일들을 통해서 이루어 지게 됩니다.
2.2 그렇다면 *.so 파일는 어떻게 사용(연결)할까?
만약 내가 설치하고자 하는 파일이 특정 기능 때문에 어떤 so 파일이 필요하다고 할 때, 어떤 경우는 설치시 so 파일 존재 여부를 확인해 보거나, 어떤 경우는 설치된 이후 실제 so 파일에 구현된 기능이 필요할 때 메모리에 올리기 위해 그 so 파일을 찾다가 없어서 에러가 날 때도 있습니다. 그런 경우 주로 다음과 같은 에러 메세지가 나타납니다.
libstdc++.so.5: cannot open shared object file: No such file or directory
libgcc_s.so.1: cannot open shared object file: No such file or directory
- 이는 일반적으로 so 파일을 어디에서 찾아야 하는지를 설정해 놓은 경로를 모두 찾아 보았음에도 불구하고 libstdc++.so.5 와 libgcc_s.so.1 파일을 찾을 수 없었기 때문에 발생합니다.
- 물론 저 파일이 실제로 어딘가에 있기 때문에, 심지어 현재 경로에 있기 때문에 대체 왜 저런 에러가 나타났을까 의아해 할 수도 있는데, so 파일은 특정 경로를 순회하며 찾기에 해당 경로에서 찾지 못하면 위와 같이 같은 에러 메세지가 나타납니다.
2.3 특정 실행파일에 사용되는 *.so 파일는 어떻게 확인할까?
$ ldd ./bin/MbrGen
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f54939be000)
libstdc++.so.5 => not found
libgcc_s.so.1 => not found
- 특정 파일이나 프로그램에 링크되거나 의존하고 있는 공유 라이브러리 정보를 확인할 수 있는 명령입니다.
- 이때,
- libc.so.6의 경우: 파일의 위치를 프로그램 내에서 찾았지만,
- libstdc++.so.5, libgcc_s.so.1의 경우: 파일의 위치를 찾지 못한 것을 확인할 수 있습니다.
- 이는 특정 파일에 파일의 경로를 추가해주어 링킹할 수 있습니다.
2.4 *.so 파일은 어디에 있을까? 링킹하려면 경로를 알아야 할텐데..
$ locate libstdc++.so.5 | more
그렇게 해서 원하는 so 파일을 찾았으면 *.so 파일 경로 설정하는 방법으로 link 할 수 있습니다. 동적 라이브러리 파일의 경로를 지정하는 방법은 하단에서 설명하도록 하겠습니다.
3. *.so 파일 경로 설정
3.1 *.so 파일을 찾는 순서
- LD_LIBRARY_PATH
- system default 경로
- /lib
- /usr/lib
3.2 *.so 파일 경로 설정 방법
- LD_LIBRARY_PATH
- system default 경로
- binary code 에 hard-coding 된 경로
3.3 *.so 파일 경로 설정 상세 방법
3.3.1 LD_LIBRARY_PATH
LD_LIBRARY_PATH라는 환경 변수에 경로를 넣어주어 설정할 수 있습니다. 환경 변수를 확인하고 동적 라이브러리의 경로를 추가해줍시다.
$ env
$ env | grep LD_
$ export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/home/${USER}/gmbdsvr/MbrGen/AutocryptV2X/lib
$ export LD_LIBRARY_PATH=/usr/local/lib64:$LD_LIBRARY_PATH
$ env | grep LD_
LD_LIBRARY_PATH=:/home/sjchoi/gmbdsvr/MbrGen/AutocryptV2X/lib
- env | grep LD_: 'LD_'가 들어가 있는 환경 변수를 찾아줍니다.
- 처음 찾았을 때는 변수가 지정되지 않은 것을 확인할 수 있는데, export로 지정해준 후 확인하면 적용된 것을 확인할 수 있습니다.
- 하지만 이렇게 지정해줄 경우 터미널을 다시 실행하거나 재부팅하는 경우, 변수를 다시 설정해야하기에, ~/.bash_profile과 같이 bash shell을 실행할 때마다 변수를 지정해주는 곳에 저장할 필요가 있습니다.
$ nano ~/.bash_profile
...
export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/home/sjchoi/lib
// 수정한 .bash_profile 파일을 적용
$ source ~/.bash_profile
3.3.2 system default 경로 feat. /etc/ld.so.conf
$ cat /etc/ld.so.conf
include ld.so.conf.d/*.conf
- 일반적으로 system default 경로는 /usr/local/bin 과 /usr/bin 이며, 이 값은 /etc/ld.so.conf 파일에 설정이 된 값입니다.
- 즉, /etc/ld.so.conf 파일에 설정된 경로를 차례대로 돌아 가면서 원하는 so 파일을 찾습니다.
- 만약 내가 어떤 프로그램을 만들어 그것을 ld.so.conf 에 넣고 싶으면, /etc/ld.so.conf.d/ 경로 밑에 *.conf 파일 이름으로 저장 후 그 파일에 그 경로를 집어 넣으면 됩니다.
$ cat /etc/ld.so.conf
include ld.so.conf.d/*.conf
...
$ ls /etc/ld.so.conf/
libs.conf
$ cat /etc/ld.so.conf/libs.conf
/usr/local/lib
// 위 conf를 수정했다면, ldconfig를 수행하여 적용할 수 있습니다.
$ ldconfig
- include 구문에 의해 ld.so.conf.d 안에 있는 *.conf 파일의 내용들이 ld.so.conf 파일에 모두 들어 가게 됩니다.
- 위 파일을 수정을 했으면 적용하기 위해, ldconfig 명령어를 실행시켜 줍니다.
3.3.3 binary code에 hard-coding 된 경로
프로그래머가 아예 소스 코드에 so 파일 경로를 설정하는 방법도 있습니다. 물론 hard-coding은 어떤 문제의 해결방법이던 권장하진 않습니다.
const char* lib_path[] = { "/home/adnoctum/test/libabcd.so.1.0", "/home/adnoctum/test/libabcc.so.1.0"};
이런 경우 문제가 생기면 사용자가 해결할 수 있는 방법은 그 경로에 so 파일을 가져다 놓는 것인데, 프로그래머가 hard-coding 한 경로를 알지 못하면 도무지 방법이 없습니다. 따라서 이 방법을 사용하기 보다는 위의 방법처럼.
- /etd/ld.so.conf 파일에 특정 so 파일이 있는 경로를 집어 넣거나, 아니면 so 파일을 /usr/local/bin 과 같은 곳으로 이동시키거나 link 를 만들어 줍니다.
- 이때, 일반적으로 프로그램은 여러 개의 so 파일이 사용하게 되므로 하나 옮기거나 링크 만들어도 또 다른 so 파일에서 동일한 에러가 날 수 있으므로 LD_LIBRARY_PATH 에 그 경로를 덧붙이거나 ld.so.conf 파일에 그 경로를 집어 넣는 것이 추천합니다.
- 그런데 locate 로 했는데 정말로 원하는 so 파일이 없는 것이라면, 마지막 방법으로 구글링을 해본다. 그러면 그 so 파일이 어떤 라이브러리에 있는지, 그래서 어떤 라이브러리를 설치해야 하는지를 알 수 있습니다.
참고
- 동적 라이브러리: https://wiseworld.tistory.com/68
- 리눅스에서 무슨무슨 so 파일이 없다고 할 때: https://adnoctum.tistory.com/541
- linux 에서 라이브러리를 찾을 수 없다며 프로그램 실행이 안 될때 해결방법(error while loading shared libraries): https://www.lesstif.com/lpt/linux-error-while-loading-shared-libraries-95880436.html
728x90
반응형
'컴퓨터 활용(한글, 오피스 등) > 50_2.운영체제_리눅스' 카테고리의 다른 글
CentOS 8/7에서 Apache Tomcat 9를 설치 및 구성하는 방법 (1) | 2023.11.14 |
---|---|
Centos 7 환경에서 Tomcat 9 설치 (0) | 2023.11.13 |
리눅스에서 서버 구축 CENTOS (1) | 2023.11.13 |
리눅스 라이브러리 경로 추가 Linux library path setting (1) | 2023.11.13 |
Using Emacs on Windows 11 with WSL2 (0) | 2023.11.12 |