macos path ld dylib dyld

macos - install_name_tool para actualizar un ejecutable para buscar dylib en Mac OS X



path ld (1)

Desde otool -l , analicé lo que debería agregarse o modificarse desde la biblioteca original y el binario.

Dylib

El cambio está en id:

Load command 2 <-- OLD cmd LC_ID_DYLIB cmdsize 40 name libtest.dylib (offset 24) time stamp 1 Wed Dec 31 18:00:01 1969 Load command 2 <-- NEW cmd LC_ID_DYLIB cmdsize 64 name @loader_path/../lib/libtest.dylib (offset 24)

Este es el comando para lograr el cambio:

install_name_tool -id "@loader_path/../lib/libtest.dylib" libtest.dylib

O utilice rpath:

install_name_tool -id "@rpath/libtest.dylib" libtest.dylib

El ejecutable

Hay dos cambios: rpath y load_dylib

Load command 12 <-- OLD cmd LC_LOAD_DYLIB cmdsize 40 name libtest.dylib (offset 24) Load command 12 <-- NEW cmd LC_LOAD_DYLIB cmdsize 64 name @loader_path/../lib/libtest.dylib (offset 24)

Este es el comando para realizar el cambio.

install_name_tool -change libtest.dylib @loader_path/../lib/libtest.dylib myapp

También necesitaba añadir el rpath.

Load command 14 cmd LC_RPATH cmdsize 32 path @loader_path/../lib (offset 12)

Este es el comando para llevar a cabo la adición:

install_name_tool -add_rpath "@loader_path/../lib" myapp

La idea

El binario intenta encontrar la biblioteca, sabe dónde se encuentra desde install_name_tool -add_rpath "@loader_path/../lib" myapp . Carga la biblioteca, y el ID de la biblioteca es @rpath/libtest.dylib donde @rpath se establece en @loader_path/../lib en el binario ejecutable para hacer la coincidencia.

Referencia

Cmake

Cuando usamos CMake, podemos automatizar el proceso con la siguiente adición en el archivo CMakeLists.txt.

Biblioteca

El id debe ser agregado.

# https://cmake.org/pipermail/cmake/2006-October/011530.html SET_TARGET_PROPERTIES (test PROPERTIES BUILD_WITH_INSTALL_RPATH 1 INSTALL_NAME_DIR "@rpath" ) Ejecutable

El rpath debe ser especificado:

SET(CMAKE_INSTALL_RPATH "@loader_path/../lib/libtest.dylib")

Tengo un libray libtest.dylib dinámico que está instalado en /PATH/lib , y un binario de ejecución, myapp, que usa el dylib instalado en /PATH/bin .

Puedo ejecutar myapp para encontrar el dylib de la siguiente manera ( ¿está bien usar DYLD_LIBRARY_PATH en Mac OS X? Y, ¿cuál es el algoritmo de búsqueda de biblioteca dinámica con él? ):

DYLD_LIBRARY_PATH="/PATH/lib" myapp

Creo que puedo usar install_name_tool para actualizar la biblioteca y el ejecutable para que la biblioteca pueda encontrarse con rpath. Utilicé las sugerencias en esta publicación. ¿Cómo puedo especificar la ruta en un dylib? .

En lib, ejecuté este comando para agregar rpath.

install_name_tool -id "@rpath/libtest.dylib" libtest.dylib install_name_tool -add_rpath "@executable_path/../lib/" libtest.dylib

En bin, install_name_tool -add_rpath "@executable_path/../lib/" myapp .

Sin embargo, cuando myapp en el directorio bin , tengo los mensajes de error.

dyld: Library not loaded: libtest.dylib Referenced from: /PATH/bin/./myapp Reason: image not found Trace/BPT trap: 5

otool -l myapp muestra que la ruta se ha actualizado correctamente en myapp.

Load command 16 cmd LC_RPATH cmdsize 40 path @executable_path/../lib/ (offset 12)

Lo mismo ocurre con libtest.dylib

Load command 13 cmd LC_RPATH cmdsize 40 path @executable_path/../lib/ (offset 12)

¿Qué podría estar mal?

ADICIONAL

Por supuesto, puedo usar cc -install_name cuando se compila y enlaza el tiempo, pero quería saber cómo hacer lo mismo al modificar el dylib generatd y el binario de ejecución.

De la lib

cc -install_name "@loader_path/../lib/libtest.dylib" -dynamiclib -o libtest.dylib test.c

O, el nombre de instalación puede usar @rpath:

cc -install_name "@rpath/libtest.dylib" -dynamiclib -o libtest.dylib test.c

De la papelera:

cc -I../lib -c main.c cc -o main main.o ../lib/libtest.dylib -Wl,-rpath -Wl,@loader_path/../lib

O solo una línea:

cc -I../lib -L../lib -o main main.c -ltest -Wl,-rpath -Wl,@loader_path/../lib