It seems that you want to count lines of code consumed by the compiler
after preprocessing. Exactly what is meant by that is debatable, but I
assume a reasonable way of counting would be good enough for your
purposes. A GNU Make makefile such as:
Makefile
%.o: %.c # Cancel built-in rule
%.o: %.i
$(CC) $(CFLAGS) -c $< -o $@
@loc=$$(wc -l $<); echo "Compiled $${loc%% *} LOC from $<"
%.i: %.c
$(CC) $(CPPFLAGS) -E -P $< > $@
illustrates a way of doing it:-
- Preprocess the source file first.
- Count the lines of preprocessed output.
- Compile the preprocessed output.
The Makefile avoids the wastage of preprocessing the source code twice,
because gcc recognises the extension .i
as signifying a file of already-preprocessed
C source and will
not preprocess it again. It is also unncessary to clean up the intermediate
.i
files because GNU make recognises them as intermediate and auto-deletes
them. Example:
$ cat foo.c
#ifdef FOO
/* A
* B
* C
*/
int foo(int x, int y)
{
while(x < y) {
if (++x == y) {
return y;
}
--y;
}
while(y < x) {
if (++y == x) {
return x;
}
--x;
}
return y;
}
#else
/* D */
int bar(int x) {
return x * x;
}
#endif
$ make foo.o
cc -E -P foo.c > foo.i
cc -c foo.i -o foo.o
Compiled 3 LOC from foo.i
rm foo.i
$ rm foo.o
$ make CPPFLAGS=-DFOO foo.o
cc -DFOO -E -P foo.c > foo.i
cc -c foo.i -o foo.o
Compiled 16 LOC from foo.i
rm foo.i
You probably want to pass the -P
option in the preprocessing step, as shown, to suppress
the production of line-marked output that will inflate the line-count. E.g. your probably don't want foo.i
to be:
$ cc -DFOO -E foo.c > foo.i
$ cat foo.i
# 1 "foo.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 1 "<command-line>" 2
# 1 "foo.c"
int foo(int x, int y)
{
while(x < y) {
if (++x == y) {
return y;
}
--y;
}
while(y < x) {
if (++y == x) {
return x;
}
--x;
}
return y;
}
but rather want it to be:
$ cc -DFOO -E -P foo.c > foo.i
$ cat foo.i
int foo(int x, int y)
{
while(x < y) {
if (++x == y) {
return y;
}
--y;
}
while(y < x) {
if (++y == x) {
return x;
}
--x;
}
return y;
}
Obviously, for a make-system that compiled many source files, you would devise
more or different apparatus from adding up the per-file LOC reports.