给你的library定义一个带"IMPORTED" 属性的target,同时需要并为此定义lib和dll路径属性,需要区分debug和release。
add_library(sdl2 SHARED IMPORTED GLOBAL)
set_property(TARGET sdl2 PROPERTY IMPORTED_IMPLIB_RELEASE "${SDL_ROOT_PATH}/lib/SDL2.lib")
set_property(TARGET sdl2 PROPERTY IMPORTED_LOCATION_RELEASE "${SDL_ROOT_PATH}/bin/SDL2.dll")
set_property(TARGET sdl2 PROPERTY IMPORTED_IMPLIB_DEBUG "${SDL_ROOT_PATH}/lib/SDL2d.lib")
set_property(TARGET sdl2 PROPERTY IMPORTED_LOCATION_DEBUG "${SDL_ROOT_PATH}/bin/SDL2d.dll")
链接此库用上面定义target的名字即可,这样会自动隐藏背后的不同版本的lib库文件。
target_link_libraries(YourProg sdl2 ...)
在CMakeLists.txt定义一个定制的build step来自动拷贝运行所需的dll文件:
add_custom_command (TARGET YourProg POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
$<TARGET_FILE:sdl2> $<TARGET_FILE_DIR:YourProg>
)
通常,当你的项目集成了很多第三方库,以上这么干会把CMakeLists.txt搞得很复杂,因此推荐得方式还是得写FindXXX.cmake, 并在FindXXX.cmake里创建对应的target,关于如何写可以参考这篇文章。
特殊情况
有些第三方库提供已编译好的库文件且是多个,这时候上面的target不再能拷贝dll,而且会报错unknwon target,对于这种第三方库的target得如下定义:
add_library(ffmpeg INTERFACE IMPORTED)
set_target_properties(ffmpeg PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${ffmpeg_INCLUDE_DIRS}"
INTERFACE_LINK_LIBRARIES "${ffmpeg_LIBRARIES}"
IMPORTED_LOCATION "${ffmpeg_LIBRARY_DLLS}")
拷贝DLL文件的command得改成如下方式:
get_target_property(DLLS ffmpeg IMPORTED_LOCATION)
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
${DLLS} $<TARGET_FILE_DIR:${PROJECT_NAME}>)
${DLLS} 即对应所有dll文件路径总和。
其实,Qt打包时候拷贝DLL也是同样这个做法:
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
$<TARGET_FILE:Qt5::Core> $<TARGET_FILE_DIR:${PROJECT_NAME}>
$<TARGET_FILE:Qt5::Widgets> $<TARGET_FILE_DIR:${PROJECT_NAME}
... etc ...
)
网友评论