2009-07-08 15 views
90

estoy tratando de importar pycurl:¿Por qué Python no puede encontrar objetos compartidos que estén en directorios en sys.path?

$ 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 

Ahora, libcurl.so.4 está en// local/lib usr. Como puede ver, esto se encuentra en 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'] 

Cualquier ayuda será muy apreciada.

+0

Consulte mi respuesta actualizada, en caso de que no haya establecido 'LD_LIBRARY_PATH' correctamente (pensé que su comentario tenía dos puntos). –

+1

¿Hay un enlace simbólico roto en algún lugar llamado libcurl.so.4? Me parece que está buscando el archivo pero no puede abrirlo. Si todo lo demás falla, dirija al intérprete y busque la llamada que falla. –

Respuesta

124

sys.path solo se busca módulos de Python. Para las bibliotecas vinculadas dinámicas, las rutas buscadas deben estar en LD_LIBRARY_PATH. Compruebe si su LD_LIBRARY_PATH incluye /usr/local/lib, y si no lo tiene, agréguelo e intente de nuevo.

Algunos más información (source):

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).

Actualización: para establecer LD_LIBRARY_PATH, utilice uno de los siguientes, idealmente en su ~/.bashrc o archivo equivalente:

export LD_LIBRARY_PATH=/usr/local/lib 

o

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

Utilice la primera forma si está vacía (equivalente a la cadena vacía, o no está presente en absoluto), y la segunda si no lo está. Tenga en cuenta el uso de exportación.

+2

Gracias. Mi LD_LIBRARY_PATH no se ha establecido, por lo que: $ LD_LIBRARY_PATH =/usr/local/lib $ LD_LIBRARY_PATH /usr/local/lib Pero sigo teniendo el mismo error: $ python -c "pycurl importación" Rastreo (última llamada más reciente): Archivo "", línea 1, en ImportError: libcurl.so.4: no se puede abrir el archivo de objeto compartido: No existe dicho archivo o directorio –

+1

También tuve que dar permisos a mi usuario para leer la biblioteca después de establecer la variable LD_LIBRARY_PATH. Ahora finalmente funciona. –

46

Asegúrese de que su módulo libcurl.so se encuentre en la ruta de la biblioteca del sistema, que es distinta e independiente de la ruta de acceso de la biblioteca de python.

Una "solución rápida" es agregar esta ruta a una variable LD_LIBRARY_PATH. Sin embargo, configurar ese sistema (o incluso toda la cuenta) es una IDEA MALA, ya que es posible configurarlo de tal manera que algunos programas encuentren una biblioteca que no debería, o incluso peor, abrir agujeros de seguridad.

Si sus "bibliotecas instaladas localmente" se instalan en, por ejemplo,// ​​local/lib usr, añadir este directorio a /etc/ld.so.conf (es un archivo de texto) y ejecutar "ldconfig"

El comando ejecutará una utilidad de almacenamiento en caché, pero también creará todos los "enlaces simbólicos" necesarios para que funcione el sistema cargador. Es sorprendente que la "instalación de make" para libcurl no haya hecho esto, pero es posible que no pueda si/usr/local/lib ya no está en /etc/ld.so.conf.

PD: es posible que su /etc/ld.so.conf no contenga nada más que "include ld.so.conf.d/*. Conf". Todavía puede agregar una ruta de directorio después de ella, o simplemente crear un nuevo archivo dentro del directorio desde el que se está incluyendo. No te olvides de ejecutar "ldconfig" después de él.

Ten cuidado. Hacer esto mal puede arruinar su sistema.

Además: asegúrese de que su módulo python esté compilado contra ESA versión de libcurl. Si acaba de copiar algunos archivos desde otro sistema, esto no siempre funcionará. En caso de duda, compile sus módulos en el sistema en el que desea ejecutarlos.

+0

Gracias, esto funcionó. Me pregunto por qué mi intento anterior de "corrección rápida" al cambiar la variable LD_LIBRARY_PATH no. –

+1

Depende de muchos factores. Aquí hay una posibilidad: su código se estaba ejecutando desde apache o cron. Esos programas normalmente "limpian" el entorno, por lo que debe hacer cosas adicionales para obtener variables de entorno. Por ejemplo, "SetEnv" en apache, o configurar la variable en el archivo crontab para cron. ¡Las posibilidades de errores son infinitas! –

+0

Excelente respuesta, gracias – glarrain

22

También puede establecer LD_RUN_PATH en/usr/local/lib en su entorno de usuario cuando compila pycurl en primer lugar. Esto incorporará/usr/local/lib en el atributo RPATH del módulo de extensión C.para que sepa dónde encontrar la biblioteca automáticamente en tiempo de ejecución sin tener que tener definida LD_LIBRARY_PATH en tiempo de ejecución.

+0

+1 justo lo que estaba buscando. ¡Gracias! –

+3

Como alternativa, use 'configuración de python.py build_ext --rpath =/usr/local/lib' al construir el módulo de extensión para hornear en * rpath * – kynan

+0

Gracias esta debería ser la respuesta aceptada –

8

Tenía exactamente el mismo problema. Instalé curl 7.19 en/opt/curl/para asegurarme de que no afectaría el curl actual en nuestros servidores de producción. Una vez que vinculados libcurl.so.4 a/usr/lib:

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

todavía tiene el mismo error! Durf.

Pero ejecutar ldconfig hace que el enlace para mí y que funcionó. No es necesario establecer LD_RUN_PATH o LD_LIBRARY_PATH en absoluto. Solo necesitaba ejecutar ldconfig.

+0

+1 para ejecutar 'ldconfig', todos los errores corregidos –

+0

¿Qué pasa si no me pongo? no tiene privilegio sudo? No puedo ejecutar ldconfig? ¿Hay alguna manera de borrar el error anterior, entonces? – SPRajagopal

+1

@SPRajagopal: si no tiene privilegios para modificar los atributos del sistema, tiene que utilizar el método de variable de entorno 'LD_LIBRARY_PATH' descrito anteriormente. Si no quiere configurarlo en su '~/.bashrc' (agregando que la configuración no es una buena idea para IMO), puede escribir un script de shell que establezca esta variable y luego ejecute python, luego llame a ese script. – MadScientist

7

Como complemento de las respuestas anteriores, me encuentro con un problema similar y estoy trabajando completamente con la versión predeterminada de python.

Cuando llamo el ejemplo de la biblioteca de objetos compartidos Busco con LD_LIBRARY_PATH, me sale algo como esto:

$ 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 

Cabe destacar que ni siquiera se quejan de la importación - se queja el archivo de origen!

Pero si la fuerza de carga del objeto usando 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 

... inmediatamente me sale un mensaje de error más significativo - aproximadamente falta una dependencia!

Sólo pensé en anotar esto aquí - ¡salud!

+0

¿Estás seguro de que no se trata de un error nuevo antes del error de OP? –

0

Uso python setup.py build_ext -R/usr/local/lib -I/usr/local/include/libcalg-1.0 y el archivo compilado .so se encuentra en la carpeta de compilación. Puede escribir python setup.py --help build_ext para ver las explicaciones de -R y -I

Cuestiones relacionadas