링크/컴파일 시 포함된 공유 객체를 정의하는 방법을 이해합니다. 그러나 실행 파일이 *.so
실행될 때 공유 객체(라이브러리)를 어떻게 찾는지 여전히 알고 싶습니다 .
예를 들어, 내 애플리케이션은 a.out
라이브러리에 정의된 함수를 호출합니다 lib.so
. 컴파일 lib.so
후 $HOME
.
a.out
어디서 찾을 수 있는지 어떻게 알 수 있나요 ?
답변1
이것공유도서관 안내관련된 대부분의 메커니즘을 설명합니다.다이나믹 로더 매뉴얼자세한 내용은. 각 UNIX 변형에는 고유한 방식이 있지만 대부분은 동일한 실행 파일 형식(매우 낮은 주파수) 그리고 다음과 같은 것이 있습니다동적 링커1(솔라리스에서). 아래에서는 Linux의 일반적인 동작을 요약하는 데 중점을 둘 것입니다. 전체 그림을 보려면 시스템 설명서를 확인하세요.
(용어 참고 사항: 공유 라이브러리를 로드하는 시스템 부분은 종종 "동적 링커"라고 불리지만 때로는 "동적 로더"라고 더 정확하게 불립니다. "동적 링커"는 다음을 위한 명령의 컴파일 타임 생성을 나타낼 수도 있습니다. 동적 로더 프로그램 또는 컴파일 타임 도구와 런타임 로더의 조합입니다. 이 답변에서 "링커"는 런타임 부분을 나타냅니다.
간단히 말해서 .so
링커는 동적 라이브러리(파일)를 찾을 때 다음을 시도합니다.
- 환경 변수에 나열된 디렉토리
LD_LIBRARY_PATH
(DYLD_LIBRARY_PATH
OSX의 경우) - 실행 파일에 나열된 디렉터리길;
- (적어도 Linux에서는)
/etc/ld.so.conf
플러스 및/lib
의 항목으로 구성된 시스템 검색 경로의 디렉토리입니다/usr/lib
.
rpath는 실행 파일에 저장됩니다(동적 속성임 DT_RPATH
) DT_RUNPATH
. 여기에는 $ORIGIN
실행 파일의 위치에 상대적인 경로를 나타내기 위해 절대 경로나 로 시작하는 경로가 포함될 수 있습니다 . 예를 들어 실행 파일이 에 있고 /opt/myapp/bin
해당 rpath가 이면 $ORIGIN/../lib:$ORIGIN/../plugins
동적 링커는 /opt/myapp/lib
및 를 찾습니다 /opt/myapp/plugins
. rpath는 일반적으로 실행 파일을 컴파일할 때 옵션을 통해 결정되지만 그런 다음 사용할 수 있습니다 -rpath
.ld
chrpath
.
설명하는 시나리오에서 애플리케이션의 개발자 또는 패키저이고 이를 구조에 설치하려는 경우 …/bin
시스템 에 미리 빌드된 바이너리를 설치하는 경우 라이브러리를 의 디렉터리에 넣습니다 …/lib
. -rpath='$ORIGIN/../lib'
검색 경로( /usr/local/lib
시스템 관리자인 경우 경로를 추가한 디렉터리에 넣거나 $LD_LIBRARY_PATH
)를 시도하십시오 chrpath
.
답변2
Linux에서는 이 동작이 ld(1)
매뉴얼 페이지에 명확하게 명시되어 있습니다.
The linker uses the following search paths to locate required shared libraries: 1. Any directories specified by -rpath-link options. 2. Any directories specified by -rpath options. The difference between -rpath and -rpath-link is that directories specified by -rpath options are included in the executable and used at runtime, whereas the -rpath-link option is only effective at link time. Searching -rpath in this way is only supported by native linkers and cross linkers which have been configured with the --with-sysroot option. 3. On an ELF system, for native linkers, if the -rpath and -rpath-link options were not used, search the contents of the environment variable "LD_RUN_PATH". 4. On SunOS, if the -rpath option was not used, search any directories specified using -L options. 5. For a native linker, the search the contents of the environment variable "LD_LIBRARY_PATH". 6. For a native ELF linker, the directories in "DT_RUNPATH" or "DT_RPATH" of a shared library are searched for shared libraries needed by it. The "DT_RPATH" entries are ignored if "DT_RUNPATH" entries exist. 7. The default directories, normally /lib and /usr/lib. 8. For a native linker on an ELF system, if the file /etc/ld.so.conf exists, the list of directories found in that file. If the required shared library is not found, the linker will issue a warning and continue with the link.
답변3
나는 여기에 대한 대답이 이라고 확신합니다 ldconfig
.
ldconfig는 명령줄에 지정된 디렉토리, 파일 /etc/ld.so.conf 및 신뢰할 수 있는 디렉토리(/lib 및 /usr/lib)에 있는 최신 공유 라이브러리에 대한 필요한 링크와 캐시를 생성합니다. 이 캐시는 런타임 링커 ld.so 또는 ld-linux.so에서 사용됩니다. ldconfig는 업데이트해야 하는 링크 버전을 결정할 때 발견되는 라이브러리의 헤더와 파일 이름을 확인합니다.
답변4
실행 중인 애플리케이션의 경우 이 파일에는 /proc/1234/maps
실제 동적 링크 라이브러리가 모두 포함되어 있습니다.
1234
실행 중인 실행 파일의 pid는 어디에 있습니까?
Gilles가 답변에서 지적했듯이 Linux는 LD_LIBRARY_PATH 및 기타 변수를 존중합니다.