At this point of the discussion, I think that we need someone else to join. We both have made strong points for our viewpoints, and neither of us has a "perfect" solution.
On Sunday 05 December 2010 12:48:49 Michael Hertling wrote: > On 12/01/2010 05:57 PM, Johannes Zarl wrote: > > On 12/01/2010 at 16:06, Michael Hertling <mhertling at online.de> wrote: > > These variables are well-known and officially recommended for > > component- less packages only. Nobody bothered to write > > recommendations for component-packages yet. > > ${CMAKE_ROOT}/Modules/readme.txt mentions the XXX_YYY_EXECUTABLE and > XXX_YY_{LIBRARY,INCLUDE_DIR} variables explicitly, and IMO, wordings > as "YYY tool that comes with XXX" or "YY library that is part of the > XXX system" allow the general terms "tool" and "part" to be applied > smoothly to the components of a package. Furthermore, the component- > specific variables like XXX_FIND_COMPONENTS are handled also, so I > do believe that this file is relevant for multi-component packages, > too, including the XXX_{LIBRARIES,INCLUDE_DIRS} variables. However, > variables like XXX_YYY_{LIBRARIES,INCLUDE_DIRS} are not mentioned > at all, i.e. there're completely new and should be well founded. IMO the wording is ambiguous. When I read it, it was obvious to me that the XXX_YYY_LIBRARIES etc. are to be defined. To quote readme.txt: > XXX_EXECUTABLE Where to find the XXX tool. > XXX_YYY_EXECUTABLE Where to find the YYY tool that comes with XXX. I assumed XXX_YYY_EXECUTABLE as an example, so that not every variable has to be mentioned a second time in its component-specific form. Now that I heard your interpretation and reread readme.txt, it fits the description just as well. > Anyway, the ${CMAKE_ROOT}/Modules/readme.txt doesn't handle multi- > component packages thouroughly, so I would greatly appreciate any > improvements to decrease ambiguities/uncertainties and to reach a > consensus. For this reason, I regret that we haven't seen further > opinions on this topic, in particular because pretty much every > non-trivial package could make good use of a components-aware > find module or config file. As I have written above, I totally agree. > > The problem is that FPHSA simply wasn't created with components in > > mind. As worthwhile as code-reuse is, it's not a goal in itself. > > Rather than jump through hoops in order to reuse the existing > > interface, IMO one should create a good interface for the more > > complex use-case at hand. > > To apply FPHSA to a component and, thus, re-use existing code, I just > need to define two variables; this is not "jumping through hoops". Setting a specific variable for its side-effects before calling a function makes a truly bad interface-style for me. Regardless of the outcome of this discussion, I'll create a patch for the FPHSA module introducing the component-keyword (once, I have time, whenever that is; a totally different topic is whether the patch will be included to cmake). > Suppose you have components YYY and ZZZ with ZZZ depending on YYY. > When handling ZZZ in the find module, there's a certain probability > that you must access the YYY stuff, so one would like to have the > XXX_YYY_FOUND variable already defined at this time. This is a sensible assumption, and should be supported by a component- aware FPHSA... > With the > FPCHSA, the components' FOUND variables are defined in one go at the > module's end; hence, one has to check YYY's availability by oneself > when it's needed for ZZZ, and FPCHSA will do the same work once more > later. Well, there currently does not exist a single line of code for a component-aware FPHSA. If it were to be implemented like this, There wouldn't be much incentive to use it. > Instead, IMO, it's convenient to check a component's presence > right after the relevant variables have received their values, and > for this purpose, FPHSA is entirely sufficient. Apart from the whole defining-variables-for-side-effect thing, yes. Still this would benefit from component-awareness: ... FPHSA(XXX XXX_LIBRARIES XXX_INCLUDE_DIRS) #detect component YYY FPHSA(XXX COMPONENT YYY XXX_YYY_FOO XXX_YYY_BAR) ... > > find_package( XXX COMPONENTS YYY) > > target_link_libraries(foo ${YYY_LIBRARIES}) > > find_package( XXX COMPONENTS ZZZ) > > target_link_libraries(bar ${ZZZ_LIBRARIES}) > > > > At this point, I just realised that I was being inconsistent. After > > all, the components do depend on the whole package. So > > YYY_LIBRARIES should also contain XXX_LIBRARIES. > > If I understand correctly, you intend to populate XXX_YYY_LIBRARIES, > e.g., with its own value XXX_YYY_LIBRARY *and all* its prerequisite > components' values, too? If so, you will end up with many repeatedly > mentioned libraries on the link command line unless there're hardly > any inter-component dependencies. Suppose ZZZ depends on YYY, so > I have to admit that I didn't encounter a use-case with inter-component dependencies before this discussion, so my thoughts on this might be called "developing". Still, you misquoted me there: My current use case (and the use case I used at the beginning of this discussion) assumes multiple components, but no dependencies. Thus the example: > FIND_PACKAGE(XXX COMPONENTS YYY ZZZ) > ... > TARGET_LINK_LINK_LIBRARIES(... > ${XXX_LIBRARIES} ${XXX_YYY_LIBRARIES} ${XXX_ZZZ_LIBRARIES} > ) does not repeat anything in my original use case. When you brought up dependencies, I tried to adopt my approach, which eventually ended up with the following link-line for the above example: TARGET_LINK_LINK_LIBRARIES(... ${XXX_ZZZ_LIBRARIES}) So again, no duplicates. However, my approach still was shortsighted: If you have a target depend on two components which are not dependent upon each other, but in turn depend on (some of) the same components. You actually do end up with duplicates in your link-lines. A bad situation, but not as bad as your O(n^2) assumption -- the duplicated entries grow linearly. Unless you really have packages with a lot of components with many inter-component dependencies, I doubt this will become perceptible even for a large project. > In general, from a user's perspective, I don't want to wonder if ZZZ > depends on YYY so I could possibly drop the latter from the list of > components although I need to use it. Furthermore, while the effect > of unnecessarily mentioned libraries during link phases is mostly > negligible, I'd bear it in mind. Finally, overlinking due to any > overstuffed XXX_LIBRARIES variable can be easily avoided by an > additional FIND_PACKAGE() call which is cheap to have. So, basically the user doesn't want to wonder whether some component can be dropped or not, and when writing programs the user is already aware of dependencies. That brings us back to my original use case without dependencies-support. The user just adds all components that are needed, and XXX*LIBRARIES contains exactly the correct entries. I'll come back to the overlinking issue later on... > In order not to be misunderstood: I see your intention, and I see the > advantages you want to achieve, but I think the disadvantages > prevail: > > - More work for the user due to component-specific sets of variables. Yes, that's the price of my approach. > - Unnecessary repetition of libraries on the link command line. My original approach doesn't have this problem, as dependencies are not handled. > - Inconvenient centralization of the FOUND variables' setup. That's not true. First of all, the side-discussion about FPHSA is valid for both your and my approach. Secondly, as I outlined above, you can have a better FPHSA that is component-aware and still use it exactly like you do in your approach. > In addition, when looking at FPHSA's current implementation, I've > doubts whether a component-related extension should be added to this > somewhat non-trivial function, in particular since it's already > applicable to components, but of course, feel free to specify and > implement an improved version and bring it up for discussion. As written above, I'll do that ;-) One thing important to me slipped through in this discussion: component- aware XXXConfig.cmake packages. I bring them up again, because they are to be functionally equivalent to the FindXXX.cmake modules. Config-mode packages differ substantially to modules in what is possible to do with them: In a config-mode script you can not make any assumption about the cmake version in use, or which other packages are available. This means, that if you need to do any sort of processing to your variables, you essentially have to include your code in each XXXConfig.cmake script. If you move the responsibility for merging all relevant variables into the find_package call, you end up with massive code-duplication inside the config-mode scripts. Let's make a clear cut here, and summarise both of our viewpoints and their advantages. That should make it easier for someone else to join the discussion. Also I'd like to stick to the "big-picture" and not get tangled too much in technicalities. Viewpoint: Johannes' position Use case: - Multi-component packages, little or no inter-component dependencies - Only explicit inter-component dependencies, known to the user - multiple targets inside one list file linking against different libraries/components. Advantages: - Only explicit behaviour (value of XXX_LIBRARIES etc. is not context-sensitive). - XXXConfig.cmake files don't need to do any computations. - No overlinking possible. - No need to backup any variables. Example (normal case): FIND_PACKAGE(XXX COMPONENTS YYY ZZZ) TARGET_LINK_LIBRARIES(... ${XXX_LIBRARIES} ${XXX_YYY_LIBRARIES}) TARGET_LINK_LIBRARIES(... ${XXX_LIBRARIES} ${XXX_ZZZ_LIBRARIES}) Example (worst case): FIND_PACKAGE(XXX COMPONENTS YYY ZZZ AAA BBB) TARGET_LINK_LIBRARIES(... ${XXX_LIBRARIES} ${XXX_YYY_LIBRARIES} ${XXX_AAA_LIBRARIES} ${XXX_AAA_LIBRARIES}) Viewpoint: Michaels position Use case: - Multi-component packages, complicate inter-component dependencies - Implicit inter-component dependencies, maybe unknown to the user - Mostly just one target per file Advantages: - User only needs to know leaves of dependency tree. - Normally short notation, user can write compact list files. Example (normal case): FIND_PACKAGE(XXX COMPONENTS YYY ZZZ) TARGET_LINK_LIBRARIES(... ${XXX_LIBRARIES} Example (worst case): FIND_PACKAGE(XXX COMPONENTS YYY ) SET(TARGET_A_LIBRARIES ${XXX_LIBRARIES}) TARGET_LINK_LIBRARIES(... ${TARGET_A_LIBRARIES}) FIND_PACKAGE(XXX COMPONENTS ZZZ ) SET(TARGET_B_LIBRARIES ${XXX_LIBRARIES}) TARGET_LINK_LIBRARIES(... ${TARGET_B_LIBRARIES}) Currently, I'm tired, so I'm sure there are advantages that I didn't mention. Please add them! > Regards, > > Michael > > PS: Could you prevent your signature from sometimes appearing midway > through your posts? This confuses my mail client when replying. Sorry! A quotation-level >= 4 (more concisely, a line beginning with ">>>>") confuses my mail-client at work. I'll try to keep an eye on this in the future... _______________________________________________ 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