라이브러리 경로의 기본 설정을 지정하는 방법은 무엇입니까?
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
내$PATH
en` 변수 의 시작 또는 끝에 추가/my/dir/libfoo.so.0
g ++에 인수로 추가
새 라이브러리가있는 경로를 추가합니다 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++ /my/dir/libfoo.so.0 ...
-lfoo
절대 경로를 추가 한 후 제거하는 것을 기억 했습니까 ?
이것은 오래된 질문이지만 아무도 이것을 언급하지 않은 것 같습니다.
당신은 그 일이 전혀 연결되어 있다는 것을 운이 좋았습니다.
당신은 변화가 필요했습니다
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.a
libfoo.so
libfoo.so.0
ln
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.
Adding the file directly to g++
's command line should have worked, unless of course, you put it prior to bar.cpp
, causing the linker to ignore it for lacking any needed symbols, because no symbols were needed yet.
As an alternative, you can use the environment variables LIBRARY_PATH
and CPLUS_INCLUDE_PATH
, which respectively indicate where to look for libraries and where to look for headers (CPATH
will also do the job), without specifying the -L and -I options.
Edit: CPATH
includes header with -I
and CPLUS_INCLUDE_PATH
with -isystem
.
If one is used to work with DLL in Windows and would like to skip .so version numbers in linux/QT, adding CONFIG += plugin
will take version numbers out. To use absolute path to .so, giving it to linker works fine, as Mr. Klatchko mentioned.
참고URL : https://stackoverflow.com/questions/2726993/how-to-specify-preference-of-library-path
'developer tip' 카테고리의 다른 글
프로비저닝 프로필 갱신 (0) | 2020.09.22 |
---|---|
"hg cat"또는 "svn cat"의 git에 해당 (0) | 2020.09.22 |
iOS 장치 (모바일 Safari)의 입력 필드에서 프로그래밍 방식으로 텍스트 선택 (0) | 2020.09.21 |
HTTP 상태 코드 0-오류 도메인 = NSURLErrorDomain? (0) | 2020.09.21 |
Swift에서 Array [String] 슬라이싱 반환 유형이 [String]이 아닌 것 같습니다. (0) | 2020.09.21 |