From 8d481cf58a5338e6ba62a2e9b4c3b2776071cac0 Mon Sep 17 00:00:00 2001 From: Matt McCutchen Date: Mon, 4 Jun 2007 13:18:08 -0400 Subject: [PATCH] - Add a full target obfuscation factory and rule and a comment explaining them. - Change target scouting to use the new target obfuscation system. - Add an obfuscated target to demo/Makefile that is silly but does test the system. - Change obfuscation-dump.mk back to normal after performance testing. --- demo/Makefile | 7 ++++- experiments/obfuscation-dump.mk | 12 ++++---- src/mage.mk | 51 ++++++++++++++++++++++++--------- 3 files changed, 50 insertions(+), 20 deletions(-) diff --git a/demo/Makefile b/demo/Makefile index cfdfc32..947822e 100644 --- a/demo/Makefile +++ b/demo/Makefile @@ -4,10 +4,15 @@ include mage.mk .SECONDARY: -foo.x.h: +all: cmd-xgrep = grep 'X' '$<' >'$@' $(call mg-define-rule,%.x,%,$(value cmd-xgrep)) cmd-addheader = echo 'Header:' | cat - '$<' >'$@' $(call mg-define-rule,%.h,%,$(value cmd-addheader)) + +# Testing obfuscation +mainoid := $(newoid) +all: $(mainoid) +$(mainoid)@opr:=foo.x.h diff --git a/experiments/obfuscation-dump.mk b/experiments/obfuscation-dump.mk index 3c6bd9f..fc24ab9 100644 --- a/experiments/obfuscation-dump.mk +++ b/experiments/obfuscation-dump.mk @@ -2,8 +2,8 @@ obfn1:=/./. #obfn=$(obfn1)$(eval obfn1=$(patsubst /.//////%,/.//./%,$(subst /.//////,//./,$(obfn1)/))) -#obfn=$(obfn1)$(eval pr$(obfn1)=$1)$(eval cmd$(obfn1)=$2)$(eval obfn1:=$(subst /.//////,//./,$(patsubst /.//////%,/././%,$(obfn1:.=/.)))) -obfn=$(obfn1)$(eval pr=$1)$(eval cmd=$2)$(eval obfn1:=$(subst /.//////,//./,$(patsubst /.//////%,/././%,$(obfn1:.=/.)))) +obfn=$(obfn1)$(eval pr$(obfn1)=$1)$(eval cmd$(obfn1)=$2)$(eval obfn1:=$(subst /.//////,//./,$(patsubst /.//////%,/././%,$(obfn1:.=/.)))) +#obfn=$(obfn1)$(eval pr=$1)$(eval cmd=$2)$(eval obfn1:=$(subst /.//////,//./,$(patsubst /.//////%,/././%,$(obfn1:.=/.)))) digits=0 1 2 3 4 5 6 7 8 9 @@ -13,9 +13,9 @@ digits=0 1 2 3 4 5 6 7 8 9 %yx: $(foreach d,$(digits),%$dy) -#%y: $$(call obfn,FORCE,$$$$(info Running $$@ $$$$@)) -%y: $$(call obfn,,) +%y: $$(call obfn,FORCE,$$$$(info Running $$@ $$$$@)) +#%y: $$(call obfn,,) -/./%: $$(pr) - $(cmd) +/./%: $$(pr$$@) + $(cmd$@) FORCE: diff --git a/src/mage.mk b/src/mage.mk index eba3c6d..22e33aa 100644 --- a/src/mage.mk +++ b/src/mage.mk @@ -26,14 +26,42 @@ streq = $(findstring x$1,$(findstring x$2,x$1)) # newlines appearing in bar safely. fmt-make-assignment = $1:=$$(empty)$(call mqas,$2) -# OBFUSCATION - -# Coming soon. +# We use second-expansion heavily to dynamically compute prerequisites when they +# are needed. Second-expansion lets us follow make's implicit rule search +# instead of trying to anticipate which prerequisites it will need in advance. +.SECONDEXPANSION: -# High-priority implicit rule to ensure that we don't try to actually update -# obfuscated targets. TEMP -/./proc/self/cwd/%: - +# TARGET OBFUSCATION + +# Mage uses two kinds of "obfuscated targets" (those that are not the simple +# names of real files): +# - An always-exists target like /.//. is used as a prerequisite of an implicit +# rule. Since it exists, make doesn't second-expand its own prerequisites +# until it is actually run. This way, a target's prerequisites can depend on +# the results of previous command scripts. +# - An alternative-name target like /.//./proc/self/cwd/bar is used to check the +# mtime of a file without actually building it or introducing a circular +# dependency. + +# $(newoid) allocates and returns a new obfuscation ID (oid). Example: +# x:=$(newoid) +# You can then refer to target $x or $x$(aname)bar (for any file bar). +# Prerequisites and commands come from $($x@opr) and $($x@ocmd). +# Target-specific variables $(oid) and $(otgt) (if alternate-name) are +# available. + +opfx:=/./ +# TODO If the system doesn't support /proc/self/cwd, use something else. +aname:=/proc/self/cwd/ +nextoid:=/./. +newoid=$(nextoid)$(eval nextoid:=$(subst /.//////,//./,$(patsubst /.//////%,/././%,$(nextoid:.=/.)))) + +# High-priority implicit rule for obfuscated targets. Works for both always- +# exists and alternate-name targets. +$(opfx)%: oid=$(word 1,$(subst $(aname), ,$@)) +$(opfx)%: otgt=$(word 2,$(subst $(aname), ,$@)) +$(opfx)%: $$($$(oid)@opr) + $($(oid)@ocmd) # MAIN BUILD LOGIC @@ -67,10 +95,6 @@ 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. @@ -86,6 +110,7 @@ endef # - bar is unmanaged => warn about override MG-FORCE: .PHONY: MG-FORCE +scout-oid:=$(newoid) define mg-define-rule $(eval @@ -117,7 +142,7 @@ endef # If the target is unmanaged, we must run the rule; we'll see that the # obfuscated target is in $? and complain. -mg-scout-target=$(if $(wildcard $(target)),/./proc/self/cwd/$(target),) +mg-scout-target=$(if $(wildcard $(target)),$(scout-oid)$(aname)$(target),) # If the command changed, we must regenerate. mg-check-cmd=$(if $(call streq,$(cmd),$($(target)@cmd)),,x) @@ -152,7 +177,7 @@ endef # from before the removal. (trap EXIT) define mg-generate $(call gload,$(target))\ - $(if $(filter /./proc/self/cwd/$(target),$?),\ + $(if $(filter $(scout-oid)$(aname)$(target),$?),\ $(info mage: warning: Manually created/modified file at $(target) overrides rule.)\ $(eval $(target)@cmd:=)$(eval $(target)@warnings:=)$(eval $(target)@deps:=)\ ,\ -- 2.34.1