[CMake] Apply FIND_PACKAGE_HANDLE_STANDARD_ARGS() on COMPONENTS

Michael Hertling mhertling at online.de
Sat Apr 24 03:47:19 EDT 2010


On 04/22/2010 02:04 PM, Michael Wild wrote:
> 
> On 22. Apr, 2010, at 13:50 , S Roderick wrote:
> 
>> On Apr 22, 2010, at 06:21 , Michael Hertling wrote:
>>
>>> On 04/21/2010 09:29 PM, S Roderick wrote:
>>>> On Apr 21, 2010, at 15:13 , Alexander Neundorf wrote:
>>>>
>>>>> On Tuesday 20 April 2010, Michael Hertling wrote:
>>>>>> Dear CMake community, dear CMake developers,
>>>>>>
>>>>> ...
>>>>>> There's another aspect related to this I'd like to comment on: During
>>>>>> the abovementioned considerations on the bug tracker and the mailing
>>>>>> list, the question has arisen if it's reasonable to set XXX_FOUND to
>>>>>> FALSE if any of the requested components aren't found. As for myself,
>>>>>> I'd say: No, it isn't. Let's have a look at the following scenario:
>>>>>>
>>>>>> Package XXX normally provides components YY1 and YY2, but for some
>>>>>> reason, only YY1 is installed. Moreover, XXX provides a config file
>>>>>> XXXConfig.cmake. Now, a project's CMake script requests both YY1/2 by
>>>>>> FIND_PACKAGE(XXX COMPONENTS YY1 YY2). As Brad King has pointed out in
>>>>>> <http://www.mail-archive.com/cmake@cmake.org/msg15952.html>, finding a
>>>>>> config file results in XXX_FOUND to be set to TRUE automatically. Thus,
>>>>>> the absence of YY2 does not mean the absence of XXX as a whole in any
>>>>>> case, and, notwithstanding, the requesting CMake script should have a
>>>>>> chance to proceed even if YY2 isn't available, i.e. the following seems
>>>>>> reasonable: XXX_YY1_FOUND=TRUE, XXX_YY2_FOUND=FALSE *but* XXX_FOUND=TRUE.
>>>>>
>>>>> I think I don't agree here.
>>>>> If I say
>>>>> find_package(XXX COMPONENTS YY1 YY2 REQUIRED)
>>>>> I think it makes a lot of sense to interpret this as "search package XXX, and 
>>>>> I need YY1 and YY2 from it".
>>>>> What other reason would I have to give YY1 and YY2 there otherwise ?
>>>>> If it still succeeds if they are not found, why should I list them then ?
>>>>
>>>>
>>>> +1
>>>>
>>>> find_package(XXX COMPONENTS YY1 YY2 REQUIRED)
>>>>
>>>> means to me, I _require_ both YY1 and YY2 from XXX. Any other YYx I don't care about.
>>>
>>> Yes, of course, the REQUIRED option is definitive; it's
>>> COMPONENTS without REQUIRED which raises the questions.
>>>
>>>> The first version above translates to me to be
>>>>
>>>> find_package(XXX COMPONENTS YY1 REQUIRED)
>>>>
>>>> I only _require_ YY1.
>>>
>>> As I have replied recently to AN, I sometimes dislike FIND_PACKAGE() to
>>> look for unrequested components, so I need to request them even if they
>>> are optional, but this is just my personal preference and, also, not my
>>> concern here.
>>>
>>> My concern is that FIND_PACKAGE(XXX COMPONENTS YY) will always return
>>> XXX_FOUND=TRUE if it's driven by XXXConfig.cmake, regardless if YY is
>>> found or not, while the same command could return XXX_FOUND=FALSE if
>>> driven by FindXXX.cmake since the latter has XXX_FOUND in its hands.
>>> Thus, IMHO, it should be reconsidered how XXX_FOUND is interpreted
>>> w.r.t. components because I would expect both variants - XXXConfig
>>> and FindXXX - to behave the same.
>>
>> That seems to make sense. YY isn't listed as required, therefore it is optional. Having XXX_FOUND=TRUE seems reasonable if CMake found some portion of XXX, regardless of whether it did, or did not, find YY. If we required YY, then we should have added REQUIRED.
>>
>> Now the fact that COMPONENTS and REQUIRED are mutually exclusive is not right IMHO. I'd love to hear Kitware's take on why it was done this way.
>> Stephen
> 
> I haven't tried it out, but as I read the synopsis of find_package, they are not mutually exclusive. Rather, COMPONENTS is implied if any components are listed after REQUIRED:

Yes, this applies better, I think. Possibly, COMPONENTS arises from a
syntactical need: You can't say, e.g., FIND_PACKAGE(Qt4 QtCore QtXml),
but you must have a keyword to introduce the list of components; else,
FIND_PACKAGE() gets confused. Thus, if you don't want to say REQUIRED
you have to say something different.

> # optionally finds component YY of package XX
> find_package(XXX COMPONENTS YY)
> 
> # requires that component YY of package XX is found
> find_package(XXX REQUIRED YY)

As far as I've observed, you can use options like QUIET or REQUIRED to
mark the end of the components' list; indeed, the following syntax is
widely-used: FIND_PACKAGE(Qt4 COMPONENTS QtCore QtGui QtXml REQUIRED),
although this can hardly be seen from FIND_PACKAGES()'s specification,
IMHO, and hopefully, no one will ever have a package with a component
named "QUIET", "REQUIRED" or "NO_POLICY_SCOPE"... ;)

Best regards,

Michael


More information about the CMake mailing list