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.sosoname 입니다 /usr/local/lib/libtatlas.so. ldconfig동일한 디렉터리에 있는 해당 soname(존재하지 않는 경우)에 라이브러리를 연결해 보십시오. 라이브러리를 찾고, 해당 soname을 확인하고, /usr/local/lib/libtatlas.so(디렉토리 및 soname 연결)에서 링크를 만들어야 하는지 결정하고, 존재하지 않기 때문에 실패합니다./usr/local/lib//usr/local/lib/libtatlas.so/usr/local/lib/libtatlas.so/usr/local/lib/usr/local/lib

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

또는 편집 라이브러리의 soname을 사용할 수 있습니다.패치 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을 찾을 수 없는 경우(예: 다른 버전의 makefile 사용 ATLAS) grep -IR soname수정해야 하는 위치를 찾아보세요.

관련 정보