[cmake-developers] the future of FIND_PACKAGE()
Alexander Neundorf
neundorf at kde.org
Mon Jun 26 17:19:11 EDT 2006
Hi,
I guess you already know what this email is about.
Now KDE 4 uses cmake, Boson and Scribus also switched already, the Qt bindings
for DBUS are built with cmake.
Probably more and more software packages will follow.
This leads to a new problem.
Until now cmake comes with a collection of FindXXX.cmake files. Each of the
FindXXX.cmake files defines a set of variables and optionally macros required
for building software which uses this package.
This makes using the FIND_PACKAGE() command very easy, all the more difficult
things are hidden inside the FindXXX.cmake files:
find_package(Foo)
and you are done.
For the case that really a lot of projects might switch to cmake as native
buildsystem, it is not realistic to expect that all will commit there
respective FindXXX.cmake files to cmake cvs.
The FIND_PACKAGE() command checks for two things:
FindXXX.cmake
and XXXConfig.cmake
The FindXXX.cmake file is intended to contain cmake code which searches for
header and library files. The XXXConfig.cmake files are intended to contain
the fixed locations of the installed software on the specific system.
"Third party software" can install either a FindXXX.cmake file or a
XXXConfig.cmake file.
Currently the only way to make additional files available to cmake is to
either
A) install the modules directly into CMAKE_ROOT/Modules/
-this is probably not recommended
B) setting up CMAKE_MODULE_PATH
-this can only be done once you know where to set it to
In KDE4 we have a lot of additional modules, there we do it this way:
we added a small and simple FindKDE4.cmake to cmake cvs, which really only
tries to find the cmake files installed by kdelibs/, in this case installed
to KDEDIR/share/apps/cmake/modules/FindKDE4Internal.cmake.
This file is then included and KDEDIR/share/apps/cmake/modules/ is added to
CMAKE_MODULE_PATH.
I.e. this works only since we have the combination of a simple cmake module
directly in cmake, and the sophisticated one in
KDEDIR/share/apps/cmake/modules/.
It would be nice, if not required, if there was a standard way for 3rd party
software to make its cmake files avaiable to cmake.
There are several options to do this:
1) define a set of directories where cmake searches for files
Currently cmake searches in CMAKE_ROOT/Modules/. This means it only finds the
modules installed with this version of cmake.
A directory could be defined for 3rd party cmake modules, e.g.
CMAKE_ROOT/3rdPartyModules/. 3rd party packages could install their files
directly into this directory, or into subdirs named after the package
( CMAKE_ROOT/3rdPartyModules/Foo/) or into subdirs named after the package
with an additional version or install-location suffix
(CMAKE_ROOT/Foo.usr_local_lib/)
Pros:
-easy for the user to understand
Cons:
-may change the include() and find_package() behaviour
-on systems with multiple versions of cmake only one version of cmake will
find the modules automatically, since the other cmake version will have a
different CMAKE_ROOT.
This could be worked around with a command line switch or an environment
variable -CMAKE_3rdPARTY_MODULE_DIR.
This would mean that KDE 4 doesn't install its files to
KDEDIR/share/apps/cmake/, but e.g. to CMAKE_ROOT/3rdPartyModules/KDE4/
2) install the cmake files in the installation of the project
This would mean that a project installs its files somewhere indepedent from
cmake, e.g. to INSTALL_PREFIX/(lib|share)/Foo/cmake/.
Pro:
-available for multiple installed versions of cmake
-no clashes when multiple versions of the same package
Cons:
-it will be hard for cmake to find the modules, since they can end up anywhere
on the system
This is IMO a major problem.
Until now one can simply do
find_package(Foo)
and FindFoo.cmake can search in all appropriate places on the system for the
package. With a enhanced version of find_package() this is not possible
anymore, since cmake will search only in a predefined set of directories, and
no matter how well they are tuned, there will always be cases where it wont
work. And then it can only be made to work by setting some options or
environment variables so that they contain the list of the root directories
of all packages which haven't been found. This can be a big number, KDE uses
maybe 15..25 packages. Having to set up a variable which contains 25
directories wouldn't be practical.
Compared to option 1) there would have to be set up only one directory, the
central directory where all cmake files are installed to.
-----------------
FindFoo.cmake vs. FooConfig.cmake files
FindFoo.cmake files are generic (and I personally think I like them more). So
being generic means they should be installed somewhere under share/ and not
under lib/ (according to the file system hier. standard).
FooConfig.cmake files are not generic and as such shouldn't be installed
somewhere under lib/ and not under share/.
The cmake module directory is located under share/, so it doesn't fit very
well for FooConfig.cmake files.
So the location for FooConfig.cmake files should go either to
INSTALL_PREFIX/lib/Foo/cmake/ or CMAKE_ROOT/Configs/.
The FooConfig.cmake files can probably not be transferred to another
installation, since they contain the fixed paths, while FindFoo.cmake files
can be copied.
--------------------
Different types of packages
I think there are at least three different kinds of packages to consider:
1) packages coming with the distribution
these packages know which version of cmake belongs to the distribution, know
where it's located, and can install their files just to the correct location,
so that they will be found automatically by cmake
2) packages compiled by the user, using cmake
If a package is compiled from sources by the user with cmake, he has a cmake
inatalled on the system. In this case it would be possible to put some
intelligence into cmake so that it can install cmake files in such locations
so that this cmake will find them.
3) packages compiled by the user, not using cmake but installing cmake files
Such packages don't exist yet, but might exist in the future, in the case that
cmake becomes the real successor of autotools.
During "make install" it's not reliable that the locations where cmake
searches are known.
During the configure step of the package it could be checked whether cmake is
installed on the system and if so it could be queried for its installation
and search directories (using -P print_some_vars.cmake).
--------------------
How does pkgconfig deal with this issues ?
pkgconfig has very similar issues.
AFAIK software packages install their files into INSTALL_PREFIX/lib/pkgconfig/
(-> hint: FooConfig.cmake files should also go under lib/ something).
pkgconfig searches the files in PKGCONFIG_INSTALL_PREFIX/lib/pkgconfig/, and
additionally directories listed in some environment variable. This fails on
many distributions where the environemtn variable is not set up so that it
contains usual install dirs (e.g. /usr/local/lib/pkgconfig/ is not searched
by default under both kubuntu and slackware) and the environment variable is
not known by many users.
The same would be true if cmake relies on some environment variables to be set
up correctly.
That's why I would prefer if there would be a defined location under
CMAKE_ROOT, this would work for all users which have only one version of
cmake installed (I think this is the big majority), and all other could set
up one env.var to point to the extra module dir or an cmd line argument.
-------------------
Next week I'm in Trysil ( http://dot.kde.org/1151271635/ ) where I could
discuss this topic with other KDE core developers, e.g. David.
This issue needs a really good solution.
Bye
Alex
--
Work: alexander.neundorf AT jenoptik.com - http://www.jenoptik-los.de
Home: neundorf AT kde.org - http://www.kde.org
alex AT neundorf.net - http://www.neundorf.net
More information about the cmake-developers
mailing list