[cmake-developers] How to handle package Config.cmake files with dependencies ?
Michael Hertling
mhertling at online.de
Wed Mar 7 10:22:49 EST 2012
On 02/27/2012 09:15 PM, Alexander Neundorf wrote:
> Hi,
>
> I think find_package in Config mode might still need some more work.
>
> When the FooConfig.cmake has been found, Foo_FOUND is set to TRUE:
>
> // Set a variable marking whether the package was found.
> std::string foundVar = this->Name;
> foundVar += "_FOUND";
>
>
> This means it is true in all cases that the Config.cmake file has been found
> (and the version was compatible).
>
> Now I have to questions:
>
>
> * how to handle COMPONENTS ?
>
>
> If a package is requested with COMPONENTS, these should be considered for
> setting Foo_FOUND:
> find_package(Foo REQUIRED COMPONENTS A B C)
> should only succeed if A, B and C are found.
>
> This is how I would expect COMPONENTS to be handled in a FindFoo.cmake:
> (a) all components are searched by the Find-module, and each per-component
> X_Y_FOUND is set accordingly
>
> (b) there is a package-specific default subset of these components which have
> to be found to make the package found, i.e. FOO_FOUND=TRUE
>
> (c) by adding COMPONENTS to the find_package() call, these components are
> added to the set of components which have to be found to make FOO_FOUND=TRUE
>
> (d) if REQUIRED is used and FOO_FOUND is false, it errors out
Sorry for chiming in so late, but I haven't got an answer on the
users' mailing list, so I retry here. Some objections and remarks:
(1) Foo might have a non-(de)selectable unnamed core component and
an ordinary selectable component X. FIND_PACKAGE(Foo COMPONENTS X)
returning Foo_FOUND==FALSE and Foo_X_FOUND!=TRUE does not allow to
determine if the core component is available. Potential candidates
for packages like that are Qt, GTK and - most notably - SDL.
(2) FIND_PACKAGE(Foo COMPONENTS ...) returns Foo_FOUND==FALSE if a
config file has not been found - crystal. Who sets the components'
FOUND variables in this case? FIND_PACKAGE() on its own behalf? If
so, note [1] and think of the same uncertainty w.r.t. components:
FIND_PACKAGE() on its own might return with Foo_bar_FOUND whereas
the config file sets Foo_Bar_FOUND. Leaving the components' FOUND
variables untouched? Note [2]. IMO, Brad is absolutely right *not*
to assume that Foo_FOUND was undefined before FIND_PACKAGE() ran.
So, concerning Foo_Bar_FOUND, one should also not rely on that
assumption, but your approach can't guarantee this, AFAICS.
(3) Suppose a component Y is added to Foo in a later release. Run
against such a release, FIND_PACKAGE(Foo COMPONENTS Y) is perfect,
but would face an older FooConfig.cmake with an unknown component
Y. Thus, "all components are searched" should read "all requested
components are searched", the known ones are enabled, and for the
unknown ones, just the respective FOUND variable is set to FALSE.
Personally, my favored approach for {FindFoo,FooConfig}.cmake is:
- Set a FOUND variable for each requested component, known or not.
- Foo_FOUND==FALSE: Foo totally unavailable, don't use it in any
manner. In particular, do not use any further Foo_* variables.
- Foo_FOUND==TRUE: Foo basically available, but no information
about components. Check their availability by the respective
FOUND variable, e.g. IF(Foo_FOUND AND Foo_Bar_FOUND).
For the user, this means:
- Request all components that will be used.
- Use only components that have been requested.
IMO, this approach is robust, versatile and anything but difficult
to implement, and it does not require any change in FIND_PACKAGE().
Regards,
Michael
[1] http://www.mail-archive.com/cmake-developers@cmake.org/msg03036.html
[2] http://www.mail-archive.com/cmake-developers@cmake.org/msg03085.html
More information about the cmake-developers
mailing list