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.

printf.c:

#include <stdio.h>

int main(int argc, char **argv) {
    for (int i = 0; i < argc; i++) {
        printf("%s\n", argv[i]);
    }
}

int_overflow.c:

#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

© Copyright 2024, Remington Furman

blog@remcycles.net

@remcycles@subdued.social