| || |
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 intalled 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.