2
votes

I'm having some trouble building shared libraries from Ada packages without using GPR's.

I have a package, Numerics, in files "numerics.ads" and "numerics.adb". They have no dependencies. There is a small build script which does:

gnatmake -Os numerics.ad[bs] -cargs -fPIC
gcc -shared numerics.o -o libnumerics.so -Wl,-soname,libnumerics.so

The .so and .ali files are installed at /usr/lib, and the .ads file is installed at /usr/include.

gnatls -v outputs the following relevant parts:

Source Search Path:
    <Current_Directory>
    /usr/include
    /usr/lib/gcc/x86_64-unknown-linux-gnu/5.1.0/adainclude

Object Search Path:
    <Current_Directory>
    /usr/lib
    /usr/lib/gcc/x86_64-unknown-linux-gnu/5.1.0/adalib

So GNAT should have no problem finding the files.

Then, trying to compile a package that depends on Numerics:

gnatmake -O2 mathematics.ad[bs] -cargs -fPIC

outputs:

gcc -c -fPIC mathematics.adb
gcc -c -I./ -fPIC -I- /usr/include/numerics.ads
cannot generate code for file numerics.ads (package spec)
gnatmake: "/usr/include/numerics.ads" compilation error

This error has me thinking GNAT doesn't recognize the shared library, and is trying to rebuild Numerics.

I'd like to be building shared libraries, and only supply the spec for reference/documentation purposes.

edit: So, it looks like gprbuild does two things I'm not doing. The first, is also passing -lnumerics to the compiler. The second, which shouldn't matter since libnumerics.so is in a standard directory anyways, is -L«ProjectDirectory». GPRbuild is obviously not doing desired behavior either, even though it's building the dependent project. It should be using the installed library /usr/lib/libnumerics.so, but instead is using «path»/Numerics/build/libnumerics.so. Furthermore, after building Numerics with GPRbuild, and then renaming the body to make it as if the body didn't exist (like with the installed files), when building Mathematics with GPRbuild, it complains about the exact same problem. It's as if the libraries aren't even shared, and GPRBuild is just making them look that way (except readelf reports the correct dependencies inside the libraries).

Adding -lnumerics to the build script accomplishes nothing; the build error is exactly the same. I'm completely lost at this point.

edit: Following the link from Simon, the buildscript has changed to:

gnatmake -O2 mathematics.ad[bs] \
    -aI/usr/include \
    -aO/usr/lib \
    -cargs -fPIC \
    -largs -lnumerics

The error is essentially the same:

 gcc -c -O2 -I/usr/include/ -fPIC mathematics.adb
 gcc -c -I./ -O2 -I/usr/include/ -fPIC -I- /usr/include/numerics.ads
 cannot generate code for file numerics.ads (package spec)
 gnatmake: "/usr/include/numerics.ads" compilation error

I thought to check libnumerics.so is actually a correct shared library. ldd reports:

 linux-vdso.so.1 (0x00007ffd944c1000)
 libc.so.6 => /usr/lib/libc.so.6 (0x00007f50d3927000)
 /usr/lib64/ld-linux-x86-64.so.2 (0x00007f50d3ed4000)

So I'm thinking yes, the library is fine, and gnatmake still isn't recognizing it.

1
As GNAT is source based, you have to supply the specification files for any precompiled libraries you want to use.Jacob Sparre Andersen
What is the reason you don't want to use GPR files to manage the compilation and use of shared libraries? (Even if you don't want to use gprbuild in your distributed library, you could use it to figure out which flags are needed to get GNAT to solve the problem.)Jacob Sparre Andersen
@JacobSparreAndersen, yes, but the spec file is there and present like it should be. It's only the body that is missing, which is what's confusing me. I'll try setting up the GPR and comparing the flags from gprbuild to what I was doing.Patrick Kelly
@JacobSparreAndersen So... I'm totally lost. See the edits.Patrick Kelly
You might find this answer helpfulSimon Wright

1 Answers

4
votes

In general, you need to install the body of the packages as well (numerics.adb in your case). Also, I suspect you want to set the ALI files (numerics.ali) as read-only, so that gnatmake does not try to recompile them.