I've got a neat (so I thought) way of having each of my modules produce a unit-test executable if compiled with the -DTESTMODULE flag. This flag guards a main() function that can access all static data and functions in the module, without #including a C file.
From the README:
-- Modules --
The various modules were written and tested separately before being
coupled together to achieve the necessary basic functionality.
Each module retains its unit-test, its main() function, guarded
by #ifdef TESTMODULE. `make test` will compile and execute all the
unit tests, producing copious output, but importantly exitting with
an appropriate success or failure code, so the `make test` command will
fail if any of the tests fail.
Module TOC
__________
test obj src header structures CONSTANTS
---- --- --- --- --------------------
m m.o m.c m.h mfile mtab TABSZ
s s.o s.c s.h stack STACKSEGSZ
v v.o v.c v.h saverec_
f.o f.c f.h file
ob ob.o ob.c ob.h object
ar ar.o ar.c ar.h array
st st.o st.c st.h string
di di.o di.c di.h dichead dictionary
nm nm.o nm.c nm.h name
gc gc.o gc.c gc.h garbage collector
itp itp.c itp.h context
osunix.o osunix.c osunix.h unix-dependent functions
It's compile by a tricky bit of makefile,
m:m.c ob.h ob.o err.o $(CORE) itp.o $(OP)
cc $(CFLAGS) -DTESTMODULE $(LDLIBS) -o $@ $< err.o ob.o s.o ar.o st.o v.o di.o gc.o nm.o itp.o $(OP) f.o
where the module is compiled with its own C file plus every other object file except itself.
But it's creating difficulties for the kindly programmer who offered to write the Autotools files for me. So the obvious way to make it "less weird" would be to bust-out all the main functions into separate source files. But, but ... Do I gotta?