将资产目录从源复制到在CMAKE中构建目录

Copying assets directory from source to build directory in CMake

本文关键字:CMAKE 构建 复制      更新时间:2023-10-16

我正在尝试在C 中写游戏。我正在使用CMAKE,并且我的项目由我的IDE自动构建在单独的构建目录中。但是,我的 assets文件夹是不是被复制到新目录。

目前,我正在尝试以以下方式解决此问题:

add_custom_command(TARGET ${PROJECT_NAME}
    POST_BUILD
    COMMAND cp -r ${PROJECT_SOURCE_DIR}/assets ${CMAKE_BINARY_DIR}
    )

但是,这似乎对结果绝对没有影响,并且资产目录仍然不存在于我的构建目录中。

我如何真正使它复制此资产目录到我的构建位置?是否有一种更聪明的方法将我的程序指向我的资产位置(也许也可以与资产一起使用/usr/share的资产?)

在更多的搜索之后,我设法找到了 file(COPY {files} DESTINATION {directory})命令:

file(COPY assets DESTINATION ${CMAKE_BINARY_DIR})

我发现的两种方式,都确保它在目标构建上复制并保持最新状态,即使目标不需要重建。


第一个使用CMAKE命令行工具copy_directory。从文档中尚不清楚该副本是否总是发生,无论assets目录中的文件是否已更新,或者仅在资产文件不存在或更新资产文件时才复制:

add_custom_target(copy_assets
    COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_LIST_DIR}/assets ${CMAKE_CURRENT_BINARY_DIR}/assets
)
add_dependencies(mytarget copy_assets)

第二个需要一个小的额外的cmake脚本文件,但它允许我们使用 file(COPY ...) cmake comamnd,该文件在文档中指出"复制保留postist opture putput input文件时间戳相同的时间戳。&quot&quot

首先,在与您的CMakeLists.txt相同的目录中创建CMAKE脚本文件copy-assets.cmake,其中内容为(类似于Ethan Mctague的答案)

file(COPY ${CMAKE_CURRENT_LIST_DIR}/assets DESTINATION ${CMAKE_CURRENT_BINARY_DIR})

然后在您的CMakeLists.txt中,添加以下内容:

add_custom_target(copy_assets
    COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_LIST_DIR}/copy-assets.cmake
)
add_dependencies(mytarget copy_assets)

上面使用add_custom_target的解决方案适用于大多数情况,但有一些问题。

  • 不支持依赖的生成器表达式(例如$&&< target_file_dir:tgt>)
  • 重复每个构建(众多/大文件的缓慢)
  • 不是特别可读,尤其是从多个位置复制

而是,我一直在使用文件生成

set(ASSETS
    assetfile
    ...)
foreach(ASSET ${ASSETS})
    file(GENERATE OUTPUT ${ASSET} INPUT ${ASSET})
endforeach()

注意我还不需要发电机表达式,但是看起来最新版本的Cmake(3.19)将Generator Expression添加到此功能中。

这是我对Vulkan着色器的作用。只需用复制命令替换汇编步骤:

macro(add_shaders)
    cmake_parse_arguments("MY" "TARGET" "SOURCES" ${ARGN})
    foreach(src ${MY_SOURCES})
        set(OUTF "${CMAKE_CURRENT_BINARY_DIR}/shaders/${src}.spv")
        get_filename_component(PARENT_DIR "${OUTF}" DIRECTORY)
        add_custom_command(
            OUTPUT "${OUTF}"
            COMMAND ${CMAKE_COMMAND} -E make_directory "${PARENT_DIR}"
            COMMAND "${Vulkan_GLSLC_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/${src}" -o "${OUTF}"
            DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/${src}"
            VERBATIM
        )
        # src in order to get listed in the IDE, OUTF to declare the build relationship
        target_sources("${MY_TARGET}" PRIVATE "${src}" "${OUTF}")
    endforeach()
endmacro()
add_shaders(TARGET my_target SOURCES asset1 asset2 asset3 ...)

您必须自行指定每个资产(或列表上的循环)。将通配符包括在构建中是一个坏主意[TM]。这也将仅在更改时复制/处理内容。