¿Cómo puedo crear una biblioteca dinámica (dylib) con Xcode?


Estoy construyendo algunas utilidades de línea de comandos en Xcode (C simple, sin Cacao). Quiero que todos ellos usen mi versión personalizada de libpng, y quiero ahorrar espacio compartiendo una copia de la biblioteca entre todos los ejecutables (no me importa redistribuir .dylib con ellos).

¿Necesito hacer algo de magia para obtener los símbolos de exportación de libpng?

¿"Enlaza Binario Con Bibliotecas" construye enlace de fase estáticamente?

Los documentos de Apple mencionan la carga de bibliotecas en tiempo de ejecución con dlopen, pero ¿cómo puedo hacer que Xcode cree ejecutable sin quejarme de los símbolos que faltan?


Creo que lo he descubierto:

  • Libpng no estaba enlazando correctamente, porque he construido ejecutables de 32/64 bits y una biblioteca de 32 bits. Los ajustes de compilación de la biblioteca y los ejecutables deben coincidir.

  • Configuración de Libpng.h necesita tener toneladas de define como #define FEATURE_XXX_SUPPORTED

  • "Enlace Binario Con Bibliotecas" fase de compilación maneja bibliotecas dinámicas muy bien, y DYLD_FALLBACK_LIBRARY_PATHla variable ambiental es necesaria para cargar .dylib s del paquete de aplicaciones.

Author: Kornel, 2008-10-11

4 answers

Probablemente necesite asegurarse de que la biblioteca dinámica que compila tenga un archivo de símbolos exportados que enumera lo que debe exportarse de la biblioteca. Es solo una lista plana de los símbolos, uno por línea, para exportar.

Además, cuando se construye su biblioteca dinámica, obtiene un nombre de instalación incrustado dentro de ella que es, por defecto, la ruta en la que se construye. Posteriormente, cualquier cosa que se vincule contra ella lo buscará en la ruta especificada primero y solo después buscará un (pequeño) conjunto de rutas predeterminadas descritas en DYLD_FALLBACK_LIBRARY_PATH en el dyld(1) página de manual .

Si va a poner esta biblioteca junto a sus ejecutables, debe ajustar su nombre de instalación para hacer referencia a eso. Simplemente haciendo una búsqueda de Google para "nombre de instalación" debería aparecer un montón de información sobre hacer eso.

 7
Author: Chris Hanson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-10-12 03:00:34

Enlace dinámico en Mac OS X, un pequeño ejemplo

Pasos:

  1. cree una biblioteca libmylib.dylib contiene mymod.o
  2. compilar y enlazar un "callmymod" que lo llama
  3. llama a mymod desde callmymod, usando DYLD_LIBRARY_PATH y DYLD_PRINT_LIBRARIES

Problema: "solo" desea crear una biblioteca para que otros módulos la usen. Sin embargo, hay una enorme cantidad de programas g gcc, ld, macosx libtool, dyld -- con millones de opciones, algunos bien podridos compost, y diferencias entre MacOSX y Linux. Hay toneladas de páginas de manual (cuento 7679 + 1358 + 228 + 226 líneas en 10.4.11 ppc) pero no mucho en el camino de ejemplos, o programas con un" dime lo que estás haciendo " modo.

(Lo más importante en la comprensión es hacer un simplificado RESUMEN para usted: dibuje algunos dibujos, ejecute algunos ejemplos pequeños, explícaselo a otra persona).

Antecedentes: Panorama de Apple de bibliotecas dinámicas, Wikipedia Dynamic_library


Paso 1, crea libmylib.dylib {

mymod.c:
    #include <stdio.h>
    void mymod( int x )
    {
        printf( "mymod: %d\n", x );
    }
gcc -c mymod.c  # -> mymod.o
gcc -dynamiclib -current_version 1.0  mymod.o  -o libmylib.dylib
    # calls libtool with many options -- see man libtool
    # -compatibility_version is used by dyld, see also cmpdylib

file libmylib.dylib  # Mach-O dynamically linked shared library ppc
otool -L libmylib.dylib  # versions, refs /usr/lib/libgcc_s.1.dylib

Paso 2, compilar y vincular callmymod {

callmymod.c:
    extern void mymod( int x );
    int main( int argc, char** argv )
    {
        mymod( 42 );
    }
gcc -c callmymod.c
gcc -v callmymod.o ./libmylib.dylib -o callmymod
    # == gcc callmymod.o -dynamic -L. -lmylib
otool -L callmymod  # refs libmylib.dylib
nm -gpv callmymod  # U undef _mymod: just a reference, not mymod itself

Paso 3, ejecute el enlace callmymod a libmylib.dylib {

export DYLD_PRINT_LIBRARIES=1  # see what dyld does, for ALL programs
./callmymod
    dyld: loaded: libmylib.dylib ...
    mymod: 42

mv libmylib.dylib /tmp
export DYLD_LIBRARY_PATH=/tmp  # dir:dir:...
./callmymod
    dyld: loaded: /tmp/libmylib.dylib ...
    mymod: 42

unset DYLD_PRINT_LIBRARIES
unset DYLD_LIBRARY_PATH

Eso termina con un pequeño ejemplo; espero que ayude a entender los pasos.
(Si hace esto mucho, vea GNU Libtool que es glibtool en macs, y SCons .)
saludos
-- denis

 49
Author: denis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-01-07 12:37:00

Desafortunadamente, en mi experiencia, la documentación de Apple es anticuada, redundante y falta mucha información común que normalmente necesitaría.

Escribí un montón de cosas sobre esto en mi sitio web donde tuve que conseguir FMOD (Sound API) para trabajar con mi juego multiplataforma que desarrollamos en uni. Es un proceso extraño y me sorprende que Apple no agregue más información sobre sus documentos de desarrollador.

Desafortunadamente, tan" malvados " como Microsoft, en realidad hacen un trabajo mucho mejor de cuidando de sus desarrolladores con documentación (esto viene de un evangelista de Apple ).

Creo que básicamente, lo que no están haciendo es DESPUÉS de haber compilado su .paquete de aplicaciones. A continuación, debe ejecutar un comando en el binario ejecutable /MyApp.app / contents / macOS / MyApp para cambiar dónde el ejecutable busca su archivo de biblioteca. Debe crear una nueva fase de compilación que pueda ejecutar un script. No voy a explicar este proceso de nuevo, ya lo he hecho en profundidad aquí:

Http://brockwoolf.com/blog/how-to-use-dynamic-libraries-in-xcode-31-using-fmod

Espero que esto ayude.

 6
Author: Brock Woolf,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-02-06 17:04:47

¿Conoce la página de referencia de Apple Temas de Programación de Bibliotecas Dinámicas? Debería cubrir la mayor parte de lo que necesitas. Tenga en cuenta que hay bibliotecas compartidas que se cargan incondicionalmente al iniciar el programa y bibliotecas cargadas dinámicamente (paquetes, IIRC) que se cargan bajo demanda, y las dos son algo diferentes en macOS X de las equivalentes en Linux o Solaris.

 5
Author: Jonathan Leffler,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-12-18 07:38:13