问题
Is there a way to partially pre-process a C or C++ source file? By "partially preprocess" I mean expanding some but not all of the #include directives. For example, I would like to expand #includes pointing to my project headers, but not #includes pointing to other libraries' headers.
I tried to do this by running gcc -E
with only the -I
flags for my project headers and not the -I
flags for the libraries, but that doesn't work because gcc gives an error when it encounters an #include it cannot expand.
EDIT: I do not really care about the preprocessor's behaviour with respect to macro expansion.
回答1:
The C preprocessor isn't smart enough to do this on its own. If you're only interested in #include
, you should just roll your own tool (in, say, Perl) to process the source files, expanding #include
lines that interest you and ignoring the rest.
This script prefixes uninteresting header lines with // Ignored
:
#!/usr/bin/perl
use warnings;
use strict;
my @uninteresting = qw(iostream vector map);
my $uninteresting = join '|', @uninteresting;
while (<>) {
s%(#include <(?:$uninteresting)>)%// Ignored $1%;
print;
}
Now you can do:
cat sourcefile.cpp | perl ignore-meh.pl | g++ -E
And if you want to get really fancy:
#!/usr/bin/perl
use warnings;
use strict;
while (<>) {
s%// Ignored (#include <[^>]+>)%$1%;
print;
}
Now you can do:
cat sourcefile.cpp | perl ignore-meh.pl | g++ -E | perl restore-meh.pl
回答2:
The #include
which you don't want to expand, you can replace with something like $$$include
(in short, which cannot be understood by pre-processor). Preferably first you copy original files into the temporary files and then run gcc -E <filename>;
. Once you are done, again replace to the original source files.
The only concern here is that you have to go and edit your source files at least once. But that may not be a big deal as you can use the facility provided by your text editor.
回答3:
How about this?:
#include <always_include.h>
#include <another_always_include.h>
#ifdef PART_2_INCLUDES
#include <part2.h>
#include <part2a.h>
#endif
#ifdef PART_3_INCLUDES
#include <part3.h>
#include <part3a.h>
#endif
...
Then, to compile everything, gcc -DPART_2_INCLUDES -DPART_2_INCLUDES ...
Or, since it seems like usually everything should be included by default and not including some items is the special case, reverse the sense of the tests:
#include <always_include.h>
#include <another_always_include.h>
#ifndef PART_2_INCLUDES_OMITTED
#include <part2.h>
#include <part2a.h>
#endif
...
回答4:
Use -nostdinc
for gcc (or cpp).
gcc ... -nostdinc ...
回答5:
In the general case, a partial header expansion is meaningless. Consider the following example:
#include <limits.h>
#if UINT_MAX > 0xffffffff
# include "fasthash_64.h"
#elif UINT_MAX == 0xffffffff
# include "hash.h"
#else
# error "int too small for hash implementation."
#endif
来源:https://stackoverflow.com/questions/6482321/partially-preprocess-a-c-or-c-source-file