Reputation: 16391
I have a project that looks like this:
executable
\---> bsp.so
|---> bsp_protobuf.a
\---> protobuf.a
Where there are two static libraries that get build first (the two protobuf ones) that are statically linked into the bsp.so shared lib. And then finally bsp.so is linked into executable.
When I link executable and link bsp.so using gcc
on the command line it links ok.
However if I dont link bsp.so then it also builds fine - this is by design - because I want to use dlopen()
to determine if I need this library or not (I have pointers to the objects, but none that are instantiated etc...).
The problem I have is that when I use dlopen()
(in the code) it fails to open the library due to an undefined symbole. The symbol in question lives within the static librarys.
What I really struggle to understand is why it works on the command line but does not work when I use dlopen()
and runtime.
I have 3-4 other shared libs that I can successfully use dlopen()
on - so I know my general process for using dlopen()
is good.
I am using dlerror()
to get the undefined symbol error message out.
I have looked at the following links:
how-to-force-symbols-from-a-static-library-to-be-included-in-a-shared-library-bu
how-to-apply-fvisibility-option-to-symbols-in-static-libraries
I tied the -Wl,--whole-archive
idea, but that seemed to pull in too much and the build failed with soooo many warnings - probably somthing more to do with the google protobuf stuff, plus I am not sure that is the approach I want to end up with.
I checked that my shared lib was built with -fPIC
, I am not sure if the static libs are build with -fPIC
or if they need to be?
I also looked here:
which discusses how to link with dlopen()
but this is using libtools - we don't have that for all of our targets so I don't want to use libtools.
I am really not sure which way to progress - it feels like this should be a simple fix somewhere - but as I say, I can't get my head around why one method works and the other does not...
Update
So, after Sam's comment I started to look in the right place. It turns out the makefile for bsp.so statically links only one of the two libraries. There is a seperate tester for that shared lib that links both libraries (and so the tester works) and I had no reason to suspect that lib was broken... well, I learnt quite alot about dlopen and linking etc... :o
Upvotes: 0
Views: 1489
Reputation: 118425
When you link an executable with shared libraries, unresolved symbol references from the executable must be resolved by the shared libraries, otherwise the link fails.
When you link a shared library, it is not required that all of the unresolved symbol from the shared library itself must be resolved by any other shared library that it links with; therefore when you link together a shared library it's possible to wind up with unresolved symbols from the shared library itself.
Linking an executable with the shared library succeeds because all unresolved symbols in the executable get resolved by the shared library; but the executable will fail to load due to unresolved symbol references from the shared library itself. Alternatively, dlopen
()ing the shared library produces the same error.
The dlopen
manual page also describes several optional flags that can be used to control this behavior.
Upvotes: 1