8076060: Improve make bootstrap process
authorihse
Thu, 26 Mar 2015 16:17:30 +0100
changeset 29662 78c47f0002c3
parent 29565 34ead0aa3d9d
child 29663 74ff65003536
child 29667 c3348fd718cc
8076060: Improve make bootstrap process Reviewed-by: erikj
Makefile
common/autoconf/basics.m4
common/autoconf/configure.ac
common/autoconf/generated-configure.sh
common/autoconf/spec.gmk.in
configure
make/Help.gmk
make/HotspotWrapper.gmk
make/Init.gmk
make/InitSupport.gmk
make/Jprt.gmk
make/Main.gmk
make/MainSupport.gmk
make/MakeHelpers.gmk
make/common/MakeBase.gmk
--- a/Makefile	Mon Mar 23 11:44:40 2015 -0700
+++ b/Makefile	Thu Mar 26 16:17:30 2015 +0100
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -23,200 +23,42 @@
 # questions.
 #
 
-# This must be the first rule
-default:
+###
+### This file is just a very small wrapper needed to run the real make/Init.gmk.
+### It also performs some sanity checks on make.
+###
 
-# Inclusion of this pseudo-target will cause make to execute this file
-# serially, regardless of -j. Recursively called makefiles will not be
-# affected, however. This is required for correct dependency management.
-.NOTPARALLEL:
+# The shell code below will be executed on /usr/ccs/bin/make on Solaris, but not in GNU Make.
+# /usr/ccs/bin/make lacks basically every other flow control mechanism.
+.TEST_FOR_NON_GNUMAKE:sh=echo You are not using GNU Make/gmake, this is a requirement. Check your path. 1>&2 && exit 1
 
-# The shell code below will be executed on /usr/ccs/bin/make on Solaris, but not in GNU make.
-# /usr/ccs/bin/make lacks basically every other flow control mechanism.
-.TEST_FOR_NON_GNUMAKE:sh=echo You are not using GNU make/gmake, this is a requirement. Check your path. 1>&2 && exit 1
+# The .FEATURES variable is likely to be unique for GNU Make.
+ifeq ($(.FEATURES), )
+  $(info Error: '$(MAKE)' does not seem to be GNU Make, which is a requirement.)
+  $(info Check your path, or upgrade to GNU Make 3.81 or newer.)
+  $(error Cannot continue)
+endif
 
-# Assume we have GNU make, but check version.
+# Assume we have GNU Make, but check version.
 ifeq ($(strip $(foreach v, 3.81% 3.82% 4.%, $(filter $v, $(MAKE_VERSION)))), )
-  $(error This version of GNU Make is too low ($(MAKE_VERSION)). Check your path, or upgrade to 3.81 or newer.)
+  $(info Error: This version of GNU Make is too low ($(MAKE_VERSION)).)
+  $(info Check your path, or upgrade to GNU Make 3.81 or newer.)
+  $(error Cannot continue)
+endif
+
+# In Cygwin, the MAKE variable gets prepended with the current directory if the
+# make executable is called using a Windows mixed path (c:/cygwin/bin/make.exe).
+ifneq ($(findstring :, $(MAKE)), )
+  MAKE := $(patsubst $(CURDIR)%, %, $(patsubst $(CURDIR)/%, %, $(MAKE)))
 endif
 
 # Locate this Makefile
-ifeq ($(filter /%,$(lastword $(MAKEFILE_LIST))),)
-  makefile_path:=$(CURDIR)/$(lastword $(MAKEFILE_LIST))
+ifeq ($(filter /%, $(lastword $(MAKEFILE_LIST))),)
+  makefile_path := $(CURDIR)/$(strip $(lastword $(MAKEFILE_LIST)))
 else
-  makefile_path:=$(lastword $(MAKEFILE_LIST))
-endif
-root_dir:=$(patsubst %/,%,$(dir $(makefile_path)))
-
-ifeq ($(MAIN_TARGETS), )
-  COMMAND_LINE_VARIABLES:=$(subst =command,,$(filter %=command,$(foreach var,$(.VARIABLES),$(var)=$(firstword $(origin $(var))))))
-  MAKE_CONTROL_VARIABLES:=LOG CONF SPEC JOBS TEST IGNORE_OLD_CONFIG
-  UNKNOWN_COMMAND_LINE_VARIABLES:=$(strip $(filter-out $(MAKE_CONTROL_VARIABLES), $(COMMAND_LINE_VARIABLES)))
-  ifneq ($(UNKNOWN_COMMAND_LINE_VARIABLES), )
-    $(info Note: Command line contains non-control variables: $(UNKNOWN_COMMAND_LINE_VARIABLES).)
-    $(info Make sure it is not mistyped, and that you intend to override this variable.)
-    $(info 'make help' will list known control variables)
-  endif
-endif
-
-ifneq ($(findstring qp,$(MAKEFLAGS)),)
-  # When called with -qp, assume an external part (e.g. bash completion) is trying
-  # to understand our targets.
-  # Duplication of global targets, needed before ParseConfAndSpec in case we have
-  # no configurations.
-  help:
-  # If both CONF and SPEC are unset, look for all available configurations by
-  # setting CONF to the empty string.
-  ifeq ($(SPEC), )
-    CONF?=
-  endif
+  makefile_path := $(lastword $(MAKEFILE_LIST))
 endif
-
-# ... and then we can include our helper functions
-include $(root_dir)/make/MakeHelpers.gmk
-
-$(eval $(call ParseLogLevel))
-$(eval $(call ParseConfAndSpec))
-
-# Now determine if we have zero, one or several configurations to build.
-ifeq ($(SPEC),)
-  # Since we got past ParseConfAndSpec, we must be building a global target. Do nothing.
-else
-  # In Cygwin, the MAKE variable gets messed up if the make executable is called with
-  # a Windows mixed path (c:/cygwin/bin/make.exe). If that's the case, fix it by removing
-  # the prepended root_dir.
-  ifneq ($(findstring :, $(MAKE)), )
-    MAKE := $(patsubst $(root_dir)%, %, $(MAKE))
-  endif
-
-  # We are potentially building multiple configurations.
-  # First, find out the valid targets
-  # Run the makefile with an arbitrary SPEC using -p -q (quiet dry-run and dump rules) to find
-  # available PHONY targets. Use this list as valid targets to pass on to the repeated calls.
-  all_phony_targets := $(sort $(filter-out $(global_targets), $(strip $(shell \
-      cd $(root_dir)/make && $(MAKE) -f Main.gmk -p -q FRC SPEC=$(firstword $(SPEC)) \
-      -I $(root_dir)/make/common | grep "^.PHONY:" | head -n 1 | cut -d " " -f 2-))))
-
-  # Loop through the configurations and call the main-wrapper for each one. The wrapper
-  # target will execute with a single configuration loaded.
-  $(all_phony_targets):
-	@$(if $(TARGET_RUN),,\
-          $(foreach spec,$(SPEC),\
-            (cd $(root_dir) && $(MAKE) SPEC=$(spec) MAIN_TARGETS="$(call GetRealTarget)" \
-	    $(VERBOSE) VERBOSE=$(VERBOSE) LOG_LEVEL=$(LOG_LEVEL) main-wrapper) &&) true)
-	@echo > /dev/null
-	$(eval TARGET_RUN=true)
-
-  .PHONY: $(all_phony_targets)
-
-  ifneq ($(MAIN_TARGETS), )
-    # The wrapper target was called so we now have a single configuration. Load the spec file
-    # and call the real Main.gmk.
-    include $(SPEC)
-    include $(SRC_ROOT)/make/common/MakeBase.gmk
+topdir := $(strip $(patsubst %/, %, $(dir $(makefile_path))))
 
-    ### Clean up from previous run
-    # Remove any build.log from a previous run, if they exist
-    ifneq (,$(BUILD_LOG))
-      ifneq (,$(BUILD_LOG_PREVIOUS))
-        # Rotate old log
-        $(shell $(RM) $(BUILD_LOG_PREVIOUS) 2> /dev/null)
-        $(shell $(MV) $(BUILD_LOG) $(BUILD_LOG_PREVIOUS) 2> /dev/null)
-      else
-        $(shell $(RM) $(BUILD_LOG) 2> /dev/null)
-      endif
-      $(shell $(RM) $(OUTPUT_ROOT)/build-trace-time.log 2> /dev/null)
-    endif
-    # Remove any javac server logs and port files. This
-    # prevents a new make run to reuse the previous servers.
-    ifneq (,$(SJAVAC_SERVER_DIR))
-      $(shell $(MKDIR) -p $(SJAVAC_SERVER_DIR) && $(RM) -rf $(SJAVAC_SERVER_DIR)/*)
-    endif
-
-    # Split out the targets requiring sequential execution. Run these targets separately
-    # from the rest so that the rest may still enjoy full parallel execution.
-    SEQUENTIAL_TARGETS := $(filter dist-clean clean% reconfigure, $(MAIN_TARGETS))
-    PARALLEL_TARGETS := $(filter-out $(SEQUENTIAL_TARGETS), $(MAIN_TARGETS))
-
-    main-wrapper:
-        ifneq ($(SEQUENTIAL_TARGETS), )
-	  (cd $(SRC_ROOT)/make && $(MAKE) -f Main.gmk SPEC=$(SPEC) -j 1 \
-	      $(VERBOSE) VERBOSE=$(VERBOSE) LOG_LEVEL=$(LOG_LEVEL) $(SEQUENTIAL_TARGETS))
-        endif
-        ifneq ($(PARALLEL_TARGETS), )
-	  @$(call AtMakeStart)
-	  (cd $(SRC_ROOT)/make && $(BUILD_LOG_WRAPPER) $(MAKE) -f Main.gmk SPEC=$(SPEC) -j $(JOBS) \
-	      $(VERBOSE) VERBOSE=$(VERBOSE) LOG_LEVEL=$(LOG_LEVEL) $(PARALLEL_TARGETS) \
-	      $(if $(filter true, $(OUTPUT_SYNC_SUPPORTED)), -O$(OUTPUT_SYNC)))
-	  @$(call AtMakeEnd)
-        endif
-
-     .PHONY: main-wrapper
-
-   endif
-endif
-
-# Here are "global" targets, i.e. targets that can be executed without specifying a single configuration.
-# If you add more global targets, please update the variable global_targets in MakeHelpers.
-
-# Helper macro to allow $(info) to properly print strings beginning with spaces.
-_:=
-
-help:
-	$(info )
-	$(info OpenJDK Makefile help)
-	$(info =====================)
-	$(info )
-	$(info Common make targets)
-	$(info $(_) make [default]         # Compile all modules in langtools, hotspot, jdk, jaxws,)
-	$(info $(_)                        # jaxp and corba, and create a runnable "exploded" image)
-	$(info $(_) make all               # Compile everything, all repos, docs and images)
-	$(info $(_) make images            # Create complete j2sdk and j2re images)
-	$(info $(_) make <phase>           # Build the specified phase and everything it depends on)
-	$(info $(_)                        # (gensrc, java, copy, libs, launchers, gendata, rmic))
-	$(info $(_) make *-only            # Applies to most targets and disables compling the)
-	$(info $(_)                        # dependencies for the target. This is faster but may)
-	$(info $(_)                        # result in incorrect build results!)
-	$(info $(_) make docs              # Create all docs)
-	$(info $(_) make docs-javadoc      # Create just javadocs, depends on less than full docs)
-	$(info $(_) make profiles          # Create complete j2re compact profile images)
-	$(info $(_) make bootcycle-images  # Build images twice, second time with newly built JDK)
-	$(info $(_) make install           # Install the generated images locally)
-	$(info $(_) make reconfigure       # Rerun configure with the same arguments as last time)
-	$(info $(_) make help              # Give some help on using make)
-	$(info $(_) make test              # Run tests, default is all tests (see TEST below))
-	$(info )
-	$(info Targets for cleaning)
-	$(info $(_) make clean             # Remove all files generated by make, but not those)
-	$(info $(_)                        # generated by configure)
-	$(info $(_) make dist-clean        # Remove all files, including configuration)
-	$(info $(_) make clean-<outputdir> # Remove the subdir in the output dir with the name)
-	$(info $(_) make clean-<phase>     # Remove all build results related to a certain build)
-	$(info $(_)                        # phase (gensrc, java, libs, launchers))
-	$(info $(_) make clean-<module>    # Remove all build results related to a certain module)
-	$(info $(_) make clean-<module>-<phase> # Remove all build results related to a certain)
-	$(info $(_)                        # module and phase)
-	$(info )
-	$(info Targets for specific modules)
-	$(info $(_) make <module>          # Build <module> and everything it depends on.)
-	$(info $(_) make <module>-<phase>  # Compile the specified phase for the specified module)
-	$(info $(_)                        # and everything it depends on)
-	$(info $(_)                        # (gensrc, java, copy, libs, launchers, gendata, rmic))
-	$(info )
-	$(info Make control variables)
-	$(info $(_) CONF=                  # Build all configurations (note, assignment is empty))
-	$(info $(_) CONF=<substring>       # Build the configuration(s) with a name matching)
-	$(info $(_)                        # <substring>)
-	$(info $(_) SPEC=<spec file>       # Build the configuration given by the spec file)
-	$(info $(_) LOG=<loglevel>         # Change the log level from warn to <loglevel>)
-	$(info $(_)                        # Available log levels are:)
-	$(info $(_)                        # 'warn' (default), 'info', 'debug' and 'trace')
-	$(info $(_)                        # To see executed command lines, use LOG=debug)
-	$(info $(_) JOBS=<n>               # Run <n> parallel make jobs)
-	$(info $(_)                        # Note that -jN does not work as expected!)
-	$(info $(_) IGNORE_OLD_CONFIG=true # Skip tests if spec file is up to date)
-	$(info $(_) make test TEST=<test>  # Only run the given test or tests, e.g.)
-	$(info $(_)                        # make test TEST="jdk_lang jdk_net")
-	$(info )
-
-.PHONY: help
+# ... and then we can include the real makefile
+include $(topdir)/make/Init.gmk
--- a/common/autoconf/basics.m4	Mon Mar 23 11:44:40 2015 -0700
+++ b/common/autoconf/basics.m4	Thu Mar 26 16:17:30 2015 +0100
@@ -78,7 +78,7 @@
 AC_DEFUN([BASIC_FIXUP_PATH],
 [
   # Only process if variable expands to non-empty
-  
+
   if test "x[$]$1" != x; then
     if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.cygwin"; then
       BASIC_FIXUP_PATH_CYGWIN($1)
@@ -118,7 +118,7 @@
 AC_DEFUN([BASIC_FIXUP_EXECUTABLE],
 [
   # Only process if variable expands to non-empty
-  
+
   if test "x[$]$1" != x; then
     if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.cygwin"; then
       BASIC_FIXUP_EXECUTABLE_CYGWIN($1)
@@ -709,18 +709,6 @@
   AC_CONFIG_FILES([$OUTPUT_ROOT/Makefile:$AUTOCONF_DIR/Makefile.in])
 ])
 
-AC_DEFUN_ONCE([BASIC_SETUP_LOGGING],
-[
-  # Setup default logging of stdout and stderr to build.log in the output root.
-  BUILD_LOG='$(OUTPUT_ROOT)/build.log'
-  BUILD_LOG_PREVIOUS='$(OUTPUT_ROOT)/build.log.old'
-  BUILD_LOG_WRAPPER='$(BASH) $(SRC_ROOT)/common/bin/logger.sh $(BUILD_LOG)'
-  AC_SUBST(BUILD_LOG)
-  AC_SUBST(BUILD_LOG_PREVIOUS)
-  AC_SUBST(BUILD_LOG_WRAPPER)
-])
-
-
 #%%% Simple tools %%%
 
 # Check if we have found a usable version of make
--- a/common/autoconf/configure.ac	Mon Mar 23 11:44:40 2015 -0700
+++ b/common/autoconf/configure.ac	Thu Mar 26 16:17:30 2015 +0100
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -88,7 +88,6 @@
 
 # Continue setting up basic stuff. Most remaining code require fundamental tools.
 BASIC_SETUP_PATHS
-BASIC_SETUP_LOGGING
 
 # Check if it's a pure open build or if custom sources are to be used.
 JDKOPT_SETUP_OPEN_OR_CUSTOM
--- a/common/autoconf/generated-configure.sh	Mon Mar 23 11:44:40 2015 -0700
+++ b/common/autoconf/generated-configure.sh	Thu Mar 26 16:17:30 2015 +0100
@@ -907,9 +907,6 @@
 JVM_INTERPRETER
 JDK_VARIANT
 SET_OPENJDK
-BUILD_LOG_WRAPPER
-BUILD_LOG_PREVIOUS
-BUILD_LOG
 TOPDIR
 PATH_SEP
 ZERO_ARCHDEF
@@ -3471,9 +3468,6 @@
 
 
 
-
-
-
 #%%% Simple tools %%%
 
 # Check if we have found a usable version of make
@@ -4369,7 +4363,7 @@
 #CUSTOM_AUTOCONF_INCLUDE
 
 # Do not change or remove the following line, it is needed for consistency checks:
-DATE_WHEN_GENERATED=1426774983
+DATE_WHEN_GENERATED=1427382753
 
 ###############################################################################
 #
@@ -14401,15 +14395,6 @@
   AUTOCONF_DIR=$TOPDIR/common/autoconf
 
 
-  # Setup default logging of stdout and stderr to build.log in the output root.
-  BUILD_LOG='$(OUTPUT_ROOT)/build.log'
-  BUILD_LOG_PREVIOUS='$(OUTPUT_ROOT)/build.log.old'
-  BUILD_LOG_WRAPPER='$(BASH) $(SRC_ROOT)/common/bin/logger.sh $(BUILD_LOG)'
-
-
-
-
-
 # Check if it's a pure open build or if custom sources are to be used.
 
   # Check whether --enable-openjdk-only was given.
--- a/common/autoconf/spec.gmk.in	Mon Mar 23 11:44:40 2015 -0700
+++ b/common/autoconf/spec.gmk.in	Thu Mar 26 16:17:30 2015 +0100
@@ -55,25 +55,12 @@
 # A self-referential reference to this file.
 SPEC:=@SPEC@
 
-# Specify where the spec file is.
-MAKE_ARGS="SPEC=$(SPEC)"
-
-MAKE:=@MAKE@
-
-# Pass along the verbosity and log level settings.
-ifeq (,$(findstring VERBOSE=,$(MAKE)))
-  MAKE:=$(MAKE) $(VERBOSE) VERBOSE="$(VERBOSE)" LOG_LEVEL="$(LOG_LEVEL)"
-endif
+# What make to use for main processing, after bootstrapping top-level Makefile.
+MAKE := @MAKE@
 
-# No implicit variables or rules!
-ifeq (,$(findstring -R,$(MAKE)))
-  MAKE:=$(MAKE) -R
-endif
-
-# Specify where the common include directory for makefiles is.
-ifeq (,$(findstring -I @TOPDIR@/make/common,$(MAKE)))
-  MAKE:=$(MAKE) -I @TOPDIR@/make/common
-endif
+# The default make arguments
+MAKE_ARGS = $(MAKE_LOG_FLAGS) -R -I $(TOPDIR)/make/common SPEC=$(SPEC) \
+    MAKE_LOG_FLAGS="$(MAKE_LOG_FLAGS)" LOG_LEVEL=$(LOG_LEVEL)
 
 OUTPUT_SYNC_SUPPORTED:=@OUTPUT_SYNC_SUPPORTED@
 OUTPUT_SYNC:=@OUTPUT_SYNC@
@@ -573,18 +560,6 @@
 XCODEBUILD=@XCODEBUILD@
 FIXPATH:=@FIXPATH@
 
-# Where the build output is stored for your convenience.
-BUILD_LOG:=@BUILD_LOG@
-BUILD_LOG_PREVIOUS:=@BUILD_LOG_PREVIOUS@
-# Disable the build log wrapper on sjavac+windows until
-# we have solved how to prevent the log wrapper to wait
-# for the background sjavac server process.
-ifeq (@ENABLE_SJAVAC@X@OPENJDK_BUILD_OS@,yesXwindows)
-  BUILD_LOG_WRAPPER:=
-else
-  BUILD_LOG_WRAPPER:=@BUILD_LOG_WRAPPER@
-endif
-
 # Build setup
 ENABLE_JFR=@ENABLE_JFR@
 ENABLE_INTREE_EC=@ENABLE_INTREE_EC@
--- a/configure	Mon Mar 23 11:44:40 2015 -0700
+++ b/configure	Thu Mar 26 16:17:30 2015 +0100
@@ -31,4 +31,5 @@
 
 # Delegate to wrapper, forcing wrapper to believe $0 is this script by using -c.
 # This trick is needed to get autoconf to co-operate properly.
-bash -c ". $this_script_dir/common/autoconf/configure" $this_script_dir/configure CHECKME $this_script_dir "$@"
+# The ${-:+-$-} construction passes on bash options.
+bash ${-:+-$-} -c ". $this_script_dir/common/autoconf/configure" $this_script_dir/configure CHECKME $this_script_dir "$@"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/Help.gmk	Thu Mar 26 16:17:30 2015 +0100
@@ -0,0 +1,115 @@
+#
+# Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.  Oracle designates this
+# particular file as subject to the "Classpath" exception as provided
+# by Oracle in the LICENSE file that accompanied this code.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+###
+### Global targets for printing help etc.
+###
+
+# Helper macro to allow $(info) to properly print strings beginning with spaces.
+_:=
+
+help:
+	$(info )
+	$(info OpenJDK Makefile help)
+	$(info =====================)
+	$(info )
+	$(info Common make targets)
+	$(info $(_) make [default]         # Compile all modules in langtools, hotspot, jdk, jaxws,)
+	$(info $(_)                        # jaxp and corba, and create a runnable "exploded" image)
+	$(info $(_) make all               # Compile everything, all repos, docs and images)
+	$(info $(_) make images            # Create complete jdk and jre images)
+	$(info $(_) make <phase>           # Build the specified phase and everything it depends on)
+	$(info $(_)                        # (gensrc, java, copy, libs, launchers, gendata, rmic))
+	$(info $(_) make *-only            # Applies to most targets and disables compling the)
+	$(info $(_)                        # dependencies for the target. This is faster but may)
+	$(info $(_)                        # result in incorrect build results!)
+	$(info $(_) make docs              # Create all docs)
+	$(info $(_) make docs-javadoc      # Create just javadocs, depends on less than full docs)
+	$(info $(_) make profiles          # Create complete jre compact profile images)
+	$(info $(_) make bootcycle-images  # Build images twice, second time with newly built JDK)
+	$(info $(_) make install           # Install the generated images locally)
+	$(info $(_) make reconfigure       # Rerun configure with the same arguments as last time)
+	$(info $(_) make help              # Give some help on using make)
+	$(info $(_) make test              # Run tests, default is all tests (see TEST below))
+	$(info )
+	$(info Targets for cleaning)
+	$(info $(_) make clean             # Remove all files generated by make, but not those)
+	$(info $(_)                        # generated by configure)
+	$(info $(_) make dist-clean        # Remove all files, including configuration)
+	$(info $(_) make clean-<outputdir> # Remove the subdir in the output dir with the name)
+	$(info $(_) make clean-<phase>     # Remove all build results related to a certain build)
+	$(info $(_)                        # phase (gensrc, java, libs, launchers))
+	$(info $(_) make clean-<module>    # Remove all build results related to a certain module)
+	$(info $(_) make clean-<module>-<phase> # Remove all build results related to a certain)
+	$(info $(_)                        # module and phase)
+	$(info )
+	$(info Targets for specific modules)
+	$(info $(_) make <module>          # Build <module> and everything it depends on)
+	$(info $(_) make <module>-<phase>  # Compile the specified phase for the specified module)
+	$(info $(_)                        # and everything it depends on)
+	$(info $(_)                        # (gensrc, java, copy, libs, launchers, gendata, rmic))
+	$(info )
+	$(info Make control variables)
+	$(info $(_) CONF=                  # Build all configurations (note, assignment is empty))
+	$(info $(_) CONF=<substring>       # Build the configuration(s) with a name matching)
+	$(info $(_)                        # <substring>)
+	$(info $(_) SPEC=<spec file>       # Build the configuration given by the spec file)
+	$(info $(_) LOG=<loglevel>         # Change the log level from warn to <loglevel>)
+	$(info $(_)                        # Available log levels are:)
+	$(info $(_)                        # 'warn' (default), 'info', 'debug' and 'trace')
+	$(info $(_)                        # To see executed command lines, use LOG=debug)
+	$(info $(_) JOBS=<n>               # Run <n> parallel make jobs)
+	$(info $(_)                        # Note that -jN does not work as expected!)
+	$(info $(_) CONF_CHECK=<method>    # What to do if spec file is out of date)
+	$(info $(_)                        # method is 'auto', 'ignore' or 'fail' (default))
+	$(info $(_) make test TEST=<test>  # Only run the given test or tests, e.g.)
+	$(info $(_)                        # make test TEST="jdk_lang jdk_net")
+	$(info )
+	$(if $(all_confs), $(info Available configurations in $(build_dir):) $(foreach var,$(all_confs),$(info * $(var))),\
+	    $(info No configurations were found in $(build_dir).) $(info Run 'bash configure' to create a configuration))
+        # We need a dummy rule otherwise make will complain
+	@true
+
+print-targets:
+	$(if $(any_spec_file), ,\
+	  @echo "Note: More targets will be available when at least one configuration exists." 1>&2\
+	)
+	@echo $(ALL_TARGETS)
+
+print-modules:
+	$(if $(any_spec_file), \
+	  @$(MAKE) -s -f $(topdir)/make/Main.gmk -I $(topdir)/make/common SPEC=$(any_spec_file) print-modules \
+	, \
+	  @echo print-modules can currently only be run when at least one configuration exists \
+	)
+
+print-configurations:
+	$(foreach var, $(all_confs), $(info $(var)))
+        # We need a dummy rule otherwise make will complain
+	@true
+
+ALL_GLOBAL_TARGETS := help print-modules print-targets print-configurations
+
+.PHONY: $(ALL_GLOBAL_TARGETS)
--- a/make/HotspotWrapper.gmk	Mon Mar 23 11:44:40 2015 -0700
+++ b/make/HotspotWrapper.gmk	Thu Mar 26 16:17:30 2015 +0100
@@ -42,7 +42,7 @@
 # not doing it breaks builds on msys.
 $(HOTSPOT_OUTPUTDIR)/_hotspot.timestamp: $(HOTSPOT_FILES)
 	@$(MKDIR) -p $(HOTSPOT_OUTPUTDIR)
-	@($(CD) $(HOTSPOT_TOPDIR)/make && $(MAKE) $(HOTSPOT_MAKE_ARGS) SPEC=$(HOTSPOT_SPEC) BASE_SPEC=$(BASE_SPEC))
+	@($(CD) $(HOTSPOT_TOPDIR)/make && $(MAKE) $(HOTSPOT_MAKE_ARGS) LOG_LEVEL=$(LOG_LEVEL) SPEC=$(HOTSPOT_SPEC) BASE_SPEC=$(BASE_SPEC))
 	$(TOUCH) $@
 
 hotspot: $(HOTSPOT_OUTPUTDIR)/_hotspot.timestamp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/Init.gmk	Thu Mar 26 16:17:30 2015 +0100
@@ -0,0 +1,229 @@
+#
+# Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.  Oracle designates this
+# particular file as subject to the "Classpath" exception as provided
+# by Oracle in the LICENSE file that accompanied this code.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+################################################################################
+# This is the bootstrapping part of the build. This file is included from the
+# top level Makefile, and is responsible for launching the Main.gmk file with
+# the proper make and the proper make arguments.
+################################################################################
+
+# This must be the first rule
+default:
+.PHONY: default
+
+# Inclusion of this pseudo-target will cause make to execute this file
+# serially, regardless of -j.
+.NOTPARALLEL:
+
+# If included from the top-level Makefile then topdir is set, but not when
+# recursively calling ourself with a spec.
+ifeq ($(topdir),)
+  topdir := $(strip $(patsubst %/make/, %, $(dir $(lastword $(MAKEFILE_LIST)))))
+endif
+
+# Our helper functions. Will include $(SPEC) if $(HAS_SPEC) is true.
+include $(topdir)/make/InitSupport.gmk
+
+# Here are "global" targets, i.e. targets that can be executed without having a configuration.
+# This will define ALL_GLOBAL_TARGETS.
+include $(topdir)/make/Help.gmk
+
+# Extract main targets from Main.gmk.
+ifneq ($(any_spec_file), )
+  ifeq ($(wildcard $(dir $(any_spec_file))/make-support),)
+    # If make-support does not exist, we need to build the genmodules java tool first.
+    $(info Creating data for first make execution in new configuration...)
+    ignore_output := $(shell $(MAKE) -r -R -f $(topdir)/make/Main.gmk \
+        -I $(topdir)/make/common SPEC=$(any_spec_file) NO_RECIPES=true FRC)
+    $(info Done)
+  endif
+  ALL_MAIN_TARGETS := $(shell $(MAKE) -r -R -f $(topdir)/make/Main.gmk \
+      -I $(topdir)/make/common SPEC=$(any_spec_file) NO_RECIPES=true print-targets)
+else
+  # Without at least a single valid configuration, we cannot extract any real
+  # targets. To provide a helpful error message about the missing configuration
+  # later on, accept whatever targets the user has provided for now.
+  ALL_MAIN_TARGETS := $(if $(MAKECMDGOALS), $(MAKECMDGOALS), default)
+endif
+
+# Targets provided by this file.
+ALL_INIT_TARGETS := reconfigure
+
+ALL_TARGETS := $(sort $(ALL_GLOBAL_TARGETS) $(ALL_MAIN_TARGETS) $(ALL_INIT_TARGETS))
+
+ifneq ($(findstring qp, $(MAKEFLAGS)),)
+  ##############################################################################
+  # When called with -qp, assume an external part (e.g. bash completion) is trying
+  # to understand our targets. Just list our targets and do no more checking.
+  ##############################################################################
+
+  $(ALL_TARGETS):
+
+  .PHONY: $(ALL_TARGETS)
+
+else ifeq ($(HAS_SPEC),)
+
+  ##############################################################################
+  # This is the normal case, we have been called from the command line by the
+  # user and we need to call ourself back with a proper SPEC.
+  ##############################################################################
+
+  $(eval $(call CheckControlVariables))
+  $(eval $(call CheckDeprecatedEnvironment))
+  $(eval $(call CheckInvalidMakeFlags))
+
+  $(eval $(call ParseConfCheckOption))
+
+  # Check that the LOG given is valid, and set LOG_LEVEL, LOG_NOFILE and MAKE_LOG_FLAGS.
+  $(eval $(call ParseLogLevel))
+
+  ifneq ($(findstring $(LOG_LEVEL),info debug trace),)
+    $(info Running make as '$(strip $(MAKE) $(MFLAGS) $(COMMAND_LINE_VARIABLES) $(MAKECMDGOALS))')
+  endif
+
+  # CALLED_TARGETS is the list of targets that the user provided,
+  # or "default" if unspecified.
+  CALLED_TARGETS := $(if $(MAKECMDGOALS), $(MAKECMDGOALS), default)
+  CALLED_SPEC_TARGETS := $(filter $(ALL_MAIN_TARGETS) $(ALL_INIT_TARGETS), $(CALLED_TARGETS))
+  ifneq ($(CALLED_SPEC_TARGETS),)
+    # We have at least one non-global target, which need a SPEC
+    $(eval $(call ParseConfAndSpec))
+    # Now SPECS contain 1..N spec files (otherwise ParseConfAndSpec fails)
+
+    INIT_TARGETS := $(filter $(ALL_INIT_TARGETS), $(CALLED_SPEC_TARGETS))
+    SEQUENTIAL_TARGETS := $(filter dist-clean clean%, $(CALLED_SPEC_TARGETS))
+    PARALLEL_TARGETS := $(filter-out $(INIT_TARGETS) $(SEQUENTIAL_TARGETS), $(CALLED_SPEC_TARGETS))
+
+    # The spec files depend on the autoconf source code. This check makes sure
+    # the configuration is up to date after changes to configure.
+    $(SPECS): $(wildcard $(topdir)/common/autoconf/*)
+        ifeq ($(CONF_CHECK), fail)
+	  @echo "Error: The configuration is not up to date for '$(lastword $(subst /, , $(dir $@)))'."
+	  $(call PrintConfCheckFailed)
+	  @exit 2
+        else ifeq ($(CONF_CHECK), auto)
+	  @echo "Note: The configuration is not up to date for '$(lastword $(subst /, , $(dir $@)))'."
+	  @( cd $(topdir) && \
+	      $(MAKE) $(MFLAGS) $(MAKE_LOG_FLAGS) -f $(topdir)/make/Init.gmk SPEC=$@ HAS_SPEC=true \
+	      reconfigure )
+        else ifeq ($(CONF_CHECK), ignore)
+          # Do nothing
+        endif
+
+    # Unless reconfigure is explicitely called, let all targets depend on the spec files to be up to date.
+    ifeq ($(findstring reconfigure, $(CALLED_SPEC_TARGETS)), )
+      $(CALLED_SPEC_TARGETS): $(SPECS)
+    endif
+
+    # The recipe will be run once for every target specified, but we only want to execute the
+    # recipe a single time, hence the TARGET_DONE with a dummy command if true.
+    $(ALL_MAIN_TARGETS) $(ALL_INIT_TARGETS):
+	@$(if $(TARGET_DONE), \
+	  true \
+	, \
+	  $(foreach spec, $(SPECS), \
+	    ( cd $(topdir) && \
+	    $(MAKE) $(MFLAGS) $(MAKE_LOG_FLAGS) -j 1 -f $(topdir)/make/Init.gmk \
+	        SPEC=$(spec) HAS_SPEC=true \
+	        USER_MAKE_VARS="$(USER_MAKE_VARS)" MAKE_LOG_FLAGS=$(MAKE_LOG_FLAGS) \
+	        LOG_LEVEL=$(LOG_LEVEL) LOG_NOFILE=$(LOG_NOFILE) \
+	        INIT_TARGETS="$(INIT_TARGETS)" SEQUENTIAL_TARGETS="$(SEQUENTIAL_TARGETS)" \
+	        PARALLEL_TARGETS="$(PARALLEL_TARGETS)"  \
+	        main ) && \
+	  ) true \
+	  $(eval TARGET_DONE=true) \
+	)
+
+    .PHONY: $(ALL_MAIN_TARGETS) $(ALL_INIT_TARGETS)
+
+  endif # has $(CALLED_SPEC_TARGETS)
+
+else # HAS_SPEC=true
+
+  ##############################################################################
+  # Now we have a spec. This part provides the "main" target that acts as a
+  # trampoline to call the Main.gmk with the value of $(MAKE) found in the spec
+  # file.
+  ##############################################################################
+
+  ifeq ($(LOG_NOFILE), true)
+    # Disable log wrapper if LOG=[level,]nofile was given
+    override BUILD_LOG_WRAPPER :=
+  endif
+
+  ifeq ($(OUTPUT_SYNC_SUPPORTED), true)
+    OUTPUT_SYNC_FLAG := -O$(OUTPUT_SYNC)
+  endif
+
+  $(eval $(call CheckSpecSanity))
+
+  reconfigure:
+        ifneq ($(CONFIGURE_COMMAND_LINE), )
+	  $(ECHO) "Re-running configure using arguments '$(CONFIGURE_COMMAND_LINE)'"
+        else
+	  $(ECHO) "Re-running configure using default settings"
+        endif
+	( cd $(OUTPUT_ROOT) && PATH="$(ORIGINAL_PATH)" \
+	    $(BASH) $(TOPDIR)/configure $(CONFIGURE_COMMAND_LINE) )
+
+  main-init:
+	$(call RotateLogFiles)
+	$(BUILD_LOG_WRAPPER) $(PRINTF) "Building target(s) '$(strip \
+	    $(INIT_TARGETS) $(SEQUENTIAL_TARGETS) $(PARALLEL_TARGETS) \
+	    )' in configuration '$(CONF_NAME)'\n"
+
+
+  # MAKEOVERRIDES is automatically set and propagated by Make to sub-Make calls.
+  # We need to clear it of the init-specific variables. The user-specified
+  # variables are explicitely propagated using $(USER_MAKE_VARS).
+  main: MAKEOVERRIDES :=
+
+  main: $(INIT_TARGETS) main-init
+        ifneq ($(SEQUENTIAL_TARGETS), )
+          # Don't touch build output dir since we might be cleaning. That means
+	  # no log wrapper.
+	  ( cd $(TOPDIR) && \
+	      $(MAKE) $(MAKE_ARGS) -j 1 -f make/Main.gmk $(USER_MAKE_VARS) \
+	      $(SEQUENTIAL_TARGETS) \
+	  )
+        endif
+        ifneq ($(PARALLEL_TARGETS), )
+	  $(call StartGlobalTimer)
+	  $(call PrepareSmartJavac)
+	  ( cd $(TOPDIR) && \
+	      $(BUILD_LOG_WRAPPER) $(MAKE) $(MAKE_ARGS) $(OUTPUT_SYNC_FLAG) \
+	      -j $(JOBS) -f make/Main.gmk $(USER_MAKE_VARS) \
+	      $(PARALLEL_TARGETS) \
+	  )
+	  $(call CleanupSmartJavac)
+	  $(call StopGlobalTimer)
+	  $(call ReportBuildTimes)
+        endif
+	$(BUILD_LOG_WRAPPER) $(PRINTF) "Finished building target(s) '$(strip \
+	    $(INIT_TARGETS) $(SEQUENTIAL_TARGETS) $(PARALLEL_TARGETS) \
+	    )' in configuration '$(CONF_NAME)'\n"
+
+  .PHONY: reconfigure main-init main
+endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/InitSupport.gmk	Thu Mar 26 16:17:30 2015 +0100
@@ -0,0 +1,319 @@
+#
+# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.  Oracle designates this
+# particular file as subject to the "Classpath" exception as provided
+# by Oracle in the LICENSE file that accompanied this code.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+################################################################################
+# This file contains helper functions for Init.gmk.
+# It is divided in two parts, depending on if a SPEC is present or not
+# (HAS_SPEC is true or not).
+################################################################################
+
+ifndef _INITSUPPORT_GMK
+_INITSUPPORT_GMK := 1
+
+# Setup information about available configurations, if any.
+build_dir=$(topdir)/build
+all_spec_files=$(wildcard $(build_dir)/*/spec.gmk)
+# Extract the configuration names from the path
+all_confs=$(patsubst %/spec.gmk, %, $(patsubst $(build_dir)/%, %, $(all_spec_files)))
+any_spec_file=$(firstword $(all_spec_files))
+
+ifeq ($(HAS_SPEC),)
+  ##############################################################################
+  # Helper functions for the initial part of Init.gmk, before the spec file is
+  # loaded. Most of these functions provide parsing and setting up make options
+  # from the command-line.
+  ##############################################################################
+
+  # Make control variables, handled by Init.gmk
+  INIT_CONTROL_VARIABLES := LOG CONF SPEC JOBS CONF_CHECK
+
+  # All known make control variables
+  MAKE_CONTROL_VARIABLES := $(INIT_CONTROL_VARIABLES) TEST JDK_FILTER
+
+  # Define a simple reverse function.
+  # Should maybe move to MakeBase.gmk, but we can't include that file now.
+  reverse = \
+      $(if $(strip $(1)), $(call reverse, $(wordlist 2, $(words $(1)), $(1)))) \
+          $(firstword $(1))
+
+  # The variable MAKEOVERRIDES contains variable assignments from the command
+  # line, but in reverse order to what the user entered.
+  COMMAND_LINE_VARIABLES := $(subst \#,\ , $(call reverse, $(subst \ ,\#,$(MAKEOVERRIDES))))
+
+  # A list like FOO="val1" BAR="val2" containing all user-supplied make variables
+  # that we should propagate.
+  USER_MAKE_VARS := $(filter-out $(addsuffix =%, $(INIT_CONTROL_VARIABLES)), \
+      $(MAKEOVERRIDES))
+
+  # Check for unknown command-line variables
+  define CheckControlVariables
+    command_line_variables := $$(strip $$(foreach var, \
+        $$(subst \ ,_,$$(MAKEOVERRIDES)), \
+        $$(firstword $$(subst =, , $$(var)))))
+    unknown_command_line_variables := $$(strip $$(filter-out $$(MAKE_CONTROL_VARIABLES), $$(command_line_variables)))
+    ifneq ($$(unknown_command_line_variables), )
+      $$(info Note: Command line contains non-control variables:)
+      $$(foreach var, $$(unknown_command_line_variables), $$(info * $$(var)=$$($$(var))))
+      $$(info Make sure it is not mistyped, and that you intend to override this variable.)
+      $$(info 'make help' will list known control variables.)
+      $$(info )
+    endif
+  endef
+
+  # Check for deprecated ALT_ variables
+  define CheckDeprecatedEnvironment
+    defined_alt_variables := $$(filter ALT_%, $$(.VARIABLES))
+    ifneq ($$(defined_alt_variables), )
+      $$(info Warning: You have the following ALT_ variables set:)
+      $$(foreach var, $$(defined_alt_variables), $$(info * $$(var)=$$($$(var))))
+      $$(info ALT_ variables are deprecated, and may result in a failed build.)
+      $$(info Please clean your environment.)
+      $$(info )
+    endif
+  endef
+
+  # Check for invalid make flags like -j
+  define CheckInvalidMakeFlags
+    # This is a trick to get this rule to execute before any other rules
+    # MAKEFLAGS only indicate -j if read in a recipe (!)
+    $$(topdir)/make/Init.gmk: .FORCE
+	$$(if $$(findstring --jobserver, $$(MAKEFLAGS)), \
+	    $$(info Error: 'make -jN' is not supported, use 'make JOBS=N') \
+	    $$(error Cannot continue) \
+	)
+    .FORCE:
+    .PHONY: .FORCE
+  endef
+
+  # Check that the CONF_CHECK option is valid and set up handling
+  define ParseConfCheckOption
+    ifeq ($$(CONF_CHECK), )
+      # Default behavior is fail
+      CONF_CHECK := fail
+    else ifneq ($$(filter-out auto fail ignore, $$(CONF_CHECK)),)
+      $$(info Error: CONF_CHECK must be one of: auto, fail or ignore.)
+      $$(error Cannot continue)
+    endif
+  endef
+
+  define ParseLogLevel
+    # Catch old-style VERBOSE= command lines.
+    ifneq ($$(origin VERBOSE), undefined)
+      $$(info Error: VERBOSE is deprecated. Use LOG=<warn|info|debug|trace> instead.)
+      $$(error Cannot continue)
+    endif
+
+    # Setup logging according to LOG
+
+    # If the "nofile" argument is given, act on it and strip it away
+    ifneq ($$(findstring nofile, $$(LOG)),)
+      LOG_NOFILE := true
+      # COMMA is defined in spec.gmk, but that is not included yet
+      COMMA := ,
+      # First try to remove ",nofile" if it exists, otherwise just remove "nofile"
+      LOG_STRIPPED := $$(subst nofile,, $$(subst $$(COMMA)nofile,, $$(LOG)))
+      # We might have ended up with a leading comma. Remove it
+      LOG_LEVEL := $$(strip $$(patsubst $$(COMMA)%, %, $$(LOG_STRIPPED)))
+    else
+      LOG_LEVEL := $$(LOG)
+    endif
+
+    ifeq ($$(LOG_LEVEL),)
+      # Set LOG to "warn" as default if not set
+      LOG_LEVEL := warn
+    endif
+
+    ifeq ($$(LOG_LEVEL), warn)
+      MAKE_LOG_FLAGS := -s
+    else ifeq ($$(LOG_LEVEL), info)
+      MAKE_LOG_FLAGS := -s
+    else ifeq ($$(LOG_LEVEL), debug)
+      MAKE_LOG_FLAGS :=
+    else ifeq ($$(LOG_LEVEL), trace)
+      MAKE_LOG_FLAGS := -d
+    else
+      $$(info Error: LOG must be one of: warn, info, debug or trace.)
+      $$(error Cannot continue)
+    endif
+  endef
+
+  define ParseConfAndSpec
+    ifneq ($$(origin SPEC), undefined)
+      # We have been given a SPEC, check that it works out properly
+      ifneq ($$(origin CONF), undefined)
+        # We also have a CONF argument. We can't have both.
+        $$(info Error: Cannot use CONF=$$(CONF) and SPEC=$$(SPEC) at the same time. Choose one.)
+        $$(error Cannot continue)
+      endif
+      ifeq ($$(wildcard $$(SPEC)),)
+        $$(info Error: Cannot locate spec.gmk, given by SPEC=$$(SPEC).)
+        $$(error Cannot continue)
+      endif
+      ifeq ($$(filter /%, $$(SPEC)),)
+        # If given with relative path, make it absolute
+        SPECS := $$(CURDIR)/$$(strip $$(SPEC))
+      else
+        SPECS := $$(SPEC)
+      endif
+
+      # For now, unset this SPEC variable.
+      override SPEC :=
+    else
+      # Use spec.gmk files in the build output directory
+      ifeq ($$(any_spec_file),)
+        $$(info Error: No configurations found for $$(topdir).)
+        $$(info Please run 'bash configure' to create a configuration.)
+        $$(info )
+        $$(error Cannot continue)
+      endif
+
+      ifneq ($$(origin CONF), undefined)
+        # User have given a CONF= argument.
+        ifeq ($$(CONF),)
+          # If given CONF=, match all configurations
+          matching_confs := $$(strip $$(all_confs))
+        else
+          # Otherwise select those that contain the given CONF string
+          matching_confs := $$(strip $$(foreach var, $$(all_confs), $$(if $$(findstring $$(CONF), $$(var)), $$(var))))
+        endif
+        ifeq ($$(matching_confs),)
+          $$(info Error: No configurations found matching CONF=$$(CONF).)
+          $$(info Available configurations in $$(build_dir):)
+          $$(foreach var, $$(all_confs), $$(info * $$(var)))
+          $$(error Cannot continue)
+        else
+          ifeq ($$(words $$(matching_confs)), 1)
+            $$(info Building configuration '$$(matching_confs)' (matching CONF=$$(CONF)))
+          else
+            $$(info Building these configurations (matching CONF=$$(CONF)):)
+            $$(foreach var, $$(matching_confs), $$(info * $$(var)))
+          endif
+        endif
+
+        # Create a SPEC definition. This will contain the path to one or more spec.gmk files.
+        SPECS := $$(addsuffix /spec.gmk, $$(addprefix $$(build_dir)/, $$(matching_confs)))
+      else
+        # No CONF or SPEC given, check the available configurations
+        ifneq ($$(words $$(all_spec_files)), 1)
+          $$(info Error: No CONF given, but more than one configuration found.)
+          $$(info Available configurations in $$(build_dir):)
+          $$(foreach var, $$(all_confs), $$(info * $$(var)))
+          $$(info Please retry building with CONF=<config pattern> (or SPEC=<spec file>).)
+          $$(info )
+          $$(error Cannot continue)
+        endif
+
+        # We found exactly one configuration, use it
+        SPECS := $$(strip $$(all_spec_files))
+      endif
+    endif
+  endef
+
+  define PrintConfCheckFailed
+	@echo ' '
+	@echo "Please rerun configure! Easiest way to do this is by running"
+	@echo "'make reconfigure'."
+	@echo "This behavior may also be changed using CONF_CHECK=<ignore|auto>."
+	@echo ' '
+  endef
+
+else # $(HAS_SPEC)=true
+  ##############################################################################
+  # Helper functions for the 'main' target. These functions assume a single,
+  # proper and existing SPEC is provided, and will load it.
+  ##############################################################################
+
+  include $(SPEC)
+  include $(SRC_ROOT)/make/common/MakeBase.gmk
+
+  # Define basic logging setup
+  BUILD_LOG := $(OUTPUT_ROOT)/build.log
+  BUILD_TRACE_LOG := $(OUTPUT_ROOT)/build-trace-time.log
+
+  BUILD_LOG_WRAPPER := $(BASH) $(SRC_ROOT)/common/bin/logger.sh $(BUILD_LOG)
+
+  # Disable the build log wrapper on sjavac+windows until
+  # we have solved how to prevent the log wrapper to wait
+  # for the background sjavac server process.
+  ifeq ($(ENABLE_SJAVAC)X$(OPENJDK_BUILD_OS),yesXwindows)
+    LOG_NOFILE := true
+  endif
+
+  # Sanity check the spec file, so it matches this source code
+  define CheckSpecSanity
+    ifneq ($$(topdir), $$(TOPDIR))
+      $$(info Error: SPEC mismatch. $$$$(TOPDIR) does not match current directory.)
+      $$(error Cannot continue)
+    endif
+  endef
+
+  define RotateLogFiles
+	$(RM) $(BUILD_LOG).old 2> /dev/null
+	$(MV) $(BUILD_LOG) $(BUILD_LOG).old 2> /dev/null || true
+	$(if $(findstring trace, $(LOG_LEVEL)), \
+	  $(RM) $(BUILD_TRACE_LOG).old 2> /dev/null && \
+	  $(MV) $(BUILD_TRACE_LOG) $(BUILD_TRACE_LOG).old 2> /dev/null || true \
+	)
+  endef
+
+  # Remove any javac server logs and port files. This
+  # prevents a new make run to reuse the previous servers.
+  define PrepareSmartJavac
+	$(if $(SJAVAC_SERVER_DIR), \
+	  $(RM) -r $(SJAVAC_SERVER_DIR) 2> /dev/null && \
+	  $(MKDIR) -p $(SJAVAC_SERVER_DIR) \
+	)
+  endef
+
+  define CleanupSmartJavac
+	[ -f $(SJAVAC_SERVER_DIR)/server.port ] && $(ECHO) Stopping sjavac server && \
+	    $(TOUCH) $(SJAVAC_SERVER_DIR)/server.port.stop; true
+  endef
+
+  define StartGlobalTimer
+	$(RM) -r $(BUILDTIMESDIR) 2> /dev/null
+	$(MKDIR) -p $(BUILDTIMESDIR)
+	$(call RecordStartTime,TOTAL)
+  endef
+
+  define StopGlobalTimer
+	$(call RecordEndTime,TOTAL)
+  endef
+
+  # Find all build_time_* files and print their contents in a list sorted
+  # on the name of the sub repository.
+  define ReportBuildTimes
+	$(BUILD_LOG_WRAPPER) $(PRINTF) $(LOG_INFO) -- \
+	    "----- Build times -------\nStart %s\nEnd   %s\n%s\n%s\n-------------------------\n" \
+	    "`$(CAT) $(BUILDTIMESDIR)/build_time_start_TOTAL_human_readable`" \
+	    "`$(CAT) $(BUILDTIMESDIR)/build_time_end_TOTAL_human_readable`" \
+	    "`$(LS) $(BUILDTIMESDIR)/build_time_diff_* | $(GREP) -v _TOTAL | \
+	    $(XARGS) $(CAT) | $(SORT) -k 2`" \
+	    "`$(CAT) $(BUILDTIMESDIR)/build_time_diff_TOTAL`"
+  endef
+
+endif # HAS_SPEC
+
+endif # _INITSUPPORT_GMK
--- a/make/Jprt.gmk	Mon Mar 23 11:44:40 2015 -0700
+++ b/make/Jprt.gmk	Thu Mar 26 16:17:30 2015 +0100
@@ -130,7 +130,4 @@
         endif
 	@$(call TargetExit)
 
-
-###########################################################################
-# Phony targets
-.PHONY: jprt_bundle bundles final-images
+ALL_TARGETS += jprt_bundle bundles final-images
--- a/make/Main.gmk	Mon Mar 23 11:44:40 2015 -0700
+++ b/make/Main.gmk	Thu Mar 26 16:17:30 2015 +0100
@@ -26,14 +26,19 @@
 ################################################################################
 # This is the main makefile containing most actual top level targets. It needs
 # to be called with a SPEC file defined.
+################################################################################
 
 # Declare default target
 default:
 
+ifeq ($(wildcard $(SPEC)),)
+  $(error Main.gmk needs SPEC set to a proper spec.gmk)
+endif
+
 # Now load the spec
 include $(SPEC)
 
-include $(SRC_ROOT)/make/MakeHelpers.gmk
+include $(SRC_ROOT)/make/MainSupport.gmk
 
 # Load the vital tools for all the makefiles.
 include $(SRC_ROOT)/make/common/MakeBase.gmk
@@ -589,42 +594,29 @@
     $(CLEAN_PHASE_TARGETS) $(CLEAN_MODULE_TARGETS) $(CLEAN_MODULE_PHASE_TARGETS)
 
 ################################################################################
-
-# Setup a rule for SPEC file that fails if executed. This check makes sure the
-# configuration is up to date after changes to configure.
-ifeq ($(findstring reconfigure, $(MAKECMDGOALS)), )
-  $(SPEC): $(wildcard $(SRC_ROOT)/common/autoconf/*)
-	@$(ECHO) "ERROR: $(SPEC) is not up to date."
-	@$(ECHO) "Please rerun configure! Easiest way to do this is by running"
-	@$(ECHO) "'make reconfigure'."
-	@$(ECHO) "It may also be ignored by setting IGNORE_OLD_CONFIG=true"
-	@if test "x$(IGNORE_OLD_CONFIG)" != "xtrue"; then exit 1; fi
-endif
-
-# The reconfigure target is automatically run serially from everything else
-# by the Makefile calling this file.
-
-reconfigure:
-        ifneq ($(CONFIGURE_COMMAND_LINE), )
-	  @$(ECHO) "Re-running configure using arguments '$(CONFIGURE_COMMAND_LINE)'"
-        else
-	  @$(ECHO) "Re-running configure using default settings"
-        endif
-	@( cd $(OUTPUT_ROOT) && PATH="$(ORIGINAL_PATH)" \
-	    $(BASH) $(TOPDIR)/configure $(CONFIGURE_COMMAND_LINE) )
-
-ALL_TARGETS += reconfigure
-
-################################################################################
 # Declare *-only targets for each normal target
 $(foreach t, $(ALL_TARGETS), $(eval $(t)-only: $(t)))
 
-ALL_TARGETS += $(addsuffix -only, $(filter-out clean%, $(ALL_TARGETS)))
+ALL_TARGETS += $(addsuffix -only, $(filter-out dist-clean clean%, $(ALL_TARGETS)))
+
+################################################################################
+
+# Include JPRT targets
+include $(SRC_ROOT)/make/Jprt.gmk
+
+################################################################################
+
+print-targets:
+	  @$(ECHO) $(sort $(ALL_TARGETS))
+
+print-modules:
+	  @$(ECHO) $(sort $(ALL_MODULES))
+
+# print-* targets intentionally not added to ALL_TARGETS since they are internal only.
+# The corresponding external targets are in Help.gmk
 
 ################################################################################
 
 .PHONY: $(ALL_TARGETS)
 
-include $(SRC_ROOT)/make/Jprt.gmk
-
 FRC: # Force target
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/MainSupport.gmk	Thu Mar 26 16:17:30 2015 +0100
@@ -0,0 +1,186 @@
+#
+# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.  Oracle designates this
+# particular file as subject to the "Classpath" exception as provided
+# by Oracle in the LICENSE file that accompanied this code.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+################################################################################
+# This file contains helper functions for Main.gmk.
+################################################################################
+
+ifndef _MAINSUPPORT_GMK
+_MAINSUPPORT_GMK := 1
+
+# Run the tests specified by $1.
+define RunTests
+	($(CD) $(SRC_ROOT)/test && $(MAKE) $(MAKE_ARGS) -j1 -k MAKEFLAGS= \
+	    JT_HOME=$(JT_HOME) PRODUCT_HOME=$(JDK_IMAGE_DIR) \
+	    TEST_IMAGE_DIR=$(TEST_IMAGE_DIR) \
+	    ALT_OUTPUTDIR=$(OUTPUT_ROOT) CONCURRENCY=$(JOBS) $1) || true
+endef
+
+# Cleans the dir given as $1
+define CleanDir
+	@$(PRINTF) "Cleaning $(strip $1) build artifacts ..."
+	@($(CD) $(OUTPUT_ROOT) && $(RM) -r $1)
+	@$(PRINTF) " done\n"
+endef
+
+define CleanTest
+	@$(PRINTF) "Cleaning test $(strip $1) ..."
+	@$(RM) -r $(SUPPORT_OUTPUTDIR)/test/$(strip $(subst -,/,$1))
+	@$(PRINTF) " done\n"
+endef
+
+define Clean-gensrc
+	@$(PRINTF) "Cleaning gensrc $(if $1,for $(strip $1) )..."
+	@$(RM) -r $(SUPPORT_OUTPUTDIR)/gensrc/$(strip $1)
+	@$(RM) -r $(SUPPORT_OUTPUTDIR)/gensrc_no_docs/$(strip $1)
+	@$(PRINTF) " done\n"
+endef
+
+define Clean-java
+	@$(PRINTF) "Cleaning java $(if $1,for $(strip $1) )..."
+	@$(RM) -r $(JDK_OUTPUTDIR)/modules/$(strip $1)
+	@$(RM) -r $(SUPPORT_OUTPUTDIR)/misc/$(strip $1)
+	@$(PRINTF) " done\n"
+	@$(PRINTF) "Cleaning headers $(if $1,for $(strip $1)) ..."
+	@$(RM) -r $(SUPPORT_OUTPUTDIR)/headers/$(strip $1)
+	@$(PRINTF) " done\n"
+endef
+
+define Clean-native
+	@$(PRINTF) "Cleaning native $(if $1,for $(strip $1) )..."
+	@$(RM) -r $(SUPPORT_OUTPUTDIR)/native/$(strip $1)
+	@$(RM) -r $(SUPPORT_OUTPUTDIR)/modules_libs/$(strip $1)
+	@$(RM) -r $(SUPPORT_OUTPUTDIR)/modules_libs-stripped/$(strip $1)
+	@$(RM) -r $(SUPPORT_OUTPUTDIR)/modules_cmds/$(strip $1)
+	@$(RM) -r $(SUPPORT_OUTPUTDIR)/modules_cmds-stripped/$(strip $1)
+	@$(PRINTF) " done\n"
+endef
+
+define Clean-include
+	@$(PRINTF) "Cleaning include $(if $1,for $(strip $1) )..."
+	@$(RM) -r $(SUPPORT_OUTPUTDIR)/modules_include/$(strip $1)
+	@$(PRINTF) " done\n"
+endef
+
+define CleanModule
+  $(call Clean-gensrc, $1)
+  $(call Clean-java, $1)
+  $(call Clean-native, $1)
+  $(call Clean-include, $1)
+endef
+
+
+################################################################################
+
+MAKE_TOPDIR_LIST := $(JDK_TOPDIR) $(CORBA_TOPDIR) $(LANGTOOLS_TOPDIR)
+MAKE_MAKEDIR_LIST := make
+
+# Helper macro for DeclareRecipesForPhase
+# Declare a recipe for calling the module and phase specific makefile.
+# If there are multiple makefiles to call, create a rule for each topdir
+# that contains a makefile with the target $module-$suffix-$repodir,
+# (i.e: java.base-gensrc-jdk)
+# Normally there is only one makefile, and the target will just be
+# $module-$suffix
+# Param 1: Name of list to add targets to
+# Param 2: Module name
+# Param 3: Topdir
+define DeclareRecipeForModuleMakefile
+  ifeq ($$($1_MULTIPLE_MAKEFILES), true)
+    $2-$$($1_TARGET_SUFFIX): $2-$$($1_TARGET_SUFFIX)-$$(notdir $3)
+    $1 += $2-$$($1_TARGET_SUFFIX)-$$(notdir $3)
+
+    $2-$$($1_TARGET_SUFFIX)-$$(notdir $3):
+  else
+    $2-$$($1_TARGET_SUFFIX):
+  endif
+	$(ECHO) $(LOG_INFO) "Building $$@"
+        ifeq ($$($1_USE_WRAPPER), true)
+	  +($(CD) $(SRC_ROOT)/make && $(MAKE) $(MAKE_ARGS) \
+	      -f ModuleWrapper.gmk \
+	          $$(addprefix -I, $$(wildcard $$(addprefix $3/, $(MAKE_MAKEDIR_LIST)) \
+	          $$(addsuffix /$$($1_MAKE_SUBDIR), $$(addprefix $3/, $(MAKE_MAKEDIR_LIST))))) \
+	          MODULE=$2 MAKEFILE_PREFIX=$$($1_FILE_PREFIX))
+        else
+	  +($(CD) $$(dir $$(firstword $$(wildcard $$(patsubst %, \
+	          $3/%/$$($1_MAKE_SUBDIR)/$$($1_FILE_PREFIX)-$2.gmk, $(MAKE_MAKEDIR_LIST))))) \
+	    && $(MAKE) $(MAKE_ARGS) \
+	          -f $$($1_FILE_PREFIX)-$2.gmk \
+	          $$(addprefix -I, $$(wildcard $$(addprefix $3/, $(MAKE_MAKEDIR_LIST)) \
+	          $$(addsuffix /$$($1_MAKE_SUBDIR), $$(addprefix $3/, $(MAKE_MAKEDIR_LIST))))) \
+	          MODULE=$2)
+        endif
+
+endef
+
+# Helper macro for DeclareRecipesForPhase
+# Param 1: Name of list to add targets to
+# Param 2: Module name
+define DeclareRecipesForPhaseAndModule
+  $1_$2_TOPDIRS := $$(strip $$(sort $$(foreach d, $(MAKE_TOPDIR_LIST), \
+      $$(patsubst $$d/%, $$d, $$(filter $$d/%, \
+          $$(wildcard $$(patsubst %, %/$$($1_MAKE_SUBDIR)/$$($1_FILE_PREFIX)-$2.gmk, \
+          $$(foreach s, $(MAKE_MAKEDIR_LIST), \
+              $$(addsuffix /$$s, $(MAKE_TOPDIR_LIST))))))))))
+
+  # Only declare recipes if there are makefiles to call
+  ifneq ($$($1_$2_TOPDIRS), )
+    ifeq ($(NO_RECIPES),)
+      $$(foreach d, $$($1_$2_TOPDIRS), \
+          $$(eval $$(call DeclareRecipeForModuleMakefile,$1,$2,$$d)))
+    endif
+    $1 += $2-$$($1_TARGET_SUFFIX)
+    $1_MODULES += $2
+  endif
+endef
+
+# Declare recipes for a specific module and build phase if there are makefiles
+# present for the specific combination.
+# Param 1: Name of list to add targets to
+# Named params:
+# TARGET_SUFFIX : Suffix of target to create for recipe
+# MAKE_SUBDIR : Subdir for this build phase
+# FILE_PREFIX : File prefix for this build phase
+# USE_WRAPPER : Set to true to use ModuleWrapper.gmk
+# CHECK_MODULES : List of modules to try
+# MULTIPLE_MAKEFILES : Set to true to handle makefils for the same module in
+#                      phase in multiple repos
+# Exported variables:
+# $1_MODULES : All modules that had rules generated
+# $1_TARGETS : All targets generated
+define DeclareRecipesForPhase
+  $(foreach i,2 3 4 5 6 7, $(if $($i),$(strip $1)_$(strip $($i)))$(NEWLINE))
+  $(if $(8),$(error Internal makefile error: Too many arguments to \
+      DeclareRecipesForPhase, please update MakeHelper.gmk))
+
+  $$(foreach m, $$($(strip $1)_CHECK_MODULES), \
+      $$(eval $$(call DeclareRecipesForPhaseAndModule,$(strip $1),$$m)))
+
+  $(strip $1)_TARGETS := $$($(strip $1))
+endef
+
+################################################################################
+
+endif # _MAINSUPPORT_GMK
--- a/make/MakeHelpers.gmk	Mon Mar 23 11:44:40 2015 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,451 +0,0 @@
-#
-# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation.  Oracle designates this
-# particular file as subject to the "Classpath" exception as provided
-# by Oracle in the LICENSE file that accompanied this code.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-# or visit www.oracle.com if you need additional information or have any
-# questions.
-#
-
-################################################################
-#
-# This file contains helper functions for the top-level Makefile that does
-# not depend on the spec.gmk file having been read. (The purpose of this
-# file is ju to avoid cluttering the top-level Makefile.)
-#
-################################################################
-
-ifndef _MAKEHELPERS_GMK
-_MAKEHELPERS_GMK := 1
-
-##############################
-# Stuff to run at include time
-##############################
-
-# Find out which variables were passed explicitely on the make command line. These
-# will be passed on to sub-makes, overriding spec.gmk settings.
-MAKE_ARGS=$(foreach var,$(subst =command,,$(filter %=command,$(foreach var,$(.VARIABLES),$(var)=$(firstword $(origin $(var)))))),$(var)="$($(var))")
-
-list_alt_overrides_with_origins=$(filter ALT_%=environment ALT_%=command,$(foreach var,$(.VARIABLES),$(var)=$(firstword $(origin $(var)))))
-list_alt_overrides=$(subst =command,,$(subst =environment,,$(list_alt_overrides_with_origins)))
-
-# Store the build times in this directory.
-BUILDTIMESDIR=$(OUTPUT_ROOT)/make-support/build-times
-
-# Global targets are possible to run either with or without a SPEC. The prototypical
-# global target is "help".
-global_targets=help
-
-##############################
-# Functions
-##############################
-
-define CheckEnvironment
-        # Find all environment or command line variables that begin with ALT.
-	$(if $(list_alt_overrides),
-	  @$(PRINTF) "\nWARNING: You have the following ALT_ variables set:\n"
-	  @$(PRINTF) "$(foreach var,$(list_alt_overrides),$(var)=$$$(var))\n"
-	  @$(PRINTF) "ALT_ variables are deprecated and will be ignored. Please clean your environment.\n\n"
-	)
-endef
-
-### Functions for timers
-
-# Record starting time for build of a sub repository.
-define RecordStartTime
-	$(MKDIR) -p $(BUILDTIMESDIR)
-	$(DATE) '+%Y %m %d %H %M %S' | $(NAWK) '{ print $$1,$$2,$$3,$$4,$$5,$$6,($$4*3600+$$5*60+$$6) }' > $(BUILDTIMESDIR)/build_time_start_$1
-	$(DATE) '+%Y-%m-%d %H:%M:%S' > $(BUILDTIMESDIR)/build_time_start_$1_human_readable
-endef
-
-# Record ending time and calculate the difference and store it in a
-# easy to read format. Handles builds that cross midnight. Expects
-# that a build will never take 24 hours or more.
-define RecordEndTime
-	$(DATE) '+%Y %m %d %H %M %S' | $(NAWK) '{ print $$1,$$2,$$3,$$4,$$5,$$6,($$4*3600+$$5*60+$$6) }' > $(BUILDTIMESDIR)/build_time_end_$1
-	$(DATE) '+%Y-%m-%d %H:%M:%S' > $(BUILDTIMESDIR)/build_time_end_$1_human_readable
-	$(ECHO) `$(CAT) $(BUILDTIMESDIR)/build_time_start_$1` `$(CAT) $(BUILDTIMESDIR)/build_time_end_$1` $1 | \
-	    $(NAWK) '{ F=$$7; T=$$14; if (F > T) { T+=3600*24 }; D=T-F; H=int(D/3600); \
-	    M=int((D-H*3600)/60); S=D-H*3600-M*60; printf("%02d:%02d:%02d %s\n",H,M,S,$$15); }' \
-	    > $(BUILDTIMESDIR)/build_time_diff_$1
-endef
-
-# Find all build_time_* files and print their contents in a list sorted
-# on the name of the sub repository.
-define ReportBuildTimes
-	$(BUILD_LOG_WRAPPER) $(PRINTF) -- "----- Build times -------\nStart %s\nEnd   %s\n%s\n%s\n-------------------------\n" \
-	    "`$(CAT) $(BUILDTIMESDIR)/build_time_start_TOTAL_human_readable`" \
-	    "`$(CAT) $(BUILDTIMESDIR)/build_time_end_TOTAL_human_readable`" \
-	    "`$(LS) $(BUILDTIMESDIR)/build_time_diff_* | $(GREP) -v _TOTAL | $(XARGS) $(CAT) | $(SORT) -k 2`" \
-	    "`$(CAT) $(BUILDTIMESDIR)/build_time_diff_TOTAL`"
-endef
-
-define ResetAllTimers
-  $$(shell $(MKDIR) -p $(BUILDTIMESDIR) && $(RM) $(BUILDTIMESDIR)/build_time_*)
-endef
-
-define StartGlobalTimer
-	$(call RecordStartTime,TOTAL)
-endef
-
-define StopGlobalTimer
-	$(call RecordEndTime,TOTAL)
-endef
-
-### Functions for managing makefile structure (start/end of makefile and individual targets)
-
-# Do not indent this function, this will add whitespace at the start which the caller won't handle
-define GetRealTarget
-$(strip $(if $(findstring main-wrapper, $(MAKECMDGOALS)), $(MAIN_TARGETS), \
-    $(if $(MAKECMDGOALS),$(MAKECMDGOALS),default)))
-endef
-
-# Do not indent this function, this will add whitespace at the start which the caller won't handle
-define LastGoal
-$(strip $(lastword $(call GetRealTarget)))
-endef
-
-# Check if the current target is the final target, as specified by
-# the user on the command line. If so, call AtRootMakeEnd.
-define CheckIfMakeAtEnd
-        # Check if the current target is the last goal
-	$(if $(filter $@,$(call LastGoal)),$(call AtMakeEnd))
-        # If the target is 'foo-only', check if our goal was stated as 'foo'
-	$(if $(filter $@,$(call LastGoal)-only),$(call AtMakeEnd))
-endef
-
-# Hook to be called when starting to execute a top-level target
-define TargetEnter
-	$(PRINTF) "## Starting $(patsubst %-only,%,$@)\n"
-	$(call RecordStartTime,$(patsubst %-only,%,$@))
-endef
-
-# Hook to be called when finish executing a top-level target
-define TargetExit
-	$(call RecordEndTime,$(patsubst %-only,%,$@))
-	$(PRINTF) "## Finished $(patsubst %-only,%,$@) (build time %s)\n\n" \
-	    "`$(CAT) $(BUILDTIMESDIR)/build_time_diff_$(patsubst %-only,%,$@) | $(CUT) -f 1 -d ' '`"
-endef
-
-# Hook to be called as the very first thing when running a normal build
-define AtMakeStart
-	$(if $(findstring --jobserver,$(MAKEFLAGS)),$(error make -j is not supported, use make JOBS=n))
-	$(call CheckEnvironment)
-	$(BUILD_LOG_WRAPPER) $(PRINTF) $(LOG_INFO) "Running make as '$(MAKE) $(MFLAGS) $(MAKE_ARGS)'\n"
-	$(BUILD_LOG_WRAPPER) $(PRINTF) "Building $(PRODUCT_NAME) for target '$(call GetRealTarget)' in configuration '$(CONF_NAME)'\n\n"
-	$(call StartGlobalTimer)
-endef
-
-# Hook to be called as the very last thing for targets that are "top level" targets
-define AtMakeEnd
-	[ -f $(SJAVAC_SERVER_DIR)/server.port ] && echo Stopping sjavac server && $(TOUCH) $(SJAVAC_SERVER_DIR)/server.port.stop; true
-	$(call StopGlobalTimer)
-	$(call ReportBuildTimes)
-	@$(PRINTF) "\nFinished building $(PRODUCT_NAME) for target '$(call GetRealTarget)'\n"
-	$(call CheckEnvironment)
-endef
-
-### Functions for parsing and setting up make options from command-line
-
-define FatalError
-  # If the user specificed a "global" target (e.g. 'help'), do not exit but continue running
-  $$(if $$(filter-out $(global_targets),$$(call GetRealTarget)),$$(error Cannot continue))
-endef
-
-define ParseLogLevel
-  ifeq ($$(origin VERBOSE),undefined)
-    # Setup logging according to LOG (but only if VERBOSE is not given)
-
-    # If the "nofile" argument is given, act on it and strip it away
-    ifneq ($$(findstring nofile,$$(LOG)),)
-      # Reset the build log wrapper, regardless of other values
-      override BUILD_LOG_WRAPPER=
-      # COMMA is defined in spec.gmk, but that is not included yet
-      COMMA=,
-      # First try to remove ",nofile" if it exists
-      LOG_STRIPPED1=$$(subst $$(COMMA)nofile,,$$(LOG))
-      # Otherwise just remove "nofile"
-      LOG_STRIPPED2=$$(subst nofile,,$$(LOG_STRIPPED1))
-      # We might have ended up with a leading comma. Remove it
-      LOG_STRIPPED3=$$(strip $$(patsubst $$(COMMA)%,%,$$(LOG_STRIPPED2)))
-      LOG_LEVEL:=$$(LOG_STRIPPED3)
-    else
-      LOG_LEVEL:=$$(LOG)
-    endif
-
-    ifeq ($$(LOG_LEVEL),)
-      # Set LOG to "warn" as default if not set (and no VERBOSE given)
-      override LOG_LEVEL=warn
-    endif
-    ifeq ($$(LOG_LEVEL),warn)
-      VERBOSE=-s
-    else ifeq ($$(LOG_LEVEL),info)
-      VERBOSE=-s
-    else ifeq ($$(LOG_LEVEL),debug)
-      VERBOSE=
-    else ifeq ($$(LOG_LEVEL),trace)
-      VERBOSE=
-    else
-      $$(info Error: LOG must be one of: warn, info, debug or trace.)
-      $$(eval $$(call FatalError))
-    endif
-  else
-    # Provide resonable interpretations of LOG_LEVEL if VERBOSE is given.
-    ifeq ($(VERBOSE),)
-      LOG_LEVEL:=debug
-    else
-      LOG_LEVEL:=warn
-    endif
-    ifneq ($$(LOG),)
-      # We have both a VERBOSE and a LOG argument. This is OK only if this is a repeated call by ourselves,
-      # but complain if this is the top-level make call.
-      ifeq ($$(MAKELEVEL),0)
-        $$(info Cannot use LOG=$$(LOG) and VERBOSE=$$(VERBOSE) at the same time. Choose one.)
-        $$(eval $$(call FatalError))
-      endif
-    endif
-  endif
-endef
-
-define ParseConfAndSpec
-  ifneq ($$(filter-out $(global_targets),$$(call GetRealTarget)),)
-    # If we only have global targets, no need to bother with SPEC or CONF
-    ifneq ($$(origin SPEC),undefined)
-      # We have been given a SPEC, check that it works out properly
-      ifneq ($$(origin CONF),undefined)
-        # We also have a CONF argument. This is OK only if this is a repeated call by ourselves,
-        # but complain if this is the top-level make call.
-        ifeq ($$(MAKELEVEL),0)
-          $$(info Error: Cannot use CONF=$$(CONF) and SPEC=$$(SPEC) at the same time. Choose one.)
-          $$(eval $$(call FatalError))
-        endif
-      endif
-      ifeq ($$(wildcard $$(SPEC)),)
-        $$(info Error: Cannot locate spec.gmk, given by SPEC=$$(SPEC).)
-        $$(eval $$(call FatalError))
-      endif
-      # ... OK, we're satisfied, we'll use this SPEC later on
-    else
-      # Find all spec.gmk files in the build output directory
-      output_dir=$$(root_dir)/build
-      all_spec_files=$$(wildcard $$(output_dir)/*/spec.gmk)
-      ifeq ($$(all_spec_files),)
-        $$(info Error: No configurations found for $$(root_dir).)
-        $$(info Please run 'bash configure' to create a configuration.)
-        $$(eval $$(call FatalError))
-      endif
-      # Extract the configuration names from the path
-      all_confs=$$(patsubst %/spec.gmk,%,$$(patsubst $$(output_dir)/%,%,$$(all_spec_files)))
-
-      ifneq ($$(origin CONF),undefined)
-        # User have given a CONF= argument.
-        ifeq ($$(CONF),)
-          # If given CONF=, match all configurations
-          matching_confs=$$(strip $$(all_confs))
-        else
-          # Otherwise select those that contain the given CONF string
-          matching_confs=$$(strip $$(foreach var,$$(all_confs),$$(if $$(findstring $$(CONF),$$(var)),$$(var))))
-        endif
-        ifeq ($$(matching_confs),)
-          $$(info Error: No configurations found matching CONF=$$(CONF).)
-          $$(info Available configurations in $$(output_dir):)
-          $$(foreach var,$$(all_confs),$$(info * $$(var)))
-          $$(eval $$(call FatalError))
-        else
-          ifeq ($$(words $$(matching_confs)),1)
-            $$(info Building '$$(matching_confs)' (matching CONF=$$(CONF)))
-          else
-            $$(info Building target '$(call GetRealTarget)' in these configurations (matching CONF=$$(CONF)):)
-            $$(foreach var,$$(matching_confs),$$(info * $$(var)))
-          endif
-        endif
-
-        # Create a SPEC definition. This will contain the path to one or more spec.gmk files.
-        SPEC=$$(addsuffix /spec.gmk,$$(addprefix $$(output_dir)/,$$(matching_confs)))
-      else
-        # No CONF or SPEC given, check the available configurations
-        ifneq ($$(words $$(all_spec_files)),1)
-          $$(info Error: No CONF given, but more than one configuration found.)
-          $$(info Available configurations in $$(output_dir):)
-          $$(foreach var,$$(all_confs),$$(info * $$(var)))
-          $$(info Please retry building with CONF=<config pattern> (or SPEC=<specfile>).)
-          $$(eval $$(call FatalError))
-        endif
-
-        # We found exactly one configuration, use it
-        SPEC=$$(strip $$(all_spec_files))
-      endif
-    endif
-  endif
-endef
-
-### Convenience functions from Main.gmk
-
-# Run the tests specified by $1.
-define RunTests
-	($(CD) $(SRC_ROOT)/test && $(MAKE) $(MAKE_ARGS) -j1 -k MAKEFLAGS= \
-	    JT_HOME=$(JT_HOME) PRODUCT_HOME=$(JDK_IMAGE_DIR) \
-	    TEST_IMAGE_DIR=$(TEST_IMAGE_DIR) \
-	    ALT_OUTPUTDIR=$(OUTPUT_ROOT) CONCURRENCY=$(JOBS) $1) || true
-endef
-
-# Cleans the dir given as $1
-define CleanDir
-	@$(PRINTF) "Cleaning $(strip $1) build artifacts ..."
-	@($(CD) $(OUTPUT_ROOT) && $(RM) -r $1)
-	@$(PRINTF) " done\n"
-endef
-
-define CleanTest
-	@$(PRINTF) "Cleaning test $(strip $1) ..."
-	@$(RM) -r $(SUPPORT_OUTPUTDIR)/test/$(strip $(subst -,/,$1))
-	@$(PRINTF) " done\n"
-endef
-
-define Clean-gensrc
-	@$(PRINTF) "Cleaning gensrc $(if $1,for $(strip $1) )..."
-	@$(RM) -r $(SUPPORT_OUTPUTDIR)/gensrc/$(strip $1)
-	@$(RM) -r $(SUPPORT_OUTPUTDIR)/gensrc_no_docs/$(strip $1)
-	@$(PRINTF) " done\n"
-endef
-
-define Clean-java
-	@$(PRINTF) "Cleaning java $(if $1,for $(strip $1) )..."
-	@$(RM) -r $(JDK_OUTPUTDIR)/modules/$(strip $1)
-	@$(RM) -r $(SUPPORT_OUTPUTDIR)/misc/$(strip $1)
-	@$(PRINTF) " done\n"
-	@$(PRINTF) "Cleaning headers $(if $1,for $(strip $1)) ..."
-	@$(RM) -r $(SUPPORT_OUTPUTDIR)/headers/$(strip $1)
-	@$(PRINTF) " done\n"
-endef
-
-define Clean-native
-	@$(PRINTF) "Cleaning native $(if $1,for $(strip $1) )..."
-	@$(RM) -r $(SUPPORT_OUTPUTDIR)/native/$(strip $1)
-	@$(RM) -r $(SUPPORT_OUTPUTDIR)/modules_libs/$(strip $1)
-	@$(RM) -r $(SUPPORT_OUTPUTDIR)/modules_libs-stripped/$(strip $1)
-	@$(RM) -r $(SUPPORT_OUTPUTDIR)/modules_cmds/$(strip $1)
-	@$(RM) -r $(SUPPORT_OUTPUTDIR)/modules_cmds-stripped/$(strip $1)
-	@$(PRINTF) " done\n"
-endef
-
-define Clean-include
-	@$(PRINTF) "Cleaning include $(if $1,for $(strip $1) )..."
-	@$(RM) -r $(SUPPORT_OUTPUTDIR)/modules_include/$(strip $1)
-	@$(PRINTF) " done\n"
-endef
-
-define CleanModule
-  $(call Clean-gensrc, $1)
-  $(call Clean-java, $1)
-  $(call Clean-native, $1)
-  $(call Clean-include, $1)
-endef
-
-
-################################################################################
-
-MAKE_TOPDIR_LIST := $(JDK_TOPDIR) $(CORBA_TOPDIR) $(LANGTOOLS_TOPDIR)
-MAKE_MAKEDIR_LIST := make
-
-# Helper macro for DeclareRecipesForPhase
-# Declare a recipe for calling the module and phase specific makefile.
-# If there are multiple makefiles to call, create a rule for each topdir
-# that contains a makefile with the target $module-$suffix-$repodir,
-# (i.e: java.base-gensrc-jdk)
-# Normally there is only one makefile, and the target will just be
-# $module-$suffix
-# Param 1: Name of list to add targets to
-# Param 2: Module name
-# Param 3: Topdir
-define DeclareRecipeForModuleMakefile
-  ifeq ($$($1_MULTIPLE_MAKEFILES), true)
-    $2-$$($1_TARGET_SUFFIX): $2-$$($1_TARGET_SUFFIX)-$$(notdir $3)
-    $1 += $2-$$($1_TARGET_SUFFIX)-$$(notdir $3)
-
-    $2-$$($1_TARGET_SUFFIX)-$$(notdir $3):
-  else
-    $2-$$($1_TARGET_SUFFIX):
-  endif
-	$(ECHO) $(LOG_INFO) "Building $$@"
-        ifeq ($$($1_USE_WRAPPER), true)
-	  +($(CD) $(SRC_ROOT)/make && $(MAKE) $(MAKE_ARGS) \
-	      -f ModuleWrapper.gmk \
-	          $$(addprefix -I, $$(wildcard $$(addprefix $3/, $(MAKE_MAKEDIR_LIST)) \
-	          $$(addsuffix /$$($1_MAKE_SUBDIR), $$(addprefix $3/, $(MAKE_MAKEDIR_LIST))))) \
-	          MODULE=$2 MAKEFILE_PREFIX=$$($1_FILE_PREFIX))
-        else
-	  +($(CD) $$(dir $$(firstword $$(wildcard $$(patsubst %, \
-	          $3/%/$$($1_MAKE_SUBDIR)/$$($1_FILE_PREFIX)-$2.gmk, $(MAKE_MAKEDIR_LIST))))) \
-	    && $(MAKE) $(MAKE_ARGS) \
-	          -f $$($1_FILE_PREFIX)-$2.gmk \
-	          $$(addprefix -I, $$(wildcard $$(addprefix $3/, $(MAKE_MAKEDIR_LIST)) \
-	          $$(addsuffix /$$($1_MAKE_SUBDIR), $$(addprefix $3/, $(MAKE_MAKEDIR_LIST))))) \
-	          MODULE=$2)
-        endif
-
-endef
-
-# Helper macro for DeclareRecipesForPhase
-# Param 1: Name of list to add targets to
-# Param 2: Module name
-define DeclareRecipesForPhaseAndModule
-  $1_$2_TOPDIRS := $$(strip $$(sort $$(foreach d, $(MAKE_TOPDIR_LIST), \
-      $$(patsubst $$d/%, $$d, $$(filter $$d/%, \
-          $$(wildcard $$(patsubst %, %/$$($1_MAKE_SUBDIR)/$$($1_FILE_PREFIX)-$2.gmk, \
-          $$(foreach s, $(MAKE_MAKEDIR_LIST), \
-              $$(addsuffix /$$s, $(MAKE_TOPDIR_LIST))))))))))
-
-  # Only declare recipes if there are makefiles to call
-  ifneq ($$($1_$2_TOPDIRS), )
-    $$(foreach d, $$($1_$2_TOPDIRS), \
-        $$(eval $$(call DeclareRecipeForModuleMakefile,$1,$2,$$d)))
-    $1 += $2-$$($1_TARGET_SUFFIX)
-    $1_MODULES += $2
-  endif
-endef
-
-# Declare recipes for a specific module and build phase if there are makefiles
-# present for the specific combination.
-# Param 1: Name of list to add targets to
-# Named params:
-# TARGET_SUFFIX : Suffix of target to create for recipe
-# MAKE_SUBDIR : Subdir for this build phase
-# FILE_PREFIX : File prefix for this build phase
-# USE_WRAPPER : Set to true to use ModuleWrapper.gmk
-# CHECK_MODULES : List of modules to try
-# MULTIPLE_MAKEFILES : Set to true to handle makefils for the same module in
-#                      phase in multiple repos
-# Exported variables:
-# $1_MODULES : All modules that had rules generated
-# $1_TARGETS : All targets generated
-define DeclareRecipesForPhase
-  $(foreach i,2 3 4 5 6 7, $(if $($i),$(strip $1)_$(strip $($i)))$(NEWLINE))
-  $(if $(8),$(error Internal makefile error: Too many arguments to \
-      DeclareRecipesForPhase, please update MakeHelper.gmk))
-
-  $$(foreach m, $$($(strip $1)_CHECK_MODULES), \
-      $$(eval $$(call DeclareRecipesForPhaseAndModule,$(strip $1),$$m)))
-
-  $(strip $1)_TARGETS := $$($(strip $1))
-endef
-
-################################################################################
-
-endif # _MAKEHELPERS_GMK
--- a/make/common/MakeBase.gmk	Mon Mar 23 11:44:40 2015 -0700
+++ b/make/common/MakeBase.gmk	Thu Mar 26 16:17:30 2015 +0100
@@ -32,6 +32,53 @@
 ifndef _MAKEBASE_GMK
 _MAKEBASE_GMK := 1
 
+ifeq ($(wildcard $(SPEC)),)
+  $(error MakeBase.gmk needs SPEC set to a proper spec.gmk)
+endif
+
+
+##############################
+# Functions
+##############################
+
+
+### Functions for timers
+
+# Store the build times in this directory.
+BUILDTIMESDIR=$(OUTPUT_ROOT)/make-support/build-times
+
+# Record starting time for build of a sub repository.
+define RecordStartTime
+	$(MKDIR) -p $(BUILDTIMESDIR)
+	$(DATE) '+%Y %m %d %H %M %S' | $(NAWK) '{ print $$1,$$2,$$3,$$4,$$5,$$6,($$4*3600+$$5*60+$$6) }' > $(BUILDTIMESDIR)/build_time_start_$(strip $1)
+	$(DATE) '+%Y-%m-%d %H:%M:%S' > $(BUILDTIMESDIR)/build_time_start_$(strip $1)_human_readable
+endef
+
+# Record ending time and calculate the difference and store it in a
+# easy to read format. Handles builds that cross midnight. Expects
+# that a build will never take 24 hours or more.
+define RecordEndTime
+	$(DATE) '+%Y %m %d %H %M %S' | $(NAWK) '{ print $$1,$$2,$$3,$$4,$$5,$$6,($$4*3600+$$5*60+$$6) }' > $(BUILDTIMESDIR)/build_time_end_$(strip $1)
+	$(DATE) '+%Y-%m-%d %H:%M:%S' > $(BUILDTIMESDIR)/build_time_end_$(strip $1)_human_readable
+	$(ECHO) `$(CAT) $(BUILDTIMESDIR)/build_time_start_$(strip $1)` `$(CAT) $(BUILDTIMESDIR)/build_time_end_$(strip $1)` $1 | \
+	    $(NAWK) '{ F=$$7; T=$$14; if (F > T) { T+=3600*24 }; D=T-F; H=int(D/3600); \
+	    M=int((D-H*3600)/60); S=D-H*3600-M*60; printf("%02d:%02d:%02d %s\n",H,M,S,$$15); }' \
+	    > $(BUILDTIMESDIR)/build_time_diff_$(strip $1)
+endef
+
+# Hook to be called when starting to execute a top-level target
+define TargetEnter
+	$(PRINTF) "## Starting $(patsubst %-only,%,$@)\n"
+	$(call RecordStartTime,$(patsubst %-only,%,$@))
+endef
+
+# Hook to be called when finish executing a top-level target
+define TargetExit
+	$(call RecordEndTime,$(patsubst %-only,%,$@))
+	$(PRINTF) "## Finished $(patsubst %-only,%,$@) (build time %s)\n\n" \
+	    "`$(CAT) $(BUILDTIMESDIR)/build_time_diff_$(patsubst %-only,%,$@) | $(CUT) -f 1 -d ' '`"
+endef
+
 ################################################################################
 # This macro translates $ into \$ to protect the $ from expansion in the shell.
 # To make this macro resilient against already escaped strings, first remove
@@ -341,7 +388,7 @@
 endef
 
 define SetupLogging
-  ifeq ($$(LOG_LEVEL),trace)
+  ifeq ($$(LOG_LEVEL), trace)
     # Shell redefinition trick inspired by http://www.cmcrossroads.com/ask-mr-make/6535-tracing-rule-execution-in-gnu-make
     # For each target executed, will print
     # Building <TARGET> (from <FIRST PREREQUISITE>) (<ALL NEWER PREREQUISITES> newer)
@@ -349,25 +396,25 @@
     # (and causing a crash on Cygwin).
     # Default shell seems to always be /bin/sh. Must override with bash to get this to work on Solaris.
     # Only use time if it's GNU time which supports format and output file.
-    WRAPPER_SHELL:=$$(BASH) $$(SRC_ROOT)/common/bin/shell-tracer.sh $$(if $$(findstring yes,$$(IS_GNU_TIME)),$$(TIME),-) $$(OUTPUT_ROOT)/build-trace-time.log $$(SHELL)
-    SHELL=$$(warning $$(if $$@,Building $$@,Running shell command) $$(if $$<, (from $$<))$$(if $$?, ($$(wordlist 1, 20, $$?) $$(if $$(wordlist 21, 22, $$?), ... [in total $$(words $$?) files]) newer)))$$(WRAPPER_SHELL)
+    WRAPPER_SHELL := $$(BASH) $$(SRC_ROOT)/common/bin/shell-tracer.sh $$(if $$(findstring yes,$$(IS_GNU_TIME)),$$(TIME),-) $$(OUTPUT_ROOT)/build-trace-time.log $$(SHELL)
+    SHELL := $$(warning $$(if $$@,Building $$@,Running shell command) $$(if $$<, (from $$<))$$(if $$?, ($$(wordlist 1, 20, $$?) $$(if $$(wordlist 21, 22, $$?), ... [in total $$(words $$?) files]) newer)))$$(WRAPPER_SHELL)
   endif
   # Never remove warning messages; this is just for completeness
-  LOG_WARN=
-  ifneq ($$(findstring $$(LOG_LEVEL),info debug trace),)
-    LOG_INFO=
+  LOG_WARN :=
+  ifneq ($$(findstring $$(LOG_LEVEL), info debug trace),)
+    LOG_INFO :=
   else
-    LOG_INFO=> /dev/null
+    LOG_INFO := > /dev/null
   endif
-  ifneq ($$(findstring $$(LOG_LEVEL),debug trace),)
-    LOG_DEBUG=
+  ifneq ($$(findstring $$(LOG_LEVEL), debug trace),)
+    LOG_DEBUG :=
   else
-    LOG_DEBUG=> /dev/null
+    LOG_DEBUG := > /dev/null
   endif
-  ifneq ($$(findstring $$(LOG_LEVEL),trace),)
-    LOG_TRACE=
+  ifneq ($$(findstring $$(LOG_LEVEL), trace),)
+    LOG_TRACE :=
   else
-    LOG_TRACE=> /dev/null
+    LOG_TRACE := > /dev/null
   endif
 endef