我正在切换到Linux进行开发,我很困惑如何在我的程序中保持良好的FHS合规性。
例如,在Windows下,我知道我的程序需要的所有资源(位图,音频数据等)都可以通过可执行文件中的相对路径找到,所以如果我正在运行程序则相同从我的开发目录或安装(例如在“Program Files”下),程序将能够找到它的所有文件。
现在,在Linux下,我看到通常可执行文件位于/ usr / local / bin下,其资源位于/ usr / local / share下。 (事实上,我甚至不确定这一点)
为了方便起见(例如版本控制)我想让所有与项目相关的文件都在相同的路径下,例如,项目/ src表示资源文件的源和项目/数据。 / p>
是否有任何标准或推荐方法让我只重建二进制文件以进行测试并使用项目/数据目录中的文件,同时还可以在/ usr / local / share下找到文件?< / p>
我想例如在/ usr / local / share下设置指向我的资源目录的符号链接,然后在我的程序中硬编码该路径,但我觉得它非常hackish并且不太便携。
另外,我想过运行一个安装脚本,每次更改或添加资源时都会将所有资源复制到/ usr / local / share。但我也觉得这不是一个好方法。
有人能告诉我或指出我在哪里说明这个问题通常是如何解决的?
谢谢!
答案 0 :(得分:2)
为了方便起见(例如版本控制)我想让所有与项目相关的文件都在相同的路径下,例如,项目/ src表示资源文件的源和项目/数据。 / p>
您可以根据需要组织源代码树 - 它不需要与所安装软件所需的FHS布局有任何相似之处。
我看到通常可执行文件位于/ usr / local / bin下,其资源位于/ usr / local / share下。 (事实上,我甚至不确定这一点)
标准前缀为/usr
。正如FHS规范所重申的那样,/usr/local
用于“本地安装”。
是否有任何标准或推荐的方法让我只重建二进制文件以进行测试并使用项目/数据目录中的文件
当然。例如,运行./configure --datadir=$PWD/share
是将构建指向源树的数据文件的方法(用适当的路径替换),并使用-DDATADIR="'${datadir}'"
中的AM_CFLAGS
之类的值来使值知道(推测是C)代码。 (所有这些,只要您使用autoconf / automake。其他构建系统中可能有类似的选项。)
这种硬编码是在实践中使用的,它就足够了。对于您自己的工作副本中的开发构建,拥有硬编码路径应该不是问题,最终构建(由打包程序完成)将只使用标准FHS路径。
答案 1 :(得分:0)
你可以测试几个地点。例如,首先检查您当前正在运行程序的目录中是否有data
目录。如果是这样,请继续使用它。如果没有,请尝试/usr/local/share/yourproject/data
,依此类推。
对于开发/测试,您可以使用项目文件夹中的data
目录,并进行部署,使用/usr/local/share/
中的内容。当然,您可以测试更多位置(例如/usr/share
)。
基本上,对此方法的要求是您具有为所有文件系统访问构建正确路径的函数。而不是fopen("data/blabla.conf", "w")
使用类似fopen(path("blabla.conf"), "w")
的内容。 path()将从程序启动时使用目录测试确定的路径构造正确的路径。例如。如果路径为/usr/local/share/yourproject/data/
,则path("blabla.conf")
返回的字符串将为"/usr/local/share/yourproject/data/blabla.conf"
- 并且存在您的绝对路径。
我就是这样做的。 HTH。
答案 2 :(得分:0)
在这种情况下,我首选的解决方案是使用配置文件以及覆盖其位置的命令行选项。
例如,名为myapp
的完全部署的应用程序的配置文件可以驻留在/etc/myapp/settings.conf
中,其中一部分可能如下所示:
...
confdir=/etc/myapp/
bindir=/usr/bin/
datadir=/usr/share/myapp/
docdir=/usr/share/doc/myapp/
...
您的应用程序(或启动程序脚本)可以解析此文件以确定在何处找到所需的其余文件。
我相信您可以在代码中合理地假设配置文件的位置是在/etc/myapp
下修复的 - 或在编译时指定的任何其他位置。然后,您提供命令行选项以允许覆盖该位置:
myapp --configfile=/opt/myapp/etc/settings.conf ...
为某些目录路径提供选项也是有意义的,这样用户可以轻松覆盖任何配置文件设置。这种方法有几个优点:
您的用户可以非常轻松地重新定位应用程序 - 只需移动文件,修改配置文件中的路径,然后使用例如一个包装器脚本,用适当的--configfile
选项调用主应用程序。
您可以轻松支持FHS以及您需要的任何其他方案。
在开发过程中,您可以让您的测试套件使用经过特殊设计的配置文件,路径就在您需要的位置。
有些人主张在运行时探测系统来解决这样的问题。我通常建议至少出于以下原因避免使用此类解决方案:
它使您的程序不确定。乍看之下,您永远无法分辨出哪个配置文件 - 特别是如果您的系统上有多个版本的应用程序。
在任何安装混乱中,应用程序都会保持肥胖和快乐 - 用户也是如此。在我看来,应用程序应该查看一个特定和记录良好的位置,并在信息性消息中止,如果它找不到它是什么寻找。
你不可能总是把事情做好。将始终存在应用程序无法处理的意外罕见环境或极端情况。
这种行为违反了Unix哲学。即使是comamnd shell也可以探测多个位置,因为所有位置都可以容纳一个应该被解析的文件。
编辑:
我所知道的任何正式标准都没有规定此方法,但 是Unix世界中流行的解决方案。大多数主要守护进程(例如BIND,sendmail,postfix,INN,Apache)将在某个位置查找配置文件,但允许您覆盖该位置,并通过文件覆盖任何其他路径。
这主要是为了让系统管理员能够实现他们想要的方案或设置多个并发安装,但它在测试期间也有帮助。如果不是一个合适的标准,这种灵活性使其成为最佳实践。