Я установил ATLAS
(с помощью Netlib LAPACK
) в образ Docker, и теперь при каждом запуске 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, если он не существует, в том же каталоге: он находит /usr/local/lib/libtatlas.so
, проверяет его soname, определяет, что необходимо создать ссылку из /usr/local/lib//usr/local/lib/libtatlas.so
(объединенные каталог и soname) на /usr/local/lib/libtatlas.so
, и терпит неудачу, поскольку /usr/local/lib/usr/local/lib
не существует.
Правильный способ исправить это — убедиться, что sonames библиотек определены правильно. Обычно я ожидаю libtatlas.so.3
etc. без имени каталога (версия будет зависеть от уровня ABI собираемой библиотеки). Вероятно, вам нужно пересобрать библиотеки или найти правильно собранный пакет...
Кроме того, вы можете редактировать soname библиотеки, используяPatchELF:
patchelf --set-soname libtatlas.so /usr/local/lib/libtatlas.so
В идеале вам следует перекомпоновать программы, созданные вами с использованием этой библиотеки, поскольку в них также будет встроено имя soname (его также можно исправить с помощью PatchELF).
В развивающейся системе вам действительно захочется указать версию в soname, но в контейнере это, вероятно, не имеет значения — вам в любом случае придется перестраивать контейнер для обновлений.
решение2
В данном конкретном случае библиотеки BLAS ATLAS
. Исправление настоящей причины заключается в исправлении makefile, используемого для сборки пакета.
Обоснование см. в ответе @Stephen Kitt.
Однако из-заошибка --set-sonameв patchelf
, решение patchelf не может работать.
Путь к вашей библиотеке содержит «/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: -soname $(LIBINSTdir)/$(outso)
. Измените его на -soname $(outso)
, затем пересоберите библиотеку, и эта проблема будет устранена.
В случае, если у вас уже есть успешная сборка, измените соответствующую строку в $(BUILD)/lib/Makefile
, где $(BUILD)
находится каталог для сборки библиотеки. Затем make shared
для сборки библиотек.
Используйте команду, например, readelf -d libtatlas.so | grep soname
для проверки soname в полученном .so-файле. Он не должен содержать никакой части каталога.
Если вы не можете найти правильный make-файл (например, используете другую версию ATLAS
), попробуйте grep -IR soname
найти место, которое необходимо изменить.