web-dev-qa-db-fra.com

Puis-je obtenir un rapport de TOUTES les bibliothèques liées lors de la construction de mon exécutable C++ (gcc)? (y compris statiquement lié)

J'ai une application C++ dont j'ai hérité et qui comprend:

  • Mon application principale
  • Plusieurs bibliothèques spécifiques aux applications (libapp1, libapp2, etc ...)
  • Plusieurs bibliothèques "tierces" (la plupart des "tierces parties ne sont que d'autres équipes de la société") liées à la fois à l'application principale, aux bibliothèques libappX spécifiques à l'application et à d'autres bibliothèques tierces - par exemple. libext1, libext2, etc ...

En d'autres termes, mon code ressemble à ceci:

// main.C
#include <app1/a1l1.H>
#include <app2/a2l1.H>
#include <ext1/e1l1.H>

// app1/a1l1.H
#include <app1/a1l2.H>
#include <ext2/e2l1.H>

// app2/a2l1.H
#include <ext2/e2l2.H>

// ext1/e1l1.H
#include <ext3/e3l1.H>

// ext3/e3l1.H
#include <ext4/e4l1.H>

Des questions:

1) Comment puis-je savoir quelles bibliothèques ont été liées à l'exécutable final? Cela doit inclure les liens liés statiquement

En d'autres termes, je veux une réponse de "app1, app2, ext1, ext2, ext3, ext4"

Idéalement, la réponse serait disponible à partir de l'exécutable lui-même (j'ai une version de débogage construite au cas où cela le rendrait plus possible). Si cela est impossible, j'aimerais savoir s'il existe un outil simple d'analyse de code (quelque chose de vraiment réel dans gcc lui-même) pour fournir cette analyse.

Veuillez noter que les fichiers objets pour les bibliothèques externes sont déjà générés. Par conséquent, si vous consultez les journaux de construction pour savoir ce qui était lié, "ext4" n'apparaîtra pas dans le journal, car nous ne construirons pas "ext3". "bibliothèque déjà pré-construite.

REMARQUE: exécuter "nmake" avec DEPS défini sur yes pour reconstruire tout n'est pas une option. Mais j’ai accès au code source complet pour les bibliothèques externes.

2) Une question légèrement distincte et moins importante, comment puis-je donner une liste de tous les inclure des fichiers utilisés dans l’ensemble de l’arborescence source que je suis en train de construire. Encore une fois, idéalement, un exécutable déjà construit, dans lequel j’ai une version de débogage.

==================

UPDATE: Juste pour clarifier, nos bibliothèques sont liées statiquement, donc ldd (Liste des dépendances synamiques) ne fonctionne pas.

En outre, la réponse peut être soit pour Solaris, soit pour Linux, peu importe.

J'ai essayé d'utiliser nm mais cela ne liste pas les bibliothèques

20
DVK

J'avais un problème similaire et j'ai trouvé une solution: ajoutez l'option -Wl, - verbose lors de la liaison. Il passera l'éditeur de liens en mode commenté:

gcc -o test main.o -ltest -L. -Wl,--verbose

Voici un exemple de sortie:

GNU ld (GNU Binutils) 2.23.52.20130604
  Supported emulations:
   i386pep
   i386pe
using internal linker script:
==================================================
/* Default linker script, for normal executables */
[many lines here]
==================================================
attempt to open /usr/lib/gcc/x86_64-pc-cygwin/4.8.2/../../../../lib/crt0.o succeeded
/usr/lib/gcc/x86_64-pc-cygwin/4.8.2/../../../../lib/crt0.o
attempt to open /usr/lib/gcc/x86_64-pc-cygwin/4.8.2/crtbegin.o succeeded
/usr/lib/gcc/x86_64-pc-cygwin/4.8.2/crtbegin.o
attempt to open main.o succeeded
main.o
attempt to open ./libtest.dll.a failed
attempt to open ./test.dll.a failed
attempt to open ./libtest.a succeeded
(./libtest.a)test.o
[more lines here]
attempt to open /usr/lib/gcc/x86_64-pc-cygwin/4.8.2/crtend.o succeeded
/usr/lib/gcc/x86_64-pc-cygwin/4.8.2/crtend.o

Mise à jour: Vous pouvez également utiliser l'option -Wl, - trace au lieu de -Wl, - verbose. Il vous donnera également une liste de bibliothèques, mais est moins détaillé.

Mise à jour 2: -Wl, - trace ne affiche pas les bibliothèques incluses indirectement. Exemple: vous vous connectez à libA, et libA était lié à libB. Si vous voulez voir que libB est également nécessaire, vous devez utiliser -Wl, - verbose.

27
Daniel Frużyński

Pour les dépendances directes;

ldd <app>

Dépendances indirectes/toutes;

ldd -r <app>
9
ismail

Autant que je sache, peu d'informations sur les bibliothèques statiques sont conservées lors de la liaison (car l'éditeur de liens considère simplement cette bibliothèque comme une collection d'objets * .o).

Si vous trouvez la commande make qui relie l'exécutable final et ajoutez un indicateur -v, g++ vous montrera exactement comment il appelle la commande ld. Cela devrait inclure toutes les bibliothèques statiques nécessaires, y compris les bibliothèques utilisées par d'autres bibliothèques, sinon l'étape de liaison échouerait. Mais cela pourrait aussi inclure des bibliothèques supplémentaires qui ne sont pas réellement utilisées.

Une autre chose éventuellement utile est que, du moins sous Linux, les objets et les exécutables stockent généralement les noms des fichiers de code source à partir desquels ils ont été créés. (Nom de fichier uniquement, pas de chemin.) Essayez

objdump -t executable | grep '*ABS*'
4
aschepler

Essayez d'utiliser ldd + votre nom de fichier, cela listera les bibliothèques.

1
kohlehydrat

Je vais d'abord répondre à votre deuxième question. Vous pouvez simplement utiliser le drapeau -H ou -M pour voir tous les en-têtes (y compris le système) traités dans la compilation. gcc -H main.c devrait faire l'affaire. Voir quels en-têtes sont inclus vous mettra sur la bonne voie pour trouver les bibliothèques statiques qui ont été liées.

Vous pouvez utiliser objdump sur votre objet final (ou readelf sur votre binaire final) pour obtenir le nom de toutes les fonctions qu'il contient. Il faudrait ensuite aller chercher les bibliothèques dans lesquelles les fonctions ont été extraites, mais c'est un peu lourd. Vous devrez certainement faire un script pour minimiser la douleur.

Quelqu'un d'autre a mentionné l'utilisation de gcc <stuff> -Wl,-verbose qui passe simplement l'indicateur -verbose à l'éditeur de liens. C'est un moyen idéal pour obtenir une liste de bibliothèques partagées (fichiers .so), mais vous avez dit que les vôtres étaient statiques, ce qui ne vous convient pas dans ce cas.

Bonne chance!

0
s g