[CMake] Reverse dependencies (Unix Makefiles)

Jesper Eskilson jesper.eskilson at iar.se
Tue May 25 04:52:29 EDT 2010


On 05/24/2010 03:40 PM, Michael Hertling wrote:
> 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.

The functions in A or B called by C actually *idenfities* which of A or 
B that C is being linked into. Think of A and B as the compiler and the 
assembler which links with a utility library C which calls a method in 
either A or B which identifies which if the compiler and assembler the 
utility library is being used in.

> 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.

Yes, that would probably be nice, but it is unfortunately not an option 
at this time. Rewriting this is not an option due to the sheer size of 
the code base which would need refactoring.

I've solved this for now by doing

    target_link_libraries(D A C A)

which seems to work, although D needs to know that A has to be repeated 
in the libraries list.

--
/Jesper



More information about the CMake mailing list