setup instal python distribution packaging distutils software-distribution

python - instal - Dependencias de bibliotecas compartidas con distutils



python setup py install windows (2)

Soy un novato en distutils y tengo un problema que realmente me tiene atascado. Estoy compilando un paquete que requiere una extensión, así que hago la extensión así:

a_module = Extension( "amodule", ["initmodule.cpp"], library_dirs=libdirs, extra_objects = [ "unix/x86_64/lib/liba.so" "unix/x86_64/lib/lib.so", "unix/x86_64/lib/libc.so"], )

Luego ejecuto el método de configuración:

setup(name="apackage", version="7.2", package_dir = {'''':instdir+''/a/b/python''}, packages=[''apackage'',''package.tests''], ext_modules=[hoc_module] )

La distribución del paquete se ha realizado correctamente y puedo "instalar Python setup.py" bien, pero cuando intento importar mi paquete, ImportError: liba.so.0: cannot open shared object file: No such file or directory un error. ImportError: liba.so.0: cannot open shared object file: No such file or directory

Me doy cuenta de que cuando agrego la ubicación de liba.so.0 a mi LD_LIBRARY_PATH, el programa funciona bien. Desafortunadamente, no he escrito estos módulos y no entiendo bien la compilación. He estado tratando de resolver esto durante varios días sin éxito.

ACTUALIZACIÓN : intenté pasar los archivos liba.a, libb.a etc a extra_objects pero esto no funcionó, generando el siguiente error: liba.a: no se pudieron leer los símbolos: valor incorrecto collect2: ld devolvió 1 estado de salida. Lo que estoy tratando de hacer es empaquetar un módulo de Python que requiere que se compile una biblioteca que, a su vez, depende de otras bibliotecas que necesito incluir en el paquete. Sospecho que mi problema es muy similar a este: http://mail.python.org/pipermail/distutils-sig/2009-February/010960.html pero ese no se resolvió, pensé que, dado que tiene dos años, ¿se encontró una resolución?

ACTUALIZACIÓN 2 : Por ahora he resuelto esto haciendo:

data_files=[(''/usr/local/lib'', glob.glob(''unix/x86_64/lib/*''))]

Es decir, estoy copiando las bibliotecas que necesito en / usr / local / lib. Sin embargo, no estoy muy contento con esta solución, entre otras cosas porque requiere que mis usuarios tengan privilegios de root y también porque puede que esto todavía no funcione con las distribuciones de Redhat. Entonces, si alguien puede sugerir algo mejor que esta solución, hágamelo saber.


El argumento extra_objects para la clase de Extension no es tanto una lista de bibliotecas para vincular a su extensión, sino una lista de archivos de objetos que se pasarán al vinculador (y los nombres de archivos no deben incluir extensiones, ya que los agregados serán agregados por distutils). ) No hace lo que parece querer.

Si desea enlazar contra bibliotecas compartidas específicas, como los nombres de esos archivos sugieren que quiere hacer, tiene que hacer dos cosas: decirle a distutils que le diga al compilador que vincule a esas bibliotecas compartidas, y decirle al enlazador dinámico (generalmente ld.so ) donde encontrar esas bibliotecas compartidas. Puede decirle a distutils que le diga al compilador que se vincule con las bibliotecas usando el argumento de las libraries a Extension , que debería ser una lista de nombres de bibliotecas (sin el prefijo lib y el sufijo .so ). En su ejemplo, parece ser [''a'', ''b'', ''c''] (aunque parece que la ''b'' cayó de ''lib.so '', y ''c'' realidad chocaría con el sistema libc.)

Puede indicar al vinculador dónde encontrar estas bibliotecas compartidas configurando la LD_LIBRARY_PATH entorno LD_LIBRARY_PATH , como lo hizo, o cambiando una configuración de configuración de todo el sistema (con ldconfig o editando /etc/ld.so.conf ), o codificar la ruta de búsqueda en el módulo de extensión; puede hacer esto último pasando el argumento runtime_library_dirs a Extension . Codificar la ruta de acceso tiene sus propios problemas, sin embargo, tiene que mantener esas bibliotecas en el mismo lugar y accesibles para todos los usuarios del módulo de extensión.

(Alternativamente, puede usar enlaces estáticos en lugar de dinámicos, por ejemplo, al proporcionar solo las bibliotecas en forma estática, los archivos liba.a (en cuyo caso, los enlaces se vincularán automáticamente de forma estática). Eso básicamente significa que toda la biblioteca está incluida en el módulo de extensión, que tiene varias desventajas y aspectos positivos.)


Puede pasar indicadores al compilador o al vinculador para que sepa dónde encontrar bibliotecas en tiempo de ejecución, lo que evita la necesidad de tener LD_LIBRARY_PATH configurado correctamente. Voy a ilustrar con algunos ejemplos:

# Will link just fine, then fail to find libpcap.so unless it''s in LD_LIBRARY_PATH gcc -o blah blah.o -lpcap -L/opt/csw/lib # If libpcap is in LD_LIBRARY_PATH, it''ll link fine. Other people who may not have # LD_LIBRARY_PATH set properly can still run it without fixing their environment gcc -o blah blah.o -lpcap -R/opt/csw/lib # This will allow me to link and execute the binary without having LD_LIBRARY_PATH # setup properly gcc -o blah blah.o -lpcap -{L,R}/opt/csw/lib # This makes it possible to use relative paths. The literal string `$ORIGIN/../lib/` # gets stored in the binary (`readelf -d binary_name` if you want to see the effect # it has), which causes `$ORIGIN` to resolve to the directory containing the binary # when it was executed. In a makefile, you''ll see that written as `$$ORIGIN/../lib/` # to prevent `make` from expanding it. gcc -o blah blah.o -lsomelib -L/whatever/path/floats/your/boat -R''$ORIGIN/../lib/''

En el modo de explicación, en caso de que no fuera obvio (ya que odio las respuestas sin una explicación):

  • Las rutas dadas con -L solo se usan para encontrar bibliotecas cuando se está enlazando
  • Las rutas dadas con -R solo se usan para encontrar bibliotecas cuando se ejecuta el binario