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# 47################################################################################ 48 49ifndef BUILD_TEMPLATE 50define BUILD_TEMPLATE 51 52# Target Objects ############################################################### 53 54# Source files. 55$(1)_CC_SRCS = $$(filter %.cc, $(COMMON_SRCS) $(8)) 56$(1)_CPP_SRCS = $$(filter %.cpp, $(COMMON_SRCS) $(8)) 57$(1)_C_SRCS = $$(filter %.c, $(COMMON_SRCS) $(8)) 58$(1)_S_SRCS = $$(filter %.S, $(COMMON_SRCS) $(8)) 59 60# Object files. 61$(1)_OBJS_DIR = $(1)_objs 62$(1)_CC_OBJS = $$(patsubst %.cc, $(OUT)/$$($(1)_OBJS_DIR)/%.o, \ 63 $$($(1)_CC_SRCS)) 64$(1)_CPP_OBJS = $$(patsubst %.cpp, $(OUT)/$$($(1)_OBJS_DIR)/%.o, \ 65 $$($(1)_CPP_SRCS)) 66$(1)_C_OBJS = $$(patsubst %.c, $(OUT)/$$($(1)_OBJS_DIR)/%.o, \ 67 $$($(1)_C_SRCS)) 68$(1)_S_OBJS = $$(patsubst %.S, $(OUT)/$$($(1)_OBJS_DIR)/%.o, \ 69 $$($(1)_S_SRCS)) 70 71# Automatic dependency resolution Makefiles. 72$(1)_CC_DEPS = $$(patsubst %.cc, $(OUT)/$$($(1)_OBJS_DIR)/%.d, \ 73 $$($(1)_CC_SRCS)) 74$(1)_CPP_DEPS = $$(patsubst %.cpp, $(OUT)/$$($(1)_OBJS_DIR)/%.d, \ 75 $$($(1)_CPP_SRCS)) 76$(1)_C_DEPS = $$(patsubst %.c, $(OUT)/$$($(1)_OBJS_DIR)/%.d, \ 77 $$($(1)_C_SRCS)) 78$(1)_S_DEPS = $$(patsubst %.S, $(OUT)/$$($(1)_OBJS_DIR)/%.d, \ 79 $$($(1)_S_SRCS)) 80 81# Add object file directories. 82$(1)_DIRS = $$(sort $$(dir $$($(1)_CC_OBJS) \ 83 $$($(1)_CPP_OBJS) \ 84 $$($(1)_C_OBJS) \ 85 $$($(1)_S_OBJS))) 86 87# Outputs ###################################################################### 88 89# Shared Object 90$(1)_SO = $(OUT)/$(1)/$(OUTPUT_NAME).so 91 92# Static Archive 93$(1)_AR = $(OUT)/$(1)/$(OUTPUT_NAME).a 94 95# Nanoapp Header 96$(1)_HEADER = $$(if $(IS_NANOAPP_BUILD), $(OUT)/$(1)/$(OUTPUT_NAME).napp_header, ) 97 98# Optional Binary 99$(1)_BIN = $$(if $(9), $(OUT)/$(1)/$(OUTPUT_NAME), ) 100 101# Optional token mapping 102$(1)_TOKEN_MAP = $$(if $(CHRE_TOKENIZED_LOGGING_ENABLED), \ 103 $(OUT)/$(1)/$(OUTPUT_NAME)_log_database.bin,) 104 105$(1)_TOKEN_MAP_CSV = $$(if $(CHRE_TOKENIZED_LOGGING_ENABLED), \ 106 $(OUT)/$(1)/$(OUTPUT_NAME)_log_database.csv,) 107 108# Top-level Build Rule ######################################################### 109 110# Define the phony target. 111.PHONY: $(1)_ar 112$(1)_ar: $$($(1)_AR) 113 114.PHONY: $(1)_so 115$(1)_so: $$($(1)_SO) 116 117.PHONY: $(1)_bin 118$(1)_bin: $$($(1)_BIN) 119 120.PHONY: $(1)_header 121$(1)_header: $$($(1)_HEADER) 122 123.PHONY: $(1)_token_map 124$(1)_token_map: $$($(1)_TOKEN_MAP) 125 126.PHONY: $(1) 127ifeq ($(IS_ARCHIVE_ONLY_BUILD),true) 128$(1): $(1)_ar $(1)_token_map 129else 130$(1): $(1)_ar $(1)_so $(1)_bin $(1)_header $(1)_token_map 131endif 132 133# If building the runtime, simply add the archive and shared object to the all 134# target. When building CHRE, it is expected that this runtime just be linked 135# into another build system (or the entire runtime is built using another build 136# system). 137ifeq ($(IS_NANOAPP_BUILD),) 138all: $(1) 139endif 140 141# Nanoapp Header Generation #################################################### 142 143# 144# Whoa there... what have we here? Some binary file generation ala bash? ಠ_ಠ 145# 146# The following build rule generates a nanoapp header. A nanoapp header is a 147# small binary blob that is prepended to a nanoapp. Android can parse this 148# blob to determine some attributes about the nanoapp, such as version and 149# target hub. The layout is as follows: 150# 151# struct NanoAppBinaryHeader { 152# uint32_t headerVersion; // 0x1 for this version 153# uint32_t magic; // "NANO" 154# uint64_t appId; // App Id, contains vendor id 155# uint32_t appVersion; // Version of the app 156# uint32_t flags; // Signed, encrypted, TCM-capable 157# uint64_t hwHubType; // Which hub type is this compiled for 158# uint8_t targetChreApiMajorVersion; // CHRE API version 159# uint8_t targetChreApiMinorVersion; 160# uint8_t reserved[6]; 161# } __attribute__((packed)); 162# 163# The basic idea here is to generate a hexdump formatted file and then reverse 164# that hexdump into binary form. The way that is accomplished is as follows. 165# 166# ... Why tho? 167# 168# The build system has a lot of knowledge of what it is building: the name of 169# the nanoapp, the version and the app ID. Marshalling this data from the 170# Makefile environment into something like python or even a small C program 171# is an unnecessary step. 172# 173# For the flags field of the struct, the following values are currently defined: 174# Signed = 0x00000001 175# Encrypted = 0x00000002 176# TCM-capable = 0x00000004 177# 178# The highest order byte is reserved for platform-specific usage. 179 180$$($(1)_HEADER): $$(OUT)/$(1) $$($(1)_DIRS) 181 printf "00000000 %.8x " `$(BE_TO_LE_SCRIPT) 0x00000001` > $$@ 182 printf "%.8x " `$(BE_TO_LE_SCRIPT) 0x4f4e414e` >> $$@ 183 printf "%.16x\n" `$(BE_TO_LE_SCRIPT) $(NANOAPP_ID)` >> $$@ 184 printf "00000010 %.8x " `$(BE_TO_LE_SCRIPT) $(NANOAPP_VERSION)` >> $$@ 185 printf "%.8x " `$(BE_TO_LE_SCRIPT) $(TARGET_NANOAPP_FLAGS)` >> $$@ 186 printf "%.16x\n" `$(BE_TO_LE_SCRIPT) $(13)` >> $$@ 187 printf "00000020 %.2x " \ 188 `$(BE_TO_LE_SCRIPT) $(TARGET_CHRE_API_VERSION_MAJOR)` >> $$@ 189 printf "%.2x " \ 190 `$(BE_TO_LE_SCRIPT) $(TARGET_CHRE_API_VERSION_MINOR)` >> $$@ 191 printf "%.12x \n" `$(BE_TO_LE_SCRIPT) 0x000000` >> $$@ 192 cp $$@ $$@_ascii 193 xxd -r $$@_ascii > $$@ 194 rm $$@_ascii 195 196# Compile ###################################################################### 197 198$$($(1)_CPP_OBJS): $(OUT)/$$($(1)_OBJS_DIR)/%.o: %.cpp $(MAKEFILE_LIST) 199 @echo " [CPP] $$<" 200 $(V)$(3) $(COMMON_CXX_CFLAGS) -DCHRE_FILENAME=\"$$(notdir $$<)\" $(2) -c \ 201 $$< -o $$@ 202 203$$($(1)_CC_OBJS): $(OUT)/$$($(1)_OBJS_DIR)/%.o: %.cc $(MAKEFILE_LIST) 204 @echo " [CC] $$<" 205 $(V)$(3) $(COMMON_CXX_CFLAGS) -DCHRE_FILENAME=\"$$(notdir $$<)\" $(2) -c \ 206 $$< -o $$@ 207 208$$($(1)_C_OBJS): $(OUT)/$$($(1)_OBJS_DIR)/%.o: %.c $(MAKEFILE_LIST) 209 @echo " [C] $$<" 210 $(V)$(3) $(COMMON_C_CFLAGS) -DCHRE_FILENAME=\"$$(notdir $$<)\" $(2) -c $$< \ 211 -o $$@ 212 213$$($(1)_S_OBJS): $(OUT)/$$($(1)_OBJS_DIR)/%.o: %.S $(MAKEFILE_LIST) 214 @echo " [AS] $$<" 215 $(V)$(3) -DCHRE_FILENAME=\"$$(notdir $$<)\" $(2) -c $$< \ 216 -o $$@ 217 218# Archive ###################################################################### 219 220# Add common and target-specific archive flags. 221$(1)_ARFLAGS = $(COMMON_ARFLAGS) \ 222 $(6) 223 224$$($(1)_AR): $$($(1)_CC_OBJS) $$($(1)_CPP_OBJS) $$($(1)_C_OBJS) \ 225 $$($(1)_S_OBJS) | $$(OUT)/$(1) $$($(1)_DIRS) 226 @echo " [AR] $$@" 227 $(V)$(7) $$($(1)_ARFLAGS) $$@ $$(filter %.o, $$^) 228 229# Token Mapping ################################################################ 230 231$$($(1)_TOKEN_MAP): $$($(1)_AR) 232 @echo " [TOKEN_MAP_GEN] $<" 233 $(V)mkdir -p $(OUT)/$(1) 234 $(V)$(TOKEN_MAP_GEN_CMD) $$($(1)_TOKEN_MAP) $$($(1)_AR) 235 $(V)$(TOKEN_MAP_CSV_GEN_CMD) $$($(1)_TOKEN_MAP_CSV) $$($(1)_AR) 236 237# Link ######################################################################### 238 239$$($(1)_SO): $$($(1)_CC_DEPS) \ 240 $$($(1)_CPP_DEPS) $$($(1)_C_DEPS) $$($(1)_S_DEPS) \ 241 $$($(1)_CC_OBJS) $$($(1)_CPP_OBJS) $$($(1)_C_OBJS) \ 242 $$($(1)_S_OBJS) | $$(OUT)/$(1) $$($(1)_DIRS) 243 $(V)$(5) $(4) -o $$@ $(11) $$(filter %.o, $$^) $(12) 244 245$$($(1)_BIN): $$($(1)_CC_DEPS) \ 246 $$($(1)_CPP_DEPS) $$($(1)_C_DEPS) $$($(1)_S_DEPS) \ 247 $$($(1)_CC_OBJS) $$($(1)_CPP_OBJS) $$($(1)_C_OBJS) \ 248 $$($(1)_S_OBJS) | $$(OUT)/$(1) $$($(1)_DIRS) 249 $(V)$(3) -o $$@ $(11) $$(filter %.o, $$^) $(12) $(10) 250 251# Output Directories ########################################################### 252 253$$($$$(1)_DIRS): 254 $(V)mkdir -p $$@ 255 256$$(OUT)/$(1): 257 $(V)mkdir -p $$@ 258 259# Automatic Dependency Resolution ############################################## 260 261$$($(1)_CC_DEPS): $(OUT)/$$($(1)_OBJS_DIR)/%.d: %.cc 262 $(V)mkdir -p $$(dir $$@) 263 $(V)$(3) $(DEP_CFLAGS) $(COMMON_CXX_CFLAGS) \ 264 -DCHRE_FILENAME=\"$$(notdir $$<)\" $(2) -c $$< -o $$@ 265 266$$($(1)_CPP_DEPS): $(OUT)/$$($(1)_OBJS_DIR)/%.d: %.cpp 267 $(V)mkdir -p $$(dir $$@) 268 $(V)$(3) $(DEP_CFLAGS) $(COMMON_CXX_CFLAGS) \ 269 -DCHRE_FILENAME=\"$$(notdir $$<)\" $(2) -c $$< -o $$@ 270 271$$($(1)_C_DEPS): $(OUT)/$$($(1)_OBJS_DIR)/%.d: %.c 272 $(V)mkdir -p $$(dir $$@) 273 $(V)$(3) $(DEP_CFLAGS) $(COMMON_C_CFLAGS) \ 274 -DCHRE_FILENAME=\"$$(notdir $$<)\" $(2) -c $$< -o $$@ 275 276$$($(1)_S_DEPS): $(OUT)/$$($(1)_OBJS_DIR)/%.d: %.S 277 $(V)mkdir -p $$(dir $$@) 278 $(V)$(3) $(DEP_CFLAGS) \ 279 -DCHRE_FILENAME=\"$$(notdir $$<)\" $(2) -c $$< -o $$@ 280 281# Include generated dependency files if they are in the requested build target. 282# This avoids dependency generation from occuring for a debug target when a 283# non-debug target is requested. 284ifneq ($(filter $(1) all, $(MAKECMDGOALS)),) 285-include $$(patsubst %.o, %.d, $$($(1)_CC_DEPS)) 286-include $$(patsubst %.o, %.d, $$($(1)_CPP_DEPS)) 287-include $$(patsubst %.o, %.d, $$($(1)_C_DEPS)) 288-include $$(patsubst %.o, %.d, $$($(1)_S_DEPS)) 289endif 290 291endef 292endif 293 294# Template Invocation ########################################################## 295 296TARGET_CFLAGS_LOCAL = $(TARGET_CFLAGS) 297TARGET_CFLAGS_LOCAL += -DCHRE_PLATFORM_ID=$(TARGET_PLATFORM_ID) 298 299# Default the nanoapp header flag values to signed if not overidden. 300TARGET_NANOAPP_FLAGS ?= 0x00000001 301$(eval $(call BUILD_TEMPLATE,$(TARGET_NAME), \ 302 $(COMMON_CFLAGS) $(TARGET_CFLAGS_LOCAL) \ 303 $(NANOAPP_LATE_CFLAGS), \ 304 $(TARGET_CC), \ 305 $(TARGET_SO_LDFLAGS), \ 306 $(TARGET_LD), \ 307 $(TARGET_ARFLAGS), \ 308 $(TARGET_AR), \ 309 $(TARGET_VARIANT_SRCS), \ 310 $(TARGET_BUILD_BIN), \ 311 $(TARGET_BIN_LDFLAGS), \ 312 $(TARGET_SO_EARLY_LIBS), \ 313 $(TARGET_SO_LATE_LIBS), \ 314 $(TARGET_PLATFORM_ID))) 315 316# Debug Template Invocation #################################################### 317 318$(eval $(call BUILD_TEMPLATE,$(TARGET_NAME)_debug, \ 319 $(COMMON_CFLAGS) $(COMMON_DEBUG_CFLAGS) \ 320 $(TARGET_CFLAGS_LOCAL) $(TARGET_DEBUG_CFLAGS) \ 321 $(NANOAPP_LATE_CFLAGS), \ 322 $(TARGET_CC), \ 323 $(TARGET_SO_LDFLAGS), \ 324 $(TARGET_LD), \ 325 $(TARGET_ARFLAGS), \ 326 $(TARGET_AR), \ 327 $(TARGET_VARIANT_SRCS), \ 328 $(TARGET_BUILD_BIN), \ 329 $(TARGET_BIN_LDFLAGS), \ 330 $(TARGET_SO_EARLY_LIBS), \ 331 $(TARGET_SO_LATE_LIBS), \ 332 $(TARGET_PLATFORM_ID))) 333