2
# Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved.
3
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5
# This code is free software; you can redistribute it and/or modify it
6
# under the terms of the GNU General Public License version 2 only, as
7
# published by the Free Software Foundation. Oracle designates this
8
# particular file as subject to the "Classpath" exception as provided
9
# by Oracle in the LICENSE file that accompanied this code.
11
# This code is distributed in the hope that it will be useful, but WITHOUT
12
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
# version 2 for more details (a copy is included in the LICENSE file that
15
# accompanied this code).
17
# You should have received a copy of the GNU General Public License version
18
# 2 along with this work; if not, write to the Free Software Foundation,
19
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
21
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22
# or visit www.oracle.com if you need additional information or have any
26
################################################################################
27
# This file contains helper functions for Init.gmk.
28
# It is divided in two parts, depending on if a SPEC is present or not
29
# (HAS_SPEC is true or not).
30
################################################################################
32
ifndef _INITSUPPORT_GMK
37
# COMMA is defined in spec.gmk, but that is not included yet
40
# Include the corresponding closed file, if present.
41
ifneq ($(CUSTOM_MAKE_DIR), )
42
-include $(CUSTOM_MAKE_DIR)/InitSupport.gmk
45
##############################################################################
46
# Helper functions for the initial part of Init.gmk, before the spec file is
47
# loaded. Most of these functions provide parsing and setting up make options
48
# from the command-line.
49
##############################################################################
51
# Make control variables, handled by Init.gmk
52
INIT_CONTROL_VARIABLES += LOG CONF CONF_NAME SPEC JOBS TEST_JOBS CONF_CHECK \
53
COMPARE_BUILD JTREG GTEST MICRO TEST_OPTS TEST_VM_OPTS
55
# All known make control variables
56
MAKE_CONTROL_VARIABLES := $(INIT_CONTROL_VARIABLES) TEST JDK_FILTER SPEC_FILTER
58
# Define a simple reverse function.
59
# Should maybe move to MakeBase.gmk, but we can't include that file now.
61
$(if $(strip $(1)), $(call reverse, $(wordlist 2, $(words $(1)), $(1)))) \
64
# The variable MAKEOVERRIDES contains variable assignments from the command
65
# line, but in reverse order to what the user entered.
66
# The '§' <=> '\ 'dance is needed to keep values with space in them connected.
67
COMMAND_LINE_VARIABLES := $(subst §,\ , $(call reverse, $(subst \ ,§,$(MAKEOVERRIDES))))
69
# A list like FOO="val1" BAR="val2" containing all user-supplied make
70
# variables that we should propagate.
71
# The '§' <=> '\ 'dance is needed to keep values with space in them connected.
72
USER_MAKE_VARS := $(subst §,\ , $(filter-out $(addsuffix =%, $(INIT_CONTROL_VARIABLES)), \
73
$(subst \ ,§,$(MAKEOVERRIDES))))
75
# Setup information about available configurations, if any.
76
ifneq ($(CUSTOM_ROOT), )
77
build_dir=$(CUSTOM_ROOT)/build
79
build_dir=$(topdir)/build
81
all_spec_files=$(wildcard $(build_dir)/*/spec.gmk)
82
# Extract the configuration names from the path
83
all_confs=$(patsubst %/spec.gmk, %, $(patsubst $(build_dir)/%, %, $(all_spec_files)))
85
# Check for unknown command-line variables
86
define CheckControlVariables
87
command_line_variables := $$(strip $$(foreach var, \
88
$$(subst \ ,_,$$(MAKEOVERRIDES)), \
89
$$(firstword $$(subst =, , $$(var)))))
90
unknown_command_line_variables := $$(strip \
91
$$(filter-out $$(MAKE_CONTROL_VARIABLES), $$(command_line_variables)))
92
ifneq ($$(unknown_command_line_variables), )
93
$$(info Note: Command line contains non-control variables:)
94
$$(foreach var, $$(unknown_command_line_variables), $$(info * $$(var)=$$($$(var))))
95
$$(info Make sure it is not mistyped, and that you intend to override this variable.)
96
$$(info 'make help' will list known control variables.)
101
# Check for deprecated ALT_ variables
102
define CheckDeprecatedEnvironment
103
defined_alt_variables := $$(filter ALT_%, $$(.VARIABLES))
104
ifneq ($$(defined_alt_variables), )
105
$$(info Warning: You have the following ALT_ variables set:)
106
$$(foreach var, $$(defined_alt_variables), $$(info * $$(var)=$$($$(var))))
107
$$(info ALT_ variables are deprecated, and may result in a failed build.)
108
$$(info Please clean your environment.)
113
# Check for invalid make flags like -j
114
define CheckInvalidMakeFlags
115
# This is a trick to get this rule to execute before any other rules
116
# MAKEFLAGS only indicate -j if read in a recipe (!)
117
$$(topdir)/make/Init.gmk: .FORCE
118
$$(if $$(findstring --jobserver, $$(MAKEFLAGS)), \
119
$$(info Error: 'make -jN' is not supported, use 'make JOBS=N') \
120
$$(error Cannot continue) \
126
# Check that the CONF_CHECK option is valid and set up handling
127
define ParseConfCheckOption
128
ifeq ($$(CONF_CHECK), )
129
# Default behavior is fail
131
else ifneq ($$(filter-out auto fail ignore, $$(CONF_CHECK)),)
132
$$(info Error: CONF_CHECK must be one of: auto, fail or ignore.)
133
$$(error Cannot continue)
137
define ParseConfAndSpec
138
ifneq ($$(origin SPEC), undefined)
139
# We have been given a SPEC, check that it works out properly
140
ifneq ($$(origin CONF), undefined)
141
# We also have a CONF argument. We can't have both.
142
$$(info Error: Cannot use CONF=$$(CONF) and SPEC=$$(SPEC) at the same time. Choose one.)
143
$$(error Cannot continue)
145
ifneq ($$(origin CONF_NAME), undefined)
146
# We also have a CONF_NAME argument. We can't have both.
147
$$(info Error: Cannot use CONF_NAME=$$(CONF_NAME) and SPEC=$$(SPEC) at the same time. Choose one.)
148
$$(error Cannot continue)
150
ifeq ($$(wildcard $$(SPEC)),)
151
$$(info Error: Cannot locate spec.gmk, given by SPEC=$$(SPEC).)
152
$$(error Cannot continue)
154
ifeq ($$(filter /%, $$(SPEC)),)
155
# If given with relative path, make it absolute
156
SPECS := $$(CURDIR)/$$(strip $$(SPEC))
161
# For now, unset this SPEC variable.
164
# Use spec.gmk files in the build output directory
165
ifeq ($$(all_spec_files),)
166
ifneq ($(CUSTOM_ROOT), )
167
$$(info Error: No configurations found for $$(CUSTOM_ROOT).)
169
$$(info Error: No configurations found for $$(topdir).)
171
$$(info Please run 'bash configure' to create a configuration.)
173
$$(error Cannot continue)
176
ifneq ($$(origin CONF_NAME), undefined)
177
ifneq ($$(origin CONF), undefined)
178
# We also have a CONF argument. We can't have both.
179
$$(info Error: Cannot use CONF=$$(CONF) and CONF_NAME=$$(CONF_NAME) at the same time. Choose one.)
180
$$(error Cannot continue)
182
matching_conf := $$(strip $$(filter $$(CONF_NAME), $$(all_confs)))
183
ifeq ($$(matching_conf),)
184
$$(info Error: No configurations found matching CONF_NAME=$$(CONF_NAME).)
185
$$(info Available configurations in $$(build_dir):)
186
$$(foreach var, $$(all_confs), $$(info * $$(var)))
187
$$(error Cannot continue)
188
else ifneq ($$(words $$(matching_conf)), 1)
189
$$(info Error: Matching more than one configuration CONF_NAME=$$(CONF_NAME).)
190
$$(info Available configurations in $$(build_dir):)
191
$$(foreach var, $$(all_confs), $$(info * $$(var)))
192
$$(error Cannot continue)
194
$$(info Building configuration '$$(matching_conf)' (matching CONF_NAME=$$(CONF_NAME)))
196
# Create a SPEC definition. This will contain the path to exactly one spec file.
197
SPECS := $$(build_dir)/$$(matching_conf)/spec.gmk
198
else ifneq ($$(origin CONF), undefined)
199
# User have given a CONF= argument.
201
# If given CONF=, match all configurations
202
matching_confs := $$(strip $$(all_confs))
204
# Otherwise select those that contain the given CONF string
205
ifeq ($$(patsubst !%,,$$(CONF)),)
206
# A CONF starting with ! means we should negate the search term
207
matching_confs := $$(strip $$(foreach var, $$(all_confs), \
208
$$(if $$(findstring $$(subst !,,$$(CONF)), $$(var)), ,$$(var))))
210
matching_confs := $$(strip $$(foreach var, $$(all_confs), \
211
$$(if $$(findstring $$(CONF), $$(var)), $$(var))))
213
ifneq ($$(filter $$(CONF), $$(matching_confs)), )
214
# If we found an exact match, use that
215
matching_confs := $$(CONF)
216
# Don't repeat this output on make restarts caused by including
218
ifeq ($$(MAKE_RESTARTS),)
219
$$(info Using exact match for CONF=$$(CONF) (other matches are possible))
223
ifeq ($$(matching_confs),)
224
$$(info Error: No configurations found matching CONF=$$(CONF).)
225
$$(info Available configurations in $$(build_dir):)
226
$$(foreach var, $$(all_confs), $$(info * $$(var)))
227
$$(error Cannot continue)
229
# Don't repeat this output on make restarts caused by including
231
ifeq ($$(MAKE_RESTARTS),)
232
ifeq ($$(words $$(matching_confs)), 1)
233
ifneq ($$(findstring $$(LOG_LEVEL), info debug trace),)
234
$$(info Building configuration '$$(matching_confs)' (matching CONF=$$(CONF)))
237
$$(info Building these configurations (matching CONF=$$(CONF)):)
238
$$(foreach var, $$(matching_confs), $$(info * $$(var)))
243
# Create a SPEC definition. This will contain the path to one or more spec.gmk files.
244
SPECS := $$(addsuffix /spec.gmk, $$(addprefix $$(build_dir)/, $$(matching_confs)))
246
# No CONF or SPEC given, check the available configurations
247
ifneq ($$(words $$(all_spec_files)), 1)
248
$$(info Error: No CONF given, but more than one configuration found.)
249
$$(info Available configurations in $$(build_dir):)
250
$$(foreach var, $$(all_confs), $$(info * $$(var)))
251
$$(info Please retry building with CONF=<config pattern> (or SPEC=<spec file>).)
253
$$(error Cannot continue)
256
# We found exactly one configuration, use it
257
SPECS := $$(strip $$(all_spec_files))
262
# Extract main targets from Main.gmk using the spec provided in $2.
264
# Param 1: FORCE = force generation of main-targets.gmk or LAZY = do not force.
265
# Param 2: The SPEC file to use.
266
define DefineMainTargets
268
# We will start by making sure the main-targets.gmk file is removed, if
269
# make has not been restarted. By the -include, we will trigger the
270
# rule for generating the file (which is never there since we removed it),
271
# thus generating it fresh, and make will restart, incrementing the restart
273
main_targets_file := $$(dir $(strip $2))make-support/main-targets.gmk
275
ifeq ($$(MAKE_RESTARTS),)
276
# Only do this if make has not been restarted, and if we do not force it.
277
ifeq ($(strip $1), FORCE)
278
$$(shell rm -f $$(main_targets_file))
282
$$(main_targets_file):
283
@( cd $$(topdir) && \
284
$$(MAKE) $$(MAKE_LOG_FLAGS) -r -R -f $$(topdir)/make/Main.gmk \
285
-I $$(topdir)/make/common SPEC=$(strip $2) NO_RECIPES=true \
287
create-main-targets-include )
289
# Now include main-targets.gmk. This will define ALL_MAIN_TARGETS.
290
-include $$(main_targets_file)
293
define PrintConfCheckFailed
295
@echo "Please rerun configure! Easiest way to do this is by running"
296
@echo "'make reconfigure'."
297
@echo "This behavior may also be changed using CONF_CHECK=<ignore|auto>."
301
else # $(HAS_SPEC)=true
302
##############################################################################
303
# Helper functions for the 'main' target. These functions assume a single,
304
# proper and existing SPEC is included.
305
##############################################################################
307
include $(TOPDIR)/make/common/MakeBase.gmk
309
# Define basic logging setup
310
BUILD_LOG := $(OUTPUTDIR)/build.log
311
BUILD_PROFILE_LOG := $(OUTPUTDIR)/build-profile.log
313
BUILD_LOG_PIPE := > >($(TEE) -a $(BUILD_LOG)) 2> >($(TEE) -a $(BUILD_LOG) >&2) && wait
314
# Use this for simple echo/printf commands that are never expected to print
316
BUILD_LOG_PIPE_SIMPLE := | $(TEE) -a $(BUILD_LOG)
318
ifneq ($(CUSTOM_ROOT), )
319
topdir=$(CUSTOM_ROOT)
324
# Setup the build environment to match the requested specification on
325
# level of reproducible builds
326
define SetupReproducibleBuild
327
ifeq ($$(SOURCE_DATE), updated)
328
# For static values of SOURCE_DATE (not "updated"), these are set in spec.gmk
329
export SOURCE_DATE_EPOCH := $$(shell $$(DATE) +"%s")
330
export SOURCE_DATE_ISO_8601 := $$(call EpochToISO8601, $$(SOURCE_DATE_EPOCH))
334
# Parse COMPARE_BUILD into COMPARE_BUILD_*
335
# Syntax: COMPARE_BUILD=CONF=<configure options>:PATCH=<patch file>:
336
# MAKE=<make targets>:COMP_OPTS=<compare script options>:
337
# COMP_DIR=<compare script base dir>|<default>:
339
# If neither CONF or PATCH is given, assume <default> means CONF if it
340
# begins with "--", otherwise assume it means PATCH.
341
# MAKE and COMP_OPTS can only be used with CONF and/or PATCH specified.
342
# If any value contains "+", it will be replaced by space.
343
# FAIL can be set to false to have the return value of compare be ignored.
344
define ParseCompareBuild
345
ifneq ($$(COMPARE_BUILD), )
346
COMPARE_BUILD_OUTPUTDIR := $(topdir)/build/compare-build/$(CONF_NAME)
347
COMPARE_BUILD_FAIL := true
349
ifneq ($$(findstring :, $$(COMPARE_BUILD)), )
350
$$(foreach part, $$(subst :, , $$(COMPARE_BUILD)), \
351
$$(if $$(filter PATCH=%, $$(part)), \
352
$$(eval COMPARE_BUILD_PATCH=$$(strip $$(patsubst PATCH=%, %, $$(part)))) \
354
$$(if $$(filter CONF=%, $$(part)), \
355
$$(eval COMPARE_BUILD_CONF=$$(strip $$(subst +, , $$(patsubst CONF=%, %, $$(part))))) \
357
$$(if $$(filter MAKE=%, $$(part)), \
358
$$(eval COMPARE_BUILD_MAKE=$$(strip $$(subst +, , $$(patsubst MAKE=%, %, $$(part))))) \
360
$$(if $$(filter COMP_OPTS=%, $$(part)), \
361
$$(eval COMPARE_BUILD_COMP_OPTS=$$(strip $$(subst +, , $$(patsubst COMP_OPTS=%, %, $$(part))))) \
363
$$(if $$(filter COMP_DIR=%, $$(part)), \
364
$$(eval COMPARE_BUILD_COMP_DIR=$$(strip $$(subst +, , $$(patsubst COMP_DIR=%, %, $$(part))))) \
366
$$(if $$(filter FAIL=%, $$(part)), \
367
$$(eval COMPARE_BUILD_FAIL=$$(strip $$(subst +, , $$(patsubst FAIL=%, %, $$(part))))) \
369
$$(if $$(filter NODRYRUN=%, $$(part)), \
370
$$(eval COMPARE_BUILD_NODRYRUN=$$(strip $$(subst +, , $$(patsubst NODRYRUN=%, %, $$(part))))) \
374
# Separate handling for single field case, to allow for spaces in values.
375
ifneq ($$(filter PATCH=%, $$(COMPARE_BUILD)), )
376
COMPARE_BUILD_PATCH=$$(strip $$(patsubst PATCH=%, %, $$(COMPARE_BUILD)))
377
else ifneq ($$(filter CONF=%, $$(COMPARE_BUILD)), )
378
COMPARE_BUILD_CONF=$$(strip $$(subst +, , $$(patsubst CONF=%, %, $$(COMPARE_BUILD))))
379
else ifneq ($$(filter --%, $$(COMPARE_BUILD)), )
380
# Assume CONF if value begins with --
381
COMPARE_BUILD_CONF=$$(strip $$(subst +, , $$(COMPARE_BUILD)))
383
# Otherwise assume patch file
384
COMPARE_BUILD_PATCH=$$(strip $$(COMPARE_BUILD))
387
ifneq ($$(COMPARE_BUILD_PATCH), )
388
ifneq ($$(wildcard $$(topdir)/$$(COMPARE_BUILD_PATCH)), )
389
# Assume relative path, if file exists
390
COMPARE_BUILD_PATCH := $$(wildcard $$(topdir)/$$(COMPARE_BUILD_PATCH))
391
else ifeq ($$(wildcard $$(COMPARE_BUILD_PATCH)), )
392
$$(error Patch file $$(COMPARE_BUILD_PATCH) does not exist)
394
ifneq ($$(COMPARE_BUILD_NODRYRUN), true)
395
PATCH_DRY_RUN := $$(shell cd $$(topdir) && $$(PATCH) --dry-run -p1 < $$(COMPARE_BUILD_PATCH) > /dev/null 2>&1 || $$(ECHO) FAILED)
396
ifeq ($$(PATCH_DRY_RUN), FAILED)
397
$$(error Patch file $$(COMPARE_BUILD_PATCH) does not apply cleanly)
401
ifneq ($$(COMPARE_BUILD_FAIL), true)
402
COMPARE_BUILD_IGNORE_RESULT := || true
407
# Prepare for a comparison rebuild
408
define PrepareCompareBuild
409
$(ECHO) "Preparing for comparison rebuild"
410
# Apply patch, if any
411
$(if $(COMPARE_BUILD_PATCH), cd $(topdir) && $(PATCH) -p1 < $(COMPARE_BUILD_PATCH))
412
# Move the first build away temporarily
413
$(RM) -r $(topdir)/build/.compare-build-temp
414
$(MKDIR) -p $(topdir)/build/.compare-build-temp
415
$(MV) $(OUTPUTDIR) $(topdir)/build/.compare-build-temp
416
# Restore an old compare-build, or create a new compare-build directory.
417
if test -d $(COMPARE_BUILD_OUTPUTDIR); then \
418
$(MV) $(COMPARE_BUILD_OUTPUTDIR) $(OUTPUTDIR); \
420
$(MKDIR) -p $(OUTPUTDIR); \
422
# Re-run configure with the same arguments (and possibly some additional),
423
# must be done after patching.
424
( cd $(CONFIGURE_START_DIR) && PATH="$(ORIGINAL_PATH)" \
425
$(BASH) $(topdir)/configure $(CONFIGURE_COMMAND_LINE) $(COMPARE_BUILD_CONF))
428
# Cleanup after a compare build
429
define CleanupCompareBuild
430
# If running with a COMPARE_BUILD patch, reverse-apply it, but continue
431
# even if that fails (can happen with removed files).
432
$(if $(COMPARE_BUILD_PATCH), cd $(topdir) && $(PATCH) -R -p1 < $(COMPARE_BUILD_PATCH) || true)
433
# Move this build away and restore the original build
434
$(MKDIR) -p $(topdir)/build/compare-build
435
$(MV) $(OUTPUTDIR) $(COMPARE_BUILD_OUTPUTDIR)
436
$(MV) $(topdir)/build/.compare-build-temp/$(CONF_NAME) $(OUTPUTDIR)
437
$(RM) -r $(topdir)/build/.compare-build-temp
440
# Do the actual comparison of two builds
441
define CompareBuildDoComparison
442
# Compare first and second build. Ignore any error code from compare.sh.
443
$(ECHO) "Comparing between comparison rebuild (this/new) and baseline (other/old)"
444
$(if $(COMPARE_BUILD_COMP_DIR), \
445
+(cd $(COMPARE_BUILD_OUTPUTDIR) && ./compare.sh --diffs $(COMPARE_BUILD_COMP_OPTS) \
446
-2dirs $(COMPARE_BUILD_OUTPUTDIR)/$(COMPARE_BUILD_COMP_DIR) \
447
$(OUTPUTDIR)/$(COMPARE_BUILD_COMP_DIR) $(COMPARE_BUILD_IGNORE_RESULT)), \
448
+(cd $(COMPARE_BUILD_OUTPUTDIR) && ./compare.sh --diffs $(COMPARE_BUILD_COMP_OPTS) \
449
-o $(OUTPUTDIR) $(COMPARE_BUILD_IGNORE_RESULT)) \
453
define PrintFailureReports
454
$(if $(filter none, $(LOG_REPORT)), , \
455
$(RM) $(MAKESUPPORT_OUTPUTDIR)/failure-summary.log ; \
456
$(if $(wildcard $(MAKESUPPORT_OUTPUTDIR)/failure-logs/*.log), \
458
$(PRINTF) "\n=== Output from failing command(s) repeated here ===\n" ; \
459
$(foreach logfile, $(sort $(wildcard $(MAKESUPPORT_OUTPUTDIR)/failure-logs/*.log)), \
460
$(PRINTF) "* For target $(notdir $(basename $(logfile))):\n" ; \
461
$(if $(filter all, $(LOG_REPORT)), \
462
$(GREP) -v -e "^Note: including file:" < $(logfile) || true ; \
464
($(GREP) -v -e "^Note: including file:" < $(logfile) || true) | $(HEAD) -n 15 ; \
465
if test `$(WC) -l < $(logfile)` -gt 15; then \
466
$(ECHO) " ... (rest of output omitted)" ; \
470
$(PRINTF) "\n* All command lines available in $(MAKESUPPORT_OUTPUTDIR)/failure-logs.\n" ; \
471
$(PRINTF) "=== End of repeated output ===\n" ; \
472
) >> $(MAKESUPPORT_OUTPUTDIR)/failure-summary.log \
477
define PrintBuildLogFailures
478
$(if $(filter none, $(LOG_REPORT)), , \
479
if $(GREP) -q "recipe for target .* failed" $(BUILD_LOG) 2> /dev/null; then \
480
$(PRINTF) "\n=== Make failed targets repeated here ===\n" ; \
481
$(GREP) "recipe for target .* failed" $(BUILD_LOG) ; \
482
$(PRINTF) "=== End of repeated output ===\n" ; \
483
$(PRINTF) "\nHELP: Try searching the build log for the name of the first failed target.\n" ; \
485
$(PRINTF) "\nNo indication of failed target found.\n" ; \
486
$(PRINTF) "HELP: Try searching the build log for '] Error'.\n" ; \
487
fi >> $(MAKESUPPORT_OUTPUTDIR)/failure-summary.log ; \
488
$(CAT) $(MAKESUPPORT_OUTPUTDIR)/failure-summary.log \
492
define RotateLogFiles
493
$(RM) $(BUILD_LOG).old 2> /dev/null && \
494
$(MV) $(BUILD_LOG) $(BUILD_LOG).old 2> /dev/null || true
495
$(if $(findstring true, $(LOG_PROFILE_TIMES_FILE)), \
496
$(RM) $(BUILD_PROFILE_LOG).old 2> /dev/null && \
497
$(MV) $(BUILD_PROFILE_LOG) $(BUILD_PROFILE_LOG).old 2> /dev/null || true \
501
# Failure logs are only supported for "parallel" main targets, not the
502
# (trivial) sequential make targets (such as clean and reconfigure),
503
# since the failure-logs directory creation will conflict with clean.
504
# We also make sure the javatmp directory exists, which is needed if a java
505
# process (like javac) is using java.io.tmpdir.
506
define PrepareFailureLogs
507
$(RM) -r $(MAKESUPPORT_OUTPUTDIR)/failure-logs 2> /dev/null && \
508
$(MKDIR) -p $(MAKESUPPORT_OUTPUTDIR)/failure-logs
509
$(MKDIR) -p $(JAVA_TMP_DIR)
510
$(RM) $(MAKESUPPORT_OUTPUTDIR)/exit-with-error 2> /dev/null
513
# Remove any javac server logs and port files. This
514
# prevents a new make run to reuse the previous servers.
515
define PrepareJavacServer
516
$(if $(JAVAC_SERVER_DIR), \
517
$(RM) -r $(JAVAC_SERVER_DIR) 2> /dev/null && \
518
$(MKDIR) -p $(JAVAC_SERVER_DIR) \
522
define CleanupJavacServer
523
[ -f $(JAVAC_SERVER_DIR)/server.port ] && $(ECHO) Stopping javac server && \
524
$(TOUCH) $(JAVAC_SERVER_DIR)/server.port.stop; true
527
ifeq ($(call isBuildOs, windows), true)
528
# On windows we need to synchronize with the javac server to be able to
529
# move or remove the build output directory. Since we have no proper
530
# synchronization process, wait for a while and hope it helps. This is only
531
# used by build comparisons.
532
define WaitForJavacServerFinish
533
$(if $(JAVAC_SERVER_DIR), \
538
define WaitForJavacServerFinish
542
##############################################################################
543
# Functions for timers
544
##############################################################################
546
# Store the build times in this directory.
547
BUILDTIMESDIR=$(OUTPUTDIR)/make-support/build-times
549
# Record starting time for build of a sub repository.
550
define RecordStartTime
551
$(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) && \
552
$(DATE) '+%Y-%m-%d %H:%M:%S' > $(BUILDTIMESDIR)/build_time_start_$(strip $1)_human_readable
555
# Record ending time and calculate the difference and store it in a
556
# easy to read format. Handles builds that cross midnight. Expects
557
# that a build will never take 24 hours or more.
559
$(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)
560
$(DATE) '+%Y-%m-%d %H:%M:%S' > $(BUILDTIMESDIR)/build_time_end_$(strip $1)_human_readable
561
$(ECHO) `$(CAT) $(BUILDTIMESDIR)/build_time_start_$(strip $1)` `$(CAT) $(BUILDTIMESDIR)/build_time_end_$(strip $1)` $1 | \
562
$(AWK) '{ F=$$7; T=$$14; if (F > T) { T+=3600*24 }; D=T-F; H=int(D/3600); \
563
M=int((D-H*3600)/60); S=D-H*3600-M*60; printf("%02d:%02d:%02d %s\n",H,M,S,$$15); }' \
564
> $(BUILDTIMESDIR)/build_time_diff_$(strip $1)
567
define StartGlobalTimer
568
$(RM) -r $(BUILDTIMESDIR) 2> /dev/null && \
569
$(MKDIR) -p $(BUILDTIMESDIR) && \
570
$(call RecordStartTime,TOTAL)
573
define StopGlobalTimer
574
$(call RecordEndTime,TOTAL)
577
# Find all build_time_* files and print their contents in a list sorted
578
# on the name of the sub repository.
579
define ReportBuildTimes
580
$(PRINTF) $(LOG_INFO) -- \
581
"----- Build times -------\nStart %s\nEnd %s\n%s\n%s\n-------------------------\n" \
582
"`$(CAT) $(BUILDTIMESDIR)/build_time_start_TOTAL_human_readable`" \
583
"`$(CAT) $(BUILDTIMESDIR)/build_time_end_TOTAL_human_readable`" \
584
"`$(LS) $(BUILDTIMESDIR)/build_time_diff_* | $(GREP) -v _TOTAL | \
585
$(XARGS) $(CAT) | $(SORT) -k 2`" \
586
"`$(CAT) $(BUILDTIMESDIR)/build_time_diff_TOTAL`" \
587
$(BUILD_LOG_PIPE_SIMPLE)
590
define ReportProfileTimes
591
$(if $(findstring true, $(LOG_PROFILE_TIMES_LOG)), \
592
[ ! -f $(BUILD_PROFILE_LOG) ] || \
593
{ $(ECHO) Begin $(notdir $(BUILD_PROFILE_LOG)) && \
594
$(CAT) $(BUILD_PROFILE_LOG) && \
595
$(ECHO) End $(notdir $(BUILD_PROFILE_LOG)); \
597
$(BUILD_LOG_PIPE_SIMPLE)
603
# Look for a given option in the LOG variable, and if found, set a variable
604
# and remove the option from the LOG variable
605
# $1: The option to look for
606
# $2: The variable to set to "true" if the option is found
608
ifneq ($$(findstring $1, $$(LOG)),)
610
# First try to remove ",<option>" if it exists, otherwise just remove "<option>"
611
LOG_STRIPPED := $$(subst $1,, $$(subst $$(COMMA)$$(strip $1),, $$(LOG)))
612
# We might have ended up with a leading comma. Remove it. Need override
613
# since LOG is set from the command line.
614
override LOG := $$(strip $$(patsubst $$(COMMA)%, %, $$(LOG_STRIPPED)))
618
# Look for a given option with an assignment in the LOG variable, and if found,
619
# set a variable to that value and remove the option from the LOG variable
620
# $1: The option to look for
621
# $2: The variable to set to the value of the option, if found
623
ifneq ($$(findstring $1=, $$(LOG)),)
624
# Make words of out comma-separated list and find the one with opt=val
625
value := $$(strip $$(subst $$(strip $1)=,, $$(filter $$(strip $1)=%, $$(subst $$(COMMA), , $$(LOG)))))
626
override $2 := $$(value)
627
# First try to remove ",<option>" if it exists, otherwise just remove "<option>"
628
LOG_STRIPPED := $$(subst $$(strip $1)=$$(value),, \
629
$$(subst $$(COMMA)$$(strip $1)=$$(value),, $$(LOG)))
630
# We might have ended up with a leading comma. Remove it. Need override
631
# since LOG is set from the command line.
632
override LOG := $$(strip $$(patsubst $$(COMMA)%, %, $$(LOG_STRIPPED)))
638
# Catch old-style VERBOSE= command lines.
639
ifneq ($$(origin VERBOSE), undefined)
640
$$(info Error: VERBOSE is deprecated. Use LOG=<warn|info|debug|trace> instead.)
641
$$(error Cannot continue)
644
# Setup logging according to LOG
646
# If "nofile" is present, do not log to a file
647
$$(eval $$(call ParseLogOption, nofile, LOG_NOFILE))
649
# If "cmdline" is present, print all executes "important" command lines.
650
$$(eval $$(call ParseLogOption, cmdlines, LOG_CMDLINES))
652
# If "report" is present, use non-standard reporting options at build failure.
653
$$(eval $$(call ParseLogValue, report, LOG_REPORT))
654
ifneq ($$(LOG_REPORT), )
655
ifeq ($$(filter $$(LOG_REPORT), none all default), )
656
$$(info Error: LOG=report has invalid value: $$(LOG_REPORT).)
657
$$(info Valid values: LOG=report=<none>|<all>|<default>)
658
$$(error Cannot continue)
662
# If "profile-to-log" is present, write shell times in build log
663
$$(eval $$(call ParseLogOption, profile-to-log, LOG_PROFILE_TIMES_LOG))
665
# If "profile" is present, write shell times in separate log file
666
# IMPORTANT: $(ParseLogOption profile-to-log) should go first. Otherwise
667
# parsing of 'LOG=debug,profile-to-log,nofile' ends up in the following error:
668
# Error: LOG contains unknown option or log level: debug-to-log.
669
$$(eval $$(call ParseLogOption, profile, LOG_PROFILE_TIMES_FILE))
671
# Treat LOG=profile-to-log as if it were LOG=profile,profile-to-log
672
LOG_PROFILE_TIMES_FILE := $$(firstword $$(LOG_PROFILE_TIMES_FILE) $$(LOG_PROFILE_TIMES_LOG))
674
override LOG_LEVEL := $$(LOG)
676
ifeq ($$(LOG_LEVEL),)
677
# Set LOG to "warn" as default if not set
678
override LOG_LEVEL := warn
681
ifeq ($$(LOG_LEVEL), warn)
682
override MAKE_LOG_FLAGS := -s
683
else ifeq ($$(LOG_LEVEL), info)
684
override MAKE_LOG_FLAGS := -s
685
else ifeq ($$(LOG_LEVEL), debug)
686
override MAKE_LOG_FLAGS :=
687
else ifeq ($$(LOG_LEVEL), trace)
688
override MAKE_LOG_FLAGS :=
690
$$(info Error: LOG contains unknown option or log level: $$(LOG).)
691
$$(info LOG can be <level>[,<opt>[...]] where <opt> is nofile | cmdlines | profile | profile-to-log)
692
$$(info and <level> is warn | info | debug | trace)
693
$$(error Cannot continue)
697
MAKE_LOG_VARS = $(foreach v, \
698
LOG_LEVEL LOG_NOFILE LOG_CMDLINES LOG_REPORT LOG_PROFILE_TIMES_LOG \
699
LOG_PROFILE_TIMES_FILE, \
703
endif # _INITSUPPORT_GMK