Bug 738404 - Makefile.in edits to use threadsafe mkdir (bug 680246) - r=ted
authorJoey Armstrong <jarmstrong@mozilla.com>
Tue, 03 Apr 2012 16:08:16 -0400
changeset 90977 1f093ab9df776721fe2a3c9420c9bd5baf403e50
parent 90976 106c7696d3b7a4cf0bf25beb0225d80ed2f4c530
child 90978 c598b7b202e7c94f1135f4437898294548f53005
push id22404
push usercoop@mozilla.com
push dateWed, 04 Apr 2012 18:06:17 +0000
treeherdermozilla-central@c598b7b202e7 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersted
bugs738404, 680246
milestone14.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 738404 - Makefile.in edits to use threadsafe mkdir (bug 680246) - r=ted
b2g/app/Makefile.in
build/win32/Makefile.in
client.mk
config/Makefile.in
config/config.mk
config/makefiles/autotargets.mk
config/makefiles/makeutils.mk
config/makefiles/test/Makefile.in
config/rules.mk
config/tests/makefiles/autodeps/Makefile.in
config/tests/makefiles/autodeps/testor.tmpl
dom/workers/test/extensions/bootstrap/Makefile.in
dom/workers/test/extensions/traditional/Makefile.in
js/src/config/Makefile.in
js/src/config/config.mk
js/src/config/makefiles/autotargets.mk
js/src/config/makefiles/makeutils.mk
js/src/config/rules.mk
--- a/b2g/app/Makefile.in
+++ b/b2g/app/Makefile.in
@@ -122,30 +122,34 @@ clean clobber repackage::
 	rm -rf $(DIST)/$(APP_NAME).app
 
 ifdef LIBXUL_SDK
 APPFILES = Resources
 else
 APPFILES = MacOS
 endif
 
-libs repackage::
-	mkdir -p $(DIST)/$(APP_NAME).app/Contents/MacOS
+libs-preqs = \
+  $(call mkdir_deps,$(DIST)/$(APP_NAME).app/Contents/MacOS) \
+  $(call mkdir_deps,$(DIST)/$(APP_NAME).app/Contents/Resources/$(AB).lproj) \
+  $(NULL)
+
+.PHONY: repackage
+libs repackage:: $(libs-preqs)
 	rsync -a --exclude "*.in" $(srcdir)/macbuild/Contents $(DIST)/$(APP_NAME).app --exclude English.lproj
-	mkdir -p $(DIST)/$(APP_NAME).app/Contents/Resources/$(AB).lproj
 	rsync -a --exclude "*.in" $(srcdir)/macbuild/Contents/Resources/English.lproj/ $(DIST)/$(APP_NAME).app/Contents/Resources/$(AB).lproj
 	sed -e "s/%MOZ_APP_VERSION%/$(MOZ_APP_VERSION)/" -e "s/%MOZ_APP_NAME%/$(MOZ_APP_NAME)/" -e "s/%APP_VERSION%/$(APP_VERSION)/" -e "s/%APP_NAME%/$(APP_NAME)/" -e "s/%APP_BINARY%/$(APP_BINARY)/" $(srcdir)/macbuild/Contents/Info.plist.in > $(DIST)/$(APP_NAME).app/Contents/Info.plist
 	sed -e "s/%APP_VERSION%/$(APP_VERSION)/" -e "s/%APP_NAME%/$(APP_NAME)/" $(srcdir)/macbuild/Contents/Resources/English.lproj/InfoPlist.strings.in | iconv -f UTF-8 -t UTF-16 > $(DIST)/$(APP_NAME).app/Contents/Resources/$(AB).lproj/InfoPlist.strings
 	rsync -a $(DIST)/bin/ $(DIST)/$(APP_NAME).app/Contents/$(APPFILES)
 	$(RM) $(DIST)/$(APP_NAME).app/Contents/$(APPFILES)/mangle $(DIST)/$(APP_NAME).app/Contents/$(APPFILES)/shlibsign
 ifdef LIBXUL_SDK
 	cp $(LIBXUL_DIST)/bin/xulrunner$(BIN_SUFFIX) $(DIST)/$(APP_NAME).app/Contents/MacOS/$(APP_BINARY)
 	rsync -a --exclude nsinstall --copy-unsafe-links $(LIBXUL_DIST)/XUL.framework $(DIST)/$(APP_NAME).app/Contents/Frameworks
 else
-	rm -f $(DIST)/$(APP_NAME).app/Contents/MacOS/$(PROGRAM)
+	$(RM) $(DIST)/$(APP_NAME).app/Contents/MacOS/$(PROGRAM)
 	rsync -aL $(PROGRAM) $(DIST)/$(APP_NAME).app/Contents/MacOS
 endif
 	printf "APPLMOZB" > $(DIST)/$(APP_NAME).app/Contents/PkgInfo
 
 else # MOZ_WIDGET_TOOLKIT != cocoa
 
 libs::
 ifdef LIBXUL_SDK
--- a/build/win32/Makefile.in
+++ b/build/win32/Makefile.in
@@ -30,20 +30,20 @@
 # use your version of this file under the terms of the MPL, indicate your
 # decision by deleting the provisions above and replace them with the notice
 # and other provisions required by the GPL or the LGPL. If you do not delete
 # the provisions above, a recipient may use your version of this file under
 # the terms of any one of the MPL, the GPL or the LGPL.
 #
 # ***** END LICENSE BLOCK *****
 
-DEPTH = ../..
+DEPTH     = ../..
 topsrcdir = @top_srcdir@
-srcdir = @srcdir@
-VPATH = @srcdir@
+srcdir    = @srcdir@
+VPATH     = @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
 NO_PROFILE_GUIDED_OPTIMIZE = 1
 
 ifdef _MSC_VER
 ifneq ($(OS_TEST),x86_64)
 TEST_DIRS += vmwarerecordinghelper
@@ -97,18 +97,21 @@ endif
 ifeq (1700,$(_MSC_VER))
 REDIST_FILES = \
   msvcp110.dll \
   msvcr110.dll \
   $(NULL)
 endif
 
 ifdef REDIST_FILES
-libs::
-	mkdir -p $(FINAL_TARGET)
+libs-preqs = \
+  $(call mkdir_deps,$(FINAL_TARGET)) \
+  $(NULL)
+
+libs:: $(libs-preqs)
 	install --preserve-timestamps $(foreach f,$(REDIST_FILES),"$(WIN32_REDIST_DIR)"/$(f)) $(FINAL_TARGET)
 endif
 
 endif # ! MOZ_DEBUG
 endif # WIN32_REDIST_DIR
 
 # run the binscope tool to make sure the binary and all libraries
 # are using all available Windows OS-level security mechanisms
--- a/client.mk
+++ b/client.mk
@@ -96,17 +96,16 @@ endif
 # try to find autoconf 2.13 - discard errors from 'which'
 # MacOS X 10.4 sends "no autoconf*" errors to stdout, discard those via grep
 AUTOCONF ?= $(shell which autoconf-2.13 autoconf2.13 autoconf213 2>/dev/null | grep -v '^no autoconf' | head -1)
 
 ifeq (,$(strip $(AUTOCONF)))
 AUTOCONF=$(error Could not find autoconf 2.13)
 endif
 
-MKDIR := mkdir
 SH := /bin/sh
 PERL ?= perl
 PYTHON ?= python
 
 CONFIG_GUESS_SCRIPT := $(wildcard $(TOPSRCDIR)/build/autoconf/config.guess)
 ifdef CONFIG_GUESS_SCRIPT
   CONFIG_GUESS = $(shell $(CONFIG_GUESS_SCRIPT))
 endif
@@ -176,16 +175,19 @@ OBJDIR_TARGETS = install export libs cle
 
 #######################################################################
 # Rules
 
 # The default rule is build
 build::
 	$(MAKE) -f $(TOPSRCDIR)/client.mk $(if $(MOZ_PGO),profiledbuild,realbuild)
 
+# Define mkdir
+include $(TOPSRCDIR)/config/makefiles/makeutils.mk
+include $(TOPSRCDIR)/config/makefiles/autotargets.mk
 
 # Print out any options loaded from mozconfig.
 all realbuild clean depend distclean export libs install realclean::
 	@if test -f .mozconfig.out; then \
 	  cat .mozconfig.out; \
 	  rm -f .mozconfig.out; \
 	else true; \
 	fi
@@ -311,21 +313,23 @@ CONFIGURE_ENV_ARGS += \
 ifeq ($(TOPSRCDIR),$(OBJDIR))
   CONFIGURE = ./configure
 else
   CONFIGURE = $(TOPSRCDIR)/configure
 endif
 
 configure-files: $(CONFIGURES)
 
-configure:: configure-files
-ifdef MOZ_BUILD_PROJECTS
-	@if test ! -d $(MOZ_OBJDIR); then $(MKDIR) $(MOZ_OBJDIR); else true; fi
-endif
-	@if test ! -d $(OBJDIR); then $(MKDIR) $(OBJDIR); else true; fi
+configure-preqs = \
+  configure-files \
+  $(call mkdir_deps,$(OBJDIR)) \
+  $(if $(MOZ_BUILD_PROJECTS),$(call mkdir_deps,$(MOZ_OBJDIR))) \
+  $(NULL)
+
+configure:: $(configure-preqs)
 	@echo cd $(OBJDIR);
 	@echo $(CONFIGURE) $(CONFIGURE_ARGS)
 	@cd $(OBJDIR) && $(BUILD_PROJECT_ARG) $(CONFIGURE_ENV_ARGS) $(CONFIGURE) $(CONFIGURE_ARGS) \
 	  || ( echo "*** Fix above errors and then restart with\
                \"$(MAKE) -f client.mk build\"" && exit 1 )
 	@touch $(OBJDIR)/Makefile
 
 ifneq (,$(MAKEFILE))
--- a/config/Makefile.in
+++ b/config/Makefile.in
@@ -1,13 +1,47 @@
 # -*- Makefile -*-
 #
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this file,
-# You can obtain one at http://mozilla.org/MPL/2.0/.
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is mozilla.org code.
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1998
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#   Robert Ginda <rginda@netscape.com>
+#   John Taylor <jtaylor@netscape.com>
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either of the GNU General Public License Version 2 or later (the "GPL"),
+# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
 
 DEPTH		= ..
 topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
@@ -79,18 +113,21 @@ endif
 export::
 ifdef MOZ_BUILD_DATE
 	printf "%s" $(MOZ_BUILD_DATE) > buildid
 else
 	$(PYTHON) $(topsrcdir)/toolkit/xre/make-platformini.py --print-buildid > buildid
 endif
 
 ifdef WRAP_SYSTEM_INCLUDES
-export::
-	if test ! -d system_wrappers; then mkdir system_wrappers; fi
+export-preqs = \
+  $(call mkdir_deps,system_wrappers) \
+  $(NULL)
+
+export:: $(export-preqs)
 	$(PYTHON) $(topsrcdir)/config/Preprocessor.py $(DEFINES) $(ACDEFINES) \
 		-DMOZ_TREE_CAIRO=$(MOZ_TREE_CAIRO) \
 		-DMOZ_TREE_PIXMAN=$(MOZ_TREE_PIXMAN) \
 		-DMOZ_NATIVE_HUNSPELL=$(MOZ_NATIVE_HUNSPELL) \
 		-DMOZ_NATIVE_BZ2=$(MOZ_NATIVE_BZ2) \
 		-DMOZ_NATIVE_ZLIB=$(MOZ_NATIVE_ZLIB) \
 		-DMOZ_NATIVE_PNG=$(MOZ_NATIVE_PNG) \
 		-DMOZ_NATIVE_JPEG=$(MOZ_NATIVE_JPEG) \
@@ -152,21 +189,24 @@ PYUNITS := \
   unit-nsinstall.py \
   unit-printprereleasesuffix.py \
   unit-JarMaker.py \
   unit-buildlist.py \
   unit-expandlibs.py \
   unit-writemozinfo.py \
   $(NULL)
 
-check::\
-  check-python-modules check-jar-mn\
-  check-makefiles\
+check-preqs = \
+  check-python-modules \
+  check-jar-mn \
+  check-makefiles \
   $(NULL)
 
+check:: $(check-preqs)
+
 check-python-modules::
 	@$(EXIT_ON_ERROR) \
 	for test in $(PYUNITS); do \
 	  $(PYTHON) $(srcdir)/tests/$$test ; \
 	done
 
 check-jar-mn::
 	$(MAKE) -C tests/src-simple check-jar
--- a/config/config.mk
+++ b/config/config.mk
@@ -41,17 +41,17 @@
 #
 # Determines the platform and builds the macros needed to load the
 # appropriate platform-specific .mk file, then defines all (most?)
 # of the generic macros.
 #
 
 # Define an include-at-most-once flag
 ifdef INCLUDED_CONFIG_MK
-$(error Don't include config.mk twice!)
+$(error Do not include config.mk twice!)
 endif
 INCLUDED_CONFIG_MK = 1
 
 EXIT_ON_ERROR = set -e; # Shell loops continue past errors without this.
 
 ifndef topsrcdir
 topsrcdir	= $(DEPTH)
 endif
--- a/config/makefiles/autotargets.mk
+++ b/config/makefiles/autotargets.mk
@@ -6,32 +6,40 @@
 # You can obtain one at http://mozilla.org/MPL/2.0/.
 #
 
 ###########################################################################
 #      AUTO_DEPS - A list of deps/targets drived from other macros.
 #         *_DEPS - Make dependencies derived from a given macro.
 ###########################################################################
 
+MKDIR ?= mkdir -p
+TOUCH ?= touch
 
 ###########################################################################
 # Threadsafe directory creation
 # GENERATED_DIRS - Automated creation of these directories.
 ###########################################################################
-mkdir_deps =$(foreach dir,$($(1)),$(dir)/.mkdir.done)
+mkdir_deps =$(foreach dir,$(getargv),$(dir)/.mkdir.done)
 
 ifneq (,$(GENERATED_DIRS))
   tmpauto :=$(call mkdir_deps,GENERATED_DIRS)
   GENERATED_DIRS_DEPS +=$(tmpauto)
   GARBAGE_DIRS        +=$(tmpauto)
 endif
 
 %/.mkdir.done:
 	$(subst $(SPACE)-p,$(null),$(MKDIR)) -p $(dir $@)
 	@$(TOUCH) $@
 
 #################################################################
 # One ring/dep to rule them all:
 #   config/rules.mk::all target is available by default
 #   Add $(AUTO_DEPS) as an explicit target dependency when needed.
 #################################################################
+
 AUTO_DEPS +=$(GENERATED_DIRS_DEPS)
 
+
+# Complain loudly if deps have not loaded so getargv != $(NULL)
+ifndef getargv
+  $(error config/makefiles/makeutil.mk has not been included)
+endif
--- a/config/makefiles/makeutils.mk
+++ b/config/makefiles/makeutils.mk
@@ -29,22 +29,8 @@ argv +=)
 ###########################################################################
 ## Access function args as a simple list, inline within user functions.
 ## Usage: $(info ** $(call banner,$(getargv)))
 ##    $(call banner,scalar)
 ##    $(call banner,list0 list1 list2)
 ##    $(call banner,ref) ; ref=foo bar tans
 ## getarglist() would be a more accurate name but is longer to type
 getargv = $(if $(call isvar,$(1)),$($(1)),$(argv))
-
-## http://www.gnu.org/software/make/manual/make.html#Call-Function
-## Usage: o = $(call map,origin,o map $(MAKE))
-map = $(foreach val,$(2),$(call $(1),$(val)))
-
-
-# Usage: $(call checkIfEmpty,[error|warning] foo NULL bar)
-checkIfEmpty =$(foreach var,$(wordlist 2,100,$(getargv)),$(if $(strip $($(var))),$(NOP),$(call $(1),Variable $(var) does not contain a value)))
-
-# Usage: $(call errorIfEmpty,foo NULL bar)
-errorIfEmpty =$(call checkIfEmpty,error $(getargv))
-warnIfEmpty  =$(call checkIfEmpty,warning $(getargv))
-
-
--- a/config/makefiles/test/Makefile.in
+++ b/config/makefiles/test/Makefile.in
@@ -31,24 +31,16 @@ check::
 
 ## Logic processed at compile time so be selective about when to test
 ifneq ($(NULL),$(findstring check,$(MAKECMDGOALS)))
 
 $(info ===========================================================================)
 $(info Running test: $(MAKECMDGOALS): pwd=$(CURDIR))
 $(info ===========================================================================)
 
-
-ifdef VERBOSE
-$(info )
-$(info ===========================================================================)
-$(info Running test: istype, getargv)
-$(info ===========================================================================)
-endif
-
 ## Silent errors are oh so much fun
 ifndef istype
   $(error makeutils.mk was not included)
 endif
 
 # arg_scalar = [scalar|literal]
 arg_list = foo bar
 arg_ref  = arg_list
@@ -93,37 +85,11 @@ ifneq (scalar,$(call getargv,scalar))
 endif
 ifneq ($(arg_list),$(call getargv,arg_list))
   $(error getargv(arg_list)=list, found [$(call getargv,arg_list)])
 endif
 ifneq (arg_list,$(call getargv,arg_ref))
   $(error getargv(arg_ref)=list, found [$(call getargv,arg_ref)])
 endif
 
-
-ifdef MANUAL_TEST
-  # For automated testing a callback is needed that can set an external status
-  # variable that can be tested.  Syntax is tricky to get correct functionality.
-  ifdef VERBOSE
-    $(info )
-    $(info ===========================================================================)
-    $(info Running test: checkIfEmpty)
-    $(info ===========================================================================)
-  endif
-
-  #status =
-  #setTRUE =status=true
-  #setFALSE =status=$(NULL)
-  #$(call checkIfEmpty,setFALSE NULL)
-  #$(if $(status),$(error checkIfEmpty(xyz) failed))
-  #$(call checkIfEmpty,setTRUE xyz)
-  #$(if $(status),$(error checkIfEmpty(xyz) failed))
-  xyz=abc
-  $(info STATUS: warnIfEmpty - two vars)
-  $(call warnIfEmpty,foo xyz bar)
-  $(info STATUS: errorIfEmpty - on first var)
-  $(call errorIfEmpty,foo xyz bar)
-  $(error TEST FAILED: processing should not reach this point)
-endif
-
 endif # check in MAKECMDGOALS
 
 
--- a/config/rules.mk
+++ b/config/rules.mk
@@ -17,16 +17,19 @@ endif
 ifndef INCLUDED_CONFIG_MK
 include $(topsrcdir)/config/config.mk
 endif
 
 ifndef INCLUDED_VERSION_MK
 include $(topsrcdir)/config/version.mk
 endif
 
+include $(topsrcdir)/config/makefiles/makeutils.mk
+include $(topsrcdir)/config/makefiles/autotargets.mk
+
 ifdef SDK_XPIDLSRCS
 XPIDLSRCS += $(SDK_XPIDLSRCS)
 endif
 ifdef SDK_HEADERS
 EXPORTS += $(SDK_HEADERS)
 endif
 
 REPORT_BUILD = @echo $(notdir $<)
@@ -472,18 +475,18 @@ endif
 ifndef HOST_PROGOBJS
 HOST_PROGOBJS		= $(HOST_OBJS)
 endif
 
 # MAKE_DIRS: List of directories to build while looping over directories.
 # A Makefile that needs $(MDDEPDIR) created but doesn't set any of these
 # variables we know to check can just set NEED_MDDEPDIR explicitly.
 ifneq (,$(OBJS)$(XPIDLSRCS)$(SIMPLE_PROGRAMS)$(NEED_MDDEPDIR))
-MAKE_DIRS		+= $(CURDIR)/$(MDDEPDIR)
-GARBAGE_DIRS		+= $(MDDEPDIR)
+MAKE_DIRS       += $(CURDIR)/$(MDDEPDIR)
+GARBAGE_DIRS    += $(CURDIR)/$(MDDEPDIR)
 endif
 
 #
 # Tags: emacs (etags), vi (ctags)
 # TAG_PROGRAM := ctags -L -
 #
 TAG_PROGRAM		= xargs etags -a
 
@@ -1421,42 +1424,41 @@ export:: FORCE
 	@echo "*** Error processing XPIDLSRCS:"
 	@echo "Please define MODULE or XPIDL_MODULE when defining XPIDLSRCS,"
 	@echo "so we have a module name to use when creating MODULE.xpt."
 	@echo; sleep 2; false
 endif
 
 # generate .h files from into $(XPIDL_GEN_DIR), then export to $(DIST)/include;
 # warn against overriding existing .h file.
-$(XPIDL_GEN_DIR)/.done:
-	$(MKDIR) -p $(XPIDL_GEN_DIR)
-	@$(TOUCH) $@
-
-# don't depend on $(XPIDL_GEN_DIR), because the modification date changes
-# with any addition to the directory, regenerating all .h files -> everything.
 
 XPIDL_DEPS = \
   $(topsrcdir)/xpcom/idl-parser/header.py \
   $(topsrcdir)/xpcom/idl-parser/typelib.py \
   $(topsrcdir)/xpcom/idl-parser/xpidl.py \
   $(NULL)
 
-$(XPIDL_GEN_DIR)/%.h: %.idl $(XPIDL_DEPS) $(XPIDL_GEN_DIR)/.done
+xpidl-preqs = \
+  $(call mkdir_deps,$(XPIDL_GEN_DIR)) \
+  $(call mkdir_deps,$(MDDEPDIR)) \
+  $(NULL)
+
+$(XPIDL_GEN_DIR)/%.h: %.idl $(XPIDL_DEPS) $(xpidl-preqs)
 	$(REPORT_BUILD)
 	$(PYTHON_PATH) \
 	  -I$(topsrcdir)/other-licenses/ply \
 	  -I$(topsrcdir)/xpcom/idl-parser \
 	  $(topsrcdir)/xpcom/idl-parser/header.py --cachedir=$(DEPTH)/xpcom/idl-parser $(XPIDL_FLAGS) $(_VPATH_SRCS) -d $(MDDEPDIR)/$(@F).pp -o $@
 	@if test -n "$(findstring $*.h, $(EXPORTS))"; \
 	  then echo "*** WARNING: file $*.h generated from $*.idl overrides $(srcdir)/$*.h"; else true; fi
 
 ifndef NO_GEN_XPT
 # generate intermediate .xpt files into $(XPIDL_GEN_DIR), then link
 # into $(XPIDL_MODULE).xpt and export it to $(FINAL_TARGET)/components.
-$(XPIDL_GEN_DIR)/%.xpt: %.idl $(XPIDL_DEPS) $(XPIDL_GEN_DIR)/.done
+$(XPIDL_GEN_DIR)/%.xpt: %.idl $(XPIDL_DEPS) $(xpidl-preqs)
 	$(REPORT_BUILD)
 	$(PYTHON_PATH) \
 	  -I$(topsrcdir)/other-licenses/ply \
 	  -I$(topsrcdir)/xpcom/idl-parser \
 	  -I$(topsrcdir)/xpcom/typelib/xpt/tools \
 	  $(topsrcdir)/xpcom/idl-parser/typelib.py --cachedir=$(DEPTH)/xpcom/idl-parser $(XPIDL_FLAGS) $(_VPATH_SRCS) -d $(MDDEPDIR)/$(@F).pp -o $@
 
 # no need to link together if XPIDLSRCS contains only XPIDL_MODULE
@@ -1988,17 +1990,17 @@ FREEZE_VARIABLES = \
   EXTRA_PP_COMPONENTS \
   $(NULL)
 
 $(foreach var,$(FREEZE_VARIABLES),$(eval $(var)_FROZEN := '$($(var))'))
 
 CHECK_FROZEN_VARIABLES = $(foreach var,$(FREEZE_VARIABLES), \
   $(if $(subst $($(var)_FROZEN),,'$($(var))'),$(error Makefile variable '$(var)' changed value after including rules.mk. Was $($(var)_FROZEN), now $($(var)).)))
 
-libs export libs::
+libs export::
 	$(CHECK_FROZEN_VARIABLES)
 
 default all::
 	if test -d $(DIST)/bin ; then touch $(DIST)/bin/.purgecaches ; fi
 
 
 #############################################################################
 # Derived targets and dependencies
--- a/config/tests/makefiles/autodeps/Makefile.in
+++ b/config/tests/makefiles/autodeps/Makefile.in
@@ -12,17 +12,16 @@ PYTEST = $(PYTHON) -E
 export PYTHONDONTWRITEBYTECODE=1
 
 DEPTH     = ../../../..
 topsrcdir = @top_srcdir@
 srcdir    = @srcdir@
 VPATH     = @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
-# INCLUDED_CONFIG_MK = 1
 include $(topsrcdir)/config/config.mk
 include $(topsrcdir)/config/rules.mk
 
 autotgt_tests = .deps/autotargets.mk.ts
 
 tgts =\
   .deps/.mkdir.done\
   $(autotgt_tests)
@@ -33,12 +32,10 @@ tgts =\
 ##---]  TARGETS  [---##
 ##------------------_##
 all::
 
 check:: $(tgts)
 
 # Only run unit test when autotargets.mk is modified
 $(autotgt_tests): $(topsrcdir)/config/makefiles/autotargets.mk
-	echo "MAKECMD=$(MAKE)"
 	MAKECMD=$(MAKE) $(PYTEST) $(srcdir)/check_mkdir.tpy
 	@$(TOUCH) $@
-
--- a/config/tests/makefiles/autodeps/testor.tmpl
+++ b/config/tests/makefiles/autodeps/testor.tmpl
@@ -12,16 +12,17 @@
 deps =$(NULL)
 tgts =$(NULL)
 
 ifdef VERBOSE
   tgts += show
 endif
 
 # Define macros
+include $(topsrcdir)/config/makefiles/makeutils.mk
 include $(topsrcdir)/config/makefiles/autotargets.mk
 
 ##########################
 ## Verify threadsafe mkdir
 ##########################
 ifdef deps_mkdir_bycall
   deps += $(call mkdir_deps,deps_mkdir_bycall)
   tgts += check_mkdir
--- a/dom/workers/test/extensions/bootstrap/Makefile.in
+++ b/dom/workers/test/extensions/bootstrap/Makefile.in
@@ -47,13 +47,14 @@ XPI_NAME = workerbootstrap
 DIST_FILES = \
   bootstrap.js \
   install.rdf \
   worker.js \
   $(NULL)
 
 TEST_EXTENSIONS_DIR = $(DEPTH)/_tests/testing/mochitest/extensions
 
+GENERATED_DIRS = $(TEST_EXTENSIONS_DIR)
+
 include $(topsrcdir)/config/rules.mk
 
 libs::
-	$(MKDIR) -p $(TEST_EXTENSIONS_DIR)
 	@(cd $(DIST)/xpi-stage && tar $(TAR_CREATE_FLAGS) - $(XPI_NAME)) | (cd $(TEST_EXTENSIONS_DIR) && tar -xf -)
--- a/dom/workers/test/extensions/traditional/Makefile.in
+++ b/dom/workers/test/extensions/traditional/Makefile.in
@@ -56,13 +56,14 @@ EXTRA_COMPONENTS = \
 
 DIST_FILES = \
   install.rdf \
   worker.js \
   $(NULL)
 
 TEST_EXTENSIONS_DIR = $(DEPTH)/_tests/testing/mochitest/extensions
 
+GENERATED_DIRS = $(TEST_EXTENSIONS_DIR)
+
 include $(topsrcdir)/config/rules.mk
 
 libs::
-	$(MKDIR) -p $(TEST_EXTENSIONS_DIR)
 	@(cd $(DIST)/xpi-stage && tar $(TAR_CREATE_FLAGS) - $(XPI_NAME)) | (cd $(TEST_EXTENSIONS_DIR) && tar -xf -)
--- a/js/src/config/Makefile.in
+++ b/js/src/config/Makefile.in
@@ -84,18 +84,19 @@ include $(topsrcdir)/config/rules.mk
 HOST_CFLAGS += -DUNICODE -D_UNICODE
 
 export:: $(TARGETS)
 ifdef HOST_PROGRAM
 	$(INSTALL) $(HOST_PROGRAM) $(DIST)/bin
 endif
 
 ifdef WRAP_SYSTEM_INCLUDES
-export::
-	if test ! -d system_wrappers_js; then mkdir system_wrappers_js; fi
+export:: \
+  $(call mkdir_deps,system_wrappers_js) \
+  $(NULL)
 	$(PYTHON) $(srcdir)/Preprocessor.py $(DEFINES) $(ACDEFINES) \
 		$(srcdir)/system-headers | $(PERL) $(srcdir)/make-system-wrappers.pl system_wrappers_js
 	$(INSTALL) system_wrappers_js $(DIST)
 
 GARBAGE_DIRS += system_wrappers_js
 endif
 
 GARBAGE += $(srcdir)/*.pyc *.pyc
--- a/js/src/config/config.mk
+++ b/js/src/config/config.mk
@@ -41,17 +41,17 @@
 #
 # Determines the platform and builds the macros needed to load the
 # appropriate platform-specific .mk file, then defines all (most?)
 # of the generic macros.
 #
 
 # Define an include-at-most-once flag
 ifdef INCLUDED_CONFIG_MK
-$(error Don't include config.mk twice!)
+$(error Do not include config.mk twice!)
 endif
 INCLUDED_CONFIG_MK = 1
 
 EXIT_ON_ERROR = set -e; # Shell loops continue past errors without this.
 
 ifndef topsrcdir
 topsrcdir	= $(DEPTH)
 endif
--- a/js/src/config/makefiles/autotargets.mk
+++ b/js/src/config/makefiles/autotargets.mk
@@ -6,32 +6,40 @@
 # You can obtain one at http://mozilla.org/MPL/2.0/.
 #
 
 ###########################################################################
 #      AUTO_DEPS - A list of deps/targets drived from other macros.
 #         *_DEPS - Make dependencies derived from a given macro.
 ###########################################################################
 
+MKDIR ?= mkdir -p
+TOUCH ?= touch
 
 ###########################################################################
 # Threadsafe directory creation
 # GENERATED_DIRS - Automated creation of these directories.
 ###########################################################################
-mkdir_deps =$(foreach dir,$($(1)),$(dir)/.mkdir.done)
+mkdir_deps =$(foreach dir,$(getargv),$(dir)/.mkdir.done)
 
 ifneq (,$(GENERATED_DIRS))
   tmpauto :=$(call mkdir_deps,GENERATED_DIRS)
   GENERATED_DIRS_DEPS +=$(tmpauto)
   GARBAGE_DIRS        +=$(tmpauto)
 endif
 
 %/.mkdir.done:
 	$(subst $(SPACE)-p,$(null),$(MKDIR)) -p $(dir $@)
 	@$(TOUCH) $@
 
 #################################################################
 # One ring/dep to rule them all:
 #   config/rules.mk::all target is available by default
 #   Add $(AUTO_DEPS) as an explicit target dependency when needed.
 #################################################################
+
 AUTO_DEPS +=$(GENERATED_DIRS_DEPS)
 
+
+# Complain loudly if deps have not loaded so getargv != $(NULL)
+ifndef getargv
+  $(error config/makefiles/makeutil.mk has not been included)
+endif
--- a/js/src/config/makefiles/makeutils.mk
+++ b/js/src/config/makefiles/makeutils.mk
@@ -29,22 +29,8 @@ argv +=)
 ###########################################################################
 ## Access function args as a simple list, inline within user functions.
 ## Usage: $(info ** $(call banner,$(getargv)))
 ##    $(call banner,scalar)
 ##    $(call banner,list0 list1 list2)
 ##    $(call banner,ref) ; ref=foo bar tans
 ## getarglist() would be a more accurate name but is longer to type
 getargv = $(if $(call isvar,$(1)),$($(1)),$(argv))
-
-## http://www.gnu.org/software/make/manual/make.html#Call-Function
-## Usage: o = $(call map,origin,o map $(MAKE))
-map = $(foreach val,$(2),$(call $(1),$(val)))
-
-
-# Usage: $(call checkIfEmpty,[error|warning] foo NULL bar)
-checkIfEmpty =$(foreach var,$(wordlist 2,100,$(getargv)),$(if $(strip $($(var))),$(NOP),$(call $(1),Variable $(var) does not contain a value)))
-
-# Usage: $(call errorIfEmpty,foo NULL bar)
-errorIfEmpty =$(call checkIfEmpty,error $(getargv))
-warnIfEmpty  =$(call checkIfEmpty,warning $(getargv))
-
-
--- a/js/src/config/rules.mk
+++ b/js/src/config/rules.mk
@@ -17,16 +17,19 @@ endif
 ifndef INCLUDED_CONFIG_MK
 include $(topsrcdir)/config/config.mk
 endif
 
 ifndef INCLUDED_VERSION_MK
 include $(topsrcdir)/config/version.mk
 endif
 
+include $(topsrcdir)/config/makefiles/makeutils.mk
+include $(topsrcdir)/config/makefiles/autotargets.mk
+
 ifdef SDK_XPIDLSRCS
 XPIDLSRCS += $(SDK_XPIDLSRCS)
 endif
 ifdef SDK_HEADERS
 EXPORTS += $(SDK_HEADERS)
 endif
 
 REPORT_BUILD = @echo $(notdir $<)
@@ -472,18 +475,18 @@ endif
 ifndef HOST_PROGOBJS
 HOST_PROGOBJS		= $(HOST_OBJS)
 endif
 
 # MAKE_DIRS: List of directories to build while looping over directories.
 # A Makefile that needs $(MDDEPDIR) created but doesn't set any of these
 # variables we know to check can just set NEED_MDDEPDIR explicitly.
 ifneq (,$(OBJS)$(XPIDLSRCS)$(SIMPLE_PROGRAMS)$(NEED_MDDEPDIR))
-MAKE_DIRS		+= $(CURDIR)/$(MDDEPDIR)
-GARBAGE_DIRS		+= $(MDDEPDIR)
+MAKE_DIRS       += $(CURDIR)/$(MDDEPDIR)
+GARBAGE_DIRS    += $(CURDIR)/$(MDDEPDIR)
 endif
 
 #
 # Tags: emacs (etags), vi (ctags)
 # TAG_PROGRAM := ctags -L -
 #
 TAG_PROGRAM		= xargs etags -a
 
@@ -1421,42 +1424,41 @@ export:: FORCE
 	@echo "*** Error processing XPIDLSRCS:"
 	@echo "Please define MODULE or XPIDL_MODULE when defining XPIDLSRCS,"
 	@echo "so we have a module name to use when creating MODULE.xpt."
 	@echo; sleep 2; false
 endif
 
 # generate .h files from into $(XPIDL_GEN_DIR), then export to $(DIST)/include;
 # warn against overriding existing .h file.
-$(XPIDL_GEN_DIR)/.done:
-	$(MKDIR) -p $(XPIDL_GEN_DIR)
-	@$(TOUCH) $@
-
-# don't depend on $(XPIDL_GEN_DIR), because the modification date changes
-# with any addition to the directory, regenerating all .h files -> everything.
 
 XPIDL_DEPS = \
   $(topsrcdir)/xpcom/idl-parser/header.py \
   $(topsrcdir)/xpcom/idl-parser/typelib.py \
   $(topsrcdir)/xpcom/idl-parser/xpidl.py \
   $(NULL)
 
-$(XPIDL_GEN_DIR)/%.h: %.idl $(XPIDL_DEPS) $(XPIDL_GEN_DIR)/.done
+xpidl-preqs = \
+  $(call mkdir_deps,$(XPIDL_GEN_DIR)) \
+  $(call mkdir_deps,$(MDDEPDIR)) \
+  $(NULL)
+
+$(XPIDL_GEN_DIR)/%.h: %.idl $(XPIDL_DEPS) $(xpidl-preqs)
 	$(REPORT_BUILD)
 	$(PYTHON_PATH) \
 	  -I$(topsrcdir)/other-licenses/ply \
 	  -I$(topsrcdir)/xpcom/idl-parser \
 	  $(topsrcdir)/xpcom/idl-parser/header.py --cachedir=$(DEPTH)/xpcom/idl-parser $(XPIDL_FLAGS) $(_VPATH_SRCS) -d $(MDDEPDIR)/$(@F).pp -o $@
 	@if test -n "$(findstring $*.h, $(EXPORTS))"; \
 	  then echo "*** WARNING: file $*.h generated from $*.idl overrides $(srcdir)/$*.h"; else true; fi
 
 ifndef NO_GEN_XPT
 # generate intermediate .xpt files into $(XPIDL_GEN_DIR), then link
 # into $(XPIDL_MODULE).xpt and export it to $(FINAL_TARGET)/components.
-$(XPIDL_GEN_DIR)/%.xpt: %.idl $(XPIDL_DEPS) $(XPIDL_GEN_DIR)/.done
+$(XPIDL_GEN_DIR)/%.xpt: %.idl $(XPIDL_DEPS) $(xpidl-preqs)
 	$(REPORT_BUILD)
 	$(PYTHON_PATH) \
 	  -I$(topsrcdir)/other-licenses/ply \
 	  -I$(topsrcdir)/xpcom/idl-parser \
 	  -I$(topsrcdir)/xpcom/typelib/xpt/tools \
 	  $(topsrcdir)/xpcom/idl-parser/typelib.py --cachedir=$(DEPTH)/xpcom/idl-parser $(XPIDL_FLAGS) $(_VPATH_SRCS) -d $(MDDEPDIR)/$(@F).pp -o $@
 
 # no need to link together if XPIDLSRCS contains only XPIDL_MODULE
@@ -1988,17 +1990,17 @@ FREEZE_VARIABLES = \
   EXTRA_PP_COMPONENTS \
   $(NULL)
 
 $(foreach var,$(FREEZE_VARIABLES),$(eval $(var)_FROZEN := '$($(var))'))
 
 CHECK_FROZEN_VARIABLES = $(foreach var,$(FREEZE_VARIABLES), \
   $(if $(subst $($(var)_FROZEN),,'$($(var))'),$(error Makefile variable '$(var)' changed value after including rules.mk. Was $($(var)_FROZEN), now $($(var)).)))
 
-libs export libs::
+libs export::
 	$(CHECK_FROZEN_VARIABLES)
 
 default all::
 	if test -d $(DIST)/bin ; then touch $(DIST)/bin/.purgecaches ; fi
 
 
 #############################################################################
 # Derived targets and dependencies