2012-03-21 20 views
10

Tengo una colección de proyectos que estoy compilando como bibliotecas dinámicas. Cada uno de estos .dylibs depende de otros varios .dylibs que me gustaría colocar en varios otros directorios (es decir, algunos en la ruta del ejecutable, algunos en la ruta del cargador, otros en una ruta fija).¿Cómo establecer correctamente las rutas de ejecución, las rutas de búsqueda y los nombres de instalación?

Cuando ejecuto otool -L en las bibliotecas compiladas, obtengo una lista de rutas a esas dependencias, pero sé cómo se están estableciendo/determinando las rutas. Casi parecen pseudoaleatorios. Pasé horas jugando con las "Configuraciones de compilación" en Xcode para tratar de cambiar estas rutas (w/@rpath, @executable_path, @loader_path, etc.) pero parece que no puedo cambiar nada (como se comprueba al ejecutar otool -L) Ni siquiera estoy del todo seguro de dónde agregar estas banderas y realmente no entiende la diferencia entre el siguiente o el uso correcto de ellos:

Vinculación - "Dynamic Library Instalar Nombre"
Linking - "RUNPATH rutas de búsqueda "
Vinculación - 'Otras banderas linking'
rutas de búsqueda - 'Biblioteca de la búsqueda de rutas'

Cuando corro install_name_tool -change en las diferentes bibliotecas, soy capaz de cambiar con éxito las rutas de búsqueda de ruta de ejecución (de nuevo como se verifica mediante la ejecución otool -L para confirmar).

Estoy ejecutando Xcode 4.2 y estoy muy cerca de darme por vencido y solo usar un script de post-construcción que ejecute install_tool_name para hacer los cambios. Pero es una solución de hack kludge y preferiría no hacerlo.

¿Dónde puedo ver cómo se están configurando las rutas de búsqueda/ejecución para las dependencias de dylib?
¿Alguien tiene alguna idea sobre lo que podría estar haciendo mal?

Respuesta

10

Normalmente, en el objetivo de mi dylib, establezco INSTALL_PATH también conocido como "Directorio de instalación" con el prefijo que quiero (por ejemplo, @executable_path/../Frameworks).

Dejo LD_DYLIB_INSTALL_NAME también conocido como "Dynamic Library Install Name" establecido en su valor predeterminado, que es $(DYLIB_INSTALL_NAME_BASE:standardizepath)/$(EXECUTABLE_PATH).

Xcode se expande según el nombre de su destino, por lo que podría terminar siendo @executable_path/../Frameworks/MyFramework.framework/Versions/A/MyFramework, por ejemplo.

Lo importante es darse cuenta de que la ruta de instalación es integrada en dylib, como parte de su proceso de compilación. Más adelante, cuando vincula B.dylib que hace referencia a A.dylib, la ruta de instalación de A.dylib es copiada en B.dylib. (Eso es lo que otool le está mostrando, esas rutas de instalación copiadas). Por lo tanto, lo mejor es obtener la ruta de instalación correcta integrada en el dylib en primer lugar.

Antes de intentar que todos los dylib trabajen juntos, verifique cada uno individualmente. Compilarlo, luego otool -L en el dylib incorporado. La primera línea para cada arquitectura debería ser lo que LD_DYLIB_INSTALL_NAME te estaba mostrando.

Una vez que tenga eso organizado, intente vincular los dylibs. Debería ser mucho más directo.

+3

Aunque no es la respuesta exacta que estaba buscando, esto me ayudó a identificar mi problema. 'otool -L' enumera todos los nombres de instalación. El primer 'nombre de instalación' enumerado es el de la biblioteca en sí. Cualquier ruta adicional enumerada es para sus dependencias. Suponiendo que haya compilado las dependencias de la fuente, configurar el "Nombre de instalación de la biblioteca dinámica" en Xcode establecerá correctamente estas rutas. Sin embargo, en mi caso, las dependencias son de terceros, por lo que las rutas ya estaban establecidas. Como no tengo control sobre la compilación de las bibliotecas de terceros, me veo obligado a usar 'install_name_tool -change'. – BigMacAttack

+0

Me alegra que te hayas dado cuenta. –

+2

respuesta muy útil. – Ahmed

1

install_name_tool es muy útil para configurar los nombres y las rutas. Es especialmente útil si el programa ejecuta sus autocomprobaciones en el directorio de compilación, y luego las cosas cambian durante un make install.En este caso, puede usar install_name_tool sin la necesidad de una compilación separada.

install_name_tool también es útil porque el LD de Apple no respeta las opciones del enlazador rpath como lo hace Linux/GCC. Es decir, debe usar un conjunto diferente de comandos para configurarlos.

Aquí está la página del hombre para ello. Está incluido en su totalidad porque analiza otras opciones, como -headerpad_max_install_names.

INSTALL_NAME_TOOL(1)          INSTALL_NAME_TOOL(1) 

NAME 
     install_name_tool - change dynamic shared library install names 

SYNOPSIS 
     install_name_tool [-change old new ] ... [-rpath old new ] ... 
     [-add_rpath new ] ... [-delete_rpath new ] ... [-id name] file 

DESCRIPTION 
     Install_name_tool changes the dynamic shared library install names and 
     or adds, changes or deletes the rpaths recorded in a Mach-O binary. 
     For this tool to work when the install names or rpaths are larger the 
     binary should be built with the ld(1) -headerpad_max_install_names 
     option. 

     -change old new 
       Changes the dependent shared library install name old to new in 
       the specified Mach-O binary. More than one of these options can 
       be specified. If the Mach-O binary does not contain the old 
       install name in a specified -change option the option is 
       ignored. 

     -id name 
       Changes the shared library identification name of a dynamic 
       shared library to name. If the Mach-O binary is not a dynamic 
       shared library and the -id option is specified it is ignored. 

     -rpath old new 
       Changes the rpath path name old to new in the specified Mach-O 
       binary. More than one of these options can be specified. If 
       the Mach-O binary does not contain the old rpath path name in a 
       specified -rpath it is an error. 

     -add_rpath new 
       Adds the rpath path name new in the specified Mach-O binary. 
       More than one of these options can be specified. If the Mach-O 
       binary already contains the new rpath path name specified in 
       -add_rpath it is an error. 

     -delete_rpath old 
       deletes the rpath path name old in the specified Mach-O binary. 
       More than one of these options can be specified. If the Mach-O 
       binary does not contains the old rpath path name specified in 
       -delete_rpath it is an error. 

SEE ALSO 
     ld(1) 
Cuestiones relacionadas