如何在使用CMake进行make后将目录内容复制到构建目录中?

106

我的源代码旁边有一些配置文件(xml、ini等),它们存放在config文件夹中。每次构建项目时,我该如何将config文件夹中的所有文件复制到生成目录中(与可执行文件相邻的目录)?

5个回答

182

你可以使用 add_custom_command

如果你的目标叫做MyTarget,那么你可以这样做:

add_custom_command(TARGET MyTarget PRE_BUILD
                   COMMAND ${CMAKE_COMMAND} -E copy_directory
                       ${CMAKE_SOURCE_DIR}/config/ $<TARGET_FILE_DIR:MyTarget>)

每次构建 MyTarget 时都会执行此操作,将 "/config" 的内容复制到目标 exe/lib 将要存放的目录中。

正如Mark Lakata在下面的评论中指出的那样,将 add_custom_command 中的 PRE_BUILD 替换为 POST_BUILD 可以确保只有在构建成功时才会进行复制。

解释

  • ${CMAKE_COMMAND} 是 CMake 的路径
  • -E 使 CMake 运行命令而不是构建
  • copy_directory 是一个命令行工具
  • config 是要复制到构建目标中的(项目根目录下的)目录
  • $<TARGET_FILE_DIR:MyTarget> 是一个生成器表达式,在 add_custom_command 文档中有描述。


1
好的,它起作用了。但是配置文件只有在make clean之后才会被复制。简单的make不会复制配置文件。有什么想法吗? - B Faley
7
POST_BUILD可能是更好的选择,这意味着只有在构建成功后才会复制文件。 - Mark Lakata
7
有没有办法让“make clean”知道在清理项目时必须删除复制的文件? - moonwalker
3
有没有一种方法可以复制整个目录而不是其中的内容? - user796530
1
我有一个目录层次结构,并希望在构建后将整个层次结构复制到其他位置。 使用此命令无法完成。请问您能否给出一些提示/语法?@Fraser - CodeWithVikas
显示剩余8条评论

24

除了最佳答案之外,

如果要复制整个目录而不是其中的内容,您可以在第二个参数的末尾添加/${FOLDER_NAME}

像这样:

add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
                   COMMAND ${CMAKE_COMMAND} -E copy_directory
                       ${CMAKE_SOURCE_DIR}/config $<TARGET_FILE_DIR:${PROJECT_NAME}>/config)

7

6
使用符号链接 [仅限开发者!]
CMake通过create_symlink功能实现符号链接:
add_custom_command(TARGET ${CMAKE_PROJECT_NAME} PRE_BUILD
                   COMMAND ${CMAKE_COMMAND} -E create_symlink
                   ${CMAKE_SOURCE_DIR}/config $<TARGET_FILE_DIR:${PROJECT_NAME}>/config)

它确保当您对目录中的文件进行更改时,构建文件夹将随之更新。
然而,正如@Vallerious指出的那样,这只是一个仅用于开发的解决方案,因为它实际上并没有复制目录内容,而只是链接它们。

1
太喜欢了!谢谢! - frankelot
3
但是,如果你正在构建一个发布版本,符号链接不起作用,因为你还没有将文件放置在正确的位置。你需要解决的问题是在调试和发布之间使用相同的路径,但是在发布时仍需要不同的命令来复制内容。 - Vallerious
正确的“安装”命令可以使这个解决方案不仅适用于开发者。例如,一个包含一些编译的C代码和一些Python文件的Python模块。在编译后的.so文件所在的构建目录中,您可以将其他Python文件的链接放在源目录中。然后,您可以使用install(TARGET compiled_lib ...)install(FILES <python files> ...)命令将Python文件从源目录复制到安装前缀的某个位置。非开发者应始终使用已安装的软件包。 - Philippe Carphin
@PhilippeCarphin 好主意,我会很快扩展这个想法,包括非开发解决方案和install - satk0

-6
在我的项目中,我使用INSTALL来在CMake中指定二进制文件和配置文件的移动位置。在执行cmake后,使用"make install"命令。

有位用户询问如何在构建完成后完成此操作。 暗示是不需要在shell中输入另一个命令。 执行构建,瞬间你二进制文件需要的文件就神奇般地出现了。 我也使用install()命令,但这是一个特殊情况:代码构建成功,通过了单元测试,并准备好供他人使用。 我不会安装它来调试。 - PfunnyGuy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接