web-dev-qa-db-fra.com

Comment définir le chemin d'exécution (-rpath) d'un exécutable avec gcc sous Mac OSX?

Je veux définir sous Mac OSX le chemin d'exécution d'un exécutable (pour l'éditeur de liens) au moment de la compilation, de sorte que les bibliothèques partagées à des emplacements non standard soient trouvées par l'éditeur de liens dynamique au démarrage du programme.

Sous Linux, cela est possible avec -Xlinker -rpath -Xlinker /path/to (ou en utilisant -Wl,-rpath,/path/to) et sous Solaris vous pouvez ajouter -R/path/to à la ligne de commande du compilateur.

J'ai trouvé quelques informations que Mac OS X gcc prend en charge -rpath depuis 10.5, c'est-à-dire depuis ~ 2008.

J'ai essayé de le faire fonctionner avec un exemple minimal - sans succès:

$ cat blah.c 
int blah(int b)
{
  return b+1;
}

Et:

$ cat main.c 

#include <stdio.h>

int blah(int);

int main ()
{
  printf("%d\n", blah(22));
  return 0;
}

Compilé comme ceci:

$ gcc -c  blah.c
$ gcc -dynamiclib blah.o -o libblah.dylib
$ gcc main.c -lblah -L`pwd`  -Xlinker -rpath -Xlinker `pwd`/t

Maintenant, le test:

$ mkdir t
$ mv libblah.dylib t
$ ./a.out
dyld: Library not loaded: libblah.dylib
  Referenced from: /Users/max/test/./a.out
  Reason: image not found
Trace/BPT trap

D'où la question: comment définir le chemin d'exécution de l'éditeur de liens sous Mac OSX?

Btw, définissant DYLD_LIBRARY_PATH fonctionne - mais je ne veux pas utiliser ce hack.

Modifier: Concernant otool -L:

$ otool -L a.out 
a.out:
        libblah.dylib (compatibility version 0.0.0, current version 0.0.0)
        /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 125.2.1)

Il paraît que otool -L affiche uniquement les noms de bibliothèque (et probablement les emplacements au moment de la liaison) avec lesquels l'exécutable était lié et aucune information sur le chemin d'exécution.

43
maxschlepzig

Trouvé par expérimentation et en inspectant les lignes de commande générées par Xcode pour un projet de démonstration de rpath de référence par Dave Driblin :

otool -L vous indique le nom d'installation des bibliothèques liées. Obtenir @rpath pour fonctionner, vous devez modifier le nom d'installation de la bibliothèque:

$ gcc -dynamiclib blah.o -install_name @rpath/t/libblah.dylib -o libblah.dylib
$ mkdir t ; mv libblah.dylib t/
$ gcc main.c -lblah -L`pwd`/t -Xlinker -rpath -Xlinker `pwd`
36
Ben Karel