我已经创建了一个我创建的C ++应用程序的DEB包。我希望这个应用程序使用“data”目录中的资源,在我的测试中(为方便起见),它与程序二进制文件位于同一位置,我通过其相对路径从代码内部调用它。在Debian OS中有标准位置放置数据文件(类似于/ usr / share / ...),以及其他位置放置二进制文件(可能是/ usr / bin)。我不想把路径硬编码在我的程序中,我认为通过“data / img.png”访问图像比“/usr/share/.../data/img.png更好”。所有GNU经典程序都尊重目录结构,我想它们是以良好的方式完成的。我试图使用dpkg来找出应用程序的结构,但这对我没有帮助。我有更好的方法来做这件事吗?
PS:我还希望我的代码能够移植到Windows(跨平台),避免尽可能使用像“if WIN32”这样的解决方法。
答案 0 :(得分: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已存在非可执行数据时,不需要“data”目录。
如果打包Debian,您可能需要检查http://www.debian.org/doc/manuals/developers-reference/best-pkging-practices.html。但它不是像adroid或iphone或Windows文件那样的资源。这些文件在包安装时提取到目标文件系统中作为真实文件。
修改:请参阅http://www.debian.org/doc/packaging-manuals/fhs/fhs-2.3.html
Edit2:至于多平台解决方案,我建议你做一些包装函数。在Windows上,它依赖于安装程序,通常程序通常在注册表中具有安装它们的目录的路径。在unix上,或多或少给出了数据的位置,您可以考虑用于更改目标前缀的构建选项,或使用环境变量来覆盖默认路径。在Windows上,前缀也足够了,如果它不应该太灵活。
我建议一些函数,你将传递对象的名称,它们将返回文件的路径。它取决于所使用的工具包,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 :: GetImagePath()作为方法。
答案 1 :(得分:1)
在Debian软件包中,您确实应该将数据安装在/ usr / share /中。访问数据时,应使用XDG standard,其中指出$ XDG_DATA_DIRS是要搜索的以冒号分隔的数据目录列表(另外,“如果$ XDG_DATA_DIRS未设置或为空,则值等于/ usr / local / share /:/ usr / share /应该使用。“)。