deheader - report which includes in C or C++ compiles can be removed
[-h] [-m command] [-b builddir]
[-i pattern] [-q] [-r] [-v] [-x pattern] [-V]
This tool takes a list of C or C++ sourcefiles and generates a report on which
#includes can be omitted from them; also, what standard inclusions may be
required for portability. The test, for each foo.c or foo.cc or foo.cpp, is
simply whether "rm foo.o; make foo.o" returns a zero status (but the
build command may be overridden).
Exception: Under cmake, foo.o is a phoney target. Therefore, when a
"CMakeList.txt" is detected, "make clean" is done rather
than "rm foo.o".
Optionally, with the -r
switch, the unneeded headers are removed from the
sourcefiles. Don't use this option unless you have your sourcefiles safely
under version control and can revert!
If a sourcefile argument is a directory, the report is generated on all source
files beneath it. Subdirectories beginning with a dot are assumed to be
repository directories for version-control systems and ignored. If no
arguments are given, the program runs as if the name of the current directory
had been passed to it.
Inclusions within the scope of #if/#ifdef/#else/#endif directives are left
alone, because trying to reason about potential combinations of -D and U
options would be too complicated and prone to weird errors. One exception:
headers protected only by S_SPLINT_S, the conditional for blocking scanning by
the static analysis tool splint
(1), are scanned normally.
The tool will also emit warnings about duplicate inclusions, and inclusions
required for portability but not present.
It is recommended that you arrange to compile with options that will stop the
compiler on warnings when using this tool; otherwise it will report headers
that only declare prototypes and return types (and thus throw only warnings)
as being not required. Under gcc the compiler options to accomplish this are
-Werror -Wfatal-errors. If your makefile follows normal conventions, running
with -m "make CFLAGS='-Werror -Wfatal-errors'"
may do the
right thing; you can check this by running with -v -v -v to see what
compilation commands are actually emitted.
On each test compile, the original sourcefile is moved to a name with an .orig
suffix and restored on interrupt or after processing with its original
timestamp, unless the -r
option was given and headers removed.
If the -b option is given, it tells the program that generated .o files live in
a file tree parallel to the source tree but rooted at the specified argument.
If the argument is a relative path, it is interpreted relative to the
directory in which deaheader is run.
If the first test compilation from the top-level directory fails, deheader
descends into the subdirectory of the source file and retries compiling inside
At verbosity level 0, only messages indicating removable headers are issued. At
verbosity 1, test compilations are timed and progress indicated with a
twirling-baton prompt. At verbosity level 2, you get verbose progress messages
on the analysis. At verbosity level 3, you see the output from the make and
If the -q (--quiet) option flag was not set, the last line of the output will be
a statistical summary.
Running deheader will leave a lot of binaries in your directory that were
compiled in ways possibly not invoked by your normal build process. Running
"make clean" afterwards (or the equivalent under whatever build
system you are using) is strongly recommended.
Display some help and exit.
Set the build command used for test compiles.
Defaults to 'make'.
Set the build directory for object
Set a pattern for includes to be ignored.
Takes a Python regular expression.
Suppress statistical summary.
Remove header inclusions from sourcefiles
where they are not required.
Exclude files with names matching the
specified Python regexp.
Show version of program and exit.
Returns 1 if unneeded includes were found, 0 otherwise. Thus, you can use it for
pre-release sanity checking in Makefile.
Very rarely, test-compiling after running with -r
may show that this tool
removed some headers that are actually required for your build. This can
happen because deheader
doesn't know about all the strange things your
build system gets up to, and the problem of analyzing your build to understand
them would be Turing-complete. Simply revert the altered files and continue.
Due to minor variations in system headers, it is possible your program may not
port correctly to other Unix variants after being deheadered. This is normally
not a problem with the portion of the API specified by POSIX and ANSI C, but
may be for headers that are not standardized or only weakly standardized. The
sockets API (sys/select.h, sys/sockets.h, and friends such as sys/types.h and
sys.stat.h) is perhaps the most serious trouble spot. deheader
internal table of rules that heads off the most common problems by suppressing
deletion of headers that are required for portability, but your mileage may
The depenedency scanner does not ignore the text of comments. This, e.g, a
reference to "log10" in a comment will produce a spurious warning
that <math.h> is required for portability.
Sufficiently perverse C++ can silently invalidate the brute-force algorithm this
tool uses. Example: if an overloaded function has different overloads from two
different files, removing one may expose the other, changing runtime semantics
without a compile-time warning. Similarly, removing a later file containing a
template specialization may lead to undefined behavior from a template defined
in an earlier file. Use this with caution near such features, and test
Eric S. Raymond <email@example.com>; (home page at