V0_SRC := v0/main.c v0/token.c v0/parser.c v0/log.c # V0_TEST must only include `v0/test.c` itself, as all other test C–source files are # included directly into `v0/test.c` using `#include "test_xyz.c"`. V0_TEST := v0/test.c V0_SRC_OBJ := $(patsubst v0/%.c,v0/bin/%.o,$(V0_SRC)) V0_TEST_OBJ := $(patsubst v0/%.c,v0/bin/%.o,$(V0_TEST)) # Define dependency file lists for sources and tests V0_SRC_DEPS := $(V0_SRC_OBJ:.o=.d) V0_TEST_DEPS := $(V0_TEST_OBJ:.o=.d) v0/bin/c2: $(V0_SRC_OBJ) $(CC) $(CFLAGS) -o $@ $^ V0_SRC_OBJ_NO_MAIN := $(filter-out v0/bin/main.o,$(V0_SRC_OBJ)) v0/bin/test: $(V0_SRC_OBJ_NO_MAIN) $(V0_TEST_OBJ) $(CC) $(CFLAGS) -o $@ $^ test:: v0/bin/test valgrind --leak-check=full --error-exitcode=1 v0/bin/test generate_golden:: v0/bin/test GENERATE_GOLDEN=1 v0/bin/test clean:: rm -f v0/bin/test v0/bin/c2 $(V0_SRC_OBJ) $(V0_TEST_OBJ) $(V0_SRC_DEPS) $(V0_TEST_DEPS) # Build each .c file into a .o file, tracking header dependencies. v0/bin/%.o: v0/%.c v0/include.mk @mkdir -p $(dir $@) $(CC) $(CFLAGS) -MMD -MP -c $< -o $@ # Reference dependency files -include $(V0_SRC_DEPS) -include $(V0_TEST_DEPS)