공유 라이브러리를 로드하는 중 오류가 발생했습니다.

공유 라이브러리를 로드하는 중 오류가 발생했습니다.

내 프로젝트 트리는 다음과 같습니다.

src/
include/
Makefile
lib/
   lib/3rdparylib/

저는 코딩을 하지 않지만 3rdpartylib소스 코드를 프로젝트 패키징에 포함하기로 결정했습니다. 다음 단계를 수행하여 소프트웨어를 컴파일했습니다.

$ cd lib/3rdpartylib/
$ make
$ ln -s 3rdpartylib.so.0 3rdpartylib.so

그런 다음 각각을 컴파일합니다.내 거소스 파일은 다음과 같습니다.

$ gcc -c src/file.c -I include -o file.o -l 3rdparylib -L lib/3rdpartylib -I lib/3rdpartylib/include

그런 다음 다음을 연결합니다.

$ gcc file1.o file2.o -l3rdpartylib -L lib/3rdpartylib -o myapp

내가 호스트에 있을 때는 잘 작동합니다. 오늘은 다른 컴퓨터에서 시작하려고 했습니다. 문제없이 컴파일되고 링크됩니다. 그러나 애플리케이션을 실행하려고 하면 다음과 같은 오류 메시지가 나타납니다.

./myapp: 공유 라이브러리 로드 오류: 3rdpartylib.so.0: 공유 개체 파일을 열 수 없습니다. 해당 파일 또는 디렉터리가 없습니다.

나는 다음을 시도합니다 :

export LD_LIBRARY_PATH=/path/to/3rdpartylib.so

작동하는 것 같습니다. 하지만 LD_LIBRARY_PATH를 사용하는 것이 나쁜 습관이라는 것을 알고 있습니다. 애플리케이션을 실행할 때마다 이 변수를 설정해야 한다는 점이 귀찮습니다.

내가 무엇을 놓치고 있나요? 내 호스트에서는 작동하지만(LD_LIBRARY_PATH는 아무 것도 설정되지 않음) 다른 컴퓨터에서는 작동하지 않는 이유는 무엇입니까? 다른 머신이 가상 머신인지 여부는 중요합니까?

도움이 된다면 내 주 컴퓨터는 Debian 컴퓨터이고 내 "새" 컴퓨터는 Virtualbox에서 실행되는 Sabayon(Gentoo)입니다.

답변1

중요한 것은 각 머신이 라이브러리 경로를 다르게 처리하기 때문에 어떤 Linux 배포판을 사용하는지입니다. Gentoo(Sabayon) 시스템에서 시스템 전체에서 타사 라이브러리를 사용하려면 다음을 수행해야 합니다.

  • /etc/env.d/추가 환경 설정을 포함할 이 파일 아래에 파일을 만듭니다 . 파일 이름은 이 구성표를 사용하여 지정됩니다 [0-9][0-9]somename. 두 개의 초기 숫자가 사용되는 순서를 결정합니다. 좋은 방법은 사용자 정의 설정(근처)을 추가하는 것입니다.마지막, 99작동하는 한 이것은 올바른 시작입니다.제목에:다음과 같은 이름의 파일을 만듭니다.

    /etc/env.d/99mythirdpartylib
    

    포함하다

    LDPATH=/path/to/your/library
    
  • 재부팅하지 않고 변경 사항을 적용하려면 루트로 실행하십시오.

    env-update && source /etc/profile
    

    (이렇게 하면 환경이 업데이트되고 실행됩니다 ldconfig).

인용하다, 네가 원한다면.

답변2

이 방법을 사용하여 전체 시스템에 대한 전역 라이브러리 검색 경로를 설정하지 않으려면 다음을 /etc/env.d수행할 수 있습니다.

그냥 LD_LIBRARY_PATH바꾸세요라이브러리의 설정(라이브러리 자체에 설정하면 아무런 효과가 없습니다)은 -Lgcc 매개변수로 설정한 것과 동일합니다.

export LD_LIBRARY_PATH="$PROJ/lib/3rdpartylib/:$LD_LIBRARY_PATH"

(마지막 부분은 변수가 설정된 경우 이를 보존하는 데 사용되지만 일반적으로 그렇게 해서는 안 됩니다.) 이는 현재 셸에서만 작동하며 매번 다시 설정해야 합니다.

또는 다음과 같이 "정적" 라이브러리 검색 경로를 사용하여 연결합니다.

gcc file1.o file2.o -L./lib/3rdpartylib -Wl,-rpath=./lib/3rdpartylib  -l3rdpartylib  -o myapp

-Wlgcc에서 처리되지 않고 링커로 전달되는 명령줄 인수를 지정합니다. 라이브러리 검색 경로는 바이너리에 기록되므로 다른 컴퓨터에서도 작동합니다(라이브러리가 존재하는 한).

첨부된:단지 프로젝트를 개발하고 있는 상황에 대해서 말씀하신 것이므로 시스템 전체 구성 파일에 넣는 것보다 이러한 임시 접근 방식이 더 적절하다고 생각합니다.

답변3

은행:

$ gcc file1.o file2.o -l3rdpartylib -L lib/3rdpartylib -o myapp

lib3rdpartylib.so포함되지도 않은 라이브러리 경로에 있는 파일을 검색하세요 lib/3rdpartylib! gcc 매뉴얼 페이지를 보면 라이브러리 경로를 지정할 때 플래그 앞에 -L와야 하며 그렇지 않으면 검색되지 않는다고 명시되어 있습니다. -l실제로 가장 간단한 해결책은 라이브러리 자체에 연결하는 것입니다.

$ gcc file1.o file2.o lib/3rdpartylib/3rdpartylib.so -o myapp

이렇게 하면 라이브러리 경로에서 라이브러리가 검색되어 myapp런타임에 동적으로 로드됩니다.

확인하고 싶다면 strace -eopen ./myapp설치 후 한 번만 해보고 어디에서 라이브러리를 로드하려고 하는지 확인하면 됩니다.

답변4

시스템에 라이브러리를 찾을 위치를 알려주어야 합니다. 이 작업은 에 의해 수행됩니다 /etc/ld.so.cache. 에서 라이브러리나 전체 디렉토리를 추가할 수 있습니다 /etc/ld.so.conf.

다음을 수행하여 캐시를 다시 작성할 수 있습니다.

# /sbin/ldconfig -v

관련 정보