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