]>
Commit | Line | Data |
---|---|---|
1 | # -*- mode: makefile;-*- | |
2 | # | |
3 | # Copyright (C) 2010-2020 Apple Inc. All rights reserved. | |
4 | # | |
5 | # MakeInc.top is the top-level makefile for the xnu | |
6 | # build system. All the main XBS targets | |
7 | # (like "installhdrs") are defined here, as | |
8 | # well as globals that can be overridden on | |
9 | # the command-line by the user. | |
10 | # | |
11 | # This makefile's main purpose is to bootstrap | |
12 | # the user's intent ("build these 3 kernels") | |
13 | # into 3 single-architecture builds that each | |
14 | # invoke the recursive make build system. | |
15 | # As such, we have no knowledge of how to build | |
16 | # a kernel or perform actions other than | |
17 | # invoking a sub-make with a different | |
18 | # current directory, makefile, and target. One | |
19 | # side effect of this is that each | |
20 | # single-architecture build is responsible for | |
21 | # inserting its build products into the final | |
22 | # multi-architecture output files. To avoid | |
23 | # races, these aggregating stages for | |
24 | # "primary" build configs are done in serial. | |
25 | # | |
26 | ||
27 | export MakeInc_cmd=${VERSDIR}/makedefs/MakeInc.cmd | |
28 | ||
29 | include $(MakeInc_cmd) | |
30 | ||
31 | ||
32 | # | |
33 | # Architecture Configuration options | |
34 | # | |
35 | ||
36 | # Default to current kernel architecture | |
37 | ||
38 | ifneq ($(filter $(SUPPORTED_EMBEDDED_PLATFORMS),$(PLATFORM)),) | |
39 | override DEFAULT_ARCH_CONFIG := ARM | |
40 | else ifneq ($(filter $(SUPPORTED_SIMULATOR_PLATFORMS),$(PLATFORM)),) | |
41 | override DEFAULT_ARCH_CONFIG := X86_64 | |
42 | else | |
43 | override DEFAULT_ARCH_CONFIG := X86_64 | |
44 | endif | |
45 | ||
46 | # Accept either explicit ARCH_CONFIGS or XBS-style RC_ARCHS | |
47 | ifndef ARCH_CONFIGS | |
48 | ifdef RC_ARCHS | |
49 | ARCH_CONFIGS := $(shell printf "%s" "$(RC_ARCHS)" | $(TR) a-z A-Z | $(TR) " " "\n" | sort -u | $(TR) "\n" " ") | |
50 | else | |
51 | ARCH_CONFIGS := DEFAULT | |
52 | endif | |
53 | endif | |
54 | ||
55 | # | |
56 | # Kernel Configuration options | |
57 | # | |
58 | ||
59 | DEFAULT_PRODUCT_CONFIGS := | |
60 | ||
61 | ifneq ($(filter $(RC_ProjectName),xnu_debug),) | |
62 | override DEFAULT_KERNEL_CONFIG := DEBUG | |
63 | else ifneq ($(filter $(RC_ProjectName),xnu_kasan),) | |
64 | override KERNEL_CONFIGS := KASAN | |
65 | else ifneq ($(filter $(SUPPORTED_EMBEDDED_PLATFORMS),$(PLATFORM)),) | |
66 | override DEFAULT_KERNEL_CONFIG := DEVELOPMENT | |
67 | else ifeq ($(PLATFORM),MacOSX) | |
68 | override DEFAULT_KERNEL_CONFIG := DEVELOPMENT | |
69 | else | |
70 | override DEFAULT_KERNEL_CONFIG := RELEASE | |
71 | endif | |
72 | ||
73 | # If KERNEL_CONFIGS is specified it should override default | |
74 | ifndef KERNEL_CONFIGS | |
75 | KERNEL_CONFIGS := DEFAULT | |
76 | endif | |
77 | ||
78 | # If PRODUCT_CONFIGS is specified it should override default | |
79 | ifndef PRODUCT_CONFIGS | |
80 | PRODUCT_CONFIGS := $(DEFAULT_PRODUCT_CONFIGS) | |
81 | endif | |
82 | ||
83 | # | |
84 | # Machine Configuration options | |
85 | # | |
86 | ||
87 | override DEFAULT_I386_MACHINE_CONFIG := NONE | |
88 | override DEFAULT_X86_64_MACHINE_CONFIG := NONE | |
89 | override DEFAULT_X86_64H_MACHINE_CONFIG := NONE | |
90 | ||
91 | ifneq ($(findstring _Sim,$(RC_ProjectName)),) | |
92 | override DEFAULT_ARM_MACHINE_CONFIG := NONE | |
93 | override DEFAULT_ARM64_MACHINE_CONFIG := NONE | |
94 | else ifneq ($(findstring _host,$(RC_ProjectName)),) | |
95 | override DEFAULT_ARM_MACHINE_CONFIG := NONE | |
96 | override DEFAULT_ARM64_MACHINE_CONFIG := NONE | |
97 | else | |
98 | override DEFAULT_ARM_MACHINE_CONFIG := T8002 | |
99 | override DEFAULT_ARM64_MACHINE_CONFIG := T7000 | |
100 | endif | |
101 | ||
102 | # This is typically never specified (TARGET_CONFIGS is used) | |
103 | ifndef MACHINE_CONFIGS | |
104 | MACHINE_CONFIGS := DEFAULT | |
105 | endif | |
106 | ||
107 | # | |
108 | # Target configuration options. NOTE - target configurations will | |
109 | # override ARCH_CONFIGS and KERNEL_CONFIGS and MACHINE_CONFIGS. | |
110 | # | |
111 | # Target configs come in groups of three parameters. The first is the | |
112 | # kernel configuration, the second is the architecture configuration, | |
113 | # and the third is the machine configuration. You may pass in as | |
114 | # many groups of configurations as you wish. Each item passed in is | |
115 | # seperated by whitespace. | |
116 | # | |
117 | # Example: | |
118 | # TARGET_CONFIGS="release ppc default debug i386 default release arm MX31ADS" | |
119 | # Parameters may be in upper or lower case (they are converted to upper). | |
120 | # | |
121 | # "default" parameter is a special case. It means use the default value for | |
122 | # that parameter. Here are the default values for each configuration: | |
123 | # | |
124 | # default kernel configuration = DEFAULT_KERNEL_CONFIG | |
125 | # default architecture configuration = system architecture where you are running make. | |
126 | ||
127 | ifneq ($(filter $(SUPPORTED_PLATFORMS),$(PLATFORM)),) | |
128 | ||
129 | # Defaults for "make all_embedded" | |
130 | ifeq ($(KERNEL_CONFIGS),DEFAULT) | |
131 | KERNEL_CONFIGS_EMBEDDED := RELEASE DEVELOPMENT | |
132 | else | |
133 | KERNEL_CONFIGS_EMBEDDED := $(KERNEL_CONFIGS) | |
134 | endif | |
135 | ||
136 | ifeq ($(ARCH_CONFIGS),DEFAULT) | |
137 | ARCH_CONFIGS_EMBEDDED := ARM ARM64 | |
138 | ARCH_CONFIGS_DESKTOP := X86_64 | |
139 | else | |
140 | ARCH_CONFIGS_EMBEDDED := $(strip $(shell echo $(filter-out X86_64, $(ARCH_CONFIGS)) | $(TR) a-z A-Z)) | |
141 | ARCH_CONFIGS_DESKTOP := $(strip $(shell echo $(filter X86_64, $(ARCH_CONFIGS)) | $(TR) a-z A-Z)) | |
142 | endif | |
143 | ||
144 | # Find supported products from the device map | |
145 | ifneq ($(EMBEDDED_DEVICE_MAP),) | |
146 | DEVICEMAP_PRODUCTS_ARMV7 := $(shell $(EMBEDDED_DEVICE_MAP) -db $(EDM_DBPATH) \ | |
147 | -query 'SELECT DISTINCT TargetType \ | |
148 | FROM Files \ | |
149 | INNER JOIN Manifests USING (manifestID) \ | |
150 | INNER JOIN Targets USING (Target) \ | |
151 | WHERE (KernelMachOArchitecture LIKE "armv7" \ | |
152 | AND fileType in ("KernelCache", "RestoreKernelCache"))') | |
153 | DEVICEMAP_PRODUCTS_ARMV7S := $(shell $(EMBEDDED_DEVICE_MAP) -db $(EDM_DBPATH) \ | |
154 | -query 'SELECT DISTINCT TargetType \ | |
155 | FROM Files \ | |
156 | INNER JOIN Manifests USING (manifestID) \ | |
157 | INNER JOIN Targets USING (Target) \ | |
158 | WHERE (KernelMachOArchitecture LIKE "armv7s" \ | |
159 | AND fileType in ("KernelCache", "RestoreKernelCache"))') | |
160 | DEVICEMAP_PRODUCTS_ARMV7K := $(shell $(EMBEDDED_DEVICE_MAP) -db $(EDM_DBPATH) \ | |
161 | -query 'SELECT DISTINCT TargetType \ | |
162 | FROM Files \ | |
163 | INNER JOIN Manifests USING (manifestID) \ | |
164 | INNER JOIN Targets USING (Target) \ | |
165 | WHERE (KernelMachOArchitecture LIKE "armv7k" \ | |
166 | AND fileType in ("KernelCache", "RestoreKernelCache"))') | |
167 | DEVICEMAP_PRODUCTS_ARM := $(DEVICEMAP_PRODUCTS_ARMV7) $(DEVICEMAP_PRODUCTS_ARMV7S) $(DEVICEMAP_PRODUCTS_ARMV7K) | |
168 | ||
169 | ||
170 | DEVICEMAP_PRODUCTS_ARM64 := $(shell $(EMBEDDED_DEVICE_MAP) -db $(EDM_DBPATH) \ | |
171 | -query 'SELECT DISTINCT TargetType \ | |
172 | FROM Files \ | |
173 | INNER JOIN Manifests USING (manifestID) \ | |
174 | INNER JOIN Targets USING (Target) \ | |
175 | WHERE (KernelMachOArchitecture LIKE "arm64" \ | |
176 | AND fileType in ("KernelCache", "RestoreKernelCache"))') | |
177 | DEVICEMAP_PRODUCTS_OSX_ARM64 := $(shell $(EMBEDDED_DEVICE_MAP) -db $(EDM_DBPATH) \ | |
178 | -query 'SELECT DISTINCT TargetType \ | |
179 | FROM Files \ | |
180 | INNER JOIN Manifests USING (manifestID) \ | |
181 | INNER JOIN Targets USING (Target) \ | |
182 | WHERE (KernelMachOArchitecture LIKE "arm64" \ | |
183 | AND fileType in ("KernelCache", "RestoreKernelCache") \ | |
184 | AND SDKPlatform == "macosx")') | |
185 | ||
186 | ||
187 | # Generate a list of mappings of the form "n75:arm;t8002" based on the device map | |
188 | DEVICEMAP_PRODUCT_SOC_MAPPINGS := $(shell $(EMBEDDED_DEVICE_MAP) -db $(EDM_DBPATH) -query SELECT DISTINCT TargetType, KernelMachOArchitecture, KernelPlatform FROM Targets | awk -F\| '{ if ($$2 ~ /armv[0-9][a-z]?/) { print $$1 ":arm;" $$3 } else if ($$2 ~ /arm64[a-z]?/) { print $$1 ":arm64;" $$3 ";" $$4} else { print $$1 ":" $$2 ";" $$3 ";" $$4} }' ) | |
189 | ||
190 | # use embedded_device_map | |
191 | endif | |
192 | ||
193 | # Map a product like "n75" to "arm;t8002" | |
194 | # $(1) is a product name in lower case | |
195 | function_lookup_product = $(call function_substitute_word_with_replacement, \ | |
196 | $(1), \ | |
197 | $(DEVICEMAP_PRODUCT_SOC_MAPPINGS), \ | |
198 | unknown_arch_for_$(1);unknown_platform_for_$(1) \ | |
199 | ) | |
200 | ||
201 | ifneq ($(PLATFORM),MacOSX) | |
202 | ifneq ($(EMBEDDED_DEVICE_MAP),) | |
203 | # Generate a list of mappings for products that use a different platform for their kernel configuration than their true platform | |
204 | # of the form "n71m:arm64;s8000;s8003". The 4th element is the true SoC platform, which will get an on-disk copy, while the | |
205 | # kernel's recursive build system will build the 3rd element as the KernelPlatform | |
206 | DEVICEMAP_PRODUCT_SOC_ALIASES := $(shell $(EMBEDDED_DEVICE_MAP) -db $(EDM_DBPATH) -query SELECT DISTINCT TargetType, KernelMachOArchitecture, KernelPlatform, Platform FROM Targets WHERE KernelPlatform "!=" Platform | awk -F\| '{ if ($$2 ~ /armv[0-9][a-z]?/) { print $$1 ":arm;" $$3 ";" $$4} else if ($$2 ~ /arm64[a-z]?/) { print $$1 ":arm64;" $$3 ";" $$4} else { print $$1 ":" $$2 ";" $$3 ";" $$4} }' ) | |
207 | ||
208 | endif | |
209 | endif | |
210 | ||
211 | function_lookup_product_alias = $(call function_substitute_word_with_replacement, \ | |
212 | $(1), \ | |
213 | $(DEVICEMAP_PRODUCT_SOC_ALIASES), \ | |
214 | ) | |
215 | endif | |
216 | ||
217 | ifeq ($(PLATFORM),MacOSX) | |
218 | ||
219 | # Defaults for "make all_desktop" | |
220 | ifeq ($(KERNEL_CONFIGS),DEFAULT) | |
221 | KERNEL_CONFIGS_DESKTOP := RELEASE DEVELOPMENT | |
222 | else | |
223 | KERNEL_CONFIGS_DESKTOP := $(KERNEL_CONFIGS) | |
224 | endif | |
225 | ||
226 | endif | |
227 | ||
228 | ifndef TARGET_CONFIGS | |
229 | ifneq ($(PRODUCT_CONFIGS),) | |
230 | # generate TARGET_CONFIGS using KERNEL_CONFIGS and PRODUCT_CONFIGS | |
231 | TARGET_CONFIGS := $(foreach my_devicemap_config,$(foreach my_product_config,$(shell printf "%s" "$(PRODUCT_CONFIGS)" | $(TR) A-Z a-z),$(call function_lookup_product,$(my_product_config))),$(foreach my_kernel_config,$(KERNEL_CONFIGS),$(my_kernel_config) $(subst ;, ,$(my_devicemap_config)))) | |
232 | TARGET_CONFIGS_ALIASES := $(foreach my_devicemap_config,$(foreach my_product_config,$(shell printf "%s" "$(PRODUCT_CONFIGS)" | $(TR) A-Z a-z),$(call function_lookup_product_alias,$(my_product_config))),$(foreach my_kernel_config,$(KERNEL_CONFIGS),$(my_kernel_config) $(subst ;, ,$(my_devicemap_config)))) | |
233 | else ifneq ($(filter %_release_embedded,$(MAKECMDGOALS)),) | |
234 | # generate TARGET_CONFIGS for RELEASE kernel configs and products in the device map | |
235 | TARGET_CONFIGS := $(foreach my_devicemap_config,$(foreach my_arch_config,$(ARCH_CONFIGS_EMBEDDED),$(foreach my_product_config,$(DEVICEMAP_PRODUCTS_$(my_arch_config)),$(call function_lookup_product,$(my_product_config)))),$(foreach my_kernel_config,RELEASE,$(my_kernel_config) $(subst ;, ,$(my_devicemap_config)))) | |
236 | TARGET_CONFIGS_ALIASES := $(foreach my_devicemap_config,$(foreach my_arch_config,$(ARCH_CONFIGS_EMBEDDED),$(foreach my_product_config,$(DEVICEMAP_PRODUCTS_$(my_arch_config)),$(call function_lookup_product_alias,$(my_product_config)))),$(foreach my_kernel_config,RELEASE,$(my_kernel_config) $(subst ;, ,$(my_devicemap_config)))) | |
237 | else ifneq ($(filter %_development_embedded,$(MAKECMDGOALS)),) | |
238 | # generate TARGET_CONFIGS for DEVELOPMENT kernel configs and products in the device map | |
239 | TARGET_CONFIGS := $(foreach my_devicemap_config,$(foreach my_arch_config,$(ARCH_CONFIGS_EMBEDDED),$(foreach my_product_config,$(DEVICEMAP_PRODUCTS_$(my_arch_config)),$(call function_lookup_product,$(my_product_config)))),$(foreach my_kernel_config,DEVELOPMENT,$(my_kernel_config) $(subst ;, ,$(my_devicemap_config)))) | |
240 | TARGET_CONFIGS_ALIASES := $(foreach my_devicemap_config,$(foreach my_arch_config,$(ARCH_CONFIGS_EMBEDDED),$(foreach my_product_config,$(DEVICEMAP_PRODUCTS_$(my_arch_config)),$(call function_lookup_product_alias,$(my_product_config)))),$(foreach my_kernel_config,DEVELOPMENT,$(my_kernel_config) $(subst ;, ,$(my_devicemap_config)))) | |
241 | else ifneq ($(filter %_embedded,$(MAKECMDGOALS)),) | |
242 | # generate TARGET_CONFIGS for all kernel configs and products in the device map | |
243 | TARGET_CONFIGS := $(foreach my_devicemap_config,$(foreach my_arch_config,$(ARCH_CONFIGS_EMBEDDED),$(foreach my_product_config,$(DEVICEMAP_PRODUCTS_$(my_arch_config)),$(call function_lookup_product,$(my_product_config)))),$(foreach my_kernel_config,$(KERNEL_CONFIGS_EMBEDDED),$(my_kernel_config) $(subst ;, ,$(my_devicemap_config)))) | |
244 | TARGET_CONFIGS_ALIASES := $(foreach my_devicemap_config,$(foreach my_arch_config,$(ARCH_CONFIGS_EMBEDDED),$(foreach my_product_config,$(DEVICEMAP_PRODUCTS_$(my_arch_config)),$(call function_lookup_product_alias,$(my_product_config)))),$(foreach my_kernel_config,$(KERNEL_CONFIGS_EMBEDDED),$(my_kernel_config) $(subst ;, ,$(my_devicemap_config)))) | |
245 | else ifneq ($(filter %_desktop,$(MAKECMDGOALS)),) | |
246 | # generate TARGET_CONFIGS for all kernel configs for B&I | |
247 | TARGET_CONFIGS := $(foreach my_kern_config, $(KERNEL_CONFIGS_DESKTOP), $(foreach my_arch_config, $(ARCH_CONFIGS_DESKTOP), $(foreach my_machine_config, $(MACHINE_CONFIGS), $(my_kern_config) $(my_arch_config) $(my_machine_config)))) | |
248 | TARGET_CONFIGS += $(foreach my_devicemap_config,$(foreach my_arch_config,$(ARCH_CONFIGS_EMBEDDED),$(foreach my_product_config,$(DEVICEMAP_PRODUCTS_OSX_$(my_arch_config)),$(call function_lookup_product,$(my_product_config)))),$(foreach my_kernel_config,$(KERNEL_CONFIGS_EMBEDDED),$(my_kernel_config) $(subst ;, ,$(my_devicemap_config)))) | |
249 | TARGET_CONFIGS_ALIASES := $(foreach my_devicemap_config,$(foreach my_arch_config,$(ARCH_CONFIGS_EMBEDDED),$(foreach my_product_config,$(DEVICEMAP_PRODUCTS_OSX_$(my_arch_config)),$(call function_lookup_product_alias,$(my_product_config)))),$(foreach my_kernel_config,$(KERNEL_CONFIGS_EMBEDDED),$(my_kernel_config) $(subst ;, ,$(my_devicemap_config)))) | |
250 | else | |
251 | # generate TARGET_CONFIGS using KERNEL_CONFIGS and ARCH_CONFIGS and MACHINE_CONFIGS (which defaults to "DEFAULT") | |
252 | TARGET_CONFIGS := $(foreach my_kern_config, $(KERNEL_CONFIGS), $(foreach my_arch_config, $(ARCH_CONFIGS), $(foreach my_machine_config, $(MACHINE_CONFIGS), $(my_kern_config) $(my_arch_config) $(my_machine_config)))) | |
253 | TARGET_CONFIGS_ALIASES := | |
254 | endif | |
255 | endif | |
256 | ||
257 | ifeq ($(TARGET_CONFIGS),) | |
258 | $(error No TARGET_CONFIGS specified) | |
259 | endif | |
260 | ||
261 | TARGET_CONFIGS_UC := $(strip $(shell printf "%s" "$(TARGET_CONFIGS)" | $(TR) a-z A-Z)) | |
262 | TARGET_CONFIGS_ALIASES_UC := $(strip $(shell printf "%s" "$(TARGET_CONFIGS_ALIASES)" | $(TR) a-z A-Z)) | |
263 | ||
264 | # | |
265 | # Build Configurations | |
266 | # | |
267 | # TARGET_CONFIGS is unwieldy for use in Makefiles. Convert them to | |
268 | # "build configurations" which are tuples joined by "^". For | |
269 | # example, "RELEASE I386 DEFAULT DEVELOPMENT ARM DEFAULT" becomes | |
270 | # "RELEASE^I386^NONE DEVELOPMENT^ARM^T8002", which can be looped | |
271 | # over trivially. PRIMARY_BUILD_CONFIGS is the first config | |
272 | # for each architecture, used primarily for machine-dependent recursion. | |
273 | ||
274 | BUILD_CONFIGS = $(call function_create_build_configs, $(TARGET_CONFIGS_UC)) | |
275 | ||
276 | PRIMARY_ARCHS = $(strip $(sort $(foreach build_config, $(BUILD_CONFIGS), $(call function_extract_arch_config_from_build_config, $(build_config))))) | |
277 | PRIMARY_BUILD_CONFIGS = $(strip $(foreach arch, $(PRIMARY_ARCHS), $(firstword $(foreach build_config, $(BUILD_CONFIGS), $(if $(filter $(arch),$(call function_extract_arch_config_from_build_config, $(build_config))), $(build_config), ))))) | |
278 | NON_PRIMARY_BUILD_CONFIGS = $(strip $(filter-out $(PRIMARY_BUILD_CONFIGS), $(BUILD_CONFIGS))) | |
279 | FIRST_BUILD_CONFIG = $(firstword $(BUILD_CONFIGS)) | |
280 | ||
281 | ifneq ($(TARGET_CONFIGS_ALIASES_UC),) | |
282 | ALIAS_CONFIGS = $(call function_create_alias_configs, $(TARGET_CONFIGS_ALIASES_UC)) | |
283 | else | |
284 | ALIAS_CONFIGS = | |
285 | endif | |
286 | ||
287 | # $(warning PRIMARY_ARCHS is $(PRIMARY_ARCHS)) | |
288 | # $(warning TARGET_CONFIGS is $(TARGET_CONFIGS)) | |
289 | # $(warning BUILD_CONFIGS is $(BUILD_CONFIGS)) | |
290 | # $(warning PRIMARY_BUILD_CONFIGS is $(PRIMARY_BUILD_CONFIGS)) | |
291 | # $(warning NON_PRIMARY_BUILD_CONFIGS is $(NON_PRIMARY_BUILD_CONFIGS)) | |
292 | # $(warning TARGET_CONFIGS_ALIASES is $(TARGET_CONFIGS_ALIASES)) | |
293 | # $(warning ALIAS_CONFIGS is $(ALIAS_CONFIGS)) | |
294 | ||
295 | MEMORY_SIZE := $(shell /usr/sbin/sysctl -n hw.memsize) | |
296 | ||
297 | # Assume LTO scaling by default, unless it is being explicitly passed on the command-line | |
298 | LARGE_BUILD_FOOTPRINT := $(if $(BUILD_LTO),$(BUILD_LTO),1) | |
299 | ||
300 | ifeq ($(LARGE_BUILD_FOOTPRINT),1) | |
301 | RAM_PER_KERNEL_BUILD := 4294967296 | |
302 | else | |
303 | RAM_PER_KERNEL_BUILD := 268435456 | |
304 | endif | |
305 | ||
306 | KERNEL_BUILDS_IN_PARALLEL := $(shell if [ $(MEMORY_SIZE) -le $$((1 * $(RAM_PER_KERNEL_BUILD))) ]; then echo 1; elif [ $(MEMORY_SIZE) -gt $$(($(SYSCTL_HW_PHYSICALCPU) * $(RAM_PER_KERNEL_BUILD))) ]; then echo $(SYSCTL_HW_PHYSICALCPU); else expr $(MEMORY_SIZE) / $(RAM_PER_KERNEL_BUILD); fi ) | |
307 | # $(warning Building $(KERNEL_BUILDS_IN_PARALLEL) kernels in parallel) | |
308 | ||
309 | # | |
310 | # TOP_LEVEL_EACH_BUILD_CONFIG_BOOTSTRAP_template | |
311 | # | |
312 | # $(1) is the name of the makefile target to invoke for the each build config | |
313 | # after setting up the parallel hierarchy in the TARGET directory | |
314 | # $(2) is an optional suffix on the TARGET directory, which might even be | |
315 | # "/.." | |
316 | # $(3) are any dependencies for the bootstrap target | |
317 | # $(4) are any dependencies that are expanded per-build config to another bootstrap target | |
318 | # $(5) is how many build configurations to build in parallel | |
319 | # $(6) is which build configs to build in parallel | |
320 | # | |
321 | # Since building many configurations in parallel may overwhelm the system, | |
322 | # we try to throttle behavior into more managable S "stripes" of N/S | |
323 | # configurations by generating sequential dependencies between configs | |
324 | # in each stripe. That ensures that only S kernel builds are occurring | |
325 | # at once at any point in time | |
326 | ||
327 | define TOP_LEVEL_EACH_BUILD_CONFIG_BOOTSTRAP_template | |
328 | ||
329 | # Create a list of synthesized targets for each build config | |
330 | $(1)_bootstrap_target_list = $$(addprefix $(1)_bootstrap_,$(6)) | |
331 | ||
332 | .PHONY: $$($(1)_bootstrap_target_list) | |
333 | ||
334 | $(1)_generated_stripe_dependencies = $$(call _function_generate_stripe_groupings,$(1),$(5),$(call reverse,$(6))) | |
335 | ifeq ($$(VERBOSE_GENERATED_MAKE_FRAGMENTS),YES) | |
336 | $$(warning Generate makefile fragment: $$($(1)_generated_stripe_dependencies)) | |
337 | endif | |
338 | $$(eval $$($(1)_generated_stripe_dependencies)) | |
339 | ||
340 | $$($(1)_bootstrap_target_list): $(1)_bootstrap_% : $(1)_stripe_dep_for_% $$(addsuffix _bootstrap_%,$(4)) $(3) | |
341 | $$(_v)$$(MKDIR) $${OBJROOT}/$$(call function_convert_build_config_to_objdir,$$(patsubst $(1)_bootstrap_%,%,$$@))$(2) | |
342 | $$(_v)$${MAKE} \ | |
343 | -C $${OBJROOT}/$$(call function_convert_build_config_to_objdir,$$(patsubst $(1)_bootstrap_%,%,$$@))$(2) \ | |
344 | -f $${SRCROOT}/Makefile \ | |
345 | CURRENT_KERNEL_CONFIG=$$(call function_extract_kernel_config_from_build_config,$$(patsubst $(1)_bootstrap_%,%,$$@)) \ | |
346 | CURRENT_ARCH_CONFIG=$$(call function_extract_arch_config_from_build_config,$$(patsubst $(1)_bootstrap_%,%,$$@)) \ | |
347 | CURRENT_MACHINE_CONFIG=$$(call function_extract_machine_config_from_build_config,$$(patsubst $(1)_bootstrap_%,%,$$@)) \ | |
348 | CURRENT_BUILD_CONFIG=$$(patsubst $(1)_bootstrap_%,%,$$@) \ | |
349 | PRIMARY_BUILD_CONFIGS="$(PRIMARY_BUILD_CONFIGS)" \ | |
350 | SOURCE=$${SRCROOT}/ \ | |
351 | RELATIVE_SOURCE_PATH=. \ | |
352 | TARGET=$${OBJROOT}/$$(call function_convert_build_config_to_objdir,$$(patsubst $(1)_bootstrap_%,%,$$@))$(2)/ \ | |
353 | OBJPATH=$${OBJROOT}/$$(call function_convert_build_config_to_objdir,$$(patsubst $(1)_bootstrap_%,%,$$@)) \ | |
354 | $(1) | |
355 | ||
356 | .PHONY: $(1)_bootstrap | |
357 | ||
358 | $(1)_bootstrap: $$($(1)_bootstrap_target_list) | |
359 | endef | |
360 | ||
361 | # | |
362 | # TOP_LEVEL_STRIPE_DEPENDENCY_template | |
363 | # | |
364 | # $(1) is the Makefile target we are building for | |
365 | # $(2) is the build config that must build first | |
366 | # $(3) is the build config that must build after $(2) | |
367 | ||
368 | define TOP_LEVEL_STRIPE_DEPENDENCY_template | |
369 | ||
370 | .PHONY: $(1)_stripe_dep_for_$(3) | |
371 | ||
372 | $(1)_stripe_dep_for_$(3): $(if $(2),$(1)_bootstrap_$(2)) | |
373 | ||
374 | endef | |
375 | ||
376 | # $(1) is the Makefile target we are building for | |
377 | # $(2) is the stripe size | |
378 | # $(3) is the list of the build configs in the current group | |
379 | # $(4) is the list of remaining build configs | |
380 | _function_generate_stripe_groupings_recursive = $(foreach stripe_index,$(call sequence,$(2)),$(if $(word $(stripe_index),$(4)),$(call TOP_LEVEL_STRIPE_DEPENDENCY_template,$(1),$(word $(stripe_index),$(3)),$(word $(stripe_index),$(4))))) $(if $(word $(call increment,$(2)),$(4)),$(call _function_generate_stripe_groupings_recursive,$(1),$(2),$(wordlist 1,$(2),$(4)),$(wordlist $(call increment,$(2)),$(words $(4)),$(4)))) | |
381 | ||
382 | # $(1) is the Makefile target we are building for | |
383 | # $(2) is the stripe size | |
384 | # $(3) is the list of the build configs | |
385 | _function_generate_stripe_groupings = $(call _function_generate_stripe_groupings_recursive,$(1),$(2),,$(3)) | |
386 | ||
387 | # | |
388 | # Setup pass for build system tools | |
389 | # | |
390 | ||
391 | generated_top_level_build_setup = $(call TOP_LEVEL_EACH_BUILD_CONFIG_BOOTSTRAP_template,build_setup,/..,,,1,$(FIRST_BUILD_CONFIG)) | |
392 | ifeq ($(VERBOSE_GENERATED_MAKE_FRAGMENTS),YES) | |
393 | $(warning Generate makefile fragment: $(generated_top_level_build_setup)) | |
394 | endif | |
395 | $(eval $(generated_top_level_build_setup)) | |
396 | ||
397 | .PHONY: setup | |
398 | ||
399 | # invalidate current kernel in $(SYMROOT). Timestamp must be +1 from a previous kernel build | |
400 | setup: build_setup_bootstrap | |
401 | $(_v)$(TOUCH) $(OBJROOT)/.mach_kernel.timestamp.new | |
402 | $(_v)while [ \! $(OBJROOT)/.mach_kernel.timestamp.new -nt $(OBJROOT)/.mach_kernel.timestamp ]; do \ | |
403 | $(SLEEP) 1; \ | |
404 | $(TOUCH) $(OBJROOT)/.mach_kernel.timestamp.new; \ | |
405 | done | |
406 | $(_v)$(MV) $(OBJROOT)/.mach_kernel.timestamp.new $(OBJROOT)/.mach_kernel.timestamp | |
407 | $(_v)$(TOUCH) $(OBJROOT)/.symbolset.timestamp.new | |
408 | $(_v)while [ \! $(OBJROOT)/.symbolset.timestamp.new -nt $(OBJROOT)/.symbolset.timestamp ]; do \ | |
409 | $(SLEEP) 1; \ | |
410 | $(TOUCH) $(OBJROOT)/.symbolset.timestamp.new; \ | |
411 | done | |
412 | $(_v)$(MV) $(OBJROOT)/.symbolset.timestamp.new $(OBJROOT)/.symbolset.timestamp | |
413 | ||
414 | # | |
415 | # Install kernel header files | |
416 | # | |
417 | .PHONY: exporthdrs exporthdrs_mi exporthdrs_md | |
418 | ||
419 | exporthdrs: exporthdrs_mi exporthdrs_md | |
420 | ||
421 | # | |
422 | # Install machine independent kernel header files | |
423 | # | |
424 | ||
425 | generated_top_level_build_exporthdrs_mi = $(call TOP_LEVEL_EACH_BUILD_CONFIG_BOOTSTRAP_template,build_exporthdrs_mi,,setup,,1,$(FIRST_BUILD_CONFIG)) | |
426 | ifeq ($(VERBOSE_GENERATED_MAKE_FRAGMENTS),YES) | |
427 | $(warning Generate makefile fragment: $(generated_top_level_build_exporthdrs_mi)) | |
428 | endif | |
429 | $(eval $(generated_top_level_build_exporthdrs_mi)) | |
430 | ||
431 | exporthdrs_mi: build_exporthdrs_mi_bootstrap | |
432 | ||
433 | # | |
434 | # Install machine dependent kernel header files | |
435 | # | |
436 | ||
437 | generated_top_level_build_exporthdrs_md = $(call TOP_LEVEL_EACH_BUILD_CONFIG_BOOTSTRAP_template,build_exporthdrs_md,,setup,,$(KERNEL_BUILDS_IN_PARALLEL),$(PRIMARY_BUILD_CONFIGS)) | |
438 | ifeq ($(VERBOSE_GENERATED_MAKE_FRAGMENTS),YES) | |
439 | $(warning Generate makefile fragment: $(generated_top_level_build_exporthdrs_md)) | |
440 | endif | |
441 | $(eval $(generated_top_level_build_exporthdrs_md)) | |
442 | ||
443 | exporthdrs_md: build_exporthdrs_md_bootstrap | |
444 | ||
445 | # | |
446 | # Install kernel header files | |
447 | # | |
448 | ||
449 | .PHONY: installhdrs installhdrs_mi installhdrs_md | |
450 | ||
451 | ifneq ($(filter $(RC_ProjectName),xnu_debug),) | |
452 | installhdrs: | |
453 | @: | |
454 | else ifneq ($(filter $(RC_ProjectName),xnu_kasan),) | |
455 | installhdrs: | |
456 | @: | |
457 | else | |
458 | ||
459 | installhdrs: installhdrs_mi installhdrs_md | |
460 | endif | |
461 | ||
462 | .PHONY: installhdrs_embedded installhdrs_release_embedded installhdrs_development_embedded installhdrs_desktop | |
463 | ||
464 | installhdrs_embedded installhdrs_release_embedded installhdrs_desktop: installhdrs | |
465 | ||
466 | installhdrs_development_embedded: | |
467 | ||
468 | # | |
469 | # Install machine independent header files | |
470 | # | |
471 | ||
472 | generated_top_level_build_installhdrs_mi = $(call TOP_LEVEL_EACH_BUILD_CONFIG_BOOTSTRAP_template,build_installhdrs_mi,,setup,build_exporthdrs_mi,1,$(FIRST_BUILD_CONFIG)) | |
473 | ifeq ($(VERBOSE_GENERATED_MAKE_FRAGMENTS),YES) | |
474 | $(warning Generate makefile fragment: $(generated_top_level_build_installhdrs_mi)) | |
475 | endif | |
476 | $(eval $(generated_top_level_build_installhdrs_mi)) | |
477 | ||
478 | installhdrs_mi: build_installhdrs_mi_bootstrap | |
479 | ||
480 | # | |
481 | # Install machine dependent kernel header files | |
482 | # | |
483 | ||
484 | generated_top_level_build_installhdrs_md = $(call TOP_LEVEL_EACH_BUILD_CONFIG_BOOTSTRAP_template,build_installhdrs_md,,setup,build_exporthdrs_md,$(KERNEL_BUILDS_IN_PARALLEL),$(PRIMARY_BUILD_CONFIGS)) | |
485 | ifeq ($(VERBOSE_GENERATED_MAKE_FRAGMENTS),YES) | |
486 | $(warning Generate makefile fragment: $(generated_top_level_build_installhdrs_md)) | |
487 | endif | |
488 | $(eval $(generated_top_level_build_installhdrs_md)) | |
489 | ||
490 | installhdrs_md: build_installhdrs_md_bootstrap | |
491 | ||
492 | .PHONY: install_textfiles install_textfiles_mi install_textfiles_md | |
493 | ||
494 | install_textfiles: install_textfiles_mi install_textfiles_md | |
495 | ||
496 | # | |
497 | # Install machine independent text files (man pages, dtrace scripts, etc.) | |
498 | # | |
499 | ||
500 | generated_top_level_textfiles_install_mi = $(call TOP_LEVEL_EACH_BUILD_CONFIG_BOOTSTRAP_template,textfiles_install_mi,,setup,,1,$(FIRST_BUILD_CONFIG)) | |
501 | ifeq ($(VERBOSE_GENERATED_MAKE_FRAGMENTS),YES) | |
502 | $(warning Generate makefile fragment: $(generated_top_level_textfiles_install_mi)) | |
503 | endif | |
504 | $(eval $(generated_top_level_textfiles_install_mi)) | |
505 | ||
506 | install_textfiles_mi: textfiles_install_mi_bootstrap | |
507 | ||
508 | # | |
509 | # Install machine dependent text files (man pages, dtrace scripts, etc.) | |
510 | # | |
511 | ||
512 | generated_top_level_textfiles_install_md = $(call TOP_LEVEL_EACH_BUILD_CONFIG_BOOTSTRAP_template,textfiles_install_md,,setup,,$(KERNEL_BUILDS_IN_PARALLEL),$(PRIMARY_BUILD_CONFIGS)) | |
513 | ifeq ($(VERBOSE_GENERATED_MAKE_FRAGMENTS),YES) | |
514 | $(warning Generate makefile fragment: $(generated_top_level_textfiles_install_md)) | |
515 | endif | |
516 | $(eval $(generated_top_level_textfiles_install_md)) | |
517 | ||
518 | install_textfiles_md: textfiles_install_md_bootstrap | |
519 | ||
520 | # | |
521 | # Build all architectures for all Configuration/Architecture options | |
522 | # | |
523 | ||
524 | generated_top_level_build_all = $(call TOP_LEVEL_EACH_BUILD_CONFIG_BOOTSTRAP_template,build_all,,setup exporthdrs,,$(KERNEL_BUILDS_IN_PARALLEL),$(BUILD_CONFIGS)) | |
525 | ifeq ($(VERBOSE_GENERATED_MAKE_FRAGMENTS),YES) | |
526 | $(warning Generate makefile fragment: $(generated_top_level_build_all)) | |
527 | endif | |
528 | $(eval $(generated_top_level_build_all)) | |
529 | ||
530 | .PHONY: build | |
531 | ||
532 | build: build_all_bootstrap | |
533 | ||
534 | # | |
535 | # Post-process build results | |
536 | # | |
537 | ||
538 | generated_top_level_config_all = $(call TOP_LEVEL_EACH_BUILD_CONFIG_BOOTSTRAP_template,config_all,,setup,build_all,$(KERNEL_BUILDS_IN_PARALLEL),$(BUILD_CONFIGS)) | |
539 | ifeq ($(VERBOSE_GENERATED_MAKE_FRAGMENTS),YES) | |
540 | $(warning Generate makefile fragment: $(generated_top_level_config_all)) | |
541 | endif | |
542 | $(eval $(generated_top_level_config_all)) | |
543 | ||
544 | .PHONY: all config | |
545 | ||
546 | all config: config_all_bootstrap | |
547 | ||
548 | .PHONY: all_embedded all_release_embedded all_development_embedded all_desktop | |
549 | ||
550 | all_embedded all_release_embedded all_development_embedded all_desktop: all | |
551 | ||
552 | # | |
553 | # Install kernel files | |
554 | # | |
555 | ||
556 | generated_top_level_build_install_primary = $(call TOP_LEVEL_EACH_BUILD_CONFIG_BOOTSTRAP_template,build_install_primary,,setup,config_all,1,$(PRIMARY_BUILD_CONFIGS)) | |
557 | ifeq ($(VERBOSE_GENERATED_MAKE_FRAGMENTS),YES) | |
558 | $(warning Generate makefile fragment: $(generated_top_level_build_install_primary)) | |
559 | endif | |
560 | $(eval $(generated_top_level_build_install_primary)) | |
561 | ||
562 | .PHONY: install_primary | |
563 | ||
564 | install_primary: build_install_primary_bootstrap | |
565 | ||
566 | generated_top_level_build_install_non_primary = $(call TOP_LEVEL_EACH_BUILD_CONFIG_BOOTSTRAP_template,build_install_non_primary,,setup,config_all,$(KERNEL_BUILDS_IN_PARALLEL),$(NON_PRIMARY_BUILD_CONFIGS)) | |
567 | ifeq ($(VERBOSE_GENERATED_MAKE_FRAGMENTS),YES) | |
568 | $(warning Generate makefile fragment: $(generated_top_level_build_install_non_primary)) | |
569 | endif | |
570 | $(eval $(generated_top_level_build_install_non_primary)) | |
571 | ||
572 | .PHONY: install_non_primary | |
573 | ||
574 | install_non_primary: build_install_non_primary_bootstrap | |
575 | ||
576 | generated_top_level_config_install = $(call TOP_LEVEL_EACH_BUILD_CONFIG_BOOTSTRAP_template,config_install,,setup,config_all,1,$(PRIMARY_BUILD_CONFIGS)) | |
577 | ifeq ($(VERBOSE_GENERATED_MAKE_FRAGMENTS),YES) | |
578 | $(warning Generate makefile fragment: $(generated_top_level_config_install)) | |
579 | endif | |
580 | $(eval $(generated_top_level_config_install)) | |
581 | ||
582 | .PHONY: install_config final_touch_config_timestamps | |
583 | ||
584 | install_config: config_install_bootstrap final_touch_config_timestamps | |
585 | ||
586 | # Tell the next build the latest timestamp of any potential file in DSTROOT/SYMROOT | |
587 | final_touch_config_timestamps: config_install_bootstrap | |
588 | $(_v)$(TOUCH) $(OBJROOT)/.symbolset.timestamp | |
589 | ||
590 | # | |
591 | # Aggregate install targets, which install everything appropriate for the current build alias/make target | |
592 | # | |
593 | ||
594 | .PHONY: install | |
595 | ||
596 | ifneq ($(filter $(RC_ProjectName),xnu_debug),) | |
597 | install: install_kernels | |
598 | else ifneq ($(filter $(RC_ProjectName),xnu_kasan),) | |
599 | install: install_config install_kernels | |
600 | else ifneq ($(filter $(RC_ProjectName),xnu_headers_Sim),) | |
601 | install: installhdrs | |
602 | else ifneq ($(filter $(RC_ProjectName),xnu_headers_host),) | |
603 | install: installhdrs | |
604 | export INSTALLHDRS_SKIP_HOST=YES | |
605 | else ifneq ($(filter $(RC_ProjectName),xnu_headers_driverkit),) | |
606 | install: installhdrs_desktop | |
607 | else | |
608 | ||
609 | install: installhdrs install_textfiles install_config install_kernels install_aliases | |
610 | endif | |
611 | ||
612 | .PHONY: install_embedded install_release_embedded install_development_embedded install_desktop | |
613 | ||
614 | # By default, all kernel files, headers, text files, and pseudo-kexts are installed | |
615 | install_embedded install_release_embedded install_desktop: install | |
616 | ||
617 | # These special configs only install the kernel files | |
618 | install_development_embedded: install_kernels install_aliases | |
619 | ||
620 | .PHONY: install_kernels final_touch_kernel_timestamps install_aliases | |
621 | ||
622 | install_kernels: build_install_primary_bootstrap build_install_non_primary_bootstrap final_touch_kernel_timestamps | |
623 | ||
624 | # Tell the next build the latest timestamp of any potential file in DSTROOT/SYMROOT | |
625 | final_touch_kernel_timestamps: build_install_primary_bootstrap build_install_non_primary_bootstrap | |
626 | $(_v)$(TOUCH) $(OBJROOT)/.mach_kernel.timestamp | |
627 | @echo "done building xnu" | |
628 | ||
629 | # Copy kernels that are aliases of another configuration | |
630 | generated_top_level_install_alias = $(call TOP_LEVEL_EACH_BUILD_CONFIG_BOOTSTRAP_template,install_alias,,install_kernels,,$(KERNEL_BUILDS_IN_PARALLEL),$(ALIAS_CONFIGS)) | |
631 | ifeq ($(VERBOSE_GENERATED_MAKE_FRAGMENTS),YES) | |
632 | $(warning Generate makefile fragment: $(generated_top_level_install_alias)) | |
633 | endif | |
634 | $(eval $(generated_top_level_install_alias)) | |
635 | ||
636 | install_aliases: install_alias_bootstrap | |
637 | ||
638 | # | |
639 | # Install source tree | |
640 | # | |
641 | .PHONY: installsrc | |
642 | ||
643 | installsrc: | |
644 | @echo INSTALLSRC $(SRCROOT) | |
645 | $(_v)$(MKDIR) $(SRCROOT) | |
646 | $(_v)$(FIND) -x . \! \( \( -name BUILD -o -name .svn -o -name .git -o -name cscope.\* -o -name \*~ \) -prune \) -print0 | $(PAX) -rw -p a -d0 $(SRCROOT) | |
647 | $(_v)$(CHMOD) -R go+rX $(SRCROOT) | |
648 | ||
649 | ||
650 | # | |
651 | # Clean up source tree | |
652 | # | |
653 | .PHONY: clean | |
654 | ||
655 | CLEAN_RM_DIRS= $(OBJROOT) $(SYMROOT) $(DSTROOT) \ | |
656 | $(SRCROOT)/tools/test/BUILD \ | |
657 | $(SRCROOT)/tools/tests/darwintests/build \ | |
658 | $(SRCROOT)/tools/tests/testkext/build \ | |
659 | $(SRCROOT)/libkdd/build \ | |
660 | $(SRCROOT)/tools/tests/unit_tests/BUILD \ | |
661 | $(SRCROOT)/tools/tests/execperf/BUILD \ | |
662 | $(SRCROOT)/tools/tests/packetdrill/BUILD \ | |
663 | $(SRCROOT)/tools/tests/perf_index/BUILD | |
664 | ||
665 | CLEAN_ACTION_DIRS= $(SRCROOT)/tools/tests/MPMMTest \ | |
666 | $(SRCROOT)/tools/tests/TLBcoherency \ | |
667 | $(SRCROOT)/tools/tests/kqueue_tests \ | |
668 | $(SRCROOT)/tools/tests/mktimer \ | |
669 | $(SRCROOT)/tools/tests/zero-to-n \ | |
670 | $(SRCROOT)/tools/tests/personas | |
671 | ||
672 | clean: | |
673 | @: | |
674 | $(_v)rm -f cscope.* 2> /dev/null | |
675 | $(_v)rm -f TAGS 2> /dev/null | |
676 | $(_v)for cdir in $(CLEAN_RM_DIRS); do \ | |
677 | if [ -d $${cdir} ] ; then \ | |
678 | echo "Removing $${cdir}"; \ | |
679 | rm -fr $${cdir} 2> /dev/null || true ; \ | |
680 | fi ; \ | |
681 | done | |
682 | ||
683 | $(_v)for mcdir in $(CLEAN_ACTION_DIRS); do \ | |
684 | make -C $${mcdir} clean; \ | |
685 | done | |
686 | ||
687 | ||
688 | # | |
689 | # Build source file list for cscope database and tags | |
690 | # | |
691 | .PHONY: cscope.files | |
692 | ||
693 | cscope.files: | |
694 | @echo "Building file list for cscope and tags" | |
695 | @find . -name '*.h' -type f | grep -v ^..BUILD > _cscope.files 2> /dev/null | |
696 | @find . -name '*.defs' -type f | grep -v ^..BUILD >> _cscope.files 2> /dev/null | |
697 | @find . -name '*.c' -type f | grep -v ^..BUILD >> _cscope.files 2> /dev/null | |
698 | @find . -name '*.cpp' -type f | grep -v ^..BUILD >> _cscope.files 2> /dev/null | |
699 | @find . -name '*.s' -type f | grep -v ^..BUILD >> _cscope.files 2> /dev/null | |
700 | @find . -name '*.h.template' -type f | grep -v ^..BUILD >> _cscope.files 2> /dev/null | |
701 | @cat $(OBJROOT)/cscope.genhdrs/* >> _cscope.files 2> /dev/null || true | |
702 | @echo -k -q -c > cscope.files 2> /dev/null | |
703 | @sort -u < _cscope.files >> cscope.files 2> /dev/null | |
704 | @rm -f _cscope.files _cscope.files2 2> /dev/null | |
705 | ||
706 | # | |
707 | # Build cscope database | |
708 | # | |
709 | cscope: cscope.files | |
710 | @echo "Building cscope database" | |
711 | @cscope -bvU 2> /dev/null | |
712 | ||
713 | # | |
714 | # Build tags | |
715 | # | |
716 | tags: cscope.files | |
717 | @echo "Building ctags" | |
718 | @-sed 1d cscope.files | xargs ctags -dtw 2> /dev/null || \ | |
719 | echo "Phantom files detected!" 2>&1 > /dev/null | |
720 | @-[ -f TAGS ] || ${MAKE} -f $(firstword $(MAKEFILE_LIST)) TAGS | |
721 | ||
722 | TAGS: cscope.files | |
723 | @echo "Building etags" | |
724 | @-cat cscope.files | etags -l auto -S - 2> /dev/null | |
725 | @rm -f cscope.files 2> /dev/null | |
726 | ||
727 | ||
728 | .PHONY: help | |
729 | ||
730 | help: | |
731 | @cat README.md | |
732 | ||
733 | .PHONY: print_exports | |
734 | ||
735 | print_exports: | |
736 | $(_v)printenv | sort | |
737 | ||
738 | generated_top_level_print_exports = $(call TOP_LEVEL_EACH_BUILD_CONFIG_BOOTSTRAP_template,print_exports,,,,1,$(FIRST_BUILD_CONFIG)) | |
739 | ifeq ($(VERBOSE_GENERATED_MAKE_FRAGMENTS),YES) | |
740 | $(warning Generate makefile fragment: $(generated_top_level_print_exports)) | |
741 | endif | |
742 | $(eval $(generated_top_level_print_exports)) | |
743 | ||
744 | .PHONY: print_exports_first_build_config | |
745 | ||
746 | print_exports_first_build_config: print_exports_bootstrap | |
747 | ||
748 | # vim: set ft=make: |