cmakepackagingbuildconfigurationsoftware-packaging

Why should foo-config.cmake and foo-config-version.cmake be separate?


In talks by Daniel Pfeiffer (Effective CMake) and by Deniz Bahadir (More Modern CMake), and even in the CMake documentation, it is suggested that (at least) to .cmake files be generated for using a repository with CMake in other projects: foo-config.cmake and foo-config-version.cmake (for package foo; another possible naming scheme is FooConfig.cmake and FooConfigVersion.cmake).

This already seems strange to me. Why shouldn't foo-config.cmake also have information/commands regarding the installed version? Is there some objective reason for the two separate files to exist, or is it just a CMake design 'gaffe'?

Edit: snipped the rest of this question, for focus and since I got something wrong.


Solution

  • Why shouldn't foo-config.cmake also have information/commands regarding the installed version?

    The package script foo-config.cmake is free to create targets (which cannot be deleted), set variables in the parent scope, and so on. Splitting foo-config-version.cmake into a script that runs in an isolated scope makes it easy for the package search to proceed without fear of clobbering variables. It would have been possible to incorporate all this functionality in one file (the way find modules do) but history has shown this practice to be error-prone and redundant.

    Basically, there are two advantages:

    1. Isolation. Running a version script won't clobber variables in the find_package caller. Once foo-config.cmake runs, it may set package variables, create targets, and so on with full confidence that the user intended this action.
    2. Reduced boilerplate. The CMakePackageConfigHelpers can generate good version scripts at the cost of two lines in your CMakeLists.txt file. Given the new version range features in CMake 3.19, this is a welcome task to automate.