Я попытался статически связать некоторые встроенные библиотеки, используя статический параметр в компоновщике. Я использую SCons для компиляции/связывания библиотек. У меня создалось впечатление, что статические сборки происходят во время связи, и поэтому неважно, что вы связываете. Я получил кучу ошибок и задавался вопросом, существует ли какая-либо разница между файлами .o, которые были предназначены для статической привязки к библиотекам и файлам .o, которые были предназначены для динамической привязки к библиотекам. Теоретически, должны ли они быть одинаковыми?Происходит ли какое-либо событие во время сборки, специфичное для статической привязки
ответ
В общем случае вы не можете использовать статические и динамические библиотеки взаимозаменяемо. См: Static link of shared library function in gcc
Что касается вашего актуальный вопрос:
... если есть какая-то разница между .o файлов, которые были предназначены, чтобы быть статически связан с библиотеками и .o файлы, которые были предназначены, чтобы быть динамически связанных с библиотеками. Теоретически, должны ли они быть одинаковыми?
Нет, они не должны быть одинаковыми. Существуют различия, наиболее заметным из которых является то, что динамическая библиотека имеет непустую раздел .dynsym
.
Если функция foo()
связана статически в приложение, то функции Defintion будет на фиксированной (статический!) Месте относительно остальной части кода приложений.
С другой стороны, если мы ссылаемся foo()
динамически в наше приложение, а затем во время компиляции приложение не может знать, где он может найти определение foo()
во время выполнения, так как приложение не может делать какие-либо предположения о библиотека - не о местонахождении библиотек во время выполнения, ни о ее внутренней структуре. Таким образом, сама библиотека предоставляет раздел .dynsym
, чтобы клиентский код мог найти определение foo
, хотя было неясно, в какое время это будет происходить.
Я мало знаю о SCons, но насколько я знаю, он похож на другие системы make и по-прежнему выполняет те же шаги компиляции/связывания. Архитектура связывания уже well documented on Stack Overflow, поэтому я попытаюсь объяснить различия.
Поскольку статические библиотеки предназначены для разрешения символов в исполняемом файле при связывании, им не требуется ничего особенного, поскольку во время компиляции происходит разбор. Динамические библиотеки нуждаются в особом рассмотрении, поскольку они разрешены во время выполнения, и компоновщик не знает, как они будут использоваться. Вам понадобятся специальные флаги (например, флаг fPIC для создания кода, который можно запустить в любом месте в памяти).
Итак, короткий ответ: да, есть различия. Насколько мне известно, объектный файл, созданный для динамической компоновки, может быть превращен в статическую библиотеку (с некоторыми possible code bloat), но большинство объектных файлов, созданных для статической привязки, не могут использоваться для динамической компоновки, поскольку они, вероятно, не имеют необходимые флаги. Обычно я думаю об этом (неофициально), поскольку статическая библиотека похожа на другой объектный файл, тогда как динамическая библиотека похожа на автономный исполняемый файл, который просто подключен (что фактически ближе к формату ELF, обычно используемому для общих библиотек).