Add a testsuite (./testsuite) and dependency-logging command stuff that doesn't
[mgear/mgear.git] / src / mage.mk
diff --git a/src/mage.mk b/src/mage.mk
deleted file mode 100644 (file)
index 465a05a..0000000
+++ /dev/null
@@ -1,145 +0,0 @@
-# Mage by Matt McCutchen
-
-# Text utilities
-empty :=
-bs := \$(empty)
-define nl
-
-
-endef
-# Shell-quote: a'b => 'a'\''b'
-sq = '$(subst ','\'',$1)'
-# Make-quote: a$\nb => a$$$(nl)b
-# This is enough to assign the value, *but not to use it as an argument!*
-mqas = $(subst $(nl),$$(nl),$(subst $$,$$$$,$1))
-# Return nonempty if the strings are equal, empty otherwise.
-# If the strings have only nice characters, you can do $(filter x$1,x$2).
-streq = $(findstring x$1,$(findstring x$2,x$1))
-
-# $(call fmt-make-assignment,foo,bar)
-# Output a make assignment that stores bar in variable foo.
-# The result is like `foo:=bar' but handles leading spaces, $, and
-# newlines appearing in bar safely.
-fmt-make-assignment = $1:=$$(empty)$(call mqas,$2)
-
-mg-orig-default-goal := $(.DEFAULT_GOAL)
-
-# bar.g file format:
-# cmd-bar:=cat foo >bar.tmp
-# errors-bar:=$(empty)yikes!
-# exitcode-bar:=0
-
-# $(call mg-check-file,foo.o)
-# Make sure foo.o's genfile, if any, has been loaded.
-define mg-check-file
-$(if $(mg-checked-$1),,$(eval 
-cmd-$1 :=
-errors-$1 :=
-exitcode-$1 :=
--include $1.g
-mg-checked-$1 := done
-))
-endef
-
-# $(call mg-translate-cmd,touch $$@)
-# Currently translates $@, $<, $^, $+ to Mage-ized variables.
-# $* needs no translation.  We won't support $%, $?, $|.
-# There might be false matches, e.g., $$@ => $$(out) ;
-# to prevent that, do $$$(empty)@ .
-define mg-translate-cmd
-$(subst $$@,$$(mg@),$(subst $$<,$$(mg<),$(subst $$^,$$(mg^),$(subst $$+,$$(mg+),$1))))
-endef
-
-# OOOH!!! .SECONDEXPANSION does let us watch the implicit rule search as it
-# happens.
-.SECONDEXPANSION:
-
-# $(call mg-rule,target,prerequisite,cmd)
-# Defines a rule.
-# If cmd uses $@, quote if necessary so this function sees $@, etc.
-# 
-# When we build bar from foo using a Mage rule:
-# Division of work:
-# - "bar.g: foo" does the computation.
-# - "bar: bar.g" replays errors and exit code.
-# Cases:
-# - bar is managed and up to date => replay
-# - bar doesn't exist or is managed and out of date => compute
-# - bar is unmanaged => warn about override 
-MG-FORCE-TARGET-DNE:
-MG-FORCE-CMD-CHANGED:
-MG-FORCE-REPLAY:
-.PHONY: MG-FORCE-TARGET-DNE MG-FORCE-CMD-CHANGED MG-FORCE-REPLAY
-define mg-rule
-$(eval 
-
-# Define some target-specific variables.
-# It might look like we could use $*, but $1 most likely isn't %.
-$1.g: target = $$(@:.g=)
-$1.g: cmd = $(call mg-translate-cmd,$3)
-$1.g: mg@ = $$(target).tmp
-$1.g: mg^ = $$(filter-out MG-% $$(abspath $$(target)),$$^)
-$1.g: mg+ = $$(filter-out MG-% $$(abspath $$(target)),$$+)
-$1.g: mg< = $$(firstword $$(mg^))
-
-# Load the target's genfile if necessary.
-$1.g: $$$$(call mg-check-file,$$$$(target))
-
-# If the target doesn't exist, we must run the rule; we'll generate it.
-# If the target is unmanaged, we must run the rule; we'll see that the
-# obfuscated target is in $? and complain.
-$1.g: $$$$(if $$$$(wildcard $$$$(target)),$$$$(abspath $$$$(target)),$$$$(if $$(exitcode-$$$$(target)),,MG-FORCE-TARGET-DNE))
-
-# If the command changed, we must regenerate.
-$1.g: $$$$(if $$$$(call streq,$$$$(cmd),$$$$(cmd-$$$$(target))),,MG-FORCE-CMD-CHANGED)
-
-$1.g: $2
-       $(value mg-commands)
-
-# Replay the errors and the exit code (if any of either).
-# We don't have to worry about .DELETE_ON_ERROR deleting the target because
-# it is only touched if we *successfully* regenerate it.
-# Recheck the file in case it was regenerated.
-# HMMM Maybe errors should go to stderr???
-$1: $1.g MG-FORCE-REPLAY
-       $$(call mg-check-file,$$@)
-       $$(if $$(errors-$$@)$$(exitcode-$$@)$$(built-$$@),$$(info $$(cmd-$$@)$$(if $$(built-$$@),, [replay]))$$(if $$(errors-$$@),$$(info $$(errors-$$@)),),)
-       $$(if $$(exitcode-$$@),@exit $$(exitcode-$$@),)
-)
-endef
-
-# Just add additional prerequisites.
-define mg-prereq
-$(eval 
-$1.g: $2
-)
-endef
-
-# If an override:
-#     1. Complain.
-#     2. Clear out the errors and exit code so we don't replay them.
-# Otherwise:
-#     1. Store the command.
-#     2. Run the command, storing errors.
-#     3. Store exit code.
-#     4. Update the real files as applicable.
-#     5. Read the new genfile.
-define mg-commands
-       $(if $(filter $(abspath $(target)),$?),\
-               $(info mage: warning: Manually created/modified file at $(target) overrides rule.)\
-               $(eval cmd-$(target):=)$(eval errors-$(target):=)$(eval exitcode-$(target):=)\
-       ,\
-       @$(eval mg-checked-$(target) :=)$(eval built-$(target) := yes)\
-       exec 3>$@.tmp &&\
-       echo $(call sq,$(call fmt-make-assignment,cmd-$(target),$(cmd))) >&3 &&\
-       set -o pipefail &&\
-       { { ($(cmd)) && { [ -r $(target).tmp ] || { echo 'mage: error: Command for $(target) succeeded without creating it!'; false; }; }; } 2>&1\
-       | sed -re '1s/^/errors-$(target):=$$(empty)/; 1!s/^/errors-$(target)+=$$(nl)/' >&3; xc=$$?; } &&\
-       { [ $$xc == 0 ] || echo "exitcode-$(target):=$$xc" >&3; } &&\
-       if [ $$xc != 0 ] || cmp -s $(target) $(target).tmp; then mv -f $@.tmp $@ && rm -f $(target).tmp;\
-       else rm -f $(target) && mv -f $@.tmp $@ && mv -f $(target).tmp $(target); fi\
-       )
-endef
-
-# We don't want anything we defined to become the default goal.
-.DEFAULT_GOAL := $(mg-orig-default-goal)
\ No newline at end of file