cmake-conan icon indicating copy to clipboard operation
cmake-conan copied to clipboard

[question] Installing libraries from Conan via CMake's `install` when using 'CMakeDeps'-generator?

Open Kuxe opened this issue 3 years ago • 1 comments
trafficstars

I currently have a CMakeLists.txt which is similar to the example CMakeLists.txt in the README.md:

CMakeLists.txt

cmake_minimum_required(VERSION 3.5)
project(conan-cmake-install-question CXX)

list(APPEND CMAKE_MODULE_PATH ${CMAKE_BINARY_DIR})
list(APPEND CMAKE_PREFIX_PATH ${CMAKE_BINARY_DIR})

add_definitions("-std=c++11")

if(NOT EXISTS "${CMAKE_BINARY_DIR}/conan.cmake")
  message(STATUS "Downloading conan.cmake from https://github.com/conan-io/cmake-conan")
  file(DOWNLOAD "https://raw.githubusercontent.com/conan-io/cmake-conan/v0.16.1/conan.cmake"
                "${CMAKE_BINARY_DIR}/conan.cmake"
                EXPECTED_HASH SHA256=396e16d0f5eabdc6a14afddbcfff62a54a7ee75c6da23f32f7a31bc85db23484
                TLS_VERIFY ON)
endif()

include(${CMAKE_BINARY_DIR}/conan.cmake)

conan_cmake_configure(REQUIRES fmt/6.1.2
                      GENERATORS CMakeDeps
                      OPTIONS fmt:shared=True)

conan_cmake_autodetect(settings)

conan_cmake_install(PATH_OR_REFERENCE .
                    BUILD missing
                    REMOTE conancenter
                    SETTINGS ${settings})

find_package(fmt)

file(WRITE main.cpp [[
#include <fmt/core.h>
#include <cstdio>

int main()
{
	printf("%s\n", fmt::format("{} {}!\n", "hello", "world").c_str());
	return 0;
}
]])

add_executable(main main.cpp)
target_link_libraries(main fmt::fmt)

install(TARGETS main DESTINATION bin)
install(TARGETS fmt::fmt DESTINATION bin)

The notable differences are in snippet above is:

  • Generator CMakeDeps is used instead of cmake_find_package
  • Using shared fmt instead of static fmt
  • Attempting to link AND install target fmt::fmt instead of just linking target fmt::fmt

When install this CMakeLists.txt, I get the following output (excerpt):

[cmake] -- Conan: Target declared 'fmt::fmt'
[cmake] CMake Error at CMakeLists.txt:47 (install):
[cmake]   install TARGETS given target "fmt::fmt" which does not exist.

I am told that conan just declared the target fmt::fmt, only to be told by CMake that the target fmt::fmt does not exist 🤔.

Per this stackoverflow post I take it that installing imported libraries via install(TARGETS ...) is unsupported, and that install(FILES ...) should be used instead. I can make that work, however it is not as ergonomic as just using install(TARGETS fmt::fmt DESTINATION bin).

What is the recommended way of installing libraries from Conan via CMake's install when using 'CMakeDeps'-generator?

Kuxe avatar Nov 26 '21 19:11 Kuxe

Hi @Kuxe, Yes, as you say probably the way of doing that in CMake is using install(FILES ...) As an alternative you could also use the IMPORTS argument of conan_cmake_configure() like this:

conan_cmake_configure(REQUIRES fmt/6.1.2
                      GENERATORS cmake_find_package
                      IMPORTS "bin, *.dll -> ./bin"
                      IMPORTS "lib, *.dylib* -> ./bin")
                      OPTIONS fmt:shared=True)

Or adding an imports section to the conanfile.py/txt you can use also as an argument of conan_cmake_install()

czoido avatar Dec 29 '21 17:12 czoido