A Makefile for Quick C Experiments
Here's a handy Makefile I use when I want to experiment with some C
code to check my understanding of the language or some library. It
simply takes a directory of .c
files, each with their own main()
functions, and compiles them into binaries, preprocessor output, and
assembly output. The assembly output is nicer than using Godbolt's
Compiler Explorer when you have a large file or you want to keep your
code private. With minor modifications, the Makefile can be
configured to match your exact cross-compiler settings for embedded
development.
SRCS=$(wildcard *.c) # Find all the .c files in this directory. BINS=$(SRCS:.c=) # Make binaries for them all. ASMS=$(SRCS:.c=.s) # Output assembly code for them. PRES=$(SRCS:.c=.i) # Save the pre-processor output. # Set these as environment variables before running make if you want # to override these defaults: CC?=gcc OPT?=-O3 CFLAGS=-Wall -Wpedantic CFLAGS+=$(OPT) LIBS=-lm all: $(BINS) $(ASMS) $(PRES) bin: $(BINS) asm: $(ASMS) pre: $(PRES) # Make the binary. %: %.c $(CC) $(CFLAGS) -o $@ $< $(LIBS) # Make the assembly output. %.s: %.c $(CC) $(CFLAGS) -S -fverbose-asm -o $@ $< $(LIBS) # Make the preprocessor output. %.i: %.c $(CC) $(CFLAGS) -E -o $@ $< $(LIBS) .PHONY: clean clean: rm -f $(BINS) $(ASMS) $(PRES)
Some example usage follows.
#include <stdio.h> int main(int argc, char **argv) { for (int i = 0; i < argc; i++) { printf("%s\n", argv[i]); } }
#include <stdio.h> #include <stdint.h> int main(int argc, char **argv) { int8_t max = INT8_MAX; printf("max: % 4d\n", max); int8_t max_incr = max + 1; printf("max+1: % 4d\n", max_incr); int8_t min = INT8_MIN; printf("min: % 4d\n", min); }
~/code/experiments $ make cc -Wall -Wpedantic -O3 -o int_overflow int_overflow.c -lm cc -Wall -Wpedantic -O3 -o printf printf.c -lm cc -Wall -Wpedantic -O3 -S -fverbose-asm -o int_overflow.s int_overflow.c -lm cc -Wall -Wpedantic -O3 -S -fverbose-asm -o printf.s printf.c -lm cc -Wall -Wpedantic -O3 -E -o int_overflow.i int_overflow.c -lm cc -Wall -Wpedantic -O3 -E -o printf.i printf.c -lm ~/code/experiments $ ./printf this is a test ./printf this is a test ~/code/experiments $ ./int_overflow max: 127 max+1: -128 min: -128
Example output:
printf.i | int_overflow.i |
printf.s | int_overflow.s |