Ada 每个源文件都是主文件的GPR项目?

Ada 每个源文件都是主文件的GPR项目?,ada,gnat,Ada,Gnat,我有以下项目结构,其中每个.adb文件都是一个独立的可执行文件,不依赖任何其他内容: 这是project.gpr: project Project is for Source_Dirs use ("src"); for Object_Dir use "obj"; for Exec_Dir use "bin"; for Main use ("src/foo.adb", "src/bar.adb", "src/baz.adb"); end Project; 目前,gprbu

我有以下项目结构,其中每个
.adb
文件都是一个独立的可执行文件,不依赖任何其他内容:

这是
project.gpr

project Project is
   for Source_Dirs use ("src");
   for Object_Dir use "obj";
   for Exec_Dir use "bin";
   for Main use ("src/foo.adb", "src/bar.adb", "src/baz.adb");
end Project;
目前,
gprbuild
gprclean
正是我想要的,但是
src/
下的文件数量可能会增加到数百个


有没有办法告诉GPRbuild,在
src/
下的每个
.adb
文件都应被视为
Main
目标,而不明确列出它们中的每一个?

IIRC,不声明任何
Main
等同于要求GPRbuild编译所有可用的源文件。

因为您正在使用GPR,您可以考虑使用聚合项目。

每个要生成的可执行文件定义1个GPR。 然后定义1个聚合GPR来构建它们

我相信您非常接近所描述的用例

引述:

通常,应用程序被组织成模块和子模块,它们非常方便地表示为项目树或图(根项目a包含每个模块的项目(例如B和C),而根项目a又包含子模块的项目

通常,模块将构建它们自己的可执行文件(例如用于测试目的)或库(以便在各种上下文中更容易重用)

但是,如果您通过gnatmake或gprbuild构建项目,则使用类似于

这将只重建项目A的主程序,而不是导入的项目B和C的主程序。因此,您必须生成多个gnatmake命令,每个项目一个,以构建所有可执行文件。这有点不方便,但更重要的是效率低下,因为gnatmake需要重复工作以确保源是最新的,并且在使用-j开关时无法轻松并行编译

此外,在构建项目时,库始终会重建

因此,您可以定义一个聚合项目Agg,将A、B和C分组

这将从A、B和C构建所有干线

当然,为每个主设备创建1个GPR会有一点开销,但是清楚地定义每个构建的人工制品似乎是合乎逻辑的,特别是如果它们愿意的话

永远不要相互依赖

正如你在问题中所说的那样

然而,GPR似乎接受GPR聚合的语法,其中考虑了给定目录中的所有GPRs。请参阅,特别是

项目文件:

此属性是必需的。它指定在聚合中分组的组成.gpr文件的列表。该列表可能为空。项目文件可以是除配置项目或抽象项目之外的任何项目;它们可以是其他聚合项目。对标准项目分组时,可以同时具有项目导入结束的根(并且不需要指定其所有导入的项目)和闭包中的任何项目

基本思想是指定所有那些具有要生成和链接的主程序或要生成的库的项目。您可以指定不使用main属性或
Library*
属性的项目,结果将生成其所有源文件(而不仅仅是其他项目所需的源文件)

[……]

路径还可以包括
*
***
全局模式。后者表示将(递归地)搜索任何子目录以查找匹配的文件。
***
模式只能出现在目录部分的最后一个位置(即
a/***。支持gpr
,但不支持
***/a/*.gpr
)。以
**
开头的模式等同于以
/**
开头

目前,模式
*
只允许在文件名部分使用,而不允许在目录部分使用。这主要是为了提高效率,以限制所需的系统调用数量

以下是几个例子:


上面说不应该将目录组件放在主文件名中(我知道这不是答案,但是…)尽管如此,我还是刚开始学习Ada的诀窍。既然你是从Ada开始的,你应该记住Ada是一种编程语言,GNAT是该语言的特定编译器。GNAT如何执行编译的详细信息,包括其项目机制、项目文件语言、使用特定文件的压力名称、每个文件只有一个编译单元的压力等等,从技术上讲不是Ada。你应该试着在脑海中区分你正在学习的部分是Ada,哪些是GNAT特定的。从技术上讲,这是正确的,但是如果没有
Main
子句,GPRbuild只编译源文件,而没有performing绑定和链接步骤。因此最终的可执行文件没有生成。您可以尝试
gprbuild-P project src/*。adb
-gprbuild将命令行中提到的文件视为主程序,如果它们包含潜在的主程序(无参数子程序)。而不是(此处)似乎很关心目录组件。这会让您需要一个Makefile。我可能会误解这一点,但这不就是将指定GPR中每个主文件的负担转移到指定聚合GPR中的每个GPR吗?或者这个示例就是这样做的,并且有一种替代语法,您不必手动指定聚合中的y GPR?答案相应编辑:似乎可以避免指定每个.GPR文件的痛苦。
project Project is
   for Source_Dirs use ("src");
   for Object_Dir use "obj";
   for Exec_Dir use "bin";
   for Main use ("src/foo.adb", "src/bar.adb", "src/baz.adb");
end Project;
    gprbuild -PA.gpr
     gprbuild -PAgg.gpr
    aggregate project Agg is
       for Project_Files use ("a.gpr", "b.gpr", "c.gpr");
    end Agg;
    for Project_Files use ("a.gpr", "subdir/b.gpr");
    --  two specific projects relative to the directory of agg.gpr

    for Project_Files use ("/.gpr");
    --  all projects recursively