J'ai une application C++ dont j'ai hérité et qui comprend:
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
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.
Pour les dépendances directes;
ldd <app>
Dépendances indirectes/toutes;
ldd -r <app>
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*'
Essayez d'utiliser ldd
+ votre nom de fichier, cela listera les bibliothèques.
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!