.POSIX: CC = gcc CFLAGS = -std=c17 \ -pedantic -pedantic-errors -Werror -Wall -Wextra -Wshadow \ -Wstrict-prototypes -Wmissing-prototypes -Wold-style-definition \ -Wformat=2 -Wcast-qual -Wwrite-strings -Winit-self -Wnull-dereference \ -Wdouble-promotion -Wconversion -Wsign-conversion -Wsign-compare \ -Wtype-limits -Wunreachable-code -Wswitch-enum -Wswitch-default \ -Wundef -Wendif-labels -Wpointer-arith -Wredundant-decls \ -Wbad-function-cast -Wmissing-noreturn -Wnested-externs -Wlogical-op \ -Wclobbered -Wfloat-equal -Wrestrict -Wsequence-point -Waddress \ -Wvla -Wduplicated-cond -Wduplicated-branches -fno-common -ftrapv \ -fstack-protector-strong LIBS = DEBUG_FLAGS = -g3 -O0 -fsanitize=undefined RELEASE_FLAGS = -O2 -s -D NDEBUG all: help help: @echo "Please use: 'make init', 'make debug', 'make fast', 'make release', or 'make clean'" @echo "Supports parallel builds (via 'make -j8 debug')" init: @mkdir -p output source_code includes config @touch config/version source_code/main.c @echo "_00.000.00.0000" > config/version @echo "Project initialized." clean: @rm -rf output/obj_debug output/obj_release config/*.mk @rm -f output/* @echo "Project Cleaned" # Dynamic Build Graph Generators debug: @mkdir -p config output/obj_debug @PROJ_NAME=$$(basename "$$(pwd)"); \ VERS=$$(cat config/version 2>/dev/null || echo "_00.000.00.0000"); \ OUT="output/$${PROJ_NAME}$${VERS}"; \ MK="config/debug.mk"; \ echo ".POSIX:" > $$MK; \ HEADERS=$$(find includes -type f -name '*.h' | tr '\n' ' '); \ OBJS=""; \ for SRC in $$(find source_code -type f -name '*.c'); do \ OBJ="output/obj_debug/$${SRC}.o"; \ OBJS="$$OBJS $$OBJ"; \ echo "$$OBJ: $$SRC $$HEADERS" >> $$MK; \ echo " @mkdir -p $$(dirname $$OBJ)" >> $$MK; \ echo " $(CC) $(CFLAGS) $(DEBUG_FLAGS) -I includes -c $$SRC -o $$OBJ $(LIBS)" >> $$MK; \ done; \ echo "$$OUT: $$OBJS" >> $$MK; \ echo " $(CC) $(CFLAGS) $(DEBUG_FLAGS) -o $$OUT $$OBJS $(LIBS)" >> $$MK; \ $(MAKE) -f $$MK "$$OUT" fast: @mkdir -p config output/obj_release @PROJ_NAME=$$(basename "$$(pwd)"); \ VERS=$$(cat config/version 2>/dev/null || echo "_00.000.00.0000"); \ OUT="output/$${PROJ_NAME}$${VERS}"; \ MK="config/fast.mk"; \ echo ".POSIX:" > $$MK; \ HEADERS=$$(find includes -type f -name '*.h' | tr '\n' ' '); \ OBJS=""; \ for SRC in $$(find source_code -type f -name '*.c'); do \ OBJ="output/obj_release/$${SRC}.o"; \ OBJS="$$OBJS $$OBJ"; \ echo "$$OBJ: $$SRC $$HEADERS" >> $$MK; \ echo " @mkdir -p $$(dirname $$OBJ)" >> $$MK; \ echo " $(CC) $(CFLAGS) $(RELEASE_FLAGS) -I includes -c $$SRC -o $$OBJ $(LIBS)" >> $$MK; \ done; \ echo "$$OUT: $$OBJS" >> $$MK; \ echo " $(CC) $(CFLAGS) $(RELEASE_FLAGS) -o $$OUT $$OBJS $(LIBS)" >> $$MK; \ $(MAKE) -f $$MK "$$OUT" release: @mkdir -p config output/obj_release @DATE_STR=$$(date +_%y.%j.%H.%M%S); \ echo "$$DATE_STR" > config/version; \ echo "Project version updated to: $$DATE_STR" @PROJ_NAME=$$(basename "$$(pwd)"); \ VERS=$$(cat config/version 2>/dev/null); \ OUT="output/$${PROJ_NAME}$${VERS}"; \ MK="config/release.mk"; \ echo ".POSIX:" > $$MK; \ HEADERS=$$(find includes -type f -name '*.h' | tr '\n' ' '); \ OBJS=""; \ for SRC in $$(find source_code -type f -name '*.c'); do \ OBJ="output/obj_release/$${SRC}.o"; \ OBJS="$$OBJS $$OBJ"; \ echo "$$OBJ: $$SRC $$HEADERS" >> $$MK; \ echo " @mkdir -p $$(dirname $$OBJ)" >> $$MK; \ echo " $(CC) $(CFLAGS) $(RELEASE_FLAGS) -I includes -c $$SRC -o $$OBJ $(LIBS)" >> $$MK; \ done; \ echo "$$OUT: $$OBJS" >> $$MK; \ echo " $(CC) $(CFLAGS) $(RELEASE_FLAGS) -o $$OUT $$OBJS $(LIBS)" >> $$MK; \ $(MAKE) -f $$MK "$$OUT"