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

vsaztqbk  于 2022-11-11  发布在  其他
关注(0)|答案(8)|浏览(273)

我尝试在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})

但没有一个是有效的。
我做错了什么?

h79rfbju

h79rfbju1#

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

configure_file(<input> <output> COPYONLY)

file(COPY ...)不同,它在输入和输出之间创建了文件级依赖关系,即:
如果修改了输入文件,构建系统将重新运行CMake以重新配置文件并再次生成构建系统。

lokaqttq

lokaqttq2#

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

  1. file(COPY ...在配置步骤中复制文件,并且只在此步骤中复制。当您在没有更改cmake配置的情况下重建项目时,将不会执行此命令。
    1.当您希望在每个构建步骤中复制文件时,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之间进行选择,最好阅读add_custom_command的文档
有关如何使用第一个版本的示例,请参见:Use CMake add_custom_command to generate source for another target

ruoxqz4g

ruoxqz4g3#

您尝试的第一个选项不起作用,原因有二。
首先,你忘了关闭括号。
第二,DESTINATION应该是一个目录,而不是文件名。假设你关闭了括号,文件将结束在一个名为input.txt的文件夹中。
要使其正常工作,只需将其更改为

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

azpvetkf4#

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

zzoitvuj5#

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

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

则语法为:

file(COPY pathSource DESTINATION pathDistination)
k5hmc34c

k5hmc34c6#

如果您希望将文件复制到与.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相同的文件中,无论它是调试还是发布。

s6fujrry

s6fujrry7#

这是我用来复制一些资源文件的:copy-files为空目标,可忽略错误

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

brgchamk8#

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

code/
  src/
  example/
  CMakeLists.txt

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

install(DIRECTORY example/ DESTINATION example)

相关问题