xref: /aosp_15_r20/system/chre/build/build_template.mk (revision 84e339476a462649f82315436d70fd732297a399)
1#
2# Build Template
3#
4# Invoke this template with a set of variables in order to make build targets
5# for a build variant that targets a specific CPU architecture.
6#
7
8################################################################################
9#
10# Build Template
11#
12# Invoke this to instantiate a set of build targets. Two build targets are
13# produced by this template that can be either used directly or depended on to
14# perform post processing (ie: during a nanoapp build).
15#
16# TARGET_NAME_ar - An archive of the code compiled by this template.
17# TARGET_NAME_so - A shared object of the code compiled by this template.
18# TARGET_NAME    - A convenience target that depends on the above archive and
19#                  shared object targets.
20#
21# Nanoapps can optionally use the NANOAPP_LATE_CFLAGS variable to provide
22# compile flags, which will be added at the end of the compile command
23# (for instance, it can be used to override common flags in COMMON_CFLAGS).
24#
25# Argument List:
26#     $1  - TARGET_NAME          - The name of the target being built.
27#     $2  - TARGET_CFLAGS        - The compiler flags to use for this target.
28#     $3  - TARGET_CC            - The C/C++ compiler for the target variant.
29#     $4  - TARGET_SO_LDFLAGS    - The linker flags to use for this target.
30#     $5  - TARGET_LD            - The linker for the target variant.
31#     $6  - TARGET_ARFLAGS       - The archival flags to use for this target.
32#     $7  - TARGET_AR            - The archival tool for the targer variant.
33#     $8  - TARGET_VARIANT_SRCS  - Source files specific to this variant.
34#     $9  - TARGET_BUILD_BIN     - Build a binary. Typically this means that the
35#                                  source files provided include an entry point.
36#     $10 - TARGET_BIN_LDFLAGS   - Linker flags that are passed to the linker
37#                                  when building an executable binary.
38#     $11 - TARGET_SO_EARLY_LIBS - Link against a set of libraries when building
39#                                  a shared object or binary. These are placed
40#                                  before the objects produced by this build.
41#     $12 - TARGET_SO_LATE_LIBS  - Link against a set of libraries when building
42#                                  a shared object or binary. These are placed
43#                                  after the objects produced by this build.
44#     $13 - TARGET_PLATFORM_ID   - The ID of the platform that this nanoapp
45#                                  build targets.
46#     $14 - TARGET_ACONFIGFLAGS  - The list of aconfig flag value files specific
47#                                  to this build target
48#     $15 - TARGET_ADDITIONAL_LD - Additional linker for this target variant.
49#
50################################################################################
51
52ifndef BUILD_TEMPLATE
53define BUILD_TEMPLATE
54
55# Target Objects ###############################################################
56
57# Remove duplicates
58COMMON_SRCS := $(sort $(COMMON_SRCS))
59
60# Source files.
61$(1)_CC_SRCS = $$(filter %.cc, $(COMMON_SRCS) $(8))
62$(1)_CPP_SRCS = $$(filter %.cpp, $(COMMON_SRCS) $(8))
63$(1)_C_SRCS = $$(filter %.c, $(COMMON_SRCS) $(8))
64$(1)_S_SRCS = $$(filter %.S, $(COMMON_SRCS) $(8))
65
66# Object files.
67$(1)_OBJS_DIR = $(1)_objs
68$(1)_CC_OBJS = $$(patsubst %.cc, $(OUT)/$$($(1)_OBJS_DIR)/%.o, \
69                           $$($(1)_CC_SRCS))
70$(1)_CPP_OBJS = $$(patsubst %.cpp, $(OUT)/$$($(1)_OBJS_DIR)/%.o, \
71                            $$($(1)_CPP_SRCS))
72$(1)_C_OBJS = $$(patsubst %.c, $(OUT)/$$($(1)_OBJS_DIR)/%.o, \
73                          $$($(1)_C_SRCS))
74$(1)_S_OBJS = $$(patsubst %.S, $(OUT)/$$($(1)_OBJS_DIR)/%.o, \
75                          $$($(1)_S_SRCS))
76
77# Automatic dependency resolution Makefiles.
78$(1)_CC_DEPS = $$(patsubst %.cc, $(OUT)/$$($(1)_OBJS_DIR)/%.d, \
79                           $$($(1)_CC_SRCS))
80$(1)_CPP_DEPS = $$(patsubst %.cpp, $(OUT)/$$($(1)_OBJS_DIR)/%.d, \
81                            $$($(1)_CPP_SRCS))
82$(1)_C_DEPS = $$(patsubst %.c, $(OUT)/$$($(1)_OBJS_DIR)/%.d, \
83                          $$($(1)_C_SRCS))
84$(1)_S_DEPS = $$(patsubst %.S, $(OUT)/$$($(1)_OBJS_DIR)/%.d, \
85                          $$($(1)_S_SRCS))
86
87# Add object file directories.
88$(1)_DIRS = $$(sort $$(dir $$($(1)_CC_OBJS) \
89                           $$($(1)_CPP_OBJS) \
90                           $$($(1)_C_OBJS) \
91                           $$($(1)_S_OBJS)))
92
93# Outputs ######################################################################
94
95# Shared Object
96$(1)_SO = $(OUT)/$(1)/$(OUTPUT_NAME).so
97
98# Static Archive
99$(1)_AR = $(OUT)/$(1)/$(OUTPUT_NAME).a
100
101# Nanoapp Header
102$(1)_HEADER = $$(if $(IS_NANOAPP_BUILD), $(OUT)/$(1)/$(OUTPUT_NAME).napp_header, )
103
104# Optional Binary
105$(1)_BIN = $$(if $(9), $(OUT)/$(1)/$(OUTPUT_NAME), )
106
107# Optional token mapping
108$(1)_TOKEN_MAP = $$(if $(CHRE_TOKENIZED_LOGGING_ENABLED), \
109                    $(OUT)/$(1)/$(OUTPUT_NAME)_log_database.bin,)
110
111$(1)_TOKEN_MAP_CSV = $$(if $(CHRE_TOKENIZED_LOGGING_ENABLED), \
112                        $(OUT)/$(1)/$(OUTPUT_NAME)_log_database.csv,)
113
114# Top-level Build Rule #########################################################
115
116# Define the phony target.
117.PHONY: $(1)_ar
118$(1)_ar: $$($(1)_AR)
119
120.PHONY: $(1)_so
121$(1)_so: $$($(1)_SO)
122
123.PHONY: $(1)_bin
124$(1)_bin: $$($(1)_BIN)
125
126.PHONY: $(1)_header
127$(1)_header: $$($(1)_HEADER)
128
129.PHONY: $(1)_token_map
130$(1)_token_map: $$($(1)_TOKEN_MAP)
131
132.PHONY: $(1)_flags
133$(1)_flags: $$((1)_FLAGS)
134
135.PHONY: $(1)
136ifeq ($(IS_ARCHIVE_ONLY_BUILD),true)
137$(1): $(1)_flags $(1)_ar $(1)_token_map
138else
139$(1): $(1)_flags $(1)_ar $(1)_so $(1)_bin $(1)_header $(1)_token_map
140endif
141
142# If building the runtime, simply add the archive and shared object to the all
143# target. When building CHRE, it is expected that this runtime just be linked
144# into another build system (or the entire runtime is built using another build
145# system).
146ifeq ($(IS_NANOAPP_BUILD),)
147all: $(1)
148endif
149
150# Nanoapp Header Generation ####################################################
151
152#
153# Whoa there... what have we here? Some binary file generation ala bash? ಠ_ಠ
154#
155# The following build rule generates a nanoapp header. A nanoapp header is a
156# small binary blob that is prepended to a nanoapp. Android can parse this
157# blob to determine some attributes about the nanoapp, such as version and
158# target hub. The layout is as follows:
159#
160# struct NanoAppBinaryHeader {
161#   uint32_t headerVersion;        // 0x1 for this version
162#   uint32_t magic;                // "NANO"
163#   uint64_t appId;                // App Id, contains vendor id
164#   uint32_t appVersion;           // Version of the app
165#   uint32_t flags;                // Signed, encrypted, TCM-capable
166#   uint64_t hwHubType;            // Which hub type is this compiled for
167#   uint8_t targetChreApiMajorVersion; // CHRE API version
168#   uint8_t targetChreApiMinorVersion;
169#   uint8_t reserved[6];
170# } __attribute__((packed));
171#
172# The basic idea here is to generate a hexdump formatted file and then reverse
173# that hexdump into binary form. The way that is accomplished is as follows.
174#
175# ... Why tho?
176#
177# The build system has a lot of knowledge of what it is building: the name of
178# the nanoapp, the version and the app ID. Marshalling this data from the
179# Makefile environment into something like python or even a small C program
180# is an unnecessary step.
181#
182# For the flags field of the struct, the following values are currently defined:
183# Signed                 = 0x00000001
184# Encrypted              = 0x00000002
185# TCM-capable            = 0x00000004
186#
187# The highest order byte is reserved for platform-specific usage.
188
189$$($(1)_HEADER): $$(OUT)/$(1) $$($(1)_DIRS)
190	printf "00000000  %.8x " `$(BE_TO_LE_SCRIPT) 0x00000001` > $$@
191	printf "%.8x " `$(BE_TO_LE_SCRIPT) 0x4f4e414e` >> $$@
192	printf "%.16x\n" `$(BE_TO_LE_SCRIPT) $(NANOAPP_ID)` >> $$@
193	printf "00000010  %.8x " `$(BE_TO_LE_SCRIPT) $(NANOAPP_VERSION)` >> $$@
194	printf "%.8x " `$(BE_TO_LE_SCRIPT) $(TARGET_NANOAPP_FLAGS)` >> $$@
195	printf "%.16x\n" `$(BE_TO_LE_SCRIPT) $(13)` >> $$@
196	printf "00000020  %.2x " \
197	    `$(BE_TO_LE_SCRIPT) $(TARGET_CHRE_API_VERSION_MAJOR)` >> $$@
198	printf "%.2x " \
199	    `$(BE_TO_LE_SCRIPT) $(TARGET_CHRE_API_VERSION_MINOR)` >> $$@
200	printf "%.12x \n" `$(BE_TO_LE_SCRIPT) 0x000000` >> $$@
201	cp $$@ $$@_ascii
202	xxd -r $$@_ascii > $$@
203	rm $$@_ascii
204
205# Compile ######################################################################
206
207$$($(1)_CPP_OBJS): $(OUT)/$$($(1)_OBJS_DIR)/%.o: %.cpp $(MAKEFILE_LIST)
208	@echo " [CPP] $$<"
209	$(V)$(3) $(COMMON_CXX_CFLAGS) -DCHRE_FILENAME=\"$$(notdir $$<)\" $(2) -c \
210		$$< -o $$@
211
212$$($(1)_CC_OBJS): $(OUT)/$$($(1)_OBJS_DIR)/%.o: %.cc $(MAKEFILE_LIST)
213	@echo " [CC] $$<"
214	$(V)$(3) $(COMMON_CXX_CFLAGS) -DCHRE_FILENAME=\"$$(notdir $$<)\" $(2) -c \
215		$$< -o $$@
216
217$$($(1)_C_OBJS): $(OUT)/$$($(1)_OBJS_DIR)/%.o: %.c $(MAKEFILE_LIST)
218	@echo " [C] $$<"
219	$(V)$(3) $(COMMON_C_CFLAGS) -DCHRE_FILENAME=\"$$(notdir $$<)\" $(2) -c $$< \
220		-o $$@
221
222$$($(1)_S_OBJS): $(OUT)/$$($(1)_OBJS_DIR)/%.o: %.S $(MAKEFILE_LIST)
223	@echo " [AS] $$<"
224	$(V)$(3) -DCHRE_FILENAME=\"$$(notdir $$<)\" $(2) -c $$< \
225		-o $$@
226
227# Archive ######################################################################
228
229# Add common and target-specific archive flags.
230$(1)_ARFLAGS = $(COMMON_ARFLAGS) \
231    $(6)
232
233$$($(1)_AR): $$($(1)_CC_OBJS) $$($(1)_CPP_OBJS) $$($(1)_C_OBJS) \
234              $$($(1)_S_OBJS) | $$(OUT)/$(1) $$($(1)_DIRS)
235	@echo " [AR] $$@"
236	$(V)$(7) $$($(1)_ARFLAGS) $$@ $$(filter %.o, $$^)
237
238# Token Mapping ################################################################
239
240$$($(1)_TOKEN_MAP): $$($(1)_AR)
241	@echo " [TOKEN_MAP_GEN] $$@"
242	$(V)mkdir -p $$(@D)
243	$(V)$(TOKEN_MAP_GEN_CMD) $$($(1)_TOKEN_MAP) $$($(1)_AR) 2>&1
244	$(V)$(TOKEN_MAP_CSV_GEN_CMD) $$($(1)_TOKEN_MAP_CSV) $$($(1)_AR) 2>&1
245
246# Rust #########################################################################
247
248ifeq ($(IS_BUILD_REQUIRING_RUST),)
249RUST_DEPENDENCIES =
250else
251RUST_DEPENDENCIES = rust_archive_$(1)
252endif
253
254# Always invoke the cargo build, let cargo decide if updates are needed
255.PHONY: rust_archive_$(1)
256rust_archive_$(1):
257	@echo " [RUST_ARCHIVE] $$@"
258	$(RUST_FLAGS) cargo +nightly build -Z build-std=core,alloc \
259	    --$(RUST_OPT_LEVEL) --target $(RUST_TARGET_DIR)/$(RUST_TARGET).json
260
261# Aconfig Flag Generation ######################################################
262
263# This must be handled in the final build_template to allow for layers of flag
264# overwriting ( common > device_specific > local ).
265
266ifeq ($(IS_BUILD_REQUIRING_FLAG_LIBRARY),)
267FLAG_DEPENDENCIES =
268else
269FLAG_DEPENDENCIES = flagging_library_$(1)
270endif
271
272$$((1)_FLAGS): $(FLAG_DEPENDENCIES)
273
274.PHONY: flagging_library_$(1)
275flagging_library_$(1):
276	@echo " [ACONFIG] $$@"
277	$(ACONFIG_FLAG_BUILD_SCRIPT) $(ACONFIG_BIN) $(ACONFIG_EMB_DIR) \
278	    $(COMMON_ACONFIG_FLAG_VALUES) $(TARGET_ACONFIGFLAGS)
279
280# Link #########################################################################
281
282$$($(1)_SO): $$($(1)_CC_DEPS) \
283              $$($(1)_CPP_DEPS) $$($(1)_C_DEPS) $$($(1)_S_DEPS) \
284              $$($(1)_CC_OBJS) $$($(1)_CPP_OBJS) $$($(1)_C_OBJS) \
285              $$($(1)_S_OBJS) $(RUST_DEPENDENCIES) | $$(OUT)/$(1) $$($(1)_DIRS)
286	$(5) $(4) -o $$@ $(11) $$(filter %.o, $$^) $(12) $(15)
287
288$$($(1)_BIN): $$($(1)_CC_DEPS) \
289               $$($(1)_CPP_DEPS) $$($(1)_C_DEPS) $$($(1)_S_DEPS) \
290               $$($(1)_CC_OBJS) $$($(1)_CPP_OBJS) $$($(1)_C_OBJS) \
291               $$($(1)_S_OBJS) | $$(OUT)/$(1) $$($(1)_DIRS)
292	$(V)$(3) -o $$@ $(11) $$(filter %.o, $$^) $(12) $(10)
293
294# Output Directories ###########################################################
295
296$$($$$(1)_DIRS):
297	$(V)mkdir -p $$@
298
299$$(OUT)/$(1):
300	$(V)mkdir -p $$@
301
302# Automatic Dependency Resolution ##############################################
303
304$$($(1)_CC_DEPS): $(OUT)/$$($(1)_OBJS_DIR)/%.d: %.cc
305	$(V)mkdir -p $$(dir $$@)
306	$(V)$(3) $(DEP_CFLAGS) $(COMMON_CXX_CFLAGS) \
307		-DCHRE_FILENAME=\"$$(notdir $$<)\" $(2) -c $$< -o $$@
308
309$$($(1)_CPP_DEPS): $(OUT)/$$($(1)_OBJS_DIR)/%.d: %.cpp
310	$(V)mkdir -p $$(dir $$@)
311	$(V)$(3) $(DEP_CFLAGS) $(COMMON_CXX_CFLAGS) \
312		-DCHRE_FILENAME=\"$$(notdir $$<)\" $(2) -c $$< -o $$@
313
314$$($(1)_C_DEPS): $(OUT)/$$($(1)_OBJS_DIR)/%.d: %.c
315	$(V)mkdir -p $$(dir $$@)
316	$(V)$(3) $(DEP_CFLAGS) $(COMMON_C_CFLAGS) \
317		-DCHRE_FILENAME=\"$$(notdir $$<)\" $(2) -c $$< -o $$@
318
319$$($(1)_S_DEPS): $(OUT)/$$($(1)_OBJS_DIR)/%.d: %.S
320	$(V)mkdir -p $$(dir $$@)
321	$(V)$(3) $(DEP_CFLAGS) \
322		-DCHRE_FILENAME=\"$$(notdir $$<)\" $(2) -c $$< -o $$@
323
324# Include generated dependency files if they are in the requested build target.
325# This avoids dependency generation from occuring for a debug target when a
326# non-debug target is requested.
327ifneq ($(filter $(1) all, $(MAKECMDGOALS)),)
328-include $$(patsubst %.o, %.d, $$($(1)_CC_DEPS))
329-include $$(patsubst %.o, %.d, $$($(1)_CPP_DEPS))
330-include $$(patsubst %.o, %.d, $$($(1)_C_DEPS))
331-include $$(patsubst %.o, %.d, $$($(1)_S_DEPS))
332endif
333
334endef
335endif
336
337# Template Invocation ##########################################################
338
339TARGET_CFLAGS_LOCAL = $(TARGET_CFLAGS)
340TARGET_CFLAGS_LOCAL += -DCHRE_PLATFORM_ID=$(TARGET_PLATFORM_ID)
341
342# Default the nanoapp header flag values to signed if not overidden.
343TARGET_NANOAPP_FLAGS ?= 0x00000001
344$(eval $(call BUILD_TEMPLATE,$(TARGET_NAME), \
345                             $(COMMON_CFLAGS) $(TARGET_CFLAGS_LOCAL) \
346                                 $(NANOAPP_LATE_CFLAGS), \
347                             $(TARGET_CC), \
348                             $(TARGET_SO_LDFLAGS), \
349                             $(TARGET_LD), \
350                             $(TARGET_ARFLAGS), \
351                             $(TARGET_AR), \
352                             $(TARGET_VARIANT_SRCS), \
353                             $(TARGET_BUILD_BIN), \
354                             $(TARGET_BIN_LDFLAGS), \
355                             $(TARGET_SO_EARLY_LIBS), \
356                             $(TARGET_SO_LATE_LIBS), \
357                             $(TARGET_PLATFORM_ID), \
358                             $(TARGET_ACONFIGFLAGS), \
359                             $(TARGET_ADDITIONAL_LD)))
360
361# Debug Template Invocation ####################################################
362
363$(eval $(call BUILD_TEMPLATE,$(TARGET_NAME)_debug, \
364                             $(COMMON_CFLAGS) $(COMMON_DEBUG_CFLAGS) \
365                                 $(TARGET_CFLAGS_LOCAL) $(TARGET_DEBUG_CFLAGS) \
366                                 $(NANOAPP_LATE_CFLAGS), \
367                             $(TARGET_CC), \
368                             $(TARGET_SO_LDFLAGS), \
369                             $(TARGET_LD), \
370                             $(TARGET_ARFLAGS), \
371                             $(TARGET_AR), \
372                             $(TARGET_VARIANT_SRCS), \
373                             $(TARGET_BUILD_BIN), \
374                             $(TARGET_BIN_LDFLAGS), \
375                             $(TARGET_SO_EARLY_LIBS), \
376                             $(TARGET_SO_LATE_LIBS), \
377                             $(TARGET_PLATFORM_ID), \
378                             $(TARGET_ACONFIGFLAGS), \
379                             $(TARGET_ADDITIONAL_LD)))
380