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

时间:2016-01-14 21:17:49

标签: cmake

我正在尝试在CLion上创建一个简单的项目。它使用CMake(我是新来的)生成Makefile来构建项目(或某种类型)

每次运行我的代码时,我只需要将一些非项目文件(某种资源文件)传输到二进制目录。

该文件包含测试数据,应用程序将其打开以读取它们。我尝试了几种方法:

  • 通过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

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

    但没有一个有效。

我做错了什么?

8 个答案:

答案 0 :(得分:88)

您可以考虑将configure_fileCOPYONLY选项一起使用:

configure_file(<input> <output> COPYONLY)

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

  

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

答案 1 :(得分:41)

这两个选项都有效,并定位了您构建的两个不同步骤:

  1. file(COPY ...在配置步骤中复制文件,仅在此步骤中复制。在未更改cmake配置的情况下重建项目时,将不会执行此命令。
  2. 如果要在每个构建步骤中复制文件,
  3. add_custom_command是首选。
  4. 您的任务的正确版本将是:

    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 最好是阅读add_custom_command

    的文档

    可以在此处找到有关如何使用第一个版本的示例:Use CMake add_custom_command to generate source for another target

答案 2 :(得分:8)

您尝试过的第一个选项并非有效,原因有两个。

首先,您忘记关闭括号。

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

要使其正常工作,只需将其更改为

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

答案 3 :(得分:1)

如果要将文件夹从醋栗目录复制到二进制(构建文件夹)文件夹

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

然后该syntexe是:

file(COPY pathSource DESTINATION pathDistination)

答案 4 :(得分:0)

建议的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)

答案 5 :(得分:0)

如果要将该文件复制到.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相同的文件中。

答案 6 :(得分:0)

这是我用来复制一些资源文件的内容: 复制文件是忽略错误的空目标

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

答案 7 :(得分:0)

如果要在构建后将example的内容放入install文件夹中:

code/
  src/
  example/
  CMakeLists.txt

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

install(DIRECTORY example/ DESTINATION example)