Импорт прагм в Аду: откуда GNAT знает, где искать? - PullRequest
3 голосов
/ 13 апреля 2020

Я использовал эту прагму для импорта getpid из C:

function Get_Process_ID return Process_ID;
pragma Import (C, Get_Process_ID, "getpid");

Я ожидал, что это будет немного сложнее. Чтобы использовать getpid в C, мне нужно явно включить заголовочный файл unistd.h; в приведенной выше прагме я не делал никаких ссылок на заголовочный файл. Как GNAT точно знает, где найти getpid?

Редактировать:

Вот минимальный рабочий пример:

with Ada.Text_IO;

procedure Main is
   subtype Process_ID is Integer;
   function Get_Process_ID return Process_ID;
   pragma Import (C, Get_Process_ID, "getpid");   
begin
   Ada.Text_IO.Put_Line (Process_ID'Image (Get_Process_ID));
end Main;

Сохранено как основное .adb, это компилируется с помощью следующей команды:

gnat make main.adb

Я использую fre sh установку пакета gnat из репозиториев программного обеспечения Ubuntu 18.04 без файлов конфигурации или файлов проекта. Версия GNAT: 7.5.0.

1 Ответ

6 голосов
/ 13 апреля 2020

Подробное объяснение доступно в документации AdaCore на GNAT Configurable Runtime Facility . По умолчанию программа, скомпилированная с помощью GNAT, связана с lib c .a и некоторыми другими:

При сборке программы Ada объектный код, составляющий конечный исполняемый файл, может быть получен из следующие объекты (в дополнение к самому пользовательскому коду):

  • библиотека времени выполнения GNAT Pro
  • C библиотека
  • библиотека математики
  • Внутренняя библиотека G CC
  • Код запуска

Драйверы GNAT и G CC автоматически связывают все эти библиотеки и объекты с конечным исполняемым файлом, статически или динамически в зависимости от цель и некоторые параметры компиляции. Опции -nostdlib и -nodefaultlibs могут использоваться для управления этим автоматическим поведением c.

Компиляция моего минимального рабочего примера с флагом -nostdlib завершается неудачно со следующей ошибкой (среди многих других ):

...
main.adb:(.text+0x20): undefined reference to `getpid'
...

Функции, предоставляемые в lib c .a, могут различаться в зависимости от платформы. В Ubuntu вы можете найти lib c .a с помощью locate и проверить, какие символы определены с помощью nm.

...