1 # 2 # Copyright (c) 2011, 2020, Oracle and/or its affiliates. All rights reserved. 3 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 # 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. 10 # 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). 16 # 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. 20 # 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 23 # questions. 24 # 25 26 ################################################################ 27 # 28 # Setup common utility functions. 29 # 30 ################################################################ 31 32 ifndef _MAKEBASE_GMK 33 _MAKEBASE_GMK := 1 34 35 ifeq ($(wildcard $(SPEC)),) 36 $(error MakeBase.gmk needs SPEC set to a proper spec.gmk) 37 endif 38 39 # By defining this pseudo target, make will automatically remove targets 40 # if their recipe fails so that a rebuild is automatically triggered on the 41 # next make invocation. 42 .DELETE_ON_ERROR: 43 44 ################################################################################ 45 # Definitions for special characters 46 ################################################################################ 47 48 # When calling macros, the spaces between arguments are 49 # often semantically important! Sometimes we need to subst 50 # spaces and commas, therefore we need the following macros. 51 X:= 52 SPACE:=$(X) $(X) 53 COMMA:=, 54 DOLLAR:=$$ 55 HASH:=\# 56 LEFT_PAREN:=( 57 RIGHT_PAREN:=) 58 SQUOTE:=' 59 #' 60 DQUOTE:=" 61 #" 62 define NEWLINE 63 64 65 endef 66 67 # Certain features only work in newer version of GNU Make. The build will still 68 # function in 3.81, but will be less performant. 69 ifeq (4.0, $(firstword $(sort 4.0 $(MAKE_VERSION)))) 70 HAS_FILE_FUNCTION := true 71 CORRECT_FUNCTION_IN_RECIPE_EVALUATION := true 72 RWILDCARD_WORKS := true 73 endif 74 75 76 # For convenience, MakeBase.gmk continues to include these separate files, at 77 # least for now. 78 79 include $(TOPDIR)/make/common/Utils.gmk 80 include $(TOPDIR)/make/common/MakeIO.gmk 81 include $(TOPDIR)/make/common/CopyFiles.gmk 82 83 ################################################################################ 84 # Functions for timers 85 ################################################################################ 86 87 # Store the build times in this directory. 88 BUILDTIMESDIR=$(OUTPUTDIR)/make-support/build-times 89 90 # Record starting time for build of a sub repository. 91 define RecordStartTime 92 $(DATE) '+%Y %m %d %H %M %S' | $(NAWK) '{ print $$1,$$2,$$3,$$4,$$5,$$6,($$4*3600+$$5*60+$$6) }' > $(BUILDTIMESDIR)/build_time_start_$(strip $1) && \ 93 $(DATE) '+%Y-%m-%d %H:%M:%S' > $(BUILDTIMESDIR)/build_time_start_$(strip $1)_human_readable 94 endef 95 96 # Record ending time and calculate the difference and store it in a 97 # easy to read format. Handles builds that cross midnight. Expects 98 # that a build will never take 24 hours or more. 99 define RecordEndTime 100 $(DATE) '+%Y %m %d %H %M %S' | $(NAWK) '{ print $$1,$$2,$$3,$$4,$$5,$$6,($$4*3600+$$5*60+$$6) }' > $(BUILDTIMESDIR)/build_time_end_$(strip $1) 101 $(DATE) '+%Y-%m-%d %H:%M:%S' > $(BUILDTIMESDIR)/build_time_end_$(strip $1)_human_readable 102 $(ECHO) `$(CAT) $(BUILDTIMESDIR)/build_time_start_$(strip $1)` `$(CAT) $(BUILDTIMESDIR)/build_time_end_$(strip $1)` $1 | \ 103 $(NAWK) '{ F=$$7; T=$$14; if (F > T) { T+=3600*24 }; D=T-F; H=int(D/3600); \ 104 M=int((D-H*3600)/60); S=D-H*3600-M*60; printf("%02d:%02d:%02d %s\n",H,M,S,$$15); }' \ 105 > $(BUILDTIMESDIR)/build_time_diff_$(strip $1) 106 endef 107 108 # Hook to be called when starting to execute a top-level target 109 define TargetEnter 110 $(PRINTF) "## Starting $(patsubst %-only,%,$@)\n" 111 $(call RecordStartTime,$(patsubst %-only,%,$@)) 112 endef 113 114 # Hook to be called when finish executing a top-level target 115 define TargetExit 116 $(call RecordEndTime,$(patsubst %-only,%,$@)) 117 $(PRINTF) "## Finished $(patsubst %-only,%,$@) (build time %s)\n\n" \ 118 "`$(CAT) $(BUILDTIMESDIR)/build_time_diff_$(patsubst %-only,%,$@) | $(CUT) -f 1 -d ' '`" 119 endef 120 121 ################################################################################ 122 123 # A file containing a way to uniquely identify the source code revision that 124 # the build was created from 125 SOURCE_REVISION_TRACKER := $(SUPPORT_OUTPUTDIR)/src-rev/source-revision-tracker 126 127 # Locate all hg repositories included in the forest, as absolute paths 128 FindAllReposAbs = \ 129 $(strip $(sort $(dir $(filter-out $(TOPDIR)/build/%, $(wildcard \ 130 $(addprefix $(TOPDIR)/, .hg */.hg */*/.hg */*/*/.hg */*/*/*/.hg) \ 131 $(addprefix $(TOPDIR)/, .git */.git */*/.git */*/*/.git */*/*/*/.git) \ 132 ))))) 133 134 # Locate all hg repositories included in the forest, as relative paths 135 FindAllReposRel = \ 136 $(strip $(subst $(TOPDIR)/,.,$(patsubst $(TOPDIR)/%/, %, $(FindAllReposAbs)))) 137 138 ################################################################################ 139 140 define SetupLogging 141 ifeq ($$(LOG_PROFILE_TIMES_FILE), true) 142 ifeq ($$(IS_GNU_TIME), yes) 143 SHELL := $$(BASH) $$(TOPDIR)/make/scripts/shell-profiler.sh \ 144 gnutime $$(TIME) \ 145 $$(OUTPUTDIR)/build-profile.log $$(SHELL) 146 else ifneq ($$(FLOCK), ) 147 SHELL := $$(BASH) $$(TOPDIR)/make/scripts/shell-profiler.sh \ 148 flock $$(FLOCK) \ 149 $$(OUTPUTDIR)/build-profile.log $$(SHELL) 150 endif 151 endif 152 153 ifeq ($$(LOG_LEVEL), trace) 154 SHELL_NO_RECURSE := $$(SHELL) 155 # Shell redefinition trick inspired by http://www.cmcrossroads.com/ask-mr-make/6535-tracing-rule-execution-in-gnu-make 156 # For each target executed, will print 157 # Building <TARGET> (from <FIRST PREREQUISITE>) (<ALL NEWER PREREQUISITES> newer) 158 # but with a limit of 20 on <ALL NEWER PREREQUISITES>, to avoid cluttering logs too much 159 # (and causing a crash on Cygwin). 160 SHELL = $$(warning $$(if $$@,Building $$@,Running shell command) $$(if $$<, (from $$<))$$(if $$?, ($$(wordlist 1, 20, $$?) $$(if $$(wordlist 21, 22, $$?), ... [in total $$(words $$?) files]) newer)))$$(SHELL_NO_RECURSE) -x 161 endif 162 163 # The LOG_PREFIX is set for sub recursive calls like buildjdk and bootcycle. 164 # The warn level can never be turned off 165 LogWarn = $$(info $(LOG_PREFIX)$$(strip $$1)) 166 LOG_WARN := 167 ifneq ($$(findstring $$(LOG_LEVEL), info debug trace),) 168 LogInfo = $$(info $(LOG_PREFIX)$$(strip $$1)) 169 LOG_INFO := 170 else 171 LogInfo = 172 LOG_INFO := > /dev/null 173 endif 174 ifneq ($$(findstring $$(LOG_LEVEL), debug trace),) 175 LogDebug = $$(info $(LOG_PREFIX)$$(strip $$1)) 176 LOG_DEBUG := 177 else 178 LogDebug = 179 LOG_DEBUG := > /dev/null 180 endif 181 ifneq ($$(findstring $$(LOG_LEVEL), trace),) 182 LogTrace = $$(info $(LOG_PREFIX)$$(strip $$1)) 183 LOG_TRACE := 184 else 185 LogTrace = 186 LOG_TRACE := > /dev/null 187 endif 188 endef 189 190 # Make sure logging is setup for everyone that includes MakeBase.gmk. 191 $(eval $(call SetupLogging)) 192 193 ################################################################################ 194 195 MAX_PARAMS := 36 196 PARAM_SEQUENCE := $(call sequence, 2, $(MAX_PARAMS)) 197 198 # Template for creating a macro taking named parameters. To use it, assign the 199 # template to a variable with the name you want for your macro, using '=' 200 # assignment. Then define a macro body with the suffix "Body". The Body macro 201 # should take 1 parameter which should be a unique string for that invocation 202 # of the macro. 203 # Ex: 204 # SetupFoo = $(NamedParamsMacroTemplate) 205 # define SetupFooBody 206 # # do something 207 # # access parameters as $$($1_BAR) 208 # endef 209 # Call it like this 210 # $(eval $(call SetupFoo, BUILD_SOMETHING, \ 211 # BAR := some parameter value, \ 212 # )) 213 define NamedParamsMacroTemplate 214 $(if $($(MAX_PARAMS)),$(error Internal makefile error: \ 215 Too many named arguments to macro, please update MAX_PARAMS in MakeBase.gmk)) 216 # Iterate over 2 3 4... and evaluate the named parameters with $1_ as prefix 217 $(foreach i,$(PARAM_SEQUENCE), $(if $(strip $($i)),\ 218 $(strip $1)_$(strip $(call EscapeHash, $(call DoubleDollar, $($i))))$(NEWLINE))) 219 # Debug print all named parameter names and values 220 $(if $(findstring $(LOG_LEVEL),debug trace), \ 221 $(info $0 $(strip $1) $(foreach i,$(PARAM_SEQUENCE), \ 222 $(if $(strip $($i)),$(NEWLINE) $(strip [$i] $(if $(filter $(LOG_LEVEL), trace), \ 223 $($i), $(wordlist 1, 20, $($(i))) $(if $(word 21, $($(i))), ...))))))) 224 225 $(if $(DEBUG_$(strip $1)), 226 $(info -------- <<< Begin expansion of $(strip $1)) \ 227 $(info $(call $(0)Body,$(strip $1))) \ 228 $(info -------- >>> End expansion of $(strip $1)) \ 229 ) 230 231 $(call $(0)Body,$(strip $1)) 232 endef 233 234 ################################################################################ 235 # Make directory without forking mkdir if not needed. 236 # 237 # If a directory with an encoded space is provided, the wildcard function 238 # sometimes returns false answers (typically if the dir existed when the 239 # makefile was parsed, but was deleted by a previous rule). In that case, always 240 # call mkdir regardless of what wildcard says. 241 # 242 # 1: List of directories to create 243 MakeDir = \ 244 $(strip \ 245 $(eval MakeDir_dirs_to_make := $(strip $(foreach d, $1, \ 246 $(if $(findstring ?, $d), '$(call DecodeSpace, $d)', \ 247 $(if $(wildcard $d), , $d) \ 248 ) \ 249 ))) \ 250 $(if $(MakeDir_dirs_to_make), $(shell $(MKDIR) -p $(MakeDir_dirs_to_make))) \ 251 ) 252 253 # Make directory for target file. Should handle spaces in filenames. Just 254 # calling $(call MakeDir $(@D)) will not work if the directory contains a space 255 # and the target file already exists. In that case, the target file will have 256 # its wildcard ? resolved and the $(@D) will evaluate each space separated dir 257 # part on its own. 258 MakeTargetDir = \ 259 $(call MakeDir, $(dir $(call EncodeSpace, $@))) 260 261 ################################################################################ 262 # All install-file and related macros automatically call DecodeSpace when needed. 263 264 ifeq ($(call isTargetOs, solaris), true) 265 # On Solaris, if the target is a symlink and exists, cp won't overwrite. 266 # Cp has to operate in recursive mode to allow for -P flag, to preserve soft links. If the 267 # name of the target file differs from the source file, rename after copy. 268 # If the source and target parent directories are the same, recursive copy doesn't work 269 # so we fall back on regular copy, which isn't preserving symlinks. 270 define install-file 271 $(call MakeTargetDir) 272 $(RM) '$(call DecodeSpace, $@)' 273 if [ '$(call DecodeSpace, $(dir $(call EncodeSpace, $@)))' != \ 274 '$(call DecodeSpace, $(dir $(call EncodeSpace, $<)))' ]; then \ 275 $(CP) -f -r -P '$(call DecodeSpace, $<)' \ 276 '$(call DecodeSpace, $(dir $(call EncodeSpace, $@)))'; \ 277 if [ '$(call DecodeSpace, $(notdir $(call EncodeSpace, $@)))' != \ 278 '$(call DecodeSpace, $(notdir $(call EncodeSpace, $(<))))' ]; then \ 279 $(MV) '$(call DecodeSpace, $(dir $(call EncodeSpace, $@))/$(notdir $(call EncodeSpace, $<)))' \ 280 '$(call DecodeSpace, $@)'; \ 281 fi; \ 282 else \ 283 if [ -L '$(call DecodeSpace, $<)' ]; then \ 284 $(ECHO) "Source file is a symlink and target is in the same directory: $< $@" ; \ 285 exit 1; \ 286 fi; \ 287 $(CP) -f '$(call DecodeSpace, $<)' '$(call DecodeSpace, $@)'; \ 288 fi 289 endef 290 else ifeq ($(call isTargetOs, macosx), true) 291 # On mac, extended attributes sometimes creep into the source files, which may later 292 # cause the creation of ._* files which confuses testing. Clear these with xattr if 293 # set. Some files get their write permissions removed after being copied to the 294 # output dir. When these are copied again to images, xattr would fail. By only clearing 295 # attributes when they are present, failing on this is avoided. 296 # 297 # If copying a soft link to a directory, need to delete the target first to avoid 298 # weird errors. 299 define install-file 300 $(call MakeTargetDir) 301 $(RM) '$(call DecodeSpace, $@)' 302 # Work around a weirdness with cp on Macosx. When copying a symlink, if 303 # the target of the link is write protected (e.g. 444), cp will add 304 # write permission for the user on the target file (644). Avoid this by 305 # using ln to create a new link instead. 306 if [ -h '$(call DecodeSpace, $<)' ]; then \ 307 $(LN) -s "`$(READLINK) '$(call DecodeSpace, $<)'`" '$(call DecodeSpace, $@)'; \ 308 else \ 309 $(CP) -fRP '$(call DecodeSpace, $<)' '$(call DecodeSpace, $@)'; \ 310 fi 311 if [ -n "`$(XATTR) -ls '$(call DecodeSpace, $@)'`" ]; then \ 312 $(XATTR) -cs '$(call DecodeSpace, $@)'; \ 313 fi 314 endef 315 else 316 define install-file 317 $(call MakeTargetDir) 318 $(CP) -fP '$(call DecodeSpace, $<)' '$(call DecodeSpace, $@)' 319 endef 320 endif 321 322 # Variant of install file that does not preserve symlinks 323 define install-file-nolink 324 $(call MakeTargetDir) 325 $(CP) -f '$(call DecodeSpace, $<)' '$(call DecodeSpace, $@)' 326 endef 327 328 ################################################################################ 329 # link-file-* works similarly to install-file but creates a symlink instead. 330 # There are two versions, either creating a relative or an absolute link. Be 331 # careful when using this on Windows since the symlink created is only valid in 332 # the unix emulation environment. 333 define link-file-relative 334 $(call MakeTargetDir) 335 $(RM) '$(call DecodeSpace, $@)' 336 $(LN) -s '$(call DecodeSpace, $(call RelativePath, $<, $(@D)))' '$(call DecodeSpace, $@)' 337 endef 338 339 define link-file-absolute 340 $(call MakeTargetDir) 341 $(RM) '$(call DecodeSpace, $@)' 342 $(LN) -s '$(call DecodeSpace, $<)' '$(call DecodeSpace, $@)' 343 endef 344 345 ################################################################################ 346 347 # Recursive wildcard function. Walks down directories recursively and matches 348 # files with the search patterns. Patterns use standard file wildcards (* and 349 # ?). 350 # 351 # $1 - Directories to start search in 352 # $2 - Search patterns 353 rwildcard = \ 354 $(strip \ 355 $(foreach d, \ 356 $(patsubst %/,%,$(sort $(dir $(wildcard $(addsuffix /*/*, $(strip $1)))))), \ 357 $(call rwildcard,$d,$2) \ 358 ) \ 359 $(call DoubleDollar, $(wildcard $(foreach p, $2, $(addsuffix /$(strip $p), $(strip $1))))) \ 360 ) 361 362 # Find non directories using recursive wildcard function. This function may 363 # be used directly when a small amount of directories is expected to be 364 # searched and caching is not expected to be of use. 365 # 366 # $1 - Directory to start search in 367 # $2 - Optional search patterns, defaults to '*'. 368 WildcardFindFiles = \ 369 $(sort $(strip \ 370 $(eval WildcardFindFiles_result := $(call rwildcard,$(patsubst %/,%,$1),$(if $(strip $2),$2,*))) \ 371 $(filter-out $(patsubst %/,%,$(sort $(dir $(WildcardFindFiles_result)))), \ 372 $(WildcardFindFiles_result) \ 373 ) \ 374 )) 375 376 # Find non directories using the find utility in the shell. Safe to call for 377 # non existing directories, or directories containing wildcards. 378 # 379 # Files containing space will get spaces replaced with ? because GNU Make 380 # cannot handle lists of files with space in them. By using ?, make will match 381 # the wildcard to space in many situations so we don't need to replace back 382 # to space on every use. While not a complete solution it does allow some uses 383 # of FindFiles to function with spaces in file names, including for 384 # SetupCopyFiles. Unfortunately this does not work for WildcardFindFiles so 385 # if files with spaces are anticipated, use ShellFindFiles directly. 386 # 387 # $1 - Directories to start search in. 388 # $2 - Optional search patterns, empty means find everything. Patterns use 389 # standard file wildcards (* and ?) and should not be quoted. 390 # $3 - Optional options to find. 391 ShellFindFiles = \ 392 $(if $(wildcard $1), \ 393 $(sort \ 394 $(shell $(FIND) $3 $(patsubst %/,%,$(wildcard $1)) \( -type f -o -type l \) \ 395 $(if $(strip $2), -a \( -name "$(firstword $2)" \ 396 $(foreach p, $(filter-out $(firstword $2), $2), -o -name "$(p)") \)) \ 397 | $(TR) ' ' '?' \ 398 ) \ 399 ) \ 400 ) 401 402 # Find non directories using the method most likely to work best for the 403 # current build host 404 # 405 # $1 - Directory to start search in 406 # $2 - Optional search patterns, defaults to '*'. 407 ifeq ($(OPENJDK_BUILD_OS)-$(RWILDCARD_WORKS), windows-true) 408 DirectFindFiles = $(WildcardFindFiles) 409 else 410 DirectFindFiles = $(ShellFindFiles) 411 endif 412 413 # Finds files using a cache that is populated by FillFindCache below. If any of 414 # the directories given have not been cached, DirectFindFiles is used for 415 # everything. Caching is especially useful in Cygwin, where file finds are very 416 # costly. 417 # 418 # $1 - Directories to start search in. 419 # $2 - Optional search patterns. If used, no caching is done. 420 CacheFindFiles_CACHED_DIRS := 421 CacheFindFiles_CACHED_FILES := 422 CacheFindFiles = \ 423 $(if $2, \ 424 $(call DirectFindFiles, $1, $2) \ 425 , \ 426 $(if $(filter-out $(addsuffix /%, $(CacheFindFiles_CACHED_DIRS)) \ 427 $(CacheFindFiles_CACHED_DIRS), $1), \ 428 $(call DirectFindFiles, $1) \ 429 , \ 430 $(filter $(addsuffix /%,$(patsubst %/,%,$1)) $1,$(CacheFindFiles_CACHED_FILES)) \ 431 ) \ 432 ) 433 434 # Explicitly adds files to the find cache used by CacheFindFiles. 435 # 436 # $1 - Directories to start search in 437 FillFindCache = \ 438 $(eval CacheFindFiles_NEW_DIRS := $$(filter-out $$(addsuffix /%,\ 439 $$(CacheFindFiles_CACHED_DIRS)) $$(CacheFindFiles_CACHED_DIRS), $1)) \ 440 $(if $(CacheFindFiles_NEW_DIRS), \ 441 $(eval CacheFindFiles_CACHED_DIRS += $$(patsubst %/,%,$$(CacheFindFiles_NEW_DIRS))) \ 442 $(eval CacheFindFiles_CACHED_FILES := $$(sort $$(CacheFindFiles_CACHED_FILES) \ 443 $$(call DirectFindFiles, $$(CacheFindFiles_NEW_DIRS)))) \ 444 ) 445 446 # Findfiles is the default macro that should be used to find files in the file 447 # system. This function does not always support files with spaces in the names. 448 # If files with spaces are anticipated, use ShellFindFiles directly. 449 # 450 # $1 - Directories to start search in. 451 # $2 - Optional search patterns, empty means find everything. Patterns use 452 # standard file wildcards (* and ?) and should not be quoted. 453 ifeq ($(DISABLE_CACHE_FIND), true) 454 FindFiles = $(DirectFindFiles) 455 else 456 FindFiles = $(CacheFindFiles) 457 endif 458 459 ################################################################################ 460 # FixPath 461 # 462 # On Windows, converts a path from cygwin/unix style (e.g. /bin/foo) into 463 # "mixed mode" (e.g. c:/cygwin/bin/foo). On other platforms, return the path 464 # unchanged. 465 # This is normally not needed since we use the FIXPATH prefix for command lines, 466 # but might be needed in certain circumstances. 467 ifeq ($(call isTargetOs, windows), true) 468 ifeq ($(call isBuildOsEnv, windows.wsl), true) 469 FixPath = \ 470 $(shell $(WSLPATH) -m $1) 471 else 472 FixPath = \ 473 $(shell $(CYGPATH) -m $1) 474 endif 475 else 476 FixPath = \ 477 $1 478 endif 479 480 ################################################################################ 481 # FixPathList 482 # 483 # On Windows, converts a cygwin/unix style path list (colon-separated) into 484 # the native format (mixed mode, semicolon-separated). On other platforms, 485 # return the path list unchanged. 486 ################################################################################ 487 ifeq ($(call isTargetOs, windows), true) 488 FixPathList = \ 489 $(subst @,$(SPACE),$(subst $(SPACE),;,$(foreach entry,$(subst :,$(SPACE),\ 490 $(subst $(SPACE),@,$(strip $1))),$(call FixPath, $(entry))))) 491 else 492 FixPathList = \ 493 $1 494 endif 495 496 ################################################################################ 497 # DependOnVariable 498 # 499 # This macro takes a variable name and puts the value in a file only if the 500 # value has changed since last. The name of the file is returned. This can be 501 # used to create rule dependencies on make variable values. The following 502 # example would get rebuilt if the value of SOME_VAR was changed: 503 # 504 # path/to/some-file: $(call DependOnVariable, SOME_VAR) 505 # echo $(SOME_VAR) > $@ 506 # 507 # Note that leading and trailing white space in the value is ignored. 508 # 509 510 # Defines the sub directory structure to store variable value file in 511 DependOnVariableDirName = \ 512 $(strip $(addsuffix $(if $(MODULE),/$(MODULE)), \ 513 $(subst $(TOPDIR)/,, $(if $(filter /%, $(firstword $(MAKEFILE_LIST))), \ 514 $(firstword $(MAKEFILE_LIST)), \ 515 $(CURDIR)/$(firstword $(MAKEFILE_LIST)))))) 516 517 # Defines the name of the file to store variable value in. Generates a name 518 # unless parameter 2 is given. 519 # Param 1 - Name of variable 520 # Param 2 - (optional) name of file to store value in 521 DependOnVariableFileName = \ 522 $(strip $(if $(strip $2), $2, \ 523 $(MAKESUPPORT_OUTPUTDIR)/vardeps/$(DependOnVariableDirName)/$(strip $1).vardeps)) 524 525 # Does the actual work with parameters stripped. 526 # If the file exists AND the contents is the same as the variable, do nothing 527 # else print a new file. 528 # Always returns the name of the file where the value was printed. 529 # Param 1 - Name of variable 530 # Param 2 - (optional) name of file to store value in 531 DependOnVariableHelper = \ 532 $(strip \ 533 $(eval $1_filename := $(call DependOnVariableFileName, $1, $2)) \ 534 $(if $(wildcard $($1_filename)), $(eval include $($1_filename))) \ 535 $(if $(call equals, $(strip $($1)), $(strip $($1_old))),,\ 536 $(call MakeDir, $(dir $($1_filename))) \ 537 $(if $(findstring $(LOG_LEVEL), trace), \ 538 $(info NewVariable $1: >$(strip $($1))<) \ 539 $(info OldVariable $1: >$(strip $($1_old))<)) \ 540 $(call WriteFile, $1_old:=$(call DoubleDollar,$(call EscapeHash,$($1))), \ 541 $($1_filename))) \ 542 $($1_filename) \ 543 ) 544 545 # Main macro 546 # Param 1 - Name of variable 547 # Param 2 - (optional) name of file to store value in 548 DependOnVariable = \ 549 $(call DependOnVariableHelper,$(strip $1),$(strip $2)) 550 551 # LogCmdlines is only intended to be used by ExecuteWithLog 552 ifeq ($(LOG_CMDLINES), true) 553 LogCmdlines = $(info $(strip $1)) 554 else 555 LogCmdlines = 556 endif 557 558 ################################################################################ 559 # ExecuteWithLog will run a command and log the output appropriately. This is 560 # meant to be used by commands that do "real" work, like a compilation. 561 # The output is stored in a specified log file, which is displayed at the end 562 # of the build in case of failure. The command line itself is stored in a file, 563 # and also logged to stdout if the LOG=cmdlines option has been given. 564 # 565 # NOTE: If the command redirects stdout, the caller needs to wrap it in a 566 # subshell (by adding parentheses around it), otherwise the redirect to the 567 # subshell tee process will create a race condition where the target file may 568 # not be fully written when the make recipe is done. 569 # 570 # Param 1 - The path to base the name of the log file / command line file on 571 # Param 2 - The command to run 572 ExecuteWithLog = \ 573 $(call LogCmdlines, Executing: [$(strip $2)]) \ 574 $(call MakeDir, $(dir $(strip $1)) $(MAKESUPPORT_OUTPUTDIR)/failure-logs) \ 575 $(call WriteFile, $2, $(strip $1).cmdline) \ 576 ( $(RM) $(strip $1).log && $(strip $2) > >($(TEE) -a $(strip $1).log) 2> >($(TEE) -a $(strip $1).log >&2) || \ 577 ( exitcode=$(DOLLAR)? && \ 578 $(CP) $(strip $1).log $(MAKESUPPORT_OUTPUTDIR)/failure-logs/$(subst /,_,$(patsubst $(OUTPUTDIR)/%,%,$(strip $1))).log && \ 579 $(CP) $(strip $1).cmdline $(MAKESUPPORT_OUTPUTDIR)/failure-logs/$(subst /,_,$(patsubst $(OUTPUTDIR)/%,%,$(strip $1))).cmdline && \ 580 exit $(DOLLAR)exitcode ) ) 581 582 ################################################################################ 583 584 # Hook to include the corresponding custom file, if present. 585 $(eval $(call IncludeCustomExtension, common/MakeBase.gmk)) 586 587 endif # _MAKEBASE_GMK