From 5878e45ae07404bc18518e6a2cb551a7969fddd6 Mon Sep 17 00:00:00 2001 From: Magnus Ihse Bursie Date: Fri, 31 Jan 2025 13:48:09 +0000 Subject: [PATCH] 8348998: Split out PreInit.gmk from Init.gmk Reviewed-by: erikj --- Makefile | 11 +- make/Init.gmk | 312 ++++------------- make/InitSupport.gmk | 692 +++++++++----------------------------- make/PreInit.gmk | 215 ++++++++++++ make/PreInitSupport.gmk | 295 ++++++++++++++++ make/RunTestsPrebuilt.gmk | 5 +- make/common/LogUtils.gmk | 127 +++++++ 7 files changed, 864 insertions(+), 793 deletions(-) create mode 100644 make/PreInit.gmk create mode 100644 make/PreInitSupport.gmk create mode 100644 make/common/LogUtils.gmk diff --git a/Makefile b/Makefile index ebe52d5d7f2..b094e14efbd 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/make/Init.gmk b/make/Init.gmk index f2cfe3625a5..2e71319c9a8 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,68 @@ 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 +# Parse COMPARE_BUILD (for makefile development) +$(eval $(call ParseCompareBuild)) - # CALLED_TARGETS is the list of targets that the user provided, - # or "default" if unspecified. - CALLED_TARGETS := $(if $(MAKECMDGOALS), $(MAKECMDGOALS), default) +# Setup reproducible build environment +$(eval $(call SetupReproducibleBuild)) - # Extract non-global targets that require a spec file. - CALLED_SPEC_TARGETS := $(filter-out $(ALL_GLOBAL_TARGETS), $(CALLED_TARGETS)) - - # 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 +116,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 +156,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 +176,7 @@ else # HAS_SPEC=true $(call ReportProfileTimes) endif - on-failure: +on-failure: $(call CleanupJavacServer) $(call StopGlobalTimer) $(call ReportBuildTimes) @@ -365,15 +188,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 baee52a888e..a4b4f2ca964 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 +# Define basic logging setup +BUILD_LOG := $(OUTPUTDIR)/build.log +BUILD_PROFILE_LOG := $(OUTPUTDIR)/build-profile.log -ifeq ($(HAS_SPEC), ) +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) - # COMMA is defined in spec.gmk, but that is not included yet - COMMA := , +ifneq ($(CUSTOM_ROOT), ) + topdir = $(CUSTOM_ROOT) +else + topdir = $(TOPDIR) +endif - # Include the corresponding closed file, if present. - ifneq ($(CUSTOM_MAKE_DIR), ) - -include $(CUSTOM_MAKE_DIR)/InitSupport.gmk +# 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 - ############################################################################## - # 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. - ############################################################################## +# 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 - # 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 - 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 - - # For now, unset this SPEC variable. - override SPEC := + 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) + # Otherwise assume patch file + COMPARE_BUILD_PATCH = $$(strip $$(COMPARE_BUILD)) + endif + 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 - - # 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)) - endif + ifneq ($$(COMPARE_BUILD_FAIL), true) + COMPARE_BUILD_IGNORE_RESULT := || true 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 +endef - # 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 - 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 - endif - endif - 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 ",