openubmc-bingo 0.5.240__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of openubmc-bingo might be problematic. Click here for more details.

Files changed (242) hide show
  1. bmcgo/__init__.py +12 -0
  2. bmcgo/bmcgo.py +22 -0
  3. bmcgo/bmcgo_config.py +176 -0
  4. bmcgo/cli/__init__.py +10 -0
  5. bmcgo/cli/cli.py +584 -0
  6. bmcgo/codegen/__init__.py +14 -0
  7. bmcgo/codegen/c/__init__.py +9 -0
  8. bmcgo/codegen/c/annotation.py +52 -0
  9. bmcgo/codegen/c/argument.py +42 -0
  10. bmcgo/codegen/c/codegen.py +153 -0
  11. bmcgo/codegen/c/comment.py +22 -0
  12. bmcgo/codegen/c/ctype_defination.py +353 -0
  13. bmcgo/codegen/c/helper.py +87 -0
  14. bmcgo/codegen/c/interface.py +63 -0
  15. bmcgo/codegen/c/method.py +82 -0
  16. bmcgo/codegen/c/property.py +180 -0
  17. bmcgo/codegen/c/renderer.py +21 -0
  18. bmcgo/codegen/c/signal.py +64 -0
  19. bmcgo/codegen/c/template/client.c.mako +145 -0
  20. bmcgo/codegen/c/template/client.h.mako +36 -0
  21. bmcgo/codegen/c/template/interface.c.mako +0 -0
  22. bmcgo/codegen/c/template/interface.introspect.xml.mako +99 -0
  23. bmcgo/codegen/c/template/micro_component.c.mako +32 -0
  24. bmcgo/codegen/c/template/public.c.mako +228 -0
  25. bmcgo/codegen/c/template/public.h.mako +128 -0
  26. bmcgo/codegen/c/template/server.c.mako +104 -0
  27. bmcgo/codegen/c/template/server.h.mako +36 -0
  28. bmcgo/codegen/lua/.lua-format +7 -0
  29. bmcgo/codegen/lua/Makefile +101 -0
  30. bmcgo/codegen/lua/__init__.py +9 -0
  31. bmcgo/codegen/lua/codegen.py +171 -0
  32. bmcgo/codegen/lua/proto/Makefile +87 -0
  33. bmcgo/codegen/lua/proto/ipmi_types.proto +17 -0
  34. bmcgo/codegen/lua/proto/types.proto +52 -0
  35. bmcgo/codegen/lua/script/check_intfs.py +161 -0
  36. bmcgo/codegen/lua/script/dto/__init__.py +11 -0
  37. bmcgo/codegen/lua/script/dto/exception.py +53 -0
  38. bmcgo/codegen/lua/script/dto/kepler_abstract.py +47 -0
  39. bmcgo/codegen/lua/script/dto/options.py +33 -0
  40. bmcgo/codegen/lua/script/dto/print_simple.py +19 -0
  41. bmcgo/codegen/lua/script/dto/redfish_api.py +241 -0
  42. bmcgo/codegen/lua/script/dto/url_route.py +195 -0
  43. bmcgo/codegen/lua/script/gen_db_json.py +444 -0
  44. bmcgo/codegen/lua/script/gen_depends.py +89 -0
  45. bmcgo/codegen/lua/script/gen_entry.py +263 -0
  46. bmcgo/codegen/lua/script/gen_feature_json.py +156 -0
  47. bmcgo/codegen/lua/script/gen_historical_local_db_json.py +88 -0
  48. bmcgo/codegen/lua/script/gen_intf_json.py +261 -0
  49. bmcgo/codegen/lua/script/gen_intf_rpc_json.py +575 -0
  50. bmcgo/codegen/lua/script/gen_ipmi_json.py +485 -0
  51. bmcgo/codegen/lua/script/gen_mdb_json.py +117 -0
  52. bmcgo/codegen/lua/script/gen_rpc_msg_json.py +487 -0
  53. bmcgo/codegen/lua/script/gen_schema.py +302 -0
  54. bmcgo/codegen/lua/script/ipmi_types_pb2.py +135 -0
  55. bmcgo/codegen/lua/script/loader/__init__.py +11 -0
  56. bmcgo/codegen/lua/script/loader/file_utils.py +33 -0
  57. bmcgo/codegen/lua/script/loader/kepler_abstract_collect.py +79 -0
  58. bmcgo/codegen/lua/script/loader/kepler_abstract_loader.py +47 -0
  59. bmcgo/codegen/lua/script/loader/redfish_loader.py +127 -0
  60. bmcgo/codegen/lua/script/lua_format.py +62 -0
  61. bmcgo/codegen/lua/script/mds_util.py +385 -0
  62. bmcgo/codegen/lua/script/merge_model.py +330 -0
  63. bmcgo/codegen/lua/script/merge_proto_algo.py +85 -0
  64. bmcgo/codegen/lua/script/proto_loader.py +47 -0
  65. bmcgo/codegen/lua/script/proto_plugin.py +140 -0
  66. bmcgo/codegen/lua/script/redfish_source_tree.py +118 -0
  67. bmcgo/codegen/lua/script/render_utils/__init__.py +38 -0
  68. bmcgo/codegen/lua/script/render_utils/base.py +25 -0
  69. bmcgo/codegen/lua/script/render_utils/client_lua.py +98 -0
  70. bmcgo/codegen/lua/script/render_utils/controller_lua.py +71 -0
  71. bmcgo/codegen/lua/script/render_utils/db_lua.py +224 -0
  72. bmcgo/codegen/lua/script/render_utils/error_lua.py +185 -0
  73. bmcgo/codegen/lua/script/render_utils/factory.py +52 -0
  74. bmcgo/codegen/lua/script/render_utils/ipmi_lua.py +159 -0
  75. bmcgo/codegen/lua/script/render_utils/ipmi_message_lua.py +24 -0
  76. bmcgo/codegen/lua/script/render_utils/mdb_lua.py +177 -0
  77. bmcgo/codegen/lua/script/render_utils/mdb_register.py +215 -0
  78. bmcgo/codegen/lua/script/render_utils/message_lua.py +26 -0
  79. bmcgo/codegen/lua/script/render_utils/messages_lua.py +156 -0
  80. bmcgo/codegen/lua/script/render_utils/model_lua.py +485 -0
  81. bmcgo/codegen/lua/script/render_utils/old_model_lua.py +429 -0
  82. bmcgo/codegen/lua/script/render_utils/plugin_lua.py +38 -0
  83. bmcgo/codegen/lua/script/render_utils/redfish_proto.py +86 -0
  84. bmcgo/codegen/lua/script/render_utils/request_lua.py +76 -0
  85. bmcgo/codegen/lua/script/render_utils/service_lua.py +130 -0
  86. bmcgo/codegen/lua/script/render_utils/utils_message_lua.py +125 -0
  87. bmcgo/codegen/lua/script/render_utils/validate_lua.py +221 -0
  88. bmcgo/codegen/lua/script/sep_ipmi_message_cmds.py +217 -0
  89. bmcgo/codegen/lua/script/template.py +166 -0
  90. bmcgo/codegen/lua/script/types_pb2.py +516 -0
  91. bmcgo/codegen/lua/script/utils.py +663 -0
  92. bmcgo/codegen/lua/script/validate.py +80 -0
  93. bmcgo/codegen/lua/script/yaml_to_json.py +73 -0
  94. bmcgo/codegen/lua/templates/Makefile +114 -0
  95. bmcgo/codegen/lua/templates/apps/Makefile +261 -0
  96. bmcgo/codegen/lua/templates/apps/Makefile.mdb.mk +64 -0
  97. bmcgo/codegen/lua/templates/apps/app.lua.mako +19 -0
  98. bmcgo/codegen/lua/templates/apps/class.lua.mako +35 -0
  99. bmcgo/codegen/lua/templates/apps/client.lua.mako +429 -0
  100. bmcgo/codegen/lua/templates/apps/controller.lua.mako +276 -0
  101. bmcgo/codegen/lua/templates/apps/datas.lua.mako +8 -0
  102. bmcgo/codegen/lua/templates/apps/db.lua.mako +89 -0
  103. bmcgo/codegen/lua/templates/apps/entry.lua.mako +128 -0
  104. bmcgo/codegen/lua/templates/apps/feature.lua.mako +37 -0
  105. bmcgo/codegen/lua/templates/apps/generate_route.mako +25 -0
  106. bmcgo/codegen/lua/templates/apps/impl_feature.lua.mako +72 -0
  107. bmcgo/codegen/lua/templates/apps/ipmi.lua.mako +97 -0
  108. bmcgo/codegen/lua/templates/apps/ipmi_cmd.lua.mako +18 -0
  109. bmcgo/codegen/lua/templates/apps/ipmi_message.lua.mako +36 -0
  110. bmcgo/codegen/lua/templates/apps/local_db.lua.mako +263 -0
  111. bmcgo/codegen/lua/templates/apps/main.lua.mako +25 -0
  112. bmcgo/codegen/lua/templates/apps/mc.lua.mako +77 -0
  113. bmcgo/codegen/lua/templates/apps/mdb.lua.mako +45 -0
  114. bmcgo/codegen/lua/templates/apps/mdb_interface.lua.mako +73 -0
  115. bmcgo/codegen/lua/templates/apps/message.lua.mako +38 -0
  116. bmcgo/codegen/lua/templates/apps/model.lua.mako +239 -0
  117. bmcgo/codegen/lua/templates/apps/orm_classes.lua.mako +16 -0
  118. bmcgo/codegen/lua/templates/apps/plugin.lua.mako +8 -0
  119. bmcgo/codegen/lua/templates/apps/redfish.proto.mako +47 -0
  120. bmcgo/codegen/lua/templates/apps/service.lua.mako +440 -0
  121. bmcgo/codegen/lua/templates/apps/signal_listen.lua.mako +19 -0
  122. bmcgo/codegen/lua/templates/apps/utils/default_intf.lua.mako +41 -0
  123. bmcgo/codegen/lua/templates/apps/utils/enum.mako +10 -0
  124. bmcgo/codegen/lua/templates/apps/utils/imports.mako +13 -0
  125. bmcgo/codegen/lua/templates/apps/utils/mdb_intf.lua.mako +25 -0
  126. bmcgo/codegen/lua/templates/apps/utils/mdb_obj.lua.mako +23 -0
  127. bmcgo/codegen/lua/templates/apps/utils/message.mako +160 -0
  128. bmcgo/codegen/lua/templates/apps/utils/request.lua.mako +59 -0
  129. bmcgo/codegen/lua/templates/apps/utils/validate.mako +83 -0
  130. bmcgo/codegen/lua/templates/errors.lua.mako +36 -0
  131. bmcgo/codegen/lua/templates/messages.lua.mako +32 -0
  132. bmcgo/codegen/lua/templates/new_app/.clang-format.mako +170 -0
  133. bmcgo/codegen/lua/templates/new_app/.gitignore.mako +26 -0
  134. bmcgo/codegen/lua/templates/new_app/CHANGELOG.md.mako +0 -0
  135. bmcgo/codegen/lua/templates/new_app/CMakeLists.txt.mako +29 -0
  136. bmcgo/codegen/lua/templates/new_app/Makefile.mako +25 -0
  137. bmcgo/codegen/lua/templates/new_app/README.md.mako +0 -0
  138. bmcgo/codegen/lua/templates/new_app/conanfile.py.mako +7 -0
  139. bmcgo/codegen/lua/templates/new_app/config.cfg.mako +6 -0
  140. bmcgo/codegen/lua/templates/new_app/mds/model.json.mako +3 -0
  141. bmcgo/codegen/lua/templates/new_app/mds/service.json.mako +21 -0
  142. bmcgo/codegen/lua/templates/new_app/permissions.ini.mako +16 -0
  143. bmcgo/codegen/lua/templates/new_app/src/lualib/${project_name}_app.lua.mako +16 -0
  144. bmcgo/codegen/lua/templates/new_app/src/service/main.lua.mako +25 -0
  145. bmcgo/codegen/lua/templates/new_app/test/integration/test_${project_name}.conf.mako +9 -0
  146. bmcgo/codegen/lua/templates/new_app/test/integration/test_${project_name}.lua.mako +47 -0
  147. bmcgo/codegen/lua/templates/new_app/test/unit/test.lua.mako +23 -0
  148. bmcgo/codegen/lua/templates/new_app/user_conf/rootfs/etc/systemd/system/${project_name}.service.mako +18 -0
  149. bmcgo/codegen/lua/templates/new_app/user_conf/rootfs/etc/systemd/system/multi-user.target.wants/${project_name}.service.link +1 -0
  150. bmcgo/component/__init__.py +10 -0
  151. bmcgo/component/analysis/analysis.py +183 -0
  152. bmcgo/component/analysis/build_deps.py +165 -0
  153. bmcgo/component/analysis/data_deps.py +333 -0
  154. bmcgo/component/analysis/dep-rules.json +912 -0
  155. bmcgo/component/analysis/dep_node.py +110 -0
  156. bmcgo/component/analysis/intf_deps.py +163 -0
  157. bmcgo/component/analysis/intf_validation.py +254 -0
  158. bmcgo/component/analysis/rule.py +211 -0
  159. bmcgo/component/analysis/smc_dfx_whitelist.json +11 -0
  160. bmcgo/component/analysis/sr_validation.py +391 -0
  161. bmcgo/component/build.py +222 -0
  162. bmcgo/component/component_dt_version_parse.py +348 -0
  163. bmcgo/component/component_helper.py +114 -0
  164. bmcgo/component/coverage/__init__.py +11 -0
  165. bmcgo/component/coverage/c_incremental_cov_report.template +53 -0
  166. bmcgo/component/coverage/incremental_cov.py +464 -0
  167. bmcgo/component/deploy.py +110 -0
  168. bmcgo/component/gen.py +169 -0
  169. bmcgo/component/package_info.py +236 -0
  170. bmcgo/component/template/conanbase.py.mako +278 -0
  171. bmcgo/component/template/conanfile.deploy.py.mako +40 -0
  172. bmcgo/component/test.py +947 -0
  173. bmcgo/errors.py +119 -0
  174. bmcgo/frame.py +217 -0
  175. bmcgo/functional/__init__.py +10 -0
  176. bmcgo/functional/analysis.py +96 -0
  177. bmcgo/functional/bmc_studio_action.py +98 -0
  178. bmcgo/functional/check.py +185 -0
  179. bmcgo/functional/conan_index_build.py +251 -0
  180. bmcgo/functional/config.py +332 -0
  181. bmcgo/functional/csr_build.py +724 -0
  182. bmcgo/functional/deploy.py +263 -0
  183. bmcgo/functional/diff.py +235 -0
  184. bmcgo/functional/fetch.py +235 -0
  185. bmcgo/functional/full_component.py +391 -0
  186. bmcgo/functional/maintain.py +381 -0
  187. bmcgo/functional/new.py +166 -0
  188. bmcgo/functional/schema_valid.py +111 -0
  189. bmcgo/functional/simple_sign.py +104 -0
  190. bmcgo/functional/upgrade.py +78 -0
  191. bmcgo/ipmigen/__init__.py +13 -0
  192. bmcgo/ipmigen/ctype_defination.py +82 -0
  193. bmcgo/ipmigen/ipmigen.py +309 -0
  194. bmcgo/ipmigen/template/cmd.c.mako +366 -0
  195. bmcgo/ipmigen/template/ipmi.c.mako +25 -0
  196. bmcgo/ipmigen/template/ipmi.h.mako +51 -0
  197. bmcgo/logger.py +176 -0
  198. bmcgo/misc.py +117 -0
  199. bmcgo/target/app.yml +17 -0
  200. bmcgo/target/install_sdk.yml +15 -0
  201. bmcgo/target/personal.yml +53 -0
  202. bmcgo/target/publish.yml +45 -0
  203. bmcgo/tasks/__init__.py +11 -0
  204. bmcgo/tasks/download_buildtools_hm.py +124 -0
  205. bmcgo/tasks/misc.py +15 -0
  206. bmcgo/tasks/task.py +354 -0
  207. bmcgo/tasks/task_build_conan.py +714 -0
  208. bmcgo/tasks/task_build_rootfs_img.py +595 -0
  209. bmcgo/tasks/task_buildgppbin.py +88 -0
  210. bmcgo/tasks/task_buildhpm_ext4.py +82 -0
  211. bmcgo/tasks/task_create_interface_config.py +122 -0
  212. bmcgo/tasks/task_download_buildtools.py +99 -0
  213. bmcgo/tasks/task_download_dependency.py +72 -0
  214. bmcgo/tasks/task_hpm_envir_prepare.py +112 -0
  215. bmcgo/tasks/task_packet_to_supporte.py +87 -0
  216. bmcgo/tasks/task_prepare.py +105 -0
  217. bmcgo/tasks/task_sign_and_pack_hpm.py +42 -0
  218. bmcgo/utils/__init__.py +10 -0
  219. bmcgo/utils/buffer.py +128 -0
  220. bmcgo/utils/combine_json_schemas.py +170 -0
  221. bmcgo/utils/component_post.py +54 -0
  222. bmcgo/utils/component_version_check.py +86 -0
  223. bmcgo/utils/config.py +1067 -0
  224. bmcgo/utils/fetch_component_code.py +232 -0
  225. bmcgo/utils/install_manager.py +61 -0
  226. bmcgo/utils/installations/__init__.py +10 -0
  227. bmcgo/utils/installations/base_installer.py +70 -0
  228. bmcgo/utils/installations/install_consts.py +30 -0
  229. bmcgo/utils/installations/install_plans/bingo.yml +11 -0
  230. bmcgo/utils/installations/install_workflow.py +50 -0
  231. bmcgo/utils/installations/installers/apt_installer.py +177 -0
  232. bmcgo/utils/installations/installers/pip_installer.py +46 -0
  233. bmcgo/utils/installations/version_util.py +100 -0
  234. bmcgo/utils/mapping_config_patch.py +443 -0
  235. bmcgo/utils/perf_analysis.py +114 -0
  236. bmcgo/utils/tools.py +704 -0
  237. bmcgo/worker.py +417 -0
  238. openubmc_bingo-0.5.240.dist-info/METADATA +30 -0
  239. openubmc_bingo-0.5.240.dist-info/RECORD +242 -0
  240. openubmc_bingo-0.5.240.dist-info/WHEEL +5 -0
  241. openubmc_bingo-0.5.240.dist-info/entry_points.txt +2 -0
  242. openubmc_bingo-0.5.240.dist-info/top_level.txt +1 -0
bmcgo/utils/config.py ADDED
@@ -0,0 +1,1067 @@
1
+ #!/usr/bin/env python
2
+ # coding: utf-8
3
+ # Copyright (c) 2024 Huawei Technologies Co., Ltd.
4
+ # openUBMC is licensed under Mulan PSL v2.
5
+ # You can use this software according to the terms and conditions of the Mulan PSL v2.
6
+ # You may obtain a copy of Mulan PSL v2 at:
7
+ # http://license.coscl.org.cn/MulanPSL2
8
+ # THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
9
+ # EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
10
+ # MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
11
+ # See the Mulan PSL v2 for more details.
12
+
13
+ import json
14
+ import os
15
+ import sys
16
+ import copy
17
+ import hashlib
18
+ import stat
19
+ import shutil
20
+ import argparse
21
+ import subprocess
22
+ import logging
23
+ import time
24
+ import struct
25
+ import functools
26
+ import hashlib
27
+ import configparser
28
+ from multiprocessing import Lock
29
+
30
+ import jsonschema
31
+ import yaml
32
+
33
+ from bmcgo.utils.tools import Tools
34
+ from bmcgo.logger import Logger
35
+ from bmcgo import errors, misc
36
+ from bmcgo.bmcgo_config import BmcgoConfig
37
+
38
+ tools = Tools("config")
39
+ log = Logger("config")
40
+ VERSION = "Version"
41
+ BUILD_NUMBER = "BuildNum"
42
+ VERSION_LEN = 5
43
+
44
+
45
+ class Config:
46
+ # RTOS版本号
47
+ rtos_version = None
48
+ rtos_kernel = None
49
+ arm_dic = {"V3": "arm", "V5": "arm", "V6": "arm64"}
50
+ sdk_path = None
51
+ hpm_build_dir = None
52
+ gpp_build_dir = None
53
+ buildimg_dir = None
54
+ inner_path = None
55
+ component_list_file = None
56
+ asan = None
57
+ enable_qemu = False
58
+ pull_up_qemu = False
59
+ version = ""
60
+ chip = "1711"
61
+ _rtos_offering = None
62
+ enable_luajit = False
63
+ _profile = ""
64
+ conan_index_options = []
65
+ _manifest_data = {}
66
+ schema_file = f"{misc.SCHEMA_FILE_PATH}/manifest.schema.json"
67
+ schema_need_validate = False # 由frame.py或target文件配置是否启用
68
+ enable_debug_model = False # # 是否启用调测模式,默认为false,个人构建启用
69
+
70
+ def __init__(self, bconfig: BmcgoConfig, board_name="openUBMC", target="target_personal"):
71
+ self.bconfig = bconfig
72
+
73
+ # 单板名
74
+ self.board_name = board_name
75
+ # 构建目标的文件名,不包含py尾缀,文件存储在application/build/target目录
76
+ self.target = target
77
+ self.from_source = False
78
+ self.local = ""
79
+ # step???
80
+ self.step = "ultimate"
81
+ # 编译选项,默认值为 False,可用方法 set_enable_arm_gcov 设置
82
+ self.enable_arm_gcov = False
83
+ # 是否需要进行签名
84
+ self.sign = ""
85
+ self.init_path()
86
+ self.doc_file = "Open Source Software Notice.docx"
87
+
88
+ self.download_0502 = f"{self.temp_path}/download_0502"
89
+ os.makedirs(self.download_0502, exist_ok=True)
90
+ # 存储0502编码
91
+ self.manufacture_code = None
92
+ # 存储tosupporte编码
93
+ self.tosupporte_code = None
94
+ self.build_type = "debug"
95
+ self.stage = misc.StageEnum.STAGE_DEV.value
96
+ self.set_common_params()
97
+ # 构建日志临时目录
98
+ self.log_path = os.path.join(self.temp_path, 'log')
99
+ if os.path.isdir(self.log_path):
100
+ shutil.rmtree(self.log_path)
101
+ os.makedirs(self.log_path)
102
+ os.makedirs(self.output_path, 0o755, exist_ok=True)
103
+ # MR门禁编译标志位,由prepare任务根据MR配置修改
104
+ self.update_mr_info()
105
+ os.environ['CONAN_REVISIONS_ENABLED'] = "1"
106
+ self.publish_version = ""
107
+ self.verbose = False
108
+ self.update_conan_cache = False
109
+ self.source_mode = os.getenv('SOURCE_MODE')
110
+ self.partner_path = f'{os.path.expanduser("~")}/partner_path'
111
+ self.container_tag = "v3:v3_partner"
112
+ self.partner_docker_home = f"{self.code_root}/dev_tools/partner_docker"
113
+ self.partner_workspace = f"{self.temp_path}/archive_to_cmc"
114
+ self.docker_component_home = f"{self.temp_path}/docker_component_home"
115
+ self.conan_parallel_lock = Lock()
116
+ self.archive_conf = None
117
+ self.archive_path = None
118
+ self.partner_docker = False
119
+ # 版本号拆分
120
+ self.major_ver = ""
121
+ self.miner_ver = ""
122
+ self.release_ver = ""
123
+ self.patch_ver = ""
124
+ self.build_ver = ""
125
+ self.date = None
126
+ self.show_version = ""
127
+ # Docker相关
128
+ self.upload_docker = False
129
+ self.partner_name = None
130
+ self.docker_tag = None
131
+ # 伙伴/开源远端相关
132
+ self.open_remote = None
133
+
134
+ @property
135
+ def partner_mode(self):
136
+ """是否是伙伴模式"""
137
+ return self.bconfig.partner_mode
138
+
139
+ @property
140
+ def sysroot(self):
141
+ return f"/opt/{self.rtos_offering}/{self.rtos_version}/arm64le_{self.rtos_kernel}/sdk"
142
+
143
+ @property
144
+ def sign_certificates(self):
145
+ return self.get_manufacture_config("base/signature/certificates")
146
+
147
+ @property
148
+ def rootca_der(self):
149
+ """签名根公钥"""
150
+ output = self.get_manufacture_config("base/signature/certificates/rootca_der")
151
+ if not os.path.isfile(output):
152
+ raise errors.BmcGoException("base/signature/certificates/rootca_der 配置的根证书不存在")
153
+ return output
154
+
155
+ @property
156
+ def rootca_crl(self):
157
+ """签名根公钥"""
158
+ output = self.get_manufacture_config("base/signature/certificates/rootca_crl")
159
+ if not os.path.isfile(output):
160
+ raise errors.BmcGoException("base/signature/certificates/rootca_crl 配置的证书吊销列表文件不存在")
161
+ return output
162
+
163
+ @property
164
+ def signer_pem(self):
165
+ """签名证书私钥"""
166
+ output = self.get_manufacture_config("base/signature/certificates/signer_pem")
167
+ if not os.path.isfile(output):
168
+ raise errors.BmcGoException("base/signature/certificates/signer_pem 配置的签名私钥文件不存在")
169
+ return output
170
+
171
+ @property
172
+ def ts_signer_pem(self):
173
+ """时间戳签名证书私钥"""
174
+ output = self.get_manufacture_config("base/signature/certificates/timestamp_signer_pem")
175
+ if not os.path.isfile(output):
176
+ raise errors.BmcGoException("base/signature/certificates/timestamp_signer_pem 配置的时间戳签名私钥文件不存在")
177
+ return output
178
+
179
+ @property
180
+ def ts_signer_cnf(self):
181
+ """时间戳签名配置"""
182
+ output = self.get_manufacture_config("base/signature/certificates/timestamp_signer_cnf")
183
+ if not os.path.isfile(output):
184
+ raise errors.BmcGoException("base/signature/certificates/timestamp_signer_cnf 配置的时间戳配置文件不存在")
185
+ return output
186
+
187
+ @property
188
+ def profile(self):
189
+ return Tools.get_conan_profile(self._profile, self.build_type, self.enable_luajit)
190
+
191
+ @property
192
+ def subsys_dir(self):
193
+ subsys = os.path.join(self.code_path, "subsys")
194
+ if self.stage == misc.StageEnum.STAGE_STABLE.value:
195
+ subsys = os.path.join(subsys, misc.StageEnum.STAGE_STABLE.value)
196
+ else:
197
+ subsys = os.path.join(subsys, misc.StageEnum.STAGE_RC.value)
198
+ return subsys
199
+
200
+ @staticmethod
201
+ def argparser(code_path, partner_mode=False):
202
+ parser = argparse.ArgumentParser(description="构建openUBMC", formatter_class=argparse.RawTextHelpFormatter)
203
+ boards = Config.get_all_board(code_path)
204
+ help_txt = "单板包,可选值为build/product/<Kunpeng|...>/下的目录名\n默认:openUBMC"
205
+ help_txt += "\n支持的单板列表:"
206
+ for board, _ in boards.items():
207
+ help_txt += "\n" + board
208
+ parser.add_argument("-b", "--board_name", help=help_txt, default="openUBMC")
209
+ parser.add_argument("-bt", "--build_type",
210
+ help="构建类型,可选:debug(调试包), release(正式包), dt(开发者测试包)", default="debug")
211
+ parser.add_argument(
212
+ "-s",
213
+ "--from_source",
214
+ help=argparse.SUPPRESS if partner_mode else "使能全量源码构建",
215
+ action=misc.STORE_TRUE,
216
+ )
217
+ parser.add_argument("--stage", help="包类型,可选值为: dev(调试包), rc(预发布包), stable(发布包)\n默认:dev",
218
+ default='dev')
219
+ parser.add_argument("--verbose", help="使能conan构建详细日志打印", action=misc.STORE_TRUE)
220
+ parser.add_argument("-ucc", "--update_conan_cache", help="全量更新本地conan缓存", action=misc.STORE_TRUE)
221
+ parser.add_argument("-r", "--remote", help=f"conan仓别名,请检查conan remote list查看已配置的conan仓")
222
+ parser.add_argument("-z", "--zip_code",
223
+ help=(
224
+ argparse.SUPPRESS
225
+ if partner_mode
226
+ else "0502编码,可选值参考单板manifest/manufacture,示例: 05023UDK"
227
+ ), default=None)
228
+ parser.add_argument("-sc", "--supporte_code",
229
+ help="待发布的SupportE编码,可选值参考单板manifest.yml/tosupporte\n默认:default",
230
+ default="default")
231
+ parser.add_argument("-q", "--enable_qemu", help=argparse.SUPPRESS, action=misc.STORE_TRUE)
232
+ parser.add_argument("-qi", "--qemu_in", help=argparse.SUPPRESS, action=misc.STORE_TRUE)
233
+ parser.add_argument("-cov", "--coverage", help=argparse.SUPPRESS if partner_mode else "使能覆盖率统计功能",
234
+ action=misc.STORE_TRUE)
235
+ parser.add_argument("-as", "--asan", help=argparse.SUPPRESS if partner_mode else "Enable address sanitizer",
236
+ action=misc.STORE_TRUE)
237
+ parser.add_argument("-pr", "--profile",
238
+ help=argparse.SUPPRESS if partner_mode else Tools.get_profile_arg_help(), default="")
239
+ parser.add_argument("-jit", "--enable_luajit", help=argparse.SUPPRESS if partner_mode else "Enable luajit",
240
+ action=misc.STORE_FALSE if partner_mode else misc.STORE_TRUE)
241
+ return parser
242
+
243
+ # 从product/productline查找所有单板
244
+ @staticmethod
245
+ def get_all_board(code_path):
246
+ product_path = os.path.join(code_path, "product")
247
+ boards = {}
248
+ for productline in os.listdir(product_path):
249
+ path = os.path.join(product_path, productline)
250
+ if not os.path.isdir(path):
251
+ continue
252
+ for board in os.listdir(path):
253
+ board_path = os.path.join(path, board)
254
+ manifest = os.path.join(board_path, "manifest.yml")
255
+ if not os.path.isfile(manifest):
256
+ continue
257
+ boards[board] = board_path
258
+ return boards
259
+
260
+ @staticmethod
261
+ def log_init():
262
+ """在manifest仓未删除frame.py及works前保留"""
263
+ logger = logging.getLogger()
264
+ logger.setLevel(logging.INFO)
265
+ loglevel = os.environ.get("LOG")
266
+ if loglevel is not None:
267
+ formatter = logging.Formatter(fmt='[{asctime} {levelname} {filename}:{lineno} {funcName:4}] {message}',
268
+ style='{')
269
+ if loglevel == "debug":
270
+ logger.setLevel(logging.DEBUG)
271
+ elif loglevel == "warn":
272
+ logger.setLevel(logging.WARNING)
273
+ elif loglevel == "error":
274
+ logger.setLevel(logging.ERROR)
275
+ else:
276
+ logger.setLevel(logging.INFO)
277
+ else:
278
+ formatter = logging.Formatter(fmt='[{levelname} {filename}:{lineno} {funcName:4}] {message}',
279
+ style='{')
280
+ handler = logging.StreamHandler(sys.stdout)
281
+ handler.setFormatter(formatter)
282
+ logger.handlers = []
283
+ logger.addHandler(handler)
284
+
285
+ @staticmethod
286
+ def set_conf(conf_file, scheme: dict):
287
+ """设置.ini文件
288
+ 参数:
289
+ scheme (dict): 需设置的ini文件的节与参数,
290
+ e.g.
291
+ ```
292
+ {
293
+ "Section A": { "key1": "val1", "key2": "val2" },
294
+ "Section B": { "key3": "val3" },
295
+ "Section C": {}
296
+ }
297
+ ```
298
+ """
299
+ conf = configparser.ConfigParser()
300
+ if os.path.isfile(conf_file):
301
+ conf.read(conf_file)
302
+ for section, entries in scheme.items():
303
+ try:
304
+ sec = conf[section]
305
+ except Exception as e:
306
+ conf[section] = {}
307
+ sec = conf[section]
308
+ for key, val in entries.items():
309
+ sec[key] = str(val)
310
+ with os.fdopen(os.open(conf_file, flags=os.O_WRONLY | os.O_CREAT | os.O_TRUNC, \
311
+ mode=stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP | stat.S_IROTH), "w") as conf_fd:
312
+ conf.write(conf_fd)
313
+ conf_fd.close()
314
+
315
+ @staticmethod
316
+ def _calc_manifest_data_sha256(filename, template):
317
+ sha256 = Tools.sha256sum(filename)
318
+ template_str = json.dumps(template)
319
+ template_hash = hashlib.sha256()
320
+ template_hash.update(template_str.encode())
321
+ template_sha256 = template_hash.hexdigest()
322
+ return sha256 + template_sha256
323
+
324
+ @functools.cached_property
325
+ def rtos_offering(self):
326
+ return self.get_manufacture_config("base/rtos_offering", "RTOS")
327
+
328
+ @functools.cached_property
329
+ def skynet_config(self):
330
+ deps = self.get_manufacture_config('dependencies', [])
331
+ for dep in deps:
332
+ conan = dep.get(misc.CONAN)
333
+ name = conan.split("/")[0]
334
+ if name == 'skynet':
335
+ return dep
336
+ return {'conan': 'skynet'}
337
+
338
+ @functools.cached_property
339
+ def conan_remotes(self):
340
+ """conan remotes列表"""
341
+ cmd = 'conan remote list -raw'
342
+ _, data = subprocess.getstatusoutput(cmd)
343
+ remotes_list = [{remote.split()[0]: remote.split()[1]} for remote in data.split('\n')]
344
+ return remotes_list
345
+
346
+ # 从manifest中获取属性值
347
+ def get_manufacture_config(self, key: str, default_val=None):
348
+ """获取manifest.yml当中的配置
349
+ 参数:
350
+ key (str): 要获取的配置,采用路径类似格式,比如'manufacture/05023VAY'
351
+ 返回值:
352
+ None: 未找到配置
353
+ str: 配置的值
354
+ """
355
+ manifest_conf = self.load_manifest_yml()
356
+ splits = key.split("/")
357
+ processed = ""
358
+ for split in splits:
359
+ if processed == "":
360
+ processed = split
361
+ else:
362
+ processed = processed + "/" + split
363
+ manifest_conf = manifest_conf.get(split)
364
+ if manifest_conf is None:
365
+ log.info('不能从 yaml 文件中获取到键值 {}, 没有相关配置'.format(processed))
366
+ return default_val
367
+ return manifest_conf
368
+
369
+ def get_origin_manufacture_config(self, key: str, default_val=None):
370
+ """获取origin manifest.yml当中的配置
371
+ 参数:
372
+ key (str): 要获取的配置,采用路径类似格式,比如'manufacture/05023VAY'
373
+ 返回值:
374
+ None: 未找到配置
375
+ str: 配置的值
376
+ """
377
+ manifest_file = os.path.join(self.board_path, "manifest.yml")
378
+ with open(manifest_file, "r", encoding="utf-8") as fp:
379
+ manifest_conf = yaml.safe_load(fp)
380
+ splits = key.split("/")
381
+ processed = ""
382
+ for split in splits:
383
+ if processed == "":
384
+ processed = split
385
+ else:
386
+ processed = processed + "/" + split
387
+ manifest_conf = manifest_conf.get(split)
388
+ if manifest_conf is None:
389
+ log.info('不能从 yaml 文件中获取到键值 {}, 没有相关配置'.format(processed))
390
+ return default_val
391
+ return manifest_conf
392
+
393
+ def get_manufacture_version(self) -> str:
394
+ """调整version的值,特殊场景要求装备版本号要在正常版修订号加1
395
+
396
+ 返回值:
397
+ str: 新的修正后的版本号
398
+ """
399
+ if self.version == "":
400
+ return self.version
401
+ version = self.version.rsplit(".", 1)[0] if "B" in self.version else self.version
402
+ correction_version = str(int(version.rsplit(".", 1)[-1]) + 1)
403
+ version = "{}.{}".format(version.rsplit(".", 1)[0], correction_version.zfill(2))
404
+ return version
405
+
406
+ def read_m4i_template(self):
407
+ file = os.path.join(self.work_out, "m4i_template.m4i")
408
+ if os.path.isfile(file):
409
+ with open(file) as fp:
410
+ return fp.read()
411
+ return None
412
+
413
+ # 模板化,manifest.yml替换时使用
414
+ def get_template(self) -> dict:
415
+ version = self.version.rsplit(".", 1)[0] if "B" in self.version else self.version
416
+ template = {
417
+ "code_root": self.code_root,
418
+ "product": f"{self.code_path}/product",
419
+ "manufacture": f"{self.code_path}/manufacture",
420
+ "hpm_build_dir": self.hpm_build_dir,
421
+ "board_path": self.board_path,
422
+ "ori_board_path": self.ori_board_path,
423
+ "download_0502": self.download_0502,
424
+ "version": version,
425
+ "manufacture_version": self.get_manufacture_version(),
426
+ "manufacture_code": self.manufacture_code,
427
+ "tosupporte_code": self.tosupporte_code,
428
+ "board_name": self.board_name,
429
+ "work_out": self.work_out,
430
+ "output_path": self.output_path,
431
+ "m4i_template": self.read_m4i_template(),
432
+ "doc_file": self.doc_file,
433
+ "sdk_path": self.sdk_path,
434
+ "partner_path": self.partner_path,
435
+ "major_ver": self.major_ver,
436
+ "minor_ver": self.miner_ver,
437
+ "release_ver": self.release_ver,
438
+ "patch_ver": self.patch_ver,
439
+ "build_ver": self.build_ver,
440
+ "show_version": self.show_version,
441
+ "package_folder": self.temp_platform_dir_name
442
+ }
443
+ return template
444
+
445
+ def init_path(self):
446
+ # 编译 debug 或者 release 或者 装备分离 版本的app包
447
+ self.build_path = ""
448
+ self.rootfs_path = ""
449
+ self.cache_path = ""
450
+ self.work_out = ""
451
+ self.work_config = ""
452
+ # build/board/<board_name>路径
453
+ self.board_path = ""
454
+ # 关键路径定义
455
+ # build目录
456
+ self.code_path = os.path.join(self.bconfig.manifest.folder, "build")
457
+ # 代码根目录
458
+ self.code_root = self.bconfig.manifest.folder
459
+ self.temp_path = os.path.join(self.code_root, 'temp')
460
+ os.makedirs(self.temp_path, exist_ok=True)
461
+ # 定义自研构建工具目录并添加到环境变量
462
+ self.tools_path = os.path.realpath(os.path.join(self.temp_path, "tools"))
463
+ os.makedirs(self.tools_path, exist_ok=True)
464
+ os.makedirs(os.path.join(self.tools_path, "build_tools"), exist_ok=True)
465
+ os.environ['PATH'] = os.environ["PATH"] + ":" + os.path.join(self.tools_path, "build_tools")
466
+ # CI工程上库路径
467
+ self.output_path = os.path.join(self.code_root, 'output')
468
+
469
+ def init_conan_profile(self, profile: str):
470
+ manifest_profile = self.get_manufacture_config("base/profile")
471
+ if manifest_profile:
472
+ log.warning(f"根据当前产品manifest.yml中的profile配置为{manifest_profile},忽略命令行指定的-pr参数")
473
+ self._profile = manifest_profile
474
+ else:
475
+ self._profile = profile
476
+
477
+ def update_mr_info(self):
478
+ self.src_git = ""
479
+ self.src_branch = ""
480
+ self.tgt_git = ""
481
+ self.tgt_branch = ""
482
+ mr_config = f"{self.code_root}/../mr_config.json"
483
+ if not os.path.isfile(mr_config):
484
+ return
485
+
486
+ with open(mr_config, "r") as json_file:
487
+ cfg = json.load(json_file)
488
+ self.src_git = cfg["src_git"]
489
+ self.src_branch = cfg["src_branch"]
490
+ self.tgt_git = cfg["tgt_git"]
491
+ self.tgt_branch = cfg["tgt_branch"]
492
+
493
+ def set_from_source(self, from_source):
494
+ self.from_source = from_source
495
+
496
+ # 设置0502编码
497
+ def set_manufacture_code(self, code):
498
+ self.manufacture_code = code
499
+
500
+ def set_tosupporte_code(self, code):
501
+ self.tosupporte_code = code
502
+
503
+ def set_step(self, arg_step):
504
+ '''
505
+ 参数:arg_step 可选值:"build"/"ultimate"/"standard"/""
506
+ '''
507
+ self.step = arg_step
508
+
509
+ def set_enable_arm_gcov(self, is_enable):
510
+ '''
511
+ 是否添加编译选项 -DGCOV=ON
512
+ 参数:is_enable 是否添加-DGCOV=ON 可选值:True;False
513
+ '''
514
+ # 实现 gcov 功能以后, 请将 False 改为 is_enable
515
+ self.enable_arm_gcov = False
516
+ self.set_enable_qemu(is_enable)
517
+
518
+ def set_sign(self, arg_sign):
519
+ '''
520
+ 是否需要签名
521
+ '''
522
+ self.sign = arg_sign
523
+
524
+ def update_path(self):
525
+ self.build_path = os.path.join(self.temp_path, f"build_{self.board_name}_{self.build_type}_{self.stage}")
526
+ self.board_path = os.path.join(self.temp_path, f"board_{self.board_name}")
527
+ self.rootfs_path = os.path.join(self.build_path, 'tmp_root')
528
+ self.work_out = os.path.join(self.build_path, 'output')
529
+ self.cache_path = os.path.join(self.build_path, 'cache')
530
+ self.sdk_path = os.path.join(self.build_path, 'sdk')
531
+ # 单板打包路径
532
+ self.hpm_build_dir = f"{self.build_path}/hpm_build_dir"
533
+ self.gpp_build_dir = f"{self.build_path}/gpp_build_dir"
534
+ self.buildimg_dir = f"{self.build_path}/buildimg"
535
+ self.inner_path = os.path.join(self.output_path, "packet/inner", self.build_type)
536
+ os.makedirs(self.build_path, 0o755, exist_ok=True)
537
+ os.makedirs(self.work_out, 0o755, exist_ok=True)
538
+ os.makedirs(self.rootfs_path, 0o755, exist_ok=True)
539
+ os.makedirs(self.cache_path, 0o755, exist_ok=True)
540
+ os.makedirs(self.hpm_build_dir, 0o755, exist_ok=True)
541
+ os.makedirs(self.gpp_build_dir, 0o755, exist_ok=True)
542
+ os.makedirs(self.buildimg_dir, 0o755, exist_ok=True)
543
+ os.makedirs(self.inner_path, 0o755, exist_ok=True)
544
+ self.component_list_file = f"{self.board_path}/component.list"
545
+
546
+ def set_build_type(self, arg_build_type="debug"):
547
+ '''
548
+ 这只编译app的cmake编译选项
549
+ 参数:arg_build_type 可选值:"debug";"release";"dt"
550
+ '''
551
+ # 可以编译的版本
552
+ build_type_turple = ("debug", "release", "dt")
553
+ if arg_build_type not in build_type_turple:
554
+ log.info("不支持的构建类型, 请从以下构建类型中输入: [debug release dt]")
555
+ return
556
+
557
+ self.build_type = arg_build_type
558
+ # 为了支持组件定制化脚本获取定制类型,在此处设置环境变量
559
+ os.environ["BUILD_TYPE"] = self.build_type
560
+ # 构建过程文件存储在以下目录
561
+ self.set_enable_luajit(self.enable_luajit)
562
+
563
+ def deal_conf(self, config_dict):
564
+ if not config_dict:
565
+ return
566
+ for conf in config_dict:
567
+ try:
568
+ method = getattr(self, f"set_{conf}")
569
+ method(config_dict.get(conf))
570
+ except Exception as e:
571
+ raise Exception(f"目标 config 无效配置: {conf}") from e
572
+
573
+ def print_config(self):
574
+ header = 30
575
+ log.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>> 根据目标开始配置 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>")
576
+ log.info("board name:".ljust(header) + self.board_name)
577
+ log.info("from source:".ljust(header) + str(self.from_source))
578
+ log.info("build type:".ljust(header) + str(self.build_type))
579
+ log.info("target:".ljust(header) + str(self.target))
580
+ log.info("qemu:".ljust(header) + str(self.enable_qemu))
581
+ log.info("partner mode:".ljust(header) + str(self.partner_mode))
582
+ log.info("build path:".ljust(header) + str(self.build_path))
583
+ log.info("rootfs path:".ljust(header) + str(self.rootfs_path))
584
+ log.info("cache path:".ljust(header) + str(self.cache_path))
585
+ log.info("work out:".ljust(header) + str(self.work_out))
586
+ log.info("board path:".ljust(header) + str(self.board_path))
587
+ log.info("temp path:".ljust(header) + str(self.temp_path))
588
+ log.info("manufacture_code:".ljust(header) + str(self.manufacture_code))
589
+ log.info("tosupporte_code:".ljust(header) + str(self.tosupporte_code))
590
+ log.info("<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 根据目标配置结束 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<")
591
+
592
+ def set_common_params(self):
593
+ # conan仓
594
+ self.remote = None
595
+ self.remote_list = []
596
+ self.temp_platform_dir_name = f"temp/board_{self.board_name}_platform"
597
+ self.temp_platform_build_dir = os.path.join(self.code_path, self.temp_platform_dir_name)
598
+ self.board_version = "V6"
599
+ self.cross_prefix = "aarch64-target-linux-gnu"
600
+ self.cross_host = "aarch64-linux-gnu"
601
+ self.cross_host_alias = "aarch64-linux-gnu"
602
+ self.cross_build_dir = "aarch64-unknown-linux-gnu"
603
+ self.cross_compile = "aarch64-unknown-linux-gnu-"
604
+ self.cross_compile_install_path = "/opt/hcc_arm64le"
605
+ self.cpu = "arm64le"
606
+ self.platform = "platform_v6"
607
+ self.strip = f"{self.cross_prefix}-strip"
608
+ self.gcc = f"{self.cross_prefix}-gcc"
609
+ self.gxx = f"{self.cross_prefix}-g++"
610
+ # build.py 构建app的全局变量,原方式从参数传递
611
+ self.arch = self.arm_dic.get(self.board_version)
612
+ # 单板配置路径
613
+ self.ori_board_path = ""
614
+ self.productline = ""
615
+ self.version = "5.01.00.01.B001"
616
+
617
+ def set_board_name(self, board_name):
618
+ if self.board_name != board_name:
619
+ log.info("设置单板名为: {}".format(board_name))
620
+ # 设置单板板名和基本属性
621
+ self.board_name = board_name
622
+ self.temp_platform_dir_name = f"temp/board_{self.board_name}_platform"
623
+ self.temp_platform_build_dir = os.path.join(self.code_path, self.temp_platform_dir_name)
624
+ boards = self.get_all_board(self.code_path)
625
+ # 单板配置路径
626
+ self.ori_board_path = boards.get(self.board_name)
627
+ log.info(f"单板源配置路径: {self.ori_board_path}")
628
+ # openUBMC get Kunpeng
629
+ self.productline = os.path.abspath(self.ori_board_path).split('/')[-2]
630
+ board_files = ["manifest.yml", "update_ext4.cfg", "version.xml", "archive.ini"]
631
+ for f in board_files:
632
+ file = os.path.join(self.ori_board_path, f)
633
+ if not os.path.isfile(file):
634
+ raise errors.ConfigException("未发现单板配置文件({}), 请检查单板配置文件".format(file))
635
+ self.update_path()
636
+ log.info("复制单板的 manifest 目录从 {} 到 {}".format(self.ori_board_path, self.board_path))
637
+ tools.run_command(f"rm -rf {self.board_path}")
638
+ tools.run_command(f"cp -rf {self.ori_board_path} {self.board_path}")
639
+
640
+ def set_enable_luajit(self, enable):
641
+ if self.build_type == "Dt":
642
+ self.enable_luajit = False
643
+ self.enable_luajit = enable
644
+
645
+ def set_schema_need_validate(self, enable):
646
+ self.schema_need_validate = enable
647
+
648
+ def set_enable_debug_model(self, enable):
649
+ self.enable_debug_model = enable
650
+
651
+ def set_conan_index_options(self, options):
652
+ if options is not None:
653
+ self.conan_index_options = options
654
+ else:
655
+ self.conan_index_options = []
656
+
657
+ def set_pull_up_qemu(self, pull_up_qemu):
658
+ self.pull_up_qemu = pull_up_qemu
659
+ # 如果要拉起qemu,那么qemu包必须存在,打开出qemu包的开关
660
+ self.enable_qemu = True if pull_up_qemu is True else self.enable_qemu
661
+
662
+ def set_enable_qemu(self, enable_qemu):
663
+ self.enable_qemu = True if enable_qemu is True else self.enable_qemu
664
+
665
+ def set_stage(self, stage: str):
666
+ in_stage = [member.value for member in misc.StageEnum if member is not misc.StageEnum.STAGE_PRE]
667
+ if stage not in in_stage:
668
+ raise errors.ConfigException(f"stage 参数错误, 可用选项为: {in_stage}, 请检查参数")
669
+ self.stage = stage
670
+
671
+ def set_show_version(self):
672
+ self.show_version = self.get_manufacture_config("base/show_version", "")
673
+ if self.manufacture_code is not None:
674
+ self.show_version = self.get_manufacture_config(f"manufacture/{self.manufacture_code}/show_version",
675
+ self.show_version)
676
+ elif self.tosupporte_code is not None:
677
+ self.show_version = self.get_manufacture_config(f"tosupporte/{self.tosupporte_code}/show_version",
678
+ self.show_version)
679
+
680
+ def set_version(self, version):
681
+ self.version = version
682
+ if self.version == "":
683
+ self.update_version()
684
+ else:
685
+ self.update_version(True)
686
+
687
+ def set_target(self, target):
688
+ self.target = target
689
+
690
+ def set_docker_info(self, docker_flags):
691
+ self.upload_docker = docker_flags.upload_docker
692
+ self.partner_name = docker_flags.partner_name
693
+ self.docker_tag = docker_flags.docker_tag + '_' + self.board_name
694
+
695
+ def set_kunpeng_publish_info(self, kunpeng_publish_flags):
696
+ self.open_remote = kunpeng_publish_flags.open_conan_remote
697
+
698
+ # 预处理manifest
699
+ def pre_cook_manifest(self):
700
+ manifest_file = os.path.join(self.board_path, "manifest.yml")
701
+ template = {
702
+ "product": f"{self.code_path}/product"
703
+ }
704
+ mani = self.load_manifest_yml(template=template)
705
+
706
+ self.merge_platform_manifest(mani)
707
+ self.complement_components(mani)
708
+
709
+ if mani.get("include"):
710
+ del mani["include"]
711
+ if mani.get("platform"):
712
+ del mani["platform"]
713
+ dumps = yaml.safe_dump(mani, sort_keys=False)
714
+ with os.fdopen(os.open(manifest_file, os.O_WRONLY | os.O_CREAT | os.O_TRUNC,
715
+ stat.S_IWUSR | stat.S_IRUSR), 'w+', encoding="utf-8") as file_handler:
716
+ file_handler.write(f"# yaml-language-server: $schema={self.schema_file}\n")
717
+ file_handler.write(dumps)
718
+
719
+ #补全组件版本号
720
+ def complement_components(self, mani):
721
+ subsys_comps = self.get_subsys_coms()
722
+ # 补全基本的dependencies
723
+ self.merge_dependencies(mani.get("dependencies", []), subsys_comps, [])
724
+ deps = mani.get("dependencies", [])
725
+ if self.manufacture_code:
726
+ manufature_deps = mani["manufacture"][self.manufacture_code].get("dependencies", [])
727
+ self.merge_dependencies(manufature_deps, subsys_comps, deps)
728
+ elif self.tosupporte_code:
729
+ supporte_deps = mani["tosupporte"][self.tosupporte_code].get("dependencies", [])
730
+ self.merge_dependencies(supporte_deps, subsys_comps, deps)
731
+
732
+ def merge_dependencies(self, dependencies, subsys_comps, base_deps):
733
+ for com_package in dependencies:
734
+ com_package_split = com_package.get(misc.CONAN).split("/")
735
+ if len(com_package_split) > 2:
736
+ continue
737
+ pkg_name = com_package_split[0]
738
+ for sub_name in base_deps:
739
+ sub_pkg_name = sub_name.get(misc.CONAN).split("/")[0]
740
+ # 上下层具有相同组件名的组件
741
+ if pkg_name == sub_pkg_name:
742
+ self.fix_com_package(com_package, misc.CONAN, sub_name.get(misc.CONAN))
743
+ break
744
+ for sub_name in subsys_comps:
745
+ sub_pkg_name = sub_name.split("/")[0]
746
+ # 上下层具有相同组件名的组件
747
+ if pkg_name == sub_pkg_name:
748
+ self.fix_com_package(com_package, misc.CONAN, sub_name)
749
+ break
750
+ self.fix_com_package(com_package, misc.CONAN, pkg_name)
751
+
752
+ def fix_com_package(self, com_package, index, sub_name):
753
+ com_package_split = com_package[index].split("/")
754
+ if len(com_package_split) == 1:
755
+ com_package[index] = sub_name
756
+ elif len(com_package_split) == 2:
757
+ stage = self.stage
758
+ if stage != misc.StageEnum.STAGE_STABLE.value:
759
+ stage = misc.StageEnum.STAGE_RC.value
760
+ user_channel = f"@{tools.conan_user}/{stage}"
761
+ com_package[index] += user_channel
762
+
763
+ def get_subsys_coms(self):
764
+ comps = []
765
+ for f in os.listdir(self.subsys_dir):
766
+ with open(os.path.join(self.subsys_dir, f)) as fp:
767
+ yml = yaml.safe_load(fp)
768
+ deps = yml.get('dependencies')
769
+ for dep in deps:
770
+ conan = dep.get(misc.CONAN)
771
+ if conan:
772
+ comps.append(conan)
773
+ return comps
774
+
775
+ def load_platform_manifest(self, package):
776
+ package_conan_dir = tools.install_platform(package, self.stage, self.remote)
777
+ if os.path.isdir(self.temp_platform_build_dir):
778
+ shutil.rmtree(self.temp_platform_build_dir)
779
+ os.makedirs(os.path.join(self.code_path, "temp"), exist_ok=True)
780
+ tools.run_command(f"cp -rf {package_conan_dir} {self.temp_platform_build_dir}")
781
+ self.copy_rtos_sdk(package_conan_dir)
782
+ platform_manifest_path = os.path.join(
783
+ self.temp_platform_build_dir, "manifest.yml"
784
+ )
785
+ platform_mani = self.load_manifest_yml(filename=platform_manifest_path, template={})
786
+ return platform_mani
787
+
788
+ def copy_rtos_sdk(self, package_conan_dir):
789
+ if self.source_mode is not None:
790
+ rtos_sdk_dir = os.path.join(self.code_path, "rtos_sdk")
791
+ rtos_sdk_src_dir = os.path.join(package_conan_dir, "rtos_sdk")
792
+ if os.path.isdir(rtos_sdk_dir):
793
+ shutil.rmtree(rtos_sdk_dir)
794
+ tools.run_command(f"cp -rf {rtos_sdk_src_dir} {rtos_sdk_dir}")
795
+
796
+ # 合并platform manifest.yml
797
+ def merge_platform_manifest(self, mani):
798
+ platform_package = self.get_manufacture_config("platform", {})
799
+ if platform_package:
800
+ platform_mani = self.load_platform_manifest(platform_package)
801
+ tools.check_product_dependencies(mani, platform_mani)
802
+ if self.manufacture_code:
803
+ tools.check_product_dependencies(mani["manufacture"][self.manufacture_code], platform_mani)
804
+ elif self.tosupporte_code:
805
+ tools.check_product_dependencies(mani["tosupporte"][self.tosupporte_code], platform_mani)
806
+ self.merge_manifest_yml(mani, platform_mani, "")
807
+ else:
808
+ shutil.rmtree(self.temp_platform_build_dir, ignore_errors=True)
809
+
810
+ def merge_manifest_yml(self, top, base, prev_path):
811
+ self._merge_manifest_yaml_easy(top, base, prev_path)
812
+ self._merge_manifest_yaml_easy(base, top, prev_path)
813
+ top_val = copy.deepcopy(top)
814
+ for key, value in top_val.items():
815
+ base_value = base.get(key)
816
+ top_value = top.get(key)
817
+ # 上层有,下层没有的,忽略
818
+ next_path = prev_path + key + "/"
819
+ if next_path == "tosupporte/" or next_path == "manufacture/":
820
+ continue
821
+ if isinstance(top_value, dict):
822
+ self.merge_manifest_yml(top_value, base_value, next_path)
823
+ # 正式出包由上层决定,忽略下层的
824
+ if next_path == "base/customization/":
825
+ if isinstance(base_value, str) and base_value != value:
826
+ top[key] = [base_value, value]
827
+ elif isinstance(base_value, list) and value not in value:
828
+ top[key].insert(0, value)
829
+ else:
830
+ top[key] = base_value
831
+ elif isinstance(value, list):
832
+ # 如果key为dependencies需要特殊处理
833
+ if key in ("dependencies", "dt_dependencies", "debug_dependencies", "platform"):
834
+ top[key] = tools.merge_dependencies(value, base_value)
835
+
836
+ def load_manifest_yml(self, filename=None, template=None):
837
+ top_manifest = False
838
+ if not filename:
839
+ filename = os.path.join(self.board_path, "manifest.yml")
840
+ top_manifest = True
841
+ # 注意:这里一定要判断template is None,不能使用if not template
842
+ if template is None:
843
+ template = self.get_template()
844
+ mani = self._load_manifest_with_template(filename, template)
845
+ inc_filename = mani.get("include")
846
+ if not inc_filename:
847
+ return mani
848
+ inc_filename = os.path.realpath(inc_filename)
849
+ boards = self.get_all_board(self.code_path)
850
+ for board, dir_path in boards.items():
851
+ manifest_yml = os.path.join(dir_path, "manifest.yml")
852
+ if manifest_yml == inc_filename:
853
+ template["ori_board_path"] = dir_path
854
+ template["board_name"] = board
855
+ break
856
+
857
+ mani_inc = self.load_manifest_yml(inc_filename, template)
858
+ self.merge_manifest_yml(mani, mani_inc, "")
859
+ if top_manifest and self.schema_need_validate:
860
+ schema_file = mani.get("schema", self.schema_file)
861
+ if not schema_file:
862
+ schema_file = misc.get_decleared_schema_file(filename)
863
+ # 获取产品配置的schema,已通过schema校验,必然存在
864
+ if schema_file is None:
865
+ raise errors.BmcGoException("未找到应该遵循的manifest规范,无法校验manifest.yml文件正确性," +
866
+ "请检查配置项yaml-language-server或schema配置项是否正确")
867
+ if not os.path.isfile(schema_file):
868
+ raise errors.BmcGoException(f"产品配置了一个不存在的manifest规范文件{schema_file}," +
869
+ "无法校验manifest.yml文件正确性,请检查bingo是否正确安装")
870
+ self.schema_file = schema_file
871
+ with open(self.schema_file, "rb") as fp:
872
+ schema = json.load(fp)
873
+ log.debug(f"使用规范配置文件{self.schema_file}校验{filename}配置项")
874
+ jsonschema.validate(mani, schema)
875
+ return mani
876
+
877
+ def get_archive(self):
878
+ self.archive_conf = self.get_manufacture_config("archive")
879
+ self.archive_path = self.get_manufacture_config("archive/archive_path")
880
+ if self.target == "docker_build":
881
+ self.archive_path = "openUBMC/ToCommunity"
882
+ self.partner_docker = self.get_manufacture_config("archive/partner_docker")
883
+
884
+ def version_split(self):
885
+ if isinstance(self.version, str):
886
+ if len(self.version.split('.')) == VERSION_LEN:
887
+ self.major_ver, self.miner_ver, self.release_ver, patch_ver, self.build_ver = self.version.split(".")
888
+ else:
889
+ self.major_ver, self.miner_ver, self.release_ver, patch_ver = self.version.split(".")
890
+ self.patch_ver = struct.pack('>i', int(patch_ver)).hex()
891
+ else:
892
+ raise ArithmeticError("版本号设置错误, 非 4 段 或 5 段样式")
893
+ # 填充构建日期
894
+ with open(f"{self.temp_path}/date/date.txt", "r") as date_fp:
895
+ date = date_fp.read().strip("\n")
896
+ self.date = time.strptime(date, "%H:%M:%S %b %d %Y")
897
+
898
+ def update_version(self, configured=False):
899
+ """ 更新版本号,并将manifest.yml文件版本号更新
900
+ 版本号使用优先级:zip包fix_version > 传入的参数 > manifest.yml > version.yml
901
+ """
902
+ self.rtos_version = self.get_manufacture_config("base/rtos_version")
903
+ self.rtos_kernel = self.get_manufacture_config("base/rtos_kernel")
904
+
905
+ # 参数从frame.py获取,如果为空(默认值),则未传入参数,从文件读取
906
+ if configured is False:
907
+ self.version = self.get_manufacture_config("base/version")
908
+ if self.version is None:
909
+ with open(f"{self.code_path}/version.yml", "r") as fp:
910
+ version_data = yaml.safe_load(fp)
911
+ self.version = f"{str(version_data[VERSION])}.{str(version_data[BUILD_NUMBER])}"
912
+
913
+ manifest_file = os.path.join(self.board_path, "manifest.yml")
914
+ with open(manifest_file, "r", encoding="utf-8") as fp:
915
+ mani = yaml.safe_load(fp)
916
+ mani["base"]["version"] = self.version
917
+ schema_file = misc.get_decleared_schema_file(manifest_file)
918
+ with os.fdopen(os.open(manifest_file, os.O_WRONLY | os.O_CREAT | os.O_TRUNC,
919
+ stat.S_IWUSR | stat.S_IRUSR), 'w+') as file_handler:
920
+ if schema_file != "":
921
+ file_handler.write(f"# yaml-language-server: $schema={schema_file}\n")
922
+ file_handler.write(yaml.safe_dump(mani))
923
+ self.version_split()
924
+
925
+ # 如果有包配置,则检查包里面的fix_version
926
+ fixed_version = None
927
+ if self.manufacture_code is not None:
928
+ key = f"manufacture/{self.manufacture_code}/fixed_version"
929
+ fixed_version = self.get_manufacture_config(key)
930
+
931
+ if fixed_version is not None:
932
+ log.warning(f"版本号因参数 {self.manufacture_code} 编码已变更为 {fixed_version}")
933
+ self.build_ver = self.version.rsplit(".")[-1]
934
+ self.version = fixed_version
935
+
936
+ # 将manifest格式化后的内容写入board_path的real_manifest.yml
937
+ def dump_manifest(self):
938
+ real_manifest_file = os.path.join(self.board_path, "real_manifest.yml")
939
+ mani = self.load_manifest_yml()
940
+ dumps = yaml.safe_dump(mani, sort_keys=False)
941
+ with os.fdopen(os.open(real_manifest_file, os.O_WRONLY | os.O_CREAT | os.O_TRUNC,
942
+ stat.S_IWUSR | stat.S_IRUSR), 'w+', encoding="utf-8") as file_handler:
943
+ file_handler.write(f"# yaml-language-server: $schema={self.schema_file}\n")
944
+ file_handler.write(dumps)
945
+
946
+ def version_conf(self, dest_file):
947
+ # 根据要打的包,确定版本号来源
948
+ version_data_source = "manufacture" if self.manufacture_code is not None else "tosupporte"
949
+ package_code = self.manufacture_code if self.manufacture_code is not None else self.tosupporte_code
950
+ package_name = self.get_origin_manufacture_config(f"{version_data_source}/{package_code}/package_name")
951
+ fixed_version = self.get_manufacture_config(f"{version_data_source}/{package_code}/fixed_version")
952
+ version = self.get_manufacture_config("base/version")
953
+
954
+ with open(dest_file, "r") as dst:
955
+ ver_dst_data = json.load(dst)
956
+ # 大版本字段为空,自动填充
957
+ if ver_dst_data[VERSION] == "":
958
+ real_version = ""
959
+ if fixed_version is not None:
960
+ real_version = fixed_version
961
+ else:
962
+ real_version = version
963
+ ver_dst_data[VERSION] = real_version.rsplit(".", 1)[0] if "B" in real_version else real_version
964
+ # 如果包名中有manufacture字段,则自动加1
965
+ if "manufacture" in package_name:
966
+ version_list = ver_dst_data[VERSION].rsplit(".", 1)
967
+ ver_dst_data[VERSION] = f"{version_list[0]}.{str(int(version_list[1]) + 1).zfill(2)}"
968
+
969
+ # 小版本为空,则填充
970
+ if ver_dst_data[BUILD_NUMBER] == "":
971
+ if fixed_version is not None and "B" in fixed_version:
972
+ ver_dst_data[BUILD_NUMBER] = fixed_version.rsplit(".", 1)[1].strip("B")
973
+ else:
974
+ ver_dst_data[BUILD_NUMBER] = version.rsplit(".", 1)[1].strip("B")
975
+
976
+ # 填充构建日期
977
+ if ver_dst_data['ReleaseDate'] == "":
978
+ with open(f"{self.temp_path}/date/date.txt", "r") as date_fp:
979
+ date = date_fp.read()
980
+ ver_dst_data['ReleaseDate'] = date.strip('\n')
981
+ dst.close()
982
+
983
+ # 写入到dest_file文件中
984
+ with os.fdopen(os.open(dest_file, os.O_WRONLY | os.O_CREAT | os.O_TRUNC,
985
+ stat.S_IWUSR | stat.S_IRUSR), 'w+') as file_handler:
986
+ json.dump(ver_dst_data, file_handler)
987
+ file_handler.close()
988
+
989
+ log.info(f"版本 json 配置: {ver_dst_data}")
990
+
991
+ def show_version_conf(self, dst_file):
992
+ """ 更新 json 文件, 并添加 ShowVersion 字段
993
+
994
+ Args:
995
+ dst_file (_type_): 要修改的 json 文件
996
+ """
997
+ with open(dst_file, "r") as js_fp:
998
+ ver_dst_data = json.load(js_fp)
999
+ if self.show_version != "":
1000
+ ver_dst_data["ShowVersion"] = self.show_version
1001
+ # 写入到dst_file文件中
1002
+ with os.fdopen(os.open(dst_file, os.O_WRONLY | os.O_CREAT | os.O_TRUNC,
1003
+ stat.S_IWUSR | stat.S_IRUSR), 'w+') as file_handler:
1004
+ json.dump(ver_dst_data, file_handler)
1005
+ file_handler.close()
1006
+ else:
1007
+ log.warning("未配置 show_version 字段")
1008
+
1009
+ def parse_args(self, args=None):
1010
+ parser = self.argparser(self.code_path)
1011
+ args, _ = parser.parse_known_args(args)
1012
+ self.set_manufacture_code(args.zip_code)
1013
+ self.set_tosupporte_code(args.supporte_code)
1014
+ self.set_from_source(args.from_source)
1015
+ self.set_build_type(args.build_type)
1016
+ self.set_stage(args.stage)
1017
+ self.set_board_name(args.board_name)
1018
+ self.asan = args.asan
1019
+ self.remote = args.remote
1020
+ self.remote_list = tools.get_conan_remote_list(self.remote)
1021
+ self.verbose = args.verbose
1022
+ if os.environ.get("LOG"):
1023
+ self.verbose = True
1024
+ self.update_conan_cache = args.update_conan_cache
1025
+ # 使能qemu放在上面,防止gcov使能的qemu包被False重置
1026
+ self.set_enable_qemu(args.enable_qemu)
1027
+ self.set_pull_up_qemu(args.qemu_in)
1028
+ # cov模式下,qemu包必定打出
1029
+ self.set_enable_arm_gcov(args.coverage)
1030
+ self.set_enable_luajit(args.enable_luajit)
1031
+ self.set_show_version()
1032
+ self.get_archive()
1033
+ self.init_conan_profile(args.profile)
1034
+
1035
+ if self.manufacture_code is not None and self.tosupporte_code != "default":
1036
+ raise errors.ConfigException("manufacture 编码和 tosupport E 编码不能同时存在")
1037
+
1038
+ # 构建阶段检查
1039
+ bt = ["dt", "debug", "release"]
1040
+ if args.build_type not in bt:
1041
+ raise errors.ConfigException("构建类型 build_type 错误, 可用选项为: [debug, release, dt], 请检查参数")
1042
+
1043
+ def _load_manifest_with_template(self, filename, template):
1044
+ try:
1045
+ real_sha256 = Config._calc_manifest_data_sha256(filename, template)
1046
+ cfg = self._manifest_data.get(real_sha256)
1047
+ if cfg:
1048
+ return copy.deepcopy(cfg)
1049
+ cfg = tools.yaml_load_template(filename, template, self.schema_need_validate)
1050
+ self._manifest_data[real_sha256] = cfg
1051
+ except Exception as e:
1052
+ raise OSError('加载 {} 时失败\n {}'.format(filename, str(e))) from e
1053
+ return copy.deepcopy(cfg)
1054
+
1055
+ def _merge_manifest_yaml_easy(self, top, base, prev_path):
1056
+ base_val = copy.deepcopy(base)
1057
+ for key, base_value in base_val.items():
1058
+ next_path = prev_path + key + "/"
1059
+ # 由上层决定出包逻辑
1060
+ if next_path == "tosupporte/" or next_path == "manufacture/":
1061
+ continue
1062
+ top_value = top.get(key)
1063
+ if top_value is None:
1064
+ top[key] = base_value
1065
+ continue
1066
+ if isinstance(base_value, dict):
1067
+ self._merge_manifest_yaml_easy(top_value, base_value, next_path)