9 Двоичная совместимость
Двоичная совместимость охватывает несколько взаимосвязанных понятий:
- интерфейс двоичного приложения (ABI)
-
Набор правил выполнения во время работы, которым следуют все инструменты, работающие с двоичными представлениями программы, включая компиляторы, ассемблеры, компоновщики и поддержку языка на уровне выполнения. Некоторые ABI формальны, с написанным спецификацией, возможно, разработанной несколькими заинтересованными сторонами. Другие — просто способ, которым фактически работают конкретные наборы инструментов.
- соответствие ABI
-
Компилятор соответствует ABI, если он генерирует код, который соответствует всем спецификациям, перечисленным в этом ABI. Библиотека соответствует ABI, если она реализована в соответствии с этим ABI. Приложение соответствует ABI, если оно скомпилировано с использованием инструментов, которые соответствуют этому ABI, и не содержит исходного кода, который специально изменяет поведение, указанное в ABI.
- конвенции вызова
-
Конвенции вызова — подмножество ABI, которые определяют способ передачи аргументов и возврата результатов функций.
- взаимодействие
-
Различные наборы инструментов взаимодействуют, если они генерируют файлы, которые могут использоваться в одной программе. Набор инструментов включает компиляторы, ассемблеры, компоновщики, библиотеки, заголовочные файлы, файлы запуска и отладчики. Двоичные файлы, созданные различными наборами инструментов, не совместимы, если они не реализуют одинаковый ABI. Это относится к различным версиям одних и тех же инструментов, а также к инструментам от разных поставщиков.
- взаимовызываемость
-
Вопрос о том, может ли функция в двоичном файле, созданном одним набором инструментов, вызвать функцию в двоичном файле, созданном другим набором инструментов, является подмножеством взаимодействия.
- функции, определяемые реализацией
-
Стандарты языка включают списки функций, определяемых реализацией, поведение которых может различаться в разных реализациях. Некоторые из этих функций обычно покрываются ABI платформы, а другие — нет. Функции, которые не покрываются ABI, обычно влияют на поведение программы, но не на взаимную вызываемость.
- совместимость
Соответствие одному и тому же ABI и одинаковому поведению функций, определяемых реализацией, имеют значение для совместимости.
Интерфейс двоичного приложения, реализованный компилятором C или C++, влияет на генерацию кода и поддержку во время выполнения для:
- размера и выравнивания типов данных
- структуры структурированных типов
- конвенций вызова
- конвенций использования регистров
- интерфейсов поддержки арифметических операций во время выполнения
- форматов файлов объектов
Кроме того, интерфейс двоичного приложения, реализованный 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 в разных компиляторах. Переключатель -Wabi GCC предупреждает, когда G++ генерирует код, который, вероятно, несовместим с C++ ABI.
C++ библиотека, используемая с C++ компилятором, включает Стандартную C++ Библиотеку с функциональностью, определённой в стандарте C++, плюс поддержку языка на уровне выполнения. Поддержка выполнения включается в C++ ABI, но нет формального ABI для Стандартной C++ Библиотеки. Две реализации этой библиотеки взаимодействуют, если одна следует фактическому ABI другой, и если обе построены с одним и тем же компилятором или с компиляторами, которые соответствуют одному и тому же ABI для C++ компилятора и поддержки выполнения.
Когда G++ и другой C++ компилятор соответствуют одному и тому же C++ ABI, но реализации Стандартной C++ Библиотеки, которые они обычно используют, не следуют одному и тому же ABI для Стандартной C++ Библиотеки, файлы объектов, построенные с этими компиляторами, могут использоваться в одной программе только если они используют одну и ту же C++ библиотеку. Это требует указания местоположения заголовочных файлов C++ библиотеки при вызове компилятора, чья обычная библиотека не используется. Местоположение заголовочных файлов C++ GCC зависит от того, как был сконфигурирован GCC build, но может быть видно с помощью опции G++ -v. С параметрами по умолчанию для G++ 3.3 строка компиляции для другого C++ компилятора должна содержать
-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-13.3.0/gcc/Compatibility.html