Почему Python не может найти общие объекты, находящиеся в каталогах в sys.path?

Я пытаюсь импортировать pycurl:

$ python -c "import pycurl"
Traceback (most recent call last):
File "<string>", line 1, in <module>
ImportError: libcurl.so.4: cannot open shared object file: No such file or directory

Теперь libcurl.so.4 находится в /usr/local/lib. Как вы можете видеть, это в sys.path:

$ python -c "import sys; print sys.path"
['', '/usr/local/lib/python2.5/site-packages/setuptools-0.6c9-py2.5.egg', 
'/usr/local/lib/python25.zip', '/usr/local/lib/python2.5', 
'/usr/local/lib/python2.5/plat-linux2', '/usr/local/lib/python2.5/lib-tk', 
'/usr/local/lib/python2.5/lib-dynload', 
'/usr/local/lib/python2.5/sitepackages', '/usr/local/lib', 
'/usr/local/lib/python2.5/site-packages']

Любая помощь будет принята с благодарностью.

Ответ 1

sys.path выполняется поиск только для модулей Python. Для динамически связанных библиотек поиск путей должен быть в LD_LIBRARY_PATH. Проверьте, включен ли LD_LIBRARY_PATH /usr/local/lib, а если нет, добавьте его и повторите попытку.

Дополнительная информация (источник):

В Linux переменная среды LD_LIBRARY_PATH разделен двоеточием набор каталогов, в которых библиотеки следует искать сначала, прежде стандартный набор каталогов; это полезно при отладке новой библиотеки или использование нестандартной библиотеки для особые цели. Окружающая среда переменная LD_PRELOAD отображает общие библиотеки с функциями, которые переопределяют стандартный набор, так же как и /etc/ld.so.preload делает. Эти реализованный погрузчиком /lib/ld -linux.so. Я должен отметить, LD_LIBRARY_PATH работает на многих Unix-подобных системах, он не работает все; например, эта функциональность доступен на HP-UX, но переменная среды SHLIB_PATH и в AIX эта функциональность переменная LIBPATH (с тем же синтаксис, список разделенных двоеточиями).

Обновить:, чтобы установить LD_LIBRARY_PATH, используйте один из следующих вариантов, в идеале, в ~/.bashrc или эквивалентный файл:

export LD_LIBRARY_PATH=/usr/local/lib

или

export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH

Используйте первую форму, если она пуста (эквивалентна пустой строке или вообще отсутствует), а вторая форма - нет. Обратите внимание на использование экспорта.

Ответ 2

Убедитесь, что ваш модуль libcurl.so находится в пути к системной библиотеке, который отличается и отделен от пути библиотеки python.

"Быстрое исправление" - это добавить этот путь к переменной LD_LIBRARY_PATH. Однако установка этой системы (или даже широкой учетной записи) является BAD IDEA, поскольку ее можно настроить таким образом, что некоторые программы найдут библиотеку, которую она не должна или, что еще хуже, открыть дыры в безопасности.

Если ваши "локально установленные библиотеки" установлены, например, /usr/local/lib, добавьте этот каталог в /etc/ld.so.conf(это текстовый файл) и запустите "ldconfig"

Команда запускает утилиту кэширования, но также создаст все необходимые "символические ссылки", необходимые для функционирования системы загрузчика. Удивительно, что "make install" для libcurl этого не делал, но, возможно, он не мог, если /usr/local/lib уже не находится в /etc/ld.so.conf.

PS: возможно, что ваш /etc/ld.so.conf содержит только "include ld.so.conf.d/*. conf". После этого вы можете добавить путь к каталогу или просто создать новый файл внутри каталога, в который он входит. Не забудьте запустить "ldconfig" после него.

Будьте осторожны. Неправильно это может испортить вашу систему.

Дополнительно: убедитесь, что ваш модуль python скомпилирован с THAT-версией libcurl. Если вы просто скопировали некоторые файлы из другой системы, это обычно не работает. Если вы сомневаетесь, скомпилируйте свои модули в системе, на которой вы собираетесь их запускать.

Ответ 3

Вы также можете установить LD_RUN_PATH в /usr/local/lib в пользовательской среде, когда вы сначала компилируете pycurl. Это будет вставлять /usr/local/lib в атрибут RPATH модуля расширения C. так, чтобы он автоматически знал, где найти библиотеку во время выполнения, не требуя установки LD_LIBRARY_PATH во время выполнения.

Ответ 4

Была такая же проблема. Я установил curl 7.19 в /opt/curl/, чтобы убедиться, что я не буду влиять на текущий завиток на наших производственных серверах. Как только я связал libcurl.so.4 с /usr/lib:

sudo ln -s/opt/curl/lib/libcurl.so/usr/lib/libcurl.so.4

У меня по-прежнему такая же ошибка! Durf.

Но запуск ldconfig делает связь для меня, и это сработало. Не нужно устанавливать LD_RUN_PATH или LD_LIBRARY_PATH. Просто нужно запустить ldconfig.

Ответ 5

Как дополнение к приведенным выше ответам - я просто сталкиваюсь с подобной проблемой и полностью работаю с установленным по умолчанию python.

Когда я вызываю пример библиотеки разделяемых объектов, которую я ищу с LD_LIBRARY_PATH, я получаю что-то вроде этого:

$ LD_LIBRARY_PATH=/path/to/mysodir:$LD_LIBRARY_PATH python example-so-user.py
python: can't open file 'example-so-user.py': [Errno 2] No such file or directory

Примечательно, что он даже не жалуется на импорт - он жалуется на исходный файл!

Но если я принудительно загружаю объект с помощью LD_PRELOAD:

$ LD_PRELOAD=/path/to/mysodir/mypyobj.so python example-so-user.py
python: error while loading shared libraries: libtiff.so.5: cannot open shared object file: No such file or directory

... Я сразу получаю более значимое сообщение об ошибке - о недостающей зависимости!

Просто подумал, что я записал это здесь - приветствия!

Ответ 6

Я использую python setup.py build_ext -R/usr/local/lib -I/usr/local/include/libcalg-1.0, а скомпилированный .so файл находится в папке сборки. вы можете ввести python setup.py --help build_ext, чтобы увидеть объяснения -R и -I