diff --git a/Makefile b/Makefile index ebe52d5d7f2fa..b094e14efbd80 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ # -# Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2012, 2025, 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 @@ -24,8 +24,9 @@ # ### -### This file is just a very small wrapper needed to run the real make/Init.gmk. -### It also performs some sanity checks on make. +### This file is just a very small wrapper which will include make/PreInit.gmk, +### where the real work is done. This wrapper also performs some sanity checks +### on make that must be done before we can include another file. ### # The shell code below will be executed on /usr/bin/make on Solaris, but not in GNU Make. @@ -60,5 +61,5 @@ else endif topdir := $(strip $(patsubst %/, %, $(dir $(makefile_path)))) -# ... and then we can include the real makefile -include $(topdir)/make/Init.gmk +# ... and then we can include the real makefile to bootstrap the build +include $(topdir)/make/PreInit.gmk diff --git a/doc/hotspot-style.html b/doc/hotspot-style.html index 0305bfeca03bd..9f26fc6636205 100644 --- a/doc/hotspot-style.html +++ b/doc/hotspot-style.html @@ -217,10 +217,10 @@

Source Files

should be put in the .hpp file, and not in the .inline.hpp file. This rule exists to resolve problems with circular dependencies between .inline.hpp files.

-
  • All .cpp files include precompiled.hpp as the first include -line.

  • -
  • precompiled.hpp is just a build time optimization, so don't rely -on it to resolve include problems.

  • +
  • Some build configurations use precompiled headers to speed up the +build times. The precompiled headers are included in the precompiled.hpp +file. Note that precompiled.hpp is just a build time optimization, so +don't rely on it to resolve include problems.

  • Keep the include lines alphabetically sorted.

  • Put conditional inclusions (#if ...) at the end of the include list.

  • diff --git a/doc/hotspot-style.md b/doc/hotspot-style.md index f5e59648cb23c..0150662981736 100644 --- a/doc/hotspot-style.md +++ b/doc/hotspot-style.md @@ -150,10 +150,10 @@ the first include line. Declarations needed by other files should be put in the .hpp file, and not in the .inline.hpp file. This rule exists to resolve problems with circular dependencies between .inline.hpp files. -* All .cpp files include precompiled.hpp as the first include line. - -* precompiled.hpp is just a build time optimization, so don't rely on -it to resolve include problems. +* Some build configurations use precompiled headers to speed up the +build times. The precompiled headers are included in the precompiled.hpp +file. Note that precompiled.hpp is just a build time optimization, so +don't rely on it to resolve include problems. * Keep the include lines alphabetically sorted. diff --git a/make/Init.gmk b/make/Init.gmk index f2cfe3625a520..5a10f42482f80 100644 --- a/make/Init.gmk +++ b/make/Init.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2012, 2025, 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 @@ -24,9 +24,11 @@ # ################################################################################ -# 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. +# Init.gmk sits between PreInit.gmk and Main.gmk when bootstrapping the build. +# It is called from PreInit.gmk, and its main responsibility is to launch +# Main.gmk with the proper make and the proper make arguments. +# PreMain.gmk has provided us with a proper SPEC. This allows us to use the +# value of $(MAKE) for all further make calls. ################################################################################ # This must be the first rule @@ -37,249 +39,74 @@ default: # serially, regardless of -j. .NOTPARALLEL: -ifeq ($(HAS_SPEC), ) - ############################################################################## - # This is the default mode. We have not been recursively called with a SPEC. - ############################################################################## +include $(SPEC) - # Include our helper functions. - include $(topdir)/make/InitSupport.gmk +include $(TOPDIR)/make/common/MakeBase.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/Global.gmk +# Our helper functions. +include $(TOPDIR)/make/InitSupport.gmk +include $(TOPDIR)/make/common/LogUtils.gmk - # Targets provided by Init.gmk. - ALL_INIT_TARGETS := print-modules print-targets print-configuration \ - print-tests reconfigure pre-compare-build post-compare-build +# Force early generation of module-deps.gmk and find-tests.gmk +GENERATE_MODULE_DEPS_FILE := true +include $(TOPDIR)/make/common/Modules.gmk +GENERATE_FIND_TESTS_FILE := true +include $(TOPDIR)/make/common/FindTests.gmk - # CALLED_TARGETS is the list of targets that the user provided, - # or "default" if unspecified. - CALLED_TARGETS := $(if $(MAKECMDGOALS), $(MAKECMDGOALS), default) +# Parse COMPARE_BUILD (for makefile development) +$(eval $(call ParseCompareBuild)) - # Extract non-global targets that require a spec file. - CALLED_SPEC_TARGETS := $(filter-out $(ALL_GLOBAL_TARGETS), $(CALLED_TARGETS)) +# Setup reproducible build environment +$(eval $(call SetupReproducibleBuild)) - # If we have only global targets, or if we are called with -qp (assuming an - # external part, e.g. bash completion, is trying to understand our targets), - # we will skip SPEC location and the sanity checks. - ifeq ($(CALLED_SPEC_TARGETS), ) - ONLY_GLOBAL_TARGETS := true - endif - ifeq ($(findstring p, $(MAKEFLAGS))$(findstring q, $(MAKEFLAGS)), pq) - ONLY_GLOBAL_TARGETS := true - endif - - ifeq ($(ONLY_GLOBAL_TARGETS), true) - ############################################################################ - # We have only global targets, or are called with -pq. - ############################################################################ - - ifeq ($(wildcard $(SPEC)), ) - # If we have no SPEC provided, we will just make a "best effort" target list. - # First try to grab any available pre-existing main-targets.gmk. - main_targets_file := $(firstword $(wildcard $(build_dir)/*/make-support/main-targets.gmk)) - ifneq ($(main_targets_file), ) - # Extract the SPEC that corresponds to this main-targets.gmk file. - SPEC := $(patsubst %/make-support/main-targets.gmk, %/spec.gmk, $(main_targets_file)) - else - # None found, pick an arbitrary SPEC for which to generate a file - SPEC := $(firstword $(all_spec_files)) - endif - endif - - ifneq ($(wildcard $(SPEC)), ) - $(eval $(call DefineMainTargets, LAZY, $(SPEC))) - else - # If we have no configurations we can not provide any main targets. - ALL_MAIN_TARGETS := - endif - - ALL_TARGETS := $(sort $(ALL_GLOBAL_TARGETS) $(ALL_MAIN_TARGETS) $(ALL_INIT_TARGETS)) - - # Just list all our targets. - $(ALL_TARGETS): - - .PHONY: $(ALL_TARGETS) - - else - ############################################################################ - # 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. - # We have at least one non-global target, so we need to find a spec file. - ############################################################################ - - # Basic checks on environment and command line. - $(eval $(call CheckControlVariables)) - $(eval $(call CheckDeprecatedEnvironment)) - $(eval $(call CheckInvalidMakeFlags)) - - # Check that CONF_CHECK is valid. - $(eval $(call ParseConfCheckOption)) - - # Check that the LOG given is valid, and set LOG_LEVEL, LOG_NOFILE, MAKE_LOG_VARS and MAKE_LOG_FLAGS. +# If no LOG= was given on command line, but we have a non-standard default +# value, use that instead and re-parse log level. +ifeq ($(LOG), ) + ifneq ($(DEFAULT_LOG), ) + override LOG := $(DEFAULT_LOG) $(eval $(call ParseLogLevel)) - - # After this SPECS contain 1..N spec files (otherwise ParseConfAndSpec fails). - $(eval $(call ParseConfAndSpec)) - - # Extract main targets from Main.gmk using the spec(s) provided. In theory, - # with multiple specs, we should find the intersection of targets provided - # by all specs, but we approximate this by an arbitrary spec from the list. - # This will setup ALL_MAIN_TARGETS. - $(eval $(call DefineMainTargets, FORCE, $(firstword $(SPECS)))) - - # Separate called targets depending on type. - INIT_TARGETS := $(filter $(ALL_INIT_TARGETS), $(CALLED_SPEC_TARGETS)) - MAIN_TARGETS := $(filter $(ALL_MAIN_TARGETS), $(CALLED_SPEC_TARGETS)) - SEQUENTIAL_TARGETS := $(filter dist-clean clean%, $(MAIN_TARGETS)) - PARALLEL_TARGETS := $(filter-out $(SEQUENTIAL_TARGETS), $(MAIN_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)/make/autoconf/*) \ - $(if $(CUSTOM_CONFIG_DIR), $(wildcard $(CUSTOM_CONFIG_DIR)/*)) \ - $(addprefix $(topdir)/make/conf/, version-numbers.conf branding.conf) \ - $(if $(CUSTOM_CONF_DIR), $(wildcard $(addprefix $(CUSTOM_CONF_DIR)/, \ - version-numbers.conf branding.conf))) - 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) -r -R -f $(topdir)/make/Init.gmk \ - SPEC=$@ HAS_SPEC=true ACTUAL_TOPDIR=$(topdir) \ - reconfigure ) - else ifeq ($(CONF_CHECK), ignore) - # Do nothing - endif - - # Do not let make delete spec files even if aborted while doing a reconfigure - .PRECIOUS: $(SPECS) - - # Unless reconfigure is explicitly called, let all main targets depend on - # the spec files to be up to date. - ifeq ($(findstring reconfigure, $(INIT_TARGETS)), ) - $(MAIN_TARGETS): $(SPECS) - endif - - make-info: - ifneq ($(findstring $(LOG_LEVEL), info debug trace), ) - $(info Running make as '$(strip $(MAKE) $(MFLAGS) \ - $(COMMAND_LINE_VARIABLES) $(MAKECMDGOALS))') - endif - - MAKE_INIT_WITH_SPEC_ARGUMENTS := ACTUAL_TOPDIR=$(topdir) \ - USER_MAKE_VARS="$(USER_MAKE_VARS)" MAKE_LOG_FLAGS=$(MAKE_LOG_FLAGS) \ - $(MAKE_LOG_VARS) \ - INIT_TARGETS="$(INIT_TARGETS)" \ - SEQUENTIAL_TARGETS="$(SEQUENTIAL_TARGETS)" \ - PARALLEL_TARGETS="$(PARALLEL_TARGETS)" - - # Now the init and main targets will be called, once for each SPEC. 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. - # The COMPARE_BUILD part implements special support for makefile development. - $(ALL_INIT_TARGETS) $(ALL_MAIN_TARGETS): make-info - @$(if $(TARGET_DONE), \ - true \ - , \ - ( cd $(topdir) && \ - $(foreach spec, $(SPECS), \ - $(MAKE) $(MFLAGS) $(MAKE_LOG_FLAGS) -r -R -j 1 -f $(topdir)/make/Init.gmk \ - SPEC=$(spec) HAS_SPEC=true $(MAKE_INIT_WITH_SPEC_ARGUMENTS) \ - main && \ - $(if $(and $(COMPARE_BUILD), $(PARALLEL_TARGETS)), \ - $(MAKE) $(MFLAGS) $(MAKE_LOG_FLAGS) -r -R -f $(topdir)/make/Init.gmk \ - SPEC=$(spec) HAS_SPEC=true ACTUAL_TOPDIR=$(topdir) \ - COMPARE_BUILD="$(COMPARE_BUILD)" pre-compare-build && \ - $(MAKE) $(MFLAGS) $(MAKE_LOG_FLAGS) -r -R -j 1 -f $(topdir)/make/Init.gmk \ - SPEC=$(spec) HAS_SPEC=true $(MAKE_INIT_WITH_SPEC_ARGUMENTS) \ - COMPARE_BUILD="$(COMPARE_BUILD):NODRYRUN=true" main && \ - $(MAKE) $(MFLAGS) $(MAKE_LOG_FLAGS) -r -R -f $(topdir)/make/Init.gmk \ - SPEC=$(spec) HAS_SPEC=true ACTUAL_TOPDIR=$(topdir) \ - COMPARE_BUILD="$(COMPARE_BUILD):NODRYRUN=true" post-compare-build && \ - ) \ - ) true ) \ - $(eval TARGET_DONE=true) \ - ) - - .PHONY: $(ALL_MAIN_TARGETS) $(ALL_INIT_TARGETS) - - endif # $(ONLY_GLOBAL_TARGETS)!=true - -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. - ############################################################################## - - include $(SPEC) - - # Our helper functions. - include $(TOPDIR)/make/InitSupport.gmk - - # Parse COMPARE_BUILD (for makefile development) - $(eval $(call ParseCompareBuild)) - - # Setup reproducible build environment - $(eval $(call SetupReproducibleBuild)) - - # If no LOG= was given on command line, but we have a non-standard default - # value, use that instead and re-parse log level. - ifeq ($(LOG), ) - ifneq ($(DEFAULT_LOG), ) - override LOG := $(DEFAULT_LOG) - $(eval $(call ParseLogLevel)) - endif endif +endif - ifeq ($(LOG_NOFILE), true) - # Disable build log if LOG=[level,]nofile was given - override BUILD_LOG_PIPE := - override BUILD_LOG_PIPE_SIMPLE := - endif +ifeq ($(LOG_NOFILE), true) + # Disable build log if LOG=[level,]nofile was given + override BUILD_LOG_PIPE := + override BUILD_LOG_PIPE_SIMPLE := +endif - ifeq ($(filter dist-clean, $(SEQUENTIAL_TARGETS)), dist-clean) - # We can't have a log file if we're about to remove it. - override BUILD_LOG_PIPE := - override BUILD_LOG_PIPE_SIMPLE := - endif +ifeq ($(filter dist-clean, $(SEQUENTIAL_TARGETS)), dist-clean) + # We can't have a log file if we're about to remove it. + override BUILD_LOG_PIPE := + override BUILD_LOG_PIPE_SIMPLE := +endif - ifeq ($(OUTPUT_SYNC_SUPPORTED), true) - OUTPUT_SYNC_FLAG := -O$(OUTPUT_SYNC) - endif +ifeq ($(OUTPUT_SYNC_SUPPORTED), true) + OUTPUT_SYNC_FLAG := -O$(OUTPUT_SYNC) +endif - ############################################################################## - # Init targets - ############################################################################## +############################################################################## +# Init targets. These are handled fully, here and now. +############################################################################## - print-modules: +print-modules: ( cd $(TOPDIR) && \ $(MAKE) $(MAKE_ARGS) -j 1 -f make/Main.gmk $(USER_MAKE_VARS) \ NO_RECIPES=true print-modules ) - print-targets: +print-targets: ( cd $(TOPDIR) && \ $(MAKE) $(MAKE_ARGS) -j 1 -f make/Main.gmk $(USER_MAKE_VARS) \ NO_RECIPES=true print-targets ) - print-tests: +print-tests: ( cd $(TOPDIR) && \ $(MAKE) $(MAKE_ARGS) -j 1 -f make/Main.gmk $(USER_MAKE_VARS) \ NO_RECIPES=true print-tests ) - print-configuration: - $(ECHO) $(CONFIGURE_COMMAND_LINE) +print-configuration: + $(ECHO) $(CONFIGURE_COMMAND_LINE) - reconfigure: +reconfigure: ifneq ($(REAL_CONFIGURE_COMMAND_EXEC_FULL), ) $(ECHO) "Re-running configure using original command line '$(REAL_CONFIGURE_COMMAND_EXEC_SHORT) $(REAL_CONFIGURE_COMMAND_LINE)'" $(eval RECONFIGURE_COMMAND := $(REAL_CONFIGURE_COMMAND_EXEC_FULL) $(REAL_CONFIGURE_COMMAND_LINE)) @@ -295,25 +122,27 @@ else # HAS_SPEC=true CUSTOM_CONFIG_DIR="$(CUSTOM_CONFIG_DIR)" \ $(RECONFIGURE_COMMAND) ) - ############################################################################## - # The main target, for delegating into Main.gmk - ############################################################################## +.PHONY: print-modules print-targets print-tests print-configuration reconfigure - MAIN_TARGETS := $(SEQUENTIAL_TARGETS) $(PARALLEL_TARGETS) $(COMPARE_BUILD_MAKE) - # If building the default target, add what they are to the description. - DESCRIPTION_TARGETS := $(strip $(MAIN_TARGETS)) - ifeq ($(DESCRIPTION_TARGETS), default) - DESCRIPTION_TARGETS += ($(DEFAULT_MAKE_TARGET)) - endif - TARGET_DESCRIPTION := target$(if $(word 2, $(MAIN_TARGETS)),s) \ - '$(strip $(DESCRIPTION_TARGETS))' in configuration '$(CONF_NAME)' +############################################################################## +# The main target. This will delegate all other targets into Main.gmk. +############################################################################## - # 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 explicitly propagated using $(USER_MAKE_VARS). - main: MAKEOVERRIDES := +MAIN_TARGETS := $(SEQUENTIAL_TARGETS) $(PARALLEL_TARGETS) $(COMPARE_BUILD_MAKE) +# If building the default target, add what they are to the description. +DESCRIPTION_TARGETS := $(strip $(MAIN_TARGETS)) +ifeq ($(DESCRIPTION_TARGETS), default) + DESCRIPTION_TARGETS += ($(DEFAULT_MAKE_TARGET)) +endif +TARGET_DESCRIPTION := target$(if $(word 2, $(MAIN_TARGETS)),s) \ + '$(strip $(DESCRIPTION_TARGETS))' in configuration '$(CONF_NAME)' - main: $(INIT_TARGETS) +# 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 explicitly propagated using $(USER_MAKE_VARS). +main: MAKEOVERRIDES := + +main: $(INIT_TARGETS) ifneq ($(SEQUENTIAL_TARGETS)$(PARALLEL_TARGETS), ) $(call RotateLogFiles) $(PRINTF) "Building $(TARGET_DESCRIPTION)\n" $(BUILD_LOG_PIPE_SIMPLE) @@ -333,7 +162,7 @@ else # HAS_SPEC=true # treat it as NOT using jobs at all. ( cd $(TOPDIR) && \ $(NICE) $(MAKE) $(MAKE_ARGS) $(OUTPUT_SYNC_FLAG) \ - $(if $(JOBS), -j $(JOBS)) \ + $(if $(JOBS), -j $(JOBS)) \ -f make/Main.gmk $(USER_MAKE_VARS) \ $(PARALLEL_TARGETS) $(COMPARE_BUILD_MAKE) $(BUILD_LOG_PIPE) || \ ( exitcode=$$? && \ @@ -353,7 +182,7 @@ else # HAS_SPEC=true $(call ReportProfileTimes) endif - on-failure: +on-failure: $(call CleanupJavacServer) $(call StopGlobalTimer) $(call ReportBuildTimes) @@ -365,15 +194,14 @@ else # HAS_SPEC=true $(call CleanupCompareBuild) endif - # Support targets for COMPARE_BUILD, used for makefile development - pre-compare-build: +# Support targets for COMPARE_BUILD, used for makefile development +pre-compare-build: $(call WaitForJavacServerFinish) $(call PrepareCompareBuild) - post-compare-build: +post-compare-build: $(call WaitForJavacServerFinish) $(call CleanupCompareBuild) $(call CompareBuildDoComparison) - .PHONY: print-targets print-modules reconfigure main on-failure -endif +.PHONY: main on-failure pre-compare-build post-compare-build diff --git a/make/InitSupport.gmk b/make/InitSupport.gmk index baee52a888edc..a4b4f2ca96462 100644 --- a/make/InitSupport.gmk +++ b/make/InitSupport.gmk @@ -25,394 +25,108 @@ ################################################################################ # 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 - -ifeq ($(HAS_SPEC), ) - - # COMMA is defined in spec.gmk, but that is not included yet - COMMA := , - - # Include the corresponding closed file, if present. - ifneq ($(CUSTOM_MAKE_DIR), ) - -include $(CUSTOM_MAKE_DIR)/InitSupport.gmk - endif - - ############################################################################## - # 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. - ############################################################################## - - # Essential control variables that are handled by Init.gmk - INIT_CONTROL_VARIABLES := LOG CONF CONF_NAME SPEC JOBS CONF_CHECK ALLOW \ - COMPARE_BUILD - - # All known make control variables; these are handled in other makefiles - MAKE_CONTROL_VARIABLES += JDK_FILTER SPEC_FILTER \ - TEST TEST_JOBS JTREG GTEST MICRO TEST_OPTS TEST_VM_OPTS TEST_DEPS - - ALL_CONTROL_VARIABLES := $(INIT_CONTROL_VARIABLES) $(MAKE_CONTROL_VARIABLES) - - # 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. - # The '§' <=> '\ 'dance is needed to keep values with space in them connected. - 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. - # The '§' <=> '\ 'dance is needed to keep values with space in them connected. - USER_MAKE_VARS := $(subst §,\ , $(filter-out $(addsuffix =%, $(INIT_CONTROL_VARIABLES)), \ - $(subst \ ,§,$(MAKEOVERRIDES)))) - - # Setup information about available configurations, if any. - ifneq ($(CUSTOM_ROOT), ) - build_dir = $(CUSTOM_ROOT)/build - else - build_dir = $(topdir)/build +# Define basic logging setup +BUILD_LOG := $(OUTPUTDIR)/build.log +BUILD_PROFILE_LOG := $(OUTPUTDIR)/build-profile.log + +BUILD_LOG_PIPE := > >($(TEE) -a $(BUILD_LOG)) 2> >($(TEE) -a $(BUILD_LOG) >&2) && wait +# Use this for simple echo/printf commands that are never expected to print +# to stderr. +BUILD_LOG_PIPE_SIMPLE := | $(TEE) -a $(BUILD_LOG) + +ifneq ($(CUSTOM_ROOT), ) + topdir = $(CUSTOM_ROOT) +else + topdir = $(TOPDIR) +endif + +# Setup the build environment to match the requested specification on +# level of reproducible builds +define SetupReproducibleBuild + ifeq ($$(SOURCE_DATE), updated) + # For static values of SOURCE_DATE (not "updated"), these are set in spec.gmk + export SOURCE_DATE_EPOCH := $$(shell $$(DATE) +"%s") + export SOURCE_DATE_ISO_8601 := $$(call EpochToISO8601, $$(SOURCE_DATE_EPOCH)) endif - 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))) - - # Check for unknown command-line variables - define CheckControlVariables - command_line_variables := $$(strip $$(foreach var, \ - $$(subst \ ,_,$$(MAKEOVERRIDES)), \ - $$(firstword $$(subst =, , $$(var))))) - allowed_command_line_variables := $$(strip $$(subst $$(COMMA), , $$(ALLOW))) - unknown_command_line_variables := $$(strip \ - $$(filter-out $$(ALL_CONTROL_VARIABLES) $$(allowed_command_line_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 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 - ifneq ($$(origin CONF_NAME), undefined) - # We also have a CONF_NAME argument. We can't have both. - $$(info Error: Cannot use CONF_NAME=$$(CONF_NAME) 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 +endef - # For now, unset this SPEC variable. - override SPEC := +# Parse COMPARE_BUILD into COMPARE_BUILD_* +# Syntax: COMPARE_BUILD=CONF=:PATCH=: +# MAKE=:COMP_OPTS=: +# COMP_DIR=|: +# FAIL= +# If neither CONF or PATCH is given, assume means CONF if it +# begins with "--", otherwise assume it means PATCH. +# MAKE and COMP_OPTS can only be used with CONF and/or PATCH specified. +# If any value contains "+", it will be replaced by space. +# FAIL can be set to false to have the return value of compare be ignored. +define ParseCompareBuild + ifneq ($$(COMPARE_BUILD), ) + COMPARE_BUILD_OUTPUTDIR := $(topdir)/build/compare-build/$(CONF_NAME) + COMPARE_BUILD_FAIL := true + + ifneq ($$(findstring :, $$(COMPARE_BUILD)), ) + $$(foreach part, $$(subst :, , $$(COMPARE_BUILD)), \ + $$(if $$(filter PATCH=%, $$(part)), \ + $$(eval COMPARE_BUILD_PATCH = $$(strip $$(patsubst PATCH=%, %, $$(part)))) \ + ) \ + $$(if $$(filter CONF=%, $$(part)), \ + $$(eval COMPARE_BUILD_CONF = $$(strip $$(subst +, , $$(patsubst CONF=%, %, $$(part))))) \ + ) \ + $$(if $$(filter MAKE=%, $$(part)), \ + $$(eval COMPARE_BUILD_MAKE = $$(strip $$(subst +, , $$(patsubst MAKE=%, %, $$(part))))) \ + ) \ + $$(if $$(filter COMP_OPTS=%, $$(part)), \ + $$(eval COMPARE_BUILD_COMP_OPTS = $$(strip $$(subst +, , $$(patsubst COMP_OPTS=%, %, $$(part))))) \ + ) \ + $$(if $$(filter COMP_DIR=%, $$(part)), \ + $$(eval COMPARE_BUILD_COMP_DIR = $$(strip $$(subst +, , $$(patsubst COMP_DIR=%, %, $$(part))))) \ + ) \ + $$(if $$(filter FAIL=%, $$(part)), \ + $$(eval COMPARE_BUILD_FAIL = $$(strip $$(subst +, , $$(patsubst FAIL=%, %, $$(part))))) \ + ) \ + $$(if $$(filter NODRYRUN=%, $$(part)), \ + $$(eval COMPARE_BUILD_NODRYRUN = $$(strip $$(subst +, , $$(patsubst NODRYRUN=%, %, $$(part))))) \ + ) \ + ) else - # Use spec.gmk files in the build output directory - ifeq ($$(all_spec_files), ) - ifneq ($(CUSTOM_ROOT), ) - $$(info Error: No configurations found for $$(CUSTOM_ROOT).) - else - $$(info Error: No configurations found for $$(topdir).) - endif - $$(info Please run 'bash configure' to create a configuration.) - $$(info ) - $$(error Cannot continue) - endif - - ifneq ($$(origin CONF_NAME), undefined) - ifneq ($$(origin CONF), undefined) - # We also have a CONF argument. We can't have both. - $$(info Error: Cannot use CONF=$$(CONF) and CONF_NAME=$$(CONF_NAME) at the same time. Choose one.) - $$(error Cannot continue) - endif - matching_conf := $$(strip $$(filter $$(CONF_NAME), $$(all_confs))) - ifeq ($$(matching_conf), ) - $$(info Error: No configurations found matching CONF_NAME=$$(CONF_NAME).) - $$(info Available configurations in $$(build_dir):) - $$(foreach var, $$(all_confs), $$(info * $$(var))) - $$(error Cannot continue) - else ifneq ($$(words $$(matching_conf)), 1) - $$(info Error: Matching more than one configuration CONF_NAME=$$(CONF_NAME).) - $$(info Available configurations in $$(build_dir):) - $$(foreach var, $$(all_confs), $$(info * $$(var))) - $$(error Cannot continue) - else - $$(info Building configuration '$$(matching_conf)' (matching CONF_NAME=$$(CONF_NAME))) - endif - # Create a SPEC definition. This will contain the path to exactly one spec file. - SPECS := $$(build_dir)/$$(matching_conf)/spec.gmk - else 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 - ifeq ($$(patsubst !%,,$$(CONF)), ) - # A CONF starting with ! means we should negate the search term - matching_confs := $$(strip $$(foreach var, $$(all_confs), \ - $$(if $$(findstring $$(subst !,,$$(CONF)), $$(var)), ,$$(var)))) - else - matching_confs := $$(strip $$(foreach var, $$(all_confs), \ - $$(if $$(findstring $$(CONF), $$(var)), $$(var)))) - endif - ifneq ($$(filter $$(CONF), $$(matching_confs)), ) - ifneq ($$(word 2, $$(matching_confs)), ) - # Don't repeat this output on make restarts caused by including - # generated files. - ifeq ($$(MAKE_RESTARTS), ) - $$(info Using exact match for CONF=$$(CONF) (other matches are possible)) - endif - endif - # If we found an exact match, use that - matching_confs := $$(CONF) - endif - 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 - # Don't repeat this output on make restarts caused by including - # generated files. - ifeq ($$(MAKE_RESTARTS), ) - ifeq ($$(words $$(matching_confs)), 1) - ifneq ($$(findstring $$(LOG_LEVEL), info debug trace), ) - $$(info Building configuration '$$(matching_confs)' (matching CONF=$$(CONF))) - endif - else - $$(info Building these configurations (matching CONF=$$(CONF)):) - $$(foreach var, $$(matching_confs), $$(info * $$(var))) - endif - 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))) + # Separate handling for single field case, to allow for spaces in values. + ifneq ($$(filter PATCH=%, $$(COMPARE_BUILD)), ) + COMPARE_BUILD_PATCH = $$(strip $$(patsubst PATCH=%, %, $$(COMPARE_BUILD))) + else ifneq ($$(filter CONF=%, $$(COMPARE_BUILD)), ) + COMPARE_BUILD_CONF = $$(strip $$(subst +, , $$(patsubst CONF=%, %, $$(COMPARE_BUILD)))) + else ifneq ($$(filter --%, $$(COMPARE_BUILD)), ) + # Assume CONF if value begins with -- + COMPARE_BUILD_CONF = $$(strip $$(subst +, , $$(COMPARE_BUILD))) 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= (or SPEC=).) - $$(info ) - $$(error Cannot continue) - endif - - # We found exactly one configuration, use it - SPECS := $$(strip $$(all_spec_files)) - endif - endif - endef - - # Extract main targets from Main.gmk using the spec provided in $2. - # - # Param 1: FORCE = force generation of main-targets.gmk or LAZY = do not force. - # Param 2: The SPEC file to use. - define DefineMainTargets - - # We will start by making sure the main-targets.gmk file is removed, if - # make has not been restarted. By the -include, we will trigger the - # rule for generating the file (which is never there since we removed it), - # thus generating it fresh, and make will restart, incrementing the restart - # count. - main_targets_file := $$(dir $(strip $2))make-support/main-targets.gmk - - ifeq ($$(MAKE_RESTARTS), ) - # Only do this if make has not been restarted, and if we do not force it. - ifeq ($(strip $1), FORCE) - $$(shell rm -f $$(main_targets_file)) + # Otherwise assume patch file + COMPARE_BUILD_PATCH = $$(strip $$(COMPARE_BUILD)) endif endif - - $$(main_targets_file): - @( cd $$(topdir) && \ - $$(MAKE) $$(MAKE_LOG_FLAGS) -r -R -f $$(topdir)/make/Main.gmk \ - -I $$(topdir)/make/common SPEC=$(strip $2) NO_RECIPES=true \ - $$(MAKE_LOG_VARS) \ - create-main-targets-include ) - - # Now include main-targets.gmk. This will define ALL_MAIN_TARGETS. - -include $$(main_targets_file) - 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=." - @echo ' ' - endef - -else # $(HAS_SPEC)=true - ############################################################################## - # Helper functions for the 'main' target. These functions assume a single, - # proper and existing SPEC is included. - ############################################################################## - - include $(TOPDIR)/make/common/MakeBase.gmk - - # Define basic logging setup - BUILD_LOG := $(OUTPUTDIR)/build.log - BUILD_PROFILE_LOG := $(OUTPUTDIR)/build-profile.log - - BUILD_LOG_PIPE := > >($(TEE) -a $(BUILD_LOG)) 2> >($(TEE) -a $(BUILD_LOG) >&2) && wait - # Use this for simple echo/printf commands that are never expected to print - # to stderr. - BUILD_LOG_PIPE_SIMPLE := | $(TEE) -a $(BUILD_LOG) - - ifneq ($(CUSTOM_ROOT), ) - topdir = $(CUSTOM_ROOT) - else - topdir = $(TOPDIR) - endif - - # Setup the build environment to match the requested specification on - # level of reproducible builds - define SetupReproducibleBuild - ifeq ($$(SOURCE_DATE), updated) - # For static values of SOURCE_DATE (not "updated"), these are set in spec.gmk - export SOURCE_DATE_EPOCH := $$(shell $$(DATE) +"%s") - export SOURCE_DATE_ISO_8601 := $$(call EpochToISO8601, $$(SOURCE_DATE_EPOCH)) - endif - endef - - # Parse COMPARE_BUILD into COMPARE_BUILD_* - # Syntax: COMPARE_BUILD=CONF=:PATCH=: - # MAKE=:COMP_OPTS=: - # COMP_DIR=|: - # FAIL= - # If neither CONF or PATCH is given, assume means CONF if it - # begins with "--", otherwise assume it means PATCH. - # MAKE and COMP_OPTS can only be used with CONF and/or PATCH specified. - # If any value contains "+", it will be replaced by space. - # FAIL can be set to false to have the return value of compare be ignored. - define ParseCompareBuild - ifneq ($$(COMPARE_BUILD), ) - COMPARE_BUILD_OUTPUTDIR := $(topdir)/build/compare-build/$(CONF_NAME) - COMPARE_BUILD_FAIL := true - - ifneq ($$(findstring :, $$(COMPARE_BUILD)), ) - $$(foreach part, $$(subst :, , $$(COMPARE_BUILD)), \ - $$(if $$(filter PATCH=%, $$(part)), \ - $$(eval COMPARE_BUILD_PATCH = $$(strip $$(patsubst PATCH=%, %, $$(part)))) \ - ) \ - $$(if $$(filter CONF=%, $$(part)), \ - $$(eval COMPARE_BUILD_CONF = $$(strip $$(subst +, , $$(patsubst CONF=%, %, $$(part))))) \ - ) \ - $$(if $$(filter MAKE=%, $$(part)), \ - $$(eval COMPARE_BUILD_MAKE = $$(strip $$(subst +, , $$(patsubst MAKE=%, %, $$(part))))) \ - ) \ - $$(if $$(filter COMP_OPTS=%, $$(part)), \ - $$(eval COMPARE_BUILD_COMP_OPTS = $$(strip $$(subst +, , $$(patsubst COMP_OPTS=%, %, $$(part))))) \ - ) \ - $$(if $$(filter COMP_DIR=%, $$(part)), \ - $$(eval COMPARE_BUILD_COMP_DIR = $$(strip $$(subst +, , $$(patsubst COMP_DIR=%, %, $$(part))))) \ - ) \ - $$(if $$(filter FAIL=%, $$(part)), \ - $$(eval COMPARE_BUILD_FAIL = $$(strip $$(subst +, , $$(patsubst FAIL=%, %, $$(part))))) \ - ) \ - $$(if $$(filter NODRYRUN=%, $$(part)), \ - $$(eval COMPARE_BUILD_NODRYRUN = $$(strip $$(subst +, , $$(patsubst NODRYRUN=%, %, $$(part))))) \ - ) \ - ) - else - # Separate handling for single field case, to allow for spaces in values. - ifneq ($$(filter PATCH=%, $$(COMPARE_BUILD)), ) - COMPARE_BUILD_PATCH = $$(strip $$(patsubst PATCH=%, %, $$(COMPARE_BUILD))) - else ifneq ($$(filter CONF=%, $$(COMPARE_BUILD)), ) - COMPARE_BUILD_CONF = $$(strip $$(subst +, , $$(patsubst CONF=%, %, $$(COMPARE_BUILD)))) - else ifneq ($$(filter --%, $$(COMPARE_BUILD)), ) - # Assume CONF if value begins with -- - COMPARE_BUILD_CONF = $$(strip $$(subst +, , $$(COMPARE_BUILD))) - else - # Otherwise assume patch file - COMPARE_BUILD_PATCH = $$(strip $$(COMPARE_BUILD)) - endif + ifneq ($$(COMPARE_BUILD_PATCH), ) + ifneq ($$(wildcard $$(topdir)/$$(COMPARE_BUILD_PATCH)), ) + # Assume relative path, if file exists + COMPARE_BUILD_PATCH := $$(wildcard $$(topdir)/$$(COMPARE_BUILD_PATCH)) + else ifeq ($$(wildcard $$(COMPARE_BUILD_PATCH)), ) + $$(error Patch file $$(COMPARE_BUILD_PATCH) does not exist) endif - ifneq ($$(COMPARE_BUILD_PATCH), ) - ifneq ($$(wildcard $$(topdir)/$$(COMPARE_BUILD_PATCH)), ) - # Assume relative path, if file exists - COMPARE_BUILD_PATCH := $$(wildcard $$(topdir)/$$(COMPARE_BUILD_PATCH)) - else ifeq ($$(wildcard $$(COMPARE_BUILD_PATCH)), ) - $$(error Patch file $$(COMPARE_BUILD_PATCH) does not exist) - endif - ifneq ($$(COMPARE_BUILD_NODRYRUN), true) - PATCH_DRY_RUN := $$(shell cd $$(topdir) && $$(PATCH) --dry-run -p1 < $$(COMPARE_BUILD_PATCH) > /dev/null 2>&1 || $$(ECHO) FAILED) - ifeq ($$(PATCH_DRY_RUN), FAILED) - $$(error Patch file $$(COMPARE_BUILD_PATCH) does not apply cleanly) - endif + ifneq ($$(COMPARE_BUILD_NODRYRUN), true) + PATCH_DRY_RUN := $$(shell cd $$(topdir) && $$(PATCH) --dry-run -p1 < $$(COMPARE_BUILD_PATCH) > /dev/null 2>&1 || $$(ECHO) FAILED) + ifeq ($$(PATCH_DRY_RUN), FAILED) + $$(error Patch file $$(COMPARE_BUILD_PATCH) does not apply cleanly) endif endif - ifneq ($$(COMPARE_BUILD_FAIL), true) - COMPARE_BUILD_IGNORE_RESULT := || true - endif endif - endef + ifneq ($$(COMPARE_BUILD_FAIL), true) + COMPARE_BUILD_IGNORE_RESULT := || true + endif + endif +endef - # Prepare for a comparison rebuild - define PrepareCompareBuild +# Prepare for a comparison rebuild +define PrepareCompareBuild $(ECHO) "Preparing for comparison rebuild" # Apply patch, if any $(if $(COMPARE_BUILD_PATCH), cd $(topdir) && $(PATCH) -p1 < $(COMPARE_BUILD_PATCH)) @@ -430,10 +144,10 @@ else # $(HAS_SPEC)=true # must be done after patching. ( cd $(CONFIGURE_START_DIR) && PATH="$(ORIGINAL_PATH)" \ $(BASH) $(topdir)/configure $(CONFIGURE_COMMAND_LINE) $(COMPARE_BUILD_CONF)) - endef +endef - # Cleanup after a compare build - define CleanupCompareBuild +# Cleanup after a compare build +define CleanupCompareBuild # If running with a COMPARE_BUILD patch, reverse-apply it, but continue # even if that fails (can happen with removed files). $(if $(COMPARE_BUILD_PATCH), cd $(topdir) && $(PATCH) -R -p1 < $(COMPARE_BUILD_PATCH) || true) @@ -442,10 +156,10 @@ else # $(HAS_SPEC)=true $(MV) $(OUTPUTDIR) $(COMPARE_BUILD_OUTPUTDIR) $(MV) $(topdir)/build/.compare-build-temp/$(CONF_NAME) $(OUTPUTDIR) $(RM) -r $(topdir)/build/.compare-build-temp - endef +endef - # Do the actual comparison of two builds - define CompareBuildDoComparison +# Do the actual comparison of two builds +define CompareBuildDoComparison # Compare first and second build. Ignore any error code from compare.sh. $(ECHO) "Comparing between comparison rebuild (this/new) and baseline (other/old)" $(if $(COMPARE_BUILD_COMP_DIR), \ @@ -455,9 +169,9 @@ else # $(HAS_SPEC)=true +(cd $(COMPARE_BUILD_OUTPUTDIR) && ./compare.sh --diffs $(COMPARE_BUILD_COMP_OPTS) \ -o $(OUTPUTDIR) $(COMPARE_BUILD_IGNORE_RESULT)) \ ) - endef +endef - define PrintFailureReports +define PrintFailureReports $(if $(filter none, $(LOG_REPORT)), , \ $(RM) $(MAKESUPPORT_OUTPUTDIR)/failure-summary.log ; \ $(if $(wildcard $(MAKESUPPORT_OUTPUTDIR)/failure-logs/*.log), \ @@ -479,9 +193,9 @@ else # $(HAS_SPEC)=true ) >> $(MAKESUPPORT_OUTPUTDIR)/failure-summary.log \ ) \ ) - endef +endef - define PrintBuildLogFailures +define PrintBuildLogFailures $(if $(filter none, $(LOG_REPORT)), , \ if $(GREP) -q "recipe for target .* failed" $(BUILD_LOG) 2> /dev/null; then \ $(PRINTF) "\n=== Make failed targets repeated here ===\n" ; \ @@ -494,96 +208,96 @@ else # $(HAS_SPEC)=true fi >> $(MAKESUPPORT_OUTPUTDIR)/failure-summary.log ; \ $(CAT) $(MAKESUPPORT_OUTPUTDIR)/failure-summary.log \ ) - endef +endef - define RotateLogFiles +define RotateLogFiles $(RM) $(BUILD_LOG).old 2> /dev/null && \ $(MV) $(BUILD_LOG) $(BUILD_LOG).old 2> /dev/null || true $(if $(findstring true, $(LOG_PROFILE_TIMES_FILE)), \ $(RM) $(BUILD_PROFILE_LOG).old 2> /dev/null && \ $(MV) $(BUILD_PROFILE_LOG) $(BUILD_PROFILE_LOG).old 2> /dev/null || true \ ) - endef +endef - # Failure logs are only supported for "parallel" main targets, not the - # (trivial) sequential make targets (such as clean and reconfigure), - # since the failure-logs directory creation will conflict with clean. - # We also make sure the javatmp directory exists, which is needed if a java - # process (like javac) is using java.io.tmpdir. - define PrepareFailureLogs +# Failure logs are only supported for "parallel" main targets, not the +# (trivial) sequential make targets (such as clean and reconfigure), +# since the failure-logs directory creation will conflict with clean. +# We also make sure the javatmp directory exists, which is needed if a java +# process (like javac) is using java.io.tmpdir. +define PrepareFailureLogs $(RM) -r $(MAKESUPPORT_OUTPUTDIR)/failure-logs 2> /dev/null && \ $(MKDIR) -p $(MAKESUPPORT_OUTPUTDIR)/failure-logs $(MKDIR) -p $(JAVA_TMP_DIR) $(RM) $(MAKESUPPORT_OUTPUTDIR)/exit-with-error 2> /dev/null - endef +endef - # Remove any javac server logs and port files. This - # prevents a new make run to reuse the previous servers. - define PrepareJavacServer +# Remove any javac server logs and port files. This +# prevents a new make run to reuse the previous servers. +define PrepareJavacServer $(if $(JAVAC_SERVER_DIR), \ $(RM) -r $(JAVAC_SERVER_DIR) 2> /dev/null && \ $(MKDIR) -p $(JAVAC_SERVER_DIR) \ ) - endef +endef - define CleanupJavacServer +define CleanupJavacServer [ -f $(JAVAC_SERVER_DIR)/server.port ] && $(ECHO) Stopping javac server && \ $(TOUCH) $(JAVAC_SERVER_DIR)/server.port.stop; true - endef +endef - ifeq ($(call isBuildOs, windows), true) - # On windows we need to synchronize with the javac server to be able to - # move or remove the build output directory. Since we have no proper - # synchronization process, wait for a while and hope it helps. This is only - # used by build comparisons. +ifeq ($(call isBuildOs, windows), true) + # On windows we need to synchronize with the javac server to be able to + # move or remove the build output directory. Since we have no proper + # synchronization process, wait for a while and hope it helps. This is only + # used by build comparisons. define WaitForJavacServerFinish $(if $(JAVAC_SERVER_DIR), \ sleep 5 \ ) - endef - else - define WaitForJavacServerFinish - endef - endif + endef +else + define WaitForJavacServerFinish + endef +endif - ############################################################################## - # Functions for timers - ############################################################################## +############################################################################## +# Functions for timers +############################################################################## - # Store the build times in this directory. - BUILDTIMESDIR = $(OUTPUTDIR)/make-support/build-times +# Store the build times in this directory. +BUILDTIMESDIR = $(OUTPUTDIR)/make-support/build-times - # Record starting time for build of a sub repository. - define RecordStartTime +# Record starting time for build of a sub repository. +define RecordStartTime $(DATE) '+%Y %m %d %H %M %S' | $(AWK) '{ 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 +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 +# 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' | $(AWK) '{ 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 | \ $(AWK) '{ 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 +endef - define StartGlobalTimer +define StartGlobalTimer $(RM) -r $(BUILDTIMESDIR) 2> /dev/null && \ $(MKDIR) -p $(BUILDTIMESDIR) && \ $(call RecordStartTime,TOTAL) - endef +endef - define StopGlobalTimer +define StopGlobalTimer $(call RecordEndTime,TOTAL) - endef +endef - # Find all build_time_* files and print their contents in a list sorted - # on the name of the sub repository. - define ReportBuildTimes +# Find all build_time_* files and print their contents in a list sorted +# on the name of the sub repository. +define ReportBuildTimes $(PRINTF) $(LOG_INFO) -- \ "----- Build times -------\nStart %s\nEnd %s\n%s\n%s\n-------------------------\n" \ "`$(CAT) $(BUILDTIMESDIR)/build_time_start_TOTAL_human_readable`" \ @@ -592,119 +306,15 @@ else # $(HAS_SPEC)=true $(XARGS) $(CAT) | $(SORT) -k 2`" \ "`$(CAT) $(BUILDTIMESDIR)/build_time_diff_TOTAL`" \ $(BUILD_LOG_PIPE_SIMPLE) - endef - - define ReportProfileTimes - $(if $(findstring true, $(LOG_PROFILE_TIMES_LOG)), \ - [ ! -f $(BUILD_PROFILE_LOG) ] || \ - { $(ECHO) Begin $(notdir $(BUILD_PROFILE_LOG)) && \ - $(CAT) $(BUILD_PROFILE_LOG) && \ - $(ECHO) End $(notdir $(BUILD_PROFILE_LOG)); \ - } \ - $(BUILD_LOG_PIPE_SIMPLE) - ) - endef - -endif # HAS_SPEC - -# Look for a given option in the LOG variable, and if found, set a variable -# and remove the option from the LOG variable -# $1: The option to look for -# $2: The variable to set to "true" if the option is found -define ParseLogOption - ifneq ($$(findstring $1, $$(LOG)), ) - override $2 := true - # First try to remove ",