# generate objects from sources # arg 1: target.SRCS # arg 2: object suffix prefix # returns: target.OBJS objects = $(foreach f,$($1),$(addsuffix $2.o,$(basename $f))) # generate depends from .S .c .cpp sources # args 1: target.SRCS # returns: target.DEPS depends = $(foreach f,$(filter %.S %.c %.cpp,$($1)),$(addsuffix .d,$(basename $f))) # default target all: targets @echo " -> Built all in $(shell pwd | xargs basename)" # for each target.SRCS # - generate target.OBJS # - generate target.DEPS and include them # - generate target.a that depends on target.OBJS # - add target.a to TARGETS $(foreach V,$(filter %.SRCS, ${.VARIABLES}),\ $(eval $(V:%.SRCS=%.OBJS) := $(call objects,$V,_${ARCH})) \ $(eval TARGET.OBJS += $(V:%.SRCS=%.OBJS)) \ $(eval $(V:%.SRCS=%.DEPS) := $(call depends,$V)) \ $(eval include $($(V:%.SRCS=%.DEPS))) \ $(eval TARGET.DEPS += $(V:%.SRCS=%.DEPS)) \ $(eval $(V:%.SRCS=%.a): $($(V:%.SRCS=%.OBJS))) \ $(eval TARGETS += $(V:%.SRCS=%.a)) \ ) # for each target in HOSTTARGETBIN # - generate target.OBJS from target.SRCS # - generate target.DEPS from target.SRCS # - include target.DEPS # - generate target.exe depending on target.OBJS $(foreach T,${HOSTTARGETBIN},\ $(eval $T.OBJS := $(call objects,$T.SRC,) ) \ $(eval $T.DEPS := $(call depends,$T.SRC) ) \ $(eval $T: ${$T.OBJS}; @echo ' LD HOST $T'; ${HOST_CC} ${HOST_LDFLAGS} -o $T ${$T.OBJS} ) \ ) TESTS.DEPS = $(foreach F,${TESTS},$(addsuffix .d,$F)) include ${TESTS.DEPS} debug: @echo "targets: ${TARGETS}" @echo " OBJS: ${TARGET.OBJS}" @echo " DEPS: ${TARGET.DEPS}" @echo "tests : ${TESTS}" @echo " DEPS: ${TESTS.DEPS}" @echo "HOSTTARGETBIN: ${HOSTTARGETBIN}" %.info: @echo "Target: $(basename $@)" @echo " SRCS: ${$(basename $@).SRCS}" @echo " OBJS: ${$(basename $@).OBJS}" @echo " DEPS: ${$(basename $@).DEPS}" targets: ${TARGETS} # extra flags ${ARCH}_CFLAGS += -I../lib/libk \ -Werror=implicit-function-declaration ${ARCH}_CXXFLAGS += -I../lib/libk -Drestrict=__restrict__ # Depndency rules %.d: %.S @${${ARCH}_CC} ${${ARCH}_CFLAGS} -M -MT $(<:.S=_${ARCH}.o) $< -MF $@ %.d: %.c @${${ARCH}_CC} ${${ARCH}_CFLAGS} -M -MT $(<:.c=_${ARCH}.o) $< -MF $@ %.d: %.cpp @${${ARCH}_CXX} ${${ARCH}_CXXFLAGS} -M -MT $(<:.cpp=_${ARCH}.o) $< -MF $@ %.d: %.cc @${HOST_CXX} ${HOST_CXXFLAGS} -M -MT $(<:.cc=_${ARCH}.o) $< -MF $@ # Target suffix rules %.a: @echo ' AR $@' @${${ARCH}_AR} ${${ARCH}_ARFLAGS} $@ $(filter %.o,$^) %_${ARCH}.o: %.s @echo ' AS $<' @${${ARCH}_AS} ${${ARCH}_ASFLAGS} -c -o $@ $< %_${ARCH}.o: %.S @echo ' CC $<' @${${ARCH}_CC} ${${ARCH}_CFLAGS} -c -o $@ $< %_${ARCH}.o: %.c @echo ' CC $<' @${${ARCH}_CC} ${${ARCH}_CFLAGS} -c -o $@ $< %_${ARCH}.o: %.cpp @echo ' CXX $<' @${${ARCH}_CXX} ${${ARCH}_CXXFLAGS} -c -o $@ $< %.elf: @echo ' LD $@' @${${ARCH}_LD} ${${ARCH}_LDFLAGS} -o $@ $^ @echo -n ' B2b ' @b2sum $@ | cut -d' ' -f1 # Host suffix rules %.o: %.c @echo ' CC HOST $<' @${HOST_CC} ${HOST_CFLAGS} -c -o $@ $< # test rules tst/%: tst/%.cc @echo ' CXX TEST $@' @${HOST_CXX} ${HOST_CXXFLAGS} $< -o $@ .PHONY: test.base valgrind.base clean.base FORCE test.base: ${TESTS} @echo " -> Running tests in $(shell pwd | xargs basename)" @$(foreach f,$^,echo " -> $f"; ./$f &&) echo "Done" valgrind.base: ${TESTS} @echo " -> Running valgrind on tests in $(shell pwd | xargs basename)" @$(foreach f,$^,echo " -> $f"; valgrind --leak-check=full ./$f;) clean.base: FORCE @echo " -> Cleaning $(shell pwd | xargs basename)" @$(foreach V,$(filter %.OBJS, ${.VARIABLES}), rm -rf $($(V))) @$(foreach V,$(filter %.DEPS, ${.VARIABLES}), rm -rf $($(V))) @rm -rf *.a @rm -rf ${TESTS} %: %.base ; FORCE: ;