[Résolu] Embarquer une librairie dynamique externe dans une application ?
Bonjour
Xcode 7
Mon application A.app utilise des librairies dynamiques externes. Prenons l'exemple de libpqxx-4.0.dylib, qui est un container en C++ de la librairie C libpq standard, et qui est installée dans dans /usr/local/lib.
En local, tout marche bien, après avoir paramétré les Build settings (Library path search) et les Build phases (Link binary with libraries + Copy file).
Quand je copie A.app avec "Product->Archive->Export as mac application" et que je lance cette copie sur une autre machine avec le même OSX (10.11 en l'occurence) aucune des librairies externes n'est trouvée.
C'est un gros problème s'il faut que j'installe toutes les librairies externes sur chaque machine où mon application doit être utilisée ! Je coyais que le "Copy file" des "Build phases" les incluait dans le A.app.
Comment faire pour embarquer mes librairies dynamiques externes dans le A.app ?
Merci.
Réponses
2) Es-tu sûr que les dylibs n'ont pas été correctement copiées dans le .app ? Je me demande si elles n'ont pas été correctement copiées, mais que le install_name de la dylib n'est pas bon (genre path en dur dans la dylib qui ne colle qu'avec ton Mac au lieu d'avoir un path relatif à @rpath)... et que c'est pour ça qu'il n'arrive pas à la loader sur un autre Mac même si elles sont dans le .app...
Donc en regardant le contenu du bundle .app généré ça pourrait aussi donner des pistes... parce que là on manque un peu d'infos.
Voilà toujours les Builds phases.
Le 2) me paraà®t vraisemblable, notamment parce que j'ai compilé les librairies à partir des sources. Je cherche dans ce sens, avant de poser d'autres question...
AliGator
Ton diagnostic était bon.
Grand merci.
Voici ce que j'ai fait et qui marche.
Soit la librairie libToto.dylib
1. elle est dans la liste du panneau qui s'affiche quand on clique sur + de Link Binary with Librairies
on sélectionne et c'est bon
2. sinon
2.0 préparer libToto.dylib :
cp path-to/libToto.dylib path-to/ref.libToto.dylib
install_name_tool -id @rpath/libToto.dylib path-to/libToto.dylib
(attention la librairie n'est peut-être pas utilisable pour une autre application, d'où la copie de sauvegarde)
2.1 faire un Copy Files de libToto.dylib
clic sur +
rechercher libToto.dylib avec Add Other...
2.2 faire un Link Binary with Librairies
clic sur +
clic sur Add Other
en principe les fichiers copiés, dont libToto.dylib, apparaissent en premier
sélectionner libToto.dylib
3. en principe c'est bon (sauf oubli d'une étape...)
en tout cas chez moi
notamment in n'y a rien à faire dans Build Setting > Search Paths
Erreur : cela marche pour une librarie qui ne dépend pas d'autres librairies
Après beaucoup de recherches et d'essais, je crois avoir trouvé une (la ?) solution.
C'est bien plus compliqué que ce que j'avais proposé et mal documenté.
Le site qui m'a permis d'embarquer une dylib dans mon application Mac OSX : http://lessons.livecode.com/m/4071/l/15029-linking-an-osx-external-bundle-with-a-dylib-library
Soit une application "Wherbarium" qui marche dans XCode.
1. copier la librairie dynamique "libToto.dylib" à la racine du répertoire "Wherbarium" au même niveau que Wherbarium.xcodeproj et DerivedData.
2. faire un Add File to "Wherbarium"... de "libToto.dylib"
3. dans Build Phases faire un Copy Files de "libToto.dylib"
4. ajouter un RunScript :
C'est ce script qui permet de changer le chemin initial de /opt/local/lib/libToto.dylib en @rpath/libToto.dylib ( -id ).
Et de modifier ce même chemin dans l'exécutable Wherbarium* ( -change ) ... qu'on trouve dans .../MacOs/
A la réflexion c'est assez logique. Mais que c'est tordu d'avoir dans le dylib le chemin du fichier d'origine, en tout cas je ne comprends pas pourquoi ? XCode offre la possibilité de manipuler tout ça avec les Run Scripts, ce qui est loin d'être facile à touver : en fait tout doit se passer à l'intérieur de Xcode...
Voilà pour le principe.
A CONDITION que libToto.dylib n'appelle pas lui-même d'autres dylib.
Pour moi cela ne marche pas directement avec :
Je pense qu'il faut procéder de la même manière dans le RunScript pour les dylib incluses. Je n'ai pas essayé pour le moment...
Et de toute façon si tu link avec une dylib qui est bien faite cette dylib se base sur @executable_path ou @rpath donc ne dépend pas du chemin d'origine, seulement du chemin relatif au binaire exécutable. Et du coup tu n'es dans ce cas pas sensé avoir à manipuler install_name_tool toi-même.