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