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