我有以下项目结构,其中每个.adb
文件都是一个独立的可执行文件,它不会,也不会依赖于其他任何东西:
project/
├── project.gpr
├── bin/
│ ├── bar
│ ├── baz
│ └── foo
├── obj/
│ └── .o's, .ali's, etcetera
└── src/
├── bar.adb
├── baz.adb
└── foo.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 .adb
下的每个src/
文件都被认为是Main
目标而没有明确列出它们中的每一个?
由于您使用的是GPR,因此可以考虑使用聚合项目。
您为每个可执行文件定义1个GPR。然后定义1个聚合GPR来构建它们。
我相信你非常接近in this link描述的一个用例
引用:
大多数情况下,应用程序被组织成模块和子模块,它们非常方便地表示为项目树或图形(根项目A包含每个模块的项目(比如B和C),后者又包含子模块的项目。
通常,模块将构建自己的可执行文件(例如用于测试目的)或库(以便在各种上下文中更容易重用)。
但是,如果您通过gnatmake或gprbuild构建项目,请使用类似于的语法
gprbuild -PA.gpr
这只会重建项目A的主程序,而不是导入项目B和C的主程序。因此,您必须生成几个gnatmake命令,每个项目一个,以构建所有可执行文件。这有点不方便,但更重要的是效率低下,因为gnatmake需要做重复工作以确保源是最新的,并且在使用-j开关时不能轻易地并行编译。
在构建项目时,总是会重建库。
因此,您可以定义一个聚合项目Agg,它将A,B和C组分组。然后,在构建时使用
gprbuild -PAgg.gpr
这将构建A,B和C的所有主电源。
aggregate project Agg is
for Project_Files use ("a.gpr", "b.gpr", "c.gpr");
end Agg;
当然,你最终会为每个主要部分创建1个GPR,但是清楚地定义每个构建的人工制品似乎是相当逻辑的,特别是如果他们愿意的话
永远不要相互依赖
正如你在问题中所述。
但是,GPR似乎接受GPR聚合的语法,其中考虑了给定目录中的所有GPR。看看here,特别是here
Project_Files:
此属性是强制性的。它指定在聚合中分组的组成.gpr文件的列表。该列表可能为空。项目文件可以是除配置或抽象项目之外的任何项目;它们可以是其他聚合项目。在对标准项目进行分组时,您可以同时拥有项目导入闭包的根(并且您不需要指定其所有导入的项目)以及闭包内的任何项目。
基本思想是指定所有那些包含要构建和链接的主程序的项目,或者要构建的库。您可以指定不使用Main属性或
Library_*
属性的项目,结果将是构建所有源文件(而不仅仅是其他项目所需的文件)。[...]
路径还可以包括
*
和**
globbing模式。后者表示将搜索任何子目录(递归)以查找匹配的文件。**
模式只能出现在目录部分的最后一个位置(即支持a/**/*.gpr
,但不支持**/a/*.gpr
)。用**
开始模式相当于从./**
开始。目前,模式
*
仅允许在文件名部分中,而不是在目录部分中。这主要是出于效率原因限制所需的系统调用次数。这里有一些例子:
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
IIRC,没有声明任何Main
等同于要求GPRBuild编译所有可用的源文件。