1.1 --- a/common/makefiles/MakeHelpers.gmk Wed Oct 24 13:11:42 2012 -0700 1.2 +++ b/common/makefiles/MakeHelpers.gmk Fri Oct 26 14:29:57 2012 -0700 1.3 @@ -45,13 +45,130 @@ 1.4 list_alt_overrides_with_origins=$(filter ALT_%=environment ALT_%=command,$(foreach var,$(.VARIABLES),$(var)=$(firstword $(origin $(var))))) 1.5 list_alt_overrides=$(subst =command,,$(subst =environment,,$(list_alt_overrides_with_origins))) 1.6 1.7 +# Store the build times in this directory. 1.8 +BUILDTIMESDIR=$(OUTPUT_ROOT)/tmp/buildtimes 1.9 + 1.10 +# Global targets are possible to run either with or without a SPEC. The prototypical 1.11 +# global target is "help". 1.12 +global_targets=help configure 1.13 + 1.14 ############################## 1.15 # Functions 1.16 ############################## 1.17 1.18 -define fatal-error 1.19 +define CheckEnvironment 1.20 + # Find all environment or command line variables that begin with ALT. 1.21 + $(if $(list_alt_overrides), 1.22 + @$(PRINTF) "\nWARNING: You have the following ALT_ variables set:\n" 1.23 + @$(PRINTF) "$(foreach var,$(list_alt_overrides),$(var)=$$$(var))\n" 1.24 + @$(PRINTF) "ALT_ variables are deprecated and will be ignored. Please clean your environment.\n\n" 1.25 + ) 1.26 +endef 1.27 + 1.28 +### Functions for timers 1.29 + 1.30 +# Record starting time for build of a sub repository. 1.31 +define RecordStartTime 1.32 + $(MKDIR) -p $(BUILDTIMESDIR) 1.33 + $(DATE) '+%Y %m %d %H %M %S' | $(NAWK) '{ print $$1,$$2,$$3,$$4,$$5,$$6,($$4*3600+$$5*60+$$6) }' > $(BUILDTIMESDIR)/build_time_start_$1 1.34 + $(DATE) '+%Y-%m-%d %H:%M:%S' > $(BUILDTIMESDIR)/build_time_start_$1_human_readable 1.35 +endef 1.36 + 1.37 +# Record ending time and calculate the difference and store it in a 1.38 +# easy to read format. Handles builds that cross midnight. Expects 1.39 +# that a build will never take 24 hours or more. 1.40 +define RecordEndTime 1.41 + $(DATE) '+%Y %m %d %H %M %S' | $(NAWK) '{ print $$1,$$2,$$3,$$4,$$5,$$6,($$4*3600+$$5*60+$$6) }' > $(BUILDTIMESDIR)/build_time_end_$1 1.42 + $(DATE) '+%Y-%m-%d %H:%M:%S' > $(BUILDTIMESDIR)/build_time_end_$1_human_readable 1.43 + $(ECHO) `$(CAT) $(BUILDTIMESDIR)/build_time_start_$1` `$(CAT) $(BUILDTIMESDIR)/build_time_end_$1` $1 | \ 1.44 + $(NAWK) '{ F=$$7; T=$$14; if (F > T) { T+=3600*24 }; D=T-F; H=int(D/3600); \ 1.45 + M=int((D-H*3600)/60); S=D-H*3600-M*60; printf("%02d:%02d:%02d %s\n",H,M,S,$$15); }' \ 1.46 + > $(BUILDTIMESDIR)/build_time_diff_$1 1.47 +endef 1.48 + 1.49 +# Find all build_time_* files and print their contents in a list sorted 1.50 +# on the name of the sub repository. 1.51 +define ReportBuildTimes 1.52 + $(BUILD_LOG_WRAPPER) $(PRINTF) -- "----- Build times -------\nStart %s\nEnd %s\n%s\n%s\n-------------------------\n" \ 1.53 + "`$(CAT) $(BUILDTIMESDIR)/build_time_start_TOTAL_human_readable`" \ 1.54 + "`$(CAT) $(BUILDTIMESDIR)/build_time_end_TOTAL_human_readable`" \ 1.55 + "`$(LS) $(BUILDTIMESDIR)/build_time_diff_* | $(GREP) -v _TOTAL | $(XARGS) $(CAT) | $(SORT) -k 2`" \ 1.56 + "`$(CAT) $(BUILDTIMESDIR)/build_time_diff_TOTAL`" 1.57 +endef 1.58 + 1.59 +define ResetAllTimers 1.60 + $$(shell $(MKDIR) -p $(BUILDTIMESDIR) && $(RM) $(BUILDTIMESDIR)/build_time_*) 1.61 +endef 1.62 + 1.63 +define StartGlobalTimer 1.64 + $(call RecordStartTime,TOTAL) 1.65 +endef 1.66 + 1.67 +define StopGlobalTimer 1.68 + $(call RecordEndTime,TOTAL) 1.69 +endef 1.70 + 1.71 +### Functions for managing makefile structure (start/end of makefile and individual targets) 1.72 + 1.73 +# Do not indent this function, this will add whitespace at the start which the caller won't handle 1.74 +define GetRealTarget 1.75 +$(strip $(if $(MAKECMDGOALS),$(MAKECMDGOALS),all)) 1.76 +endef 1.77 + 1.78 +# Do not indent this function, this will add whitespace at the start which the caller won't handle 1.79 +define LastGoal 1.80 +$(strip $(lastword $(call GetRealTarget))) 1.81 +endef 1.82 + 1.83 +# Check if the current target is the final target, as specified by 1.84 +# the user on the command line. If so, call AtRootMakeEnd. 1.85 +define CheckIfMakeAtEnd 1.86 + # Check if the current target is the last goal 1.87 + $(if $(filter $@,$(call LastGoal)),$(call AtMakeEnd)) 1.88 + # If the target is 'foo-only', check if our goal was stated as 'foo' 1.89 + $(if $(filter $(patsubst %-only,%,$@),$(call LastGoal)),$(call AtMakeEnd)) 1.90 + # If no goal is given, 'all' is default, but the last target executed for all is 'jdk-only'. Check for that, too. 1.91 + # At most one of the tests can be true. 1.92 + $(if $(subst all,,$(call LastGoal)),,$(if $(filter $@,jdk-only),$(call AtMakeEnd))) 1.93 +endef 1.94 + 1.95 +# Hook to be called when starting to execute a top-level target 1.96 +define TargetEnter 1.97 + $(BUILD_LOG_WRAPPER) $(PRINTF) "## Starting $(patsubst %-only,%,$@)\n" 1.98 + $(call RecordStartTime,$(patsubst %-only,%,$@)) 1.99 +endef 1.100 + 1.101 +# Hook to be called when finish executing a top-level target 1.102 +define TargetExit 1.103 + $(call RecordEndTime,$(patsubst %-only,%,$@)) 1.104 + $(BUILD_LOG_WRAPPER) $(PRINTF) "## Finished $(patsubst %-only,%,$@) (build time %s)\n\n" \ 1.105 + "`$(CAT) $(BUILDTIMESDIR)/build_time_diff_$(patsubst %-only,%,$@) | $(CUT) -f 1 -d " "`" 1.106 + $(call CheckIfMakeAtEnd) 1.107 +endef 1.108 + 1.109 +# Hook to be called as the very first thing when running a normal build 1.110 +define AtMakeStart 1.111 + $(if $(findstring --jobserver,$(MAKEFLAGS)),$(error make -j is not supported, use make JOBS=n)) 1.112 + $(call CheckEnvironment) 1.113 + @$(PRINTF) $(LOG_INFO) "Running make as '$(MAKE) $(MFLAGS) $(MAKE_ARGS)'\n" 1.114 + @$(PRINTF) "Building $(PRODUCT_NAME) for target '$(call GetRealTarget)' in configuration '$(CONF_NAME)'\n\n" 1.115 + $(call StartGlobalTimer) 1.116 +endef 1.117 + 1.118 +# Hook to be called as the very last thing for targets that are "top level" targets 1.119 +define AtMakeEnd 1.120 + $(if $(SJAVAC_SERVER_DIR),@$(RM) -rf $(SJAVAC_SERVER_DIR)/*.port) 1.121 + $(call StopGlobalTimer) 1.122 + $(call ReportBuildTimes) 1.123 + @$(PRINTF) "Finished building $(PRODUCT_NAME) for target '$(call GetRealTarget)'\n" 1.124 + $(call CheckEnvironment) 1.125 +endef 1.126 + 1.127 +### Functions for parsing and setting up make options from command-line 1.128 + 1.129 +define FatalError 1.130 # If the user specificed a "global" target (e.g. 'help'), do not exit but continue running 1.131 - $$(if $$(findstring help,$$(MAKECMDGOALS)),,$$(error Cannot continue)) 1.132 + $$(if $$(filter-out $(global_targets),$$(call GetRealTarget)),$$(error Cannot continue)) 1.133 endef 1.134 1.135 define ParseLogLevel 1.136 @@ -80,14 +197,14 @@ 1.137 ifeq ($$(LOG),warn) 1.138 VERBOSE=-s 1.139 else ifeq ($$(LOG),info) 1.140 - VERBOSE= 1.141 + VERBOSE=-s 1.142 else ifeq ($$(LOG),debug) 1.143 VERBOSE= 1.144 else ifeq ($$(LOG),trace) 1.145 - VERBOSE=-d -p 1.146 + VERBOSE= 1.147 else 1.148 $$(info Error: LOG must be one of: warn, info, debug or trace.) 1.149 - $$(eval $$(call fatal-error)) 1.150 + $$(eval $$(call FatalError)) 1.151 endif 1.152 else 1.153 ifneq ($$(LOG),) 1.154 @@ -95,108 +212,84 @@ 1.155 # but complain if this is the top-level make call. 1.156 ifeq ($$(MAKELEVEL),0) 1.157 $$(info Cannot use LOG=$$(LOG) and VERBOSE=$$(VERBOSE) at the same time. Choose one.) 1.158 - $$(eval $$(call fatal-error)) 1.159 + $$(eval $$(call FatalError)) 1.160 endif 1.161 endif 1.162 endif 1.163 endef 1.164 1.165 -# TODO: Fix duplication in MakeBase.gmk 1.166 -define SetupLogging 1.167 - ifneq ($(findstring $(LOG),debug trace),) 1.168 - # Shell redefinition trick inspired by http://www.cmcrossroads.com/ask-mr-make/6535-tracing-rule-execution-in-gnu-make 1.169 - OLD_SHELL:=$$(SHELL) 1.170 - SHELL = $$(warning Building $$@$$(if $$<, (from $$<))$(if $$?, ($$? newer)))$$(OLD_SHELL) -x 1.171 - endif 1.172 -endef 1.173 - 1.174 define ParseConfAndSpec 1.175 - ifneq ($$(origin SPEC),undefined) 1.176 - # We have been given a SPEC, check that it works out properly 1.177 - ifeq ($$(wildcard $$(SPEC)),) 1.178 - $$(info Cannot locate spec.gmk, given by SPEC=$$(SPEC)) 1.179 - $$(eval $$(call fatal-error)) 1.180 - endif 1.181 - ifneq ($$(origin CONF),undefined) 1.182 - # We also have a CONF argument. This is OK only if this is a repeated call by ourselves, 1.183 - # but complain if this is the top-level make call. 1.184 - ifeq ($$(MAKELEVEL),0) 1.185 - $$(info Cannot use CONF=$$(CONF) and SPEC=$$(SPEC) at the same time. Choose one.) 1.186 - $$(eval $$(call fatal-error)) 1.187 + ifneq ($$(filter-out $(global_targets),$$(call GetRealTarget)),) 1.188 + # If we only have global targets, no need to bother with SPEC or CONF 1.189 + ifneq ($$(origin SPEC),undefined) 1.190 + # We have been given a SPEC, check that it works out properly 1.191 + ifeq ($$(wildcard $$(SPEC)),) 1.192 + $$(info Cannot locate spec.gmk, given by SPEC=$$(SPEC)) 1.193 + $$(eval $$(call FatalError)) 1.194 endif 1.195 - endif 1.196 - # ... OK, we're satisfied, we'll use this SPEC later on 1.197 - else 1.198 - # Find all spec.gmk files in the build output directory 1.199 - output_dir=$$(root_dir)/build 1.200 - all_spec_files=$$(wildcard $$(output_dir)/*/spec.gmk) 1.201 - ifeq ($$(all_spec_files),) 1.202 - $$(info No configurations found for $$(root_dir)! Please run configure to create a configuration.) 1.203 - $$(eval $$(call fatal-error)) 1.204 - endif 1.205 - # Extract the configuration names from the path 1.206 - all_confs=$$(patsubst %/spec.gmk,%,$$(patsubst $$(output_dir)/%,%,$$(all_spec_files))) 1.207 - 1.208 - ifneq ($$(origin CONF),undefined) 1.209 - # User have given a CONF= argument. 1.210 - ifeq ($$(CONF),) 1.211 - # If given CONF=, match all configurations 1.212 - matching_confs=$$(strip $$(all_confs)) 1.213 - else 1.214 - # Otherwise select those that contain the given CONF string 1.215 - matching_confs=$$(strip $$(foreach var,$$(all_confs),$$(if $$(findstring $$(CONF),$$(var)),$$(var)))) 1.216 - endif 1.217 - ifeq ($$(matching_confs),) 1.218 - $$(info No configurations found matching CONF=$$(CONF)) 1.219 - $$(info Available configurations:) 1.220 - $$(foreach var,$$(all_confs),$$(info * $$(var))) 1.221 - $$(eval $$(call fatal-error)) 1.222 - else 1.223 - ifeq ($$(words $$(matching_confs)),1) 1.224 - $$(info Building '$$(matching_confs)' (matching CONF=$$(CONF))) 1.225 - else 1.226 - $$(info Building the following configurations (matching CONF=$$(CONF)):) 1.227 - $$(foreach var,$$(matching_confs),$$(info * $$(var))) 1.228 + ifneq ($$(origin CONF),undefined) 1.229 + # We also have a CONF argument. This is OK only if this is a repeated call by ourselves, 1.230 + # but complain if this is the top-level make call. 1.231 + ifeq ($$(MAKELEVEL),0) 1.232 + $$(info Cannot use CONF=$$(CONF) and SPEC=$$(SPEC) at the same time. Choose one.) 1.233 + $$(eval $$(call FatalError)) 1.234 endif 1.235 endif 1.236 + # ... OK, we're satisfied, we'll use this SPEC later on 1.237 + else 1.238 + # Find all spec.gmk files in the build output directory 1.239 + output_dir=$$(root_dir)/build 1.240 + all_spec_files=$$(wildcard $$(output_dir)/*/spec.gmk) 1.241 + ifeq ($$(all_spec_files),) 1.242 + $$(info No configurations found for $$(root_dir)! Please run configure to create a configuration.) 1.243 + $$(eval $$(call FatalError)) 1.244 + endif 1.245 + # Extract the configuration names from the path 1.246 + all_confs=$$(patsubst %/spec.gmk,%,$$(patsubst $$(output_dir)/%,%,$$(all_spec_files))) 1.247 1.248 - # Create a SPEC definition. This will contain the path to one or more spec.gmk files. 1.249 - SPEC=$$(addsuffix /spec.gmk,$$(addprefix $$(output_dir)/,$$(matching_confs))) 1.250 - else 1.251 - # No CONF or SPEC given, check the available configurations 1.252 - ifneq ($$(words $$(all_spec_files)),1) 1.253 - $$(info No CONF or SPEC given, but more than one spec.gmk found in $$(output_dir).) 1.254 - $$(info Available configurations:) 1.255 - $$(foreach var,$$(all_confs),$$(info * $$(var))) 1.256 - $$(info Please retry building with CONF=<config> or SPEC=<specfile>) 1.257 - $$(eval $$(call fatal-error)) 1.258 + ifneq ($$(origin CONF),undefined) 1.259 + # User have given a CONF= argument. 1.260 + ifeq ($$(CONF),) 1.261 + # If given CONF=, match all configurations 1.262 + matching_confs=$$(strip $$(all_confs)) 1.263 + else 1.264 + # Otherwise select those that contain the given CONF string 1.265 + matching_confs=$$(strip $$(foreach var,$$(all_confs),$$(if $$(findstring $$(CONF),$$(var)),$$(var)))) 1.266 + endif 1.267 + ifeq ($$(matching_confs),) 1.268 + $$(info No configurations found matching CONF=$$(CONF)) 1.269 + $$(info Available configurations:) 1.270 + $$(foreach var,$$(all_confs),$$(info * $$(var))) 1.271 + $$(eval $$(call FatalError)) 1.272 + else 1.273 + ifeq ($$(words $$(matching_confs)),1) 1.274 + $$(info Building '$$(matching_confs)' (matching CONF=$$(CONF))) 1.275 + else 1.276 + $$(info Building target '$(call GetRealTarget)' in the following configurations (matching CONF=$$(CONF)):) 1.277 + $$(foreach var,$$(matching_confs),$$(info * $$(var))) 1.278 + endif 1.279 + endif 1.280 + 1.281 + # Create a SPEC definition. This will contain the path to one or more spec.gmk files. 1.282 + SPEC=$$(addsuffix /spec.gmk,$$(addprefix $$(output_dir)/,$$(matching_confs))) 1.283 + else 1.284 + # No CONF or SPEC given, check the available configurations 1.285 + ifneq ($$(words $$(all_spec_files)),1) 1.286 + $$(info No CONF given, but more than one configuration found in $$(output_dir).) 1.287 + $$(info Available configurations:) 1.288 + $$(foreach var,$$(all_confs),$$(info * $$(var))) 1.289 + $$(info Please retry building with CONF=<config pattern> (or SPEC=<specfile>)) 1.290 + $$(eval $$(call FatalError)) 1.291 + endif 1.292 + 1.293 + # We found exactly one configuration, use it 1.294 + SPEC=$$(strip $$(all_spec_files)) 1.295 endif 1.296 - 1.297 - # We found exactly one configuration, use it 1.298 - SPEC=$$(strip $$(all_spec_files)) 1.299 endif 1.300 endif 1.301 endef 1.302 1.303 -define CheckEnvironment 1.304 - # Find all environment or command line variables that begin with ALT. 1.305 - $(if $(list_alt_overrides), 1.306 - @$(PRINTF) "\nWARNING: You have the following ALT_ variables set:\n" 1.307 - @$(PRINTF) "$(foreach var,$(list_alt_overrides),$(var)=$$$(var))\n" 1.308 - @$(PRINTF) "ALT_ variables are deprecated and will be ignored. Please clean your environment.\n\n" 1.309 - ) 1.310 -endef 1.311 - 1.312 -define PrintStartMessage 1.313 - $(if $(VERBOSE),,@$(ECHO) Running make as $(MAKE) $(MFLAGS) $(MAKE_ARGS)) 1.314 - $(call CheckEnvironment) 1.315 - @$(ECHO) "Building OpenJDK for target $(if $(MAKECMDGOALS),'$(MAKECMDGOALS)','all') in configuration '$(CONF_NAME)'" 1.316 -endef 1.317 - 1.318 -define PrintEndMessage 1.319 - @$(ECHO) "Finished building OpenJDK for target '$@'" 1.320 - $(call CheckEnvironment) 1.321 -endef 1.322 +### Convenience functions from Main.gmk 1.323 1.324 # Cleans the component given as $1 1.325 define CleanComponent