Как определить межбиблиотечные зависимости? - PullRequest
5 голосов
/ 24 января 2011

Мой проект состоит из пары статических библиотек, которые связаны на последнем этапе. Теперь у меня проблема в том, что порядок библиотек важен (в противном случае я получаю неопределенную ошибку компоновщика символов). Иногда я сталкиваюсь с проблемой, что мне приходится пересортировать связанные библиотеки (-lcommon -lsetup -lcontrol и т. Д.). На данный момент это глупый метод проб и ошибок: пересортировать, скомпилировать, проверить ошибку, пересортировать, скомпилировать и так далее.

Итак, я написал небольшую программу, чтобы показать мне межбиблиотечные зависимости и сформировал порядок библиотек для связи. Он считывает определенные ('T', 'B' и т. Д.) И неопределенные символы ('U') из nm и удаляет слабые символы ('w', 'W ',' v 'и' V ') из «неопределенного списка символов». Теперь он определяет для каждого неопределенного символа библиотеку, которая его разрешает.

Но моя программа показывает мне круговые зависимости ... в чем моя ошибка?

Если они действительно существуют, я не смог бы связать вообще ... так что что я пропустил, анализируя вывод нм ? Или анализ выходной мощности нм не является способом получения этих зависимостей?

libcommon.a:
         U _ZN15HardwareUnit23GetHardwareSerialNumberEv
libhardware.a:
00000484 T _ZN15HardwareUnit23GetHardwareSerialNumberEv
libsecurityaccess.a:
         U _ZN15HardwareUnit23GetHardwareSerialNumberEv
---
libhardware.a:
         U _ZN21ApplicationProfile26GetApplicationSettingsPathERK7QString
libsecurityaccess.a:
00004020 T _ZN21ApplicationProfile26GetApplicationSettingsPathERK7QString
         U _ZN21ApplicationProfile26GetApplicationSettingsPathERK7QString

Ответы [ 2 ]

6 голосов
/ 24 января 2011

Другой вариант связать библиотеки с круговыми зависимостями - использовать для этого специальный параметр компоновщика. Man ld:

   -( archives -)
   --start-group archives --end-group
       The archives should be a list of archive files.  They may be either
       explicit file names, or -l options.

       The specified archives are searched repeatedly until no new
       undefined references are created.  Normally, an archive is searched
       only once in the order that it is specified on the command line.
       If a symbol in that archive is needed to resolve an undefined
       symbol referred to by an object in an archive that appears later on
       the command line, the linker would not be able to resolve that
       reference.  By grouping the archives, they all be searched
       repeatedly until all possible references are resolved.

       Using this option has a significant performance cost.  It is best
       to use it only when there are unavoidable circular references
       between two or more archives.

Хотя чище исключать круговые зависимости всегда чище.

2 голосов
/ 24 января 2011

Если у вас действительно есть круговая цепочка зависимостей статических библиотек (и это не ясно из вашей вставки; вы показываете только некруговую зависимость), есть две опции:

  1. Удалитькруговая зависимость как-то;Например, вы можете убедиться, что libcommon не ссылается на символы в libpthardware.
  2. Извлеките отдельные файлы .o из библиотеки .a и свяжите их напрямую.Тогда порядок ссылок больше не имеет значения.

В случае 2. может оказаться полезным использовать частичное связывание вместо создания статических библиотек.В системах, использующих GNU bintools, это можно сделать, вызвав что-то вроде:

ld -r -o libfoo.o foo.o bar.o

Эффект этого заключается в объединении файлов foo.o и bar.o в один файл .o.Порядок не имеет значения.После этого вы можете просто ссылаться на libfoo.o как на обычный объектный файл на последнем шаге ссылки.

Обратите внимание, что выполнение этого может помешать компоновщику отбрасывать не связанные части статической библиотеки (обычно это делается на уровне файлов .o внутри .a, я считаю).Если вы используете все или большинство из этих библиотек, это, вероятно, не проблема.Однако, если проблема с памятью кода, возможно, вы захотите изучить , автоматически отбрасывающий неиспользуемый код на уровне функции .Если вы сделаете это, передайте --gc-sections и -s только на этапе final link (и избегайте этого, если вам нужно отладить!).Кроме того, статическая связь с системными библиотеками не требуется в современном gcc.

...