LnlB
LnlB

Reputation: 300

Use package from a static library in ada

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

Answers (1)

LoneWanderer
LoneWanderer

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)

  • if the my_lib.gpr produces a static lib, nothing to do more ! GPR does what is necessary for you (build/link).
  • if the lib is dynamic (dll), then the dll need to be found at execution time in the OS search path (next to executable, or in path environment variable)

Case 2

You have access to the GPR my_lib.gpr that produces the library and it is written in another language.

  • build the library
  • define another GPR my_lib_install.gpr that contains the library interface declarations (.ads files). If the files do not existe, see Case 3.
  • reference that GPR into your own GPR project
  • you can now use the methods/types defined in the .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.

  • if the my_lib.gpr produces a static lib, you should include the appropriate link directives to use the .a file.
  • if the lib is dynamic (dll), then the dll need to be found at execution time in the OS search path (next to executable, or in path environment variable)

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

Related Questions