Доступ к ресурсам из программы в структуре пакета Debian

Я сделал пакет DEB для приложения C ++, которое я создал. Я хочу, чтобы это приложение использовало ресурсы в каталоге «data», который в моих тестах (для удобства) находится в том же месте, что и двоичный файл программы, и я вызываю его изнутри кода по его относительному пути. В ОС Debian есть стандартные места для размещения файлов данных (что-то вроде / usr / share / …) и другое место для размещения двоичных файлов (вероятно, / usr / bin). Я не хотел бы указывать пути в своей программе жестко, я думаю, что лучше получить доступ к изображению с помощью «data / img.png», чем «/usr/share/…/data/img.png». ». Все классические программы GNU уважают структуру каталогов, и я думаю, что они делают это хорошо. Я пытался использовать dpkg, чтобы выяснить структуру приложений, но это мне не помогло. Есть ли лучший способ, которым я делаю, чтобы сделать это?

PS: я также хочу, чтобы мой код был переносимым на Windows (кроссплатформенный), избегая использования обходных путей, таких как «if WIN32», насколько это возможно.

1

Решение

В вашем пакете Debian вы действительно должны установить свои данные в / usr / share /. При доступе к вашим данным, вы должны использовать Стандарт XDG, в котором говорится, что $ XDG_DATA_DIRS — это список каталогов данных для поиска, разделенных двоеточиями (также, «если $ XDG_DATA_DIRS либо не установлен, либо пуст, следует использовать значение, равное / usr / local / share /: / usr / share /». «.).

1

Другие решения

Это не полностью зависит от Linux или Debian. Я думаю, что это как-то связано со спецификациями Linux Standard Base или POSIX. Я не смог найти какую-либо спецификацию достаточно быстро.

Но вы не должны использовать какой-то «базовый» каталог и подкаталоги в нем для каждого типа данных. Зависимый от платформы код должен находиться в / usr / lib / programname, независимые от платформы данные только для чтения в /usr/share/programname/img.png. Данные изменены приложением в /var/lib/programname/cache.db. Или ~ / .programname / cache.db, зависит от того, что это за приложение и что оно делает. Примечание: нет необходимости в «каталоге данных», когда / usr / share уже существует для неисполняемых данных.

Вы можете проверить http://www.debian.org/doc/manuals/developers-reference/best-pkging-practices.html если упаковка для Debian. Но это не ресурсы, как в Android или Iphone, или файлы Windows. Эти файлы извлекаются при установке пакета в целевую файловую систему как настоящие файлы.

Изменить: см. http://www.debian.org/doc/packaging-manuals/fhs/fhs-2.3.html

Edit2: Что касается многоплатформенного решения, я предлагаю вам сделать некоторые функции-оболочки. На Windows это зависит от установщика, обычно программы обычно имеют путь в реестре к каталогу, где они установлены. В Unix место для данных более или менее задано, вы можете рассмотреть вариант сборки для изменения целевого префикса или использовать переменную среды для переопределения путей по умолчанию. На окнах префикс будет также достаточно, если он не должен быть слишком гибким.

Я предлагаю несколько функций, где вы передадите имя объекта и они вернут путь к файлу. Это зависит от используемого инструментария, библиотека Qt может иметь нечто подобное, уже реализованное.

    #include <string>
#ifdef WIN32
#define ROOT_PREFIX "c:/Program Files/"const char DATA_PREFIX[] = ROOT_PREFIX "program/data";
#else
#define ROOT_PREFIX "/usr/"/* #define ROOT_PREFIX "/usr/local/" */
const char DATA_PREFIX[] = ROOT_PREFIX "share/program";
#endif

std::string GetImageBasePath()
{
return std::string(DATA_PREFIX) + "/images";
}

std::string GetImagePath(const std::string &imagename)
{
// multiple directories and/or file types could be tried here, depends on how    sophisticated
// it should be.
// you may check if such file does exist here for example and return only image type that does exist, if you can load multiple types.
return GetImageBasePath() + imagename + ".png";
}

class Image;
extern Image * LoadImage(const char *path);

int main(int argc, char *argv[])
{
Image *img1 = LoadImage(GetImagePath("toolbox").c_str());
Image *img2 = LoadImage(GetImagePath("openfile").c_str());
return 0;
}

Возможно, было бы целесообразно создать класс Settings, в котором вы можете инициализировать зависимые от платформы корневые пути один раз за запуск, а затем использовать Settings :: GetImagePath () в качестве метода.

1

По вопросам рекламы [email protected]