Provide guidance for install location of config package files
Discussions in !2455 (closed) highlighted that the choice of install location for CMake config package files is not obvious. It would be good to provide some guidance to package maintainers for these locations. They would, of course, still be free to make other choices, but if CMake's docs provided a statement along the lines of "in the absence of any other constraints, location BLAH is a suitable choice", I think it would be helpful. I propose that this is probably more a question of updating the documentation rather than augmenting the
GNUInstallDirs module or providing further functionality elsewhere.
Similar to @zaufi's comments in !2455 (closed), I too see two main cases - packages with or without architecture-dependent contents. I put forward the following reasoning to guide such suggested locations:
Config files for an architecture-dependent package should go under an architecture-dependent path. This allows systems that support multiple architectures to have packages for multiple architectures installed simultaneously without them interfering with each other. Starting with the set of paths that
find_package() searches by default, that more or less means putting the files under a path with
lib or its variants. From there:
- Eliminate any candidates that repeat the package name (DRY principle).
- Eliminate any candidates that are not all lowercase to remove any question of case sensitivity issues across platforms.
- Eliminate any candidates that use
sharein the path because it is less common to see that used under Windows.
- Prefer something with
cmakein the path so the purpose of the directory contents is clear.
This leaves us with the following candidates from where
find_package() searches (ignoring the Mac-specific framework and bundle paths, those are covered separately further below):
I'd propose that the docs suggest using
GNUInstallDirs in place of the
(lib/<arch>|lib*) part, which just leaves whether to put
cmake before or after the package name (both choices include the package name in the path, so we have to include it one way or the other). I personally prefer the former (1) because if you have multiple packages being installed, they are nicely collected together under the
cmake area. It's also the case I've seen more commonly used.
These should not have any architecture-dependent component in their path. If we again prefer to have
cmake in the path to highlight the purpose of the directory and we also stick with a lowercase
cmake to avoid case sensitivity issues, we are left with the following candidates:
I suspect most architecture-independent packages don't need much more than the
<packageName>Config.cmake and perhaps
<packageName>ConfigVersion.cmake files, since they wouldn't produce any targets that are architecture-specific (potentially only interface targets and/or other things that are not dependent on the build config). This means the need for a package-specific directory is likely to be less compared to architecture-dependent packages (which may have more files for its export sets, etc.). For simplicity, I personally go with the
<prefix>/cmake/ choice, but I can understand a preference for either (it's a pity that there is no
<prefix>/cmake/<name>*/ option, which would have made a consistent pattern between the arch-dependent and arch-independent cases possible and logical). It would be good if anyone with an informed view of whether there is a more prevalent choice for architecture-independent packages could comment on that.
Apple Bundles And Frameworks
For Apple bundles and frameworks, I believe the likely config package location is much clearer. Having a CMake-specific path is still desirable and frameworks should always prefer a version-specific path if they use versioned frameworks, so there is one clear choice in these cases:
- App bundles -->
- Frameworks -->
If we can agree on recommended install locations, I propose that we add wording to the
cmake-packages manual to guide package maintainers and then cross-reference it in the docs for both the
GNUInstallDirs module and the