Reputation: 1391
I have the following project structure, where every .adb
file is a standalone executable that does not and will not depend on anything else:
project/
├── project.gpr
├── bin/
│ ├── bar
│ ├── baz
│ └── foo
├── obj/
│ └── .o's, .ali's, etcetera
└── src/
├── bar.adb
├── baz.adb
└── foo.adb
And this is 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;
Currently gprbuild
and gprclean
do exactly what I want, however the number of files under src/
might grow into the hundreds.
Is there a way to tell GPRbuild that every .adb
file under src/
shall be considered a Main
target without explicitly listing each one of them?
Upvotes: 2
Views: 1216
Reputation: 3341
Since you are using GPR, you may consider the use of aggregate projects.
You define 1 GPR per executable to be produced. Then you define 1 aggregate GPR to build them all.
I do believe you are very close to a use case described in this link
Quoting:
Most often, an application is organized into modules and submodules, which are very conveniently represented as a project tree or graph (the root project A withs the projects for each modules (say B and C), which in turn with projects for submodules.
Very often, modules will build their own executables (for testing purposes for instance), or libraries (for easier reuse in various contexts).
However, if you build your project through gnatmake or gprbuild, using a syntax similar to
gprbuild -PA.gpr
this will only rebuild the main programs of project A, not those of the imported projects B and C. Therefore you have to spawn several gnatmake commands, one per project, to build all executables. This is a little inconvenient, but more importantly is inefficient because gnatmake needs to do duplicate work to ensure that sources are up-to-date, and cannot easily compile things in parallel when using the -j switch.
Also libraries are always rebuilt when building a project.
You could therefore define an aggregate project Agg that groups A, B and C. Then, when you build with
gprbuild -PAgg.gpr
this will build all mains from A, B and C.
aggregate project Agg is
for Project_Files use ("a.gpr", "b.gpr", "c.gpr");
end Agg;
Of course, you end up having a little overhead of creating 1 GPR for each main, but it seems rather logic to clearly define each built artefact, specially if they will
never depend on each other
as you stated in your question.
However, it seems that GPR accepts a syntax for GPR aggregates where all GPRs in a given directory are taken into account. see here, and specifically here
Project_Files:
This attribute is compulsory. It specifies a list of constituent .gpr files that are grouped in the aggregate. The list may be empty. The project files can be any projects except configuration or abstract projects; they can be other aggregate projects. When grouping standard projects, you can have both the root of a project import closure (and you do not need to specify all its imported projects), and any project within the closure.
The basic idea is to specify all those projects that have main programs you want to build and link, or libraries you want to build. You can specify projects that do not use the Main attribute or the
Library_*
attributes, and the result will be to build all their source files (not just the ones needed by other projects).[...]
Paths can also include the
*
and**
globbing patterns. The latter indicates that any subdirectory (recursively) will be searched for matching files. The**
pattern can only occur at the last position in the directory part (i.e.a/**/*.gpr
is supported, but not**/a/*.gpr
). Starting the pattern with**
is equivalent to starting with./**
.At present the pattern
*
is only allowed in the filename part, not in the directory part. This is mostly for efficiency reasons to limit the number of system calls that are needed.Here are a few examples:
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
Upvotes: 1