# How to use CMakePackageConfigHelpers right?

**URL:** <https://discourse.cmake.org/t/how-to-use-cmakepackageconfighelpers-right/660>\
**Category:** Code\
**Tags:** os:linux\
**Created:** [February 20, 2020, 8:51am UTC](https://discourse.cmake.org/t/how-to-use-cmakepackageconfighelpers-right/660 "2020-02-20T08:51:06Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![ClausKlein](https://discourse.cmake.org/user_avatar/discourse.cmake.org/clausklein/32/352_2.png) [@ClausKlein](https://discourse.cmake.org/u/ClausKlein)\
**Post date:** [February 20, 2020, 8:51am UTC](https://discourse.cmake.org/t/how-to-use-cmakepackageconfighelpers-right/660/1 "2020-02-20T08:51:06Z")

</div>

When I try to use it like here [https://cmake.org/cmake/help/latest/module/CMakePackageConfigHelpers.html#example-generating-package-files](https://cmake.org/cmake/help/latest/module/CMakePackageConfigHelpers.html#example-generating-package-files) I run into problems.

Using **cmake version 3.16.3** on OSX and debian, same result.

I have an project **cxx\_simplelog** , that requires **spdlog** to be installed.

**spdlog** depends on **fmt** lib to be installed too.  
All that is true, but wenn I install my project und try to build an example using

> find\_package(cxx\_simplelog REQUIRED)

my package is found, but the dependent libs are not imported?

> <https://github.com/ClausKlein/cxx.simplelog/blob/develop/CMakeLists.txt>

## **project-config.cmake.in**

```cmake
@PACKAGE_INIT@

include("${CMAKE_CURRENT_LIST_DIR}/cxx_simplelog-targets.cmake")

check_required_components(cxx_simplelog)

# TODO: with this it works?
# include(CMakeFindDependencyMacro)
# find_dependency(spdlog @SPDLOG_MIN_VERSION@ CONFIG)
'''
```

---

<div class="post-metadata">

**Author:** ![ClausKlein](https://discourse.cmake.org/user_avatar/discourse.cmake.org/clausklein/32/352_2.png) [@ClausKlein](https://discourse.cmake.org/u/ClausKlein)\
**Post date:** [February 21, 2020, 5:11pm UTC](https://discourse.cmake.org/t/how-to-use-cmakepackageconfighelpers-right/660/2 "2020-02-21T17:11:17Z")

</div>

> [@ClausKlein](#):
>
> check\_required\_components

Also I am not sure, what is the right directory to install a cmake config files?

> lib/packagename/cmake

or

> lib/cmake/packagename

Both is found in cmake documentation?

What is about this tutorial page, is this still valid?  
[https://gitlab.kitware.com/cmake/community/-/wikis/doc/tutorials/How-to-create-a-ProjectConfig.cmake-file](https://gitlab.kitware.com/cmake/community/-/wikis/doc/tutorials/How-to-create-a-ProjectConfig.cmake-file)

---

<div class="post-metadata">

**Author:** ![kyle.edwards](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/k/65b543/32.png) [@kyle.edwards](https://discourse.cmake.org/u/kyle.edwards)\
**Post date:** [February 21, 2020, 5:56pm UTC](https://discourse.cmake.org/t/how-to-use-cmakepackageconfighelpers-right/660/3 "2020-02-21T17:56:06Z")

</div>

Both are found in the documentation because both are acceptable. There isn’t really a fixed, strict standard for where the `.cmake` files should go in the installation directory.

Personally, I usually put them in `lib/cmake/<package>`.

---

<div class="post-metadata">

**Author:** ![ClausKlein](https://discourse.cmake.org/user_avatar/discourse.cmake.org/clausklein/32/352_2.png) [@ClausKlein](https://discourse.cmake.org/u/ClausKlein)\
**Post date:** [February 21, 2020, 7:08pm UTC](https://discourse.cmake.org/t/how-to-use-cmakepackageconfighelpers-right/660/4 "2020-02-21T19:08:20Z")

</div>

That is also my preference and seems most often used.  
At least on my host:

```auto
bash-5.0$ tree -d /usr/local/lib/*/cmake
/usr/local/lib/*/cmake [error opening dir]

0 directories
bash-5.0$ tree -d /usr/local/*/cmake
/usr/local/lib/cmake
├── Example
├── Poco
├── Snappy
├── asio
├── cppunit
├── cxx_simplelog
├── doctest
├── fmt
├── gsl-lite
├── spdlog
├── tftpd
└── zlib

12 directories
bash-5.0$ tree -d /opt/local/lib/*/cmake
/opt/local/lib/*/cmake [error opening dir]

0 directories
bash-5.0$ tree -d /opt/local/lib/cmake
/opt/local/lib/cmake
├── DBus1
├── GTest
├── cmocka
├── harfbuzz
├── jsoncpp
├── libssh
└── libxml2

7 directories
bash-5.0$ 

```

---

<div class="post-metadata">

**Author:** ![craig.scott](https://discourse.cmake.org/user_avatar/discourse.cmake.org/craig.scott/32/20_2.png) [@craig.scott](https://discourse.cmake.org/u/craig.scott)\
**Post date:** [February 22, 2020, 1:18am UTC](https://discourse.cmake.org/t/how-to-use-cmakepackageconfighelpers-right/660/5 "2020-02-22T01:18:04Z")

</div>

You might find the following issue/discussion relevant:

[https://gitlab.kitware.com/cmake/cmake/issues/18453](https://gitlab.kitware.com/cmake/cmake/issues/18453)

---

<div class="post-metadata">

**Author:** ![ClausKlein](https://discourse.cmake.org/user_avatar/discourse.cmake.org/clausklein/32/352_2.png) [@ClausKlein](https://discourse.cmake.org/u/ClausKlein)\
**Post date:** [February 22, 2020, 9:32pm UTC](https://discourse.cmake.org/t/how-to-use-cmakepackageconfighelpers-right/660/6 "2020-02-22T21:32:50Z")

</div>

The **tutorial** seems to be outdated (cmake version 2.8)!

```cmake
get_property(TARGETS
    DIRECTORY ./
    PROPERTY BUILDSYSTEM_TARGETS
    )

install(
  EXPORT
    messageTargets
  NAMESPACE
    "message::"
  DESTINATION
    ${INSTALL_CMAKEDIR}
  COMPONENT
    dev
  )

include(CMakePackageConfigHelpers)
write_basic_package_version_file(
  ${CMAKE_CURRENT_BINARY_DIR}/messageConfigVersion.cmake
  VERSION ${PROJECT_VERSION}
  COMPATIBILITY SameMajorVersion
  )

configure_package_config_file(
  ${PROJECT_SOURCE_DIR}/cmake/messageConfig.cmake.in
  ${CMAKE_CURRENT_BINARY_DIR}/messageConfig.cmake
  INSTALL_DESTINATION ${INSTALL_CMAKEDIR}
  )

install(
  FILES
    ${CMAKE_CURRENT_BINARY_DIR}/messageConfig.cmake
    ${CMAKE_CURRENT_BINARY_DIR}/messageConfigVersion.cmake
  DESTINATION
    ${INSTALL_CMAKEDIR}
  )

```

this seems to be better!  
using **cmake/messageConfig.cmake.in**

```cmake
@PACKAGE_INIT@

include("${CMAKE_CURRENT_LIST_DIR}/messageTargets.cmake")
check_required_components(
  @TARGETS@
  )

# Remove dependency on UUID if on Windows
if(NOT WIN32)
  if(NOT TARGET PkgConfig::UUID)
    find_package(PkgConfig REQUIRED QUIET)
    pkg_search_module(UUID REQUIRED uuid IMPORTED_TARGET)
  endif()
endif()

```

But here _find\_package()_ part is also **duplicated code** and **dependent** from target\_link\_libraries() at current _CMakeLists.txt_ and should be generated!

---

<div class="post-metadata">

**Author:** ![ben.boeckel](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/b/ea5d25/32.png) [@ben.boeckel](https://discourse.cmake.org/u/ben.boeckel)\
**Post date:** [February 28, 2020, 7:38pm UTC](https://discourse.cmake.org/t/how-to-use-cmakepackageconfighelpers-right/660/7 "2020-02-28T19:38:42Z")

</div>

Are you asking for CMake to generate the `find_dependency(fmt)` call in the generated file? That is a hard problem. The targets which use `fmt` may be guarded by `COMPONENTS` of your `config.cmake` file.

In your example, the `UUID` target should set `_FOUND` for the relevant component (setting the package-wide `_FOUND` variable if it is a required component).

---

<div class="post-metadata">

**Author:** ![ClausKlein](https://discourse.cmake.org/user_avatar/discourse.cmake.org/clausklein/32/352_2.png) [@ClausKlein](https://discourse.cmake.org/u/ClausKlein)\
**Post date:** [February 29, 2020, 9:34am UTC](https://discourse.cmake.org/t/how-to-use-cmakepackageconfighelpers-right/660/8 "2020-02-29T09:34:22Z")

</div>

I have learned, there is no generic way to do it.

But I found this block: [https://pabloariasal.github.io/2018/02/19/its-time-to-do-cmake-right/](https://pabloariasal.github.io/2018/02/19/its-time-to-do-cmake-right/)

One more way to do it:

```cmake
get_filename_component(JSONUTILS_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
#
# NOTE: We had to use find_package because find_dependency does not support
# COMPONENTS or MODULE until 3.15.0? CK
#
list(APPEND CMAKE_MODULE_PATH ${JSONUTILS_CMAKE_DIR})
# NOTE: to find FindRapidJSON.cmake
find_package(RAPIDJSON @MIN_RAPIDJSON_VERSION@ REQUIRED MODULE)
list(REMOVE_AT CMAKE_MODULE_PATH -1)

include(CMakeFindDependencyMacro)
find_dependency(boost_regex @MIN_BOOST_VERSION@ REQUIRED CONFIG)

if(NOT TARGET JSONUtils::JSONUtils)
    include("${JSONUTILS_CMAKE_DIR}/JSONUtilsTargets.cmake")
endif()

set(JSONUTILS_lIBRARIES JSONUtils::JSONUtils)

```

---

<div class="post-metadata">

**Author:** ![ClausKlein](https://discourse.cmake.org/user_avatar/discourse.cmake.org/clausklein/32/352_2.png) [@ClausKlein](https://discourse.cmake.org/u/ClausKlein)\
**Post date:** [February 29, 2020, 9:36am UTC](https://discourse.cmake.org/t/how-to-use-cmakepackageconfighelpers-right/660/9 "2020-02-29T09:36:41Z")

</div>

> <https://github.com/pabloariasal/modern-cmake-sample/pull/11>
