2013-03-11 55 views
1

我已经创建了一个我创建的C++应用程序的DEB包。我希望这个应用程序使用“数据”目录中的资源,在我的测试中(为了方便起见),它与程序二进制文件位于相同的位置,我从代码中通过其相对路径调用它。在Debian操作系统中有标准位置来放置数据文件(如/ usr/share/...)和其他位置(可能位于/ usr/bin)。我不想在我的程序中使用硬编码的路径,我认为通过“data/img.png”访问图像比“/usr/share/.../data/img.png”更好。 ”。所有的GNU经典程序都尊重目录结构,我想他们以一种很好的方式来做。我试图使用dpkg来找出应用程序的结构,但这并没有帮助我。有没有更好的方法来做到这一点? PS:我也希望我的代码可以移植到Windows(跨平台),尽可能避免使用像“如果WIN32”这样的解决方法。从Debian软件包结构中的程序访问资源

回答

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已经存在于非可执行数据中时,不需要“数据”目录。

如果打包为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; 
    } 

这可能是明智的班级设置,在那里你可以初始化每一次启动依赖于平台的根路径,然后使用设置:: GetImagePath()作为方法。

+0

谢谢!我会检查链接。我编辑了我的问题,我忘了提及我希望为Windows编译相同的代码,而不使用任何类型的“如果Windows”。 – 2013-03-11 14:11:46

+0

我看到了你发布的链接,他们详细地解释了如何在Debian中打包,在哪里放置每种文件,但我认为他们假设你将编译你的程序仅用于Linux,或者你正在处理路径从你的代码中。 – 2013-03-11 14:48:21

1

在您的Debian软件包中,您的确应该将数据安装到/ usr/share /中。当访问你的数据时,你应该使用XDG standard,它指出$ XDG_DATA_DIRS是一个以冒号分隔的数据目录列表来搜索(另外,“如果$ XDG_DATA_DIRS未设置或为空,值等于/ usr/local /应该使用share /:/ usr/share /。“)。

+0

我发现这非常有用,但我想编译Windows的相同代码,而不使用任何种类的“if windows”。我忘了在我的问题中提到这一点。 – 2013-03-11 14:09:08