CMake:获取由柯南安装的软件包的共享库的路径列表用于部署依赖项

问题描述

我正在寻找一种使用CMake构建项目时部署依赖项的方法

柯南提供了一种通过[imports]中的conanfile.txt命令部署已安装依赖关系的二进制文件方法。但这会将所有依赖项复制到一个指定的路径。此外,该文件也不是CMake脚本的一部分。

我希望能够将不同目标的不同依赖项部署到其相应路径。例如,当我有多层CMake项目并且一些目标被编译到不同的位置时。我想在CMake脚本中执行此操作。

通过cmake部署共享库的理想情况是使用目标的属性。例如,目标可以提供IMPORTED_LOCATION属性,以后可以通过从$<TARGET_FILE:TARGET>获取来使用该属性。一旦提供了库二进制文件的完整路径,就可以将二进制文件复制到特定可执行文件的位置:

COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:SDL2> $<TARGET_FILE_DIR:MyExe>

柯南提供了wrapper来安装依赖项,该依赖项可以生成格式为CONAN_PKG::PkgName的目标。但是,在这些目标中未提供二进制库路径的确定列表,因此无法轻松获取所需的依赖项列表以通过CMake命令进行复制。

但是它确实提供了二进制文件的路径以及每个软件包的库列表。因此,我尝试编写一个函数,该函数可以从程序包名称生成二进制文件的完整路径列表。但是我目前还没有成功。

例如,安装SDL2依赖项将在conanbuildinfo.cmake生成此类内容。 对于在调试中的MinGW:

set(CONAN_SDL2_ROOT "C:/Users/Sergey/.conan/data/sdl2/2.0.12/bincrafters/stable/package/39ad275b86c11dca14b78d338f6262dd99e17fbd")
set(CONAN_INCLUDE_Dirs_SDL2 "C:/Users/Sergey/.conan/data/sdl2/2.0.12/bincrafters/stable/package/39ad275b86c11dca14b78d338f6262dd99e17fbd/include"
            "C:/Users/Sergey/.conan/data/sdl2/2.0.12/bincrafters/stable/package/39ad275b86c11dca14b78d338f6262dd99e17fbd/include/SDL2")
set(CONAN_LIB_Dirs_SDL2 "C:/Users/Sergey/.conan/data/sdl2/2.0.12/bincrafters/stable/package/39ad275b86c11dca14b78d338f6262dd99e17fbd/lib")
set(CONAN_BIN_Dirs_SDL2 "C:/Users/Sergey/.conan/data/sdl2/2.0.12/bincrafters/stable/package/39ad275b86c11dca14b78d338f6262dd99e17fbd/bin")
set(CONAN_RES_Dirs_SDL2 )
set(CONAN_SRC_Dirs_SDL2 )
set(CONAN_BUILD_Dirs_SDL2 "C:/Users/Sergey/.conan/data/sdl2/2.0.12/bincrafters/stable/package/39ad275b86c11dca14b78d338f6262dd99e17fbd/")
set(CONAN_FRAMEWORK_Dirs_SDL2 )
set(CONAN_LIBS_SDL2 SDL2maind SDL2d.dll)
set(CONAN_PKG_LIBS_SDL2 SDL2maind SDL2d.dll)
set(CONAN_SYstem_LIBS_SDL2 user32 gdi32 winmm imm32 ole32 oleaut32 version uuid advapi32 setupapi shell32 mingw32)

对于MSVC发行版:

set(CONAN_SDL2_ROOT "C:/Users/Sergey/.conan/data/sdl2/2.0.12/bincrafters/stable/package/7ac203a706641e5bebde26147d215ae29c8bc37f")
set(CONAN_INCLUDE_Dirs_SDL2 "C:/Users/Sergey/.conan/data/sdl2/2.0.12/bincrafters/stable/package/7ac203a706641e5bebde26147d215ae29c8bc37f/include"
            "C:/Users/Sergey/.conan/data/sdl2/2.0.12/bincrafters/stable/package/7ac203a706641e5bebde26147d215ae29c8bc37f/include/SDL2")
set(CONAN_LIB_Dirs_SDL2 "C:/Users/Sergey/.conan/data/sdl2/2.0.12/bincrafters/stable/package/7ac203a706641e5bebde26147d215ae29c8bc37f/lib")
set(CONAN_BIN_Dirs_SDL2 "C:/Users/Sergey/.conan/data/sdl2/2.0.12/bincrafters/stable/package/7ac203a706641e5bebde26147d215ae29c8bc37f/bin")
set(CONAN_RES_Dirs_SDL2 )
set(CONAN_SRC_Dirs_SDL2 )
set(CONAN_BUILD_Dirs_SDL2 "C:/Users/Sergey/.conan/data/sdl2/2.0.12/bincrafters/stable/package/7ac203a706641e5bebde26147d215ae29c8bc37f/")
set(CONAN_FRAMEWORK_Dirs_SDL2 )
set(CONAN_LIBS_SDL2 SDL2maind SDL2d)
set(CONAN_PKG_LIBS_SDL2 SDL2maind SDL2d)
set(CONAN_SYstem_LIBS_SDL2 user32 gdi32 winmm imm32 ole32 oleaut32 version uuid advapi32 setupapi shell32)

请注意二进制文件名称不同。 我的逻辑是遍历CONAN_PKG_LIBS_SDL2中的名称并在CONAN_BIN_Dirs_SDL2搜索它们。如果有一个具有这样名称文件,则意味着它是一个二进制文件,需要部署。

这是我的脚本,不起作用:

function(conan_get_pkg_libs PKG_NAME OUT_LIBS)
    set(BIN_DIR ${CONAN_BIN_Dirs_${PKG_NAME}})
    foreach(lib_name ${CONAN_PKG_LIBS_${PKG_NAME}})
        find_file(found_lib NAMES ${lib_name} PATHS ${BIN_DIR} NO_DEFAULT_PATH)
        if (${found_lib})
            list(APPEND OUT_LIBS ${found_lib})
        endif()
    endforeach()
endfunction()

该脚本无法找到文件,或者找不到具有该名称的目录,或者找不到另一个文件

这是我的CMakeLists.txt

cmake_minimum_required(VERSION 3.7 FATAL_ERROR)

project(sdl_conan LANGUAGES CXX)

function(conan_get_pkg_libs PKG_NAME OUT_LIBS)
    set(BIN_DIR ${CONAN_BIN_Dirs_${PKG_NAME}})

    foreach(lib_name ${CONAN_PKG_LIBS_${PKG_NAME}})
        find_file(found_lib NAMES ${lib_name} PATHS ${BIN_DIR} NO_DEFAULT_PATH)
        if (${found_lib})
            list(APPEND OUT_LIBS ${found_lib})
        endif()
    endforeach()
endfunction()

list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/cmake)
include(cmake/conan.cmake)

conan_add_remote(NAME bincrafters
        URL https://api.bintray.com/conan/bincrafters/public-conan)

conan_cmake_run(REQUIRES sdl2/2.0.12@bincrafters/stable
        OPTIONS sdl2:shared=True
        BASIC_SETUP
        CMAKE_TARGETS
        BUILD missing)

conan_get_pkg_libs(SDL2 SDL2_LIBS)

add_executable(app main.cpp)
target_link_libraries(app CONAN_PKG::sdl2)

foreach(lib SDL2_LIBS)
    add_custom_command(TARGET app PRE_LINK
            COMMAND ${CMAKE_COMMAND} -E copy_if_different ${lib} $<TARGET_FILE_DIR:app>
            )
endforeach()

  1. 如何使我的功能正常工作?
  2. 有什么方法可以改善它吗?
  3. 鉴于我想实现的目标,还有其他更好的方法吗?

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)