-ROOT_DIR = $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))
-SOURCES_LISP = env.lisp core.lisp stepA_mal.lisp
-SOURCES = utils.lisp types.lisp reader.lisp printer.lisp $(SOURCES_LISP)
+# Helper functions
+define record_lisp
+ $(shell (test -f "hist/$(1)_impl" && grep -q $(2) "hist/$(1)_impl") || echo $(2) > "hist/$(1)_impl")
+endef
+
+define steps
+ $(if $(MAKECMDGOALS),\
+ $(if $(findstring all,$(MAKECMDGOALS)),\
+ stepA_mal,\
+ $(filter step%, $(MAKECMDGOALS))),\
+ stepA_mal)
+endef
+
+ROOT_DIR := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))
+SOURCES_LISP := env.lisp core.lisp stepA_mal.lisp
+SOURCES := utils.lisp types.lisp reader.lisp printer.lisp $(SOURCES_LISP)
LISP ?= sbcl
-all : stepA_mal
+# Record the Common Lisp implementation used for all steps built in this
+# invocation This is used in the targets to rebuild the step if the
+# implementation changes
+$(foreach step, $(call steps), $(call record_lisp,$(patsubst step%,%,$(step)),$(LISP)))
+.PRECIOUS: hist/%_impl
.PHONY: stats
-step% : step%.lisp utils.lisp types.lisp env.lisp printer.lisp reader.lisp core.lisp
- cl-launch -v -l $(LISP) +Q -S $(ROOT_DIR) -s $@ -d $@.image -o $@ -E 'mal:main' -e '(load "~/quicklisp/setup.lisp")'
+all : stepA_mal
+
+hist/%_impl: ;
+
+step% : step%.lisp utils.lisp types.lisp env.lisp printer.lisp reader.lisp core.lisp hist/%_impl
+ cl-launch --verbose --lisp $(LISP) --source-registry $(ROOT_DIR) --system $@ --dump images/$@.$(LISP).image -o $@ --entry 'mal:main'
clean:
find . -name 'step*' -executable -exec git check-ignore \{\} \; -delete
- rm -f *.lib *.fas[l]
+ rm -f *.lib *.fas[l] images/* hist/*_impl
stats: $(SOURCES)
@wc $^