问题描述
我正在寻找一种使用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()
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)