大多数构建系统(如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
个文件需要它。
这是处理这类事情的通常方式吗?这看起来有点麻烦,所以我想知道是否有更好的解决方案。
答案 0 :(得分:1)
如何处理这个问题基本上有两种选择。
一种选择是执行您提到的操作 - 将相关路径编译到生成的可执行文件或库中。这里值得注意的是,如果文件安装在前缀的不同子部分中,那么每个这样的东西都需要它自己的编译时路径。这是因为用户可以与--prefix
分开指定--bindir
,与--libexecdir
分开指定,等等。这里的另一个问题是,如果有多个安装的程序相互引用,那么此过程可能应该考虑程序名称转换(请参阅--program-transform-name
和朋友的文档)。
如果你想要完全普遍的话,这就是全部。
另一种方法是让程序在运行时可重定位。许多GNU项目(至少gdb和gcc)采用这种方法。这里的想法是程序尝试在运行时在文件系统中定位其数据。在我最熟悉的项目中,这是通过libiberty函数make_relative_prefix
来完成的。但我确信还有其他方法。
这种方法经常被吹捧为更好,因为它允许程序的安装树被tar
编辑并传递给用户;但在发行的日子里,在我看来它并不像以前那么有用。我认为这种方法的主要缺点是,它很难(如果不是不可能的话)支持重定位和完整的配置安装时选项。
我认为你选择哪一个取决于你的用户想要什么。
另外,回答上述评论:我认为不支持更改配置和构建时间之间的前缀,尽管它可能适用于某些软件包。相反,通常的处理方法是要么在配置时选择,要么支持更有限的DESTDIR
功能。