Подтвердить что ты не робот

Zip файлы с помощью CMake?

tl; dr версия: возможно ли с помощью CMake ( >= 2.8) генерировать zip файлы из некоторых файлов и помещать упакованный zip файл в определенное место?

более длинная версия: У меня есть CMakeLists.txt, который создает мой проект в .exe файле. И этот exe файл будет читать данные из zip файла. Теперь это то, что содержимое, которое должно быть упаковано в zip файл, находится в моем репозитории git, чтобы его можно было отредактировать. Но программа нуждается в этих данных в zip файле. Поэтому было бы хорошо, если cmake script мог бы взять данные, поместить их в zip файл и поместить его рядом с exe. Я уже слышал о CPack, но я не нашел простых примеров и не уверен, что это даже правильный инструмент для моей задачи.

Возможно ли это? Если да: как?

4b9b3361

Ответ 1

Начиная с версии 3.2 CMake имеет функциональность для создания встроенного zip файла. Подменю CMake командной строки подкарта tar поддерживает как создание архивов zip, так и 7zip.

Например, если текущий исходный каталог CMake содержит файл testfile.txt и каталог testdir, вы можете использовать следующие команды CMake для создания zip файла, содержащего оба элемента:

add_custom_target(create_zip COMMAND
    ${CMAKE_COMMAND} -E tar "cfv" "archive.zip" --format=zip
       "${CMAKE_CURRENT_SOURCE_DIR}/testfile.txt"
       "${CMAKE_CURRENT_SOURCE_DIR}/testdir")

Как работа для более ранних версий CMake, вы можете использовать команду jar, которая является частью стандартной установки Java JRE.

find_package(Java)

execute_process(
    COMMAND
        "${Java_JAR_EXECUTABLE}" "cfM" "archive.zip" 
        "-C" "${CMAKE_CURRENT_SOURCE_DIR}" "testfile.txt" 
        "-C" "${CMAKE_CURRENT_SOURCE_DIR}" "testdir"
    RESULT_VARIABLE _result
)

Почтовый файл будет создан в текущем двоичном каталоге CMake (CMAKE_CURRENT_BINARY_DIR).

Ответ 2

Я предполагаю, что у вас уже установлен zip-инструмент (WinZip или 7z и т.д.). Вы можете написать find_zip-инструмент script, который будет искать WinZip или 7Z и т.д.

Фрагмент для WinZip:

FIND_PROGRAM(ZIP_EXECUTABLE wzzip PATHS "$ENV{ProgramFiles}/WinZip")
IF(ZIP_EXECUTABLE)
  SET(ZIP_COMMAND "\"${ZIP_EXECUTABLE}\" -P \"<ARCHIVE>\" @<FILELIST>")
ENDIF(ZIP_EXECUTABLE)

Фрагмент для 7-zip:

  FIND_PROGRAM(ZIP_EXECUTABLE 7z PATHS "$ENV{ProgramFiles}/7-Zip") 
  IF(ZIP_EXECUTABLE)
    SET(ZIP_COMMAND "\"${ZIP_EXECUTABLE}\" a -tzip \"<ARCHIVE>\" @<FILELIST>")
  ENDIF(ZIP_EXECUTABLE)

Взгляните на файл

<cmake-install-dir>\share\cmake-2.8\Modules\CPackZIP.cmake

показывает, как CPack выполняет поиск Zip_Executable и подготавливает некоторые "полезные" флаги по умолчанию.

После этого я предложил бы execute_process, подобный ответу sakra

Ответ 3

По существу, я создал пользовательскую цель

add_custom_target(STAGE_FILES)

С этой целью я копирую файлы и каталоги в CMAKE_CURRENT_BINARY_DIR

add_custom_command( 
  TARGET STAGE_FILES 
  COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/assets/video ${CMAKE_CURRENT_BINARY_DIR}/video
  COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/assets/data ${CMAKE_CURRENT_BINARY_DIR}/data
  COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/assets/strings_en.csv ${CMAKE_CURRENT_BINARY_DIR}/
  COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/assets/strings_rules_en.csv ${CMAKE_CURRENT_BINARY_DIR}/
  COMMAND ${CMAKE_COMMAND} -E tar "cfv" "data.zip" --format=zip  --files-from=${CMAKE_SOURCE_DIR}/assets/to_zip.txt
  COMMAND ${CMAKE_COMMAND} -E remove_directory ${CMAKE_CURRENT_BINARY_DIR}/data
  COMMAND ${CMAKE_COMMAND} -E rename  ${CMAKE_CURRENT_BINARY_DIR}/data.zip ${CMAKE_CURRENT_BINARY_DIR}/data
)

Важная строка

COMMAND ${CMAKE_COMMAND} -E tar "cfv" "data.zip" --format=zip  --files-from=${CMAKE_SOURCE_DIR}/assets/to_zip.txt

внутри моего

to_zip.txt

Я указываю все файлы, которые хочу включить в мой zip

data/
video/
...

Теперь я могу выполнить команду

make STAGE_FILES

который скопирует и закроет все, что мне нужно