ensure config.h is included once

autotools, header-files, linux

Solution

The way I do this is indeed creating a wrapper file (which I usually call `global.h`) that reads like this.

#ifndef MY_PROJECT_GLOBAL_H
#define MY_PROJECT_GLOBAL_H

#include <config.h>

/* Maybe other global definitions… */

#endif

Note that the recommended way to `#include` the `config.h` file is via `<config.h>` not `"config.h"` so it works better with `VPATH` builds.

Then, all the source files in my project `#include` this `global.h` header as their very first `#include` and don't care about `config.h`. A header file should never `#include` `config.h` since this would lead to bad name conflicts. Actually, if you stick to this guideline, your code should also work without `#include` guards in the configuration header.

Update regarding OP's comment

Or: How to use configuration results in headers?

If your headers need to declare different things depending on the results of the `configure` script, you have a number of options, none of which is perfect.

For internal headers, there is no problem. They simply rely on the macros being `#define`d without `#include`ing anything. This works if – as is recommended – all source files `#include` (maybe indirectly as shown above) `config.h` before any other header.

If the headers are to be installed publicly, this is not such a great solution. For those of your users that use Autoconf, it wouldn't be that bad, although even those would have to remember what checks to place in their `configure.ac` files. For users who don't use Autoconf, it will be pretty bad. If you only have a few switches (such as Glibc's fature test macros), it is okay to ask your users to `#define` them before `#include`ing your headers but if you need many, this is not a real option. Not to mention that you'll expose a lot of implementation details to your users that way.

If all you need to do is branch depending on the platform you are building for, you could probe some of the pre-defined macros like `__linux` or `_WIN32`. There is the Boost.Predef library that aims to make these check a little more convenient by providing a higher-level abstraction. The library works with C and C++ alike but, of course, it adds an additional dependency to your project.

Finally, you could make a version of your `config.h` that uses a macro prefix specific to your project. There is a contribution in the Autoconf macro archive that does exactly that for you. A minimal example could look like this.

AC_PREREQ([2.69])
AC_INIT([example-project], [1.0], [bugs@example.org])
AC_CONFIG_SRCDIR([example.c])
AC_CONFIG_MACRO_DIR([m4])
AC_CONFIG_HEADERS([config.h])
AX_PREFIX_CONFIG_H([public_config.h], [EXAMPLE_PROJECT], [config.h])
AC_PROG_CC
AC_OUTPUT

Save this as `configure.ac`, download `ax_prefix_config_h.m4` from the Autoconf macro archive and place it in the sub-directory `m4` and then run `autoreconf && ./configure`. It will create the normal `config.h` and in addition `public_config.h` where in the latter file, all macros are prefixed with `EXAMPLE_PROJECT_`. The file `public_config.h` (which also has `#include` guards by the way) can be installed and `#include`d in your project's public header files if need be.

Problem

I have a library project that I'm working on porting to using the autotools suite in Linux. I'm quite new to autotools (this week). I've learned the basics of its operation. I have a question about how to keep the contents of `config.h` from being redefined. I'm surprised to find that the generated `config.h` file doesn't either, 1) wrap each macro in a `#ifndef` or, 2) that the entire file isn't wrapped in the standard `#ifndef CONFIG_H`. As I've alluded, this code is built on Windows and Linux. Thus there are several uses of a macro, `_linux` (I'm not saying that's the best name, but it's in use everywhere) to bring in elements to classes which exist in Linux only. Thus, this will happen header.h ``` #ifndef HEADER1_H #define HEADER1_H #ifdef HAVE_CONFIG_H #include "config.h" #endif #endif ``` source.cxx ``` #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "header.h" // oops, preprocessor gets excited because of redefs ``` One simple solution is I do that standard unique wrap in `config.h.in` after the file is generated. However, I was wondering, is there a better way of handling this? I can't be the first to encounter this and there might even be a means of handling it in `configure.ac` but being a complete neophyte in this, I don't know what to even search for.

Original source