Instalei ATLAS
(com Netlib LAPACK
) em uma imagem Docker e agora toda vez que executo ldconfig
recebo os seguintes erros:
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
Claro, /usr/local/lib//usr/local/lib/libtatlas.so
não existe, mas estou confuso porque ele tentaria procurar esse arquivo, já que libtatlas.so
não é um link simbólico:
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
Por que isso estaria acontecendo e existe uma maneira de corrigir/desativar essa mensagem de erro?
Editar: aqui está a saída do Readelf:
root@cd00953552ab:/usr/local/lib# eu-readelf -a /usr/local/lib/libatlas.so | grep SONAME
SONAME Library soname: [/usr/local/lib/libtatlas.so]
Responder1
Por alguma razão, provavelmente relacionada à forma como as bibliotecas foram construídas (e mais especificamente, vinculadas), elas armazenaram seu diretório de instalação em seu soname: portanto, libtatlas.so
soname é /usr/local/lib/libtatlas.so
. ldconfig
tenta vincular bibliotecas ao seu soname, se ele não existir, no mesmo diretório: ele encontra /usr/local/lib/libtatlas.so
, verifica seu soname, determina que um link precisa ser feito de /usr/local/lib//usr/local/lib/libtatlas.so
(o diretório e o soname concatenados) para /usr/local/lib/libtatlas.so
e falha porque /usr/local/lib/usr/local/lib
não não existe.
A maneira apropriada de corrigir isso é garantir que os nomes das bibliotecas estejam definidos corretamente. Normalmente eu esperaria libtatlas.so.3
etc. sem nome de diretório (a versão dependeria do nível ABI da biblioteca que está sendo construída). Você provavelmente precisará reconstruir as bibliotecas ou encontrar um pacote construído corretamente...
Alternativamente, você pode editar o soname de uma biblioteca usandoPatchELF:
patchelf --set-soname libtatlas.so /usr/local/lib/libtatlas.so
Idealmente, você deve vincular novamente os programas que construiu usando esta biblioteca, já que eles também terão o soname incorporado (você também pode corrigir isso usando PatchELF).
Em um sistema em evolução, você realmente desejaria especificar uma versão no soname, mas em um contêiner isso provavelmente não importa — você deveria reconstruir o contêiner para atualizações de qualquer maneira.
Responder2
Neste caso específico da biblioteca BLAS ATLAS
. A solução para a causa real é corrigir o makefile usado para construir o pacote.
Veja a resposta de @Stephen Kitt para saber o raciocínio.
Contudo, devido a umbug de --set-sonameem patchelf
, a solução patchelf não pode funcionar.
O caminho da sua biblioteca contém '/usr/local', então presumo que ele esteja sendo compilado a partir do código-fonte.
Verifique o arquivo $(SRC)/makes/Make.lib
, onde $(SRC)
está o diretório raiz do seu código-fonte.
Particularmente estas linhas:
LDTRY:
$(LD) $(LDFLAGS) -shared -soname $(LIBINSTdir)/$(outso) -o $(outso) \
-rpath-link $(LIBINSTdir) \
--whole-archive $(libas) --no-whole-archive $(LIBS)
O soname é impróprio aqui: -soname $(LIBINSTdir)/$(outso)
. Altere-o para -soname $(outso)
e reconstrua a biblioteca para resolver o problema.
Caso você já tenha uma construção bem-sucedida, altere a linha correspondente em $(BUILD)/lib/Makefile
, onde $(BUILD)
está o diretório para construção da biblioteca. Depois, make shared
para construir as bibliotecas.
Use um comando como readelf -d libtatlas.so | grep soname
para verificar o soname no arquivo .so resultante. Não deve conter nenhuma parte do diretório.
Se você não conseguir encontrar o makefile correto (por exemplo, usando uma versão diferente do ATLAS
), tente grep -IR soname
localizar o local que precisa ser modificado.