Почему я должен перекомпилировать всю программу только для обновления библиотеки?

Относительно следующей ссылки: http://www.archlinux.org/news/libpnglibtiff-rebuilds-move-from-testing/

Может ли кто-нибудь объяснить мне, почему программу следует перестраивать после обновления одной из ее библиотек?

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

3 ответа

Решение

Если подписи задействованных функций не изменились, то "перестройка" программы означает, что объектные файлы должны быть снова связаны. Вам не нужно снова их компилировать.

API - это контракт, который описывает интерфейс для публичных функций в библиотеке. Когда компилятор генерирует код, он должен знать, какой тип переменных передавать в каждую функцию и в каком порядке. Он также должен знать тип возвращаемого значения, поэтому он знает размер и формат данных, которые будут возвращены из функции. Когда ваш код скомпилирован, адрес библиотечной функции может быть представлен как "начало библиотеки плюс 140 байтов". Компилятор не знает абсолютный адрес, поэтому он просто указывает смещение от начала библиотеки.

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

С другой стороны, если структуры данных в библиотеке изменились, и библиотека требует, чтобы вызывающие абоненты управляли памятью (плохая практика, но, к сожалению, обычная), вам нужно будет перекомпилировать код, чтобы он мог учесть изменения. Например, если ваш код использует malloc(sizeof(dataStructure)) чтобы выделить память для структуры данных библиотеки, которая в два раза больше, вам нужно перекомпилировать код, потому что sizeof(dataStructure) будет иметь большее значение.

Существует два вида совместимости: API и ABI.

Совместимость API - это функции и структуры данных, на которые могут опираться другие программы. Например, если версия 0.1 libfoo определяет функцию API, называемую "hello_world()", а версия 0.2 удаляет ее, любые программы, использующие "hello_world()", нуждаются в обновлении для работы с новой версией libfoo.

Совместимость ABI заключается в предположениях о том, как функции и, в частности, структуры данных представлены в двоичных файлах. Если, например, libfoo 0.1 также определил структуру данных recipe с двумя полями: "инструкции" и "ингредиенты" и libfoo 0.2 вводит "измерения" перед полем "ингредиенты", тогда программы, основанные на рецептах libfoo 0.1, должны быть перекомпилированы, поскольку поля "инструкции" и "ингредиенты", вероятно, будут находиться в разных позициях в версии 0.2 двоичного файла libfoo.so.

Что такое "библиотека"?

если "библиотека" является только двоичным файлом (например, динамически связанная библиотека, называемая ".dll", ".dylib" или ".so"; или статически связанная библиотека, называемая ".lib" или ".a"), то существует не нужно перекомпилировать, повторного связывания должно быть достаточно (и даже этого можно избежать в некоторых особых случаях)

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

Другие вопросы по тегам