8076060: Improve make bootstrap process

Reviewed-by: erikj
This commit is contained in:
Magnus Ihse Bursie 2015-03-26 16:17:30 +01:00
parent 04284faf5c
commit 1eb8d0b847
15 changed files with 975 additions and 751 deletions

214
Makefile
View File

@ -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. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
# #
# This code is free software; you can redistribute it and/or modify it # This code is free software; you can redistribute it and/or modify it
@ -23,200 +23,42 @@
# questions. # 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 # The shell code below will be executed on /usr/ccs/bin/make on Solaris, but not in GNU Make.
# 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. # /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 .TEST_FOR_NON_GNUMAKE:sh=echo You are not using GNU Make/gmake, this is a requirement. Check your path. 1>&2 && exit 1
# Assume we have GNU make, but check version. # 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.
ifeq ($(strip $(foreach v, 3.81% 3.82% 4.%, $(filter $v, $(MAKE_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 endif
# Locate this Makefile # Locate this Makefile
ifeq ($(filter /%, $(lastword $(MAKEFILE_LIST))),) ifeq ($(filter /%, $(lastword $(MAKEFILE_LIST))),)
makefile_path:=$(CURDIR)/$(lastword $(MAKEFILE_LIST)) makefile_path := $(CURDIR)/$(strip $(lastword $(MAKEFILE_LIST)))
else else
makefile_path := $(lastword $(MAKEFILE_LIST)) makefile_path := $(lastword $(MAKEFILE_LIST))
endif endif
root_dir:=$(patsubst %/,%,$(dir $(makefile_path))) topdir := $(strip $(patsubst %/, %, $(dir $(makefile_path))))
ifeq ($(MAIN_TARGETS), ) # ... and then we can include the real makefile
COMMAND_LINE_VARIABLES:=$(subst =command,,$(filter %=command,$(foreach var,$(.VARIABLES),$(var)=$(firstword $(origin $(var)))))) include $(topdir)/make/Init.gmk
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
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
### 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

View File

@ -709,18 +709,6 @@ AC_DEFUN_ONCE([BASIC_SETUP_OUTPUT_DIR],
AC_CONFIG_FILES([$OUTPUT_ROOT/Makefile:$AUTOCONF_DIR/Makefile.in]) 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 %%% #%%% Simple tools %%%
# Check if we have found a usable version of make # Check if we have found a usable version of make

View File

@ -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. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
# #
# This code is free software; you can redistribute it and/or modify it # This code is free software; you can redistribute it and/or modify it
@ -88,7 +88,6 @@ PLATFORM_SETUP_OPENJDK_BUILD_AND_TARGET
# Continue setting up basic stuff. Most remaining code require fundamental tools. # Continue setting up basic stuff. Most remaining code require fundamental tools.
BASIC_SETUP_PATHS BASIC_SETUP_PATHS
BASIC_SETUP_LOGGING
# Check if it's a pure open build or if custom sources are to be used. # Check if it's a pure open build or if custom sources are to be used.
JDKOPT_SETUP_OPEN_OR_CUSTOM JDKOPT_SETUP_OPEN_OR_CUSTOM

View File

@ -907,9 +907,6 @@ JVM_VARIANTS
JVM_INTERPRETER JVM_INTERPRETER
JDK_VARIANT JDK_VARIANT
SET_OPENJDK SET_OPENJDK
BUILD_LOG_WRAPPER
BUILD_LOG_PREVIOUS
BUILD_LOG
TOPDIR TOPDIR
PATH_SEP PATH_SEP
ZERO_ARCHDEF ZERO_ARCHDEF
@ -3471,9 +3468,6 @@ ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var.
#%%% Simple tools %%% #%%% Simple tools %%%
# Check if we have found a usable version of make # Check if we have found a usable version of make
@ -4369,7 +4363,7 @@ VS_SDK_PLATFORM_NAME_2013=
#CUSTOM_AUTOCONF_INCLUDE #CUSTOM_AUTOCONF_INCLUDE
# Do not change or remove the following line, it is needed for consistency checks: # 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 @@ $as_echo "$as_me: The path of TOPDIR, which resolves as \"$path\", is invalid."
AUTOCONF_DIR=$TOPDIR/common/autoconf 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 if it's a pure open build or if custom sources are to be used.
# Check whether --enable-openjdk-only was given. # Check whether --enable-openjdk-only was given.

View File

@ -55,25 +55,12 @@ CONFIGURE_COMMAND_LINE:=@CONFIGURE_COMMAND_LINE@
# A self-referential reference to this file. # A self-referential reference to this file.
SPEC:=@SPEC@ SPEC:=@SPEC@
# Specify where the spec file is. # What make to use for main processing, after bootstrapping top-level Makefile.
MAKE_ARGS="SPEC=$(SPEC)"
MAKE := @MAKE@ MAKE := @MAKE@
# Pass along the verbosity and log level settings. # The default make arguments
ifeq (,$(findstring VERBOSE=,$(MAKE))) MAKE_ARGS = $(MAKE_LOG_FLAGS) -R -I $(TOPDIR)/make/common SPEC=$(SPEC) \
MAKE:=$(MAKE) $(VERBOSE) VERBOSE="$(VERBOSE)" LOG_LEVEL="$(LOG_LEVEL)" MAKE_LOG_FLAGS="$(MAKE_LOG_FLAGS)" LOG_LEVEL=$(LOG_LEVEL)
endif
# 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
OUTPUT_SYNC_SUPPORTED:=@OUTPUT_SYNC_SUPPORTED@ OUTPUT_SYNC_SUPPORTED:=@OUTPUT_SYNC_SUPPORTED@
OUTPUT_SYNC:=@OUTPUT_SYNC@ OUTPUT_SYNC:=@OUTPUT_SYNC@
@ -573,18 +560,6 @@ JTREGEXE:=@JTREGEXE@
XCODEBUILD=@XCODEBUILD@ XCODEBUILD=@XCODEBUILD@
FIXPATH:=@FIXPATH@ 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 # Build setup
ENABLE_JFR=@ENABLE_JFR@ ENABLE_JFR=@ENABLE_JFR@
ENABLE_INTREE_EC=@ENABLE_INTREE_EC@ ENABLE_INTREE_EC=@ENABLE_INTREE_EC@

3
configure vendored
View File

@ -31,4 +31,5 @@ this_script_dir=`cd $this_script_dir > /dev/null && pwd`
# Delegate to wrapper, forcing wrapper to believe $0 is this script by using -c. # 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. # 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 "$@"

115
make/Help.gmk Normal file
View File

@ -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)

View File

@ -42,7 +42,7 @@ HOTSPOT_FILES := $(shell $(FIND) -L $(HOTSPOT_TOPDIR) -name ".hg" -prune -o -pri
# not doing it breaks builds on msys. # not doing it breaks builds on msys.
$(HOTSPOT_OUTPUTDIR)/_hotspot.timestamp: $(HOTSPOT_FILES) $(HOTSPOT_OUTPUTDIR)/_hotspot.timestamp: $(HOTSPOT_FILES)
@$(MKDIR) -p $(HOTSPOT_OUTPUTDIR) @$(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) $@ $(TOUCH) $@
hotspot: $(HOTSPOT_OUTPUTDIR)/_hotspot.timestamp hotspot: $(HOTSPOT_OUTPUTDIR)/_hotspot.timestamp

229
make/Init.gmk Normal file
View File

@ -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

319
make/InitSupport.gmk Normal file
View File

@ -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

View File

@ -130,7 +130,4 @@ final-images: all
endif endif
@$(call TargetExit) @$(call TargetExit)
ALL_TARGETS += jprt_bundle bundles final-images
###########################################################################
# Phony targets
.PHONY: jprt_bundle bundles final-images

View File

@ -26,14 +26,19 @@
################################################################################ ################################################################################
# This is the main makefile containing most actual top level targets. It needs # This is the main makefile containing most actual top level targets. It needs
# to be called with a SPEC file defined. # to be called with a SPEC file defined.
################################################################################
# Declare default target # Declare default target
default: default:
ifeq ($(wildcard $(SPEC)),)
$(error Main.gmk needs SPEC set to a proper spec.gmk)
endif
# Now load the spec # Now load the spec
include $(SPEC) include $(SPEC)
include $(SRC_ROOT)/make/MakeHelpers.gmk include $(SRC_ROOT)/make/MainSupport.gmk
# Load the vital tools for all the makefiles. # Load the vital tools for all the makefiles.
include $(SRC_ROOT)/make/common/MakeBase.gmk include $(SRC_ROOT)/make/common/MakeBase.gmk
@ -588,43 +593,30 @@ dist-clean: clean
ALL_TARGETS += clean dist-clean $(CLEAN_DIR_TARGETS) $(CLEAN_TEST_TARGETS) \ ALL_TARGETS += clean dist-clean $(CLEAN_DIR_TARGETS) $(CLEAN_TEST_TARGETS) \
$(CLEAN_PHASE_TARGETS) $(CLEAN_MODULE_TARGETS) $(CLEAN_MODULE_PHASE_TARGETS) $(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 # Declare *-only targets for each normal target
$(foreach t, $(ALL_TARGETS), $(eval $(t)-only: $(t))) $(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) .PHONY: $(ALL_TARGETS)
include $(SRC_ROOT)/make/Jprt.gmk
FRC: # Force target FRC: # Force target

186
make/MainSupport.gmk Normal file
View File

@ -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

View File

@ -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

View File

@ -32,6 +32,53 @@
ifndef _MAKEBASE_GMK ifndef _MAKEBASE_GMK
_MAKEBASE_GMK := 1 _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. # This macro translates $ into \$ to protect the $ from expansion in the shell.
# To make this macro resilient against already escaped strings, first remove # To make this macro resilient against already escaped strings, first remove
@ -350,24 +397,24 @@ define SetupLogging
# Default shell seems to always be /bin/sh. Must override with bash to get this to work on Solaris. # 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. # 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) 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) 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 endif
# Never remove warning messages; this is just for completeness # Never remove warning messages; this is just for completeness
LOG_WARN= LOG_WARN :=
ifneq ($$(findstring $$(LOG_LEVEL), info debug trace),) ifneq ($$(findstring $$(LOG_LEVEL), info debug trace),)
LOG_INFO= LOG_INFO :=
else else
LOG_INFO=> /dev/null LOG_INFO := > /dev/null
endif endif
ifneq ($$(findstring $$(LOG_LEVEL), debug trace),) ifneq ($$(findstring $$(LOG_LEVEL), debug trace),)
LOG_DEBUG= LOG_DEBUG :=
else else
LOG_DEBUG=> /dev/null LOG_DEBUG := > /dev/null
endif endif
ifneq ($$(findstring $$(LOG_LEVEL), trace),) ifneq ($$(findstring $$(LOG_LEVEL), trace),)
LOG_TRACE= LOG_TRACE :=
else else
LOG_TRACE=> /dev/null LOG_TRACE := > /dev/null
endif endif
endef endef