Reputation: 300
I would like to use types and services from a package which is located in a static library.
So, in my body main.adb, I put a
with Services.A;
Service.A is located in an external lib (services.a), so I need to link the lib after the compilation process.
I added the flags -L/path/of/dir/containing/my/lib
and -lservices
But because of the declaration of types is inside of lib and the compilator needs the symbols, I have to include the specs (.ads) from services.ads.
I saw multiple ways to do this, but nothings works on my project.
I tried to add the flags -I/path/to/ads
but without success.
If I add in my gpr file the specs to the Sources_Dirs, it tells me that the unit "Services.A" cannot belongs to several projects.
Is there any official ways to include the specs like a header in C from an external static library in ada ?
Upvotes: 0
Views: 1374
Reputation: 3341
Here is some stuff for you to start. I hope it can put you in a good direction.
When you use a library into a GPR, I know of 3 cases. Keep in mind that this is not a complete answer, more cases surely exist and I may forget some things. The topic is subject to pitfalls, so you should dig more into the interwebs, AdaCore/GNAT documentation and stackoverflow, since the topic is often raised. Some of the said pitfalls might not be covered here depending on the type of libs you have/produce, and some specific compile/build/link options.
Foreword: when you include a static library, its sole file name does not tell you anything useful to invoke the code it contains. So the if the static lib is 'serivices.a', it is just a file name and extension. with Services.A
won't be sufficient to invoke the code.
Case 1
You have access to the GPR my_lib.gpr
that produces the library and it is written in Ada.
Simply include the GPR, and in your code you'll only be allowed to with
the exposed interfaces. (it corresponds to Simon Wright comment about the with "services.gpr";
in your GPR)
my_lib.gpr
produces a static lib, nothing to do more ! GPR does what is necessary for you (build/link).Case 2
You have access to the GPR my_lib.gpr
that produces the library and it is written in another language.
my_lib_install.gpr
that contains the library interface declarations (.ads
files). If the files do not existe, see Case 3..ads
files in your code. The .ads
usually contains pragma Import(...)
convention declaration. They are defined once, so no unit "Services.A" cannot belongs to several projects
error message.Or you could directly include the library interface declarations (.ads
files) into your project.
my_lib.gpr
produces a static lib, you should include the appropriate link directives to use the .a file.Case 3
The library my_lib
is a COTS and it is written in another language.
It should be delivered with interface definition.
The usual method is to write a .ads
file(s) corresponding to the provided contract definition. The types and methods should be flagged with some pragma Import(...)
convention corresponding to the way the library was built (Ada convention, C convention, see ARM or this wiki)
Usually a the interface contract is a .h
file (most libraries are produced with C convention). So you can use Ada's Interfaces.c
packages which are designed for that. An example of interfacing with C is given in this example of interfacing Ada with Java via C convention). The main difference is you will ahve to pragma Import
instead of pragma Export
This should anwser to:
Is there any official ways to include the specs like a header in C from an external static library in ada ?
You can either directly include this .ads
file(s) into your sources, or write your own GPR to do that hosting as indicated in the beginning. It is up to you.
Final word, if your library is coded in the Ada language, you might have a look at the documentation concerning elaboration, 'initialize' and 'finalize' symbols.
Upvotes: 1