在可执行文件中使用 GNU 标准目录变量

Posted

技术标签:

【中文标题】在可执行文件中使用 GNU 标准目录变量【英文标题】:Using GNU Standard Directory Variables inside executable 【发布时间】:2015-09-24 09:13:32 【问题描述】:

通常需要可执行文件中标准 GNU 目录之一的位置。不幸的是,GNU autoconf 没有提供标准的方法来做到这一点,但建议了几种解决方法,每种方法都有不同的缺点,访问已安装位置的常用方法是在CPPFLAGS 中为该位置添加预处理定义:

AM_CPPFLAGS = -DDATADIR='"$(datadir)"'

但是,defining directories 的 GNU Autoconf 手册部分包含以下句子

请注意,所有以前的解决方案都将这些目录的绝对名称硬连接到可执行文件中,这不是一个好的属性。您可以尝试计算相对于前缀的名称,并尝试在运行时查找前缀,这样您的包是可重定位的。

是否有库或任何标准方法可以按照引用段落中的建议计算可执行文件中的 GNU 目录?与上面提到的预处理器定义相比,这会有其他缺点吗?

【问题讨论】:

这可能意味着如果二进制文件位于标准 GNU 目录中,您可以从可执行路径计算前缀。 【参考方案1】:

我认为文档对此非常清楚:标准方法是不对绝对路径做出任何假设,而是使用相对路径。特别是你不应该对$prefix做任何假设

因此,如果您的应用程序需要访问共享数据,请通过../share/foo/foodata.txt 访问它,而不是使用/usr/local/share/foo/foodata.txt;这样您就可以轻松地重新定位您的应用程序。

Afaik,没有外部库可以根据您的调用二进制文件为您计算标准路径。

这可能有两个原因:

如果二进制文件确实使用标准路径,那么自己计算这些路径(使用相对路径)就很简单了。图书馆在哪些方面做得更好?

如果二进制文件使用标准路径(例如,因为构建器使用了类似以下(当然是假设的)示例),那么解析这些路径的任务几乎是不可能的;所以图书馆也帮不了你

例如:

./configure --sbindir=/home/me/sbin --bindir=/opt/foo/bin
make pkglibdir=/usr/lib/goo/
make install libdir=/usr/local/foo/lib/

帮助程序库(或您的应用程序)可能会将所有这些路径记录到某个辅助文件中(以在标准路径失败时进行额外查找),但我认为最大的问题是没有定义的存储位置文件

libdirdatadir 显然不好(因为数据应该有助于解决这些路径,所以不能依赖它们) 将数据放入与应用程序二进制文件相同的目录中打破了bindir 仅包含可执行文件的假设。 将数据放入应用程序二进制文件可能需要在make install 期间修改该二进制文件,这听起来也很脏。

【讨论】:

以上是关于在可执行文件中使用 GNU 标准目录变量的主要内容,如果未能解决你的问题,请参考以下文章

是否可以使用命令行在可执行文件之间切换

使用 GCC 在可执行文件中嵌入资源

在可执行文件中使用嵌入式 .dll

在可执行 jar 中访问 derby 数据库

Visual Studio C++ 在可执行文件中创建可执行文件

对话框中的更改未反映在可执行文件中