Почему 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']

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

6 ответов

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

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

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

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

Если ваши "локально установленные библиотеки" установлены, например, в / 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 скомпилирован с ТО-версией libcurl. Если вы просто скопировали некоторые файлы из другой системы, это не всегда будет работать. Если есть сомнения, скомпилируйте ваши модули в той системе, в которой вы собираетесь их запускать.

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

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

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

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

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

Для меня то, что здесь работает, - это использование диспетчера версий, такого как pyenv, который я настоятельно рекомендую, чтобы ваши среды проекта и версии пакетов хорошо управлялись и были отделены от операционной системы.

У меня была такая же ошибка после обновления ОС, но ее легко исправить с помощью pyenv install 3.7-dev (версия, которую я использую).

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

Другие вопросы по тегам