On 23. Dec, 2009, at 15:14 , Marcel Loose wrote:
> On Wed, 2009-12-23 at 14:12 +0100, Michael Wild wrote:
>> On 23. Dec, 2009, at 13:28 , Marcel Loose wrote:
>>
>>> On Wed, 2009-12-23 at 13:09 +0100, Michael Wild wrote:
>>>> On 23. Dec, 2009, at 12:08 , Marcel Loose wrote:
>>>>
>>>>> Hi all,
>>>>>
>>>>> I suggested this in the quite long thread "third party library
>>>>> dependencies", but it may have been overlooked. Hence, I started a new
>>>>> thread.
>>>>>
>>>>> Upon (re)reading the Mandriva page
>>>>> http://wiki.mandriva.com/en/Overlinking, I was thinking: maybe the issue
>>>>> of overlinking can be solved more or less the same way as pkg-config
>>>>> does: i.e. by defining private dependencies. This could be an extra
>>>>> option to target_link_libraries.
>>>>> Something like:
>>>>>
>>>>> target_link_libraries(mylib public1 public2 PRIVATE private1 private2)
>>>>>
>>>>> This would tell CMake that mylib directly depends on public1 and public2
>>>>> and should only link in these two libraries when these are shared
>>>>> object libraries; otherwise private1 and private2 would also need to be
>>>>> added on the link line.
>>>>>
>>>>> The big hurdle to take, of course, is to detect in a
>>>>> platform-independent way whether the given library is shared or static.
>>>>> However, a lot of this knowledge is already available in the diverse
>>>>> Modules/Platform macros, so my feeling is that this should be feasible.
>>>>>
>>>>> Best regards,
>>>>> Marcel Loose.
>>>>>
>>>>
>>>> You would also need a PUBLIC keyword, and then require that all
>>>> FindXXX.cmake modules prefix their libraries with PUBLIC and PRIVATE. If
>>>> only the PRIVATE libraries where prefixed, the following would not work if
>>>> A_LIBRARIES contains PRIVATE:
>>>>
>>>> find_package(A)
>>>> find_package(B)
>>>> add_library(C source.c)
>>>> target_link_libraries(C ${A_LIBRARIES} ${B_LIBRARIES})
>>>>
>>>> Because then all the B_LIBRARIES would be considered to be private
>>>> "details" of the public A_LIBRARIES... Also, there's no way to tell CMake
>>>> which of the private libraries belongs to which of the public libraries.
>>>>
>>>> I think it would be better if a FindXXX.cmake module marked the private
>>>> libraries as a property of the public libraries and then let CMake take it
>>>> from there (although as of now I wouldn't know on what to set the
>>>> property, except if the module created an IMPORTED target for each of the
>>>> public libraries, but that bears the possibility of target name collisions
>>>> with the importing project).
>>>>
>>>> Michael
>>>
>>> Hi Michael,
>>>
>>> I don't think you'll need to prefix the library names with either
>>> PRIVATE_ or PUBLIC_. CMake could figure out whether "public1" and
>>> "public2" are shared or static libraries. If they are shared libraries,
>>> then the libraries marked as private ("private1" and "private2") do not
>>> have to be linked in as well. Otherwise they must also be linked in. I
>>> assume that CMake keeps a list internally, of all dependent targets; the
>>> private libs should only be added to that internal list if the public
>>> libs are static libs.
>>>
>>> I don't completely understand your example. Are you suggesting that
>>> you'll run into trouble if you have a library named "PRIVATE"? I think
>>> name clashes will currently occur as well if I name my library "debug",
>>> "optimized", or "general".
>>>
>>> Maybe, it would be better if the FindXXX modules would handle this. On
>>> the other hand, you then depend on third parties to properly update
>>> their FindXXX modules, or have to rewrite them yourselves :-(
>>>
>>> Best regards,
>>> Marcel Loose.
>>>
>>
>>
>> No, it won't work. For example, if FindA.cmake does
>>
>> set(A_LIBRARIES /some/path/libA.so
>> PRIVATE /some/other/path/libX.a /some/other/path/libY.a)
>>
>> and FindB.cmake contains
>>
>> # notice that this is a static library!
>> set(B_LIBRARIES /some/path/libB.a)
>>
>>
>> then the call
>>
>> target_link_libraries(C ${A_LIBRARIES} ${B_LIBRARIES})
>>
>> expands to (wrapped for legibility
>>
>> target_link_libraries(C
>> /some/path/libA.so
>> PRIVATE /some/other/path/libX.a
>> /some/other/path/libY.a
>> /some/path/libB.a)
>>
>> which is different in meaning from
>>
>> target_link_libraries(C ${B_LIBRARIES} ${A_LIBRARIES})
>>
>> which becomes
>>
>> target_link_libraries(C
>> /some/path/libB.a
>> /some/path/libA.so
>> PRIVATE
>> /some/other/path/libX.a
>> /some/other/path/libY.a)
>>
>> In the first case libB.a becomes marked as PRIVATE of libA.so! Not very nice
>> if you ask me ;-)
>>
>> Michael
>
> Hi Michael,
>
> I never suggested that A_LIBRARIES should be set to contain "PRIVATE". I
> suggested to add a keyword "PRIVATE" to the target_link_libraries
> command.
>
Ok, but then how does FindA.cmake communicate that libA.a needs some private
libraries? Does the user then have to do
target_link_libraries(C ${A_LIBRARIES} ${B_LIBRARIES}
PRIVATE ${A_PRIVATE_LIBRARIES} ${B_PRIVATE_LIBRARIES})
How, then, does CMake know that it should link ${B_PRIVATE_LIBRARIES} but NOT
${A_PRIVATE_LIBRARIES} if ${A_LIBRARIES} is a shared library and ${B_LIBRARIES}
is a static library?
Michael
_______________________________________________
Powered by www.kitware.com
Visit other Kitware open-source projects at
http://www.kitware.com/opensource/opensource.html
Please keep messages on-topic and check the CMake FAQ at:
http://www.cmake.org/Wiki/CMake_FAQ
Follow this link to subscribe/unsubscribe:
http://www.cmake.org/mailman/listinfo/cmake