问题 CMake:添加自定义资源来构建目录


我正在制作一个小程序,需要运行图像文件foo.bmp
所以我可以编译程序,但要运行它,我必须手动将foo.bmp复制到'build'子目录

我应该在CMakeLists.txt中使用什么命令在程序编译时自动将foo.bmp添加到build子目录?


5720
2018-06-10 07:05


起源



答案:


为此,您应该使用add_custom_command为构建目录中所需的文件生成构建规则。然后将目标中的依赖项添加到这些文件中:如果目标需要,CMake只构建一些东西。

如果不是从源目录构建,还应确保仅复制文件。

像这样的东西:

project(foo)

cmake_minimum_required(VERSION 2.8)

# we don't want to copy if we're building in the source dir
if (NOT CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_CURRENT_BINARY_DIR)

    # list of files for which we add a copy rule
    set(data_SHADOW yourimg.png)

    foreach(item IN LISTS data_SHADOW)
        message(STATUS ${item})
        add_custom_command(
            OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${item}"
            COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_CURRENT_SOURCE_DIR}/${item}" "${CMAKE_CURRENT_BINARY_DIR}/${item}"
            DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/${item}"
        )
    endforeach()
endif()

# files are only copied if a target depends on them
add_custom_target(data-target ALL DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/yourimg.png")

在这种情况下,我使用“ALL”自定义目标,依赖于yourimg.png文件来强制复制,但您也可以添加来自其中一个现有目标的依赖项。


9
2018-06-10 09:36



add_custom_target行做了什么。我试图修改你的代码,并包括add_custom_target行的foreach循环,但是在多个文件上失败 - Archit
是的,我猜你有依赖关系的问题...正如我所说,只建立了目标所需的文件。因此,如果您的图像没有任何目标,则不会构建它们。这就是我在我的例子中添加“add_custom_target”的原因。顺便说一下,更好的规则可能是 add_custom_target(data-target ALL DEPENDS ${data_SHADOW}) 所以它总是取决于所有图像。 - Guillaume


答案:


为此,您应该使用add_custom_command为构建目录中所需的文件生成构建规则。然后将目标中的依赖项添加到这些文件中:如果目标需要,CMake只构建一些东西。

如果不是从源目录构建,还应确保仅复制文件。

像这样的东西:

project(foo)

cmake_minimum_required(VERSION 2.8)

# we don't want to copy if we're building in the source dir
if (NOT CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_CURRENT_BINARY_DIR)

    # list of files for which we add a copy rule
    set(data_SHADOW yourimg.png)

    foreach(item IN LISTS data_SHADOW)
        message(STATUS ${item})
        add_custom_command(
            OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${item}"
            COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_CURRENT_SOURCE_DIR}/${item}" "${CMAKE_CURRENT_BINARY_DIR}/${item}"
            DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/${item}"
        )
    endforeach()
endif()

# files are only copied if a target depends on them
add_custom_target(data-target ALL DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/yourimg.png")

在这种情况下,我使用“ALL”自定义目标,依赖于yourimg.png文件来强制复制,但您也可以添加来自其中一个现有目标的依赖项。


9
2018-06-10 09:36



add_custom_target行做了什么。我试图修改你的代码,并包括add_custom_target行的foreach循环,但是在多个文件上失败 - Archit
是的,我猜你有依赖关系的问题...正如我所说,只建立了目标所需的文件。因此,如果您的图像没有任何目标,则不会构建它们。这就是我在我的例子中添加“add_custom_target”的原因。顺便说一下,更好的规则可能是 add_custom_target(data-target ALL DEPENDS ${data_SHADOW}) 所以它总是取决于所有图像。 - Guillaume


如果这可能有帮助,我尝试使用file命令的另一个解决方案。有一个选项COPY只是将文件或目录从源复制到dest。

喜欢这个: FILE(COPY yourImg.png DESTINATION "${CMAKE_BINARY_DIR}")

相对路径也适用于目的地(例如,您可以简单地使用。)

文件参考: https://cmake.org/cmake/help/v3.0/command/file.html


2
2017-08-22 03:38