Подтвердить что ты не робот

Могу ли я получить отчет обо всех библиотеках, связанных при создании моего исполняемого файла С++ (gcc)? (включая статически связанную)

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

  • Мое главное приложение
  • Несколько конкретных приложений (libapp1, libapp2 и т.д.)
  • Несколько "сторонних" библиотек (большинство "третьих сторон - это просто другие команды в компании" ), связанные как с основным приложением, так и с библиотеками libappX приложений и с другими библиотеками третьей части. 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) Немного отдельный и менее важный вопрос, как я могу рассказать список всех include файлов, используемых во всем исходном дереве, который я создаю. Опять же, в идеале frm уже созданный исполняемый файл, который у меня есть отладочная версия.

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

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

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

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

4b9b3361

Ответ 1

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

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, - trace вместо -Wl, - verbose. Он также предоставит вам список библиотек, но менее подробный.

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

Ответ 2

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

ldd <app>

Непрямые/все зависимости;

ldd -r <app>

Ответ 3

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

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

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

objdump -t executable | grep '*ABS*'

Ответ 4

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

Ответ 5

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

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

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

Удачи!