diff --git a/src/Makefile b/src/Makefile
index 18ab524b8e3fbf282a07a4dd9a67167842aba422..90776b8125efe7ec18561f034f5bb60c5b89104e 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -132,6 +132,10 @@ goals:=$(or $(MAKECMDGOALS),all)
 cleanonly:=$(filter $(clean_targets),$(goals))
 destructive:=$(filter-out info,$(cleanonly))
 
+ifndef cleanonly
+include Makefile.d/old.mk
+endif
+
 include Makefile.d/util.mk
 
 ifdef PREFIX
@@ -141,7 +145,7 @@ endif
 OBJDUMP_OPTS?=--wide --source --line-numbers
 
 OBJCOPY:=$(call Prefix,objcopy)
-OBJDUMP:=$(call Prefix,objdump) $(OBJDUMP_OPTS)
+OBJDUMP:=$(call Prefix,objdump)
 WINDRES:=$(call Prefix,windres)
 
 ifdef YASM
@@ -176,11 +180,7 @@ include Makefile.d/detect.mk
 # make would try to remove the implicitly made directories
 .PRECIOUS : %/ comptime.c
 
-# very sophisticated dependency
-sources:=\
-	$(call List,Sourcefile)\
-	$(call List,blua/Sourcefile)\
-
+sources:=
 makedir:=../make
 
 # -DCOMPVERSION: flag to use comptime.h
@@ -204,6 +204,11 @@ endif
 depdir:=$(makedir)/deps
 objdir:=$(makedir)/objs
 
+# very sophisticated dependency
+sources+=\
+	$(call List,Sourcefile)\
+	$(call List,blua/Sourcefile)\
+
 depends:=$(basename $(filter %.c %.s,$(sources)))
 objects:=$(basename $(filter %.c %.s %.nas,$(sources)))
 
@@ -268,16 +273,18 @@ opts+=$(debug_opts)
 
 opts+=$(foreach v,$(passthru_opts),$(if $($(v)),-D$(v)))
 
-CFLAGS:=$(opts) $(WFLAGS) $(CPPFLAGS) $(CFLAGS)
-LDFLAGS:=$(libs) $(LDFLAGS)
-ASFLAGS+=-x assembler-with-cpp
+opts+=$(WFLAGS) $(CPPFLAGS) $(CFLAGS)
+libs+=$(LDFLAGS)
+asflags:=$(ASFLAGS) -x assembler-with-cpp
+
+cc=$(CC)
 
 ifdef DISTCC
-CC:=distcc $(CC)
+cc=distcc $(CC)
 endif
 
 ifdef CCACHE
-CC:=ccache $(CC)
+cc=ccache $(CC)
 endif
 
 ifndef SILENT
@@ -288,11 +295,11 @@ ifndef destructive
 $(shell $(CC) -v)
 define flags =
 
-CC ........ $(CC)
+CC ........ $(cc)
 
-CFLAGS .... $(CFLAGS)
+CFLAGS .... $(opts)
 
-LDFLAGS ... $(LDFLAGS)
+LDFLAGS ... $(libs)
 
 endef
 $(info $(flags))
@@ -306,13 +313,12 @@ endif
 endif
 
 LD:=$(CC)
-CC:=$(CC) $(CFLAGS)
-NASM:=$(NASM) $(NASMOPTS) -f $(nasm_format)
-GZIP:=$(GZIP) $(GZIP_OPTS)
+cc:=$(cc) $(opts)
+nasm=$(NASM) $(NASMOPTS) -f $(nasm_format)
 ifdef UPX
-UPX:=$(UPX) $(UPX_OPTS)
+upx=$(UPX) $(UPX_OPTS)
 endif
-WINDRES:=$(WINDRES) $(WINDRESFLAGS)\
+windres=$(WINDRES) $(WINDRESFLAGS)\
 	$(debug_opts) --include-dir=win32 -O coff
 
 %/ :
@@ -322,7 +328,7 @@ WINDRES:=$(WINDRES) $(WINDRESFLAGS)\
 # prerequisites
 .SECONDEXPANSION :
 
-# 'UPX' is also recognized in the enviornment by upx
+# 'UPX' is also recognized in the environment by upx
 unexport UPX
 
 # executable stripped of debugging symbols
@@ -331,19 +337,19 @@ $(exe) : $(dbg) | $$(@D)/
 	$(.)-$(OBJCOPY) --add-gnu-debuglink=$< $@
 ifdef UPX
 	$(call Echo,Compressing final executable...)
-	$(.)-$(UPX) $@
+	$(.)-$(upx) $@
 endif
 
 # original executable with debugging symbols
 $(dbg) : $(objects) | $$(@D)/
 	$(call Echo,Linking $(@F)...)
-	$(.)$(LD) -o $@ $^ $(LDFLAGS)
+	$(.)$(LD) -o $@ $^ $(libs)
 
 # disassembly of executable
 $(dbg).txt : $(dbg)
 	$(call Echo,Dumping debugging info...)
-	$(.)$(OBJDUMP) $< > $@
-	$(.)$(GZIP) $@
+	$(.)$(OBJDUMP) $(OBJDUMP_OPTS) $< > $@
+	$(.)$(GZIP) $(GZIP_OPTS) $@
 
 # '::' means run unconditionally
 # this really updates comptime.h
@@ -368,11 +374,11 @@ ifdef Echo_name
 	@printf '%-20.20s\r' $$<
 endif
 endif
-	$(.)$(CC) -MM -MF $$@ -MT $(objdir)/$$(*F).o $(2) $$<
+	$(.)$(cc) -MM -MF $$@ -MT $(objdir)/$$(*F).o $(2) $$<
 endef
 
 $(eval $(call _recipe,c))
-$(eval $(call _recipe,s,$(ASFLAGS)))
+$(eval $(call _recipe,s,$(asflags)))
 
 # compiling recipe template
 # 1: target file suffix
@@ -384,10 +390,10 @@ $(objdir)/%.$(1) : %.$(2) | $$$$(@D)/
 	$(.)$(3)
 endef
 
-$(eval $(call _recipe,o,c,$(CC) -c -o $$@ $$<))
-$(eval $(call _recipe,o,nas,$(NASM) -o $$@ $$<))
-$(eval $(call _recipe,o,s,$(CC) $(ASFLAGS) -c -o $$@ $$<))
-$(eval $(call _recipe,res,rc,$(WINDRES) -i $$< -o $$@))
+$(eval $(call _recipe,o,c,$(cc) -c -o $$@ $$<))
+$(eval $(call _recipe,o,nas,$(nasm) -o $$@ $$<))
+$(eval $(call _recipe,o,s,$(cc) $(asflags) -c -o $$@ $$<))
+$(eval $(call _recipe,res,rc,$(windres) -i $$< -o $$@))
 
 _rm=$(.)$(rmrf) $(call Windows_path,$(1))
 
@@ -398,7 +404,7 @@ clean :
 	$(call _rm,$(exe) $(dbg) $(dbg).txt $(objects))
 
 distclean :
-	$(call _rm,../bin ../objs ../deps comptime.h)
+	$(call _rm,../bin ../objs ../deps ../make comptime.h)
 
 info:
 ifdef WINDOWSHELL
diff --git a/src/Makefile.d/detect.mk b/src/Makefile.d/detect.mk
index f576bcf784ff17cbb2be112d5a622737f4214d05..3edf0dad4b6b86eec70dfa0d6e9c4be1ca7bf8e0 100644
--- a/src/Makefile.d/detect.mk
+++ b/src/Makefile.d/detect.mk
@@ -29,7 +29,10 @@ $(call Print,$(_m))
 
 # go for a 32-bit sdl mingw exe by default
 MINGW:=1
+# cmd.exe uses native Windows semicolon delimited PATH
+ifneq (,$(findstring ;,$(PATH)))
 WINDOWSHELL:=1
+endif
 
 else # if you on the *nix
 
@@ -91,7 +94,7 @@ ifeq (,$(filter $(v),$(gcc_versions)))
 define line =
 Your compiler version, GCC $(version), \
 is not supported by the Makefile.
-The Makefile will assume GCC $(latest_gcc_version).))
+The Makefile will assume GCC $(latest_gcc_version).
 endef
 $(call Print,$(line))
 GCC$(subst .,,$(latest_gcc_version)):=1
diff --git a/src/Makefile.d/old.mk b/src/Makefile.d/old.mk
new file mode 100644
index 0000000000000000000000000000000000000000..e5890eedd11f9bc69556c08d240ea369dd511334
--- /dev/null
+++ b/src/Makefile.d/old.mk
@@ -0,0 +1,16 @@
+#
+# Warn about old build directories and offer to purge.
+#
+
+_old:=$(wildcard $(addprefix ../bin/,FreeBSD Linux \
+		Linux64 Mingw Mingw64 SDL dummy) ../objs ../deps)
+
+ifdef _old
+$(foreach v,$(_old),$(info $(abspath $(v))))
+$(info )
+$(info These directories are no longer\
+       required and should be removed.)
+$(info You may remove them manually or\
+       by using 'make distclean')
+$(error )
+endif
diff --git a/src/Makefile.d/platform.mk b/src/Makefile.d/platform.mk
index 531d073e915f42748a6b176e506a79cd6aa142b9..fad4be191639266760e689628a0a5054635e67ff 100644
--- a/src/Makefile.d/platform.mk
+++ b/src/Makefile.d/platform.mk
@@ -7,9 +7,11 @@ PKG_CONFIG?=pkg-config
 ifdef WINDOWSHELL
 rmrf=-2>NUL DEL /S /Q
 mkdir=-2>NUL MD
+cat=TYPE
 else
 rmrf=rm -rf
 mkdir=mkdir -p
+cat=cat
 endif
 
 ifdef LINUX64
diff --git a/src/Makefile.d/util.mk b/src/Makefile.d/util.mk
index e76e324224b394c197ccd5b0ed496707f436e1b1..bda68df13a3d25892ec2a3933201d88686c580f4 100644
--- a/src/Makefile.d/util.mk
+++ b/src/Makefile.d/util.mk
@@ -10,7 +10,8 @@ Wildvar=$(foreach v,$(filter $(1),$(.VARIABLES)),$($(v)))
 
 # Read a list of words from file and prepend each with the
 # directory of the file.
-List=$(addprefix $(dir $(1)),$(file < $(1)))
+_cat=$(shell $(cat) $(call Windows_path,$(1)))
+List=$(addprefix $(dir $(1)),$(call _cat,$(1)))
 
 # Convert path separators to backslash on Windows.
 Windows_path=$(if $(WINDOWSHELL),$(subst /,\,$(1)),$(1))