[CMake] Reverse dependencies (Unix Makefiles)

Michael Hertling mhertling at online.de
Tue May 25 08:41:03 EDT 2010


On 05/25/2010 10:52 AM, Jesper Eskilson wrote:
> 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.

Therefrom, I'd draw the conclusion that A and B indeed can't be linked
in at the same time because they provide some identical symbols, namely
the functions called by C for identification. So, there must be a point
in time when you decide whether to link against A or against B, and if
this point is at CMake time you could utilize TARGET_LINK_LIBRARIES()
for resolving circular dependencies by itself in the above-mentioned
manner. That's why I asked how you decide whether to use A or B.

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

Exactly: The need for A's repetition in the link line is a sole affair
of A and C. Therefore, IMO, it should not be brought explicitly to D's
link line whereas an approach with two TARGET_LINK_LIBRARIES() for the
A'n'C circular dependency and one for D against A would express the
actual relations quite accurately.

Regards,

Michael


More information about the CMake mailing list