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

Using GNU Standard Directory Variables inside executable

通常需要可执行文件中标准 GNU 目录之一的位置。不幸的是,GNU autoconf 没有提供执行此操作的标准方法,但建议了几种解决方法,每种方法都有不同的缺点,访问安装位置的一种常见方法是为 CPPFLAGS:[=14 中的位置添加预处理定义=]

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

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

Note that all the previous solutions hard wire the absolute name of these directories in the executables, which is not a good property. You may try to compute the names relative to prefix, and try to find prefix at runtime, this way your package is relocatable.

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

我认为文档对此很清楚:标准方法是不对绝对路径做任何假设,而是使用相对路径。特别是你不应该对 ${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 期间修改该二进制文件,这听起来也很脏。