我在动态和静态链接Ada中的库时遇到麻烦。我准备了一个最小的工作示例。这三个文件定义了一个输出“ 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;
我正在Windows上使用GPS 19.1 GNAT社区版。如果打开helloworld_interface.gpr并“全部构建”运行,则将编译一个exe文件,该exe文件可以按预期运行,并且完全独立。
如果在helloworld_lib.gpr中将Library_Kind
从static
更改为dynamic
,并像编译exe和dll之前一样进行构建。但是,编译后的文件现在依赖于libgnat-2019.dll
和libgcc_s_seh-1.dll
。没有这些DLL的程序将无法运行,这些DLL可以从C:\GNAT\2019\bin
复制。
鉴于可以生成一个没有其他依赖项的静态链接EXE文件,如何将此示例编译为没有其他依赖项的EXE和DLL?为什么现在需要这两个额外的DLL?
libgnat-2019.dll
是ANAT标准库的GNAT实现。 libgcc_s_seh-1.dll
是该标准库的依赖项。
如果编译没有动态库的单个可执行文件,则GNAT可以静态链接到标准库,因此您最终将不依赖于动态库。
但是,如果您链接到-nostdlib
和-nodefaultlibs
创建一个Ada DLL,但这将严重限制您在该库中执行的操作(iirc不会有例外)。