xref: /rk3399_ARM-atf/make_helpers/build_macros.mk (revision e7e231d39c68083e870cdaaa89ecc4e5045fdd64)
1#
2# Copyright (c) 2015-2026, Arm Limited and Contributors. All rights reserved.
3#
4# SPDX-License-Identifier: BSD-3-Clause
5#
6
7# Report an error if the eval make function is not available.
8$(eval eval_available := T)
9ifneq (${eval_available},T)
10    $(error This makefile only works with a Make program that supports $$(eval))
11endif
12
13# A user defined function to recursively search for a filename below a directory
14#    $1 is the directory root of the recursive search (blank for current directory).
15#    $2 is the file name to search for.
16define rwildcard
17$(strip $(foreach d,$(wildcard ${1}*),$(call rwildcard,${d}/,${2}) $(filter $(subst *,%,%${2}),${d})))
18endef
19
20# Convenience function for setting a variable to 0 if not previously set
21# $(eval $(call default_zero,FOO))
22define default_zero
23	$(eval $(1) ?= 0)
24endef
25
26# Convenience function for setting a list of variables to 0 if not previously set
27# $(eval $(call default_zeros,FOO BAR))
28define default_zeros
29	$(foreach var,$1,$(eval $(call default_zero,$(var))))
30endef
31
32# Convenience function for setting a list of variables to 1 if not set on the
33# commandline
34# $(eval $(call set_ones,FOO BAR))
35define set_ones
36	$(foreach var,$1,$(eval $(var) := 1))
37endef
38
39# Convenience function for setting CRYPTO_SUPPORT per component based on build flags
40# and set MBEDTLS_LIB based on CRYPTO_SUPPORT
41# $(eval $(call set_crypto_support,NEED_AUTH,NEED_HASH))
42#   $(1) = NEED_AUTH, determines need for authentication verification support
43#   $(2) = NEED_HASH, determines need for hash calculation support
44# CRYPTO_SUPPORT is set to 0 (default), 1 (authentication only), 2 (hash only), or
45# 3 (both) based on what support is required.
46define set_crypto_support
47	ifeq ($($1)-$($2),1-1)
48		CRYPTO_SUPPORT := 3
49	else ifeq ($($2),1)
50		CRYPTO_SUPPORT := 2
51	else ifeq ($($1),1)
52		CRYPTO_SUPPORT := 1
53	else
54		CRYPTO_SUPPORT := 0
55	endif
56	MBEDTLS_LIB ?= $(BUILD_PLAT)/lib/libmbedtls.a
57	CRYPTO_LIB := $(if $(filter-out 0,$(CRYPTO_SUPPORT)),$(MBEDTLS_LIB),)
58endef
59
60# Convenience function for creating a build definition
61# $(call make_define,FOO) will have:
62# -DFOO if $(FOO) is empty; -DFOO=$(FOO) otherwise
63make_define = -D$(1)$(if $($(1)),=$($(1)))
64
65# Convenience function for creating multiple build definitions
66# For BL1, BL1_CPPFLAGS += $(call make_defines,FOO BOO)
67make_defines = $(foreach def,$(1),$(call make_define,$(def)))
68
69# Convenience function for adding build definitions
70# $(eval $(call add_define,FOO)) will have:
71# -DFOO if $(FOO) is empty; -DFOO=$(FOO) otherwise
72define add_define
73    DEFINES			+=	-D$(1)$(if $(value $(1)),=$(value $(1)),)
74endef
75
76# Convenience function for addding multiple build definitions
77# $(eval $(call add_defines,FOO BOO))
78define add_defines
79    $(foreach def,$1,$(eval $(call add_define,$(def))))
80endef
81
82# Convenience function for adding build definitions
83# $(eval $(call add_define_val,FOO,BAR)) will have:
84# -DFOO=BAR
85define add_define_val
86    DEFINES			+=	-D$(1)=$(2)
87endef
88
89# Convenience function for verifying option has a boolean value
90# $(eval $(call assert_boolean,FOO)) will assert FOO is 0 or 1
91define assert_boolean
92    $(if $($(1)),,$(error $(1) must not be empty))
93    $(if $(filter-out 0 1,$($1)),$(error $1 must be boolean))
94endef
95
96# Convenience function for verifying options have boolean values
97# $(eval $(call assert_booleans,FOO BOO)) will assert FOO and BOO for 0 or 1 values
98define assert_booleans
99    $(foreach bool,$1,$(eval $(call assert_boolean,$(bool))))
100endef
101
1020-9 := 0 1 2 3 4 5 6 7 8 9
103
104# Function to verify that a given option $(1) contains a numeric value
105define assert_numeric
106$(if $($(1)),,$(error $(1) must not be empty))
107$(eval __numeric := $($(1)))
108$(foreach d,$(0-9),$(eval __numeric := $(subst $(d),,$(__numeric))))
109$(if $(__numeric),$(error $(1) must be numeric))
110endef
111
112# Convenience function for verifying options have numeric values
113# $(eval $(call assert_numerics,FOO BOO)) will assert FOO and BOO contain numeric values
114define assert_numerics
115    $(foreach num,$1,$(eval $(call assert_numeric,$(num))))
116endef
117
118# Convenience function to check for a given linker option. A call to
119# $(call ld_option, --no-XYZ) will return --no-XYZ if supported by the linker,
120# prefixed appropriately for the linker in use
121ld_option = $(call toolchain-ld-option,$(ARCH),$(1))
122
123# Convenience function to add a prefix to a linker flag if necessary. Useful
124# when the flag is known to be supported and it just needs to be prefixed
125# correctly.
126ld_prefix = $(toolchain-ld-prefix-$($(ARCH)-ld-id))
127
128# Convenience function to check for a given compiler option. A call to
129# $(call cc_option, --no-XYZ) will return --no-XYZ if supported by the compiler
130# NOTE: consider assigning to an immediately expanded temporary variable before
131# assigning. This is because variables like TF_CFLAGS are recursively expanded
132# and assigning this directly will cause it to be expanded every time the
133# variable is used, potentially thrashing multicore performance.
134define cc_option
135	$(shell if $($(ARCH)-cc) $(1) -c -x c /dev/null -o /dev/null >/dev/null 2>&1; then echo $(1); fi )
136endef
137
138# CREATE_SEQ is a recursive function to create sequence of numbers from 1 to
139# $(2) and assign the sequence to $(1)
140define CREATE_SEQ
141$(if $(word $(2), $($(1))),\
142  $(eval $(1) += $(words $($(1))))\
143  $(eval $(1) := $(filter-out 0,$($(1)))),\
144  $(eval $(1) += $(words $($(1))))\
145  $(call CREATE_SEQ,$(1),$(2))\
146)
147endef
148
149# IMG_MAPFILE defines the output file describing the memory map corresponding
150# to a BL stage
151#   $(1) = BL stage
152define IMG_MAPFILE
153    ${BUILD_DIR}/$(1).map
154endef
155
156# IMG_ELF defines the elf file corresponding to a BL stage
157#   $(1) = BL stage
158define IMG_ELF
159    ${BUILD_DIR}/$(1).elf
160endef
161
162# IMG_DUMP defines the symbols dump file corresponding to a BL stage
163#   $(1) = BL stage
164define IMG_DUMP
165    ${BUILD_DIR}/$(1).dump
166endef
167
168# IMG_BIN defines the default image file corresponding to a BL stage
169#   $(1) = BL stage
170define IMG_BIN
171    ${BUILD_PLAT}/$(1).bin
172endef
173
174# IMG_ENC_BIN defines the default encrypted image file corresponding to a
175# BL stage
176#   $(1) = BL stage
177define IMG_ENC_BIN
178    ${BUILD_PLAT}/$(1)_enc.bin
179endef
180
181# ENCRYPT_FW invokes enctool to encrypt firmware binary
182#   $(1) = input firmware binary
183#   $(2) = output encrypted firmware binary
184define ENCRYPT_FW
185$(2): $(1) enctool
186	$$(s)echo "  ENC     $$<"
187	$$(q)$$(ENCTOOL) $$(ENC_ARGS) -i $$< -o $$@
188endef
189
190# TOOL_ADD_PAYLOAD appends the command line arguments required by fiptool to
191# package a new payload and/or by cert_create to generate certificate.
192# Optionally, it adds the dependency on this payload
193#   $(1) = payload filename (i.e. bl31.bin)
194#   $(2) = command line option for the specified payload (i.e. --soc-fw)
195#   $(3) = tool target dependency (optional) (ex. build/fvp/release/bl31.bin)
196#   $(4) = FIP prefix (optional) (if FWU_, target is fwu_fip instead of fip)
197#   $(5) = encrypted payload (optional) (ex. build/fvp/release/bl31_enc.bin)
198define TOOL_ADD_PAYLOAD
199ifneq ($(5),)
200    $(4)FIP_ARGS += $(2) $(5)
201    $(if $(3),$(4)CRT_DEPS += $(1))
202else
203    $(4)FIP_ARGS += $(2) $(1)
204    $(if $(3),$(4)CRT_DEPS += $(3))
205endif
206    $(if $(3),$(4)FIP_DEPS += $(3))
207    $(4)CRT_ARGS += $(2) $(1)
208endef
209
210# TOOL_ADD_IMG_PAYLOAD works like TOOL_ADD_PAYLOAD, but applies image filters
211# before passing them to host tools if BL*_PRE_TOOL_FILTER is defined.
212#   $(1) = image_type (scp_bl2, bl33, etc.)
213#   $(2) = payload filepath (ex. build/fvp/release/bl31.bin)
214#   $(3) = command line option for the specified payload (ex. --soc-fw)
215#   $(4) = tool target dependency (optional) (ex. build/fvp/release/bl31.bin)
216#   $(5) = FIP prefix (optional) (if FWU_, target is fwu_fip instead of fip)
217#   $(6) = encrypted payload (optional) (ex. build/fvp/release/bl31_enc.bin)
218
219define TOOL_ADD_IMG_PAYLOAD
220
221$(eval PRE_TOOL_FILTER := $($(1)_PRE_TOOL_FILTER))
222
223ifneq ($(PRE_TOOL_FILTER),)
224
225$(eval PROCESSED_PATH := $(BUILD_PLAT)/$(1).bin$($(PRE_TOOL_FILTER)_SUFFIX))
226
227$(call $(PRE_TOOL_FILTER)_RULE,$(PROCESSED_PATH),$(2))
228
229$(PROCESSED_PATH): $(4)
230
231$(call TOOL_ADD_PAYLOAD,$(PROCESSED_PATH),$(3),$(PROCESSED_PATH),$(5),$(6))
232
233else
234$(call TOOL_ADD_PAYLOAD,$(2),$(3),$(4),$(5),$(6))
235endif
236endef
237
238# CERT_ADD_CMD_OPT adds a new command line option to the cert_create invocation
239#   $(1) = parameter filename
240#   $(2) = cert_create command line option for the specified parameter
241#   $(3) = FIP prefix (optional) (if FWU_, target is fwu_fip instead of fip)
242define CERT_ADD_CMD_OPT
243    $(3)CRT_ARGS += $(2) $(1)
244endef
245
246# TOOL_ADD_IMG allows the platform to specify an external image to be packed
247# in the FIP and/or for which certificate is generated. It also adds a
248# dependency on the image file, aborting the build if the file does not exist.
249#   $(1) = image_type (scp_bl2, bl33, etc.)
250#   $(2) = command line option for fiptool (--scp-fw, --nt-fw, etc)
251#   $(3) = FIP prefix (optional) (if FWU_, target is fwu_fip instead of fip)
252#   $(4) = Image encryption flag (optional) (0, 1)
253# Example:
254#   $(eval $(call TOOL_ADD_IMG,bl33,--nt-fw))
255define TOOL_ADD_IMG
256    # Build option to specify the image filename (SCP_BL2, BL33, etc)
257    # This is the uppercase form of the first parameter
258    $(eval BL := $(call uppercase,$(1)))
259    $(eval _V := $(BL))
260
261    # $(check_$(1)_cmd) variable is executed in the check_$(1) target and also
262    # is put into the ${CHECK_$(3)FIP_CMD} variable which is executed by the
263    # target ${BUILD_PLAT}/${$(3)FIP_NAME}.
264    $(eval check_$(1)_cmd := \
265        $(if $(value $(_V)),,$$$$(error "Platform '${PLAT}' requires $(_V). Please set $(_V) to point to the right file")) \
266        $(if $(wildcard $(value $(_V))),,$$$$(error '$(_V)=$(value $(_V))' was specified, but '$(value $(_V))' does not exist)) \
267    )
268
269    $(3)CRT_DEPS += check_$(1)
270    CHECK_$(3)FIP_CMD += $$(check_$(1)_cmd)
271ifeq ($(4),1)
272    $(eval ENC_BIN := ${BUILD_PLAT}/$(1)_enc.bin)
273    $(call ENCRYPT_FW,$(value $(_V)),$(ENC_BIN))
274    $(call TOOL_ADD_IMG_PAYLOAD,$(BL),$(value $(_V)),$(2),$(ENC_BIN),$(3), \
275		$(ENC_BIN))
276else
277    $(call TOOL_ADD_IMG_PAYLOAD,$(BL),$(value $(_V)),$(2),$(if $(wildcard $(value $(_V))),$(value $(_V)),FORCE),$(3))
278endif
279
280.PHONY: check_$(1)
281check_$(1):
282	$(check_$(1)_cmd)
283endef
284
285# SELECT_OPENSSL_API_VERSION selects the OpenSSL API version to be used to
286# build the host tools by checking the version of OpenSSL located under
287# the path defined by the OPENSSL_DIR variable. It receives no parameters.
288define SELECT_OPENSSL_API_VERSION
289    # Set default value for USING_OPENSSL3 macro to 0
290    $(eval USING_OPENSSL3 = 0)
291    # Obtain the OpenSSL version for the build located under OPENSSL_DIR
292    $(eval OPENSSL_INFO := $(shell LD_LIBRARY_PATH=${OPENSSL_DIR}:${OPENSSL_DIR}/lib ${OPENSSL_BIN_PATH}/openssl version))
293    $(eval OPENSSL_CURRENT_VER = $(word 2, ${OPENSSL_INFO}))
294    $(eval OPENSSL_CURRENT_VER_MAJOR = $(firstword $(subst ., ,$(OPENSSL_CURRENT_VER))))
295    # If OpenSSL version is 3.x, then set USING_OPENSSL3 flag to 1
296    $(if $(filter 3,$(OPENSSL_CURRENT_VER_MAJOR)), $(eval USING_OPENSSL3 = 1))
297endef
298
299################################################################################
300# Generic image processing filters
301################################################################################
302
303# GZIP
304define GZIP_RULE
305$(1): $(2)
306	$(s)echo "  GZIP    $$@"
307	$(q)gzip -n -f -9 $$< --stdout > $$@
308endef
309
310GZIP_SUFFIX := .gz
311
312################################################################################
313# Auxiliary macros to build TF images from sources
314################################################################################
315
316MAKE_DEP = -Wp,-MD,$1 -MT $2 -MP
317
318# MAKE_TOOL_C builds a C source file and generates the dependency file
319#   $(1) = output directory
320#   $(2) = source file (%.c)
321#   $(3) = lowercase name of the tool
322#   $(4) = uppercase name of the tool
323define MAKE_TOOL_C
324
325$(eval SRC := $(2))
326$(eval OBJ := $(patsubst %.c,$(1)/$(3)/%.o,$(SRC)))
327$(eval DEP := $(patsubst %.o,%.d,$(OBJ)))
328
329$(eval TOOL_DEFINES := $($(4)_DEFINES))
330$(eval TOOL_INCLUDE_DIRS := $($(4)_INCLUDE_DIRS))
331$(eval TOOL_CPPFLAGS := $($(4)_CPPFLAGS) $(addprefix -D,$(TOOL_DEFINES)) $(addprefix -I,$(TOOL_INCLUDE_DIRS)))
332$(eval TOOL_CFLAGS := $($(4)_CFLAGS))
333
334$(OBJ): $(SRC) $(filter-out %.d,$(MAKEFILE_LIST)) | $$$$(@D)/
335	$$(s)echo "  HOSTCC      $$<"
336	$$(q)$(host-cc) $$(HOSTCCFLAGS) $(TOOL_CPPFLAGS) $(TOOL_CFLAGS) $(call MAKE_DEP,$(DEP),$(OBJ)) -c $$< -o $$@
337
338-include $(DEP)
339
340endef
341
342# MAKE_TOOL
343#   $(1) = output directory
344#   $(2) = lowercase name of the tool
345#   $(3) = uppercase name of the tool
346define MAKE_TOOL
347$(eval SRCS := $($(3)_SOURCES))
348$(eval OBJS := $(patsubst %.c,$(1)/$(2)/%.o,$(SRCS)))
349$(eval DST := $(1)/$(2)/$(2)$(.exe))
350$(eval $(foreach src,$(SRCS),$(call MAKE_TOOL_C,$(1),$(src),$(2),$(3))))
351
352$(DST): $(OBJS) $(filter-out %.d,$(MAKEFILE_LIST)) | $(1)
353	$$(s)echo "  HOSTLD  $$@"
354	$$(q)$(host-ld) $$(OBJS) -o $$@ $$(HOSTLDFLAGS) $($(3)_LDFLAGS)
355	$$(s)echo
356	$$(s)echo "Built $$@ successfully"
357	$$(s)echo
358
359all: $(DST)
360endef
361
362# MAKE_C_LIB builds a C source file and generates the dependency file
363#   $(1) = output directory
364#   $(2) = source file (%.c)
365#   $(3) = library name
366#   $(4) = uppercase name of the library
367#   $(5) = optional list of cflags that needed to be removed
368define MAKE_C_LIB
369$(eval OBJ := $(1)/$(patsubst %.c,%.o,$(notdir $(2))))
370$(eval DEP := $(patsubst %.o,%.d,$(OBJ)))
371$(eval LIB := $(notdir $(1)))
372
373$(OBJ): $(2) $(filter-out %.d,$(MAKEFILE_LIST)) | $$$$(@D)/
374	$$(s)echo "  CC      $$<"
375	$$(q)$($(ARCH)-cc) $$(LIB$(4)_CFLAGS) $$(filter-out $(5),$$(TF_CFLAGS)) $(call MAKE_DEP,$(DEP),$(OBJ)) -c $$< -o $$@
376
377-include $(DEP)
378
379endef
380
381# MAKE_S_LIB builds an assembly source file and generates the dependency file
382#   $(1) = output directory
383#   $(2) = source file (%.S)
384#   $(3) = library name
385#   $(4) = uppercase name of the library
386define MAKE_S_LIB
387$(eval OBJ := $(1)/$(patsubst %.S,%.o,$(notdir $(2))))
388$(eval DEP := $(patsubst %.o,%.d,$(OBJ)))
389
390$(OBJ): $(2) $(filter-out %.d,$(MAKEFILE_LIST)) | $$$$(@D)/
391	$$(s)echo "  AS      $$<"
392	$$(q)$($(ARCH)-as) -x assembler-with-cpp $$(TF_CFLAGS) $$(ASFLAGS) $(call MAKE_DEP,$(DEP),$(OBJ)) -c $$< -o $$@
393
394-include $(DEP)
395
396endef
397
398
399# MAKE_C builds a C source file and generates the dependency file
400#   $(1) = output directory
401#   $(2) = source file (%.c)
402#   $(3) = BL stage
403#   $(4) = uppercase BL stage
404define MAKE_C
405
406$(eval OBJ := $(1)/$(patsubst %.c,%.o,$(notdir $(2))))
407$(eval DEP := $(patsubst %.o,%.d,$(OBJ)))
408
409$(eval BL_DEFINES := IMAGE_$(4) $($(4)_DEFINES))
410$(eval BL_INCLUDE_DIRS := $($(4)_INCLUDE_DIRS))
411$(eval BL_CPPFLAGS := $($(4)_CPPFLAGS) $(addprefix -D,$(BL_DEFINES)) $(addprefix -I,$(BL_INCLUDE_DIRS)))
412$(eval BL_CFLAGS := $($(4)_CFLAGS))
413
414$(OBJ): $(2) $(filter-out %.d,$(MAKEFILE_LIST)) | $$$$(@D)/ $(BL_INCLUDE_DIRS:%=%/)
415	$$(s)echo "  CC      $$<"
416	$$(q)$($(ARCH)-cc) $$(LTO_CFLAGS) $$(TF_CFLAGS) $(BL_CPPFLAGS) $(BL_CFLAGS) $(call MAKE_DEP,$(DEP),$(OBJ)) -c $$< -o $$@
417
418-include $(DEP)
419
420endef
421
422
423# MAKE_S builds an assembly source file and generates the dependency file
424#   $(1) = output directory
425#   $(2) = assembly file (%.S)
426#   $(3) = BL stage
427#   $(4) = uppercase BL stage
428define MAKE_S
429
430$(eval OBJ := $(1)/$(patsubst %.S,%.o,$(notdir $(2))))
431$(eval DEP := $(patsubst %.o,%.d,$(OBJ)))
432
433$(eval BL_DEFINES := IMAGE_$(4) $($(4)_DEFINES))
434$(eval BL_INCLUDE_DIRS := $($(4)_INCLUDE_DIRS))
435$(eval BL_CPPFLAGS := $($(4)_CPPFLAGS) $(addprefix -D,$(BL_DEFINES)) $(addprefix -I,$(BL_INCLUDE_DIRS)))
436$(eval BL_ASFLAGS := $($(4)_ASFLAGS))
437
438$(OBJ): $(2) $(filter-out %.d,$(MAKEFILE_LIST)) | $$$$(@D)/ $(BL_INCLUDE_DIRS:%=%/)
439	$$(s)echo "  AS      $$<"
440	$$(q)$($(ARCH)-as) -x assembler-with-cpp $$(TF_CFLAGS) $$(ASFLAGS) $(BL_CPPFLAGS) $(BL_ASFLAGS) $(call MAKE_DEP,$(DEP),$(OBJ)) -c $$< -o $$@
441
442-include $(DEP)
443
444endef
445
446# MAKE_PRE run the C preprocessor on a file
447#   $(1) = output file
448#   $(2) = list of input files
449#   $(3) = dep file
450#   $(4) = list of rule-specific flags to pass
451define MAKE_PRE
452$(eval OUT := $(1))
453$(eval SRC := $(2))
454$(eval DEP := $(3))
455$(eval CUSTOM_FLAGS := $(4))
456$(OUT): $(SRC) $(filter-out %.d,$(MAKEFILE_LIST)) | $$$$(@D)/
457	$$(s)echo "  CPP     $$<"
458	$$(q)$($(ARCH)-cpp) -E -P -x assembler-with-cpp $$(TF_CFLAGS) $(CUSTOM_FLAGS) $(call MAKE_DEP,$(DEP),$(OUT)) -o $$@ $$<
459endef
460
461# MAKE_LD generate the linker script using the C preprocessor
462#   $(1) = output linker script
463#   $(2) = input template
464#   $(3) = BL stage
465#   $(4) = uppercase BL stage
466define MAKE_LD
467
468$(eval DEP := $(1).d)
469
470$(eval BL_DEFINES := IMAGE_$(4) $($(4)_DEFINES))
471$(eval BL_INCLUDE_DIRS := $($(4)_INCLUDE_DIRS))
472$(eval BL_CPPFLAGS := $($(4)_CPPFLAGS) $(addprefix -D,$(BL_DEFINES)) $(addprefix -I,$(BL_INCLUDE_DIRS)))
473$(eval FLAGS := -D__LINKER__ $(BL_CPPFLAGS))
474
475$(1): | $(BL_INCLUDE_DIRS:%=%/)
476
477$(eval $(call MAKE_PRE,$(1),$(2),$(DEP),$(FLAGS)))
478-include $(DEP)
479
480endef
481
482# MAKE_LIB_OBJS builds both C and assembly source files
483#   $(1) = output directory
484#   $(2) = list of source files
485#   $(3) = name of the library
486#   $(4) = uppercase name of the library
487#   $(5) = optional list of cflags that needed to be removed
488define MAKE_LIB_OBJS
489        $(eval C_OBJS := $(filter %.c,$(2)))
490        $(eval REMAIN := $(filter-out %.c,$(2)))
491        $(eval $(foreach obj,$(C_OBJS),$(call MAKE_C_LIB,$(1),$(obj),$(3),$(4),$(5))))
492
493        $(eval S_OBJS := $(filter %.S,$(REMAIN)))
494        $(eval REMAIN := $(filter-out %.S,$(REMAIN)))
495        $(eval $(foreach obj,$(S_OBJS),$(call MAKE_S_LIB,$(1),$(obj),$(3),$(4))))
496
497        $(and $(REMAIN),$(error Unexpected source files present: $(REMAIN)))
498endef
499
500
501# MAKE_OBJS builds both C and assembly source files
502#   $(1) = output directory
503#   $(2) = list of source files (both C and assembly)
504#   $(3) = BL stage
505#   $(4) = uppercase BL stage
506define MAKE_OBJS
507        $(eval C_OBJS := $(filter %.c,$(2)))
508        $(eval REMAIN := $(filter-out %.c,$(2)))
509        $(eval $(foreach obj,$(C_OBJS),$(call MAKE_C,$(1),$(obj),$(3),$(4))))
510
511        $(eval S_OBJS := $(filter %.S,$(REMAIN)))
512        $(eval REMAIN := $(filter-out %.S,$(REMAIN)))
513        $(eval $(foreach obj,$(S_OBJS),$(call MAKE_S,$(1),$(obj),$(3),$(4))))
514
515        $(and $(REMAIN),$(error Unexpected source files present: $(REMAIN)))
516endef
517
518
519# NOTE: The line continuation '\' is required in the next define otherwise we
520# end up with a line-feed characer at the end of the last c filename.
521# Also bear this issue in mind if extending the list of supported filetypes.
522define SOURCES_TO_OBJS
523        $(notdir $(patsubst %.c,%.o,$(filter %.c,$(1)))) \
524        $(notdir $(patsubst %.S,%.o,$(filter %.S,$(1))))
525endef
526
527.PHONY: libraries
528
529# MAKE_LIB macro defines the targets and options to build each BL image.
530# Arguments:
531#   $(1) = Library name
532#   $(2) = Optinal list of cflags needed to removed
533define MAKE_LIB
534        $(eval BL         := $(call uppercase,$(1)))
535        $(eval BUILD_DIR  := ${BUILD_PLAT}/lib$(1))
536        $(eval LIB_DIR    := ${BUILD_PLAT}/lib)
537        $(eval ROMLIB_DIR    := ${BUILD_PLAT}/romlib)
538        $(eval SOURCES    := $(LIB$(BL)_SRCS))
539        $(eval OBJS       := $(addprefix $(BUILD_DIR)/,$(call SOURCES_TO_OBJS,$(SOURCES))))
540
541$(eval $(call MAKE_LIB_OBJS,$(BUILD_DIR),$(SOURCES),$(1),$(BL),$(2)))
542
543libraries: ${LIB_DIR}/lib$(1).a
544ifeq ($($(ARCH)-ld-id),arm-link)
545LDPATHS = --userlibpath=${LIB_DIR}
546LDLIBS += --library=$(1)
547else
548LDPATHS = -L${LIB_DIR}
549LDLIBS += -l$(1)
550endif
551
552ifeq ($(USE_ROMLIB),1)
553LIBWRAPPER = -lwrappers
554endif
555
556all: ${LIB_DIR}/lib$(1).a
557
558${LIB_DIR}/lib$(1).a: $(OBJS) | $$$$(@D)/
559	$$(s)echo "  AR      $$@"
560	$$(q)$($(ARCH)-ar) cr $$@ $$?
561endef
562
563# Generate the path to one or more preprocessed linker scripts given the paths
564# of their sources.
565#
566# Arguments:
567#   $(1) = path to one or more linker script sources
568define linker_script_path
569        $(patsubst %.S,$(BUILD_DIR)/%,$(1))
570endef
571
572# MAKE_BL macro defines the targets and options to build each BL image.
573# Arguments:
574#   $(1) = BL stage
575#   $(2) = FIP command line option (if empty, image will not be included in the FIP)
576#   $(3) = FIP prefix (optional) (if FWU_, target is fwu_fip instead of fip)
577#   $(4) = BL encryption flag (optional) (0, 1)
578define MAKE_BL
579        $(eval BL         := $(call uppercase,$(1)))
580        $(eval BUILD_DIR  := ${BUILD_PLAT}/$(1))
581        $(eval BL_SOURCES := $($(BL)_SOURCES))
582        $(eval SOURCES    := $(sort $(BL_SOURCES) $(BL_COMMON_SOURCES) $(PLAT_BL_COMMON_SOURCES)))
583        $(eval OBJS       := $(addprefix $(BUILD_DIR)/,$(call SOURCES_TO_OBJS,$(SOURCES))))
584        $(eval MAPFILE    := $(call IMG_MAPFILE,$(1)))
585        $(eval ELF        := $(call IMG_ELF,$(1)))
586        $(eval DUMP       := $(call IMG_DUMP,$(1)))
587        $(eval BIN        := $(call IMG_BIN,$(1)))
588        $(eval ENC_BIN    := $(call IMG_ENC_BIN,$(1)))
589        $(eval BL_LIBS    := $($(BL)_LIBS))
590
591        $(eval DEFAULT_LINKER_SCRIPT_SOURCE := $($(BL)_DEFAULT_LINKER_SCRIPT_SOURCE))
592        $(eval DEFAULT_LINKER_SCRIPT := $(call linker_script_path,$(DEFAULT_LINKER_SCRIPT_SOURCE)))
593
594        $(eval LINKER_SCRIPT_SOURCES := $($(BL)_LINKER_SCRIPT_SOURCES))
595        $(eval LINKER_SCRIPTS := $(call linker_script_path,$(LINKER_SCRIPT_SOURCES)))
596        $(eval GNU_LINKER_ARGS := $(call ld_prefix,-Map=$(MAPFILE)) $(foreach script,$(LINKER_SCRIPTS) $(DEFAULT_LINKER_SCRIPT), $(call ld_prefix,--script $(script))))
597
598$(eval $(call MAKE_OBJS,$(BUILD_DIR),$(SOURCES),$(1),$(BL)))
599
600# Generate targets to preprocess each required linker script
601$(eval $(foreach source,$(DEFAULT_LINKER_SCRIPT_SOURCE) $(LINKER_SCRIPT_SOURCES), \
602        $(call MAKE_LD,$(call linker_script_path,$(source)),$(source),$(1),$(BL))))
603
604$(eval BL_LDFLAGS := $($(BL)_LDFLAGS))
605
606ifeq ($(USE_ROMLIB),1)
607$(ELF): $(BUILD_PLAT)/romlib/romlib.bin | $$$$(@D)/
608endif
609
610# MODULE_OBJS can be assigned by vendors with different compiled
611# object file path, and prebuilt object file path.
612$(eval OBJS += $(MODULE_OBJS))
613
614$(ELF): $(OBJS) $(DEFAULT_LINKER_SCRIPT) $(LINKER_SCRIPTS) | $$$$(@D)/ libraries $(BL_LIBS)
615	$$(s)echo "  LD      $$@"
616ifeq ($($(ARCH)-ld-id),arm-link)
617	$$(q)$($(ARCH)-ld) -o $$@ $$(TF_LDFLAGS) $$(LDFLAGS) $(BL_LDFLAGS) --entry=${1}_entrypoint \
618		--predefine=$(call escape-shell,-D__LINKER__=$(__LINKER__)) \
619		--predefine=$(call escape-shell,-DTF_CFLAGS=$(TF_CFLAGS)) \
620		--map --list="$(MAPFILE)" --scatter=${PLAT_DIR}/scat/${1}.scat \
621		$(LDPATHS) $(LIBWRAPPER) $(LDLIBS) $(BL_LIBS) $(OBJS)
622else
623	$$(q)$($(ARCH)-ld) -o $$@ $$(TF_LDFLAGS) $$(LDFLAGS) $(BL_LDFLAGS) \
624		$(GNU_LINKER_ARGS) $(LDPATHS) \
625		$(call ld_prefix,--start-group) \
626			$(OBJS) $(LIBWRAPPER) $(LDLIBS) $(BL_LIBS) \
627		$(call ld_prefix,--end-group)
628endif
629ifeq ($(DISABLE_BIN_GENERATION),1)
630	$(s)echo
631	$(s)echo "Built $$@ successfully"
632	$(s)echo
633endif
634
635$(DUMP): $(ELF) | $$$$(@D)/
636	$$(s)echo "  OD      $$@"
637	$$(q)$($(ARCH)-od) -dx $$< > $$@
638
639$(BIN): $(ELF) | $$$$(@D)/
640	$$(s)echo "  BIN     $$@"
641	$$(q)$($(ARCH)-oc) -O binary $$< $$@
642	$(s)echo
643	$(s)echo "Built $$@ successfully"
644	$(s)echo
645
646.PHONY: $(1)
647ifeq ($(DISABLE_BIN_GENERATION),1)
648$(1): $(ELF) $(DUMP)
649else
650$(1): $(BIN) $(DUMP)
651endif
652
653all: $(1)
654
655ifeq ($(4),1)
656$(call ENCRYPT_FW,$(BIN),$(ENC_BIN))
657$(if $(2),$(call TOOL_ADD_IMG_PAYLOAD,$(BL),$(BIN),--$(2),$(ENC_BIN),$(3), \
658		$(ENC_BIN)))
659else
660$(if $(2),$(call TOOL_ADD_IMG_PAYLOAD,$(BL),$(BIN),--$(2),$(BIN),$(3)))
661endif
662
663endef
664
665# Convert device tree source file names to matching blobs
666#   $(1) = input dts
667define SOURCES_TO_DTBS
668        $(notdir $(patsubst %.dts,%.dtb,$(filter %.dts,$(1))))
669endef
670
671# MAKE_DTB generate the Flattened device tree binary
672#   $(1) = output directory
673#   $(2) = input dts
674define MAKE_DTB
675
676# List of DTB file(s) to generate, based on DTS file basename list
677$(eval DOBJ := $(addprefix $(1)/,$(call SOURCES_TO_DTBS,$(2))))
678# List of the pre-compiled DTS file(s)
679$(eval DPRE := $(addprefix $(1)/,$(patsubst %.dts,%.pre.dts,$(notdir $(2)))))
680# Dependencies of the pre-compiled DTS file(s) on its source and included files
681$(eval DTSDEP := $(patsubst %.dtb,%.o.d,$(DOBJ)))
682# Dependencies of the DT compilation on its pre-compiled DTS
683$(eval DTBDEP := $(patsubst %.dtb,%.d,$(DOBJ)))
684
685$(eval $(call MAKE_PRE,$(DPRE),$(2),$(DTSDEP),$(DTC_CPPFLAGS)))
686
687$(DOBJ): $(DPRE) $(filter-out %.d,$(MAKEFILE_LIST)) | $$$$(@D)/
688	$$(s)echo "  DTC     $$<"
689	$$(q)$($(ARCH)-dtc) $$(DTC_FLAGS) -d $(DTBDEP) -o $$@ $$<
690	$$($$@-after)
691
692-include $(DTBDEP)
693-include $(DTSDEP)
694
695endef
696
697# MAKE_DTBS builds flattened device tree sources
698#   $(1) = output directory
699#   $(2) = list of flattened device tree source files
700define MAKE_DTBS
701        $(eval DOBJS := $(filter %.dts,$(2)))
702        $(eval REMAIN := $(filter-out %.dts,$(2)))
703        $(and $(REMAIN),$(error FDT_SOURCES contain non-DTS files: $(REMAIN)))
704        $(eval $(foreach obj,$(DOBJS),$(call MAKE_DTB,$(1),$(obj))))
705
706dtbs: $(addprefix $(1)/,$(call SOURCES_TO_DTBS,$(2)))
707all: dtbs
708endef
709