2009-09-27 7 views
13

Tengo un programa (específicamente mi entrada para el SO DevDays Countdown app challenge) que se basa en varias bibliotecas dinámicas, a saber, libSDL, libSDL_ttf y otras. Tengo estas bibliotecas instaladas en /opt/local/lib a través de MacPorts, y muchas personas no las tendrán instaladas (y algunas podrían tenerlas instaladas, pero no en esa ubicación).¿Cómo distribuir un Mac OS X con bibliotecas dependientes?

¿Cómo distribuyo mi programa para que las personas sin estas bibliotecas instaladas puedan ejecutarlo de fábrica? Obviamente tendré que distribuir los diversos archivos .dylib, pero hacerlo no es suficiente. El cargador dinámico aún busca las bibliotecas instaladas en las ubicaciones donde las tengo instaladas. ¿Hay alguna manera de decirle al cargador dinámico que busque en el directorio actual del ejecutable, como lo que hace Windows con los DLL? Las personas no deberían tener que modificar ninguna variable de entorno (por ejemplo, DYLD_LIBRARY_PATH), ya que de nuevo quiero que esto funcione de inmediato.

Respuesta

5

Como mencionaste, no estás usando Xcode, por lo que es un poco difícil. Aquí hay opciones en mi orden de preferencia:

  1. Cambiar a Xcode. Use marcos. Las bibliotecas SDL ya están disponibles como marcos, y he visto más de un par de juegos comerciales con libsdl.framework dentro del paquete de la aplicación.

  2. Utilice marcos, pero conserve sus Makefiles. Descargue las versiones de marco de sus bibliotecas SDL (o compárelas usted mismo) y conéctelas con la bandera del enlazador de marco. Distribuya los marcos con su aplicación o no, y diga a sus usuarios que los coloquen en ~/Library/Frameworks o en/Library/Frameworks. No me molestaría con un instalador para esto.

  3. Enlace estáticamente contra SDL. En el archivo Makefile, deberá enumerar la ruta de las bibliotecas estáticas en lugar de usar el distintivo -l, por ejemplo, ejecutará "ld blah blah /opt/local/lib/libsdl.a". No hay manera de que sepa decir -l que prefiera las bibliotecas estáticas a las compartidas, y créanme, las he buscado.

+0

Después de pensarlo, creo que voy a ir con enlaces estáticos para distribución. Si voy a distribuir las bibliotecas dinámicas de todos modos, eso frustrará varios de los propósitos de su uso, así que también podría evitar el dolor de lidiar con el cargador dinámico. –

+1

4. usando la opción 2. anterior, coloque los marcos dentro de su paquete .app (archivo .dmg) y cambie las necesidades ejecutables de las rutas con install_name_tool. Estos son algunos ejemplos de cómo se usa install_name_tool: http://qt-project.org/doc/qt-4.8/deployment-mac.html. Dietrich, ¿podría incorporar esto en su respuesta, por favor? –

+0

@ MilanBabuškov: Parece que esto ya está incorporado en la respuesta a continuación. No veo la necesidad de duplicar información. –

3

Enlace estáticamente las bibliotecas.

+0

Mucho para la reutilización de código. –

+6

Las bibliotecas vinculadas de forma estática cuentan como "reutilización de código", ya que el código de la biblioteca solo debe escribirse/probarse/depurarse una sola vez, sin importar cuántas aplicaciones terminen utilizándolo. Si bien es cierto que varias copias del código compilado pueden terminar en el disco del usuario, ese no es un problema tan grande como solía ser ahora que los discos duros son tan grandes. –

13

El enfoque básico para esto es enviarlos en el paquete .app. A continuación, modificará la ubicación en la que el vinculador busca las bibliotecas compartidas para incluir esto.

Los pasos son:

  1. crear una nueva copia de archivos se acumulan fase a su objetivo que copia los archivos en el directorio de los marcos del paquete .app.

  2. Editar la configuración "RUNPATH rutas de búsqueda" configuración de generación para incluir @executable_path/../Frameworks

Si usted construye su ejecutable con estos cambios y luego mira, usted debe encontrar que existen las dylibs en el directorio Foo.app/Contents/Framework y correr otool -L Foo.app/Contents/MacOS/Foo debe ceder y la entrada con el prefijo @rpath para esos dylibs.

De este Cocoabuilder post:

En general, @loader_path se prefiere sobre @executable_path, ya que
permite marcos de trabajar tanto en un ejecutable y un paquete,
plugin, o sub-marco incrustado. El único inconveniente es que @loader_path
requiere 10.4 o más reciente. Si tiene 10.5 o más reciente, @rpath es incluso
mejor que @loader_path.

+0

No estoy usando Xcode (paquete .app), simplemente viejo gcc y make. También estoy usando OS X 10.4; de acuerdo con http://developer.apple.com/mac/library/documentation/DeveloperTools/Conceptual/DynamicLibraries/100-Articles/RunpathDependentLibraries.html, las rutas de búsqueda del camino de acceso solo se admiten en 10.5 y posteriores. –

+1

Creo que @executable_path funcionará incluso en 10.4 (@loader_path y @rpath no). También puede leer esto: http://blog.onesadcookie.com/2008/01/installname-magic.html – nall

+0

Si no está usando Xcode, su mejor opción puede ser utilizar Autotools y amigos. –