Answers:
我会add_custom_command
用来实现这一点cmake -E copy_if_different...
。有关完整的信息运行
cmake --help-command add_custom_command
cmake -E
因此,就您而言,如果您具有以下目录结构:
/CMakeLists.txt
/src
/libs/test.dll
并且命令适用的CMake目标是MyTest
,则可以将以下内容添加到CMakeLists.txt:
add_custom_command(TARGET MyTest POST_BUILD # Adds a post-build event to MyTest
COMMAND ${CMAKE_COMMAND} -E copy_if_different # which executes "cmake - E copy_if_different..."
"${PROJECT_SOURCE_DIR}/libs/test.dll" # <--this is in-file
$<TARGET_FILE_DIR:MyTest>) # <--this is out-file path
如果只想/libs/
复制目录的全部内容,请使用cmake -E copy_directory
:
add_custom_command(TARGET MyTest POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_directory
"${PROJECT_SOURCE_DIR}/libs"
$<TARGET_FILE_DIR:MyTest>)
如果您需要根据配置(例如发布,调试)复制不同的dll,则可以将它们放在以相应配置命名的子目录中:/libs/Release
和/libs/Debug
。然后,您需要将配置类型注入到add_custom_command
调用中dll的路径中,如下所示:
add_custom_command(TARGET MyTest POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_directory
"${PROJECT_SOURCE_DIR}/libs/$<CONFIGURATION>"
$<TARGET_FILE_DIR:MyTest>)
install()
指令的目标不是汇编二进制文件吗?还是cmake LIBRARY
东西?我真的不知道工具链。
$<TARGET_FILE_DIR:MyTest>
- 它是什么?如何打印信息,这是什么意思
IMPORTED_LIBRARIES
。它抱怨说什么也没建好就不能运行后建命令。
IMPORTED
库,并且需要重新定位DLL,则需要使用一个变体命令。如果您已经添加了使用IMPORTED
库,MyImportedLib
请COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:MyImportedLib> $<TARGET_FILE_DIR:MyTest>
注意,要运行多个后期构建命令,您需要将它们全部绑定到一个自定义命令中,例如add_custom_command(TARGET MyTest POST_BUILD COMMAND #your first command# COMMAND #Your second command#)
今天,当我尝试制作程序的Windows版本时遇到了这个问题。我最终自己做了一些研究,因为所有这些答案都使我不满意。存在三个主要问题:
我希望调试版本与库的调试版本链接,发行版本与库的发行版本链接。
除此之外,我希望将正确版本的DLL文件(调试/发布)复制到输出目录。
我想在不编写复杂而脆弱的脚本的情况下实现所有这些目标。
在github上浏览了一些CMake手册和一些多平台项目之后,我找到了这个解决方案:
使用“导入”属性将您的库声明为目标,引用其调试并释放.lib和.dll文件。
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_link_libraries(YourProg sdl2 ...)
如果自上次构建以来已对其进行了更改,请进行自定义构建步骤以将dll文件复制到其目标位置
add_custom_command ( TARGET YourProg POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
$<TARGET_FILE:sdl2> $<TARGET_FILE_DIR:YourProg>
)
接受的答案的附录,作为单独的答案添加,因此我得到了代码格式:
如果要在同一项目中构建dll,则它们通常位于Release,Debug等目录中。您必须使用Visual Studio环境变量来正确地复制它们。例如:
"${PROJECT_BINARY_DIR}/your_library/\$\(Configuration\)/your_library.dll"
对于源和
"${CMAKE_CURRENT_BINARY_DIR}/\$\(Configuration\)/your_library.dll"
为目的地。注意转义!
您不能将CMake CMAKE_BUILD_TYPE变量用于配置,因为它是在VS项目生成时解析的,并且始终是默认值。
$<CONFIGURATION>
我是CMake的初学者,但我仍然想分享自己的经验。就我而言,我需要安装后的副本,以便所有二进制文件都可以放入。对于可以在CMake中导入的第三方二进制文件,以下对我有用:
find_package( dependency REQUIRED )
if( MSVC )
# If done properly and if the dependency has a correct config file, IMPORTED_LOCATION_RELEASE should be defined
get_target_property( DEP_SHARED_LIB_PATH dependency IMPORTED_LOCATION_RELEASE )
# Create a bin directory in the install folder
add_custom_command(TARGET BGS POST_BUILD COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_INSTALL_PREFIX}/bin/)
# Copy the shared lib file
add_custom_command(TARGET BGS POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy ${DEP_SHARED_LIB_PATH} ${CMAKE_INSTALL_PREFIX}/bin/)
endif()
显然,IMPORTED_LOCATION_RELEASE可以具有变体,具体取决于构建/安装共享库的方式。可能是IMPORTED_LOCATION_DEBUG。
我不知道,也许有一种更好的方法来获取该属性名称。
install
我在尝试按照步骤9的CMake官方教程进行操作时遇到了这个问题。这是我要移动的文件的位置:
src
|_build
|_Debug
- `MathFunctions.dll`
这是我希望文件所在的位置:
src
|_build
|_install
|_bin
- `MathFunctions.dll`
由于此DLL是作为共享库生成的,所以我要做的就是将此行包含在包含该库源代码CMakeLists.txt
的子目录中src/Mathfunctions/CMakeLists.txt
install(FILES ${PROJECT_BINARY_DIR}/$<CONFIG>/MathFunctions.dll
DESTINATION bin)
感谢您的回答,我可以考虑这一点。只是一行而已,所以我认为还可以。将$<CONFIG>
有两个值调试或发布根据项目是如何建成的要求,原来的问题。
${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/$<CONFIG>
目标位置。否则它将复制到库构建路径,这是没有用的。