使用 CMake 将文件从源目录复制到二进制目录

我试图创建一个关于 CLion 的简单项目。它使用 CMake (我在这里是新手)生成 Makefiles 来构建项目(或某种类型的项目)

所有我需要的是传输一些非项目文件(某种资源文件)到二进制目录每次当我运行我的代码。

该文件包含测试数据和应用程序打开它来读取它们。我尝试了几种方法来做到这一点:

  • 通过 file(COPY ...

    file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/input.txt
    DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/input.txt
    

    看起来不错,但它的工作只有一次,不复制文件后下一次运行。

  • 通过 add_custom_command

    • OUTPUT版本

      add_custom_command(
      OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/input.txt
      COMMAND ${CMAKE_COMMAND} -E copy
      ${CMAKE_CURRENT_SOURCE_DIR}/input.txt
      ${CMAKE_CURRENT_BINARY_DIR}/input.txt)
      
    • TARGET version

      add_custom_target(foo)
      add_custom_command(
      TARGET foo
      COMMAND ${CMAKE_COMMAND} copy
      ${CMAKE_CURRENT_BINARY_DIR}/test/input.txt
      ${CMAKE_SOURCE_DIR})
      

    But no one of it work.

What am I doing wrong?

175600 次浏览

这两个选项都是有效的,并且针对构建的两个不同步骤:

  1. file(COPY ...在配置步骤中复制该文件,并且仅在此步骤中复制该文件。如果在没有更改 cmake 配置的情况下重新生成项目,则不会执行此命令。
  2. 当您希望在每个构建步骤中复制文件时,首选 add_custom_command

对你的任务来说,正确的版本应该是:

add_custom_command(
TARGET foo POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy
${CMAKE_SOURCE_DIR}/test/input.txt
${CMAKE_CURRENT_BINARY_DIR}/input.txt)

你可以在 PRE_BUILDPRE_LINKPOST_BUILD之间选择 最好是阅读 < a href = “ https://cmak.org/cmake/help/update/command/add _ custom_ command.html”rel = “ norefrer”> add _ custom_ command 的文档

关于如何使用第一个版本的示例可以在这里找到: 使用 CMake add _ custom_ command 为另一个目标生成源

您可以考虑使用 Configure _ fileCOPYONLY选项:

configure_file(<input> <output> COPYONLY)

file(COPY ...)不同,它在输入和输出之间创建一个文件级依赖项,即:

如果修改了输入文件,则生成系统将重新运行 CMake 以重新配置文件并再次生成生成系统。

你尝试的第一个选项不起作用有两个原因。

首先,您忘记关闭括号。

其次,DESTINATION应该是一个目录,而不是一个文件名。假设您关闭了括号,那么文件最终将位于一个名为 input.txt的文件夹中。

为了让它工作,只要改变它

file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/input.txt
DESTINATION ${CMAKE_CURRENT_BINARY_DIR})

建议的 configure _ file 可能是最简单的解决方案。但是,如果手动从生成目录中删除文件,则不会重新运行 copy 命令。为了处理这个案子,以下几点对我很有用:

add_custom_target(copy-test-makefile ALL DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/input.txt)
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/input.txt
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/input.txt
${CMAKE_CURRENT_BINARY_DIR}/input.txt
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/input.txt)

如果您希望将文件复制到与.exe 文件相同的文件夹,我建议使用 TARGET_FILE_DIR

$ 主文件目录(. exe,. so. 1.2,. a)。

add_custom_command(
TARGET ${PROJECT_NAME} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy
${CMAKE_CURRENT_SOURCE_DIR}/input.txt
$<TARGET_FILE_DIR:${PROJECT_NAME}>)

在 VS 中,这个 cmake 脚本会将 input.txt 复制到与您的最终 exe 相同的文件中,无论是调试还是发布。

如果要将文件夹从当前目录复制到二进制(生成文件夹)文件夹

file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/yourFolder/ DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/yourFolder/)

那么语法就是:

file(COPY pathSource DESTINATION pathDistination)

这就是我用来复制一些资源文件的方法: 复制文件是一个空目标,用于忽略错误

 add_custom_target(copy-files ALL
COMMAND ${CMAKE_COMMAND} -E copy_directory
${CMAKE_BINARY_DIR}/SOURCEDIRECTORY
${CMAKE_BINARY_DIR}/DESTINATIONDIRECTORY
)

如果你想把内容的 exampleinstall文件夹后生成:

code/
src/
example/
CMakeLists.txt

尝试将以下内容添加到你的 CMakeLists.txt:

install(DIRECTORY example/ DESTINATION example)