ldconfig는 특정 파일에 연결할 수 없습니다

ldconfig는 특정 파일에 연결할 수 없습니다

ATLASDocker 이미지에 Netlib을 사용 하여 설치했는데 LAPACK이제 실행할 때마다 ldconfig다음 오류가 발생합니다.

ldconfig: Can't link /usr/local/lib//usr/local/lib/libtatlas.so to libtatlas.so
ldconfig: Can't link /usr/local/lib//usr/local/lib/libsatlas.so to libsatlas.so

물론 존재하지 않지만 심볼릭 링크가 아니기 /usr/local/lib//usr/local/lib/libtatlas.so때문에 왜 이 파일을 찾으려고 하는지 혼란스럽습니다 .libtatlas.so

root@cd00953552ab:/usr/local/lib# ls -la | grep atlas
-rw-r--r-- 1 root staff 15242054 Apr 27 08:18 libatlas.a
-rwxr-xr-x 1 root staff 17590040 Apr 27 08:18 libatlas.so
-rwxr-xr-x 1 root staff 17492184 Apr 27 08:18 libsatlas.so
-rwxr-xr-x 1 root staff 17590040 Apr 27 08:18 libtatlas.so

왜 이런 일이 발생합니까? 문제를 해결하거나 이 오류 메시지를 끌 수 있는 방법이 있습니까?

편집: Readelf 출력은 다음과 같습니다.

root@cd00953552ab:/usr/local/lib# eu-readelf -a /usr/local/lib/libatlas.so | grep SONAME
  SONAME            Library soname: [/usr/local/lib/libtatlas.so]

답변1

어떤 이유로, 아마도 라이브러리가 구축된 방식(보다 구체적으로 링크된 방식)과 관련하여 설치 디렉터리를 soname에 저장했습니다. 따라서 libtatlas.so의 soname은 입니다 /usr/local/lib/libtatlas.so. ldconfig라이브러리가 존재하지 않는 경우 동일한 디렉토리에 있는 soname에 연결하려고 시도합니다. 을 찾아서 해당 soname을 확인하고 (디렉토리와 soname이 연결됨) /usr/local/lib/libtatlas.so에서 로 링크를 만들어야 한다고 결정 하지만 그렇지 않기 때문에 실패합니다 . 존재하지 않습니다./usr/local/lib//usr/local/lib/libtatlas.so/usr/local/lib/libtatlas.so/usr/local/lib/usr/local/lib

이 문제를 해결하는 적절한 방법은 라이브러리의 이름이 올바르게 정의되었는지 확인하는 것입니다. 일반적으로 디렉토리 이름이 없을 것으로 예상합니다 libtatlas.so.3(버전은 빌드 중인 라이브러리의 ABI 수준에 따라 다름). 아마도 라이브러리를 다시 빌드하거나 올바르게 빌드된 패키지를 찾아야 할 것입니다...

또는 다음을 사용하여 라이브러리의 이름을 편집할 수 있습니다.패치ELF:

patchelf --set-soname libtatlas.so /usr/local/lib/libtatlas.so

이상적으로는 이 라이브러리를 사용하여 만든 프로그램을 다시 연결해야 합니다. 왜냐하면 그 프로그램에는 soname도 포함되어 있기 때문입니다(PatchELF를 사용하여 패치할 수도 있습니다).

발전하는 시스템에서는 실제로 soname에 버전을 지정하고 싶지만 컨테이너에서는 아마도 중요하지 않을 것입니다. 어쨌든 업그레이드를 위해 컨테이너를 다시 빌드해야 합니다.

답변2

BLAS 라이브러리의 특별한 경우입니다 ATLAS. 실제 원인을 해결하려면 패키지를 빌드하는 데 사용된 makefile을 수정해야 합니다.

추론은 @Stephen Kitt의 답변을 참조하십시오.

그러나--set-soname의 버그에서는 patchelfpatchelf 솔루션이 작동하지 않습니다.

귀하의 라이브러리 경로에는 '/usr/local'이 포함되어 있으므로 소스 코드에서 구축되고 있다고 가정합니다.

소스 코드 루트 디렉터리가 $(SRC)/makes/Make.lib어디에 있는지 파일을 확인하세요 .$(SRC)

특히 다음 줄은 다음과 같습니다.

LDTRY:
    $(LD) $(LDFLAGS) -shared -soname $(LIBINSTdir)/$(outso) -o $(outso) \
       -rpath-link $(LIBINSTdir)  \
       --whole-archive $(libas) --no-whole-archive $(LIBS)

여기서 소이름은 부적절합니다: -soname $(LIBINSTdir)/$(outso). 으로 변경한 -soname $(outso)다음 라이브러리를 다시 빌드하면 이 문제가 해결됩니다.

이미 빌드에 성공했다면 에서 해당 라인을 변경하세요 $(BUILD)/lib/Makefile. 여기서 은 $(BUILD)라이브러리 빌드를 위한 디렉터리입니다. 그런 다음 make shared라이브러리를 구축합니다.

readelf -d libtatlas.so | grep soname결과 .so 파일에서 soname을 확인하려면 다음과 같은 명령을 사용하십시오 . 디렉터리 부분을 포함해서는 안 됩니다.

올바른 makefile을 찾을 수 없는 경우(예: 다른 버전의 를 사용하여 ATLAS) grep -IR soname수정해야 할 지점을 찾으십시오.

관련 정보