라이브러리 경로의 기본 설정을 지정하는 방법은 무엇입니까?


95

g++및을 사용하여 C ++ 프로그램을 컴파일 하고 ld있습니다. 나는이 .so내가 원하는 라이브러리를 연결시 사용. 그러나, 같은 이름의 라이브러리에 존재 /usr/local/lib하고, ld내가 직접 지정하고있어 하나 이상 해당 라이브러리를 선택하고있다. 이 문제를 어떻게 해결할 수 있습니까?

아래 예의 경우 내 라이브러리 파일은 /my/dir/libfoo.so.0. 작동하지 않는 시도한 것 :

  • 내 g ++ 명령은 g++ -g -Wall -o my_binary -L/my/dir -lfoo bar.cpp
  • /my/dir$PATHen` 변수 의 시작 또는 끝에 추가
  • /my/dir/libfoo.so.0g ++에 인수로 추가

1
어떤 다른 libfoo.*파일이 존재하고 - .so/ O를 w .0, .a, 등 등?
Alex Martelli

답변:


94

새 라이브러리가있는 경로를 추가합니다 LD_LIBRARY_PATH(Mac에서는 이름이 약간 다릅니다 ...).

솔루션은 -L/my/dir -lfoo옵션 을 사용하여 작동해야 하며 런타임시 LD_LIBRARY_PATH를 사용하여 라이브러리 위치를 가리 킵니다.

LD_LIBRARY_PATH 사용에주의하십시오 -간단히 말해서 (링크에서) :

..implications .. :
보안 : LD_LIBRARY_PATH에 지정된 디렉토리가 표준 위치보다 먼저 (!) 검색된다는 것을 기억하십니까? 이런 식으로, 불쾌한 사람이 악성 코드가 포함 된 공유 라이브러리 버전을 애플리케이션에로드하도록 할 수 있습니다! 이것이 setuid / setgid 실행 파일이 해당 변수를 무시하는 이유 중 하나입니다!
공연: 링크 로더는 공유 라이브러리가있는 디렉토리를 찾을 때까지 지정된 모든 디렉토리를 검색해야합니다. 모든 공유 라이브러리의 경우 응용 프로그램이 링크됩니다! 이것은 open ()에 대한 많은 시스템 호출을 의미하며, "ENOENT (해당 파일 또는 디렉토리 없음)"로 실패합니다! 경로에 많은 디렉토리가 포함 된 경우 실패한 호출 수가 선형 적으로 증가하며 애플리케이션 시작 시간에서이를 알 수 있습니다. 디렉토리의 일부 (또는 전체)가 NFS 환경에 있으면 응용 프로그램의 시작 시간이 실제로 길어질 수 있으며 전체 시스템 속도가 느려질 수 있습니다!
불일치: 이것이 가장 일반적인 문제입니다. LD_LIBRARY_PATH는 응용 프로그램이 링크되지 않은 공유 라이브러리를로드하도록 강제하며 이는 원래 버전과 호환되지 않을 가능성이 높습니다. 이것은 매우 명백 할 수 있습니다. 즉, 응용 프로그램이 충돌하거나, 선택한 라이브러리가 원래 버전에서 수행 한 작업을 수행하지 않는 경우 잘못된 결과가 발생할 수 있습니다. 특히 후자는 때때로 디버그하기 어렵습니다.

또는

링커에 gcc를 통해 rpath 옵션을 사용하십시오-런타임 라이브러리 검색 경로는 표준 dir (gcc 옵션)을 찾는 대신 사용됩니다.

-Wl,-rpath,$(DEFAULT_LIB_INSTALL_PATH)

이것은 임시 솔루션에 좋습니다. 링커는 표준 디렉토리를 조사하기 전에 먼저 LD_LIBRARY_PATH에서 라이브러리를 검색합니다.

LD_LIBRARY_PATH를 영구적으로 업데이트하지 않으려면 명령 줄에서 즉시 수행 할 수 있습니다.

LD_LIBRARY_PATH=/some/custom/dir ./fooo

링커가 사용에 대해 알고있는 라이브러리 (예제)를 확인할 수 있습니다.

/sbin/ldconfig -p | grep libpthread
        libpthread.so.0 (libc6, OS ABI: Linux 2.6.4) => /lib/libpthread.so.0

또한 애플리케이션이 사용중인 라이브러리를 확인할 수 있습니다.

ldd foo
        linux-gate.so.1 =>  (0xffffe000)
        libpthread.so.0 => /lib/libpthread.so.0 (0xb7f9e000)
        libxml2.so.2 => /usr/lib/libxml2.so.2 (0xb7e6e000)
        librt.so.1 => /lib/librt.so.1 (0xb7e65000)
        libm.so.6 => /lib/libm.so.6 (0xb7d5b000)
        libc.so.6 => /lib/libc.so.6 (0xb7c2e000)
        /lib/ld-linux.so.2 (0xb7fc7000)
        libdl.so.2 => /lib/libdl.so.2 (0xb7c2a000)
        libz.so.1 => /lib/libz.so.1 (0xb7c18000)

22
LD_LIBRARY_PATH설정하려는 컴파일 타임에 런타임에 검색됩니다 LIBRARY_PATH. gcc.gnu.org/onlinedocs/gcc/Environment-Variables.html
Bjoern Dahlgren

1
라이브러리가 시스템 라이브러리와 완전히 다른 경우, 즉 항상 사용하는 라이브러리라면 rpath 솔루션을 사용하십시오. LD_LIBRARY_PATH는 테스트 용 해킹이며 실행 파일이 올바르게 작동하도록하는 데 필요하지 않습니다.
user2746401

1
맥에 대한 DYLD_LIBRARY_PATH
cbinder

다음은이 답변을 기반으로 작동하는 전체 샘플 명령 (C 용)입니다.gcc myFile.c -o myFile.o -l myLibraryBaseName -Wl,-rpath,locationOfMyLibrary -L locationOfMyLibrary
Jet Blue

25

이것은 오래된 질문이지만 아무도 이것을 언급하지 않은 것 같습니다.

그 일이 전혀 연결되어 있다는 것이 운이 좋았습니다.

당신은 변화가 필요했습니다

g++ -g -Wall -o my_binary -L/my/dir -lfoo bar.cpp

이에:

g++ -g -Wall -o my_binary -L/my/dir bar.cpp -lfoo

링커는 해결해야하는 기호를 추적합니다. 라이브러리를 먼저 읽으면 필요한 기호가 없으므로 그 안에있는 기호를 무시합니다. 링커에서 찾을 기호를 갖도록 링크해야하는 항목 뒤에 라이브러리를 지정하십시오.

또한 필요에 따라 또는 -lfoo이름이 지정된 파일을 구체적으로 검색 합니다. 아닙니다 . 따라서 이름을 지정하거나 라이브러리의 이름을 적절하게 변경하십시오.libfoo.alibfoo.solibfoo.so.0ln

gcc 매뉴얼 페이지를 인용하려면 :

-l library
   ...
   It makes a difference where in the command you 
   write this option; the linker searches and processes 
   libraries and object files in the order they are 
   specified.  Thus, foo.o -lz bar.o searches library z 
   after file foo.o but before bar.o.  If bar.o refers 
   to functions in z, those functions may not be loaded.

파일을 g++의 명령 줄에 직접 추가하는 것은 작동 했어야합니다. 물론 이전에 파일을 넣지 않는 한 bar.cpp, 링커는 아직 기호가 필요하지 않았기 때문에 필요한 기호가 부족하여 파일을 무시하게됩니다.


22

라이브러리의 절대 경로를 지정하면 정상적으로 작동합니다.

g++ /my/dir/libfoo.so.0  ...

-lfoo절대 경로를 추가 한 후 제거하는 것을 기억 했습니까 ?


1
이 솔루션은 나에게도 잘 작동했습니다. 배포판 개발 패키지가 아닌 다른 버전의 Qt5에 연결하려고했습니다. 감사.
wump

@버전 이 지정된 기호에 대해이 작업을 수행하는 방법은 무엇입니까? 최소 예 : github.com/cirosantilli/cpp-cheat/blob/...
치로 틸리郝海东冠状病六四事件法轮功

11

또 다른 방법으로는, 환경 변수를 사용할 수 있습니다 LIBRARY_PATHCPLUS_INCLUDE_PATH각각 도서관과 장소 (헤더 찾는 방법을 찾아하는 방법 표시, CPATH에 -l 및 -I 옵션을 지정하지 않고를, 또한 일을 할 것입니다).

편집 : CPATH와 헤더를 포함 -I하고 CPLUS_INCLUDE_PATH-isystem.


사용 예를 추가해 주시겠습니까?
Hanna Khalil

export LIBRARY_PATH = /path/to/lib당신이 컴파일 같은 콘솔 세션에서
알렉산드르 하 메스

0

Windows에서 DLL로 작업하는 데 사용되며 linux / QT에서 .so 버전 번호를 건너 뛰 CONFIG += plugin려면 추가 하면 버전 번호가 제거됩니다. .so에 대한 절대 경로를 사용하려면 Klatchko가 언급했듯이 링커에 제공하면 정상적으로 작동합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.