2012-01-17 15 views
6

TL; DR¿Cómo puedo obtener Xcode para vincular y depurar una aplicación con Boost Filesystem?

Objective-C aplicación vinculada con la biblioteca estática que enlaces dinámicos Boost del sistema de archivos. La aplicación se puede ejecutar desde el directorio de salida usando Terminal, pero al tratar de ejecutar desde el depurador de Xcode o Finder se obtiene el error dyld: Library not loaded: libboost_filesystem.dylib <snip> Reason: image not found.

Problema

En mi proyecto de Xcode tengo una estructura que se parece a esto:

MainProject (Objective-C) 
- static_lib_that_uses_filesystem (C++) 

para tener todo para enlazar, añadí libboost_system y libboost_filesystem dylibs a la "Enlace binario con Bibliotecas "fase de construcción en MainProject.

Cuando trato de ejecutar la aplicación de cualquiera de Xcode o el Finder me sale:

sharedlibrary apply-load-rules all 
warning: Unable to read symbols for libboost_filesystem.dylib (file not found). 
warning: Unable to read symbols from "libboost_filesystem.dylib" (not yet mapped into memory). 
warning: Unable to read symbols for libboost_system.dylib (file not found). 
warning: Unable to read symbols from "libboost_system.dylib" (not yet mapped into memory). 
[Switching to process 43957 thread 0x0] 
dyld: Library not loaded: libboost_filesystem.dylib 
    Referenced from: /Users/ssteele/Library/Developer/Xcode/DerivedData/MainProject-dqrhyuarllykslftblocjdzxlran/Build/Products/Debug/MainProject.app/Contents/MacOS/MainProject 
    Reason: image not found 

que añade una etapa de generación para copiar los dylibs al directorio Marcos en el haz, esto no ayuda. Cambié esto para copiarlos al directorio de Ejecutables que tampoco me ayudó.

Tenerlos en el directorio de Ejecutables hace me permite ejecutar la aplicación desde la Terminal.

¿Cómo puedo obtener la aplicación para encontrar los dylibs cuando se ejecuta desde Finder/Xcode?

antecedente

estoy usando Xcode 4.2 en León y en la actualidad centrarse exclusivamente en León. Construí mis bibliotecas compartidas de sistema de archivos como esto:

./b2 threading=multi macosx-version=10.7 --with-filesystem stage 

Esto crea libboost_system.dylib, libboost_filesystem.dylib, y también .a equivalentes en el directorio de la etapa/lib, los estoy haciendo referencia en el proyecto directamente desde allí .

+0

salida de otool -l incluye: 'comando Cargar 11 LC_LOAD_DYLIB cmd cmdsize 56 nombre libboost_filesystem.dylib (offset 24) tiempo sello 2 jue 1 ene 01:00:02 1970 versión actual 0.0.0 compatibilidad versión 0.0.0' –

+0

Me pregunto si ese nombre debe incluir una @ referencia de algún tipo, como '@ executable_path/libboost_filesystem.dylib' . No puedo hacer que eso ocurra sin embargo. –

Respuesta

12

Las bibliotecas dinámicas (dylibs) en OSX hornean en la ruta desde la que se deben cargar. Por ejemplo ...

/usr/lib/some_awesome.dylib.

Cuando se vincula a un dylib, el enlazador incorpora esta ruta en el ejecutable como el lugar para buscarla en tiempo de ejecución. Esto es fácil y fácil con las librerías instaladas, pero para la vinculación de ruta relativa es más complicado.

Al compilar las libs de impulso, solo obtienen sus nombres incrustados en lugar de una ruta completa o relativa (es decir, libboost_system.dylib en lugar de /usr/lib/libboost_filesystem.dylib). Debería poder cambiar esto con el dll-pathoption, pero that seems broken currently.

Para solucionar su problema, debe obtener la ruta correcta relativa a su aplicación incrustada (por ejemplo, @executable_path/libwhatever.dylib) en los dylibs de alguna manera, lo que probablemente requeriría la opción bjam dll-path o, en su lugar, puede reparar su ejecutable buscar en una ubicación diferente.

Para ello, utilice algo como lo siguiente como un paso de guión en su construcción:

install_name_tool -change libboost_filesystem.dylib @executable_path/libboost_filesystem.dylib$BUILT_PRODUCTS_DIR/$EXECUTABLE_PATH

Tenga en cuenta que si tiene varios dylibs que hacen referencia entre sí con caminos rotos, usted necesitará arregle los caminos entre ellos también, por ejemplo

install_name_tool -change libboost_system.dylib @executable_path/libboost_system.dylib$BUILT_PRODUCTS_DIR/$EXECUTABLE_FOLDER_PATH/libboost_filesystem.dylib

El siguiente es un buen artículo sobre esto: Creating working dylibs

+0

¡Gracias, al usar install_name_tool parece hacer lo que quiero! –

0

creo que es necesario agregar la ruta de acceso al directorio donde guardó libboost_filesystem.a en la "Biblioteca de rutas de búsqueda"

Haga clic en su perfil de proyecto -> configuración de creación -> ampliar "Ruta de búsqueda" -> "rutas de búsqueda de la biblioteca"

+1

Disculpe, ya tengo el directorio 'stage/lib' en la ruta de búsqueda de la biblioteca. –

+0

No funciona. agregué mi/usr/local/lib en la ruta de búsqueda de la biblioteca. sigue sin éxito. – Zangetsu

1

El problema es que el impulso debe instalarse, por ejemplo b2 ..... install. Esto copia las bibliotecas y los encabezados en/usr/local/lib y/usr/local/include.

Las bibliotecas dinámicas de OSX solo se ejecutan desde el directorio para el que están compiladas.

Puede cambiar el directorio de instalación utilizando el argumento -prefix para aumentar la compilación. Sin embargo, las bibliotecas aún necesitarían estar en el mismo directorio para todos los usuarios.

Debería haber una manera de crear boost como un framework y/o incrustar @executable_path en la biblioteca.

Una alternativa es usar las bibliotecas estáticas de boost: crea solo las estáticas o elimina las dinámicas, Xcode busca las dinámicas antes de las estáticas. Si usa estática, la ruta a las bibliotecas no importa en tiempo de ejecución, ya que todo el código está ahora en el ejecutable.

Cuestiones relacionadas