Могу ли я получить отчет ВСЕХ библиотек, связанных при сборке моего исполняемого файла C ++ (gcc)?(включая статически связанные) - PullRequest
20 голосов
/ 07 февраля 2011

У меня есть унаследованное от меня приложение C ++, которое состоит из:

  • Моего основного приложения
  • Несколько библиотек для приложений (libapp1, libapp2 и т. Д.)
  • Несколько «сторонних» библиотек (большинство «третьих лиц - это просто другие команды в компании»), связанных как из основного приложения, из библиотек libappX для конкретного приложения, так и из других библиотек 3-й части - например, libext1,libext2 и т.д ...

Другими словами, мой код выглядит следующим образом:

// 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>

ВОПРОСЫ:

1)Как я могу сказать, какие библиотеки были связаны с конечным исполняемым файлом? Сюда должны входить статически связанные

Другими словами, я хочу получить ответ "app1, app2, ext1, ext2, ext3, ext4"

В идеале, ответбудет доступен из самого исполняемого файла (у меня есть встроенная отладочная версия на случай, если это сделает это более возможным).Если это невозможно, я хотел бы знать, есть ли простой инструмент анализа кода (то есть что-то внутри самого gcc), чтобы обеспечить этот анализ.

Обратите внимание, что объектные файлы для внешних библиотек уже созданы, поэтому ищитев журналах сборки, чтобы увидеть, что было связано, я беспокоюсь, что ext4 не будет отображаться в журнале, так как мы не будем собирать уже созданную библиотеку ext3.

ПРИМЕЧАНИЕ: запуск "nmake" с DEPS, установленным в yes, чтобы восстановить все, НЕ является опцией.Но у меня действительно есть доступ к полному исходному коду для внешних библиотек.

2) Несколько отдельный и менее важный вопрос, как я могу сказать список всех включаемых файлов , используемых ввсе исходное дерево я строю.Опять же, в идеале из уже созданного исполняемого файла, который у меня есть отладочная версия.

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

ОБНОВЛЕНИЕ: Просто для пояснения, наши библиотеки связаны статически, поэтому ldd (список динамических зависимостей) не работает.

Кроме того, ответ может быть либо для Solaris, либо для Linux - не имеет значения.

Я пытался использовать nm, но в нем нет библиотек

Ответы [ 5 ]

30 голосов
/ 17 апреля 2014

У меня была похожая проблема, и я нашел решение: добавьте опцию -Wl, - verbose при компоновке.Он переключит компоновщик в подробный режим:

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

Вот пример вывода:

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

Обновление: Вы также можете использовать -Wl, - опция трассировкивместо -Wl, - многословно.Это также даст вам список библиотек, но менее подробный.

Обновление 2: -Wl, - trace не отображает включенные библиотеки косвенно.Пример: вы связываете с libA, а libA была связана с libB.Если вы хотите увидеть, что libB также необходим, вы должны использовать -Wl, - verbose.

9 голосов
/ 07 февраля 2011

Для прямых зависимостей;

ldd <app>

Косвенные / Все зависимости;

ldd -r <app>
4 голосов
/ 07 февраля 2011

Насколько я знаю, при связывании сохраняется не так много информации о статических библиотеках (поскольку компоновщик просто видит эту библиотеку как коллекцию объектов * .o в любом случае).

Если вы найдете команду make, которая связывает конечный исполняемый файл и добавили флаг -v, g++ покажет вам, как именно она вызывает команду ld. Это должно включать все необходимые статические библиотеки, в том числе библиотеки, используемые другими библиотеками, в противном случае шаг соединения потерпит неудачу. Но это может также включать дополнительные библиотеки, которые на самом деле не используются.

Другая, возможно, полезная вещь - то, что, по крайней мере в Linux, объекты и исполняемые файлы обычно хранят имена файлов исходного кода, из которых они были созданы. (Только имя файла, без пути.) Попробуйте

objdump -t executable | grep '*ABS*'
1 голос
/ 07 февраля 2011

Попробуйте использовать ldd + ваше имя файла, это будет список библиотек.

0 голосов
/ 20 мая 2014

Сначала я отвечу на ваш второй вопрос.Вы можете просто использовать флаг -H или -M, чтобы увидеть все (включая системные) заголовки, обработанные в процессе компиляции.gcc -H main.c должен сделать свое дело.Проверка того, какие заголовки включены, фактически поможет вам определить, в какие статические библиотеки были связаны ссылки.

Вы можете использовать objdump в вашем конечном объекте (или readelf в вашем конечном двоичном файле), чтобы получитьимена всех функций там.Затем вам нужно будет найти библиотеки, из которых были извлечены функции, но это немного громоздко.Вам определенно придется создать скрипт, чтобы минимизировать боль.

Кто-то еще упомянул об использовании gcc <stuff> -Wl,-verbose, который просто передает флаг -verbose компоновщику.Это идеальный способ получить список общих библиотек (.so файлов), но вы сказали, что ваши статические, поэтому в данном случае это не тот путь.

Удачи!

...