С GNAT есть две задачи, которые выполняет компоновщик: во-первых, проверка того, что все необходимые компиляции были выполнены, чтобы закрытие программы было согласованным, и, во-вторых, организация выполнения обработки (эти задачи необходимы для любой системы сборки Ada, но они могут быть реализованы по-разному).
При использовании gnatmake
первое из этих заданий обычно лишнее, потому что gnatmake
уже организовал все необходимые компиляции. Сделать это неправильно (например, переместив модуль в другую библиотеку и не удалив продукты его компиляции из исходного места) можно, но довольно сложно!
Уточнение — это особенность Ады, которой нет во многих других языках. Объяснение есть на gcc.gnu .org и в других местах, но для простого примера
with Foo;
package Bar is
Int : Integer := Foo.Value;
[...]
end Bar;
package Foo is
function Value return Integer;
[...]
end Foo;
мы не знаем, что Foo.Value
вернет во время компиляции, и мы можем не знать до времени выполнения (что, если он считывает значение из командной строки?), поэтому Foo.Value
должен быть в подходящем состоянии для вызова до Bar
происходит инициализация.
Инициализация Bar
происходит, когда разрабатывается Bar
, а также для Foo
, поэтому задача gnatbind
состоит в том, чтобы распознать это и обеспечить, чтобы Foo
был разработан до Bar
.
Он делает это, посылая вызовы коду разработки пакетов в функцию (обычно называемую adanit
) и main()
, которая должна вызываться операционной системой, и вызывает adainit
, а затем основную программу Ады, скажем, program.adb
.
Затем gnatmake
вызывает gnatlink
, который берет код, сгенерированный gnatbind
, в Аде в файлах с именами b-program.ad[sb]
, b__program.ad[sb]
или b~program.ad[sb]
в зависимости от версии компилятора, компилирует его и связывает с закрытием программы для создания окончательного исполняемого файла.
person
Simon Wright
schedule
01.06.2018