10 Двоичная совместимость
Двоичная совместимость охватывает несколько связанных понятий:
- двоичный интерфейс приложения (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++ основываются на письменном, независимом от производителей ABI для C++, разработанном специально для 64-разрядного Itanium, но также содержащем общие спецификации, применимые к любой платформе. Этот ABI для C++ реализован и другими производителями компиляторов на некоторых платформах, в частности в системах GNU/Linux и BSD. Мы приложили большие усилия, чтобы обеспечить стабильность ABI и его совместимость с будущими выпусками GCC, однако возможно, что возникнут проблемы, затрудняющие это. К таким проблемам могут относиться разные интерпретации ABI для C++ разными производителями, ошибки в ABI или ошибки реализации ABI в разных компиляторах. Параметр -Wabi GCC выдаёт предупреждение, если G++ генерирует код, который, вероятно, несовместим с ABI для C++.
Библиотека C++, используемая компилятором C++, включает стандартную библиотеку C++, функциональность которой определена в стандарте C++, а также поддержку времени выполнения языка. Поддержка времени выполнения включена в ABI для C++, но для стандартной библиотеки C++ формального ABI не существует. Две реализации этой библиотеки взаимодействуют, если одна следует де-факто ABI другой и если они обе собраны одним и тем же компилятором либо компиляторами, соответствующими одному и тому же ABI для компилятора C++ и поддержки времени выполнения.
Если G++ и другой компилятор C++ соответствуют одному и тому же ABI для C++, но используемые ими по умолчанию реализации стандартной библиотеки C++ не следуют одному и тому же ABI для стандартной библиотеки C++, объектные файлы, собранные этими компиляторами, можно использовать в одной программе только при условии, что они используют одну и ту же библиотеку C++. Для этого при вызове компилятора, обычно использующего другую библиотеку, необходимо указать расположение заголовочных файлов библиотеки C++. Расположение заголовочных файлов C++ GCC зависит от параметров конфигурации сборки GCC, но его можно узнать с помощью параметра G++ -v. При конфигурации G++ 3.3 с параметрами по умолчанию строка компиляции для другого компилятора C++ должна включать
-Igcc_install_directory/include/c++/3.3
Аналогичным образом, для компиляции с помощью G++ кода, который должен использовать библиотеку C++, отличную от библиотеки GNU 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-15.3.0/gcc/Compatibility.html