build_template.mk 12 KB

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