Self Makefile and C source
[ date: 2024-12-04 || tags: c,make,fun ]I’ve seen this trick long time ago, one file that’s a C source and also usable as
it’s own Makefile, also known as
polyglot code.
While the polyglot has probably little use in practice, the combination with
build system can be handy, to distribute a single file. Build instructions can
be of course in a comment in the file.
Let’s see a minimal example:
Source:
#include <stdio.h>
int main() {
printf("Hello world!\n");
return 0;
}
Makefile:
CFLAGS=-Wall
hello: hello.c
gcc -o $@ $< $(CFLAGS)
Combined (syntax highlighting for C):
#if 0
CFLAGS=-Wall
hello: hello.c
gcc -o $@ $< $(CFLAGS)
ifdef false
#else
#include <stdio.h>
int main() {
printf("Hello world!\n");
return 0;
}
#endif
#if 0
endif
#endif
Combined (syntax highlighting for Makefile):
#if 0
CFLAGS=-Wall
hello: hello.c
gcc -o $@ $< $(CFLAGS)
ifdef false
#else
#include <stdio.h>
int main() {
printf("Hello world!\n");
return 0;
}
#endif
#if 0
endif
#endif
There’s still a problem that the embedded C code in the ifdef false/endif is
parsed by make, a standalone ifdef in the middle of the C code will
terminate the supposedly skipped part. I’ve tried to confuse make more but it
seems to be quite tolerant to various syntax hacks, like defining a C function
$ and emulating some built-in function calls.
How it all works is straightforward and depends on source level compatibility
of comments and code. The C preprocessor directives are comments for make so
they hide the make directives from compiler.