9 Двоичная совместимость
Двоичная совместимость охватывает несколько взаимосвязанных понятий:
- интерфейс прикладного двоичного кода (ABI)
- Набор соглашений времени выполнения, используемых всеми инструментами, работающими с двоичными представлениями программы, включая компиляторы, ассемблеры, линковщики и поддержку языка времени выполнения. Некоторые ABI формализованы с письменной спецификацией, возможно, разработанной несколькими заинтересованными сторонами. Другие просто представляют собой способ работы определённого набора инструментов.
- соответствие ABI
- Компилятор соответствует ABI, если он генерирует код, который следует всем спецификациям, перечисленным в этом ABI. Библиотека соответствует ABI, если она реализована в соответствии с этим ABI. Приложение соответствует ABI, если оно построено с использованием инструментов, которые соответствуют ABI, и не содержит исходного кода, который специально изменяет поведение, заданное ABI.
- конвенции вызова
- Конвенции вызова — это подмножество ABI, определяющее, как передаются аргументы и возвращаются результаты функций.
- взаимодействие
- Различные наборы инструментов взаимосвязаны, если они генерируют файлы, которые могут быть использованы в одной программе. Набор инструментов включает компиляторы, ассемблеры, линковщики, библиотеки, заголовочные файлы, файлы инициализации и отладчики. Двоичные файлы, созданные разными наборами инструментов, не являются взаимосвязанными, если они не реализуют один и тот же ABI. Это относится как к разным версиям одних и тех же инструментов, так и к инструментам от разных поставщиков.
- взаимовызываемость
- Возможность функции, скомпилированной одним набором инструментов, вызвать функцию, скомпилированную другим набором инструментов, является подмножеством взаимосвязанности.
- зависимые от реализации функции
- Стандарты языков включают списки зависимых от реализации функций, поведение которых может отличаться от одной реализации к другой. Некоторые из этих функций обычно покрываются ABI платформы, а другие нет. Функции, которые не покрываются ABI, обычно влияют на поведение программы, но не на взаимовызываемость.
- совместимость
- Соответствие одному ABI и одинаковому поведению зависимых от реализации функций являются важными факторами совместимости.
Интерфейс прикладного двоичного кода (ABI), реализованный компилятором C или C++, влияет на генерацию кода и поддержку времени выполнения для:
- размера и выравнивания типов данных
- расположения структурированных типов
- конвенций вызова
- конвенций использования регистров
- интерфейсов для поддержки арифметических операций во время выполнения
- форматов файлов объектов
Кроме того, интерфейс прикладного двоичного кода (ABI), реализованный компилятором C++, влияет на генерацию кода и поддержку времени выполнения для:
- изменения имён
- обработки исключений
- вызова конструкторов и деструкторов
- расположения, выравнивания и заполнения классов
- расположения и выравнивания виртуальных таблиц
Некоторые параметры компиляции GCC заставляют компилятор генерировать код, который не соответствует стандартному ABI платформы. Другие параметры вызывают разное поведение программы для функций, зависимых от реализации, которые не покрываются ABI. Эти параметры предоставляются для обеспечения согласованности с другими компиляторами, которые не следуют стандартному ABI платформы или обычному поведению функций, зависимых от реализации, на платформе. Будьте очень осторожны при использовании таких параметров.
Большинство платформ имеют чётко определённый ABI, который охватывает код C, но ABI, покрывающие функциональность C++, пока не являются распространёнными.
Начиная с GCC 3.2, двоичные соглашения GCC для C++ основаны на письменном, независимом от поставщика C++ ABI, разработанном для 64-битного Itanium, но также включающем общие спецификации, применимые к любой платформе. Этот C++ ABI также реализован другими поставщиками компиляторов на некоторых платформах, в частности, на системах GNU/Linux и BSD. Мы старались обеспечить стабильный ABI, совместимый с будущими выпусками GCC, но возможно, что мы столкнёмся с проблемами, которые сделают это затруднительным. Такие проблемы могут включать различные интерпретации C++ ABI разными поставщиками, ошибки в самом ABI или ошибки в реализации ABI в разных компиляторах. Переключатель GCC -Wabi предупреждает, когда G++ генерирует код, который, вероятно, не совместим с C++ ABI.
Библиотека C++, используемая с компилятором C++, включает Стандартную библиотеку C++, с функциональностью, определённой в стандарте C++, плюс поддержку языка времени выполнения. Поддержка времени выполнения включена в C++ ABI, но для Стандартной библиотеки C++ нет формального ABI. Две реализации этой библиотеки взаимосвязаны, если одна следует фактическому ABI другой и если обе построены с одним и тем же компилятором или компиляторами, которые соответствуют одному ABI для компилятора C++ и поддержки времени выполнения.
Когда G++ и другой компилятор C++ соответствуют одному C++ ABI, но реализации Стандартной библиотеки C++, которые они обычно используют, не следуют одному ABI для Стандартной библиотеки C++, файлы объектов, построенные этими компиляторами, могут быть использованы в одной программе только в том случае, если они используют одну и ту же библиотеку C++. Это требует указания расположения заголовочных файлов библиотеки C++ при вызове компилятора, чья обычная библиотека не используется. Расположение заголовочных файлов C++ GCC зависит от того, как был сконфигурирован сбор GCC, но его можно увидеть, используя параметр G++ -v.
-Igcc_install_directory/include/c++/3.3
Аналогично, компиляция кода с помощью G++, который должен использовать библиотеку C++, отличную от GNU C++, требует указания расположения заголовочных файлов для этой другой библиотеки.
Наиболее простой способ связать программу с использованием определённой библиотеки C++ — это использовать драйвер C++, который по умолчанию указывает на эту библиотеку C++. Драйвер g++, например, сообщает линковщику, где найти библиотеку C++ GCC (libstdc++) плюс другие необходимые библиотеки и файлы инициализации в правильном порядке.
Если программе необходимо использовать другую библиотеку C++ и нет возможности выполнить окончательную ссылку с помощью драйвера C++, который использует эту библиотеку по умолчанию, необходимо указать g++ местоположение и имя этой библиотеки. Возможно, также потребуется указать разные файлы инициализации и другие библиотеки поддержки времени выполнения, а также подавить использование библиотек поддержки GCC с одним или несколькими параметрами -nostdlib, -nostartfiles, и -nodefaultlibs.
© Free Software Foundation
Licensed under the GNU Free Documentation License, Version 1.3.
https://gcc.gnu.org/onlinedocs/gcc-4.9.4/gcc/Compatibility.html