Siler
Siler

Reputation: 9494

Config file location and binaries and build systems like autoconf

Most build systems, like autoconf/automake, allow the user to specify a target directory to install the various files needed to run a program. Usually this includes binaries, configuration files, auxilliary scripts, etc.

At the same time, many executables often need to read from a configuration file in order to allow a user to modify runtime settings.

Ultimately, a program (let's say, a compiled C or C++ program) needs to know where to look to read in a configuration file. A lot of times I will just hardcode the path as something like /etc/MYPROGAM/myprog.conf, which of course is not a great idea.

But in the autoconf world, the user might specify an install prefix, meaning that the C/C++ code needs to somehow be aware of this.

One solution would be to specify a C header file with a .in prefix, which simply is used to define the location of the config file, like:

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

This file would be named something like constants.h.in and it would have to be process by the configure.ac file to output an actual header file, which could then be included by whatever .c or .cpp files need it.

Is that the usual way this sort of thing is handled? It seems a bit cumbersome, so I wonder if there is a better solution.

Upvotes: 3

Views: 326

Answers (1)

Tom Tromey
Tom Tromey

Reputation: 22539

There are basically two choices for how to handle this.

One choice is to do what you've mentioned -- compile the relevant paths into the resulting executable or library. Here it's worth noting that if files are installed in different sub-parts of the prefix, then each such thing needs its own compile-time path. That's because the user might specify --prefix separately from --bindir, separately from --libexecdir, etc. Another wrinkle here is that if there are multiple installed programs that refer to each other, then this process probably should take into account the program name transform (see docs on --program-transform-name and friends).

That's all if you want full generality of course.

The other approach is to have the program be relocatable at runtime. Many GNU projects (at least gdb and gcc) take this approach. The idea here is for the program to attempt to locate its data in the filesystem at runtime. In the projects I'm most familiar with, this is done with the libiberty function make_relative_prefix; but I'm sure there are other ways.

This approach is often touted as being nicer because it allows the program's install tree to be tared up and delivered to users; but in the days of distros it seems to me that it isn't as useful as it once was. I think the primary drawback of this approach is that it makes it very hard, if not impossible, to support both relocation and the full suite of configure install-time options.

Which one you pick depends, I think, on what your users want.

Also, to answer the above comment: I think changing the prefix between configure- and build time is not really supported, though it may work with some packages. Instead the usual way to handle this is either to require the choice at configure time, or to supported the somewhat more limited DESTDIR feature.

Upvotes: 1

Related Questions