10

我正在做大学编程课程的介绍,选择的语言是 Ada。我正在用 Kate 编码并使用 GNAT 4.6.3 进行编译。我们必须为我们的程序使用教师提供的库,如下所示:

with foo;
use  foo;

当然,该文件foo.adb必须包含在与我的源文件相同的目录中。由于多个项目依赖于这个库,并且我喜欢将每个项目保存在自己的子目录中,因此我必须将库文件复制到每个新项目中。更不用说我的库代码和源代码都在同一个目录中。

那么有什么办法可以去:

with ../../lib/foo
use ../../lib/foo

?

我试过环顾四周,但我发现的只是关于编译器选项的东西。我宁愿不必搞乱这些,特别是因为只有某些项目需要这个特定的库,所以将它添加到全局编译器设置并让编译器毫无意义地搜索它不需要的路径是没有意义的不需要搜索。

4

4 回答 4

9

我会使用带有命令行的 GNAT 项目工具gnatmake

我只是设置了一个小例子(所以我可以确定我所说的有效!)。我有 3 个目录;teacher/包含教师提供的源代码,我假设您不想更改并且可能无论如何都没有写入权限,jacks_lib/包含teacher.gpr指向teacher/(您也可以将自己的库代码放在那里)并jack/包含您的代码main.adbmain.gpr.

jacks_lib/teacher.gpr

project Teacher is
   --  This project calls up the teacher-supplied source.

   --  This is a list of paths, which can be absolute but
   --  if relative are relative to the directory where this .gpr
   --  is found.
   for Source_Dirs use ("../teacher");

   --  Keep the built objects (.ali, .o) out of the way. Use the -p
   --  gnatmake flag to have directories like this built
   --  automatically.
   for Object_Dir use ".build";
end Teacher;

jack/main.gpr

--  teacher.gpr tells where to find library source and how to build it.
with "../jacks_lib/teacher";

project Main is
   --  for Source_Dirs use ("."); (commented out because it's the default)

   --  Keep built objects out of the way
   for Object_Dir use ".build";

   --  Build executables here rather than in Object_Dir
   for Exec_Dir use ".";

   --  What's the main program? (there can be more than one)
   for Main use ("main.adb");
end Main;

jack/main.adb

with Foo;
procedure Main is
begin
   null;
end Main;

那么,在jack/

$ gnatmake -p -P main.gpr
object directory "/Users/simon/tmp/jacks_lib/.build" created for project teacher
object directory "/Users/simon/tmp/jack/.build" created for project main
gcc -c -I- -gnatA /Users/simon/tmp/jack/main.adb
gcc -c -I- -gnatA /Users/simon/tmp/teacher/foo.ads
gnatbind -I- -x /Users/simon/tmp/jack/.build/main.ali
gnatlink /Users/simon/tmp/jack/.build/main.ali -o /Users/simon/tmp/jack/main

我应该补充一点,我在 Mac OS X 上使用 GCC 4.7.0,但这应该适用于任何最近的 GNAT。

于 2012-09-25T17:21:20.407 回答
6

编译器选项您管理构建源代码位置的方式 - 定义“搜索路径” - 特别是基于 gcc(如 GNAT)和大多数其他编译器的“-I”(包含)选项。

如果您是从命令行构建,则只需:

gnatmake -I../../lib/foo -Iother/path -Iyet/another/path project1_main.adb

gnatmake -I../../lib/foo -Isome/path -Iyet/another/path project2_main.adb

如果您使用 GPS (GNAT Programming Studio),则打开 Project Properties 对话框,选择 Source dirs 选项卡,然后在其中添加搜索路径。(您也可以直接直接编辑项目属性文件(“.gpr”),但我很少这样做。YMMV。)编译器设置很容易在每个项目的基础上设置,因此不存在“全局编译器设置”问题哪一个必须关心自己。

于 2012-09-25T13:00:31.843 回答
4

到目前为止,答案中没有明确提到它,所以我会说:

Ada 中的with&use子句没有声明废弃和使用过的单元的位置,只声明它们存在。

当涉及到实际查找单元时,这完全取决于make脚本、.gpr文件和编译选项或您想出的任何其他内容。

这就是 Ada 如何创建一定程度的代码可移植性(通过不将代码绑定到目录结构!),您只需要更正编译选项 :)

此外,了解编译器选项几乎从来都不是一个坏主意,它会在 Ada 和许多其他语言中为您提供良好的服务。

于 2012-09-26T08:09:49.180 回答
3

放大@MarcC 的答案,GNAT 用户指南gnatmake在第 6 章第 6.2 节gnatmake的开关:源和库搜索路径开关下进行了介绍;该指南应包含在您的发行版中。

gnatmake命令是一个方便的目标make,如本所示。

于 2012-09-25T16:09:27.733 回答