ensure config.h is included once
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.
Ensure config.h included
This is not exactly what you ask, but would you consider adding config.h into every file? You could add in your CFLAGS/CXXFLAGS the -include option in order to ensure that every file in the project includes the config.h.
See https://gcc.gnu.org/onlinedocs/gcc/Preprocessor-Options.html
-include file Process file as if #include "file" appeared as the first line of the primary source file. However, the first directory searched
for file is the preprocessor's working directory instead of the
directory containing the main source file. If not found there, it is
searched for in the remainder of the #include "..." search chain as
normal. If multiple -include options are given, the files are included
in the order they appear on the command line.
How to ensure a generated config.h file is in the include path?
There is an automatism for include directories with CMAKE_INCLUDE_CURRENT_DIR
in CMake:
set(CMAKE_INCLUDE_CURRENT_DIR ON)
If this variable is enabled, CMake automatically adds
CMAKE_CURRENT_SOURCE_DIR
andCMAKE_CURRENT_BINARY_DIR
to the include path for each directory.
So I prefer to individually have the following call on a need-by basis in my CMakeLists.txt
:
include_directories("${CMAKE_CURRENT_BINARY_DIR}")
Edit: Thanks for the hint of @zaufi, if your generated header file has a target scope then you should prefer (CMake >= Version 2.8.12) to make it only visible to that target (not globally to all targets) with:
target_include_directories(MyLibrary PRIVATE "${CMAKE_CURRENT_BINARY_DIR}")
Note: For source files with relative paths CMake looks in both directories CMAKE_CURRENT_SOURCE_DIR
and CMAKE_CURRENT_BINARY_DIR
.
binutils/bfd.h wants config.h now?
Well, the most correct way of using the header is to use autotools in your package as well. Some people are simply stubborn and I don't think you can do much about it.
An alternative is to work-around the check, by defining the macros it is using:
#define PACKAGE 1
#define PACKAGE_VERSION 1
Of course, if you are already defining those, you may as well set them to some reasonable values like:
#define PACKAGE "your-program-name"
#define PACKAGE_VERSION "1.2.3"
and use them for your program. You'll usually going to use something like that anyway at some point to keep the versions consistent.
This should be enough if you're using a standards-compliant compiler because then the __STDC__
macro will be declared and everything will go on just fine. Well, as long as the headers you're using won't require more autoconf-generated defines.
For example, if you wanted to use plugin-api.h
, you'd actually have to handle checking for stdint.h
and inttypes.h
...
Best practice for public C declarations depending on config.h
In the specific case of <stdbool.h>
, we chose to avoid depending on config.h
and to rely on the C (or C++) compiler to tell us what is OK. The code includes this header, and this header sorts out the mess. It is known to work on Mac OS X, Linux, Solaris, HP-UX, AIX, Windows. The actual header file name is not ourbool.h
, but I've mangled its header guards and comments so it looks as if that is what it is called. The comments quote the C99 standard for the licence to perform as it does. Note that it also works correctly if <stdbool.h>
has already been included, and it works correctly if <stdbool.h>
is included after it has been included (and getting this correct was not 100% pain-free). Defining __bool_true_false_are_defined
is crucial to this inter-working. (When your code is in use by other people, you can't mandate that they do not use <stdbool.h>
themselves, either before or after your header is included.)
#ifndef OURBOOL_H_INCLUDED
#define OURBOOL_H_INCLUDED
/*
** Ensure that type bool with constants false = 0 and true = 1 are defined.
** C++ (ISO/IEC 14882:1998/2003/2011) has bool, true and false intrinsically.
** C (ISO/IEC 9899:1999) has bool, true and false by including <stdbool.h>
** C99 <stdbool.h> also defines __bool_true_false_are_defined when included
** MacOS X <dlfcn.h> manages to include <stdbool.h> when compiling without
** -std=c89 or -std=c99 or -std=gnu89 or -std=gnu99 (and __STDC_VERSION__
** is not then 199901L or later), so check the test macro before defining
** bool, true, false. Tested on MacOS X Lion (10.7.1) and Leopard (10.5.2)
** with both:
** #include "ourbool.h"
** #include <stdbool.h>
** and:
** #include <stdbool.h>
** #include "ourbool.h"
**
** C99 (ISO/IEC 9899:1999) says:
**
** 7.16 Boolean type and values <stdbool.h>
** 1 The header <stdbool.h> defines four macros.
** 2 The macro
** bool
** expands to _Bool.
** 3 The remaining three macros are suitable for use in #if preprocessing
** directives. They are
** true
** which expands to the integer constant 1,
** false
** which expands to the integer constant 0, and
** __bool_true_false_are_defined
** which expands to the integer constant 1.
** 4 Notwithstanding the provisions of 7.1.3, a program may undefine and
** perhaps then redefine the macros bool, true, and false.213)
**
** 213) See 'future library directions' (7.26.7).
**
** 7.26.7 Boolean type and values <stdbool.h>
** 1 The ability to undefine and perhaps then redefine the macros bool, true,
** and false is an obsolescent feature.
**
** Use 'unsigned char' instead of _Bool because the compiler does not claim
** to support _Bool. This takes advantage of the license of paragraph 4.
*/
#if !defined(__cplusplus)
#if __STDC_VERSION__ >= 199901L
#include <stdbool.h>
#elif !defined(__bool_true_false_are_defined)
#undef bool
#undef false
#undef true
#define bool unsigned char
#define false 0
#define true 1
#define __bool_true_false_are_defined 1
#endif
#endif /* !_cplusplus */
#endif /* OURBOOL_H_INCLUDED */
Clearly, if you want to allow for the possibility of HAVE_STDBOOL_H
, you may, but it is not needed. You can also decide what to do if HAVE_CONFIG_H
is defined, but again it is not needed.
To use this, your header would contain:
#ifndef YOURHEADER_H_INCLUDED
#define YOURHEADER_H_INCLUDED
...other #includes as needed...
#include "ourbool.h" /* Or #include "project/ourbool.h" */
...other material...
extern bool boolean_and(bool lhs, bool rhs);
...other material...
#endif /* YOURHEADER_H_INCLUDED */
The precise location of ourbool.h
in yourheader.h
is not critical as long as it is before you declare types, functions or (perish the thought) variables that use the bool
type.
Getting full source path in config.h in autotools
You are looking for the absolute path of srcdir
. It can be easily done by using:
readlink -f $srcdir
Recall that the configure.ac file is actually a shell script with m4
macros. So virtually
every standard command will be accessible:
Here is a possible way to deal with your problem:
srcdir2=`readlink -f $srcdir`
AC_DEFINE_UNQUOTED([DATA_PATH], ["$srcdir2"], [data path])
How to ensure #include doesn't recursively add (only adds unique files once)
This is a linker and header file problem, you just need to add #pragma once
at the top of each header files, the compiler will add the content of each header files only one time, but you must ensure that you just declare methods in your header files and write the content of those methods in other .cpp
files to prevent of linking error.
Adding a dynamic symbol name not work with AC_DEFINE_UNQUOTED from configure.ac
But the final config.h file does not contain the following definition
[...] config.h.in is generated dynamically and it does not contain the
definition too.
The latter is actually the key issue. When you use AC_CONFIG_HEADERS
to request that definitions be recorded in a header file instead of being expressed via compiler command-line options, Autoconf handles it by processing one or more header templates, such as config.h.in
, to produce the resulting header(s). The autoconf
command does not produce these templates itself, however. You can write them by hand if you wish, but a separate program, autoheader
, is available to perform this job, and autoreconf
(not autoconf
) automatically runs autoheader
to generate a template for the first header named in the first AC_CONFIG_HEADERS
call.
The behavior you describe is a longtime known issue (not accounted a bug, per se), which you can find discussed in the archives of the bug-autoconf mailing list. The resolution was a documentation change, whose result you can still see in the section of the Autoconf manual that discusses Autoheader:
In order to do its job,
autoheader
needs you to document all of the
symbols that you might use. Typically this is done via anAC_DEFINE
orAC_DEFINE_UNQUOTED
call whose first argument is a literal
symbol and whose third argument describes the symbol (see Defining
Symbols).
(Emphasis added.)
This indeed seems to be the technically appropriate place for those details. That is, AC_DEFINE_UNQUOTED
does behave as advertised, as can be seen by disabling AC_CONFIG_HEADERS
(a viable workaround under many circumstances), or by employing one of the alternatives the docs go on to suggest:
you can use
AH_TEMPLATE
(see Autoheader
Macros), or you can supply a suitable input file for a subsequent
configuration header file. Symbols defined by Autoconf's builtin tests
are already documented properly; you need to document only those that
you define yourself.
If you were to argue that it would have been nice for that issue to be mentioned in the AC_DEFINE_UNQUOTED
docs, too, then I would fully agree with you. But I do also think that the situation is considerably different now than when the doc change was first put in, on account of the introduction and rise to prevalence of autoreconf
, which hides the involvement of autoheader
from most users.
In any case, I'll ignore the "supply your own template" option, which is a bit fraught, and focus on AH_TEMPLATE
. To use it to support the particular case presented in the question, one would add something along these lines to configure.ac
:
AH_TEMPLATE([USE_test], [Define to 1 to use test])
Perhaps you ask "What's the point then? I might as well use a regular AC_DEFINE
." That's a good question, to which you should indeed give careful consideration. Note well that there is no point to defining arbitrary preprocessor macros, as only those corresponding to symbols appearing in one or more of your sources will ever be expanded. That does not necessarily make configure
-time macro name generation useless, but it does mean that when maintaining configure.ac
, you can and should have a complete list of all the generated macro names that need to be supported. In that case, it is indeed plausible that you might write appropriate AH_TEMPLATE
invocations for all the needed cases. Under most circumstances, however, going straight to (conditional) AC_DEFINE
s for each symbol is probably a better choice.
Related Topics
Can Linux Flock(Fd, Lock_Ex|Lock_Nb) Fail Spuriously
How to Split Two Vertical Pane Inside a Horizontal Pane in Tmux Using Tmuxinator
Firefox Not Closing After Selenium Tests Are Run
How Existing Kernel Driver Should Be Initialized as Pci Memory-Mapped
Autoconf Check for Program and Fail If Not Found
Source Line Numbers in Perf Call Graph
How Does Docker Share Resources
How Run Different Versions of Node.Js in Same Time
How to Build for Linux 32-Bit with Go1.6.2
Save Multiple Password Accounts for Git
Jetty Bash Script Works Only with Root User
Run Any Linux Terminal Command from Typescript
What Is The Correct Way to Define a Netfilter Hook Function
How Does The 64 Bit Linux Kernel Kick Off a 32 Bit Process from an Elf
What Does It Mean to Break User Space
How to Get Groupname When I Have The Groupid
How Does Copy-On-Write in Fork() Handle Multiple Fork
Passing an Array as Command Line Argument for Linux Kernel Module