1 #
   2 # Copyright (c) 2011, 2019, 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 warn level can never be turned off
 164   LogWarn = $$(info $$(strip $$1))
 165   LOG_WARN :=
 166   ifneq ($$(findstring $$(LOG_LEVEL), info debug trace),)
 167     LogInfo = $$(info $$(strip $$1))
 168     LOG_INFO :=
 169   else
 170     LogInfo =
 171     LOG_INFO := > /dev/null
 172   endif
 173   ifneq ($$(findstring $$(LOG_LEVEL), debug trace),)
 174     LogDebug = $$(info $$(strip $$1))
 175     LOG_DEBUG :=
 176   else
 177     LogDebug =
 178     LOG_DEBUG := > /dev/null
 179   endif
 180   ifneq ($$(findstring $$(LOG_LEVEL), trace),)
 181     LogTrace = $$(info $$(strip $$1))
 182     LOG_TRACE :=
 183   else
 184     LogTrace =
 185     LOG_TRACE := > /dev/null
 186   endif
 187 endef
 188 
 189 # Make sure logging is setup for everyone that includes MakeBase.gmk.
 190 $(eval $(call SetupLogging))
 191 
 192 ################################################################################
 193 
 194 MAX_PARAMS := 36
 195 PARAM_SEQUENCE := $(call sequence, 2, $(MAX_PARAMS))
 196 
 197 # Template for creating a macro taking named parameters. To use it, assign the
 198 # template to a variable with the name you want for your macro, using '='
 199 # assignment. Then define a macro body with the suffix "Body". The Body macro
 200 # should take 1 parameter which should be a unique string for that invocation
 201 # of the macro.
 202 # Ex:
 203 # SetupFoo = $(NamedParamsMacroTemplate)
 204 # define SetupFooBody
 205 #   # do something
 206 #   # access parameters as $$($1_BAR)
 207 # endef
 208 # Call it like this
 209 # $(eval $(call SetupFoo, BUILD_SOMETHING, \
 210 #     BAR := some parameter value, \
 211 # ))
 212 define NamedParamsMacroTemplate
 213   $(if $($(MAX_PARAMS)),$(error Internal makefile error: \
 214       Too many named arguments to macro, please update MAX_PARAMS in MakeBase.gmk))
 215   # Iterate over 2 3 4... and evaluate the named parameters with $1_ as prefix
 216   $(foreach i,$(PARAM_SEQUENCE), $(if $(strip $($i)),\
 217     $(strip $1)_$(strip $(call EscapeHash, $(call DoubleDollar, $($i))))$(NEWLINE)))
 218   # Debug print all named parameter names and values
 219   $(if $(findstring $(LOG_LEVEL),debug trace), \
 220     $(info $0 $(strip $1) $(foreach i,$(PARAM_SEQUENCE), \
 221       $(if $(strip $($i)),$(NEWLINE) $(strip [$i] $(if $(filter $(LOG_LEVEL), trace), \
 222         $($i), $(wordlist 1, 20, $($(i))) $(if $(word 21, $($(i))), ...)))))))
 223 
 224   $(if $(DEBUG_$(strip $1)),
 225     $(info -------- <<< Begin expansion of $(strip $1)) \
 226     $(info $(call $(0)Body,$(strip $1))) \
 227     $(info -------- >>> End expansion of $(strip $1)) \
 228   )
 229 
 230   $(call $(0)Body,$(strip $1))
 231 endef
 232 
 233 ################################################################################
 234 # Make directory without forking mkdir if not needed.
 235 #
 236 # If a directory with an encoded space is provided, the wildcard function
 237 # sometimes returns false answers (typically if the dir existed when the
 238 # makefile was parsed, but was deleted by a previous rule). In that case, always
 239 # call mkdir regardless of what wildcard says.
 240 #
 241 # 1: List of directories to create
 242 MakeDir = \
 243     $(strip \
 244         $(eval MakeDir_dirs_to_make := $(strip $(foreach d, $1, \
 245           $(if $(findstring ?, $d), '$(call DecodeSpace, $d)', \
 246             $(if $(wildcard $d), , $d) \
 247           ) \
 248         ))) \
 249         $(if $(MakeDir_dirs_to_make), $(shell $(MKDIR) -p $(MakeDir_dirs_to_make))) \
 250     )
 251 
 252 # Make directory for target file. Should handle spaces in filenames. Just
 253 # calling $(call MakeDir $(@D)) will not work if the directory contains a space
 254 # and the target file already exists. In that case, the target file will have
 255 # its wildcard ? resolved and the $(@D) will evaluate each space separated dir
 256 # part on its own.
 257 MakeTargetDir = \
 258     $(call MakeDir, $(dir $(call EncodeSpace, $@)))
 259 
 260 ################################################################################
 261 # All install-file and related macros automatically call DecodeSpace when needed.
 262 
 263 ifeq ($(call isTargetOs, solaris), true)
 264   # On Solaris, if the target is a symlink and exists, cp won't overwrite.
 265   # Cp has to operate in recursive mode to allow for -P flag, to preserve soft links. If the
 266   # name of the target file differs from the source file, rename after copy.
 267   # If the source and target parent directories are the same, recursive copy doesn't work
 268   # so we fall back on regular copy, which isn't preserving symlinks.
 269   define install-file
 270         $(call MakeTargetDir)
 271         $(RM) '$(call DecodeSpace, $@)'
 272         if [ '$(call DecodeSpace, $(dir $(call EncodeSpace, $@)))' != \
 273             '$(call DecodeSpace, $(dir $(call EncodeSpace, $<)))' ]; then \
 274           $(CP) -f -r -P '$(call DecodeSpace, $<)' \
 275               '$(call DecodeSpace, $(dir $(call EncodeSpace, $@)))'; \
 276           if [ '$(call DecodeSpace, $(notdir $(call EncodeSpace, $@)))' != \
 277               '$(call DecodeSpace, $(notdir $(call EncodeSpace, $(<))))' ]; then \
 278             $(MV) '$(call DecodeSpace, $(dir $(call EncodeSpace, $@))/$(notdir $(call EncodeSpace, $<)))' \
 279                 '$(call DecodeSpace, $@)'; \
 280           fi; \
 281         else \
 282           if [ -L '$(call DecodeSpace, $<)' ]; then \
 283             $(ECHO) "Source file is a symlink and target is in the same directory: $< $@" ; \
 284             exit 1; \
 285           fi; \
 286           $(CP) -f '$(call DecodeSpace, $<)' '$(call DecodeSpace, $@)'; \
 287         fi
 288   endef
 289 else ifeq ($(call isTargetOs, macosx), true)
 290   # On mac, extended attributes sometimes creep into the source files, which may later
 291   # cause the creation of ._* files which confuses testing. Clear these with xattr if
 292   # set. Some files get their write permissions removed after being copied to the
 293   # output dir. When these are copied again to images, xattr would fail. By only clearing
 294   # attributes when they are present, failing on this is avoided.
 295   #
 296   # If copying a soft link to a directory, need to delete the target first to avoid
 297   # weird errors.
 298   define install-file
 299         $(call MakeTargetDir)
 300         $(RM) '$(call DecodeSpace, $@)'
 301         # Work around a weirdness with cp on Macosx. When copying a symlink, if
 302         # the target of the link is write protected (e.g. 444), cp will add
 303         # write permission for the user on the target file (644). Avoid this by
 304         # using ln to create a new link instead.
 305         if [ -h '$(call DecodeSpace, $<)' ]; then \
 306           $(LN) -s "`$(READLINK) '$(call DecodeSpace, $<)'`" '$(call DecodeSpace, $@)'; \
 307         else \
 308           $(CP) -fRP '$(call DecodeSpace, $<)' '$(call DecodeSpace, $@)'; \
 309         fi
 310         if [ -n "`$(XATTR) -ls '$(call DecodeSpace, $@)'`" ]; then \
 311           $(XATTR) -cs '$(call DecodeSpace, $@)'; \
 312         fi
 313   endef
 314 else
 315   define install-file
 316         $(call MakeTargetDir)
 317         $(CP) -fP '$(call DecodeSpace, $<)' '$(call DecodeSpace, $@)'
 318   endef
 319 endif
 320 
 321 # Variant of install file that does not preserve symlinks
 322 define install-file-nolink
 323         $(call MakeTargetDir)
 324         $(CP) -f '$(call DecodeSpace, $<)' '$(call DecodeSpace, $@)'
 325 endef
 326 
 327 ################################################################################
 328 # link-file-* works similarly to install-file but creates a symlink instead.
 329 # There are two versions, either creating a relative or an absolute link. Be
 330 # careful when using this on Windows since the symlink created is only valid in
 331 # the unix emulation environment.
 332 define link-file-relative
 333         $(call MakeTargetDir)
 334         $(RM) '$(call DecodeSpace, $@)'
 335         $(LN) -s '$(call DecodeSpace, $(call RelativePath, $<, $(@D)))' '$(call DecodeSpace, $@)'
 336 endef
 337 
 338 define link-file-absolute
 339         $(call MakeTargetDir)
 340         $(RM) '$(call DecodeSpace, $@)'
 341         $(LN) -s '$(call DecodeSpace, $<)' '$(call DecodeSpace, $@)'
 342 endef
 343 
 344 ################################################################################
 345 
 346 # Recursive wildcard function. Walks down directories recursively and matches
 347 # files with the search patterns. Patterns use standard file wildcards (* and
 348 # ?).
 349 #
 350 # $1 - Directories to start search in
 351 # $2 - Search patterns
 352 rwildcard = \
 353     $(strip \
 354         $(foreach d, \
 355           $(patsubst %/,%,$(sort $(dir $(wildcard $(addsuffix /*/*, $(strip $1)))))), \
 356           $(call rwildcard,$d,$2) \
 357         ) \
 358         $(call DoubleDollar, $(wildcard $(foreach p, $2, $(addsuffix /$(strip $p), $(strip $1))))) \
 359     )
 360 
 361 # Find non directories using recursive wildcard function. This function may
 362 # be used directly when a small amount of directories is expected to be
 363 # searched and caching is not expected to be of use.
 364 #
 365 # $1 - Directory to start search in
 366 # $2 - Optional search patterns, defaults to '*'.
 367 WildcardFindFiles = \
 368     $(sort $(strip \
 369         $(eval WildcardFindFiles_result := $(call rwildcard,$(patsubst %/,%,$1),$(if $(strip $2),$2,*))) \
 370         $(filter-out $(patsubst %/,%,$(sort $(dir $(WildcardFindFiles_result)))), \
 371             $(WildcardFindFiles_result) \
 372         ) \
 373     ))
 374 
 375 # Find non directories using the find utility in the shell. Safe to call for
 376 # non existing directories, or directories containing wildcards.
 377 #
 378 # Files containing space will get spaces replaced with ? because GNU Make
 379 # cannot handle lists of files with space in them. By using ?, make will match
 380 # the wildcard to space in many situations so we don't need to replace back
 381 # to space on every use. While not a complete solution it does allow some uses
 382 # of FindFiles to function with spaces in file names, including for
 383 # SetupCopyFiles. Unfortunately this does not work for WildcardFindFiles so
 384 # if files with spaces are anticipated, use ShellFindFiles directly.
 385 #
 386 # $1 - Directories to start search in.
 387 # $2 - Optional search patterns, empty means find everything. Patterns use
 388 #      standard file wildcards (* and ?) and should not be quoted.
 389 # $3 - Optional options to find.
 390 ShellFindFiles = \
 391     $(if $(wildcard $1), \
 392       $(sort \
 393           $(shell $(FIND) $3 $(patsubst %/,%,$(wildcard $1)) \( -type f -o -type l \) \
 394               $(if $(strip $2), -a \( -name "$(firstword $2)" \
 395               $(foreach p, $(filter-out $(firstword $2), $2), -o -name "$(p)") \)) \
 396               | $(TR) ' ' '?' \
 397           ) \
 398       ) \
 399     )
 400 
 401 # Find non directories using the method most likely to work best for the
 402 # current build host
 403 #
 404 # $1 - Directory to start search in
 405 # $2 - Optional search patterns, defaults to '*'.
 406 ifeq ($(OPENJDK_BUILD_OS)-$(RWILDCARD_WORKS), windows-true)
 407   DirectFindFiles = $(WildcardFindFiles)
 408 else
 409   DirectFindFiles = $(ShellFindFiles)
 410 endif
 411 
 412 # Finds files using a cache that is populated by FillFindCache below. If any of
 413 # the directories given have not been cached, DirectFindFiles is used for
 414 # everything. Caching is especially useful in Cygwin, where file finds are very
 415 # costly.
 416 #
 417 # $1 - Directories to start search in.
 418 # $2 - Optional search patterns. If used, no caching is done.
 419 CacheFindFiles_CACHED_DIRS :=
 420 CacheFindFiles_CACHED_FILES :=
 421 CacheFindFiles = \
 422     $(if $2, \
 423       $(call DirectFindFiles, $1, $2) \
 424     , \
 425       $(if $(filter-out $(addsuffix /%, $(CacheFindFiles_CACHED_DIRS)) \
 426           $(CacheFindFiles_CACHED_DIRS), $1), \
 427         $(call DirectFindFiles, $1) \
 428       , \
 429         $(filter $(addsuffix /%,$(patsubst %/,%,$1)) $1,$(CacheFindFiles_CACHED_FILES)) \
 430       ) \
 431     )
 432 
 433 # Explicitly adds files to the find cache used by CacheFindFiles.
 434 #
 435 # $1 - Directories to start search in
 436 FillFindCache = \
 437     $(eval CacheFindFiles_NEW_DIRS := $$(filter-out $$(addsuffix /%,\
 438         $$(CacheFindFiles_CACHED_DIRS)) $$(CacheFindFiles_CACHED_DIRS), $1)) \
 439     $(if $(CacheFindFiles_NEW_DIRS), \
 440       $(eval CacheFindFiles_CACHED_DIRS += $$(patsubst %/,%,$$(CacheFindFiles_NEW_DIRS))) \
 441       $(eval CacheFindFiles_CACHED_FILES := $$(sort $$(CacheFindFiles_CACHED_FILES) \
 442           $$(call DirectFindFiles, $$(CacheFindFiles_NEW_DIRS)))) \
 443     )
 444 
 445 # Findfiles is the default macro that should be used to find files in the file
 446 # system. This function does not always support files with spaces in the names.
 447 # If files with spaces are anticipated, use ShellFindFiles directly.
 448 #
 449 # $1 - Directories to start search in.
 450 # $2 - Optional search patterns, empty means find everything. Patterns use
 451 #      standard file wildcards (* and ?) and should not be quoted.
 452 ifeq ($(DISABLE_CACHE_FIND), true)
 453   FindFiles = $(DirectFindFiles)
 454 else
 455   FindFiles = $(CacheFindFiles)
 456 endif
 457 
 458 ################################################################################
 459 # FixPath
 460 #
 461 # On Windows, converts a path from cygwin/unix style (e.g. /bin/foo) into
 462 # "mixed mode" (e.g. c:/cygwin/bin/foo). On other platforms, return the path
 463 # unchanged.
 464 # This is normally not needed since we use the FIXPATH prefix for command lines,
 465 # but might be needed in certain circumstances.
 466 ifeq ($(call isTargetOs, windows), true)
 467   FixPath = \
 468       $(shell $(CYGPATH) -m $1)
 469 else
 470   FixPath = \
 471       $1
 472 endif
 473 
 474 ################################################################################
 475 # DependOnVariable
 476 #
 477 # This macro takes a variable name and puts the value in a file only if the
 478 # value has changed since last. The name of the file is returned. This can be
 479 # used to create rule dependencies on make variable values. The following
 480 # example would get rebuilt if the value of SOME_VAR was changed:
 481 #
 482 # path/to/some-file: $(call DependOnVariable, SOME_VAR)
 483 #         echo $(SOME_VAR) > $@
 484 #
 485 # Note that leading and trailing white space in the value is ignored.
 486 #
 487 
 488 # Defines the sub directory structure to store variable value file in
 489 DependOnVariableDirName = \
 490     $(strip $(addsuffix $(if $(MODULE),/$(MODULE)), \
 491         $(subst $(TOPDIR)/,, $(if $(filter /%, $(firstword $(MAKEFILE_LIST))), \
 492           $(firstword $(MAKEFILE_LIST)), \
 493           $(CURDIR)/$(firstword $(MAKEFILE_LIST))))))
 494 
 495 # Defines the name of the file to store variable value in. Generates a name
 496 # unless parameter 2 is given.
 497 # Param 1 - Name of variable
 498 # Param 2 - (optional) name of file to store value in
 499 DependOnVariableFileName = \
 500     $(strip $(if $(strip $2), $2, \
 501       $(MAKESUPPORT_OUTPUTDIR)/vardeps/$(DependOnVariableDirName)/$(strip $1).vardeps))
 502 
 503 # Does the actual work with parameters stripped.
 504 # If the file exists AND the contents is the same as the variable, do nothing
 505 # else print a new file.
 506 # Always returns the name of the file where the value was printed.
 507 # Param 1 - Name of variable
 508 # Param 2 - (optional) name of file to store value in
 509 DependOnVariableHelper = \
 510     $(strip \
 511         $(eval -include $(call DependOnVariableFileName, $1, $2)) \
 512         $(if $(call equals, $(strip $($1)), $(strip $($1_old))),,\
 513           $(call MakeDir, $(dir $(call DependOnVariableFileName, $1, $2))) \
 514           $(if $(findstring $(LOG_LEVEL), trace), \
 515               $(info NewVariable $1: >$(strip $($1))<) \
 516               $(info OldVariable $1: >$(strip $($1_old))<)) \
 517           $(call WriteFile, $1_old:=$(call DoubleDollar,$(call EscapeHash,$($1))), \
 518               $(call DependOnVariableFileName, $1, $2))) \
 519         $(call DependOnVariableFileName, $1, $2) \
 520     )
 521 
 522 # Main macro
 523 # Param 1 - Name of variable
 524 # Param 2 - (optional) name of file to store value in
 525 DependOnVariable = \
 526     $(call DependOnVariableHelper,$(strip $1),$(strip $2))
 527 
 528 # LogCmdlines is only intended to be used by ExecuteWithLog
 529 ifeq ($(LOG_CMDLINES), true)
 530   LogCmdlines = $(info $(strip $1))
 531 else
 532   LogCmdlines =
 533 endif
 534 
 535 ################################################################################
 536 # ExecuteWithLog will run a command and log the output appropriately. This is
 537 # meant to be used by commands that do "real" work, like a compilation.
 538 # The output is stored in a specified log file, which is displayed at the end
 539 # of the build in case of failure. The  command line itself is stored in a file,
 540 # and also logged to stdout if the LOG=cmdlines option has been given.
 541 #
 542 # NOTE: If the command redirects stdout, the caller needs to wrap it in a
 543 # subshell (by adding parentheses around it), otherwise the redirect to the
 544 # subshell tee process will create a race condition where the target file may
 545 # not be fully written when the make recipe is done.
 546 #
 547 # Param 1 - The path to base the name of the log file / command line file on
 548 # Param 2 - The command to run
 549 ExecuteWithLog = \
 550   $(call LogCmdlines, Exececuting: [$(strip $2)]) \
 551   $(call MakeDir, $(dir $(strip $1))) \
 552   $(call WriteFile, $2, $(strip $1).cmdline) \
 553   ( $(RM) $(strip $1).log && $(strip $2) > >($(TEE) -a $(strip $1).log) 2> >($(TEE) -a $(strip $1).log >&2) || \
 554       ( exitcode=$(DOLLAR)? && \
 555       $(CP) $(strip $1).log $(MAKESUPPORT_OUTPUTDIR)/failure-logs/$(subst /,_,$(patsubst $(OUTPUTDIR)/%,%,$(strip $1))).log && \
 556       $(CP) $(strip $1).cmdline $(MAKESUPPORT_OUTPUTDIR)/failure-logs/$(subst /,_,$(patsubst $(OUTPUTDIR)/%,%,$(strip $1))).cmdline && \
 557       exit $(DOLLAR)exitcode ) )
 558 
 559 ################################################################################
 560 
 561 # Hook to include the corresponding custom file, if present.
 562 $(eval $(call IncludeCustomExtension, common/MakeBase.gmk))
 563 
 564 endif # _MAKEBASE_GMK