Question

Je construis quelques utilitaires de ligne de commande dans Xcode (plain C, pas de cacao). Je veux que tous utilisent ma version personnalisée de libpng, et je veux gagner de la place en partageant une copie de la bibliothèque entre tous les exécutables (cela ne me dérange pas de redistribuer .dylib avec eux) .

Dois-je faire de la magie pour obtenir les symboles d'exportation libpng?

Est-ce que "Lier le binaire aux bibliothèques" crée une liaison de phase de manière statique?

La documentation d'Apple mentionne le chargement de bibliothèques au moment de l'exécution avec dlopen , mais comment puis-je rendre Xcode créer un exécutable sans se plaindre des symboles manquants?

Je pense l'avoir compris:

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

  • Le fichier config.h de libpng doit avoir des tonnes de définitions comme #define FEATURE_XXX_SUPPORTED

  • La phase de construction
  • "Link Binary With Libraries" gère parfaitement les bibliothèques dynamiques, et la variable d'environnement DYLD_FALLBACK_LIBRARY_PATH est nécessaire pour charger .dylib de l’application.

Était-ce utile?

La solution

Vous devez probablement vous assurer que la bibliothèque dynamique que vous créez a un fichier de symboles exporté qui répertorie ce qui doit être exporté à partir de la bibliothèque. Il s’agit d’une simple liste de symboles, un par ligne, à exporter.

En outre, lors de la construction de votre bibliothèque dynamique, un nom d'installation y est incorporé, qui correspond par défaut au chemin d'accès à sa construction. Ensuite, tout ce qui le lie le recherchera d'abord dans le chemin spécifié, puis seulement dans un (petit) ensemble de chemins par défaut décrit sous DYLD_FALLBACK_LIBRARY_PATH dans le Page de manuel de dyld (1) .

Si vous souhaitez placer cette bibliothèque à côté de vos exécutables, vous devez ajuster son nom d'installation pour le référencer. Vous effectuez simplement une recherche Google sur " nom d'installation " devrait afficher une tonne d'informations à ce sujet.

Autres conseils

La liaison dynamique sous Mac OS X, un petit exemple

Étapes:

  1. créer une bibliothèque libmylib.dylib contenant mymod.o
  2. compilez et liez un " callmymod " qui l'appelle
  3. appelez mymod à partir de callmymod, à l'aide de DYLD_LIBRARY_PATH et de DYLD_PRINT_LIBRARIES

Problème: vous "venez". vouloir créer une bibliothèque pour les autres modules à utiliser. Cependant, il existe une pile impressionnante de programmes - gcc, ld, macosx libtool, dyld - avec des zillions d’options, du compost bien décomposé 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 d'exemples ou de programmes avec un "dites-moi ce que vous faites" mode.

(La chose la plus importante dans la compréhension est de faire un APERÇU par vous-même: dessinez des images, lancez de petits exemples, expliquez-le à quelqu'un d'autre).

Arrière-plan: apple PrésentationOfDynamicLibraries , Wikipedia bibliothèque dynamique

Étape 1, créez 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, compilez et liez 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, exécutez callmymod en liant à 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 met fin à un petit exemple. espérons que cela vous aidera à comprendre les étapes.
(Si vous le faites souvent, consultez GNU Libtool . qui est glibtool sur macs, et SCons .)
acclamations
  - denis

Malheureusement, selon mon expérience, la documentation d'Apple est obsolète, redondante et manque de BEAUCOUP d'informations communes dont vous auriez normalement besoin.

Sur mon site Web, j’ai écrit beaucoup de choses sur ce sujet, où je devais faire fonctionner FMOD (Sound API) avec mon jeu multiplate-forme que nous avions développé à l’uni. C’est un processus étrange et je suis surpris que Apple n’ajoute pas plus d’informations sur ses documents de développement.

Malheureusement, comme "diabolique" comme Microsoft, ils s’occupent beaucoup mieux de la documentation de leurs développeurs (cela provient d’un évangéliste Apple).

En gros, je pense que ce que vous ne faites pas, c’est APRÈS avoir compilé votre .app Bundle. Vous devez ensuite exécuter une commande sur le fichier exécutable /MyApp.app/contents/MacOS/MyApp afin de modifier l'emplacement où l'exécutable recherche son fichier de bibliothèque. Vous devez créer une nouvelle phase de construction pouvant exécuter un script. Je n'expliquerai plus ce processus, je l'ai déjà fait de manière approfondie ici:

http: // brockwoolf .com / blog / utilisation pratique de dynamic-libraries-in-xcode-31-using-fmod

J'espère que cela vous aidera.

Connaissez-vous la page de référence Apple Dynamic Sujets de programmation de la bibliothèque ? Il devrait couvrir la plupart de ce dont vous avez besoin. Sachez qu’il existe des bibliothèques partagées chargées sans condition au démarrage du programme et des bibliothèques chargées dynamiquement (bundles, IIRC) chargées à la demande. Ces deux versions sont quelque peu différentes de MacOS X des équivalentes sous Linux ou Solaris.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top