Zbyl
Zbyl

Reputation: 2310

How to use CMake file provided by a Conan package?

Bret Brown in his talk Modern CMake Modules recommends using Conan (or other package manager) to deliver reusable CMake code.

As instructed by Brett I've created a Conan package that delivers a MyHelpersConfig.cmake CMake file.
(The MyHelpersConfig.cmake file is the content of the package; it is not part of the package build system.)
My Conan package delivers only this one file.

Unfortunately I don't know how to make this line in CMake actually work:

find_package(MyHelpers)

Brett mentions, that when using Conan you need to manually override CMAKE_PREFIX_PATH, but he doesn't go into more detail (link to the relevant portion of his talk: Delivering CMake modules).

Does anyone know what needs to go into the Conan recipe, and how to use the package from CMake, to make it work?

EDIT:

From what I was able to figure out cmake_multi (generator I use when consuming packages) will update CMAKE_PREFIX_PATH, but only if CMAKE_BUILD_TYPE is set (which is rarely the case for multi configuration projects):

if(${CMAKE_BUILD_TYPE} MATCHES "Debug")
    set(CMAKE_PREFIX_PATH ${CONAN_CMAKE_MODULE_PATH_DEBUG} ${CMAKE_PREFIX_PATH})
    ...

We would need to add something like this to CMake (pseudocode):

 set(CMAKE_PREFIX_PATH ${CONAN_CMAKE_MODULE_PATH_$<CONFIG>} ${CMAKE_PREFIX_PATH})

But that is impossible.
So my conclusion would be that it should work out of the box for non-multi configuration projects, and can not possibly work for multi configuration projects.

Upvotes: 2

Views: 2448

Answers (1)

Zbyl
Zbyl

Reputation: 2310

The problem I had was that when consuming a package from CMake Conan was not updating CMAKE_PREFIX_PATH, and therefore MyHelpersConfig.cmake was not found.

This happened when using a cmake_multi generator for the consuming project.
Single-configuration generators should not have this problem, or could be solved easily by adding something like:

set(CMAKE_PREFIX_PATH ${CONAN_CMAKE_MODULE_PATH_<BUILD-MODE-HERE>} ${CMAKE_PREFIX_PATH})

To solve it for multi-config generators you can add the following to CMake in the consuming project:

set(CMAKE_PREFIX_PATH ${CONAN_<YOUR-PACKAGE-NAME>_ROOT_RELEASE} ${CMAKE_PREFIX_PATH})

This will work only under assumption that CMake files you deliver in your Conan package are the same for all build types (Debug, Release...). So it is a viable solution for general-purpose utility functions.

I don't think it is possible solve this situation when CMake files differ between build modes, simply because in multi-config projects build type is known only after all find_package() calls were already evaluated.

Upvotes: 1

Related Questions