Suppose I want to compile a.cpp and b.cpp into two separate shared libraries liba.so and libb.so and the two libraries are interdependent, how can I go about doing it?
问题:
回答1:
Although I can think of several hack-ish way to implement something like that, they all have their own disadvantages, and the whole issue is moot for the following reason.
Although you did not explicitly mention which platform you use -- and details of shared library implementation is highly platform specific, so that, in any case, the answer to this kind of a question is platform dependent -- given the names of the shared libraries that you mention in your question, "liba.so", and "libb.so", you are most likely using Linux.
Most current Linux distributions have configured their runtime loader so that the application can resolve external references only from shared libraries that the application explicitly links with. If your application links with liba.so, which links with libb.so, your application will not be able to resolve external references from libb.so, and vice versa.
Therefore, since your application will explicitly need to link with both shared libraries, this whole issue is moot. You might as well build both shared libraries individually, and explicitly link your applications with both of them. Otherwise, it won't work.
But if you really insist on hacking this up, this shouldn't be any more complicated then explicitly linking each library with the other. There's a matter of initial bootstrapping, which can be solved via dummy Makefile targets. Briefly, the Makefile
would probably read something like this:
liba.so: liba.so-target libb.so-target
[link command with -llibb.so]
libb.so: libb.so-target liba.so-target
[link command with -lliba.so]
liba.so-target: [all object modules that build liba.so]
[link command without -llibb.so]
touch liba.so-target
libb.so-target: [all object modules that build libb.so]
[link command without -lliba.so]
touch libb.so-target
So, at the end of the day, each one of the shared libraries first gets linked by itself, then relinked against the other library, with the other library's dependency also getting relinked, thanks to its dependency too.
This isn't 100% perfect, this approach might experience occasional issues with concurrent, parallel make builds, but this is the general idea. I still suggest that given the current configuration of Linux's runtime loader, your application will have to be explicitly linked with both libraries, making this whole thing completely unnecessary.