|
9.1.2 C Header Files
There is a small amount of boiler-plate that should be added to all
header files, not least of which is a small amount of code to prevent
the contents of the header from being scanned multiple times. This is
achieved by enclosing the entire file in a preprocessor conditional
which evaluates to false after the first time it has been seen by the
preprocessor. Traditionally, the macro used is in all upper case, and
named after the installation path without the installation prefix.
Imagine a header that will be installed to
`/usr/local/include/sys/foo.h', for example. The preprocessor
code would be as follows:
|
#ifndef SYS_FOO_H
#define SYS_FOO_H 1
...
#endif /* !SYS_FOO_H */
|
Apart from comments, the entire content of the rest of this header file
must be between these few lines. It is worth mentioning that inside the
enclosing ifndef , the macro SYS_FOO_H must be defined
before any other files are #include d. It is a common mistake to
not define that macro until the end of the file, but mutual dependency
cycles are only stalled if the guard macro is defined before the
#include which starts that cycle(6).
If a header is designed to be installed, it must #include other
installed project headers from the local tree using angle-brackets.
There are some implications to working like this:
-
You must be careful that the names of header file directories in the
source tree match the names of the directories in the install tree. For
example, when I plan to install the aforementioned `foo.h' to
`/usr/local/include/project/foo.h', from which it will be included
using `#include <project/foo.h>', then in order for the same
include line to work in the source tree, I must name the source
directory it is installed from `project' too, or other headers which
use it will not be able to find it until after it has been installed.
-
When you come to developing the next version of a project laid out in
this way, you must be careful about finding the correct header.
Automake takes care of that for you by using `-I' options that
force the compiler to look for uninstalled headers in the current source
directory before searching the system directories for installed headers
of the same name.
-
You don't have to install all of your headers to `/usr/include' --
you can use subdirectories. And all without having to rewrite the
headers at install time.
|