LINUX.ORG.RU

CMake и упаковка ресурсов приложения

 ,


1

2

Моей программе требуются некоторые ресурсы во время работы. Хочется иметь возможность распространять программу в виде одного статически слинкованного файла (особенно актуально для офтопика), однако оставить возможность пользователю покопаться в ресурсах. Оптимальным решением выглядит упаковка ресурсов в zip архив и склеивание с исполняемым файлом приложения. Из-за особенностей структуры zip большинство архиваторов смогут открыть такой файл и даже работать с ним, несмотря на то, что это вообще то исполняемый файл.

Вопрос в том как его собирать не руками. Я использую CMake. У него есть команда cmake -E tar, позволяющая через add_custom_command/add_custom_target создать zip (и не только) архив. Вопрос в том, как его приклеить к исполняемому файлу. Если просто указать имя исполняемого файла в качестве выходного, то он полностью перезаписывается. Значит нужно создать промежуточный zip-файл и потом приклеить его к исполняемому после сборки. Однако, я пока не нашёл в CMake возможность для этого. Использовать утилиты типа dd плохая идея, так как тогда проект будет собираться только на онтопике, а на офтопике таких полезных утилит нет.

★★★★★

Один из вариантов – использовать xdd с опцией -i для включения ресурсов в секцию данных приложения. Причем, утилитка настолько маленькая, что некоторые проекты собирают ее из сорцов.

RussianWarShip
()
Ответ на: комментарий от RussianWarShip

Ресурсов целый каталог, а не 1-2 файлика, с такой утилитой придётся прописывать правила сборки для каждого файла и не забывать их обновлять при добавлении/удалении файлов. Самый-самый минимум была бы утилита, которой можно скормить каталог, а не один файл. Но это не удовлетворяет хотелку про возможность для пользователя покопаться в ресурсах и что-нибудь изменить при сохранении однофайловости программы для тех пользователей, которым ничего менять не надо, а чтобы просто работало.

KivApple ★★★★★
() автор топика
Ответ на: комментарий от slackwarrior

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

KivApple ★★★★★
() автор топика
Ответ на: комментарий от slackwarrior

Не будет работать, если запускать файл из RO ФС. На офтопике также будут проблемы с открытием запущенного исполняемого файла на запись. В общем, лучше сразу всё правильно положить в файл, на этапе сборки.

KivApple ★★★★★
() автор топика

А может всё-таки не нужно делать подобные «однофайловые» костыли?

Чем portable-вариант:

  • ZIP-архив: Executable + рядом директория с ресурсами
  • TGZ-архив: Executable + рядом директория с ресурсами

Плох? Раз пользователю даётся возможность модификации.

EXL ★★★★★
()
Ответ на: комментарий от KivApple

«Ну ты, барин, задачи ставишь» (с) на RO и зип не заменишь так-то. А если на этапе сборки — эквичленно, но в бинарь круче, согласно правилу крутоты :)

slackwarrior ★★★★★
()
Последнее исправление: slackwarrior (всего исправлений: 1)
Ответ на: комментарий от slackwarrior

На RO ZIP не заменишь, но сможешь выдрать ресурсы и забрать себе. Тоже хорошо. Но вообще я упомянул второй контраргумент - на некоторых ОС запущенные исполняемые файлы нельзя открывать на запись, только на чтение. Конечно, при желании это можно обойти через создание временного исполняемого файла патчера, но это уже выходит за все рамки, когда можно просто взять и собрать файл нормально.

KivApple ★★★★★
() автор топика
Последнее исправление: KivApple (всего исправлений: 1)
Ответ на: комментарий от EXL

Тем, что его нужно распаковывать куда-то, а исполняемый файл можно сразу взять и запустить. Это особенно актуально для офтопика, где запуск EXE из проводника нормальное явление.

KivApple ★★★★★
() автор топика
Ответ на: комментарий от RussianWarShip

Многие (не все) архиваторы это умеют из коробки, так как zip файл читается с конца (у него такой формат, что заголовок расположен в конце файла). Соответственно, если в архиватор не вшито жёсткой проверки, что вначале нет лишнего, то он умеет открывать такие файлы без лишних телодвижений.

А с точки зрения программиста там не надо искать сигнатуру. Просто fseek на конец и читаем заголовок ZIP и работаем как обычно.

KivApple ★★★★★
() автор топика
Последнее исправление: KivApple (всего исправлений: 1)
Ответ на: комментарий от KivApple

Причем тут архиватор? Твоя прога должна будет найти в конце себя архив и распаковать его в памяти.

RussianWarShip
()
Ответ на: комментарий от KivApple

И есть не нулевая вероятность, что на такой исполняемый файл антивирусы сделают алерт.

RussianWarShip
()
Ответ на: комментарий от KivApple

Тем, что его нужно распаковывать куда-то, а исполняемый файл можно сразу взять и запустить. Это особенно актуально для офтопика, где запуск EXE из проводника нормальное явление.

Ага, пройдя кучу идиотских вопросов самого проводника по типу «А ВЫ УВЕРЕНЫ В ТОМ ЧТО НУЖНО ЗАПУСКАТЬ ЭТОТ ФАЙЛ??? ВЕДЬ ОН СКАЧАН ИЗ ИНТЕРНЕТА!!!» и заканчивая идиотией Chrome вроде «этот файл может нанести вред вашему комплюктеру, поэтому кочать я его не буду».

В Linux-дистрибутивах же твоему исполняемому файлу нужно будет проставлять флаг запуска, а в TGZ-архиве сразу будут корректные права.

ИМХО, ни к чему это какерство, оно будет только раздражать. Сделай привычно и удобно: код – отдельно, ресурсы, раз уж хочешь оставить возможности их изменять, тоже отдельно. Архив – ожидаемое и привычное состояние portable-программы.

EXL ★★★★★
()

Имхо готовых кроссплатформенных средств для этого нет. Придётся самому. Утилиту можно сделать, которая дописывает один файл в конец другого. В cmake она должна быть указана в dependencies в add custom command , чтобы сначала собрал ее а потом пытался паковать архив.

zerhud
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.