рассуждения о статических библиотеках C / C ++ - PullRequest
4 голосов
/ 07 марта 2012

Я никогда не задумывался о проблеме ниже, но так как мне теперь приходится иметь дело с кучей зависимостей в моем коде, я подумал, что мне лучше изложить факты.Давайте ограничим это современной версией Linux, скажем, ubuntu amd64.

Поскольку статические библиотеки не содержат динамических ссылок на библиотеки, как разрешаются неопределенные символы в статических библиотеках?Может ли зависимый двоичный файл динамически загружать неопределенные символы или символы должны быть разрешены другой статической библиотекой или объектным файлом во время компиляции?

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

Например, статическая библиотека L использует malloc из libc6.so и будет использоваться приложением A.Будут ли L и A оба динамически использовать malloc из libc6.so?

Ответы [ 2 ]

7 голосов
/ 07 марта 2012

Статическая библиотека - это не что иное, как список объектных файлов, заархивированных вместе.

Как разрешаются неопределенные символы в статических библиотеках?

Они не разрешены, посколькунет неопределенных символов.Символ считается неопределенным только на этапе связывания, и при создании статической библиотеки связывание не происходит.

При связывании двоичного файла со статической библиотекой могут быть неопределенные символы.В этом случае статическая библиотека обрабатывается как часть вашей программы, и поэтому все ссылки на символы, используемые в этой статической библиотеке, должны быть доступны в объеме создаваемой вами программы.Например, если программа A связывается со статической библиотекой B, которая использует символ C из другой библиотеки D, то программа A должна связываться с B и D.

может зависимый двоичный файл динамически загружать неопределенные символы

Да, может.Но вы не должны идти по этому пути, если вам действительно не нужно ленивое динамическое разрешение.

или символы должны быть разрешены другой статической библиотекой или объектным файлом во время компиляции

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

Может ли компилятор разрешить ...

Компилятор не разрешает никаких зависимостей.Это работа линкера.Зависимости могут быть разрешены во время компоновки или во время выполнения динамическим компоновщиком.

зависимостей (приложения, зависящего от статической библиотеки), связываясь с динамической библиотекой, ...

Линкеры могут понимать, что используемая вами статическая библиотека зависит от символов в динамической библиотеке, с которой вы связываетесь.

и, если это так, будет кодировать текст статическипреобразован в получившийся двоичный файл или будет существовать динамическая ссылка?

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

Например, статическая библиотека Lиспользует malloc из libc6.so, и он будет использоваться приложением A. Будут ли L и A использовать malloc из libc6.so динамически?

Да, если только определение malloc() не было доступно ввремя компиляции статической библиотеки и компилятора по какой-то причине просто встроило тело malloc() в код статической библиотеки.Но с malloc() этого не произойдет.Может быть с другими функциями.

1 голос
/ 07 марта 2012

статическая библиотека (файл foo.a ) - для практических целей - набор объектных файлов ( xo , yo , ...) упакован с ar , архиватором.

Эта статическая библиотека используется во время соединения, чтобы удовлетворить иначе неопределенные ссылки.Все, что не выполняется во время компоновки (время компиляции здесь не важно), должно выполняться во время загрузки через динамическую библиотеку (файлы bar.so ).

В васВ последнем примере со статической библиотекой L и программой A оба (A, L) будут использовать один и тот же malloc из libc6.so, поскольку вы не используете предварительная загрузка , встроенные malloc из разных могут быть разнымифайлы заголовков или другие хитрости, которые вы не упомянули.

...