Dynami c, связывающий библиотеку в Ada, вводит дополнительные зависимости - PullRequest
5 голосов
/ 12 февраля 2020

У меня проблемы с Dynami c и Stati c, связывающими библиотеку в Аде. Я подготовил минимальный рабочий пример. Эти три файла определяют библиотеку, которая выводит «Hello world»:

helloworld_lib.gpr :

project Helloworld_Lib is

   for Library_Name use "helloworld_lib";
   for Source_Files use ("helloworld_lib.adb", "helloworld_lib.ads");
   for Library_Kind use "static";
   for Library_Dir use "obj";

end Helloworld_Lib;

helloworld_lib.adb :

with Ada.Text_IO;

package body helloworld_lib is

   procedure Hello is
   begin
      Ada.Text_IO.Put_Line("Hello world");
   end Hello;

end helloworld_lib;

helloworld_lib.ads :

with Ada.Text_IO;
use Ada.Text_IO;

package helloworld_lib is

   procedure Hello;

end helloworld_lib;

Эти два файла определяют проект, который импортирует библиотеку и выполняет ее:

helloworld_interface .gpr :

with "helloworld_lib.gpr";

project Helloworld_Interface is

   for Create_Missing_Dirs use "True";
   for Main use ("helloworld_interface.adb");
   for Source_Files use ("helloworld_interface.adb");
   for Object_Dir use "obj";

end Helloworld_Interface;

helloworld_interface.adb :

with helloworld_lib; use helloworld_lib;

procedure helloworld_interface is

begin

   Hello;

end helloworld_interface;

Я использую GPS 19.1 GNAT Community Edition на Windows. Если helloworld_interface.gpr открыт и «Build All» запускается, исполняемый файл компилируется, который работает, как ожидается, и полностью автономен.

Если мы изменим Library_Kind с static на dynamic в helloworld_lib.gpr и сборка, как и раньше, exe и dll компилируются. Однако скомпилированные файлы теперь имеют зависимость от libgnat-2019.dll и libgcc_s_seh-1.dll. Программа не будет работать без этих библиотек DLL, которые можно скопировать из C:\GNAT\2019\bin.

Учитывая, что можно создать связанный EXE-файл stati c, который работает без других зависимостей, как этот пример может быть скомпилирован в EXE и DLL без других зависимостей? Почему сейчас нужны эти две дополнительные библиотеки DLL?

1 Ответ

7 голосов
/ 13 февраля 2020

libgnat-2019.dll - реализация GNAT стандартной библиотеки Ada. libgcc_s_seh-1.dll является зависимостью этой стандартной библиотеки.

Если вы компилируете один исполняемый файл без динамических библиотек c, GNAT может статически связываться со стандартной библиотекой, так что вы в конечном итоге не будете зависеть от динамических библиотек. c библиотеки.

Если, однако, вы ссылаетесь на библиотеку Ada dynamici c, возникает ситуация, когда как для исполняемого файла, так и для кода библиотеки требуется стандартная библиотека. Если вы попытаетесь статически связать стандартную библиотеку, вы получите стандартную библиотеку, связанную с DLL, а другую - с исполняемым файлом. Таким образом, вы будете иметь все объекты в стандартной библиотеке дважды при загрузке исполняемого файла, что запрещено семантикой языка Ada (например, дважды будет вызываться весь код инициализации пакета).

Следовательно, как только когда вы компилируете код Ada в файл DLL, у вас нет другого выбора, кроме как динамически связываться со стандартной библиотекой. Однако вы можете динамически связываться с C DLL-файлами, сохраняя возможность статического включения Ada stdlib. Теоретически вы можете создать Ada DLL с -nostdlib и -nodefaultlibs, но это серьезно ограничит то, что вы будете делать внутри этой библиотеки (iir c, исключений не будет).

...