On 23. Dec, 2009, at 16:04 , Marcel Loose wrote: > On Wed, 2009-12-23 at 15:19 +0100, Michael Wild wrote: >> 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 > > Hi Michael, > > I think that FindA.cmake should set A_LIBRARIES differently when libA is > static or shared. If libA is shared, then A_LIBRARIES only has to > contain the path to libA. If libA is static then FindA should list all > its dependent libraries in A_LIBRARIES too. It doesn't really matter if > these libs are private or not, because the user of libA will still have > to link against libA's private libs in that case. > > What I wanted to avoid is that, if I have another library, say D, that > depends on C, that D is only linked against C, and not A and B, if C is > a *shared* library. That's the message I was trying to convey with the > PRIVATE keyword. > > On the other hand, maybe Alex is right when he says that, what I > proposed as a new feature, can already be achieved using > LINK_INTERFACE_LIBRARIES. I'm not sure; it feels as if I'm entering > uncharted territory. I have to study this more carefully. > > Best regards, > Marcel Loose.
Ahh, now I understand. I'm sorry, I though you intended this to be used by FindXXX.cmake modules. Another thing that comes to mind: Setting up transitive link-dependencies in a FindXXX.cmake module might be a very difficult thing to do, since there are quite a few libraries which have varying dependencies, depending on platform and compile options... This is really a tough problem ;-) 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