Как лучше обрабатывать файлы данных с помощью 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 это не сложно сделать, если вам нужно.