【问题标题】:What cmake command will copy a directory of files to a directory in a post build step什么 cmake 命令会将文件目录复制到构建后步骤中的目录
【发布时间】:2021-11-08 21:15:08
【问题描述】:

我有一组资源文件,它们与 GCC 的构建步骤或其他一些编译器的输出无关。我需要将它们从我项目中的文件夹复制到 cmake 构建输出文件夹。目标是可执行文件,当从构建输出文件夹运行时,可以看到资源。

人们通常如何在 cmake 构建中复制和安装资源?此外,无论构建中的更改如何,我都希望它们被复制,并且我希望每次运行某些 cmake 命令时都执行它,例如 build.请参阅下文了解我尝试解决此问题的方法。

例如:

我有一堆要复制的着色器文件。所有 shaders/* 文件都应该复制到构建输出中名为“shaders”的目录中,因为这是程序的可执行文件所在的位置。

file(GLOB out shaders/*)
foreach (o ${out})
    message("${o} was copied to shaders")
    file(COPY ${o} DESTINATION shaders)
endforeach ()

这仅在某些时候有效,例如当我重新加载 CMake 项目时,例如:

/opt/clion-2021.2.3/bin/cmake/linux/bin/cmake \
  -DCMAKE_BUILD_TYPE=Debug -DCMAKE_DEPENDS_USE_COMPILER=FALSE \
  -G "CodeBlocks - Unix Makefiles" \
  /home/hack/glad

此外,它不执行“POST_BUILD”,因此shaders/a.vert 文件的最新版本不会被复制到输出中的 shaders/ 目录。

我也尝试过使用它,但它让我有些头疼:

add_custom_command(TARGET my-executable POST_BUILD
  COMMAND ${CMAKE_COMMAND} -E copy shaders/* shaders)

我认为上面有一些不正确的地方,因为如果构建的代码没有改变,它就不会在每个 POST_BUILD 中运行。我不在乎构建的代码是否不会更改,因为 shaders/* 中的文件可能已经更改并且应该被复制,而不管 cmake 确定 my-executable 中是否有更改。

【问题讨论】:

  • “我不在乎构建的代码是否不会改变,因为 shaders/ 中的文件可能已经改变了”* sharder 文件是在构建过程中生成的吗?在这种情况下,听起来您没有将自定义命令添加到正确的目标。那些只是完全独立于 CMake 项目编辑的文件吗?如果是这种情况,add_custom_target(... ALL ...) 可能就是您正在寻找的,因为这允许您添加一个在默认目标 (all) 构建期间始终构建的目标。

标签: cmake


【解决方案1】:

github 上的这个要点非常有帮助,here 但适用于我的问题的要点包含在下面。

add_custom_target(bar
        COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_BINARY_DIR}/shaders
        COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/shaders ${CMAKE_BINARY_DIR}/shaders
        COMMENT "copying ${CMAKE_SOURCE_DIR}/shaders to ${CMAKE_BINARY_DIR}/shaders"
        WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
        )

上面的代码创建了一个barcmake目标,可以用Make bar单独运行;然后,如果您添加另一个需要这些资源的目标(上面的着色器是其他可执行文件的资源),那么您可以使用 add_dependencies 将依赖项绑定在一起,如下所示:

add_executable(a
        main.c
        opengl.c)
add_dependencies(a bar)

现在,每次运行a目标,同时运行bar目标,起到创建目录和复制文件的作用。

这对我来说已经足够好了,但要完成,您可以在其他依赖项完成运行后使用它在构建后步骤中创建文件:

add_custom_command(TARGET bar
    # Run after all other rules within the target have been executed
    POST_BUILD
    COMMAND echo "executing a POST_BUILD command"
    COMMENT "This command will be executed after building bar"
    VERBATIM
)

请注意,上述add_custom_command 示例中的${CMAKE_COMMAND} 是指向cmake 可执行文件的变量,您可以运行cmake -E 以查看非常有用的cmake 附带的命令列表。

YIKES 后构建步骤仅在 bar 的目标构建后运行,而不是 a 的目标。希望有人可以帮助我更好地回答这个问题。我仍然想知道如何在构建目标后复制文件,除非这完全没有必要并且没有人愿意这样做。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-11-05
    • 2012-04-17
    • 1970-01-01
    • 1970-01-01
    • 2016-12-14
    • 2016-04-20
    • 1970-01-01
    相关资源
    最近更新 更多