Вопрос по libcurl, pycurl, shared-libraries, python – Почему Python не может найти общие объекты, которые находятся в каталогах в sys.path?

103

Я пытаюсь импортировать 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']

Любая помощь будет оценена.

Есть ли где-нибудь сломанная символическая ссылка с именем libcurl.so.4? Мне кажется, что он находит файл, но не может его открыть. Если все остальное терпит неудачу, освободите интерпретатора и ищите неудавшийся вызов. Charles Duffy
См. Мой обновленный ответ, если вы не установилиLD_LIBRARY_PATH правильно (я думал, что ваш комментарий был пропущен двоеточие). Vinay Sajip

Ваш Ответ

6   ответов
10

Была точно такая же проблема. Я установил 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.

+1 за бегldconfig , все ошибки исправлены
@SPRajagopal: если у вас нет прав для изменения системных атрибутов, вы должны использоватьLD_LIBRARY_PATH метод переменной среды, описанный выше. Если вы не хотите устанавливать его в своем~/.bashrc (добавление этого параметра не является хорошей идеей IMO) вы можете написать сценарий оболочки, который устанавливает эту переменную, затем запускает python, а затем вызывает этот сценарий.
Что если у меня нет привилегии sudo? Я не могу запустить ldconfig? Есть ли способ очистить вышеупомянутую ошибку тогда?
0

я использую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

53

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

«Быстрое исправление» это добавить этот путь в переменную LD_LIBRARY_PATH. Однако установка всей системы (или даже учетной записи) является ПЛОХОЙ ИДЕЕЙ, поскольку ее можно настроить таким образом, чтобы некоторые программы находили библиотеку, которая не должна, или даже хуже, открывала дыры в безопасности.

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

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

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

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

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

Спасибо - это сработало. Интересно, почему моя ранее предпринятая попытка «быстро исправить»? изменение переменной LD_LIBRARY_PATH не произошло.
Отличный ответ, спасибо
Зависит от множества факторов. Вот одна из возможностей: ваш код запускался из apache или cron. Эти программы обычно "очищают" окружение, поэтому вы должны сделать дополнительные вещи, чтобы получить переменные окружения. Например, & quot; SetEnv & quot; в apache, или установив переменную прямо в файле crontab для cron. Возможности для ошибок бесконечны!
141

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

Еще немного информации (источник):

In Linux, the environment variable LD_LIBRARY_PATH is a colon-separated set of directories where libraries should be searched for first, before the standard set of directories; this is useful when debugging a new library or using a nonstandard library for special purposes. The environment variable LD_PRELOAD lists shared libraries with functions that override the standard set, just as /etc/ld.so.preload does. These are implemented by the loader /lib/ld-linux.so. I should note that, while LD_LIBRARY_PATH works on many Unix-like systems, it doesn't work on all; for example, this functionality is available on HP-UX but as the environment variable SHLIB_PATH, and on AIX this functionality is through the variable LIBPATH (with the same syntax, a colon-separated list).

Update: установитьLD_LIBRARY_PATH, используйте один из следующих, в идеале в вашем~/.bashrc or equivalent file:

export LD_LIBRARY_PATH=/usr/local/lib

или же

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

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

Я также должен был дать разрешения моему пользователю читать библиотеку после установки переменной LD_LIBRARY_PATH. Теперь это наконец работает.
Благодарю. Мой LD_LIBRARY_PATH не был установлен, поэтому: $ LD_LIBRARY_PATH = / usr / local / lib $ LD_LIBRARY_PATH / usr / local / lib Но я все еще получаю ту же ошибку: $ python -c & import pycurl & quot; Traceback (последний вызов был последним): файл & lt; string & gt ;, строка 1, в & lt; module & gt; ImportError: libcurl.so.4: невозможно открыть общий объектный файл: нет такого файла или каталога
8

В качестве дополнения к ответам, приведенным выше, я просто сталкиваюсь с подобной проблемой и работаю полностью с установленным по умолчанию 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

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

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

Вы уверены, что это не новая ошибка, которая происходит до ошибки OP?
24

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

+1 только то, что я искал. Спасибо!
В качестве альтернативы используйтеpython setup.py build_ext --rpath=/usr/local/lib при создании модуля расширения для выпечки вrpath
Спасибо, это должен быть принятый ответ

Похожие вопросы