ZIP-файлы с использованием CMake? - PullRequest
21 голосов
/ 13 августа 2011

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

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

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

Ответы [ 4 ]

24 голосов
/ 13 августа 2011

Начиная с версии 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
)

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

6 голосов
/ 31 августа 2011

Полагаю, у вас уже установлен zip-инструмент (WinZip или 7z и т. Д.). Вы можете написать скрипт find_zip-tool, который будет искать 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-почтового индекса:

  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, аналогично ответу Сакры

2 голосов
/ 29 октября 2018

Никогда не поздно показать реальный ответ:

function(create_zip output_file input_files working_dir)
    add_custom_command(
        COMMAND ${CMAKE_COMMAND} -E tar "cf" "${output_file}" --format=zip -- ${input_files}
        WORKING_DIRECTORY "${working_dir}"
        OUTPUT  "${output_file}"
        DEPENDS ${input_files}
        COMMENT "Zipping to ${output_file}."
    )
endfunction()

Использовать как

file(GLOB ZIP_FILES "${CMAKE_CURRENT_SOURCE_DIR}/zip/*")
create_zip("${CMAKE_CURRENT_BINARY_DIR}/native_data.zip" "${ZIP_FILES}" "${CMAKE_CURRENT_SOURCE_DIR}/zip")

Это позволит упаковать все файлы из подкаталога zip/ в native_data.zip (в каталоге сборки),Затем либо включите ваш архив (путь будет отличаться от CMakeLists.txt!) В качестве исходного файла, либо добавьте его в качестве цели:

add_custom_target("project-data" ALL DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/native_data.zip")

Установка не сильно отличается от обычной:

install(FILES "${CMAKE_CURRENT_BINARY_DIR}/native_data.zip" DESTINATION ${DATADIR} RENAME "data000.zip") # Install our zip (as data000.zip)
1 голос
/ 11 января 2018

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

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/
...

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

make STAGE_FILES

, которая будет копировать и архивировать все, что мне нужно

...