Comment créer une bibliothèque dynamique (dylib) avec Xcode?

je construis quelques utilitaires en ligne de commande dans Xcode (C, No Cocoa). Je veux qu'ils utilisent tous ma version personnalisée de libpng, et je veux économiser de l'espace en partageant une copie de la bibliothèque parmi tous les exécutables (Je n'ai pas d'objection à redistribuer .dylib avec eux).

ai-je besoin de faire un peu de magie pour obtenir les symboles d'exportation de libpng?

"Lien Binaire Avec Les Bibliothèques" Phase de construction liée statiquement?

Les Docs D'Apple mentionnent le chargement de les bibliothèques au moment de l'exécution avec dlopen, mais comment faire pour que Xcode crée un exécutable sans se plaindre de l'absence de symboles?


je crois que j'ai compris:

  • libpng ne liait pas correctement, parce que j'ai construit des exécutables 32/64 bits et une bibliothèque 32 bits. Paramètres de construction de la bibliothèque et des exécutables doivent correspondre.

  • config de libpng.h a besoin d'avoir des tonnes d'définit comme #define FEATURE_XXX_SUPPORTED

  • "Lien Binaire Avec Les Bibliothèques" build phase gère très bien les bibliothèques dynamiques, et DYLD_FALLBACK_LIBRARY_PATH variable d'environnement est nécessaire pour le chargement .dylib s de l'application bundle.

27
demandé sur Kornel 2008-10-11 23:30:47

4 réponses

vous devez probablement vous assurer que la Bibliothèque dynamique que vous construisez a un fichier de symboles exporté qui liste ce qui devrait être exporté de la bibliothèque. C'est juste une liste Plate des symboles, un par ligne, à exporter.

aussi, quand votre bibliothèque dynamique est construite, elle obtient un installer nom intégré à l'intérieur de celui-ci qui est, par défaut, le chemin sur lequel il est construit. Par la suite, tout ce qui se connecte contre lui le cherchera sur le chemin spécifié en premier et seulement après. rechercher un (petit) ensemble de chemins par défaut décrit sous DYLD_FALLBACK_LIBRARY_PATH dans le dyld(1) page de manuel de.

Si vous allez mettre cette bibliothèque à côté de vos exécutables, vous devez ajuster son installation nom de référence. Juste faire une recherche Google pour "install name" devrait révéler une tonne d'informations sur ce faire.

7
répondu Chris Hanson 2008-10-12 03:00:34

liaison dynamique sur Mac OS X, un petit exemple

Mesures:

  1. créer une bibliothèque libmylib.dylib contenant du mymod.o
  2. compilez et liez un "callmymod" qui l'appelle
  3. call mymod from callmymod, using DYLD_LIBRARY_PATH and DYLD_PRINT_LIBRARIES

problème: vous "voulez juste" créer une bibliothèque pour les autres modules à utiliser. Cependant, il y a une énorme pile de programmes -- gcc, ld, macosx libtool, dyld -- avec des millions d'options, du compost bien pourri et des différences entre MacOSX et Linux. Il y a des tonnes de pages de manuel (je compte 7679 + 1358 + 228 + 226 lignes en 10.4.11 ppc) mais pas beaucoup dans la façon d'exemples, ou des programmes avec une "dites-moi ce que vous faites".

(la chose la plus importante dans la compréhension est de faire une simplification Vue d'ensemble pour vous-même: dessinez quelques photos, lancez quelques petits exemples, expliquer à quelqu'un d'autre).

Contexte: apple OverviewOfDynamicLibraries, Wikipedia Dynamic_library


Étape 1, Créer 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

Étape 2, compiler et lier 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

Étape 3, Lancez callmymod en lien avec 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

cela termine un petit exemple; espérons qu'il aide à comprendre les étapes.

(Si vous faites cela, beaucoup, voir GNU Libtool qui est glibtool sur macs, et SCons.)

acclamations

-- denis

49
répondu denis 2017-01-07 12:37:00

malheureusement, D'après mon expérience, la documentation D'Apple est désuète, redondante et manque beaucoup d'informations communes dont vous auriez normalement besoin.

j'ai écrit un tas de trucs là-dessus sur mon site Web où J'ai dû faire travailler FMOD (sound API) avec mon jeu de plateforme cross que nous avons développé à uni. C'est un processus étrange et je suis surpris que Apple ne pas ajouter plus d'informations sur leur développeur docs.

malheureusement, en tant que" mal " que Microsoft sont, ils font en fait beaucoup mieux vaut s'occuper de leur devs avec de la documentation (cela vient d'un évangéliste D'Apple ).

je pense que fondamentalement, ce que vous ne faites pas est après que vous avez compilé votre .app Bundle. Vous devez ensuite exécuter une commande sur l'exécutable binaire /MyApp.app/contents/MacOS / MyApp afin de changer l'endroit où l'exécutable recherche son fichier de bibliothèque. Vous devez créer une nouvelle phase de construction qui peut exécuter un script. Je ne vais pas expliquer ce processus à nouveau, je l'ai déjà fait en profondeur ici:

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

J'espère que cela vous aidera.

6
répondu Brock Woolf 2010-02-06 17:04:47

Êtes-vous au courant de la Pomme de référence page Bibliothèque Dynamique Des Sujets De Programmation? Il devrait couvrir la plupart de ce dont vous avez besoin. Soyez conscient qu'il existe des bibliothèques partagées qui sont chargées inconditionnellement au démarrage du programme et des bibliothèques chargées dynamiquement (bundles, IIRC) qui sont chargées sur demande, et les deux sont quelque peu différentes sur MacOS X par rapport aux équivalents sur Linux ou Solaris.

5
répondu Jonathan Leffler 2011-12-18 07:38:13