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.