【问题标题】:How to best handle data files with CMake?如何使用 CMake 最好地处理数据文件?
【发布时间】:2010-08-07 16:24:07
【问题描述】:

我有一个 CMake 项目,其中包含代码和一些数据文件(准确地说是图像)。

我的目录结构是这样的:

  • 源代码
  • 数据

src 包含源代码、数据数据文件。 CMake 建议使用源代码构建,所以当我调用 make 时,我有可执行程序,但没有数据文件,因此我无法执行该程序。

当然,make install会将我的数据文件复制到所需的位置并使其工作,因此我现在这样开发:

  1. cmake -DCMAKE_INSTALL_DIR=dist
  2. <edit source code>
  3. 进行安装
  4. dist/myprogram.exe

如果我正在使用命令行和编辑器,那没关系,但我最近决定转向 Eclipse CDT。从 CMake 生成 Eclipse 项目效果很好,但是从 Eclipse 手动执行 install 目标就不是很好了。

你们是如何解决这个问题的?你的程序是否有一些聪明的算法来尝试找到它的数据目录,即使它不在二进制文件所在的位置?或者你不使用源外构建?

【问题讨论】:

标签: cmake eclipse-cdt


【解决方案1】:

configure_file 应该可以解决这个问题。

我的数据目录中有一个 CMakeLists.txt 文件,其中包含以下内容:

configure_file(data_file ${CMAKE_CURRENT_BINARY_DIR}/data_file COPYONLY)

这会在调用 cmake 时将指定的文件复制到构建目录中,因此即使在源代码之外的构建中,它也可以在同一位置使用。

configure_file 不支持目录,但是 file 命令支持:

file(COPY assets DESTINATION ${CMAKE_CURRENT_BINARY_DIR})

【讨论】:

  • 我必须为每个文件分别做吗
  • 我用file(COPY assets DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
【解决方案2】:

如果复制文件花费了太多时间(它们是图像......),您可以通过使用 configure_file 创建一个“自定义”data_header.h 来做得更好,其中包含仍在源目录中的数据路径.

这就是我所做的:我的源代码中有一个文件“global_build_config.h.in”,其中包含以下内容:

const char* const global_testdatapath = "@Test_Data_Path@";

然后在 CMake 中使用 configure_file:

# Assume CMake knows a variable Test_Data_Path, it will be filled in automatically
# in the generated config/Global_Build_Config.h
configure_file( Global_Build_Config.h.in ${CMAKE_BINARY_DIR}/config/Global_Build_Config.h )
# The config directory should be added as a include-searchpath
include_directories( ${CMAKE_BINARY_DIR}/config/ )

然后我可以在我的 cpp 文件中 #include "Global_Build_Config.h" 并引用固定路径。

【讨论】:

  • 你应该知道这会使项目的打包变得更加复杂,因为对于一个包构建,cmake 必须再次执行,更不用说你必须编写的 extre cmake 代码了。
【解决方案3】:

你的问题有点老了,但如果你仍然感兴趣(或其他人),我有一个类似的场景,我为单元测试目标复制测试数据:

add_custom_command( TARGET ${UTEST_EXE_NAME}
    POST_BUILD
    COMMAND ${CMAKE_COMMAND} -E echo "Copying unit test data.."
    COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_HOME_DIRECTORY}/utest/testdata ${CMAKE_BINARY_DIR}
    )

所以主要思想是使用构建后目标,并且在每次构建之后执行。对我来说,它的数据不多,文件系统缓存了它,所以我完全感觉不到复制过程。您可能可以通过使用 copy_if_different 进行复制来增强这一点。但是,在这种情况下,您必须创建一个图像文件列表并编写一个循环,因为该命令是基于文件的。使用 GLOB 命令,如果需要,这应该不难做到。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-10-01
    • 2020-10-03
    • 1970-01-01
    • 1970-01-01
    • 2016-10-14
    • 2013-06-13
    • 2014-01-28
    • 1970-01-01
    相关资源
    最近更新 更多