process_bundle.py 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. # Copyright 2024 Google LLC
  2. #
  3. # Licensed under the Apache License, Version 2.0 (the "License");
  4. # you may not use this file except in compliance with the License.
  5. # You may obtain a copy of the License at
  6. #
  7. # http://www.apache.org/licenses/LICENSE-2.0
  8. #
  9. # Unless required by applicable law or agreed to in writing, software
  10. # distributed under the License is distributed on an "AS IS" BASIS,
  11. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. # See the License for the specific language governing permissions and
  13. # limitations under the License.
  14. import os
  15. from waflib import Task
  16. from waflib.TaskGen import feature
  17. import mkbundle
  18. from pebble_package import LibraryPackage
  19. from process_elf import generate_bin_file
  20. from resources.types.resource_ball import ResourceBall
  21. @Task.update_outputs
  22. class lib_package(Task.Task):
  23. """
  24. Task class to generate a library bundle for distribution
  25. """
  26. def run(self):
  27. """
  28. This method executes when the package task runs
  29. :return: N/A
  30. """
  31. bld = self.generator.bld
  32. build_dir = bld.bldnode
  33. includes = {include.path_from(build_dir.find_node('include')): include.abspath()
  34. for include in getattr(self, 'includes', [])}
  35. binaries = {binary.path_from(build_dir): binary.abspath()
  36. for binary in getattr(self, 'binaries', [])}
  37. js = {js.path_from(build_dir.find_node('js')): js.abspath()
  38. for js in getattr(self, 'js', [])}
  39. resource_definitions = []
  40. for resball in getattr(self, 'resources', []):
  41. resource_definitions.extend(ResourceBall.load(resball.abspath()).get_all_declarations())
  42. reso_list = []
  43. for definition in resource_definitions:
  44. if definition.target_platforms:
  45. platforms = list(set(definition.target_platforms) & set(bld.env.TARGET_PLATFORMS))
  46. else:
  47. platforms = bld.env.TARGET_PLATFORMS
  48. for platform in platforms:
  49. platform_path = build_dir.find_node(bld.all_envs[platform].BUILD_DIR).relpath()
  50. reso_list.append(build_dir.find_node("{}.{}.reso".format(
  51. os.path.join(platform_path,
  52. bld.path.find_node(definition.sources[0]).relpath()),
  53. str(definition.name)
  54. )))
  55. resources = {
  56. os.path.join(resource.path_from(build_dir).split('/', 1)[0],
  57. resource.path_from(build_dir).split('/', 3)[3]): resource.abspath()
  58. for resource in reso_list}
  59. package = LibraryPackage(self.outputs[0].abspath())
  60. package.add_files(includes=includes, binaries=binaries, resources=resources, js=js)
  61. package.pack()
  62. @Task.update_outputs
  63. class app_bundle(Task.Task):
  64. """
  65. Task class to generate an app bundle for distribution
  66. """
  67. def run(self):
  68. """
  69. This method executes when the bundle task runs
  70. :return: N/A
  71. """
  72. binaries = getattr(self, 'bin_files')
  73. js_files = getattr(self, 'js_files')
  74. outfile = self.outputs[0].abspath()
  75. mkbundle.make_watchapp_bundle(
  76. timestamp=self.generator.bld.env.TIMESTAMP,
  77. appinfo=self.generator.bld.path.get_bld().find_node('appinfo.json').abspath(),
  78. binaries=binaries,
  79. js=[js_file.abspath() for js_file in js_files],
  80. outfile=outfile
  81. )
  82. @feature('package')
  83. def make_lib_bundle(task_gen):
  84. """
  85. Bundle the build artifacts into a distributable library package.
  86. Keyword arguments:
  87. js -- A list of javascript files to package into the resulting bundle
  88. includes -- A list of header files to package into library bundle
  89. :param task_gen: the task generator instance
  90. :return: None
  91. """
  92. js = task_gen.to_nodes(getattr(task_gen, 'js', []))
  93. includes = task_gen.to_nodes(getattr(task_gen, 'includes', []))
  94. resources = []
  95. binaries = []
  96. for platform in task_gen.bld.env.TARGET_PLATFORMS:
  97. bld_dir = task_gen.path.get_bld().find_or_declare(platform)
  98. env = task_gen.bld.all_envs[platform]
  99. resources.append(getattr(env, 'PROJECT_RESBALL'))
  100. project_name = env.PROJECT_INFO['name']
  101. if project_name.startswith('@'):
  102. scoped_name = project_name.rsplit('/', 1)
  103. binaries.append(
  104. bld_dir.find_or_declare(str(scoped_name[0])).
  105. find_or_declare("lib{}.a".format(scoped_name[1])))
  106. else:
  107. binaries.append(bld_dir.find_or_declare("lib{}.a".format(project_name)))
  108. task = task_gen.create_task('lib_package',
  109. [],
  110. task_gen.bld.path.make_node(task_gen.bld.env.BUNDLE_NAME))
  111. task.js = js
  112. task.includes = includes
  113. task.resources = resources
  114. task.binaries = binaries
  115. task.dep_nodes = js + includes + resources + binaries
  116. # PBL-40925 Use pebble_package.py instead of mkbundle.py
  117. @feature('bundle')
  118. def make_pbl_bundle(task_gen):
  119. """
  120. Bundle the build artifacts into a distributable package.
  121. Keyword arguments:
  122. js -- A list of javascript files to package into the resulting bundle
  123. binaries -- A list of the binaries for each platform to include in the bundle
  124. :param task_gen: the task generator instance
  125. :return: None
  126. """
  127. bin_files = []
  128. bundle_sources = []
  129. js_files = getattr(task_gen, 'js', [])
  130. has_pkjs = bool(getattr(task_gen, 'js', False))
  131. if has_pkjs:
  132. bundle_sources.extend(task_gen.to_nodes(task_gen.js))
  133. cached_env = task_gen.bld.env
  134. if hasattr(task_gen, 'bin_type') and task_gen.bin_type == 'rocky':
  135. binaries = []
  136. for platform in task_gen.bld.env.TARGET_PLATFORMS:
  137. binaries.append({"platform": platform,
  138. "app_elf": "{}/pebble-app.elf".format(
  139. task_gen.bld.all_envs[platform].BUILD_DIR)})
  140. rocky_source_node = task_gen.bld.path.get_bld().make_node('resources/rocky-app.js')
  141. js_files.append(rocky_source_node)
  142. bundle_sources.append(rocky_source_node)
  143. else:
  144. binaries = task_gen.binaries
  145. for binary in binaries:
  146. task_gen.bld.env = task_gen.bld.all_envs[binary['platform']]
  147. platform_build_node = task_gen.bld.path.find_or_declare(task_gen.bld.env.BUILD_DIR)
  148. app_elf_file = task_gen.bld.path.get_bld().make_node(binary['app_elf'])
  149. if app_elf_file is None:
  150. raise Exception("Must specify elf argument to bundle")
  151. worker_bin_file = None
  152. if 'worker_elf' in binary:
  153. worker_elf_file = task_gen.bld.path.get_bld().make_node(binary['worker_elf'])
  154. app_bin_file = generate_bin_file(task_gen, 'app', app_elf_file, has_pkjs,
  155. has_worker=True)
  156. worker_bin_file = generate_bin_file(task_gen, 'worker', worker_elf_file, has_pkjs,
  157. has_worker=True)
  158. bundle_sources.append(worker_bin_file)
  159. else:
  160. app_bin_file = generate_bin_file(task_gen, 'app', app_elf_file, has_pkjs,
  161. has_worker=False)
  162. resources_pack = platform_build_node.make_node('app_resources.pbpack')
  163. bundle_sources.extend([app_bin_file, resources_pack])
  164. bin_files.append({'watchapp': app_bin_file.abspath(),
  165. 'resources': resources_pack.abspath(),
  166. 'worker_bin': worker_bin_file.abspath() if worker_bin_file else None,
  167. 'sdk_version': {'major': task_gen.bld.env.SDK_VERSION_MAJOR,
  168. 'minor': task_gen.bld.env.SDK_VERSION_MINOR},
  169. 'subfolder': task_gen.bld.env.BUNDLE_BIN_DIR})
  170. task_gen.bld.env = cached_env
  171. bundle_output = task_gen.bld.path.get_bld().make_node(task_gen.bld.env.BUNDLE_NAME)
  172. task = task_gen.create_task('app_bundle', [], bundle_output)
  173. task.bin_files = bin_files
  174. task.js_files = js_files
  175. task.dep_nodes = bundle_sources