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