[CMake] Reverse dependencies (Unix Makefiles)

Michael Hertling mhertling at online.de
Mon May 24 09:40:35 EDT 2010


On 05/24/2010 11:20 AM, Jesper Eskilson wrote:
> Hi,
> 
> I have two targets, call them A and B. They both link with a third, 
> static library called C. C attempts to invoke a function which is 
> defined by however links with C, i.e. either A or B.
> 
> This is not a problem as long as A and B are executables or shared 
> libraries, but if A or B is a static library which in turn is linked 
> into a shared object or executable (call it D), then the command becomes 
> something like
> 
>      cc ... -o libD.so -lA -lC
> 
> since the method C calls in A is unknown by the linker when A is 
> processed, it is discarded. Instead, I would need the command line to 
> look like this:
> 
>      cc ... -o libD.so -lA -lC -lA
> 
> but how can I do this without explicitly causing A to depend on C?

According to your first paragraph, A does depend on C; what you're
asking for is a, say, optional dependency of C on A, right? How do
you decide whether to use A or B? If this is known at CMake time:

TARGET_LINK_LIBRARIES(A C)
TARGET_LINK_LIBRARIES(C A)
TARGET_LINK_LIBRARIES(D A)

should do the job for A, and

TARGET_LINK_LIBRARIES(B C)
TARGET_LINK_LIBRARIES(C B)
TARGET_LINK_LIBRARIES(D B)

does it for B, alternatively, since TARGET_LINK_LIBRARIES() attends to
circular dependencies w.r.t. static libraries, see its documentation.
Furthermore, I suppose you can't use A and B together due to equally
named symbols defined in both of them, in fact the ones called by C.

In the last resort, the GNU linker provides options "--start-group" and
"--end-group", or the short ones "-(" and "-)", respectively, meant to
resolve circular dependencies among static libraries, but I don't know
if one can have CMake intersperse these options in the link line or if
this would be portable regarding the various supported platforms.

Perhaps, if possible, you should consider to reorganize your project in
order to avoid circular dependencies at all, e.g.: Take those parts of
A and B that C refers to and turn them into separate libraries A0 and
B0. This results in A, B and C depend on A0 and/or B0, and the link
line for libD.so would be:

"cc ... -o libD.so -lA -lC -lA0" or "cc ... -o libD.so -lB -lC -lB0"

Thus, the circular dependencies are gone.

Regards,

Michael


More information about the CMake mailing list