3

I'm working on a renderer for Vulkan API. I have big trouble setting up the project correctly using CMake and conan package manager. Let's take a look at my conanfile.py for dependency setup:

from conans import ConanFile, CMake

class InexorConan(ConanFile):

settings = (
    "os",
    "compiler",
    "build_type",
    "arch"
)

requires = (
    "benchmark/1.5.0",
    "glm/0.9.9.7",
    "gtest/1.10.0",
    "spdlog/1.5.0",
    "glfw/3.3.2@bincrafters/stable",
    "toml11/3.1.0",
    "imgui/1.75",
    "assimp/5.0.1",
    "enet/1.3.14 "
)

generators = "cmake"

default_options = {
}

def imports(self):
    # Copies all dll files from packages bin folder to my "bin" folder (win)
    self.copy("*.dll", dst="bin", src="bin")
    # Copies all dylib files from packages lib folder to my "lib" folder (macosx)
    self.copy("*.dylib*", dst="lib", src="lib") # From lib to lib
    # Copies all so files from packages lib folder to my "lib" folder (linux)
    self.copy("*.so*", dst="lib", src="lib") # From lib to lib

def build(self):
    cmake = CMake(self)
    cmake.configure()
    cmake.build()

All the conan setup is working correctly, as can be seen by CMake output: enter image description here

Sadly, there is no conan setup for Vulkan API. So I am using some code of Sascha Willem's github repository. My CMake file looks like this:

cmake_minimum_required(VERSION 3.4)

project(inexor-vulkan-renderer)

file(GLOB_RECURSE source_files
  "src/*.hpp"
  "src/*.cpp"
)

# Use the folder structure in source code directory as project structure in Visual Studio.
function(assign_source_group)
    foreach(source_files IN ITEMS ${ARGN})
        if (IS_ABSOLUTE "${source_files}")
            file(RELATIVE_PATH _source_rel "${CMAKE_CURRENT_SOURCE_DIR}" "${source_files}")
        else()
            set(_source_rel "${source_files}")
        endif()
        get_filename_component(_source_path "${_source_rel}" PATH)
        string(REPLACE "/" "\\" _source_path_msvc "${_source_path}")
        source_group("${_source_path_msvc}" FILES "${source_files}")
    endforeach()
endfunction(assign_source_group)

# Use CMake to find Vulkan SDK.
if (NOT CMAKE_VERSION VERSION_LESS 3.7.0)
    message(STATUS "Using module to find Vulkan")
    find_package(Vulkan)
endif()

# Dependency setup via conan.
# Download conan executer in case it does not exists.
if(NOT EXISTS "${CMAKE_CURRENT_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.14/conan.cmake"
                 "${CMAKE_CURRENT_BINARY_DIR}/conan.cmake")
endif()

# Execute conan build instructions.
include(${CMAKE_CURRENT_BINARY_DIR}/conan.cmake)

conan_cmake_run(CONANFILE conanfile.py
                BASIC_SETUP
                BUILD outdated
                PROFILE default
                PROFILE_AUTO build_type
                KEEP_RPATHS
)

# Use the folder structure in source code directory as project structure in Visual Studio.
assign_source_group(${source_files})

add_executable(inexor-vulkan-renderer src/main.cpp ${source_files})

target_link_libraries(inexor-vulkan-renderer PUBLIC ${Vulkan_LIBS} ${CONAN_LIBS})

# Use C++17!
target_compile_features(inexor-vulkan-renderer PRIVATE cxx_std_17)

IF(WIN32)
    target_compile_definitions(inexor-vulkan-renderer PRIVATE VK_USE_PLATFORM_WIN32_KHR)
ENDIF()

target_include_directories(inexor-vulkan-renderer PRIVATE Vulkan::Vulkan)

target_link_libraries(inexor-vulkan-renderer Vulkan::Vulkan)

When I generate a Visual Studio project file with this setup, I have to add glfw3.lib, spdlogd.lib and fmtd.lib to the project manually. Other repositories like the official Vulkan samples take a more traditional approachand just paste the libs directly into the repo folders. I don't want to do this since I want conan to work for me. I've been trying to fix this problem for 6 months now.

Why does CMake not link the needed libraries although conan can find them?

Thanks you.

  • 1
    Print out all the values inside `${CONAN_LIBS}`. The only reason cmake "isn't able to find them" is likely because for what ever reason, conan isn't actually passing the libs on to cmake. Then it becomes a Conan problem, and not a CMake problem. – Krupip Feb 26 '20 at 22:02
  • Good point. It is actually empty. Maybe I need to switch some option in conanfile.py to share libs to Cmake or something. – Johannes Schneider Feb 26 '20 at 23:10

1 Answers1

5

I found the solution: There is a function called conan_target_link_libraries which must be used instead of target_link_libraries. Thanks for the answer.

  • Yes, it seems that using the ``conan.cmake`` wrapper to call conan has something to do: It is hiding or using some defaults, like using the ``cmake_multi`` generator for Visual Studio and other multi-config systems, that requires this especial way of calling ``conan_target_link_libraries()``. You can see the code of that macro, it is basically a switch between debug and release libraries when necessary. Conan is moving towards ``cmake_find_package`` generators, but this is not the default yet, and definitely not in ``conan.cmake`` wrapper. – drodri Feb 27 '20 at 14:08