'Where should I install myproj-config.cmake and myproj-version-config.cmake?

Suppose you're developing some library, myproj, using CMake for build configuration; supporting the cmake --install (using install() commands); and supporting use of myproj with CMake config mode, i.e. by making relevant .cmake files accessible to dependent projects.

Now, ,given an install root directory - where should I install my project's configuration .cmake files? Is there an idiomatic standard(ish) location?

  • Sorush Khajepor's R&D blog suggests ${LIB_INSTALL_DIR}/cmake/myproj - and it's the newest.
  • Foonathan's blog suggests placing the config .cmake files in ${LIB_INSTALL_DIR}/. So does Falkor's blog.
  • The documentation page for the CMakePackageConfigHelpers module suggests: ${LIB_INSTALL_DIR}/myproj/cmake.

What's the most popular/idiomatic choice? And what are its pros and cons relative to the other ones?



Solution 1:[1]

I advocate for setting a cache variable to override this and defaulting it to <LIBDIR>/cmake/ProjName (as you suggest in your answer):

cmake_minimum_required(VERSION 3.21)  # for saner CACHE variables
project(ProjName VERSION 0.1.0)

# ...

include(GNUInstallDirs)
include(CMakePackageConfigHelpers)

set(ProjName_INSTALL_CMAKEDIR "${CMAKE_INSTALL_LIBDIR}/cmake/ProjName"
    CACHE STRING "Path to ProjName CMake files")

install(EXPORT ProjName_Targets
        DESTINATION "${ProjName_INSTALL_CMAKEDIR}"
        NAMESPACE ProjName::
        FILE ProjNameConfig.cmake
        COMPONENT ProjName_Development)

write_basic_package_version_file(
    ProjNameConfigVersion.cmake
    COMPATIBILITY SameMajorVersion)

install(FILES
        "${CMAKE_CURRENT_BINARY_DIR}/ProjNameConfigVersion.cmake"
        DESTINATION "${ProjName_INSTALL_CMAKEDIR}"
        COMPONENT ProjName_Development)

I wrote a blog post with an expanded version of this a while back: https://alexreinking.com/blog/building-a-dual-shared-and-static-library-with-cmake.html

In general, setting an install() destination to anything other than "${SOME_CACHE_VARIABLE}" is bound to cause headaches for some package maintainer. Where GNUInstallDirs doesn't provide a valid configuration point, you must create your own.

Solution 2:[2]

I'll argue in favor of ${LIB_INSTALL_DIR}/cmake/myproj.

If you're installing to some library-specific install location, e.g. /opt/myproj - then it doesn't really matter all that much anyway. But think about what happens when you install to, say, /usr/local.

  • If you place the scripts in ${LIB_INSTALL_DIR}, that library now becomes full of foo-config.cmake and foo-version-config.cmake, instead of just library files (and some subdirs). Less fun for browsing and searching.
  • If you place the scripts in ${LIB_INSTALL_DIR}/myproj/cmake, then - the same thing happens, but with per-project subdirs instead of sets of files. Better, perhaps, but instead - why don't we just replace the path elements of myproj and cmake, and that way we would get a cmake/ directory with many subdirs, instead. That's cleaner and more convenient IMHO.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Alex Reinking
Solution 2 einpoklum