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

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 ++에 인수로 추가



답변

새 라이브러리가있는 경로를 추가합니다 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)


답변

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

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

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

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, 링커는 아직 기호가 필요하지 않았기 때문에 필요한 기호가 부족하여 파일을 무시하게됩니다.


답변

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

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

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


답변

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

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


답변

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


답변