Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Question about GNAT project files.

125 views
Skip to first unread message

Peter C. Chapin

unread,
Feb 26, 2012, 2:48:56 PM2/26/12
to
I have a library described by a project file, say lib.gpr. I also have a
test program that exercises the library described by a different project
file tests.gpr. Finally I have a benchmark program that does speed tests
of the library described by a project file benchmarks.gpr.

This is fine but it's a pain having three separate projects. Typically
if I change the library I also want to update the tests and benchmarks.
I'd like to do all that from a single instance of GPS.

Thought #1: Create an empty "master" project that imports the three
projects I mentioned above as subprojects. This doesn't work. As soon as
I try to build something GPS tells me that my project (the master
project) doesn't have any Ada sources. Perhaps I'm doing it wrong.

Thought #2: Make lib.grp my master and add "with ../tests/tests.gpr" and
"with ../benchmarks/benchmarks.gpr" to it so that I can see and
manipulate all three projects at once. This doesn't work either. My
tests and benchmarks projects have a dependency on lib.gpr resulting in
circular dependencies when I try include them in lib.gpr.

Thought #3: Ditch my tests and benchmarks projects and just add their
sources, etc, to my lib.grp project (maybe rename lib.gpr). This would
give me a project with two target executables and a library. I think
this could work but I do like having the projects optionally independent
too. Someone using the library could just "with lib.gpr" without pulling
in all sorts of other stuff.

What is the "right" way to do this?

Peter

Dmitry A. Kazakov

unread,
Feb 26, 2012, 3:15:49 PM2/26/12
to
On Sun, 26 Feb 2012 14:48:56 -0500, Peter C. Chapin wrote:

> I have a library described by a project file, say lib.gpr. I also have a
> test program that exercises the library described by a different project
> file tests.gpr. Finally I have a benchmark program that does speed tests
> of the library described by a project file benchmarks.gpr.
>
> This is fine but it's a pain having three separate projects. Typically
> if I change the library I also want to update the tests and benchmarks.
> I'd like to do all that from a single instance of GPS.

with "../lib.gpr";
project Lib.Tests is
for Main use (<list of tests>);
package Compiler renames Lib.Compiler;
package Binder renames Lib.Binder;
package Builder renames Lib.Builder;
package Linker renames Lib.Linker;
end Lib.Tests;

P.S. Lib is not really a library, rather a project containing the source
files of the library. For a true library, you would need a separate project
specially for building it static, dynamic, debug, release. I usually
generate this from a script because it depends on the target due to various
packaging policies.

--
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de

Greg Moncreaff

unread,
Feb 26, 2012, 5:18:02 PM2/26/12
to
On Feb 26, 2:48 pm, "Peter C. Chapin" <PCha...@vtc.vsc.edu> wrote:
> I have a library described by a project file, say lib.gpr. I also have a
> test program that exercises the library described by a different project
> file tests.gpr. Finally I have a benchmark program that does speed tests
> of the library described by a project file benchmarks.gpr.
>
> This is fine but it's a pain having three separate projects. Typically
> if I change the library I also want to update the tests and benchmarks.
> I'd like to do all that from a single instance of GPS.
>
> Thought #1: Create an empty "master" project that imports the three
> projects I mentioned above as subprojects. This doesn't work. As soon as
> I try to build something GPS tells me that my project (the master
> project) doesn't have any Ada sources. Perhaps I'm doing it wrong.
>

Look for something called an 'aggregate' project.

http://www.adacore.com/wp-content/files/auto_update/gnat-unw-docs/html/gnat_ugn_12.html#SEC152

Ludovic Brenta

unread,
Feb 27, 2012, 8:08:40 AM2/27/12
to
Peter C. Chapin wrote on comp.lang.ada:
> I have a library described by a project file, say lib.gpr. I also have a
> test program that exercises the library described by a different project
> file tests.gpr. Finally I have a benchmark program that does speed tests
> of the library described by a project file benchmarks.gpr.
>
> This is fine but it's a pain having three separate projects. Typically
> if I change the library I also want to update the tests and benchmarks.
> I'd like to do all that from a single instance of GPS.
[...]
> What is the "right" way to do this?

I would keep the library project file unchanged and create one project
file for both the tests and the benchmark:

with "lib.gpr";
project Main is
for Source_Dirs use ("tests", "benchmarks");
for Main use ("test", "benchmark");
end Main;

You load main.gpr in GPS. If a source file of the library has changed,
gnatmake will recursively rebuild the library using the compiler
switches
specified in lib.gpr and will rebuild any source files of the tests or
benchmark that depend on the recompiled units in the library.

Make sure the Object_Dir of your two project files are different.

Make sure that lib.gpr contains "for Externally_Built use "false";"
(this is the default if you don't specify anything).

HTH

--
Ludovic Brenta.

Peter C. Chapin

unread,
Feb 27, 2012, 8:41:10 AM2/27/12
to
On 2012-02-26 17:18, Greg Moncreaff wrote:

> Look for something called an 'aggregate' project.
>
> http://www.adacore.com/wp-content/files/auto_update/gnat-unw-docs/html/gnat_ugn_12.html#SEC152

That's interesting. I didn't realize there were such projects. I'm not
sure if it applies to my case though since two of my existing projects
are not libraries but contains main procedures. Maybe it would work anyway.

Peter

Peter C. Chapin

unread,
Feb 27, 2012, 8:43:25 AM2/27/12
to
On 2012-02-27 08:08, Ludovic Brenta wrote:

> I would keep the library project file unchanged and create one project
> file for both the tests and the benchmark:
>
> with "lib.gpr";
> project Main is
> for Source_Dirs use ("tests", "benchmarks");
> for Main use ("test", "benchmark");
> end Main;
>
> You load main.gpr in GPS.

That's an interesting idea, thanks. I've done something similar in other
cases where I configured a project to use the test program as the "main"
program even though the real purpose of the project was to build a
library. This is the same idea except 1) the library is in its own
project (which I like) and 2) the main project has two main programs.

Thanks for the suggestion.

Peter

Simon Wright

unread,
Feb 27, 2012, 10:27:37 AM2/27/12
to
Ludovic Brenta <lud...@ludovic-brenta.org> writes:

> for Main use ("test", "benchmark");

According to [1], the Main attribute contains a list of file *names* so
that should be ("test.adb", "benchmark.adb").

Clearly it works without the file extension, not sure whether it makes
any difference!

[1]
http://www.adacore.com/wp-content/files/auto_update/gprbuild-docs/html/gprbuild_ug.html#Main-Subprograms

Peter C. Chapin

unread,
Feb 27, 2012, 9:02:46 PM2/27/12
to
On 2012-02-27 08:08, Ludovic Brenta wrote:

> I would keep the library project file unchanged and create one project
> file for both the tests and the benchmark:
>
> with "lib.gpr";
> project Main is
> for Source_Dirs use ("tests", "benchmarks");
> for Main use ("test", "benchmark");
> end Main;
>
> You load main.gpr in GPS.

I set this up and it basically works fine... which is great. I do have
one quirk though. My library has some SPARK components. When I load
lib.gpr directly I can run the Examiner from inside GPS fine. It uses a
command line that looks, in part, like

spark -index_file=lib.idx ...

This works because the SPARK index file (lib.idx) is in the same folder
as the project file (lib.gpr). However, when I load my main project file
as defined above and then try to run the Examiner on a file in the lib
subproject it does not work. The command above is issued but the
Examiner complains that it can't open the file lib.idx. I suspect that
the working folder is the one containing main.gpr and not the one
containing lib.gpr.

It seems like, ideally, GPS should change to the folder of the
subproject before issuing commands defined as external tools over that
project. I don't see a way to make it do this. Perhaps this is a problem
with the GPS/SPARK integration. Maybe I could fix it myself by tinkering
with the Python files of the appropriate plug-in. However, before
attempting something like that I thought I'd ask here to see if there's
a better way.

Right now to use SPARK on my library I need to load the lib.gpr file
directly. That's not the end of the world, but it's also not everything
I had hoped for.

Peter

Phil Thornley

unread,
Feb 28, 2012, 1:56:52 AM2/28/12
to
In article <hfSdnUg7kIR...@giganews.com>, PCh...@vtc.vsc.edu
says...
Try adding:

package Ide is
for Default_Switches ("examiner")
use ("-index_file=<path to project folder>lib.idx");
end Ide;

to main.gpr. This should override the index file defined in lib.gpr.

Cheers,

Phil

Yannick Duchêne (Hibou57)

unread,
Feb 28, 2012, 11:59:49 AM2/28/12
to
Le Mon, 27 Feb 2012 14:41:10 +0100, Peter C. Chapin <PCh...@vtc.vsc.edu>
a écrit:
Seems GNAT Pro specific, I can't retrieve the same from the FSF GNAT
User's Guide.

--
“Syntactic sugar causes cancer of the semi-colons.” [1]
“Structured Programming supports the law of the excluded muddle.” [1]
[1]: Epigrams on Programming — Alan J. — P. Yale University

AdaMagica

unread,
Feb 28, 2012, 1:10:06 PM2/28/12
to
On 28 Feb., 17:59, Yannick Duchêne (Hibou57)
<yannick_duch...@yahoo.fr> wrote:
> >> Look for something called an 'aggregate' project.
>
> >>http://www.adacore.com/wp-content/files/auto_update/gnat-unw-docs/htm...
>
> Seems GNAT Pro specific, I can't retrieve the same from the FSF GNAT
> User's Guide.

Will probably be in GNAT GPL 2012 coming eventually.

GNATPro is always ahead.

Simon Wright

unread,
Feb 28, 2012, 1:14:34 PM2/28/12
to
"Yannick Duchêne (Hibou57)" <yannick...@yahoo.fr> writes:

> Le Mon, 27 Feb 2012 14:41:10 +0100, Peter C. Chapin
> <PCh...@vtc.vsc.edu> a écrit:
>
>> On 2012-02-26 17:18, Greg Moncreaff wrote:
>>
>>> Look for something called an 'aggregate' project.
>>>
>>> http://www.adacore.com/wp-content/files/auto_update/gnat-unw-docs/html/gnat_ugn_12.html#SEC152
>>
>> That's interesting. I didn't realize there were such projects. I'm
>> not sure if it applies to my case though since two of my existing
>> projects are not libraries but contains main procedures. Maybe it
>> would work anyway.
>>
>> Peter
> Seems GNAT Pro specific, I can't retrieve the same from the FSF GNAT
> User's Guide.

There is the 4.6.0 reference[1] which seems to imply that the syntax is
accepted but has no effect, and the gprbuild reference[2].

gnatmake 4.6.0 does indeed fail to process an aggregate gpr.

gprbuild GPL 2011 succeeds (modulo some strange behaviour about library
names vs project names which I think I may have introduced when I
rebuilt gprbuild vs GCC 4.6.0???).

[1] http://gcc.gnu.org/onlinedocs/gcc-4.6.0/gnat_ugn_unw/Qualified-Projects.html#Qualified-Projects
[2] http://www.adacore.com/wp-content/files/auto_update/gprbuild-docs/html/gprbuild_ug.html#Project-Declaration

Peter C. Chapin

unread,
Feb 28, 2012, 7:04:21 PM2/28/12
to
On 2012-02-28 01:56, Phil Thornley wrote:

> Try adding:
>
> package Ide is
> for Default_Switches ("examiner")
> use ("-index_file=<path to project folder>lib.idx");
> end Ide;
>
> to main.gpr. This should override the index file defined in lib.gpr.

That doesn't seem to work. Although the new switches are used for files
in the main project, when I try to examine a file in the subproject it
still uses the switches as defined by that subproject's *.gpr file
(which contain incorrect paths relative to the main project's root).

Peter

Phil Thornley

unread,
Feb 29, 2012, 4:18:50 AM2/29/12
to
In article <sOydnQ2Dss0...@giganews.com>, PCh...@vtc.vsc.edu
says...
>
> On 2012-02-28 01:56, Phil Thornley wrote:
>
> > Try adding:
> >
> > package Ide is
> > for Default_Switches ("examiner")
> > use ("-index_file=<path to project folder>lib.idx");
> > end Ide;
> >
> > to main.gpr. This should override the index file defined in lib.gpr.
>
> That doesn't seem to work.

OK then, time to try something completely different. There's a facility
in the Examiner for a switch file containing the default switch settings
that will be used if they are not specified in the command line. The
file must be called spark.sw and is only read if it is in the current
working directory.
(It is described in Section 3.2 of the Examiner User Manual.)

So create a spark.sw file in the various working directories
(presumeably the same ones as the GPS project files) with at least the
index_file option specified appropriately and do not specify the index
file in the GPS project file.

Then just make sure that the "Ignore spark.sw" checkbox (on the Examiner
switches tab of GPS) is not checked and that should do it.

Cheers,

Phil

Peter C. Chapin

unread,
Feb 29, 2012, 9:51:51 AM2/29/12
to
On 2012-02-29 04:18, Phil Thornley wrote:

> So create a spark.sw file in the various working directories
> (presumably the same ones as the GPS project files) with at least the
> index_file option specified appropriately and do not specify the index
> file in the GPS project file.

Alas this doesn't work for me either. My problem is that I want to
support both Linux and Windows development. It turns out I can use
forward slashes on the Examiner command line as a path delimiter for
either system. Thus

spark -index_file=src/spark.idx

Works as desired on both Windows and Linux platforms. However, when I
put the following into my spark.sw file

-index_file=src/spark.idx

It works fine under Linux but on Windows I'm told "spark.idx is an
invalid command line option." Apparently the parsing of these options is
not identical between the spark.sw file and the actual command line. I
can use

-index_file=src\spark.idx

on Windows but, of course, that won't work on Linux. Furthermore I have
to use the same spark.sw file on both systems (right?). I tried
enclosing the value of the switch in quotation marks

-index_file="src/spark.idx"

but this produced the same result.

I have a feeling that the right answer is for GPS to change to the
subproject's home directory when issuing the SPARK commands for that
project. Maybe this is a "bug" in the SPARK/GPS plugin.

Peter

Phil Thornley

unread,
Feb 29, 2012, 11:49:22 AM2/29/12
to
In article <C-KdnSPM0sw...@giganews.com>, PCh...@vtc.vsc.edu
says...
>
> On 2012-02-29 04:18, Phil Thornley wrote:
>
> > So create a spark.sw file in the various working directories
> > (presumably the same ones as the GPS project files) with at least the
> > index_file option specified appropriately and do not specify the index
> > file in the GPS project file.
>
> Alas this doesn't work for me either. My problem is that I want to
> support both Linux and Windows development.

I think we've reached the end of the line now.

The problem probably arises because the Windows version of the Examiner
used to use '/' as the marker for each command qualifier. This has now
been changed to '-' in line with the Unix version.

I would encourage you to report the different behaviour of the '/' in
the command-line and spark.sw versions as this looks like a bit of the
Examiner that hasn't been correctly upgraded for that change.
It would explain why
-index_file=src/spark.idx
results in "spark.idx is an invalid command line option." on Windows

Cheers,

Phil

Peter C. Chapin

unread,
Feb 29, 2012, 12:17:58 PM2/29/12
to
On 2012-02-29 11:49, Phil Thornley wrote:

> The problem probably arises because the Windows version of the Examiner
> used to use '/' as the marker for each command qualifier. This has now
> been changed to '-' in line with the Unix version.
>
> I would encourage you to report the different behaviour of the '/' in
> the command-line and spark.sw versions as this looks like a bit of the
> Examiner that hasn't been correctly upgraded for that change.
> It would explain why
> -index_file=src/spark.idx
> results in "spark.idx is an invalid command line option." on Windows

I actually I spoke too soon. A command line such as

spark -index_file=src/spark.idx ...

doesn't work (on Windows) either. So in fact the command line behavior
and the spark.sw behavior is consistent after all. On the other hand,
this might not be intended behavior with respect to path delimiters.

I could work around this with GPS by using scenario variables... using
different path delimiters depending on the development platform.
Unfortunately the direction of project overrides is wrong: the
subproject's settings overrides the master project's settings (which
generally makes sense to me).

Reporting an issue on SPARK is reasonable but I still think the
fundamental problem is with GPS. When I have a master project loaded, it
lets the subproject's settings override the master settings but when I
invoke a command on the subproject it doesn't set up the subproject
environment properly (working folder in this case). GPS is overriding
master settings without overriding the master environment. That sounds
like the root cause of my difficulties.

Peter
0 new messages