comparison make/Init.gmk @ 1427:f658baecb743

8076465: New Init.gmk needs improvements Reviewed-by: erikj, tbell
author ihse
date Tue, 07 Apr 2015 09:06:24 +0200
parents f077ae77feb1
children cfd05cc6c27b
comparison
equal deleted inserted replaced
1:23630ac9515e 2:d2db6eac64f9
35 35
36 # Inclusion of this pseudo-target will cause make to execute this file 36 # Inclusion of this pseudo-target will cause make to execute this file
37 # serially, regardless of -j. 37 # serially, regardless of -j.
38 .NOTPARALLEL: 38 .NOTPARALLEL:
39 39
40 # If included from the top-level Makefile then topdir is set, but not when 40 ifeq ($(HAS_SPEC),)
41 # recursively calling ourself with a spec. 41 ##############################################################################
42 ifeq ($(topdir),) 42 # This is the default mode. We have not been recursively called with a SPEC.
43 topdir := $(strip $(patsubst %/make/, %, $(dir $(lastword $(MAKEFILE_LIST))))) 43 ##############################################################################
44 endif 44
45 45 # Include our helper functions.
46 # Our helper functions. Will include $(SPEC) if $(HAS_SPEC) is true. 46 include $(topdir)/make/InitSupport.gmk
47 include $(topdir)/make/InitSupport.gmk 47
48 48 # Here are "global" targets, i.e. targets that can be executed without having
49 # Here are "global" targets, i.e. targets that can be executed without having a configuration. 49 # a configuration. This will define ALL_GLOBAL_TARGETS.
50 # This will define ALL_GLOBAL_TARGETS. 50 include $(topdir)/make/Help.gmk
51 include $(topdir)/make/Help.gmk 51
52 52 # Targets provided by Init.gmk.
53 # Extract main targets from Main.gmk. 53 ALL_INIT_TARGETS := print-modules print-targets reconfigure
54 ifneq ($(any_spec_file), )
55 ifeq ($(wildcard $(dir $(any_spec_file))/make-support/module-deps.gmk),)
56 # If make-support does not exist, we need to build the genmodules java tool first.
57 $(info Creating data for first make execution in new configuration...)
58 ignore_output := $(shell $(MAKE) -r -R -f $(topdir)/make/Main.gmk \
59 -I $(topdir)/make/common SPEC=$(any_spec_file) NO_RECIPES=true FRC)
60 $(info Done)
61 endif
62 ALL_MAIN_TARGETS := $(shell $(MAKE) -r -R -f $(topdir)/make/Main.gmk \
63 -I $(topdir)/make/common SPEC=$(any_spec_file) NO_RECIPES=true print-targets)
64 else
65 # Without at least a single valid configuration, we cannot extract any real
66 # targets. To provide a helpful error message about the missing configuration
67 # later on, accept whatever targets the user has provided for now.
68 ALL_MAIN_TARGETS := $(if $(MAKECMDGOALS), $(MAKECMDGOALS), default)
69 endif
70
71 # Targets provided by this file.
72 ALL_INIT_TARGETS := reconfigure
73
74 ALL_TARGETS := $(sort $(ALL_GLOBAL_TARGETS) $(ALL_MAIN_TARGETS) $(ALL_INIT_TARGETS))
75
76 ifneq ($(findstring qp, $(MAKEFLAGS)),)
77 ##############################################################################
78 # When called with -qp, assume an external part (e.g. bash completion) is trying
79 # to understand our targets. Just list our targets and do no more checking.
80 ##############################################################################
81
82 $(ALL_TARGETS):
83
84 .PHONY: $(ALL_TARGETS)
85
86 else ifeq ($(HAS_SPEC),)
87
88 ##############################################################################
89 # This is the normal case, we have been called from the command line by the
90 # user and we need to call ourself back with a proper SPEC.
91 ##############################################################################
92
93 $(eval $(call CheckControlVariables))
94 $(eval $(call CheckDeprecatedEnvironment))
95 $(eval $(call CheckInvalidMakeFlags))
96
97 $(eval $(call ParseConfCheckOption))
98
99 # Check that the LOG given is valid, and set LOG_LEVEL, LOG_NOFILE and MAKE_LOG_FLAGS.
100 $(eval $(call ParseLogLevel))
101
102 ifneq ($(findstring $(LOG_LEVEL),info debug trace),)
103 $(info Running make as '$(strip $(MAKE) $(MFLAGS) $(COMMAND_LINE_VARIABLES) $(MAKECMDGOALS))')
104 endif
105 54
106 # CALLED_TARGETS is the list of targets that the user provided, 55 # CALLED_TARGETS is the list of targets that the user provided,
107 # or "default" if unspecified. 56 # or "default" if unspecified.
108 CALLED_TARGETS := $(if $(MAKECMDGOALS), $(MAKECMDGOALS), default) 57 CALLED_TARGETS := $(if $(MAKECMDGOALS), $(MAKECMDGOALS), default)
109 CALLED_SPEC_TARGETS := $(filter $(ALL_MAIN_TARGETS) $(ALL_INIT_TARGETS), $(CALLED_TARGETS)) 58
110 ifneq ($(CALLED_SPEC_TARGETS),) 59 # Extract non-global targets that require a spec file.
111 # We have at least one non-global target, which need a SPEC 60 CALLED_SPEC_TARGETS := $(filter-out $(ALL_GLOBAL_TARGETS), $(CALLED_TARGETS))
61
62 # If we have only global targets, or if we are called with -qp (assuming an
63 # external part, e.g. bash completion, is trying to understand our targets),
64 # we will skip SPEC location and the sanity checks.
65 ifeq ($(CALLED_SPEC_TARGETS), )
66 ONLY_GLOBAL_TARGETS := true
67 endif
68 ifneq ($(findstring qp, $(MAKEFLAGS)),)
69 ONLY_GLOBAL_TARGETS := true
70 endif
71
72 ifeq ($(ONLY_GLOBAL_TARGETS), true)
73 ############################################################################
74 # We have only global targets, or are called with -pq.
75 ############################################################################
76
77 ifeq ($(wildcard $(SPEC)), )
78 # If we have no SPEC provided, we will just make a "best effort" target list.
79 # First try to grab any available pre-existing main-targets.gmk.
80 main_targets_file := $(firstword $(wildcard $(build_dir)/*/make-support/main-targets.gmk))
81 ifneq ($(main_targets_file), )
82 # Extract the SPEC that corresponds to this main-targets.gmk file.
83 SPEC := $(patsubst %/make-support/main-targets.gmk, %/spec.gmk, $(main_targets_file))
84 else
85 # None found, pick an arbitrary SPEC for which to generate a file
86 SPEC := $(firstword $(all_spec_files))
87 endif
88 endif
89
90 ifneq ($(wildcard $(SPEC)), )
91 $(eval $(call DefineMainTargets, LAZY, $(SPEC)))
92 else
93 # If we have no configurations we can not provide any main targets.
94 ALL_MAIN_TARGETS :=
95 endif
96
97 ALL_TARGETS := $(sort $(ALL_GLOBAL_TARGETS) $(ALL_MAIN_TARGETS) $(ALL_INIT_TARGETS))
98
99 # Just list all our targets.
100 $(ALL_TARGETS):
101
102 .PHONY: $(ALL_TARGETS)
103
104 else
105 ############################################################################
106 # This is the normal case, we have been called from the command line by the
107 # user and we need to call ourself back with a proper SPEC.
108 # We have at least one non-global target, so we need to find a spec file.
109 ############################################################################
110
111 # Basic checks on environment and command line.
112 $(eval $(call CheckControlVariables))
113 $(eval $(call CheckDeprecatedEnvironment))
114 $(eval $(call CheckInvalidMakeFlags))
115
116 # Check that CONF_CHECK is valid.
117 $(eval $(call ParseConfCheckOption))
118
119 # Check that the LOG given is valid, and set LOG_LEVEL, LOG_NOFILE and MAKE_LOG_FLAGS.
120 $(eval $(call ParseLogLevel))
121
122 # After this SPECS contain 1..N spec files (otherwise ParseConfAndSpec fails).
112 $(eval $(call ParseConfAndSpec)) 123 $(eval $(call ParseConfAndSpec))
113 # Now SPECS contain 1..N spec files (otherwise ParseConfAndSpec fails) 124
114 125 # Extract main targets from Main.gmk using the spec(s) provided. In theory,
126 # with multiple specs, we should find the intersection of targets provided
127 # by all specs, but we approximate this by an arbitrary spec from the list.
128 # This will setup ALL_MAIN_TARGETS.
129 $(eval $(call DefineMainTargets, FORCE, $(firstword $(SPECS))))
130
131 # Separate called targets depending on type.
115 INIT_TARGETS := $(filter $(ALL_INIT_TARGETS), $(CALLED_SPEC_TARGETS)) 132 INIT_TARGETS := $(filter $(ALL_INIT_TARGETS), $(CALLED_SPEC_TARGETS))
116 SEQUENTIAL_TARGETS := $(filter dist-clean clean%, $(CALLED_SPEC_TARGETS)) 133 MAIN_TARGETS := $(filter $(ALL_MAIN_TARGETS), $(CALLED_SPEC_TARGETS))
117 PARALLEL_TARGETS := $(filter-out $(INIT_TARGETS) $(SEQUENTIAL_TARGETS), $(CALLED_SPEC_TARGETS)) 134 SEQUENTIAL_TARGETS := $(filter dist-clean clean%, $(MAIN_TARGETS))
135 PARALLEL_TARGETS := $(filter-out $(SEQUENTIAL_TARGETS), $(MAIN_TARGETS))
118 136
119 # The spec files depend on the autoconf source code. This check makes sure 137 # The spec files depend on the autoconf source code. This check makes sure
120 # the configuration is up to date after changes to configure. 138 # the configuration is up to date after changes to configure.
121 $(SPECS): $(wildcard $(topdir)/common/autoconf/*) 139 $(SPECS): $(wildcard $(topdir)/common/autoconf/*)
122 ifeq ($(CONF_CHECK), fail) 140 ifeq ($(CONF_CHECK), fail)
124 $(call PrintConfCheckFailed) 142 $(call PrintConfCheckFailed)
125 @exit 2 143 @exit 2
126 else ifeq ($(CONF_CHECK), auto) 144 else ifeq ($(CONF_CHECK), auto)
127 @echo "Note: The configuration is not up to date for '$(lastword $(subst /, , $(dir $@)))'." 145 @echo "Note: The configuration is not up to date for '$(lastword $(subst /, , $(dir $@)))'."
128 @( cd $(topdir) && \ 146 @( cd $(topdir) && \
129 $(MAKE) $(MFLAGS) $(MAKE_LOG_FLAGS) -f $(topdir)/make/Init.gmk SPEC=$@ HAS_SPEC=true \ 147 $(MAKE) $(MFLAGS) $(MAKE_LOG_FLAGS) -r -R -f $(topdir)/make/Init.gmk \
148 SPEC=$@ HAS_SPEC=true ACTUAL_TOPDIR=$(topdir) \
130 reconfigure ) 149 reconfigure )
131 else ifeq ($(CONF_CHECK), ignore) 150 else ifeq ($(CONF_CHECK), ignore)
132 # Do nothing 151 # Do nothing
133 endif 152 endif
134 153
135 # Unless reconfigure is explicitely called, let all targets depend on the spec files to be up to date. 154 # Unless reconfigure is explicitely called, let all main targets depend on
136 ifeq ($(findstring reconfigure, $(CALLED_SPEC_TARGETS)), ) 155 # the spec files to be up to date.
137 $(CALLED_SPEC_TARGETS): $(SPECS) 156 ifeq ($(findstring reconfigure, $(INIT_TARGETS)), )
157 $(MAIN_TARGETS): $(SPECS)
138 endif 158 endif
139 159
140 # The recipe will be run once for every target specified, but we only want to execute the 160 make-info:
141 # recipe a single time, hence the TARGET_DONE with a dummy command if true. 161 ifneq ($(findstring $(LOG_LEVEL),info debug trace),)
142 $(ALL_MAIN_TARGETS) $(ALL_INIT_TARGETS): 162 $(info Running make as '$(strip $(MAKE) $(MFLAGS) \
163 $(COMMAND_LINE_VARIABLES) $(MAKECMDGOALS))')
164 endif
165
166 # Now the init and main targets will be called, once for each SPEC. The
167 # recipe will be run once for every target specified, but we only want to
168 # execute the recipe a single time, hence the TARGET_DONE with a dummy
169 # command if true.
170 $(ALL_INIT_TARGETS) $(ALL_MAIN_TARGETS): make-info
143 @$(if $(TARGET_DONE), \ 171 @$(if $(TARGET_DONE), \
144 true \ 172 true \
145 , \ 173 , \
146 $(foreach spec, $(SPECS), \ 174 $(foreach spec, $(SPECS), \
147 ( cd $(topdir) && \ 175 ( cd $(topdir) && \
148 $(MAKE) $(MFLAGS) $(MAKE_LOG_FLAGS) -j 1 -f $(topdir)/make/Init.gmk \ 176 $(MAKE) $(MFLAGS) $(MAKE_LOG_FLAGS) -r -R -j 1 -f $(topdir)/make/Init.gmk \
149 SPEC=$(spec) HAS_SPEC=true \ 177 SPEC=$(spec) HAS_SPEC=true ACTUAL_TOPDIR=$(topdir) \
150 USER_MAKE_VARS="$(USER_MAKE_VARS)" MAKE_LOG_FLAGS=$(MAKE_LOG_FLAGS) \ 178 USER_MAKE_VARS="$(USER_MAKE_VARS)" MAKE_LOG_FLAGS=$(MAKE_LOG_FLAGS) \
151 LOG_LEVEL=$(LOG_LEVEL) LOG_NOFILE=$(LOG_NOFILE) \ 179 LOG_LEVEL=$(LOG_LEVEL) LOG_NOFILE=$(LOG_NOFILE) \
152 INIT_TARGETS="$(INIT_TARGETS)" SEQUENTIAL_TARGETS="$(SEQUENTIAL_TARGETS)" \ 180 INIT_TARGETS="$(INIT_TARGETS)" \
181 SEQUENTIAL_TARGETS="$(SEQUENTIAL_TARGETS)" \
153 PARALLEL_TARGETS="$(PARALLEL_TARGETS)" \ 182 PARALLEL_TARGETS="$(PARALLEL_TARGETS)" \
154 main ) && \ 183 main ) && \
155 ) true \ 184 ) true \
156 $(eval TARGET_DONE=true) \ 185 $(eval TARGET_DONE=true) \
157 ) 186 )
158 187
159 .PHONY: $(ALL_MAIN_TARGETS) $(ALL_INIT_TARGETS) 188 .PHONY: $(ALL_MAIN_TARGETS) $(ALL_INIT_TARGETS)
160 189
161 endif # has $(CALLED_SPEC_TARGETS) 190 endif # $(ONLY_GLOBAL_TARGETS)!=true
162 191
163 else # HAS_SPEC=true 192 else # HAS_SPEC=true
164 193
165 ############################################################################## 194 ##############################################################################
166 # Now we have a spec. This part provides the "main" target that acts as a 195 # Now we have a spec. This part provides the "main" target that acts as a
167 # trampoline to call the Main.gmk with the value of $(MAKE) found in the spec 196 # trampoline to call the Main.gmk with the value of $(MAKE) found in the spec
168 # file. 197 # file.
169 ############################################################################## 198 ##############################################################################
170 199
200 include $(SPEC)
201
202 # Our helper functions.
203 include $(TOPDIR)/make/InitSupport.gmk
204
205 # Verify that the spec file we included seems okay.
206 $(eval $(call CheckSpecSanity))
207
171 ifeq ($(LOG_NOFILE), true) 208 ifeq ($(LOG_NOFILE), true)
172 # Disable log wrapper if LOG=[level,]nofile was given 209 # Disable log wrapper if LOG=[level,]nofile was given
173 override BUILD_LOG_WRAPPER := 210 override BUILD_LOG_WRAPPER :=
174 endif 211 endif
175 212
176 ifeq ($(OUTPUT_SYNC_SUPPORTED), true) 213 ifeq ($(OUTPUT_SYNC_SUPPORTED), true)
177 OUTPUT_SYNC_FLAG := -O$(OUTPUT_SYNC) 214 OUTPUT_SYNC_FLAG := -O$(OUTPUT_SYNC)
178 endif 215 endif
179 216
180 $(eval $(call CheckSpecSanity)) 217 ##############################################################################
218 # Init targets
219 ##############################################################################
220
221 print-modules:
222 ( cd $(TOPDIR) && \
223 $(MAKE) $(MAKE_ARGS) -j 1 -f make/Main.gmk $(USER_MAKE_VARS) \
224 NO_RECIPES=true print-modules )
225
226 print-targets:
227 ( cd $(TOPDIR) && \
228 $(MAKE) $(MAKE_ARGS) -j 1 -f make/Main.gmk $(USER_MAKE_VARS) \
229 NO_RECIPES=true print-targets )
181 230
182 reconfigure: 231 reconfigure:
183 ifneq ($(CONFIGURE_COMMAND_LINE), ) 232 ifneq ($(CONFIGURE_COMMAND_LINE), )
184 $(ECHO) "Re-running configure using arguments '$(CONFIGURE_COMMAND_LINE)'" 233 $(ECHO) "Re-running configure using arguments '$(CONFIGURE_COMMAND_LINE)'"
185 else 234 else
186 $(ECHO) "Re-running configure using default settings" 235 $(ECHO) "Re-running configure using default settings"
187 endif 236 endif
188 ( cd $(OUTPUT_ROOT) && PATH="$(ORIGINAL_PATH)" \ 237 ( cd $(OUTPUT_ROOT) && PATH="$(ORIGINAL_PATH)" \
189 $(BASH) $(TOPDIR)/configure $(CONFIGURE_COMMAND_LINE) ) 238 $(BASH) $(TOPDIR)/configure $(CONFIGURE_COMMAND_LINE) )
190 239
191 main-init: 240 ##############################################################################
192 $(call RotateLogFiles) 241 # The main target, for delegating into Main.gmk
193 $(BUILD_LOG_WRAPPER) $(PRINTF) "Building target(s) '$(strip \ 242 ##############################################################################
194 $(INIT_TARGETS) $(SEQUENTIAL_TARGETS) $(PARALLEL_TARGETS) \ 243
195 )' in configuration '$(CONF_NAME)'\n" 244 MAIN_TARGETS := $(SEQUENTIAL_TARGETS) $(PARALLEL_TARGETS)
196 245 TARGET_DESCRIPTION := target$(if $(word 2, $(MAIN_TARGETS)),s) \
246 '$(strip $(MAIN_TARGETS))' in configuration '$(CONF_NAME)'
197 247
198 # MAKEOVERRIDES is automatically set and propagated by Make to sub-Make calls. 248 # MAKEOVERRIDES is automatically set and propagated by Make to sub-Make calls.
199 # We need to clear it of the init-specific variables. The user-specified 249 # We need to clear it of the init-specific variables. The user-specified
200 # variables are explicitely propagated using $(USER_MAKE_VARS). 250 # variables are explicitely propagated using $(USER_MAKE_VARS).
201 main: MAKEOVERRIDES := 251 main: MAKEOVERRIDES :=
202 252
203 main: $(INIT_TARGETS) main-init 253 main: $(INIT_TARGETS)
204 ifneq ($(SEQUENTIAL_TARGETS), ) 254 ifneq ($(SEQUENTIAL_TARGETS)$(PARALLEL_TARGETS), )
205 # Don't touch build output dir since we might be cleaning. That means 255 $(call RotateLogFiles)
206 # no log wrapper. 256 $(BUILD_LOG_WRAPPER) $(PRINTF) "Building $(TARGET_DESCRIPTION)\n"
207 ( cd $(TOPDIR) && \ 257 ifneq ($(SEQUENTIAL_TARGETS), )
208 $(MAKE) $(MAKE_ARGS) -j 1 -f make/Main.gmk $(USER_MAKE_VARS) \ 258 # Don't touch build output dir since we might be cleaning. That
209 $(SEQUENTIAL_TARGETS) \ 259 # means no log wrapper.
210 ) 260 ( cd $(TOPDIR) && \
211 endif 261 $(MAKE) $(MAKE_ARGS) -j 1 -f make/Main.gmk $(USER_MAKE_VARS) \
212 ifneq ($(PARALLEL_TARGETS), ) 262 $(SEQUENTIAL_TARGETS) )
213 $(call StartGlobalTimer) 263 endif
214 $(call PrepareSmartJavac) 264 ifneq ($(PARALLEL_TARGETS), )
215 ( cd $(TOPDIR) && \ 265 $(call StartGlobalTimer)
216 $(BUILD_LOG_WRAPPER) $(MAKE) $(MAKE_ARGS) $(OUTPUT_SYNC_FLAG) \ 266 $(call PrepareSmartJavac)
217 -j $(JOBS) -f make/Main.gmk $(USER_MAKE_VARS) \ 267 ( cd $(TOPDIR) && \
218 $(PARALLEL_TARGETS) \ 268 $(BUILD_LOG_WRAPPER) $(MAKE) $(MAKE_ARGS) $(OUTPUT_SYNC_FLAG) \
219 ) 269 -j $(JOBS) -f make/Main.gmk $(USER_MAKE_VARS) \
220 $(call CleanupSmartJavac) 270 $(PARALLEL_TARGETS) )
221 $(call StopGlobalTimer) 271 $(call CleanupSmartJavac)
222 $(call ReportBuildTimes) 272 $(call StopGlobalTimer)
223 endif 273 $(call ReportBuildTimes)
224 $(BUILD_LOG_WRAPPER) $(PRINTF) "Finished building target(s) '$(strip \ 274 endif
225 $(INIT_TARGETS) $(SEQUENTIAL_TARGETS) $(PARALLEL_TARGETS) \ 275 $(BUILD_LOG_WRAPPER) $(PRINTF) "Finished building $(TARGET_DESCRIPTION)\n"
226 )' in configuration '$(CONF_NAME)'\n" 276 endif
227 277
228 .PHONY: reconfigure main-init main 278 .PHONY: print-targets print-modules reconfigure main
229 endif 279 endif