Pregunta

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

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

¿ " Enlace binario con bibliotecas " crea una fase de enlace estático?

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 quejarse de la falta de símbolos?


Creo que lo he descubierto:

  • libpng no se vinculaba correctamente, porque he creado ejecutables de 32/64 bits y una biblioteca de 32 bits. La configuración de compilación de la biblioteca y los ejecutables deben coincidir.

  • config.h de libpng necesita tener toneladas de definiciones como #define FEATURE_XXX_SUPPORTED

  • La fase de compilación
  • " Enlace binario con bibliotecas " maneja las bibliotecas dinámicas muy bien, y la variable de entorno DYLD_FALLBACK_LIBRARY_PATH es necesaria para cargar .dylib s del paquete de aplicaciones.

¿Fue útil?

Solución

Probablemente necesite asegurarse de que la biblioteca dinámica que construya tenga un archivo de símbolos exportado que enumere lo que debe exportarse desde 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, se le incrusta un nombre de instalación , que es, de forma predeterminada, la ruta en la que se construye. Posteriormente, todo lo que se vincule en su contra lo buscará primero en la ruta especificada y solo después buscará un (pequeño) conjunto de rutas predeterminadas descritas en DYLD_FALLBACK_LIBRARY_PATH en el desarrollador dyld (1) página de manual .

Si va a colocar esta biblioteca al lado de sus ejecutables, debe ajustar su nombre de instalación para hacer referencia a eso. Simplemente haciendo una búsqueda en Google de " nombre de instalación " debería mostrar un montón de información sobre cómo hacerlo.

Otros consejos

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

Pasos:

  1. crear una biblioteca libmylib.dylib que contenga mymod.o
  2. compilar y vincular un " callmymod " que lo llama
  3. llame a mymod desde callmymod, utilizando DYLD_LIBRARY_PATH y DYLD_PRINT_LIBRARIES

Problema: usted '' solo '' desea crear una biblioteca para que otros módulos la utilicen. Sin embargo, hay una gran cantidad de programas: gcc, ld, macosx libtool, dyld, con millones de opciones, algo de compost bien podrido y diferencias entre MacOSX y Linux. Hay toneladas de páginas man (cuento 7679 + 1358 + 228 + 226 líneas en 10.4.11 ppc) pero no hay muchos ejemplos o programas con un "dime qué estás haciendo" modo.

(Lo más importante para comprender es hacer un DESCRIPCIÓN GENERAL para usted: dibuje algunas imágenes, ejecute algunos ejemplos pequeños, explicárselo a otra persona).

Antecedentes: apple OverviewOfDynamicLibraries , Wikipedia Dynamic_library


Paso 1, cree 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 callmymod vinculando 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, consulte GNU Libtool que es glibtool en macs, y SCons .)
saludos
  - denis

Desafortunadamente, en mi experiencia, la documentación de Apple es anticuada, redundante y le 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 que FMOD (Sound API) funcionara 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, como "malvado" como Microsoft, en realidad hacen un trabajo mucho mejor cuidando a sus desarrolladores con documentación (esto viene de un evangelista de Apple).

Creo que básicamente, lo que no estás haciendo es DESPUÉS de haber compilado tu paquete .app. Luego debe ejecutar un comando en el binario ejecutable /MyApp.app/contents/MacOS/MyApp para cambiar dónde busca el archivo ejecutable su archivo de biblioteca. Debe crear una nueva fase de compilación que pueda ejecutar un script. No explicaré este proceso nuevamente, ya lo hice en profundidad aquí:

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

Espero que esto ayude.

¿Conoce la página de referencia de Apple Dynamic Temas de programación de la biblioteca ? Debe cubrir la mayor parte de lo que necesita. Tenga en cuenta que hay bibliotecas compartidas que se cargan incondicionalmente al inicio del programa y bibliotecas cargadas dinámicamente (paquetes, IIRC) que se cargan a pedido, y las dos son algo diferentes en MacOS X de los equivalentes en Linux o Solaris.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top