Stuart Buckingham
Stuart Buckingham

Reputation: 1774

-fPIC error when linking static and dynamic libs with GCC

I have written a small code that I want to compile with a combination of static and dynamic libs. The code uses functions from hdf5 and exodusII (a specialist CAE lib) as well as math, and of course good-old stdio.

To make the binary highly portable, I wanted to link hdf5 and exodusII statically into the code, but leave math and libc as shared, so that the code is optimised on different platforms.

I cannot work out what the correct method is to compile something like this. I already have tried:

gcc -lm -lc -fPIC test1.c /usr/lib/libexodus.a /usr/lib/libhdf5.a -Wl,-pie

This gives the error:

/usr/lib64/crt1.o: relocation R_X86_64_32S against '__libc_csu_fini' can not be used when making a shared object; recompile with -fPIC
/usr/lib64/crt1.o: could not read symbols: Bad value

I have also tried:

gcc -c test1.c (WORKS!)
ld /usr/lib/libhdf5.a /usr/lib/libexodus.a -lm -lc test1.o

Which gives a warning of not being able to find an entry symbol _start followed by a whole lot of undefined reference errors to the libexodus functions in test1.c. (I have checked libexodus.a with nm, and the functions being reported do actually exist in the archive.

I would really appreciate a hand in this. I am not overly experienced in using static libs, but for this application, I think it is the best choice, so long as I can work out a reliable way of compiling and linking.

Upvotes: 0

Views: 1824

Answers (1)

Stuart Buckingham
Stuart Buckingham

Reputation: 1774

The error was in the linking order. I have now learned that the linking order works like babushka dolls where the library at the top of the dependency tree comes first, and the most general library comes last.

For future reference, in the end, the working build command was as follows:

gcc test1.c -lexodus -lnetcdf -lhdf5_hl -hdf5 -lcurl -ldl -lm

What I don't really understand is that when I had built the exodus library as a shared library, I only had to link against the shared library, and the dependency libraries (-lnetcdf -lhdf5_hl -lhdf5 -lcurl) were not specified; however, with the static compilation of the exact same library, I now need to link all the libraries explicitly.

If someone has an answer to this behaviour, it would be helpful for my understanding and very appreciated, but as I can continue coding with this current build method, it is not an urgent matter.

Upvotes: 1

Related Questions