[CMake] Creating a XXXConfigYYY.cmake file

Michael Hertling mhertling at online.de
Mon Nov 22 22:02:16 EST 2010


On 11/17/2010 04:13 PM, Torri, Stephen CIV NSWCDD, W15 wrote:
> I have been reading email posts on goggle that says if you create a library then produce a <name>Config<version>cmake file rather than a Find<name>.cmake file. That is fine but what confuses me is:

Indeed, a package XXX - particularly a library - that's intended to
be used by a CMake-aware project should provide a configuration file
XXXConfig.cmake or xxx-config.cmake to expose the necessary information
for its usage. Nevertheless, the version file XXXConfigVersion.cmake or
xxx-config-version.cmake is meant as a companion of the configuration
file and tests whether the package provides a suitable version w.r.t.
the one requested by the user via FIND_PACKAGE()'s version parameter.

> 1. What do I put in it? 

For the library XXX, e.g., XXXConfig.cmake should provide the same as a
FindYYY.cmake module for a non CMake-aware package YYY, i.e. at least:

XXX_LIBRARY: Path of the installed libXXX.{so,a}
XXX_INCLUDE_DIR: Directory of the installed XXX.h
XXX_DEFINITIONS: Definitions necessary to use XXX.h
XXX_LIBRARIES: XXX_LIBRARY and all prerequisite libraries
XXX_INCLUDE_DIRS: XXX_INCLUDE_DIR and all prerequisite directories

The remaining XXX_FOUND variable is set to TRUE automatically if
FIND_PACKAGE() finds the configuration file, in contrast to the find
module which could set YYY_FOUND to FALSE. See [1] for more information.

> 2. How do I install it? (e.g. Linux and Windows)

Of course, it should be installed at a location which is searched by
FIND_PACKAGE(), see FIND_PACKAGE()'s documentation. On *nix, e.g., the
<prefix>/(share|lib) locations are the suitable ones. The configuration
file's installation itself can be done as usual by an INSTALL(FILES ...).

> 3. What google search terms should I use to find more information on this topic?

See [1] and [2] for the basics, and [3] for a related discussion.

> I have a large project is broken up into three separate projects each with their own CMakeLists.txt. For the sake of discussion lets call them Larry, Curly and Mo. Now Larry is the base library. Supposing I knew what I was doing I would create a LarryConfig1.0.cmake file and install it. I would do the same for the others. Do I just use find_package in the CMakeLists.txt of Curly and Mo to find the Larry library?

IMO, this depends on the degree of interconnection among Larry, Curly
and Mo. If each of them is useful on its own they could be considered
as independent such that there're {Larry,Curly,Mo}Config.cmake files,
and the latters use FIND_PACKAGE(Larry) to look for the base library.
If Larry, Curly and Mo are strongly interconnected, particularly if
they're always installed together, they could be considered as parts
of a superior project such that there's a sole <Project>Config.cmake
file which knows their installation locations and provides variables
like, e.g., <Project>_Larry_LIBRARY, <Project>_Curly_EXECUTABLE and
<Project>_Mo_FOUND. If some of these parts, e.g. Curly and Mo, don't
need to be installed along with Larry each time you might process the
<Project>_FIND_COMPONENTS variable provided by FIND_PACKAGE() for the
<Project>Config.cmake in order to let the user select or deselect them.

> Is there a tutorial on how to do this? One full example (e.g. create config file, installing config file, using config file) would be sufficient to help me. Right now I can build the large project fine on Linux but on Windows I am having trouble of telling Curly where Larry is installed.

For a simple library project XXX, I'd use a template XXXConfig.cmake.in:

FIND_LIBRARY(XXX_LIBRARY XXX
    PATHS @CMAKE_INSTALL_PREFIX@/lib
    NO_DEFAULT_PATH
)
SET(XXX_LIBRARIES ${XXX_LIBRARY})
FIND_PATH(XXX_INCLUDE_DIR XXX.h
    PATHS @CMAKE_INSTALL_PREFIX@/include
    NO_DEFAULT_PATH
)
SET(XXX_INCLUDE_DIRS ${XXX_INCLUDE_DIR})
SET(XXX_DEFINITIONS ...)
# XXX_FOUND is set to "1" by FIND_PACKAGE().

This expects the library to be installed in ${CMAKE_INSTALL_PREFIX}/lib
and the headers to be installed in ${CMAKE_INSTALL_PREFIX}/include. Use
CONFIGULE_FILE() on the template to generate the actual XXXConfig.cmake,
and INSTALL(FILES ...) for the latter's installation as mentioned above.
Finally, after a FIND_PACKAGE(XXX) in another project's CMakeLists.txt,
you can access those variables to use XXX's headers and link against
its library.

Regards,

Michael

[1] ${CMAKE_ROOT}/Modules/readme.txt
[2] http://www.cmake.org/Wiki/CMake_2.6_Notes#Packages
[3] http://www.mail-archive.com/cmake@cmake.org/msg28425.html


More information about the CMake mailing list