96 votes

Imprimer le chemin d'accès d'un exécutable sous macOS

Je souhaite modifier le chemin de ronde d'un exécutable à l'aide de install_name_tool mais je n'arrive pas à comprendre ce que le chemin de ronde est en ce moment même. install_name_tool nécessite à la fois l'ancien et le nouveau chemin de ronde à indiquer sur la ligne de commande. Quelle commande puis-je utiliser pour imprimer le chemin de ronde d'un exécutable sous macOS ?

133voto

NSGod Points 14652

Tout d'abord, il faut comprendre qu'un exécutable ne contient pas un seul rpath mais un tableau d'une ou plusieurs entrées.

Deuxièmement, vous pouvez utiliser otool pour répertorier les rpath entrées. L'utilisation de otool -l vous obtiendrez un résultat comme celui qui suit, à la toute fin duquel se trouvent les éléments suivants rpath entrées :

Load command 34
          cmd LC_LOAD_DYLIB
      cmdsize 88
         name /System/Library/Frameworks/AppKit.framework/Versions/C/AppKit (offset 24)
   time stamp 2 Wed Dec 31 19:00:02 1969
      current version 1038.32.0
compatibility version 45.0.0

Load command 35
          cmd LC_RPATH
      cmdsize 40
         path @loader_path/../Frameworks (offset 12)

Recherchez le LC_RPATH et notez le chemin d'accès sous la commande path entrée.

EDIT : à propos de quoi @loader_path est un moyen générique et dynamique de se référer à l'objet Mach-O qui veut charger le cadre.

Bien qu'il s'agisse d'un exemple plutôt artificiel, je pense qu'il devrait faire passer le message. Supposons que nous ayons une application MyApp.app qui utilise un cadre MyFramework.framework . Nous dirons également que pour fonctionner correctement, j'ai besoin que mon application soit installée dans le répertoire /Applications et nulle part ailleurs. La structure de cette application et de ce framework serait donc la suivante :

/Applications/MyApp.app/Contents/MacOS/MyApp (exécutable) /Applications/MyApp.app/Contents/Frameworks/MyFramework.framework/MyFramework (Mach-O dylib)

Si nous devions exécuter otool -L (notez le L majuscule) sur l'exécutable, il afficherait ce qui suit concernant MyFramework :

@rpath/MyFramework.framework/Versions/A/MyFramework
/System/Library/Frameworks/Cocoa.framework/Versions/A/Cocoa
/System/Library/Frameworks/Foundation.framework/Versions/C/Foundation
/usr/lib/libobjc.A.dylib
/usr/lib/libSystem.B.dylib
....

Il convient de noter que, comme MyFramework.framework utilise un fichier @rpath nous aurons besoin d'entrées de chemin de recherche au moment de l'exécution qui seront substituées à la place de @rpath au moment de l'exécution. Maintenant, je pourrais avoir une seule entrée rpath de :

/Applications/MyApp.app/Contents/Frameworks

Cela fonctionnerait et, au moment de l'exécution, les deux parties seraient réunies :

/Applications/MyApp.app/Contents/Frameworks + /MyFramework.framework/Versions/A/MyFramework ==

/Applications/MyApp.app/Contents/Frameworks/MyFramework.framework/Versions/A/MyFramework

Il est évident que le codage en dur d'un tel chemin n'est pas idéal, car il suffit de déplacer l'application dans un autre dossier ou de renommer l'application elle-même pour que la liaison échoue.

@loader_path est simplement un moyen dynamique de faire référence à l'exécutable de l'application, quel que soit l'endroit où il se trouve dans le système de fichiers. Dans ce cas particulier, au moment de l'exécution, il sera rempli avec le chemin de l'exécutable en cours d'exécution : /Applications/MyApp.app/Contents/MacOS/MyApp . Nous pouvons donc dire que pour trouver MyFramework.framework, il suffit de monter d'un répertoire et d'aller jusqu'à Frameworks .

20voto

plasmacel Points 505

Vous pouvez utiliser otool -l myexecutable mais cela imprime beaucoup d'informations inutiles si vous n'êtes intéressé que par la liste des chemin de ronde s.

Vous pouvez filtrer la sortie de otool -l à l'autorité compétente chemin de ronde entrées par

otool -l myexecutable | grep RPATH -A2

8voto

techraf Points 131

J'ai découvert que je pouvais imprimer le nom d'installation d'une bibliothèque partagée sur macOS en utilisant

otool -D mylib

De plus, je peux définir le nom d'installation directement sans référence à l'ancien nom d'installation en passant le paramètre -id à install_name_tool :

install_name_tool -id @rpath/my/path mylib

4voto

Fravadona Points 970

Je suis en train d'écrire plusieurs scripts pour traiter DYLD et celui-ci répond à la question, je le poste donc pour référence :

#!/usr/bin/env ruby
require 'open3'
stdout, stderr, status = Open3.capture3('/usr/bin/otool', '-l', *ARGV)
stdout.scan(/^ +cmd LC_RPATH$.*?^ +path (.*?) \(offset \d+\)$/m) {|(p)| puts p}

Exemple :

lsrpath /usr/local/microsoft/powershell/7/{pwsh,createdump,unknown.xyz}
@loader_path

J'espère que cela vous aidera ;-)

0voto

rosewater Points 60

J'utilise simplement la commande otool

otool -l <my executable>

Il imprime le champ rpath. Pas besoin de longs scripts.

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