17 votes

Conflit entre la priorité de liaison dynamique dans OSX ?

Il existe un conflit de liaison dynamique entre les différentes bibliothèques dynamiques libjpeg sous OSX. Il y a d'abord une libJPEG.dylib native standard (dans /System/Library/Frameworks/ImageIO.framework/Versions/A/Resources/). Mais si vous utilisez MacPorts, vous pouvez également avoir une libjpeg.dylib liée au port (dans /opt/local/lib). Cette dernière peut par exemple avoir été installée comme une dépendance pour un autre port.

Cela crée un problème lorsque vous liez votre système à libJPEG (ce qui est préférable). Alors si /opt/local/lib se trouve dans DYLD_LIBRARY_PATH, ce chemin sera prioritaire lors de la recherche d'une librairie dynamique, ce qui entraînera une erreur d'exécution lors du chargement des symboles :

dyld: Symbol not found: __cg_jpeg_resync_to_restart
 Referenced from:
/System/Library/Frameworks/ImageIO.framework/Versions/A/ImageIO
 Expected in: /opt/local/lib/libJPEG.dylib
in /System/Library/Frameworks/ImageIO.framework/Versions/A/ImageIO
Trace/BPT trap: 5

J'ai donc deux questions (probablement liées) :

  1. Quelle est la bonne façon de résoudre le problème actuel (suppression de l'eau de mer) ? /opt/local/lib de DYLD_LIBRARY_PATH résout évidemment le problème mais crée des problèmes pour les autres dépendances) ?

  2. Quels autres chemins sont recherchés pour les librairies dynamiques (c'est-à-dire où le chemin "/System/Library" est spécifié) et pourquoi DYLD_LIBRARY_PATH est-il plus prioritaire ?

33voto

mdemirst Points 469

J'ai rencontré un problème similaire en utilisant OpenCV dans MacOS El Capitan. J'ai résolu le problème en utilisant la solution dans le lien

La solution consiste à supprimer certains dlylibs dans le répertoire /usr/local/lib et à créer des liens symboliques vers les fichiers correspondants /System/Library/Frameworks/ImageIO.framework/Resources/

cd /usr/local/lib
rm libgif.dylib
ln -s /System/Library/Frameworks/ImageIO.framework/Resources/libGIF.dylib libGIF.dylib
rm libjpeg.dylib
ln -s /System/Library/Frameworks/ImageIO.framework/Resources/libJPEG.dylib libJPEG.dylib
rm libtiff.dylib
ln -s /System/Library/Frameworks/ImageIO.framework/Resources/libTIFF.dylib libTIFF.dylib
rm libpng.dylib
ln -s /System/Library/Frameworks/ImageIO.framework/Resources/libPng.dylib libPng.dylib

11voto

Rob Napier Points 92148

Vous ne devez pas définir les chemins des bibliothèques en utilisant DYLD_LIBRARY_PATH . Comme vous l'avez découvert, cela a tendance à exploser. Les exécutables et les bibliothèques devraient avoir leurs exigences en matière de bibliothèque intégrées au moment de la liaison. Utilisez otool -L pour savoir ce que le fichier cherche :

$ otool -L /System/Library/Frameworks/ImageIO.framework/Versions/A/ImageIO
/System/Library/Frameworks/ImageIO.framework/Versions/A/ImageIO:
    /System/Library/Frameworks/ImageIO.framework/Versions/A/ImageIO (compatibility version 1.0.0, current version 1.0.0)
    ...
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1197.1.1)

Pour un exemple d'un de mes programmes construits à la maison :

$ otool -L /usr/local/bin/gifcolor
/usr/local/bin/gifcolor:
    /usr/local/Cellar/giflib/4.1.6/lib/libgif.4.dylib (compatibility version 6.0.0, current version 6.6.0)
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 159.1.0)

Notez qu'il fait référence à /usr/local . Si vous l'avez construit de telle manière qu'il fait référence à la mauvaise bibliothèque, je recommande de le reconstruire et de le faire pointer vers la bonne bibliothèque.

Si cela est impossible, il est possible d'éditer le chemin utilisé en utilisant install_name_tool mais il y a des cas où cela ne fonctionne pas, comme par exemple si le nouveau chemin est plus long que l'ancien et que vous ne l'avez pas lié avec la commande -header_pad_max_install_names . Il est préférable de reconstruire avec le chemin correct.

Notez qu'il existe quelques chemins "spéciaux" qui permettent de trouver les bibliothèques par rapport à leur chargeur. Voir @executable_path/ et ses semblables dans le dyld(1) page de manuel.

10voto

Iulian Onofrei Points 353

Si vous utilisez Qt Creator vous devez décocher l'option Add build library search path to DYLD_LIBRARY_PATH and DYLD_FRAMEWORK_PATH de l'option Run dans la section Projects onglet :

qtcreator

8voto

Thien Pham Points 81

J'ai rencontré une erreur similaire en essayant d'exécuter Apache Celix sur macOS Sierra. Si vous utilisez Homebrew pour installer libjpeg, libtiff, libpng qui peut confondre le linker pour utiliser la bibliothèque imageIO de macOS. Une solution simple est délier ces libéraux :

brew unlink libpng
brew unlink libtiff
brew unlink libjpeg

Relier ces librairies quand on en a besoin :

brew link libpng
brew link libtiff
brew link libjpeg

3voto

Franzé Jr. Points 91

J'ai eu une erreur similaire, et j'ai résolu le problème en mettant la variable suivante dans mon bash_profile :

export DYLD_LIBRARY_PATH=/usr/lib/:$DYLD_LIBRARY_PATH

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X