Comment imprimer le chemin de recherche ld (linker)

154

Quelle est la manière d'imprimer les chemins de recherche qui ont été regardés par ld dans l'ordre dans lequel il recherche.

Talespin_Kit
la source

Réponses:

96

Vous pouvez le faire en exécutant la commande suivante:

ld --verbose | grep SEARCH_DIR | tr -s ' ;' \\012

gcc transmet quelques chemins -L supplémentaires à l'éditeur de liens, que vous pouvez lister avec la commande suivante:

gcc -print-search-dirs | sed '/^lib/b 1;d;:1;s,/[^/.][^/]*/\.\./,/,;t 1;s,:[^=]*=,:;,;s,;,;  ,g' | tr \; \\012

Les réponses suggérant d'utiliser ld.so.conf et ldconfig ne sont pas correctes car elles font référence aux chemins recherchés par l'éditeur de liens dynamique d'exécution (c'est-à-dire à chaque fois qu'un programme est exécuté), ce qui n'est pas le même que le chemin recherché par ld (c'est-à-dire à chaque fois un programme est lié).

faux
la source
2
Vous avez frappé l'endroit. J'ai un problème de liaison, lors du processus de liaison, l'éditeur de liens trouve des bibliothèques installées manuellement dans /usr/local/..lesquelles une erreur de bibliothèque manquante est causée et la liaison échoue. Je dois renommer à /usr/localchaque fois pour exclure ce chemin de recherche. Existe-t-il un moyen simple d'exclure ou de remplacer le /usr/localchemin?
kenn
1
Vous pouvez essayer de spécifier manuellement les chemins des bibliothèques avec l'option -L de GCC, ce qui, je pense (pas sûr), remplacera les chemins des bibliothèques système. Vous pouvez également essayer de définir la variable d'environnement LIBRARY_PATH avant de compiler: $ LIBRARY_PATH = / somedir / gcc ...
faken
1
Je sais que la liaison dans la compilation en ligne de commande. Je voulais dire un moyen global de remplacer le ldchemin de recherche. Par exemple, je dois parfois compiler un code source à partir de makefileou générer un makefile à partir d'un configurescript ou à partir de CMakeLists.txtou encore plus compliqués tels que valaou srt. Il m'est difficile de modifier le ldchemin de recherche dans de tels cas
kenn
Lorsque vous utilisez CMake, vous pouvez sélectionner les bibliothèques exactes qui sont utilisées pendant la phase de configuration (certaines de ces entrées ne sont affichées qu'en mode avancé). En ce qui concerne la configuration des scripts d'Autotools, consultez cette réponse: stackoverflow.com/questions/7561509/… . Cela ne répond pas directement à votre question, mais peut vous aider à faire ce que vous voulez.
faken le
83

Sous Linux, vous pouvez utiliser ldconfig, qui gère la configuration et le cache ld.so, pour imprimer les répertoires recherchés ld.soavec

ldconfig -v 2>/dev/null | grep -v ^$'\t'

ldconfig -vimprime la recherche de répertoires par l'éditeur de liens (sans onglet de début) et les bibliothèques partagées trouvées dans ces répertoires (avec un onglet de début); le greprécupère les répertoires. Sur ma machine, cette ligne s'imprime

/usr/lib64/atlas:
/usr/lib/llvm:
/usr/lib64/llvm:
/usr/lib64/mysql:
/usr/lib64/nvidia:
/usr/lib64/tracker-0.12:
/usr/lib/wine:
/usr/lib64/wine:
/usr/lib64/xulrunner-2:
/lib:
/lib64:
/usr/lib:
/usr/lib64:
/usr/lib64/nvidia/tls: (hwcap: 0x8000000000000000)
/lib/i686: (hwcap: 0x0008000000000000)
/lib64/tls: (hwcap: 0x8000000000000000)
/usr/lib/sse2: (hwcap: 0x0000000004000000)
/usr/lib64/tls: (hwcap: 0x8000000000000000)
/usr/lib64/sse2: (hwcap: 0x0000000004000000)

Les premiers chemins, sans hwcapdans la ligne, sont soit intégrés, soit lus depuis /etc/ld.so.conf. L'éditeur de liens peut ensuite rechercher des répertoires supplémentaires sous le chemin de recherche de la bibliothèque de base, avec des noms tels que sse2correspondant à des capacités de processeur supplémentaires. Ces chemins, avec hwcapdans la ligne, peuvent contenir des bibliothèques supplémentaires adaptées à ces capacités CPU.

Une dernière remarque: utiliser -pau lieu de -vci - dessus recherche le ld.socache à la place.

télotortium
la source
52
Il pose des questions sur l'éditeur de liens (ld) et non sur le chargeur (ld.so)!
fons le
3
Comment est-il possible que si je définis export LD_LIBRARY_PATH=/some/other/dir, cela n'affecte pas la sortie de cette commande?! Cela semble ne pas fonctionner à 100%?
TMS
3
@fons Funnything est que je suis arrivé ici à la recherche de cette réponse. :) au moment du lien ou chemin d'exécution? Je suppose que c'est la question. LIBRAY_PATH (temps de liaison) vs LD_LIBRARY_PATH.
Daniel Santos
2
J'ai trouvé sur certaines plates-formes (par exemple, armer avec la chaîne d'outils Linaro) que ldconfig ne recherche pas réellement les mêmes répertoires que l'éditeur de liens d'exécution. Vous pouvez lui faire afficher son chemin de recherche et inclure les chemins à partir de LD_LIBRARY_PATHen activant le débogage. Par exemple LD_DEBUG=libs /lib/ld-linux.so --list cat(vous pouvez utiliser n'importe quel exécutable, j'ai choisi catcomme première chose à laquelle je pourrais penser). Cela vaudra peut-être la peine d'être salué pour " search path". Notez que si vous avez un /etc/ld.so.cachequi correspond à toutes les bibliothèques nécessaires, vous ne pourrez pas voir le chemin de recherche système intégré, car il n'ira pas aussi loin.
John O'M.
Le gccchemin de recherche est-il le même avec ceux-ci?
nn0p
68

Je ne suis pas sûr qu'il existe une option pour simplement imprimer le chemin de recherche efficace complet.

Mais: le chemin de recherche se compose de répertoires spécifiés par des -Loptions sur la ligne de commande, suivis des répertoires ajoutés au chemin de recherche par des SEARCH_DIR("...")directives dans le (s) script (s) de l'éditeur de liens. Vous pouvez donc le résoudre si vous pouvez voir les deux, ce que vous pouvez faire comme suit:

Si vous appelez lddirectement:

  • Les -Loptions sont ce que vous avez dit qu'elles sont.
  • Pour voir le script de l'éditeur de liens, ajoutez l' --verboseoption. Recherchez les SEARCH_DIR("...")directives, généralement vers le haut de la sortie. (Notez que ce ne sont pas nécessairement les mêmes pour chaque appel de ld- l'éditeur de liens a un certain nombre de scripts de l'éditeur de liens par défaut intégrés différents, et choisit entre eux en fonction de diverses autres options de l'éditeur de liens.)

Si vous créez un lien via gcc:

  • Vous pouvez transmettre l' -voption à gccafin qu'elle vous montre comment elle appelle l'éditeur de liens. En fait, il n'appelle normalement pas lddirectement, mais indirectement via un outil appelé collect2(qui vit dans l'un de ses répertoires internes), qui à son tour invoque ld. Cela vous montrera quelles -Loptions sont utilisées.
  • Vous pouvez ajouter -Wl,--verbosedes gccoptions pour le faire passer --verboseà l'éditeur de liens, pour voir le script de l'éditeur de liens comme décrit ci-dessus.
Matthew Slattery
la source
5
L'option --verbose pour l'éditeur de liens a fait l'affaire. Très utile!
Ari
J'essayais de comprendre où recherchait l'éditeur de liens et je n'ai pas trouvé SEARCH_DIR dans la sortie. Il s'est avéré que j'utilisais -T scriptmon script a complètement remplacé le script par défaut de ld et n'a regardé que là où je l'ai indiqué.
thomasa88
30

La commande la plus compatible que j'ai trouvée pour gcc et clang sous Linux (grâce à armando.sano):

$ gcc -m64 -Xlinker --verbose  2>/dev/null | grep SEARCH | sed 's/SEARCH_DIR("=\?\([^"]\+\)"); */\1\n/g'  | grep -vE '^$'

si vous donnez -m32, il affichera les bons répertoires de bibliothèque.

Exemples sur ma machine:

pour g++ -m64:

/usr/x86_64-linux-gnu/lib64
/usr/i686-linux-gnu/lib64
/usr/local/lib/x86_64-linux-gnu
/usr/local/lib64
/lib/x86_64-linux-gnu
/lib64
/usr/lib/x86_64-linux-gnu
/usr/lib64
/usr/local/lib
/lib
/usr/lib

pour g++ -m32:

/usr/i686-linux-gnu/lib32
/usr/local/lib32
/lib32
/usr/lib32
/usr/local/lib/i386-linux-gnu
/usr/local/lib
/lib/i386-linux-gnu
/lib
/usr/lib/i386-linux-gnu
/usr/lib
Raphaël Londeix
la source
Je vous remercie! amélioration minuscule - se débarrasser d'un grep ou deux: sed -n 's / SEARCH_DIR ("= \? ([^"] \ +) "); * / \ 1 \ n / gp'
Bruce K
2
Pourquoi cela nécessite-t-il une méthode aussi obscure?
bmacnaughton
Cela a fonctionné comme un charme! comment ajouter les répertoires sur cette liste, chemin de recherche de l'éditeur de liens?
pari
6

La question est étiquetée Linux, mais peut-être que cela fonctionne aussi bien sous Linux?

gcc -Xlinker -v

Sous Mac OS X, cela imprime:

@(#)PROGRAM:ld  PROJECT:ld64-224.1
configured to support archs: armv6 armv7 armv7s arm64 i386 x86_64 armv6m armv7m armv7em
Library search paths:
    /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/usr/lib
Framework search paths:
    /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/System/Library/Frameworks/
[...]

L' -Xlinkeroption gccci-dessus passe simplement -và ld. Toutefois:

ld -v

n'imprime pas le chemin de recherche.

armando.sano
la source
Sous Linux, il imprime également des répertoires, mais sous la forme de -Lpath. Donc, la réponse @ Raphaël Londeix est meilleure.
pevik
2

Version Mac: $ ld -v 2, je ne sais pas comment obtenir des chemins détaillés. production

Library search paths:
    /usr/lib
    /usr/local/lib
Framework search paths:
    /Library/Frameworks/
    /System/Library/Frameworks/
Yfeleke
la source
3
J'obtiens "impossible d'ouvrir 2: aucun fichier ou répertoire de ce type". Course à piedld -v 2
Jack
2
La question est étiquetée Linux, pas OS X. Je ne pense pas qu'OS X utilise GNU ld. Les gens de Binutil l'ont désactivé dans les scripts de construction. Il est désactivé depuis des années.
jww