配置文件位置和二进制文件,并构建像autoconf这样的系统

Config file location and binaries and build systems like autoconf

本文关键字:autoconf 系统 构建 位置 二进制文件 配置文件      更新时间:2023-10-16

大多数构建系统,如autoconf/automake,都允许用户指定一个目标目录来安装运行程序所需的各种文件。通常这包括二进制文件、配置文件、辅助脚本等。

同时,许多可执行文件通常需要从配置文件中读取,以便允许用户修改运行时设置。

最终,一个程序(比如说,一个编译的C或C++程序)需要知道在配置文件中查找的位置。很多时候,我只是将路径硬编码为类似/etc/MYPROGAM/myprog.conf的东西,这当然不是一个好主意。

但在autoconf世界中,用户可能会指定一个安装前缀,这意味着C/C++代码需要以某种方式意识到这一点。

一种解决方案是指定一个带有.in前缀的C头文件,该前缀仅用于定义配置文件的位置,如:

const char* config_file_path = "@CONFIG_FILE_PATH@"; // `CONFIG_FILE_PATH` is defined in `configure.ac`.  

这个文件的名称类似于constants.h.in,它必须由configure.ac文件处理才能输出一个实际的头文件,然后可以由任何需要它的.c.cpp文件包含。

这是处理这类事情的常用方法吗?这看起来有点麻烦,所以我想知道是否有更好的解决方案。

基本上有两种处理方式。

一种选择是执行您提到的操作——将相关路径编译到生成的可执行文件或库中。这里值得注意的是,如果文件安装在前缀的不同子部分,那么每个文件都需要自己的编译时路径。这是因为用户可能会将--prefix--bindir分开,与--libexecdir分开,等等。这里的另一个问题是,如果有多个安装的程序相互引用,那么这个过程可能应该考虑程序名称转换(请参阅--program-transform-name和朋友们的文档)。

当然,如果你想要全面的通用性,那就到此为止。

另一种方法是让程序在运行时可重新定位。许多GNU项目(至少是gdb和gcc)都采用这种方法。这里的想法是让程序在运行时尝试在文件系统中定位其数据。在我最熟悉的项目中,这是用性欲函数make_relative_prefix完成的;但我相信还有其他办法。

这种方法通常被吹捧为更好,因为它允许程序的安装树被tar建立并交付给用户;但在发行版时代,它似乎不像以前那么有用了。我认为这种方法的主要缺点是,即使不是不可能,也很难同时支持重新定位和全套配置安装时间选项。

我认为,你选择哪一个取决于你的用户想要什么。

此外,为了回答上述评论:我认为在配置和构建时之间更改前缀并不是真正受支持的,尽管它可能适用于某些包。相反,处理此问题的通常方法是在配置时要求进行选择,或者支持稍微有限的DESTDIR功能。