[cmake-developers] Making Config.cmake files easier to write

Alexander Neundorf neundorf at kde.org
Fri Feb 17 04:20:01 EST 2012


On Friday 17 February 2012, Eric Noulard wrote:
> 2012/2/17 Alexander Neundorf <neundorf at kde.org>:
> > On Thursday 16 February 2012, Brad King wrote:
> >> On 2/16/2012 1:24 PM, Alexander Neundorf wrote:
> >> > Actually I expected I would prefer this over the fixed names, but now
> >> > that I've done it and look at what Config.cmake.in file I have to
> >> > write, I think I liked the previous version with the fixed names
> >> > (CONFIG_HELPER) better. I think it was easier to do, a simple scheme.
> >> 
> >> I think the fixed names are better/simpler too.  I'm not fond of
> >> "CONFIG_HELPER" specifically.  The information stored in them is
> >> about the *package* that the file is configuring, which is why
> >> I originally proposed the prefix "PACKAGE_".  The INCLUDE_INSTALL_DIR
> >> is where the *package* goes, not where the config helper is/goes.
> > 
> > I pushed a branch MakingConfigFilesEasier_ConfigureMacro to stage.
> > It has documentation and a test.
> > An example Config.cmake.in file is attached.
> > I can still change names etc. tomorrow.
> > The macro is in CMakePackageHelpers.cmake.
> 
> Nice piece of work. Should be helpful to many of us.
> Some more "tuning remarks".
> 
> Why not offering more "bundled interface" to this feature ?
> 
> currently you have to:
> 
> 1) include(CMakePackageConfigHelpers)
> 2) configure_package_config_file(FooConfig.cmake.in
>                       ${CMAKE_CURRENT_BINARY_DIR}/FooConfig.cmake
>                       INSTALL_DESTINATION ${LIB_INSTALL_DIR}/Foo/cmake
>                       PATH_VARS INCLUDE_INSTALL_DIR SYSCONFIG_INSTALL_DIR)
> 3) write_basic_package_version_file(
>                     ${CMAKE_CURRENT_BINARY_DIR}/FooConfigVersion.cmake
>                     VERSION 1.2.3 COMPATIBILITY
>                     SameMajorVersion)
> 
> 4) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/FooConfig.cmake
>              ${CMAKE_CURRENT_BINARY_DIR}/FooConfigVersion.cmake
>              DESTINATION ${LIB_INSTALL_DIR}/Foo/cmake )

Yes, these are all simple orthogonal functions, which can be described with 
one sentence without using "and".

> 1) is mandatory of course
> 3) is optional
> 2) and 4) should be using the same "INSTALL_DESTINATION"  and
> "DESTINATION" in order to be consistent.
> 
> I cannot imagine doing 2) or 3) without 4).

You are right.
It is a somewhat problematic point that the destinations must match.
 
> So in the end, wouldn't it be simpler (for the user/developer) to have
> something like:
> 
> include(CMakePackageConfigHelpers)
> create_and_install_package_config_files(NAME Foo
>                    CONFIG_TEMPLATE FooConfig.cmake.in
>                    DESTINATION ${LIB_INSTALL_DIR}/Foo/cmake
>                    PATH_VARS INCLUDE_INSTALL_DIR SYSCONFIG_INSTALL_DIR
>                    VERSION 1.2.3
>                    VERSION_COMPATIBILITY SameMajorVersion)
> 
> This would do the same as 1) + 2) + 3) +4) but...
> 
>  a) enforces that 2) "INSTALL_DESTINATION" and 4) "DESTINATION" are the
> same and produce appropriate install rule.

This is good on one side, but on the other side I always try not to "hide" 
simple cmake commands.
I mean, every cmake-using developer should know configure_file() and 
install(FILES). IMO it is ok if they have to use those functions.
Now for the Config file the issue is that it is somewhat complicated to get 
them relocatable, so we need a helper here.
Combining the install() command into this macro hides the install(), i.e. if I 
would search the CMakeLists.txt for "install" command, to find out what is 
installed, I might not notice that this 
create_and_install_package_config_files() wraps an install() command.

That's why I kept the install() out of the macro, so that for installing 
anything there is always an install() command visible.

(this is a "not sure we should do this", not a "I seriously object to this 
idea")

>  b) enforces that whatever the name of the "CONFIG_TEMPLATE" you end up
> with <NAME>Config.cmake
>        and
>        <NAME>ConfigVersion.cmake
> 
>      I think this is a good point because you don't have the choice of
> the name do you?

...and the macro should FATAL_ERROR if CONFIG_TEMPLATE doesn't match 
*Config.cmake.in or *-config.cmake.in ?

Sounds ok.
 
>  c) VERSION and VERSION_COMPATIBILITY should be optional parameters
> that would trigger the creation (and install rule) of 
> <NAME>ConfigVersion.cmake

Maybe. OTOH, is there any reason to install a package without version numbers 
?

> I can try to write (probably tomorrow) the proposed macro using those
> provided by Alex
> if you find the idea useful. The proposed macro is not meant replace
> the Alex's one but
> to offer higher-level [possibly] simpler API.
> 
> PS: I start to think in most simple cases "CONFIG_TEMPLATE" could be
> made optional as well if we add another TARGET_EXPORT_FILE option which
> indicates the name of export(TARGETS ... FILE ...), using this a proper
> config template could be created as well.

We discussed that too already.
The generated file would have to include the targets file, and it would have 
to create a
set(FOO_BAR_LIBRARY FooBar)
set(FOO_BLUB_LIBRARY FooBlub)
set(FOO_LIBRARIES ${FOO_BAR} ${FOO_BLUB} )
for all exported libraries. You would have to specifiy how these prefixes 
should look like, whether the targets have a namespace, probably more.

This would become quite a lot of parameters, for the purpose of hiding the 
Config.cmake.in from the developer, which IMO should not be done.
The developer should know what he can do with a Config.cmake file.

So I wouldn't do this, I think this would be too much.
 
> PS2: we may need to add an optional COMPONENT option as well if the
> generated install rule should be put in some install component.

Yes.
What about the PERMISSIONS and CONFIGURATIONS parameters ?

Alex



More information about the cmake-developers mailing list