xref: /xnu-10002.41.9/makedefs/MakeInc.cmd (revision 699cd48037512bf4380799317ca44ca453c82f57)
1# -*- mode: makefile;-*-
2#
3# Copyright (C) 1999-2020 Apple Inc. All rights reserved.
4#
5# MakeInc.cmd contains command paths for use during
6# the build, as well as make fragments and text
7# strings that may be evaluated as utility functions.
8#
9
10#
11# Commands for the build environment
12#
13
14#
15# Build Logging and Verbosity
16#
17
18ifeq ($(RC_XBS),YES)
19	VERBOSE = YES
20else
21	VERBOSE = NO
22endif
23
24BASH = bash
25
26ECHO = echo
27
28ERR = $(ECHO) > /dev/stderr
29PRINTF = printf
30
31QUIET ?= 0
32ifneq ($(QUIET),0)
33	PRINTF = printf > /dev/null
34	ifeq ($(VERBOSE),YES)
35		override VERBOSE = NO
36	endif
37endif
38
39# Helper functions for logging operations.
40LOG_PFX_LEN = 15
41LOG_PFX_LEN_ADJ = $(LOG_PFX_LEN)
42LOG = $(PRINTF) "$2%$4s$(Color0) $3%s$(Color0)\n" "$1"
43
44CONCISE ?= 0
45ifneq ($(CONCISE),0)
46	# Concise logging puts all logs on the same line (CSI K to clear and
47	# carriage return).
48	LOG = $(PRINTF) "$2%$4s$(Color0) $3%s$(Color0)\033[K\r" "$1"
49endif
50
51_LOG_COMP = $(call LOG,$1,$(ColorC),$(ColorF),$(LOG_PFX_LEN_ADJ))
52_LOG_HOST = $(call LOG,$1,$(ColorH),$(ColorF),$(LOG_PFX_LEN))
53_LOG_HOST_LINK = $(call LOG,$1,$(ColorH),$(ColorLF),$(LOG_PFX_LEN))
54
55# Special operations.
56LOG_LDFILELIST = $(call LOG,LDFILELIST,$(ColorL),$(ColorLF),$(LOG_PFX_LEN_ADJ))
57LOG_MIG = $(call LOG,MIG,$(ColorM),$(ColorF),$(LOG_PFX_LEN_ADJ))
58LOG_LD = $(call LOG,LD,$(ColorL),$(ColorF),$(LOG_PFX_LEN_ADJ))
59LOG_ALIGN = $(call LOG,--------->,$(Color0),$(Color0),$(LOG_PFX_LEN))
60
61# Compiling/machine-specific operations.
62LOG_CC = $(call _LOG_COMP,CC)
63LOG_CXX = $(call _LOG_COMP,C++)
64LOG_AS = $(call _LOG_COMP,AS)
65LOG_LTO = $(call _LOG_COMP,LTO)
66LOG_SYMBOLSET = $(call _LOG_COMP,SYMSET)
67LOG_SYMBOLSETPLIST = $(call _LOG_COMP,SYMSETPLIST)
68
69# Host-side operations.
70LOG_TIGHTBEAMC = $(call _LOG_HOST,TIGHTBEAMC)
71LOG_IIG = $(call _LOG_HOST,IIG)
72LOG_HOST_CC = $(call _LOG_HOST,CC)
73LOG_HOST_LD = $(call _LOG_HOST,LD)
74LOG_HOST_CODESIGN = $(call _LOG_HOST,CODESIGN)
75LOG_HOST_BISON = $(call _LOG_HOST,BISON)
76LOG_HOST_FLEX = $(call _LOG_HOST,FLEX)
77LOG_INSTALL = $(call _LOG_HOST,INSTALL)
78LOG_INSTALLVARIANT = $(call _LOG_HOST,INSTALLVARIANT)
79LOG_INSTALLSYM = $(call _LOG_HOST,INSTALLSYM)
80LOG_INSTALLHDR = $(call _LOG_HOST,INSTALLHDR)
81LOG_INSTALLMACROS = $(call _LOG_HOST,INSTALLMACROS)
82LOG_INSTALLPY = $(call _LOG_HOST,INSTALLPY)
83LOG_MAN = $(call _LOG_HOST,MAN)
84LOG_MANLINK = $(call _LOG_HOST,MANLINK)
85LOG_ALIAS = $(call _LOG_HOST,ALIAS)
86LOG_STRIP = $(call _LOG_HOST,STRIP)
87LOG_DSYMUTIL = $(call _LOG_HOST,DSYMUTIL)
88LOG_LIBTOOL = $(call _LOG_HOST,LIBTOOL)
89LOG_FILEPREP = $(call _LOG_HOST,FILEPREP)
90
91# Host-side linking operations.
92LOG_GENASSYM = $(call _LOG_HOST_LINK,GENASSYM)
93LOG_GENERATE= $(call _LOG_HOST_LINK,GENERATE)
94LOG_CTFCONVERT = $(call _LOG_HOST_LINK,CTFCONVERT)
95LOG_CTFMERGE = $(call _LOG_HOST_LINK,CTFMERGE)
96LOG_CTFINSERT = $(call _LOG_HOST_LINK,CTFINSERT)
97LOG_DSYMUTIL = $(call _LOG_HOST_LINK,DSYMUTIL)
98LOG_SUPPORTED_KPI = $(call _LOG_HOST_LINK,SUPPORTED_KPI)
99
100ifeq ($(VERBOSE),YES)
101	_v =
102	_vstdout =
103	_vstderr =
104	XCRUN = /usr/bin/xcrun -verbose
105else
106	_v = @
107	_vstdout = > /dev/null
108	_vstderr = 2> /dev/null
109	XCRUN = /usr/bin/xcrun
110endif
111
112VERBOSE_GENERATED_MAKE_FRAGMENTS = NO
113
114#
115# Defaults
116#
117
118SDKROOT ?= macosx
119HOST_SDKROOT ?= macosx
120
121# SDKROOT may be passed as a shorthand like "iphoneos.internal". We
122# must resolve these to a full path and override SDKROOT.
123
124ifeq ($(origin SDKROOT_RESOLVED),undefined)
125export SDKROOT_RESOLVED := $(shell $(XCRUN) -sdk $(SDKROOT) -show-sdk-path)
126ifeq ($(strip $(SDKROOT)_$(SDKROOT_RESOLVED)),/_)
127export SDKROOT_RESOLVED := /
128endif
129endif
130override SDKROOT = $(SDKROOT_RESOLVED)
131
132ifeq ($(origin HOST_SDKROOT_RESOLVED),undefined)
133export HOST_SDKROOT_RESOLVED := $(shell $(XCRUN) -sdk $(HOST_SDKROOT) -show-sdk-path)
134ifeq ($(strip $(HOST_SDKROOT_RESOLVED)),)
135export HOST_SDKROOT_RESOLVED := /
136endif
137endif
138override HOST_SDKROOT = $(HOST_SDKROOT_RESOLVED)
139
140ifeq ($(origin SDKVERSION),undefined)
141     export SDKVERSION := $(shell $(XCRUN) -sdk $(SDKROOT) -show-sdk-version)
142endif
143
144ifeq ($(origin PLATFORM),undefined)
145	export PLATFORMPATH := $(shell $(XCRUN) -sdk $(SDKROOT) -show-sdk-platform-path)
146	export PLATFORM := $(shell echo $(PLATFORMPATH) | sed 's,^.*/\([^/]*\)\.platform$$,\1,' | sed 's,\.[^.]*$$,,')
147	ifeq ($(PLATFORM),)
148		export PLATFORM := MacOSX
149	else ifeq ($(shell echo $(PLATFORM) | tr A-Z a-z),watchos)
150		export PLATFORM := WatchOS
151	endif
152endif
153
154ifeq ($(PLATFORM),DriverKit)
155	ifeq ($(origin COHORT_SDKROOT_RESOLVED),undefined)
156		SDK_NAME = $(notdir $(SDKROOT))
157		export COHORT_NAME := $(shell echo $(SDK_NAME) | sed -e 's|DriverKit.\([a-zA-Z]*\)$(SDKVERSION)\([.Internal]*\).sdk|\1\2|g' | tr A-Z a-z)
158		export COHORT_SDKROOT_RESOLVED := $(shell $(XCRUN) -sdk $(COHORT_NAME) -show-sdk-path)
159		ifeq ($(strip $(COHORT_SDKROOT_RESOLVED)),)
160		export COHORT_SDKROOT_RESOLVED := $(SDKROOT_RESOLVED)
161		endif
162	endif
163	override COHORT_SDKROOT = $(COHORT_SDKROOT_RESOLVED)
164	export PLATFORMPATH = $(shell $(XCRUN) -sdk $(COHORT_SDKROOT) -show-sdk-platform-path)
165	export PLATFORM := DriverKit
166	export DRIVERKIT ?= 1
167	export DRIVERKITROOT ?= /System/DriverKit
168	export DRIVERKITRUNTIMEROOT = $(DRIVERKITROOT)/Runtime
169else
170	override COHORT_SDKROOT = $(SDKROOT)
171endif
172
173ifeq ($(PLATFORM),MacOSX)
174	ifeq (DriverKit,$(shell echo $(SDKROOT_RESOLVED) | sed 's|^.*/\([^./1-9]*\)\(\.[^./1-9]*\)\{0,1\}[1-9][^/]*\.sdk$$|\1|'))
175		export PLATFORM := DriverKit
176		export DRIVERKIT ?= 1
177		export DRIVERKITROOT ?= /System/DriverKit
178		export DRIVERKITRUNTIMEROOT = $(DRIVERKITROOT)/Runtime
179	endif
180endif
181
182ifeq ($(PLATFORM),ExclaveKit)
183	ifeq ($(origin COHORT_SDKROOT_RESOLVED),undefined)
184		SDK_NAME = $(notdir $(SDKROOT))
185		export COHORT_NAME := $(shell echo $(SDK_NAME) | sed -e 's|ExclaveKit.\([a-zA-Z]*\)$(SDKVERSION)\([.Internal]*\).sdk|\1\2|g' | tr A-Z a-z)
186		export COHORT_SDKROOT_RESOLVED := $(shell $(XCRUN) -sdk $(COHORT_NAME) -show-sdk-path)
187		ifeq ($(strip $(COHORT_SDKROOT_RESOLVED)),)
188		export COHORT_SDKROOT_RESOLVED := $(SDKROOT_RESOLVED)
189		endif
190	endif
191	override COHORT_SDKROOT = $(COHORT_SDKROOT_RESOLVED)
192	export PLATFORMPATH = $(shell $(XCRUN) -sdk $(COHORT_SDKROOT) -show-sdk-platform-path)
193	export PLATFORM := ExclaveKit
194	export EXCLAVEKIT ?= 1
195	export EXCLAVEKITROOT ?= /System/ExclaveKit
196endif
197
198ifeq ($(PLATFORM),ExclaveCore)
199	ifeq ($(origin COHORT_SDKROOT_RESOLVED),undefined)
200		SDK_NAME = $(notdir $(SDKROOT))
201		export COHORT_NAME := $(shell echo $(SDK_NAME) | sed -e 's|ExclaveCore.\([a-zA-Z]*\)$(SDKVERSION)\([.Internal]*\).sdk|\1\2|g' | tr A-Z a-z)
202		export COHORT_SDKROOT_RESOLVED := $(shell $(XCRUN) -sdk $(COHORT_NAME) -show-sdk-path)
203		ifeq ($(strip $(COHORT_SDKROOT_RESOLVED)),)
204		export COHORT_SDKROOT_RESOLVED := $(SDKROOT_RESOLVED)
205		endif
206	endif
207	override COHORT_SDKROOT = $(COHORT_SDKROOT_RESOLVED)
208	export PLATFORMPATH = $(shell $(XCRUN) -sdk $(COHORT_SDKROOT) -show-sdk-platform-path)
209	export PLATFORM := ExclaveCore
210	export EXCLAVECORE ?= 1
211	export EXCLAVECOREROOT ?= /System/ExclaveCore
212endif
213
214# CC/CXX get defined by make(1) by default, so we can't check them
215# against the empty string to see if they haven't been set
216ifeq ($(origin CC),default)
217	export CC := $(shell $(XCRUN) -sdk $(SDKROOT) -find clang)
218endif
219ifeq ($(origin CXX),default)
220	export CXX := $(shell $(XCRUN) -sdk $(SDKROOT) -find clang++)
221endif
222ifeq ($(origin MIG),undefined)
223	export MIG := $(shell $(XCRUN) -sdk $(SDKROOT) -find mig)
224endif
225ifeq ($(origin MIGCOM),undefined)
226	export MIGCOM := $(shell $(XCRUN) -sdk $(SDKROOT) -find migcom)
227endif
228ifeq ($(origin MIGCC),undefined)
229	export MIGCC := $(CC)
230endif
231ifeq ($(origin IIG),undefined)
232	export IIG := $(shell $(XCRUN) -sdk $(SDKROOT) -find iig)
233endif
234ifeq ($(origin TIGHTBEAMC),undefined)
235	export TIGHTBEAMC := $(shell $(XCRUN) -sdk $(SDKROOT) -find tightbeamc)
236endif
237ifeq ($(origin STRIP),undefined)
238	export STRIP := $(shell $(XCRUN) -sdk $(SDKROOT) -find strip)
239endif
240ifeq ($(origin LIPO),undefined)
241	export LIPO := $(shell $(XCRUN) -sdk $(SDKROOT) -find lipo)
242endif
243ifeq ($(origin LIBTOOL),undefined)
244	export LIBTOOL := $(shell $(XCRUN) -sdk $(SDKROOT) -find libtool)
245endif
246ifeq ($(origin OTOOL),undefined)
247	export OTOOL := $(shell $(XCRUN) -sdk $(SDKROOT) -find otool)
248endif
249ifeq ($(origin NM),undefined)
250	export NM := $(shell $(XCRUN) -sdk $(SDKROOT) -find nm)
251endif
252ifeq ($(origin UNIFDEF),undefined)
253	export UNIFDEF := $(shell $(XCRUN) -sdk $(SDKROOT) -find unifdef)
254endif
255ifeq ($(origin DSYMUTIL),undefined)
256	export DSYMUTIL := $(shell $(XCRUN) -sdk $(SDKROOT) -find dsymutil)
257endif
258ifeq ($(origin NMEDIT),undefined)
259	export NMEDIT := $(shell $(XCRUN) -sdk $(SDKROOT) -find nmedit)
260endif
261ifeq ($(origin GIT),undefined)
262	export GIT := $(shell $(XCRUN) -sdk $(SDKROOT) -find git)
263endif
264ifeq ($(origin SCAN_BUILD),undefined)
265	export SCAN_BUILD := $(shell $(XCRUN) -sdk $(SDKROOT) -find scan-build 2> /dev/null)
266endif
267ifeq ($(origin CTFINSERT),undefined)
268	export CTFINSERT := $(shell $(XCRUN) -sdk $(SDKROOT) -find ctf_insert 2> /dev/null)
269endif
270ifeq ($(origin CTFCONVERT),undefined)
271	export CTFCONVERT := $(shell $(XCRUN) -sdk $(SDKROOT) -find ctfconvert 2> /dev/null)
272endif
273ifeq ($(origin CTFMERGE),undefined)
274	export CTFMERGE := $(shell $(XCRUN) -sdk $(SDKROOT) -find ctfmerge 2> /dev/null)
275	ifeq (,$(wildcard $(CTFMERGE)))
276		export DO_CTFMERGE := 0
277	endif
278endif
279ifeq ($(origin CTFDUMP),undefined)
280	export CTFDUMP := $(shell $(XCRUN) -sdk $(SDKROOT) -find ctfdump 2> /dev/null)
281endif
282
283#
284# Platform options
285#
286SUPPORTED_EMBEDDED_PLATFORMS := iPhoneOS iPhoneOSNano tvOS AppleTVOS WatchOS BridgeOS
287SUPPORTED_SIMULATOR_PLATFORMS := iPhoneSimulator iPhoneNanoSimulator tvSimulator AppleTVSimulator WatchSimulator
288
289
290SUPPORTED_PLATFORMS := MacOSX DriverKit ExclaveKit ExclaveCore $(SUPPORTED_SIMULATOR_PLATFORMS) $(SUPPORTED_EMBEDDED_PLATFORMS)
291
292# Platform-specific tools
293EDM_DBPATH ?= $(PLATFORMPATH)/usr/local/standalone/firmware/device_map.db
294
295# Scripts or tools we build ourselves
296#
297# setsegname - Rename segments in a Mach-O object file
298# kextsymboltool - Create kext pseudo-kext Mach-O kexts binaries
299# decomment - Strip out comments to detect whether a file is comments-only
300# installfile - Atomically copy files, esp. when multiple architectures
301#               are trying to install the same target header
302# replacecontents - Write contents to a file and update modtime *only* if
303#               contents differ
304#
305SEG_HACK = $(OBJROOT)/SETUP/setsegname/setsegname
306KEXT_CREATE_SYMBOL_SET = $(OBJROOT)/SETUP/kextsymboltool/kextsymboltool
307DECOMMENT = $(OBJROOT)/SETUP/decomment/decomment
308NEWVERS = $(SRCROOT)/config/newvers.pl
309INSTALL = $(OBJROOT)/SETUP/installfile/installfile
310REPLACECONTENTS = $(OBJROOT)/SETUP/replacecontents/replacecontents
311
312# Standard BSD tools
313RM = /bin/rm -f
314RMDIR = /bin/rmdir
315CP = /bin/cp
316MV = /bin/mv
317LN = /bin/ln -fs
318CAT = /bin/cat
319MKDIR = /bin/mkdir -p
320CHMOD = /bin/chmod
321FIND = /usr/bin/find
322XARGS = /usr/bin/xargs
323PAX = /bin/pax
324BASENAME = /usr/bin/basename
325DIRNAME = /usr/bin/dirname
326TR = /usr/bin/tr
327TOUCH = /usr/bin/touch
328SLEEP = /bin/sleep
329AWK = /usr/bin/awk
330SED = /usr/bin/sed
331PLUTIL = /usr/bin/plutil
332PATCH = /usr/bin/patch
333GREP = /usr/bin/grep
334
335#
336# Command to generate host binaries. Intentionally not
337# $(CC), which controls the target compiler
338#
339ifeq ($(origin HOST_OS_VERSION),undefined)
340	export HOST_OS_VERSION	:= $(shell sw_vers -productVersion)
341endif
342ifeq ($(origin HOST_CC),undefined)
343	export HOST_CC		:= $(shell $(XCRUN) -sdk $(HOST_SDKROOT) -find clang)
344endif
345ifeq ($(origin HOST_FLEX),undefined)
346	export HOST_FLEX	:= $(shell $(XCRUN) -sdk $(HOST_SDKROOT) -find flex)
347endif
348ifeq ($(origin HOST_BISON),undefined)
349	export HOST_BISON	:= $(shell $(XCRUN) -sdk $(HOST_SDKROOT) -find bison)
350endif
351ifeq ($(origin HOST_GM4),undefined)
352	export HOST_GM4		:= $(shell $(XCRUN) -sdk $(HOST_SDKROOT) -find gm4)
353endif
354ifeq ($(origin HOST_CODESIGN),undefined)
355	export HOST_CODESIGN	:= /usr/bin/codesign
356endif
357ifeq ($(origin HOST_CODESIGN_ALLOCATE),undefined)
358	export HOST_CODESIGN_ALLOCATE	:= $(shell $(XCRUN) -sdk $(HOST_SDKROOT) -find codesign_allocate)
359endif
360
361#
362# The following variables are functions invoked with "call", and thus
363# behave similarly to externally compiled commands
364#
365
366# $(1) is an expanded kernel config from a TARGET_CONFIGS_UC tuple
367# $(2) is an expanded arch config from a TARGET_CONFIGS_UC tuple
368# $(3) is an expanded machine config from a TARGET_CONFIGS_UC tuple
369_function_create_build_configs_join = $(strip $(1))^$(strip $(2))^$(strip $(3))
370
371# $(1) is an un-expanded kernel config from a TARGET_CONFIGS_UC tuple
372# $(2) is an un-expanded arch config from a TARGET_CONFIGS_UC tuple
373# $(3) is an un-expanded machine config from a TARGET_CONFIGS_UC tuple
374_function_create_build_configs_do_expand =          $(call _function_create_build_configs_join, \
375							   $(if $(filter DEFAULT,$(1)), \
376								$(DEFAULT_KERNEL_CONFIG), \
377								$(1) \
378							    ), \
379							   $(if $(filter DEFAULT,$(2)), \
380								$(DEFAULT_ARCH_CONFIG), \
381								$(2) \
382							    ), \
383							   $(if $(filter DEFAULT,$(3)), \
384								$(if $(filter DEFAULT,$(2)), \
385								     $(DEFAULT_$(DEFAULT_ARCH_CONFIG)_MACHINE_CONFIG), \
386								     $(DEFAULT_$(strip $(2))_MACHINE_CONFIG) \
387								), \
388								$(3) \
389							    ) \
390						     )
391
392# $(1) is an un-expanded TARGET_CONFIGS_UC list, which must be consumed
393#      3 elements at a time
394function_create_build_configs = $(sort \
395					$(strip \
396						 $(call _function_create_build_configs_do_expand, \
397							$(word 1,$(1)), \
398							$(word 2,$(1)), \
399							$(word 3,$(1)), \
400						  ) \
401						 $(if $(word 4,$(1)), \
402						      $(call function_create_build_configs, \
403							     $(wordlist 4,$(words $(1)),$(1)) \
404						       ), \
405						  ) \
406					  ) \
407				   )
408
409# Similar to build configs, but alias configs are a 4-tuple
410
411# $(1) is an expanded kernel config from a TARGET_CONFIGS_ALIASES_UC tuple
412# $(2) is an expanded arch config from a TARGET_CONFIGS_ALIASES_UC tuple
413# $(3) is an expanded kernel machine config from a TARGET_CONFIGS_ALIASES_UC tuple
414# $(4) is an expanded SoC platform config from a TARGET_CONFIGS_ALIASES_UC tuple,
415#      which should be an alias of $(3)
416_function_create_alias_configs_join = $(strip $(1))^$(strip $(2))^$(strip $(3))^$(strip $(4))
417
418_function_create_alias_configs_do_expand =	    $(call _function_create_alias_configs_join, \
419							   $(if $(filter DEFAULT,$(1)), \
420							        $(DEFAULT_KERNEL_CONFIG), \
421								$(1) \
422							    ), \
423							   $(if $(filter DEFAULT,$(2)), \
424								$(DEFAULT_ARCH_CONFIG), \
425								$(2) \
426							    ), \
427							   $(3), \
428							   $(4) \
429						     )
430
431function_create_alias_configs = $(sort \
432					$(strip \
433						 $(call _function_create_alias_configs_do_expand, \
434							$(word 1,$(1)), \
435							$(word 2,$(1)), \
436							$(word 3,$(1)), \
437							$(word 4,$(1)), \
438						  ) \
439						 $(if $(word 5,$(1)), \
440						      $(call function_create_alias_configs, \
441							     $(wordlist 5,$(words $(1)),$(1)) \
442						       ), \
443						  ) \
444					 ) \
445				 )
446
447# $(1) is a fully-expanded kernel config
448# $(2) is a fully-expanded arch config
449# $(3) is a fully-expanded machine config. "NONE" is not represented in the objdir path
450function_convert_target_config_uc_to_objdir = $(if $(filter NONE,$(3)),$(strip $(1))_$(strip $(2)),$(strip $(1))_$(strip $(2))_$(strip $(3)))
451
452# $(1) is a fully-expanded build config (like "RELEASE^X86_64^NONE")
453function_convert_build_config_to_objdir = $(call function_convert_target_config_uc_to_objdir, \
454						 $(word 1,$(subst ^, ,$(1))), \
455						 $(word 2,$(subst ^, ,$(1))), \
456						 $(word 3,$(subst ^, ,$(1))) \
457					   )
458
459# $(1) is a fully-expanded build config (like "RELEASE^X86_64^NONE")
460function_extract_kernel_config_from_build_config  = $(word 1,$(subst ^, ,$(1)))
461function_extract_arch_config_from_build_config    = $(word 2,$(subst ^, ,$(1)))
462function_extract_machine_config_from_build_config = $(word 3,$(subst ^, ,$(1)))
463
464#
465# Returns build config if both architecture and kernel configuration match.
466#
467#   $(1) - list of build configs
468#   $(1) - architecture
469#   $(2) - kernel configuration
470
471function_match_build_config_for_architecture_and_kernel_config = $(strip \
472			    $(foreach build_config, $(1), \
473			      $(if \
474				$(and \
475				  $(filter $(2), $(call function_extract_arch_config_from_build_config, $(build_config))), \
476				  $(filter $(3), $(call function_extract_kernel_config_from_build_config, $(build_config)))), \
477			      $(build_config), )))
478
479#
480# Returns build config if kernel configuration matches.
481#
482#   $(1) - list of build configs
483#   $(2) - kernel configuration
484
485function_match_build_config_for_kernel_config = $(strip \
486			    $(foreach build_config, $(1), \
487			      $(if \
488				  $(filter $(2), $(call function_extract_kernel_config_from_build_config, $(build_config))), \
489			      $(build_config), )))
490
491# $(1) is an input word
492# $(2) is a list of colon-separate potential substitutions like "FOO:BAR BAZ:QUX"
493# $(3) is a fallback if no substitutions were made
494function_substitute_word_with_replacement = $(strip $(if $(2),								\
495							 $(if $(filter $(word 1,$(subst :, ,$(word 1,$(2)))),$(1)),	\
496							      $(word 2,$(subst :, ,$(word 1,$(2)))),		\
497							      $(call function_substitute_word_with_replacement,$(1),$(wordlist 2,$(words $(2)),$(2)),$(3))), \
498							 $(3)								\
499						     )									\
500					     )
501
502# You can't assign a variable to an empty space without these
503# shenanigans
504empty :=
505space := $(empty) $(empty)
506
507# Arithmetic
508# $(1) is the number to increment
509NUM32 = x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x
510increment = $(words x $(wordlist 1,$(1),$(NUM32)))
511decrement = $(words $(wordlist 2,$(1),$(NUM32)))
512
513# Create a sequence from 1 to $(1)
514# F(N) = if N > 0: return F(N-1) + "N" else: return ""
515sequence = $(if $(wordlist 1,$(1),$(NUM32)),$(call sequence,$(call decrement,$(1))) $(1),)
516
517# Reverse a list of words in $(1)
518reverse = $(if $(word 2,$(1)),$(call reverse,$(wordlist 2,$(words $(1)),$(1)))) $(word 1,$(1))
519
520# vim: set ft=make:
521