Ich habe eine Anwendung (eine ausführbare Datei) erstellt, die erfolgreich eine Dylib aufgerufen hat. Die Dylib-Dateien und die ausführbare Datei befinden sich jedoch in einem anderen Verzeichnis. Ich habe der Umgebungsvariablen $ PATH das Verzeichnis mit den Dylib-Dateien hinzugefügt, es wird jedoch immer noch nicht geladen. Ich kopiere alle Dylib-Dateien in die ausführbare Datei, das Programm läuft schließlich. Dies bestätigt, dass die Dylib-Dateien kein Problem haben. Wie kann ich dem Betriebssystem jedoch mitteilen, dass es es finden soll? In Windows muss ich nur den Verzeichnispfad hinzufügen, der DLL-Dateien zu $ PATH enthält. Was muss ich für Mac OS X tun? Danke vielmals!
Nachdem ich den von Justin bereitgestellten Link gelesen hatte, konnte ich das Token @executable_path
Verwenden, um meinen dylib-Installationsnamen so zu ändern, dass er auf dasselbe Verzeichnis verweist, in dem sich meine ausführbare Datei befindet.
@ executable_path Absolute Pfade nerven. Manchmal möchten Sie ein Framework in eine Anwendung einbetten, anstatt das Framework in/Library oder an einem ähnlichen Speicherort installieren zu müssen.
Die Mac-Lösung dafür ist @executable_path. Dies ist ein magisches Token, das am Anfang des Installationsnamens einer Bibliothek auf den Pfad der ausführbaren Datei erweitert wird, die es lädt, abzüglich der letzten Komponente. Angenommen, Bar.app verlinkt gegen Foo.framework. Wenn Bar.app in/Applications installiert ist, wird @executable_path zu /Applications/Bar.app/Contents/MacOS erweitert. Wenn Sie das Framework in Contents/Frameworks einbetten möchten, können Sie den Installationsnamen von Foo.framework einfach auf @executable_path /../ Frameworks/Foo.framework/Versions/A/Foo setzen. Der dynamische Linker erweitert dies zu /Applications/Bar.app/Contents/MacOS/../Frameworks/Foo.framework/Versions/A/Foo und findet dort das Framework.
http://www.mikeash.com/pyblog/friday-qa-2009-11-06-linking-and-install-names.html
Ich werde mit einem Beispiel demonstrieren.
Angenommen, ich habe die folgende ausführbare Datei /opt/local/bin/convert und ihre Dylibs befinden sich in /opt/local/lib. Ich möchte es in ein anderes Verzeichnis kopieren und seine Dylibs aus demselben Verzeichnis laden lassen, in das ich die ausführbare Datei kopiert habe.
> mkdir ~/tmp/bin
> cp /opt/local/bin/convert ~/tmp/bin
Rufen Sie eine Liste der ausführbaren Dylibs ab
> otool -L ~/tmp/bin/convert
~/tmp/bin/convert:
/opt/local/lib/libtiff.3.dylib (compatibility version 13.0.0, current version 13.5.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 159.1.0)
/opt/local/lib/libjpeg.8.dylib (compatibility version 12.0.0, current version 12.0.0)
/opt/local/lib/libfontconfig.1.dylib (compatibility version 6.0.0, current version 6.4.0)
/opt/local/lib/libiconv.2.dylib (compatibility version 8.0.0, current version 8.1.0)
/opt/local/lib/libfreetype.6.dylib (compatibility version 15.0.0, current version 15.0.0)
/opt/local/lib/libexpat.1.dylib (compatibility version 7.0.0, current version 7.2.0)
/opt/local/lib/libbz2.1.0.dylib (compatibility version 1.0.0, current version 1.0.6)
/opt/local/lib/libz.1.dylib (compatibility version 1.0.0, current version 1.2.6)
...
Ich kümmere mich nur um die Dylibs in /opt/local/lib dir, also ziehen wir nur Dylibs in /opt heraus. Ich möchte alle anderen dylib-Referenzen intakt halten, insbesondere für /usr/lib/libSystem Sachen.
> DYLIBS=`otool -L ~/tmp/bin/convert | grep "/opt" | awk -F' ' '{ print $1 }'`
Kopieren Sie alle Dylibs, auf die die ausführbare Datei verweist, in dasselbe Verzeichnis, in das die ausführbare Datei kopiert wurde.
> for dylib in $DYLIBS; do cp $dylib ~/tmp/bin/; done;
Verwenden Sie den install_name_tool
, Um den Installationsnamen aller Dylibs zu ändern, die wir im obigen Schritt herausgezogen haben, und ersetzen Sie sie, indem Sie dem Dylib-Namen den @executable_path
Voranstellen. Dadurch sucht der Dynamic Linker in demselben Verzeichnis nach der Dylib, in dem sich die ausführbare Datei befindet.
> for dylib in $DYLIBS; do install_name_tool -change $dylib @executable_path/`basename $dylib` ~/tmp/bin/convert; done;
Stellen Sie sicher, dass die Installationsnamen geändert wurden und dass libSystem immer noch auf /usr/lib/libSystem zeigt.
> otool -L ~/tmp/bin/convert
~/tmp/bin/convert:
@executable_path/libtiff.3.dylib (compatibility version 13.0.0, current version 13.5.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 159.1.0)
@executable_path/libjpeg.8.dylib (compatibility version 12.0.0, current version 12.0.0)
@executable_path/libfontconfig.1.dylib (compatibility version 6.0.0, current version 6.4.0)
@executable_path/libiconv.2.dylib (compatibility version 8.0.0, current version 8.1.0)
@executable_path/libfreetype.6.dylib (compatibility version 15.0.0, current version 15.0.0)
@executable_path/libexpat.1.dylib (compatibility version 7.0.0, current version 7.2.0)
@executable_path/libbz2.1.0.dylib (compatibility version 1.0.0, current version 1.0.6)
@executable_path/libz.1.dylib (compatibility version 1.0.0, current version 1.2.6)
...
Sie müssen das DYLD_LIBRARY_PATH
Umgebungsvariable.
Aus der dyld man page :
This is a colon separated list of directories that contain libraries. The dynamic linker
searches these directories before it searches the default locations for libraries. It allows
you to test new versions of existing libraries.
For each library that a program uses, the dynamic linker looks for it in each directory in
DYLD_LIBRARY_PATH in turn. If it still can't find the library, it then searches DYLD_FALL-
BACK_FRAMEWORK_PATH and DYLD_FALLBACK_LIBRARY_PATH in turn.
viele Möglichkeiten. Vielleicht hilft das:
http://www.mikeash.com/pyblog/friday-qa-2009-11-06-linking-and-install-names.html
Befindet sich die Dylib an der in INSTALL_NAME der Bibliothek angegebenen Stelle, funktioniert sie einfach *.
Andernfalls können Sie den Speicherort der Dylib zu DYLD_LIBRARY_PATH hinzufügen. Vielleicht möchten Sie die dyld-Dokumentation lesen .
*) Um ganz genau zu sein, muss es bei DYLD_ROOT_PATH/INSTALL_NAME sein, aber es ist ziemlich selten, mit DYLD_ROOT_PATH zu fummeln.