컴퓨터활용/유닉스

LIBPATH 환경 변수

멜번초이 2016. 6. 24. 23:22

Library 로드 오류

의뢰인이 다음과 같은 문제에 대하여 질문을 하였다. 그래서 몇개의 자료를 찾아 보고 나름 정리를 해 보기로 했다.

Could not load program user:
$> user
Could not load program user:
Dependent module libclntsh.a(shr.o) could not be loaded.
Could not load module libclntsh.a(shr.o).
System error: No such file or directory

UNIX 에서 프로그램 실행시 위와 같은 오류메시지를 만났다면
libclntsh.a 라는 파일을 우선 점검해야 한다. 이 파일이 지정된 디렉토리에 실제로 존재하는 지 점검하고 존재한다면 READ권한이 있는지, PATH에 이 디렉토리가 지정되어 있는지 확인한다.

프로그램 실행시 라이브러리 파일이 존재하는지 체크하는 환경설정은 LIBPATH, LD_LIBRARY_PATH 가 있다. 정확히 어느 환경변수의 것을 참조하는지는 그 메카니즘을 잘 모르겠으니 일단 두 군데 모두다 지정해 줘 버리면 어떻게든 먹지 않을까?

찾아보니 AIX의 informix 설정 매뉴얼에는 이런 문구가 있다. AIX에서는 LIBPATH 에 동적 라이브러리가 있는 디렉토리를 지정해 주는 것이  맞는 거 같다.

LIBPATH 환경 변수는 AIX 시스템의 쉘에 INTERSOLV DataDirect ODBC Driver용 동적 링크 라이브러리를 검색할 디렉토리를 알려줍니다. 제품을 설치한 디렉토리의 완전 경로 이름을 지정해야 합니다.
                    .-:--------.
                    V          |
>>-setenv--LIBPATH----pathname-+-------------------------------><
pathname :라이브러리의 검색 경로를 지정합니다.
Solaris의 경우, LD_LIBRARY_PATH를 설정하십시오. HP-UX의 경우, SHLIB_PATH를 설정하십시오.

참고로 libclntsh.a 파일 속에 shr.o 라는 object 가 포함되어 있는지 확인해 보고자 한다면 nm 명령을 사용해 볼 수 있다. nm 명령은 Shared Object 파일에 대해서도 사용할 수 있다.  또 실행파일이나 *.so파일이 어떤 라이브러리들을 읽어서 실행시키는지 확인해 보고자 한다면 ldd 명령을 이용할 수 있다.

$>nm $ORACLE_HOME/lib/libclntsh.a | grep shr
/oracle/product/10.2.0/lib/libclntsh.a[shr.o]:
.kghbshrt            t      433856
.kghpool_start_shrink T      472032
.kghtshrt            t      434656
.kpucpdsshrink       t       95776
.kpummshrd           T      353568
/net/stadd13/scratch/sshringa/cpu/CPU_OCT2007/patches/aix5l/6397938/npg.c f           -
$>



정적라이브러리(*.a) 공유라이브러리(*.so) 차이점

라이브러리 중에 .a 형태의 정적라이브러리가 있고 .so나 .sl 과 같은 공유라이브러리가 있는데 정적라이브러리는 ar 이란 명령어로 생성을 하고 .so나 .sl 은 cc 명령으로 컴파일하면서 만들게 된다. 정적라이브러리는 프로그램이 실행될 때 참조되어 메모리에 같이 묻어서 올라가게 되고 공유라이브러리는 프로그램이 실행되는 중에 교체도 가능한 방식이다. 

정적라이브러리는 Static Library 라고 하기도 하고 Archive Library라고 부르기도 한다. 반면에 공유라이브러리는 Shared Library 라고 한다. 정적라이브러리의 로직이 변경 되면 이것을 불러서 사용하는 프로그램은 재컴파일 되어야 변경된 로직이 반영된다. 공유라이브러리는 재컴파일 필요없이 프로그램만 재기동하면 변경된 로직이 반영된다. 그러나 어쨌거나 프로그램이 실행되는 시점에는 정해진 디렉토리에 이 라이브러리 파일들이 존재하고 있어야 된다. 그 정해진 위치란 LIBPATH, LD_LIBRARY_PATH 이고 이곳에서 해당 library를 검색하게 된다. 보통 솔루션 업체들은 *.a 와 *.so 를 함께 제공해 주기도 하는데 이것은 이 솔루션을 이용하여 어떤 형태의 프로그램을 만들지 알 수 없기 때문이다., 

 

정적라이브러리(Archive Library)

공유라이브러리(Shared Library)
확장자 .a .so(IBM) 이나 .sl(HP)
라이브러리 로직변경시 반영방법

*.a 교체 후 재컴파일 후 재실행

*.so 교체후 컴파일 없이 재실행
작성방법

ar

ld

실행속도 상대적 빠름 상대적 느림

여전히 공유라이브러리는 개선된 점이 있으나 로직이 변경될 때 이 라이브러리를 불러서 사용하는 프로그램이 재실행이 되어야 하는 핸디캡을 가지고 있다. 이 단점을 개선한 것이 동적적재라이브러리인데 dlopen() 이라는 시스템콜을 이용하여 동작하게 된다. 이 dlopen()을 응용하여 상품화시킨 것이 티맥스소프트의 dlcall 이다. 이것은 라이브러리별 변경여부를 메모리상에서 관리하고 변경이 감지되면 실행중인 프로그램의 동적라이브러리를 실시간으로 재적재해 주는 기능을 포함하고 있다.

C프로그램을 경험하지 않고 자바를 먼저 경험한 사람이라면 개발자 입장에서는 .a, .so, .sl 등의 파일은 자바의 .jar, .zip 파일과 동일한 개념이라고 생각하면 된다. 마찬가지로 자바의 .class 파일은 C의 .o 파일에 해당된다고 생각하면 이해가 쉬울 것이다.

<2008년10월1일>


참고문서 : http://www.linuxjournal.com/article/6463
             : http://kldp.org/HOWTO/html/Program-Library-HOWTO/shared-libraries.html        http://masil.info/entry/%EB%A7%81%ED%81%ACLinkers-%EC%99%80-%EB%A1%9C%EB%8D%94Loaders
http://publib.boulder.ibm.com/infocenter/idshelp/v10/index.jsp?topic=/com.ibm.sqlr.doc/sqlrmst246.htm