Conan: Conan seem to not import target properties

Created on 3 Jun 2019  路  11Comments  路  Source: conan-io/conan

To help us debug your issue please explain:

  • [x] I've read the CONTRIBUTING guide.
  • [X] I've specified the Conan version, operating system version and any tool that can be relevant.
  • [x] I've explained the steps to reproduce the error or the motivation/use case of the question/suggestion.

I have a library, let' say hello, that has some PRIVATE and PUBLIC compile options:

target_compile_options(${project_name} PRIVATE /MP)
target_compile_options(${project_name} PUBLIC $<$<CONFIG:Debug>:/MTd> $<$<CONFIG:RELEASE>:/MT>)

When I integrate this library with my exe using add_subdirectory() my exe inherits all the PUBLIC compile options, i.e. it properly compiles and links using MT runtime and not the default MD.

add_subdirectory(libs/hello/)
target_link_libraries(${project_name} hello)

but when I use conan to integrate the library as a conan package the CMake options of my library are not passed to the exe. This is what I have in my exe CMake file:

include(${CMAKE_CURRENT_SOURCE_DIR}/conan.cmake)
conan_cmake_run(REQUIRES hello/0.1@org/testing
                BASIC_SETUP CMAKE_TARGETS
                BUILD outdated)
target_link_libraries(${project_name} CONAN_PKG::hello)

I have tried to reproduce the problem in this repo. If you just try to use the project as it is committed the exe will get the right compile flag and everything will compile and link properly. However if you comment out lines 13-14, and uncomment the conan_cmake_run() function it won't work because conan is not bringing the compile flag to the exe project.

This is my current setup:

  • cmake: 3.14.4
  • conan: 1.15.2
  • OS: Windows
  • Compiler/IDE: Visual Studio 2019
triaging

Most helpful comment

https://docs.conan.io/en/latest/howtos/cmake_install.html
Is an example of reusing CMake install in the Conan recipe. If you generate CMake Config files for targets correctly - they'll be installed into the package folder alongside the rest of the project.
Now to use these "native" CMake targets you can pick a generator:
CMake:
https://docs.conan.io/en/latest/integrations/build_system/cmake/cmake_generator.html
Or CMake paths and pass it to CMake as a toolchain file (vcpkg-like):
https://docs.conan.io/en/latest/integrations/build_system/cmake/cmake_paths_generator.html#included-as-a-toolchain

All 11 comments

To confirm that I understood correctly:

So, you are creating a Conan package for a library and in your CMakeLists.txt file you have the mentioned lines, right:

target_compile_options(${project_name} PRIVATE /MP)
target_compile_options(${project_name} PUBLIC $<$<CONFIG:Debug>:/MTd> $<$<CONFIG:RELEASE>:/MT>)

So when you depend on that package you don't get the target properties.

CorrecT?

Exactly, that's what seems to be happening, the CMakefile is available here.

So, when you build a recipe you get a binary package with the libraries inside. And, when you consume the package (with any other build system) you don't have anymore the original CMake targets, Conan generates an imported target with the binary and all the information gathering the cppinfo of the recipe.
That's why you don't get these properties.

But anyway you shouldn't need to propagate the runtime flags, as it is a Conan setting, when you install the dependencies, you will get the binaries for that runtime and if you use the CMake build helper, it will adjust automatically reading the settings. Are you having some trouble with this?

NOTE:
You can use native cmake targets instead if you've properly installed them in the package function of your recipe. You can use the cmake or cmake_paths generators for it. It'll allow you to preserve the cmake-side information about your library.
Conan-generated targets don't parse existing targets, they take the information provided to the recipe by the recipe author.

@lasote That's what I was afraid of. This will be a lot of work for us to maintain two sets of flags in both cmake and conan. Not all of our projects use Conan, or want to use it, and our goal is to rewrite all of our cmake packages with modern cmake so that it can be used for any project that uses modern cmake regardless of how they're integrated (add_subdirectory() or with conan, or vcpkg, etc). The modern CMake usage requirements is amazing and makes the integration of libraries really easy and I was hoping that Conan would support it. Maintaining two different files, conan recipe and cmake file, and keeping compatibility between them is hard. I am just wondering, if you can obtain all of the usage requirements from a CMakefile, why you still want the recipe maintainer to provide them in the conanfile?

@Minimonium Thanks for the tip but I have no idea how to do that. Would you happen to have an example or point me to the docs on conan website?

https://docs.conan.io/en/latest/howtos/cmake_install.html
Is an example of reusing CMake install in the Conan recipe. If you generate CMake Config files for targets correctly - they'll be installed into the package folder alongside the rest of the project.
Now to use these "native" CMake targets you can pick a generator:
CMake:
https://docs.conan.io/en/latest/integrations/build_system/cmake/cmake_generator.html
Or CMake paths and pass it to CMake as a toolchain file (vcpkg-like):
https://docs.conan.io/en/latest/integrations/build_system/cmake/cmake_paths_generator.html#included-as-a-toolchain

Thanks for the answer @Minimonium. Exactly, if you are going to use only CMake you have other alternatives. The right way is using find_package.

@Minimonium Do you by any chance know of any projects that correctly, something that would work with conan out of the box, generates the cmake config target files?

@lasote I remember two years ago there were a few "training" videos every few months and I used them a lot back then. But all the "training" materials are old now. With some guidance I am willing to write a generic example that would work for all possible generators and use cases.

@AliAskari any CMake project that correctly defines install, for example, Catch2:
https://github.com/catchorg/Catch2/blob/master/CMakeLists.txt

Was this page helpful?
0 / 5 - 0 ratings