Ada 使用GNAT使用静态库编译

Ada 使用GNAT使用静态库编译,ada,gnat,Ada,Gnat,为了了解编译Ada程序背后的过程(不必使用gpr),我决定手动编译我的一个项目。为了编译一个程序,我对其中的每个.adb文件运行以下命令(但不是手动): $gcc-csrc/.adb-o obj/.o 编译所有文件并将其放入obj目录 或者更确切地说,它会。这有一个小问题。我有一个从另一个项目生成的存档(静态库),名为libapples.a,其中包含包Apples。Apples包由您看到我在上面编译的文件使用 由于libapples.a不再有源文件(给定其存档格式),因此无法(甚至不可能)使用-

为了了解编译Ada程序背后的过程(不必使用
gpr
),我决定手动编译我的一个项目。为了编译一个程序,我对其中的每个
.adb
文件运行以下命令(但不是手动):

$gcc-csrc/.adb-o obj/.o

编译所有文件并将其放入
obj
目录

或者更确切地说,它会。这有一个小问题。我有一个从另一个项目生成的存档(静态库),名为
libapples.a
,其中包含包
Apples
Apples
包由您看到我在上面编译的文件使用

由于
libapples.a
不再有源文件(给定其存档格式),因此无法(甚至不可能)使用
-I
开关向上述命令提供该库的源文件;另一方面,如果我没有包含源代码,上面的命令会返回给我说:

.adb:::未找到文件“apples.ads”

gnatmake:“src/.adb”编译错误

我试图通过使用标志
-L
L
将库包括在编译过程中(我相信这是用C实现的方法;如果我错了,请随时纠正我)。在另一次尝试中,我将归档文件放在源目录中


如何在编译过程中包含一个库呢?

apples.ads
有点像C中的头文件,您肯定需要它来编译文件。您应该使用
-I
将gcc指向
apples.ads
所在的目录

请注意,编译Ada源代码不仅会生成一个对象文件,还会生成一个Ada库信息(
.ali
)文件。下一步你需要这个。您不应该使用
-o
标志,因为它可能导致您的
.o
.ali
文件具有不同的名称

另一方面,因为您只想生成一个对象文件,所以应该使用
-c
告诉gcc只编译。在C等其他语言中,默认情况下gcc编译和链接;在Ada中,这个过程更加复杂

编译后,需要在主程序的
.ali
文件上调用
gnatbind
。这将生成一个包,负责所有内容的正确初始化。为此,
gnatbind
需要
Apples
包的
.ali
文件!您可以使用
-aO
指定
.ali
搜索目录

最后,在主
.ali
文件上调用
gnatlink
,将所有内容链接在一起。它自行确定需要哪些对象文件和库。它将向链接器附加必要的选项,包括对
libapples.a
的引用。它还编译由
gnatlink
生成的包


我不知道gnatlink在引擎盖下到底能做什么;您可能可以手动编译由gnatbind生成的包,然后调用链接器(如果您能找到正确的参数)。

apples.ads
有点像C中的头,您肯定需要它来编译文件。您应该使用
-I
将gcc指向
apples.ads
所在的目录

请注意,编译Ada源代码不仅会生成一个对象文件,还会生成一个Ada库信息(
.ali
)文件。下一步你需要这个。您不应该使用
-o
标志,因为它可能导致您的
.o
.ali
文件具有不同的名称

另一方面,因为您只想生成一个对象文件,所以应该使用
-c
告诉gcc只编译。在C等其他语言中,默认情况下gcc编译和链接;在Ada中,这个过程更加复杂

编译后,需要在主程序的
.ali
文件上调用
gnatbind
。这将生成一个包,负责所有内容的正确初始化。为此,
gnatbind
需要
Apples
包的
.ali
文件!您可以使用
-aO
指定
.ali
搜索目录

最后,在主
.ali
文件上调用
gnatlink
,将所有内容链接在一起。它自行确定需要哪些对象文件和库。它将向链接器附加必要的选项,包括对
libapples.a
的引用。它还编译由
gnatlink
生成的包


我不知道gnatlink在引擎盖下到底能做什么;您可能可以手动编译由
gnatbind
生成的包,然后调用链接器(如果您能找到正确的参数)。

命令中没有包含
-c
,这是我的错误。谢谢你发现它!所以,不可能仅仅有一个
。一个
文件本身就表示Ada中的库,那么?您需要规范(
.ads
)文件以及
.ali
文件和
.a
文件,其中包含链接的目标文件,对吗?您需要规范来告诉Ada编译器可用的内容。您是否可以在不使用
.h
文件的情况下创建一个C应用程序来使用它的库?
.a
始终只是编译的目标代码,这部分不是特定于Ada的。C、C++和其他编译语言中的情况是一样的,除非它们编译成保留这些信息的中间代码(java,c**)。我必须承认,我以前从来没有对库有过明确的使用。我一直认为所有的东西都被藏在图书馆的文件里。:-)但是,注释可能为+1。命令中不包括
-c