우선 so 파일이 무엇인지 알아 보자. so 파일은 shared object 파일이란 뜻으로 *.so.* 일텐데, 특정한 기능을 구현해 놓은 파일을 의미한다. 즉, 프로그램들은 일반적으로 필요한 기능을 전부 구현하기 보다는 특정 기능이 이미 구현되어 있으면 그 기능이 구현된 파일을 메모리에 올린 후 그 기능을 사용하게 된다. 마치 물건을 조립하는 것과 비슷한 이치인데, 컴퓨터를 조립할 때 쿨러가 필요하면 쿨러를 만드는 회사에서 잘만쿨러 같은 것을 사서 붙이듯이, 예를 들면 인터넷에서 파일을 다운로드 받는 기능이 필요하면 그 기능이 구현된 파일을 메모리에 올린 후 그 기능을 사용하게 되는 것이다. 이처럼 한 프로그램이라 하더라도 일반적으로 사용되는 여러 기능이 내부에서 다른 so 파일들을 통해서 이루어 지게 된다.
그래서, 만약 내가 설치하고자 하는 파일이 특정 기능 때문에 어떤 so 파일이 필요하다고 할 때, 어떤 경우는 설치시 so 파일 존재 여부를 확인해 보거나, 어떤 경우는 설치된 이후 실제 so 파일에 구현된 기능이 필요할 때 메모리에 올리기 위해 그 so 파일을 찾다가 없어서 에러가 날 때도 있다. 그런 경우 주로 다음과 같은 에러 메세지가 나타난다.
libgcc_s.so.1: cannot open shared object file: No such file or directory
왜 저런 말이 나타냤느냐 하면, 일반적으로 so 파일을 어디에서 찾아야 하는지를 설정해 놓은 경로를 모두 찾아 보았음에도 불구하고 libstdc++.so.5 와 libgcc_s.so.1 파일을 찾을 수 없었기 때문이다. 물론 저 파일이 실제로 어딘가에 있기 때문에, 심지어 현재 경로에 있기 때문에 대체 왜 저런 에러가 나타났을까 의아해 할 수도 있는데, so 파일은 그것과 상관이 없이 다음과 같은 순서로 경로들을 순회하면서 찾게 되고, 그렇게 돌았던 경로에서 찾지 못하면 위와 같은 에러 메세지가 나타난다.
1. system default 경로
2. LD_LIBRARY_PATH
3. binary code 에 hard-coding 된 경로
(비슷한 개념으로 경로 설정에 관해 쓴 예전 글)
1. system default 경로
일반적으로 /usr/local/bin 과 /usr/bin 이다. 이 값은 /etc/ld.so.conf 파일에 설정이 된 값이다. 한 번 살펴 보자.
즉, /etc/ld.so.conf 파일에 설정된 경로를 차례대로 돌아 가면서 원하는 so 파일을 찾는다. 물론, 만약 내가 어떤 프로그램을 만들었고, 그것을 내 프로그램이 설치된 경로 밑의 lib 경로에 넣고 그것을 ld.so.conf 에 넣고 싶으면, /etc/ld.so.conf.d/ 경로 밑에 *.conf 파일 이름으로 저장 후 그 파일에 그 경로를 집어 넣으면 된다는 것을 위 첫 번째 줄로부터 알 수 있다. 즉, 첫 번째 줄이
이니까, ld.so.conf.d 경로에 있는 conf 로 끝나는 파일들을 살펴 보면,
total 16
-rw-r--r-- 1 root root 15 Sep 4 2009 mysql-i386.conf
-rw-r--r-- 1 root root 20 Sep 14 2007 qt-i386.conf
-rw-r--r-- 1 root root 25 Dec 10 08:44 xulrunner-32.conf
가 있고, 여기서 다시 mysql-i386.conf 파일의 내용을 보면,
/usr/lib/mysql
꼴랑 한 줄이다. 즉, include 구문에 의해, ld.so.conf.d 안에 있는 *.conf 파일의 내용들이 ld.so.conf 파일에 모두 들어 가게 된다. 그냥 ld.so.conf 파일에 모두 넣지 왜 이렇게 하나 궁금할 수도 있는데, 만약 어떤 프로그램이 10 개의 경로에 so 파일을 분산시켜 넣는다고 하면 괜히 그것 때문에 ld.so.conf 파일이 지저분해 지게 되고, 또 다른 so 파일을 찾을 때 그것 때문에 여러 경로를 순회하므로 다른 프로그램들 성능까지 떨어 뜨리게 된다. 만약 그렇게 지저분했던 프로그램을 지우면 더 골치아파지겠지. 저렇게 했다면 ld.so.conf.d 에 있던, 가령 myprogam.so.conf 파일 (이 파일이 10개의 경로를 갖고 있었다면) 만 지우면 간단히 해결되는 것이었음에도 불구하고, 그 내용이 모두 ld.so.conf 파일에 있었다면 그 경로를 지워도 되는지 (다른 so 파일이 거기 있었으면 지우면 안 될테니까) 아닌지 곤란해 지게 된다. 하여튼, 저렇게 되어 있는 것이 깔끔하다. 1
저렇게 수정을 했으면 적용하기 위해 ldconfig 명령어를 실행시켜 준다.
2. LD_LIBRARY_PATH
이 값은 환경 변수인데, 다음과 같이 직접 써 넣어 줄 수 있다.
~/.bash_profile 파일 내용중 일부.
물론 이렇게 한 후 그것을 적용시키기 위해 source 를 해줘야 겠지.
그런데 이런 방법은 그리 권장되는 것은 아닌듯 싶다.
3. binary code에 hard-coding 된 경로
이 경우는 프로그래머가 아예 소스 코드에 so 파일 경로를 설정해 버린 경우인데, 실제의 예는, 내가 동적 라이브러리를 설명한 글에서 가져 온 다음의 코드이다.
9 const char* lib_path[] = { "/home/adnoctum/test/libabcd.so.1.0",
10 "/home/adnoctum/test/libabcc.so.1.0"};
그런데 이런 경우는 별로 없을 것이다. 또한 이런 경우 문제가 생기면 사용자가 해결할 수 있는 유일한 방법은 그 경로에 so 파일을 가져다 놓는 것인데, 프로그래머가 hard-coding 한 경로를 알지 못하면 도무지 방법이 없겠지. 하여튼 이런 경우는 거의 없다.
위와 같이 설정된 경로에서 찾지 못했다고 한 so 파일은 그렇다면 어디에 있는가? 일단 locate 명령어로 찾아 본다. 그런데 아직 index 가 update 되지 않았을지도 모르므로 root 권한으로 updatedb 를 해주고 나서 locate 를 해준다.
(물론 위 결과는 실제 의미 없다. 저 위 에러 메세지도 나에게서 난 것은 아니다. 그냥 구글링 결과에서 가져 왔을 뿐이다)
그렇게 해서 원하는 so 파일을 찾았으면 /etd/ld.so.conf 파일에 그 so 파일이 있는 경로를 집어 넣거나, 아니면 so 파일을 /usr/local/bin 과 같은 곳으로 이동시키거나 link 를 만들어 준다. 그런데 일반적으로 프로그램은 여러 개의 so 파일이 사용하게 되므로 하나 옮기거나 링크 만들어도 또 다른 so 파일에서 동일한 에러가 날 수 있으므로 ld.so.conf 파일에 그 경로를 집어 넣는 것이 좋아 보인다. 혹은 LD_LIBRARY_PATH 에 그 경로를 덧붙이거나.
그런데 locate 로 했는데 정말로 원하는 so 파일이 없는 것이라면, 마지막 방법으로 구글링을 해본다. 그러면 그 so 파일이 어떤 라이브러리에 있는지, 그래서 어떤 라이브러리를 설치해야 하는지를 알 수 있다. 다음처럼.
- 윈도우즈에서도 프로그램 삭제할 때 "다른 프로그램이 이 파일의 기능을 사용할 수도 있는데 지울 것이냐?" 하고 dll 파일 삭제하기 전에 묻는 경우를 많이 봤을 것이다. 이 경우와 완전히 같다. [본문으로]
'컴퓨터 > 자질구레 팁' 카테고리의 다른 글
매틀랩에서 히스토그램 선으로 그리기 (2) | 2011.03.09 |
---|---|
정규표현식의 최소일치(non-greedy match) (2) | 2011.02.21 |
일러스트레이터에서 지정된 항목을 중심으로 정렬하기 (0) | 2011.02.15 |
파이썬의 도움말을 보는 법 (0) | 2011.02.15 |
왜 firefox를 사용하는가 (0) | 2011.02.06 |