CC ?= clang CFLAGS ?= -Og -Wall -Wpedantic -Wextra PREFIX ?= /usr/local BINDIR ?= bin DESTDIR ?= TESTS ?= ifneq ($(CURDIR),$(realpath $(dir $(realpath $(lastword $(MAKEFILE_LIST)))))) all: @$(MAKE) --no-print-directory -C .. $(filter-out all,$(MAKECMDGOALS)) test: clean: clean-objs: clean-tests: $(filter-out all,$(MAKECMDGOALS)): all @: else << := @echo ifneq ($(shell eval 'echo -e'),-e) << += -e endif <> := $(wildcard src/*.c) <> := $(<>:src/%.c=obj/%.o) ifneq ($(TESTS),) <> := $(foreach <>,$(TESTS:tests/cases/%.txt=%),tests/cases/$(<>).txt) else <> := $(wildcard tests/cases/*.txt) endif <> := $(<>:tests/cases/%.txt=tests/+results/%.txt) NAME := $(shell uname -s) ifeq ($(NAME),) BINARY := struct-test.exe else BINARY := struct-test endif # format functions ifneq ($(TERM),) <>:= $(shell tput bold) <> := $(<>)$(shell tput setaf 2) <>:= $(<>)$(shell tput setaf 1) <>:= $(shell tput sgr0) endif all: obj/$(BINARY) obj/$(BINARY): $(<>) $(<<) " LD\t"-o $(@) $(LDFLAGS)"\t"$(^:obj/%=%) @$(CC) $(^) -o $(@) $(LDFLAGS) clean: clean-objs clean-tests clean-tests: $(<<) " RM results\t" $(<>:tests/+results/%.txt=case-%) @$(RM) -rf tests/+results clean-objs: $(<<) " RM objects\t" $(<>:obj/%=%) $(BINARY) @$(RM) -rf obj test: $(<>) obj/%.o: src/%.c $(<<) " CC\t"$(CFLAGS)"\t"$(<:src/%=%) @mkdir -p $(shell dirname $(@)) @$(CC) -c $(<) -o $(@) $(CFLAGS) tests/+results/%.txt: tests/cases/%.txt obj/$(BINARY) $(<<) "$(<>)TEST\t" $(<:tests/cases/%.txt=case-%)"$(<>)" @mkdir -p tests/+results # $(<>)============ input =============$(<>) @cat $(<) # $(<>)============ output =============$(<>) @obj/$(BINARY) < $(<) | tee $(@) # $(<>)=========== expected ============$(<>) @EXPECTED=$(subst cases,expected,$(<)); \ if [ -f "$$EXPECTED" ]; \ then cat "$$EXPECTED"; \ else \ rm -f $(@); \ echo "None defined"; \ fi # $(<>)============ result =============$(<>) @EXPECTED=$(subst cases,expected,$(<)); RESULT=$(@); \ if diff --color -du "$$RESULT" "$$EXPECTED"; \ then echo "$(<>)# $(<>)========== successful ===========$(<>)"; \ else echo "$(<>)# $(<>)============ failed =============$(<>)"; rm -f $(@); fi obj/teams.o: src/teams.h endif .PHONY: all clean test clean-objs clean-tests