Как лучше обрабатывать файлы данных с помощью CMake?

У меня есть проект CMake, содержащий код и несколько файлов данных (изображения, если быть точным).

Моя структура каталогов такова:

  • ЦСИ
  • данные

src содержит исходный код, данные - файлы данных. CMake предлагает исходные сборки, поэтому, когда я вызываю make, у меня есть исполняемая программа, но не файлы данных, поэтому я не могу выполнить программу.

Конечно, make install будет скопировать мои файлы данных в нужное место и заставить его работать, поэтому я сейчас так развиваюсь:

  • cmake -DCMAKE_INSTALL_DIR = dist
  • <edit source code>
  • make install
  • расстояние /myprogram.exe

Это нормально, если я работаю с командной строкой и редактором, но недавно решил переехать в Eclipse CDT. Создание проекта Eclipse из CMake отлично работает, но вручную выполнить задачу установки из Eclipse не так приятно.

Как вы решаете эту проблему? У вашей программы есть некоторые умные алгоритмы, чтобы попытаться найти свой каталог данных, даже если он не там, где находится двоичный файл? Или вы не используете исходные сборки?

Ответ 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})

Ответ 2

И если копирование файлов занимает слишком много времени (это изображения...), вы можете сделать это еще лучше, создав "custom" data_header.h с помощью файла configure_file, который содержит пути к данным, все еще находящимся в вашем исходном каталоге.

Это то, что я делаю: у меня есть файл "global_build_config.h.in" в моем источнике, содержащий следующее:

const char* const global_testdatapath = "@[email protected]";

а затем используйте файл configure_file в CMake:

# 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/ )

Затем я могу # включить "Global_Build_Config.h" в свои файлы cpp и ссылаться на фиксированный путь.

Ответ 3

Ваш вопрос немного устарел, но в случае, если вы все еще заинтересованы (или кто-то еще), у меня есть аналогичный сценарий, где я копирую testdata для целевого объекта unit-test:

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 это не сложно сделать, если вам нужно.