The inlining method is conceptually the simplest, and practically the easiest method to use. Start with the following rules in your GNU Make Makefile:
.SUFFIXES: .c .cc .o .d .h .cd ACTIONS=pack unpack OBJS= ... include $(OBJS:.o=.d) .c.d: gcc $(CFLAGS) -w -MM $< >$@ .cc.d: gcc $(CFLAGS) -w -MM -MG $< >$@ .h.cd: classdesc $(ACTIONS) <$< >$@
The rules ending in .d automatically generate Makefile dependency rules for all the header files used in the project, and the include introduces these rules into the Makefile. This feature is not available with all makes, but is with GNU make. Since it is a relatively trivial exercise to install GNU make if its not already available, it makes sense to use the features of this tool.
The -MM option to gcc instructs the preprocessor to generate Makefile dependency lines of the form:
xxx.o: yyy.h zzz.hfor all header files yyy.h, zzz.h included with the
#include "..."
form, not the #include <...>
form. This
is usually what one wants, rather than generating large numbers of
dependency lines for system headers that don't change. The -MG
option tells the compiler to assume that files it can't find will be
generated in the current directory. This is important, because we're
going to include .cd files, which are automatically generated by classdesc by the .h.cd rule.
Some native compilers support similar automatic dependency generation,
however the behaviour differs in subtle ways from gcc. It is usually
simpler to rely on gcc being available, as with GNU make. Note that
gcc is not necessarily being used for code generation -- one can
still use the native compilers for that.
With these rules defined in the Makefile, all you need to do use a
statement of the form buf << foo;
is to place the statement
#include "foo.cd" #include <classdesc_epilogue.h>somewhere after the
#include "foo.h"
line, including the
foo class definition. Any changes to the foo definition will
update everything automatically.
It is mandatory that classdesc_epilogue.h
is included, it is not
an optional feature. You will now get a link failure if you do not
included this file when needed:
undefined reference to `(anonymous namespace)::classdesc_epilogue_not_included()'Eco Lab users should use the file
ecolab_epilogue.h
instead.