openubmc-bingo 0.5.277__py3-none-any.whl → 0.6.2__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.
- bmcgo/__init__.py +1 -1
- bmcgo/bmcgo_config.py +22 -10
- bmcgo/cli/cli.py +95 -39
- bmcgo/cli/config.conan2.yaml +9 -0
- bmcgo/codegen/lua/codegen.py +2 -2
- bmcgo/codegen/lua/script/gen_intf_rpc_json.py +15 -14
- bmcgo/component/analysis/analysis.py +8 -8
- bmcgo/component/analysis/intf_validation.py +23 -12
- bmcgo/component/build.py +76 -14
- bmcgo/component/component_dt_version_parse.py +3 -2
- bmcgo/component/component_helper.py +43 -15
- bmcgo/component/coverage/incremental_cov.py +2 -2
- bmcgo/component/deploy.py +68 -14
- bmcgo/component/gen.py +1 -1
- bmcgo/component/package_info.py +128 -38
- bmcgo/component/template/conanbase.py.mako +1 -0
- bmcgo/component/template_v2/conanbase.py.mako +383 -0
- bmcgo/component/template_v2/conanfile.deploy.py.mako +26 -0
- bmcgo/component/test.py +53 -20
- bmcgo/frame.py +7 -3
- bmcgo/functional/analysis.py +3 -2
- bmcgo/functional/check.py +10 -6
- bmcgo/functional/conan_index_build.py +96 -20
- bmcgo/functional/csr_build.py +1 -1
- bmcgo/functional/diff.py +1 -1
- bmcgo/functional/fetch.py +1 -1
- bmcgo/functional/full_component.py +32 -24
- bmcgo/functional/git_history.py +220 -0
- bmcgo/functional/maintain.py +55 -12
- bmcgo/functional/new.py +1 -1
- bmcgo/functional/schema_valid.py +2 -2
- bmcgo/logger.py +2 -3
- bmcgo/misc.py +130 -9
- bmcgo/tasks/conan/__init__.py +10 -0
- bmcgo/tasks/conan/conanfile.py +45 -0
- bmcgo/tasks/task.py +27 -4
- bmcgo/tasks/task_build_conan.py +425 -53
- bmcgo/tasks/task_buildgppbin.py +8 -2
- bmcgo/tasks/task_download_buildtools.py +76 -0
- bmcgo/tasks/task_download_dependency.py +1 -0
- bmcgo/tasks/task_hpm_envir_prepare.py +1 -1
- bmcgo/utils/build_conans.py +231 -0
- bmcgo/utils/component_post.py +6 -4
- bmcgo/utils/component_version_check.py +75 -16
- bmcgo/utils/config.py +76 -40
- bmcgo/utils/fetch_component_code.py +44 -25
- bmcgo/utils/tools.py +239 -117
- bmcgo/worker.py +2 -2
- {openubmc_bingo-0.5.277.dist-info → openubmc_bingo-0.6.2.dist-info}/METADATA +4 -2
- {openubmc_bingo-0.5.277.dist-info → openubmc_bingo-0.6.2.dist-info}/RECORD +53 -46
- {openubmc_bingo-0.5.277.dist-info → openubmc_bingo-0.6.2.dist-info}/WHEEL +0 -0
- {openubmc_bingo-0.5.277.dist-info → openubmc_bingo-0.6.2.dist-info}/entry_points.txt +0 -0
- {openubmc_bingo-0.5.277.dist-info → openubmc_bingo-0.6.2.dist-info}/top_level.txt +0 -0
bmcgo/component/package_info.py
CHANGED
|
@@ -22,9 +22,11 @@ from bmcgo.codegen import __version__ as codegen_version
|
|
|
22
22
|
from bmcgo.logger import Logger
|
|
23
23
|
from bmcgo.utils.tools import Tools
|
|
24
24
|
from bmcgo import misc
|
|
25
|
+
from bmcgo import errors
|
|
25
26
|
from bmcgo.component.component_helper import ComponentHelper
|
|
26
27
|
|
|
27
28
|
global log
|
|
29
|
+
tools = Tools()
|
|
28
30
|
log = Logger()
|
|
29
31
|
|
|
30
32
|
cwd = os.getcwd()
|
|
@@ -40,22 +42,28 @@ class CodegenPolicyError(OSError):
|
|
|
40
42
|
|
|
41
43
|
|
|
42
44
|
class InfoComp():
|
|
43
|
-
def __init__(self, args=None, service_json="mds/service.json", partner_mode=False):
|
|
44
|
-
|
|
45
|
+
def __init__(self, args=None, service_json="mds/service.json", partner_mode=False, enable_upload=True):
|
|
46
|
+
self.enable_upload = enable_upload
|
|
47
|
+
self.package = ""
|
|
48
|
+
self.setting = ""
|
|
49
|
+
self.full_profile = ""
|
|
50
|
+
self.cmd_base = ""
|
|
51
|
+
parser = self.arg_parser(True, partner_mode, enable_upload)
|
|
45
52
|
self.parse_args(parser, args, service_json)
|
|
46
53
|
|
|
47
54
|
@staticmethod
|
|
48
|
-
def arg_parser(add_help=False, partner_mode=False):
|
|
55
|
+
def arg_parser(add_help=False, partner_mode=False, enable_upload=True):
|
|
49
56
|
stage_values = [member.value for member in misc.StageEnum]
|
|
50
|
-
parser = argparse.ArgumentParser(prog="
|
|
57
|
+
parser = argparse.ArgumentParser(prog=f"{misc.tool_name()} build", description="Build conan", add_help=add_help,
|
|
51
58
|
formatter_class=argparse.RawTextHelpFormatter)
|
|
52
|
-
parser.add_argument("-bt", "--build_type", default="debug", help="构建类型,可选:
|
|
59
|
+
parser.add_argument("-bt", "--build_type", default="debug", help=f"构建类型,可选:{misc.build_type_str()}\n默认:debug")
|
|
53
60
|
parser.add_argument(
|
|
54
|
-
"--stage",
|
|
55
|
-
help=f"组件包发布阶段, 可选: {stage_values}\n默认:{misc.StageEnum.STAGE_DEV.value}",
|
|
61
|
+
"--stage",
|
|
62
|
+
help=f"组件包发布阶段, 可选: {stage_values}\n默认:{misc.StageEnum.STAGE_DEV.value}",
|
|
56
63
|
default=misc.StageEnum.STAGE_DEV.value
|
|
57
64
|
)
|
|
58
|
-
|
|
65
|
+
if enable_upload:
|
|
66
|
+
parser.add_argument("-u", "--upload", action=misc.STORE_TRUE, help="上传组件包到conan仓")
|
|
59
67
|
parser.add_argument(
|
|
60
68
|
"-r", "--remote", help=f"conan仓别名,请检查conan remote list查看已配置的conan仓"
|
|
61
69
|
)
|
|
@@ -71,14 +79,19 @@ class InfoComp():
|
|
|
71
79
|
)
|
|
72
80
|
parser.add_argument("-nc", "--no_cache",
|
|
73
81
|
help="不使用~/.conan/data目录下的缓存包(构建前删除缓存)", action=misc.STORE_FALSE)
|
|
74
|
-
|
|
75
|
-
|
|
82
|
+
if misc.conan_v2():
|
|
83
|
+
parser.add_argument("-o", "--options", action='append', default=[],
|
|
84
|
+
help="Define options values (host machine), e.g.: -o Pkg/*:with_qt=True")
|
|
85
|
+
else:
|
|
86
|
+
parser.add_argument("-o", "--options", action='append', default=[],
|
|
87
|
+
help="Define options values (host machine), e.g.: -o Pkg:with_qt=True")
|
|
76
88
|
parser.add_argument(
|
|
77
89
|
"--user",
|
|
78
|
-
help=f"指定conan包的user
|
|
90
|
+
help=f"指定conan包的user字段,未指定时依次尝试读取mds/service.json的user字段,都未指定时使用'{misc.conan_user()}'",
|
|
79
91
|
default=None
|
|
80
92
|
)
|
|
81
93
|
parser.add_argument("-cov", "--coverage", help=argparse.SUPPRESS, action=misc.STORE_TRUE)
|
|
94
|
+
parser.add_argument("-test", "--test", help=argparse.SUPPRESS, action=misc.STORE_TRUE)
|
|
82
95
|
parser.add_argument(
|
|
83
96
|
"-as",
|
|
84
97
|
"--asan",
|
|
@@ -92,11 +105,14 @@ class InfoComp():
|
|
|
92
105
|
help=argparse.SUPPRESS if partner_mode else Tools.get_profile_arg_help(),
|
|
93
106
|
default="",
|
|
94
107
|
)
|
|
108
|
+
profile_name = tools.get_conan_profile("", "", True)
|
|
109
|
+
profile_file = os.path.join(tools.conan_profiles_dir, profile_name)
|
|
110
|
+
default_enable_luajit = partner_mode and os.path.isfile(profile_file)
|
|
95
111
|
parser.add_argument(
|
|
96
112
|
"-jit",
|
|
97
113
|
"--enable_luajit",
|
|
98
|
-
help=argparse.SUPPRESS if
|
|
99
|
-
action=misc.STORE_FALSE if
|
|
114
|
+
help=argparse.SUPPRESS if default_enable_luajit else "Enable luajit",
|
|
115
|
+
action=misc.STORE_FALSE if default_enable_luajit else misc.STORE_TRUE,
|
|
100
116
|
)
|
|
101
117
|
return parser
|
|
102
118
|
|
|
@@ -104,7 +120,9 @@ class InfoComp():
|
|
|
104
120
|
def get_codegen_policy(service_data) -> Tuple[str, int]:
|
|
105
121
|
# 代码自动生成工具版本号检查
|
|
106
122
|
policy = ComponentHelper.get_config_value(service_data, "codegen_policy", {})
|
|
107
|
-
|
|
123
|
+
if "codeGenPolicy" in service_data:
|
|
124
|
+
policy = ComponentHelper.get_config_value(service_data, "codeGenPolicy", {})
|
|
125
|
+
code_version = policy.get("version", "3")
|
|
108
126
|
if not isinstance(code_version, str):
|
|
109
127
|
code_version = str(code_version)
|
|
110
128
|
code_language = policy.get("language", "c")
|
|
@@ -116,54 +134,80 @@ class InfoComp():
|
|
|
116
134
|
if code_version.startswith(">="):
|
|
117
135
|
codegen_base_version = int(code_version[2:])
|
|
118
136
|
if codegen_base_version > codegen_version:
|
|
119
|
-
raise CodegenVersionNotMatchError("代码自动生成要求的版本号大于当前
|
|
137
|
+
raise CodegenVersionNotMatchError(f"代码自动生成要求的版本号大于当前{misc.tool_name()}工具提供的版本号,建议升级到最新版本")
|
|
120
138
|
codegen_base_version = codegen_version
|
|
121
139
|
else:
|
|
122
140
|
codegen_base_version = int(code_version)
|
|
123
141
|
return code_language, codegen_base_version
|
|
124
142
|
|
|
143
|
+
@staticmethod
|
|
144
|
+
def get_dependencies_v2(service_data, key):
|
|
145
|
+
dependencies = []
|
|
146
|
+
user_channel = f"@{misc.conan_user()}/stable"
|
|
147
|
+
deps = ComponentHelper.get_config_value(service_data, key, [])
|
|
148
|
+
for dep in deps:
|
|
149
|
+
conan = dep.get(misc.CONAN)
|
|
150
|
+
if conan is None:
|
|
151
|
+
log.info("获取 conan 依赖失败, 跳过未知组件")
|
|
152
|
+
continue
|
|
153
|
+
if conan.find("@") < 0:
|
|
154
|
+
conan += user_channel
|
|
155
|
+
if not misc.conan_package_match(conan, True):
|
|
156
|
+
raise errors.BmcGoException(f"未正确定义依赖组件的名称: {conan}")
|
|
157
|
+
dependencies.append(conan)
|
|
158
|
+
|
|
159
|
+
return dependencies
|
|
160
|
+
|
|
125
161
|
def parse_args(self, parser, args, service_json):
|
|
126
162
|
self.args, _ = parser.parse_known_args(args)
|
|
127
163
|
self.build_type = self.args.build_type
|
|
128
164
|
self.stage = self.args.stage
|
|
129
|
-
|
|
165
|
+
if self.enable_upload:
|
|
166
|
+
self.upload = self.args.upload
|
|
167
|
+
else:
|
|
168
|
+
self.upload = False
|
|
130
169
|
self.from_source = self.args.from_source
|
|
131
170
|
self.options = self.args.options
|
|
132
171
|
self.coverage = self.args.coverage
|
|
133
172
|
self.asan = self.args.asan
|
|
134
173
|
self.remote = self.args.remote
|
|
174
|
+
self.user = self.args.user
|
|
175
|
+
self.test = self.args.test
|
|
135
176
|
self.no_cache = self.args.no_cache and (not os.getenv('NOT_CLEAN_CONAN_CACHE') == 'True')
|
|
136
177
|
# 是否是维护模式
|
|
137
178
|
self.is_maintain = self.args.maintain
|
|
138
179
|
self.enable_luajit = self.args.enable_luajit
|
|
139
|
-
self.profile = Tools.get_conan_profile(self.args.profile, self.build_type, self.enable_luajit)
|
|
180
|
+
self.profile = Tools.get_conan_profile(self.args.profile, self.build_type, self.enable_luajit, self.test)
|
|
181
|
+
if self.profile == "profile.luajit.ini":
|
|
182
|
+
self.enable_luajit = True
|
|
140
183
|
|
|
141
184
|
os.environ["ROOTFS_DIR"] = os.path.join(cwd, "temp")
|
|
142
185
|
stage_values = [member.value for member in misc.StageEnum]
|
|
143
186
|
if self.stage not in stage_values:
|
|
144
187
|
raise OSError(f"参数 stage 错误, 请从 {stage_values} 中选择")
|
|
145
188
|
# 构建阶段检查
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
raise OSError("参数 build_type 错误, 请从 [debug, release, dt] 中选择")
|
|
189
|
+
if self.build_type not in misc.build_type():
|
|
190
|
+
raise OSError(f"参数 build_type 错误, 请从 {misc.build_type_str()} 中选择")
|
|
149
191
|
if self.upload and not self.remote:
|
|
150
192
|
raise OSError("参数 remote 必填")
|
|
151
193
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
self.stage
|
|
156
|
-
|
|
157
|
-
|
|
194
|
+
if misc.conan_v1():
|
|
195
|
+
# 只有指定为pre时才增加prerelease编码
|
|
196
|
+
pre = ""
|
|
197
|
+
if self.stage == misc.StageEnum.STAGE_PRE:
|
|
198
|
+
self.stage = misc.StageEnum.STAGE_DEV
|
|
199
|
+
now = datetime.datetime.utcnow()
|
|
200
|
+
pre = "-pre." + now.strftime("%Y%m%d%H%M%S")
|
|
158
201
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
202
|
+
# 尝试从/etc/bmcgo.conf读取user配置
|
|
203
|
+
user = self._get_package_user()
|
|
204
|
+
self.channel = f"@{user}/{self.stage}"
|
|
205
|
+
self._parse_service_json(service_json, pre)
|
|
206
|
+
else:
|
|
207
|
+
self._parse_service_json(service_json)
|
|
164
208
|
self._conan_define()
|
|
165
209
|
|
|
166
|
-
def
|
|
210
|
+
def get_dependencies_v1(self, service_data, key):
|
|
167
211
|
dependencies = []
|
|
168
212
|
user_channel = ComponentHelper.get_user_channel(self.stage)
|
|
169
213
|
deps = ComponentHelper.get_config_value(service_data, key, [])
|
|
@@ -178,14 +222,51 @@ class InfoComp():
|
|
|
178
222
|
dependencies.append(conan + user_channel)
|
|
179
223
|
return dependencies
|
|
180
224
|
|
|
225
|
+
def get_dependencies(self, service_data, key):
|
|
226
|
+
if misc.conan_v1():
|
|
227
|
+
return self.get_dependencies_v1(service_data, key)
|
|
228
|
+
else:
|
|
229
|
+
return self.get_dependencies_v2(service_data, key)
|
|
230
|
+
|
|
181
231
|
def _conan_define(self):
|
|
232
|
+
if misc.conan_v1():
|
|
233
|
+
self._conan_define_v1()
|
|
234
|
+
else:
|
|
235
|
+
self._conan_define_v2()
|
|
236
|
+
|
|
237
|
+
def _conan_define_v2(self):
|
|
238
|
+
self.package = "%s/%s@%s/%s" % (self.name, self.version, self.user, self.stage)
|
|
239
|
+
profiles = [f"-pr:h {self.profile}"]
|
|
240
|
+
profiles.append("-pr:b default")
|
|
241
|
+
if self.enable_luajit:
|
|
242
|
+
self.options.append("*/*:enable_luajit=True")
|
|
243
|
+
if self.build_type == "debug":
|
|
244
|
+
self.setting = "-s:a build_type=Debug"
|
|
245
|
+
else:
|
|
246
|
+
self.setting = "-s:a build_type=Release"
|
|
247
|
+
self.full_profile = " ".join(profiles)
|
|
248
|
+
self.cmd_base = ". %s %s " % (self.full_profile, self.setting)
|
|
249
|
+
self.cmd_base += "%s %s " % (f"--user {self.user}", f"--channel {self.stage}")
|
|
250
|
+
if self.remote:
|
|
251
|
+
self.cmd_base += "-r %s " % self.remote
|
|
252
|
+
if self.options:
|
|
253
|
+
for option in self.options:
|
|
254
|
+
self.cmd_base += " -o " + option
|
|
255
|
+
if self.coverage:
|
|
256
|
+
self.cmd_base += f" -o {self.name}/*:gcov=True"
|
|
257
|
+
if self.asan:
|
|
258
|
+
self.cmd_base += f" -o {self.name}/*:asan=True"
|
|
259
|
+
if self.test:
|
|
260
|
+
self.cmd_base += f" -o */*:test=True"
|
|
261
|
+
|
|
262
|
+
def _conan_define_v1(self):
|
|
182
263
|
self.package = "%s/%s%s" % (self.name, self.version, self.channel)
|
|
183
264
|
profiles = [f"-pr:h {self.profile}"]
|
|
184
265
|
if self.build_type == "dt":
|
|
185
266
|
self.setting = "-s build_type=Dt"
|
|
186
267
|
else:
|
|
187
268
|
profiles.append("-pr:b profile.dt.ini")
|
|
188
|
-
if self.enable_luajit:
|
|
269
|
+
if self.enable_luajit or misc.community_name() == "openubmc":
|
|
189
270
|
self.options.append("skynet:enable_luajit=True")
|
|
190
271
|
if self.build_type == "debug":
|
|
191
272
|
self.setting = "-s build_type=Debug"
|
|
@@ -215,17 +296,26 @@ class InfoComp():
|
|
|
215
296
|
user = None
|
|
216
297
|
if user is None:
|
|
217
298
|
if self.stage == misc.StageEnum.STAGE_DEV.value:
|
|
218
|
-
user = misc.
|
|
299
|
+
user = misc.conan_user_dev()
|
|
219
300
|
else:
|
|
220
|
-
user = misc.
|
|
301
|
+
user = misc.conan_user()
|
|
221
302
|
return user
|
|
222
303
|
|
|
223
|
-
def _parse_service_json(self, service_json: str, pre: str):
|
|
304
|
+
def _parse_service_json(self, service_json: str, pre: str = ""):
|
|
224
305
|
self.language = ComponentHelper.get_language(service_json=service_json)
|
|
225
306
|
with open(service_json, "r", encoding="UTF-8") as file_handler:
|
|
226
307
|
data = json.load(file_handler)
|
|
227
|
-
|
|
228
|
-
|
|
308
|
+
if misc.conan_v2():
|
|
309
|
+
self.language = data.get("language", "lua")
|
|
310
|
+
if not self.user:
|
|
311
|
+
self.user = data.get("user", misc.conan_user()).lower()
|
|
312
|
+
if self.stage == "dev":
|
|
313
|
+
self.user += ".dev"
|
|
314
|
+
self.version = ComponentHelper.get_config_value(data, "version").lower()
|
|
315
|
+
self.name = data.get("name").lower()
|
|
316
|
+
else:
|
|
317
|
+
self.version = ComponentHelper.get_config_value(data, "version") + pre
|
|
318
|
+
self.name = data.get("name")
|
|
229
319
|
# 编译依赖
|
|
230
320
|
self.build_dependencies = self.get_dependencies(data, "dependencies/build")
|
|
231
321
|
# 开发者测试依赖
|
|
@@ -0,0 +1,383 @@
|
|
|
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
|
+
import os
|
|
13
|
+
import concurrent.futures
|
|
14
|
+
import urllib3
|
|
15
|
+
% if pkg.is_maintain:
|
|
16
|
+
import time
|
|
17
|
+
% endif
|
|
18
|
+
% if pkg.is_maintain:
|
|
19
|
+
import stat
|
|
20
|
+
import shutil
|
|
21
|
+
% endif
|
|
22
|
+
from conan import ConanFile
|
|
23
|
+
from conan.tools.scm import Git
|
|
24
|
+
from conan.tools.cmake import CMake, CMakeToolchain, cmake_layout
|
|
25
|
+
from conan.tools.files import copy, update_conandata, chdir, rm
|
|
26
|
+
from conan.errors import ConanInvalidConfiguration
|
|
27
|
+
% if language == "c":
|
|
28
|
+
from bmcgo.component.gen import GenComp
|
|
29
|
+
% endif
|
|
30
|
+
% if pkg.is_maintain:
|
|
31
|
+
from conans import tools
|
|
32
|
+
from conans.util.files import mkdir
|
|
33
|
+
from conan.tools.files import patch as apply_patch
|
|
34
|
+
from conans.errors import ConanException
|
|
35
|
+
% endif
|
|
36
|
+
|
|
37
|
+
urllib3.disable_warnings()
|
|
38
|
+
|
|
39
|
+
# 构建时由工具自动生成到业务仓,做为conanfile.py的基类参与组件构建
|
|
40
|
+
# 如需要调试,请修改模板文件(目录中存在python版本号、bingo集成开发环境应用名称,请适配):
|
|
41
|
+
# ~/.local/lib/python3.8/site-packages/bingo/component/template/conanbase.py.mako
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
class ConanBase(ConanFile):
|
|
45
|
+
name = "${pkg.name}"
|
|
46
|
+
% if not pkg.is_maintain:
|
|
47
|
+
version = "${pkg.version}"
|
|
48
|
+
% endif
|
|
49
|
+
settings = "os", "compiler", "build_type", "arch"
|
|
50
|
+
license = "Mulan PSL v2"
|
|
51
|
+
generators = "CMakeDeps", "VirtualBuildEnv", "PkgConfigDeps"
|
|
52
|
+
language = "${language}"
|
|
53
|
+
_cmake = None
|
|
54
|
+
_codegen_version = ${codegen_version}
|
|
55
|
+
options = {
|
|
56
|
+
"asan": [True, False],
|
|
57
|
+
"gcov": [True, False],
|
|
58
|
+
"test": [True, False],
|
|
59
|
+
"manufacture": [True, False],
|
|
60
|
+
% if language == "lua":
|
|
61
|
+
"enable_luajit": [True, False],
|
|
62
|
+
% endif
|
|
63
|
+
% for op, ctx in pkg.design_options.items():
|
|
64
|
+
"${op}": [${", ".join(("\"" + i + "\"") if isinstance(i, str) else str(i) for i in ctx["option"])}],
|
|
65
|
+
% endfor
|
|
66
|
+
}
|
|
67
|
+
default_options = {
|
|
68
|
+
"asan": False,
|
|
69
|
+
"gcov": False,
|
|
70
|
+
"test": False,
|
|
71
|
+
"manufacture": False,
|
|
72
|
+
% if language == "lua":
|
|
73
|
+
"enable_luajit": False,
|
|
74
|
+
% endif
|
|
75
|
+
% for op, ctx in pkg.design_options.items():
|
|
76
|
+
"${op}": ${("\"" + ctx["default"] + "\"") if isinstance(ctx["default"], str) else str(ctx["default"])},
|
|
77
|
+
% endfor
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
def layout(self):
|
|
81
|
+
cmake_layout(self, build_folder=".build")
|
|
82
|
+
|
|
83
|
+
def requirements(self):
|
|
84
|
+
% if len(pkg.build_dependencies) > 0:
|
|
85
|
+
# 编译依赖
|
|
86
|
+
% for build_dep in pkg.build_dependencies:
|
|
87
|
+
self.requires("${build_dep}")
|
|
88
|
+
% endfor
|
|
89
|
+
% endif
|
|
90
|
+
%if language == "lua":
|
|
91
|
+
skynet = self.conf.get("user.tools:skynet")
|
|
92
|
+
if skynet:
|
|
93
|
+
self.tool_requires(skynet, options={"tools_only": True})
|
|
94
|
+
luajit = self.conf.get("user.tools:luajit")
|
|
95
|
+
if luajit:
|
|
96
|
+
self.tool_requires(luajit, options={"tools_only": True})
|
|
97
|
+
% endif
|
|
98
|
+
pass
|
|
99
|
+
|
|
100
|
+
def export(self):
|
|
101
|
+
copy(self, "conanbase.py", self.recipe_folder, self.export_folder)
|
|
102
|
+
% if not pkg.is_maintain:
|
|
103
|
+
git = Git(self, self.recipe_folder)
|
|
104
|
+
if git.is_dirty():
|
|
105
|
+
update_conandata(self, {"sources": {self.version: {"branch": None, "url": None, "pwd": os.getcwd(), "timestamp": int(time.time())}}})
|
|
106
|
+
return
|
|
107
|
+
url = None
|
|
108
|
+
commit = git.get_commit()
|
|
109
|
+
branches = git.run("branch -r --contains {}".format(commit))
|
|
110
|
+
remotes = git.run("remote")
|
|
111
|
+
for remote in remotes.splitlines():
|
|
112
|
+
if "{}/".format(remote) in branches:
|
|
113
|
+
url = git.get_remote_url(remote)
|
|
114
|
+
break
|
|
115
|
+
if not url:
|
|
116
|
+
update_conandata(self, {"sources": {self.version: {"branch": None, "url": None, "pwd": os.getcwd(), "timestamp": int(time.time())}}})
|
|
117
|
+
return
|
|
118
|
+
tag = git.run("tag --points-at HEAD")
|
|
119
|
+
update_conandata(self, {"sources": {self.version: {"branch": f"refs/tags/{tag}" if tag else commit, "url": url}}})
|
|
120
|
+
% endif
|
|
121
|
+
|
|
122
|
+
% if pkg.is_maintain:
|
|
123
|
+
def export_sources(self):
|
|
124
|
+
patches = self.conan_data.get("patches", {}).get(self.version, [])
|
|
125
|
+
for patch in patches:
|
|
126
|
+
patch_file = patch.get("patch_file")
|
|
127
|
+
if patch_file is None:
|
|
128
|
+
continue
|
|
129
|
+
# 与export_conandata_patches方法不同点:所有patches将从recipes_folder/../pacthes读取
|
|
130
|
+
src = os.path.join(self.recipe_folder, "..", patch_file)
|
|
131
|
+
dst = os.path.join(self.export_sources_folder, patch_file)
|
|
132
|
+
mkdir(os.path.dirname(dst))
|
|
133
|
+
shutil.copy2(src, dst)
|
|
134
|
+
|
|
135
|
+
% endif
|
|
136
|
+
def source(self):
|
|
137
|
+
git = Git(self)
|
|
138
|
+
sources = self.conan_data["sources"][self.version]
|
|
139
|
+
% if pkg.is_maintain:
|
|
140
|
+
if sources["url"] and sources["branch"]:
|
|
141
|
+
git.fetch_commit(url=sources["url"], commit=sources["branch"].split("/")[-1])
|
|
142
|
+
else:
|
|
143
|
+
copy(self, "*", src=sources["pwd"], dst=".")
|
|
144
|
+
% else:
|
|
145
|
+
git.fetch_commit(url=sources["url"], commit=sources["branch"].split("/")[-1])
|
|
146
|
+
% endif
|
|
147
|
+
% if language == "c":
|
|
148
|
+
self._codegen()
|
|
149
|
+
% endif
|
|
150
|
+
|
|
151
|
+
def generate(self):
|
|
152
|
+
tc = self._pre_generate()
|
|
153
|
+
tc.generate()
|
|
154
|
+
|
|
155
|
+
% if pkg.is_maintain:
|
|
156
|
+
@staticmethod
|
|
157
|
+
def _get_patch_changed_files(patch_file):
|
|
158
|
+
files = {}
|
|
159
|
+
for line in open(patch_file):
|
|
160
|
+
if not line.startswith("diff --git"):
|
|
161
|
+
continue
|
|
162
|
+
line = line.strip()
|
|
163
|
+
chunk = line.split()
|
|
164
|
+
a_file = chunk[-2][2:]
|
|
165
|
+
b_file = chunk[-1][2:]
|
|
166
|
+
files[a_file] = b_file
|
|
167
|
+
return files
|
|
168
|
+
|
|
169
|
+
%endif
|
|
170
|
+
def build(self):
|
|
171
|
+
% if pkg.is_maintain:
|
|
172
|
+
for patch in self.conan_data.get("patches", {}).get(self.version, []):
|
|
173
|
+
patch_file = patch.get("patch_file")
|
|
174
|
+
if not patch_file:
|
|
175
|
+
continue
|
|
176
|
+
real_path = os.path.join(self.folders.base_source, patch_file)
|
|
177
|
+
print(f"Start patch file {patch_file}")
|
|
178
|
+
changed_files = self._get_patch_changed_files(real_path)
|
|
179
|
+
try:
|
|
180
|
+
apply_patch(self, patch_file=real_path)
|
|
181
|
+
self._revise_renamed_files(changed_files)
|
|
182
|
+
cmd = f"git commit -m \"{patch_file}\""
|
|
183
|
+
self.run(cmd)
|
|
184
|
+
except ConanException:
|
|
185
|
+
# 尝试还原文件修改
|
|
186
|
+
for a_file, b_file in changed_files.items():
|
|
187
|
+
cmd = f"git checkout -- {a_file}"
|
|
188
|
+
self.run(cmd, ignore_errors=True)
|
|
189
|
+
cmd = f"git checkout -- {b_file}"
|
|
190
|
+
self.run(cmd, ignore_errors=True)
|
|
191
|
+
cmd = "git am " + real_path
|
|
192
|
+
self.run(cmd)
|
|
193
|
+
% endif
|
|
194
|
+
cmake = self._configure_cmake()
|
|
195
|
+
cmake.build()
|
|
196
|
+
|
|
197
|
+
def package(self):
|
|
198
|
+
cmake = self._configure_cmake()
|
|
199
|
+
cmake.install()
|
|
200
|
+
files_to_copy = [
|
|
201
|
+
("permissions.ini", self.source_folder, self.package_folder),
|
|
202
|
+
("model.json", os.path.join(self.source_folder, "mds"),
|
|
203
|
+
os.path.join(self.package_folder, "include/mds")),
|
|
204
|
+
("service.json", os.path.join(self.source_folder, "mds"),
|
|
205
|
+
os.path.join(self.package_folder, "include/mds")),
|
|
206
|
+
("*", os.path.join(self.source_folder, "customization"),
|
|
207
|
+
os.path.join(self.package_folder, "include")),
|
|
208
|
+
("*", os.path.join(self.source_folder, "mds"),
|
|
209
|
+
os.path.join(self.package_folder, "usr/share/doc/openubmc/${pkg.name}/mds")),
|
|
210
|
+
("*", os.path.join(self.source_folder, "docs"),
|
|
211
|
+
os.path.join(self.package_folder, "usr/share/doc/openubmc/${pkg.name}/docs")),
|
|
212
|
+
("*", os.path.join(self.source_folder, "build"),
|
|
213
|
+
os.path.join(self.package_folder, "include")),
|
|
214
|
+
("permissions.ini", os.path.join(self.source_folder, "dist"), self.package_folder),
|
|
215
|
+
("*.md", self.source_folder, os.path.join(self.package_folder,
|
|
216
|
+
"usr/share/doc/openubmc/${pkg.name}/docs")),
|
|
217
|
+
("*.MD", self.source_folder, os.path.join(self.package_folder,
|
|
218
|
+
"usr/share/doc/openubmc/${pkg.name}/docs"))
|
|
219
|
+
]
|
|
220
|
+
for pattern, src, dst in files_to_copy:
|
|
221
|
+
copy(self, pattern, src=src, dst=dst, keep_path=True)
|
|
222
|
+
|
|
223
|
+
# 只有当需要统计覆盖率且TRANSTOBIN环境变量未设置时才不处理lua文件
|
|
224
|
+
if self.options.gcov and os.getenv("TRANSTOBIN") is None:
|
|
225
|
+
return
|
|
226
|
+
|
|
227
|
+
os.chdir(self.package_folder)
|
|
228
|
+
with concurrent.futures.ThreadPoolExecutor(max_workers=4) as executor:
|
|
229
|
+
for root, _, files in os.walk("."):
|
|
230
|
+
self.compile_files(root, files, executor)
|
|
231
|
+
rm(self, "luac.out", self.package_folder)
|
|
232
|
+
|
|
233
|
+
def compile_files(self, root, files, executor):
|
|
234
|
+
for file in files:
|
|
235
|
+
if file.endswith(".lua") and not os.path.islink(os.path.join(root, file)):
|
|
236
|
+
file_path = os.path.join(root, file)
|
|
237
|
+
if self.options.enable_luajit:
|
|
238
|
+
executor.submit(self.compile_file, file_path, True)
|
|
239
|
+
else:
|
|
240
|
+
executor.submit(self.compile_file, file_path, False)
|
|
241
|
+
|
|
242
|
+
def compile_file(self, file_path, enable_luajit):
|
|
243
|
+
if enable_luajit:
|
|
244
|
+
self.run(f"luajit -b -g {file_path} {file_path}")
|
|
245
|
+
else:
|
|
246
|
+
self.run(f"luac -o {file_path} {file_path}")
|
|
247
|
+
self.run(f"luac -s {file_path}")
|
|
248
|
+
|
|
249
|
+
def package_info(self):
|
|
250
|
+
app_dir = os.path.join(self.package_folder, "opt/bmc/apps/${pkg.name}")
|
|
251
|
+
if os.path.isdir(app_dir):
|
|
252
|
+
self.runenv_info.append("PATH", ':' + app_dir)
|
|
253
|
+
self.buildenv_info.append("PATH", ':' + app_dir)
|
|
254
|
+
% if "application" in pkg.package_type and pkg.package_info is not None:
|
|
255
|
+
% if len(pkg.package_info.get("bindirs", [])) > 0:
|
|
256
|
+
self.cpp_info.bindirs = [${", ".join("\"" + i + "\"" for i in pkg.package_info["bindirs"])}]
|
|
257
|
+
% for dir in pkg.package_info["bindirs"]:
|
|
258
|
+
self.env_info.PATH.append(os.path.join(self.package_folder, "${dir}"))
|
|
259
|
+
% endfor
|
|
260
|
+
% endif
|
|
261
|
+
% endif
|
|
262
|
+
libs = []
|
|
263
|
+
dirs = []
|
|
264
|
+
for root, _, files in os.walk("."):
|
|
265
|
+
for file in files:
|
|
266
|
+
dirname, libname = self.find_libraries(root, file)
|
|
267
|
+
if dirname and dirname not in dirs:
|
|
268
|
+
dirs.append(dirname)
|
|
269
|
+
if libname:
|
|
270
|
+
libs.append(libname)
|
|
271
|
+
|
|
272
|
+
if dirs:
|
|
273
|
+
self.cpp_info.components["${pkg.name}"].set_property("cmake_target_name", "${pkg.name}::${pkg.name}")
|
|
274
|
+
self.cpp_info.components["${pkg.name}"].set_property("cmake_target_aliass", ["${pkg.name}::${pkg.name}"])
|
|
275
|
+
self.cpp_info.components["${pkg.name}"].set_property("pkg_config_name", "${pkg.name}")
|
|
276
|
+
self.cpp_info.components["${pkg.name}"].libs = libs
|
|
277
|
+
self.cpp_info.components["${pkg.name}"].libdirs = dirs
|
|
278
|
+
for dir in dirs:
|
|
279
|
+
self.runenv_info.append("LD_LIBRARY_PATH", os.path.join(self.package_folder, dir))
|
|
280
|
+
self.buildenv_info.append("LD_LIBRARY_PATH", os.path.join(self.package_folder, dir))
|
|
281
|
+
|
|
282
|
+
def find_libraries(self, root, file):
|
|
283
|
+
if file.endswith(".so") and file.startswith("lib"):
|
|
284
|
+
if root.startswith("./"):
|
|
285
|
+
dirname = root[2:]
|
|
286
|
+
else:
|
|
287
|
+
dirname = root
|
|
288
|
+
libname = file[3:-3]
|
|
289
|
+
return (dirname, libname)
|
|
290
|
+
if file.endswith(".a") and file.startswith("lib"):
|
|
291
|
+
if root.startswith("./"):
|
|
292
|
+
dirname = root[2:]
|
|
293
|
+
else:
|
|
294
|
+
dirname = root
|
|
295
|
+
return (dirname, file)
|
|
296
|
+
return (None, None)
|
|
297
|
+
|
|
298
|
+
% if pkg.is_maintain:
|
|
299
|
+
def _revise_renamed_files(self, changed_files):
|
|
300
|
+
for a_file, b_file in changed_files.items():
|
|
301
|
+
if a_file != b_file:
|
|
302
|
+
if a_file != "/dev/null" and b_file != "/dev/null":
|
|
303
|
+
os.rename(a_file, b_file)
|
|
304
|
+
cmd = f"git rm -f {a_file}"
|
|
305
|
+
self.run(cmd)
|
|
306
|
+
elif a_file != "/dev/null":
|
|
307
|
+
cmd = f"git rm -f {a_file}"
|
|
308
|
+
self.run(cmd)
|
|
309
|
+
continue
|
|
310
|
+
cmd = f"git add {b_file}"
|
|
311
|
+
self.run(cmd)
|
|
312
|
+
|
|
313
|
+
%endif
|
|
314
|
+
def _configure_cmake(self):
|
|
315
|
+
if self._cmake is not None:
|
|
316
|
+
return self._cmake
|
|
317
|
+
self._cmake = CMake(self)
|
|
318
|
+
self._cmake.configure()
|
|
319
|
+
return self._cmake
|
|
320
|
+
|
|
321
|
+
% if language == "c":
|
|
322
|
+
def _codegen(self):
|
|
323
|
+
args = ["-s", "mds/service.json"]
|
|
324
|
+
gen = GenComp(args)
|
|
325
|
+
gen.run(self._codegen_version)
|
|
326
|
+
|
|
327
|
+
% endif
|
|
328
|
+
def _pre_generate(self):
|
|
329
|
+
tc = CMakeToolchain(self)
|
|
330
|
+
tc.preprocessor_definitions["_FORTIFY_SOURCE"] = "2"
|
|
331
|
+
|
|
332
|
+
tc.variables["BUILD_MANUFACTURE"] = self.options.manufacture
|
|
333
|
+
% if len(pkg.design_options) > 0:
|
|
334
|
+
% for op, _ in pkg.design_options.items():
|
|
335
|
+
tc.variables["CONAN_DEFS_${op.upper()}"] = self.options.${op}
|
|
336
|
+
% endfor
|
|
337
|
+
% endif
|
|
338
|
+
% if language == "lua":
|
|
339
|
+
if self.options.enable_luajit:
|
|
340
|
+
tc.variables["CONAN_DEFS_ENABLE_LUAJIT"] = True
|
|
341
|
+
% endif
|
|
342
|
+
if self.options.test:
|
|
343
|
+
tc.variables["ENABLE_TEST"] = True
|
|
344
|
+
tc.preprocessor_definitions["ENABLE_TEST"] = True
|
|
345
|
+
# 向CMAKE传递版本号信息
|
|
346
|
+
version = self.version.split(".")
|
|
347
|
+
if len(version) >= 1:
|
|
348
|
+
tc.variables["PACKAGE_VERSION_MAJOR"] = version[0]
|
|
349
|
+
if len(version) >= 2:
|
|
350
|
+
tc.variables["PACKAGE_VERSION_MINOR"] = version[1]
|
|
351
|
+
if len(version) >= 3:
|
|
352
|
+
tc.variables["PACKAGE_VERSION_REVISION"] = version[2]
|
|
353
|
+
# 设置额外编译选项或者重定义CFLAGS CXXFLAGS,也可以设置其他开关
|
|
354
|
+
# 示例: os.environ['CFLAGS'] = f"{os.getenv('CFLAGS')} -fPIE"
|
|
355
|
+
|
|
356
|
+
if self.settings.arch in ["armv8", "x86_64"]:
|
|
357
|
+
tc.variables["CMAKE_INSTALL_LIBDIR"] = "usr/lib64"
|
|
358
|
+
else:
|
|
359
|
+
tc.variables["CMAKE_INSTALL_LIBDIR"] = "usr/lib"
|
|
360
|
+
|
|
361
|
+
if self.options.get_safe("asan", False):
|
|
362
|
+
print("Enable asan flags")
|
|
363
|
+
asan_flags = "-fsanitize=address -fsanitize-recover=address,all -fno-omit-frame-pointer -fno-stack-protector -O0"
|
|
364
|
+
tc.extra_cflags.append(asan_flags)
|
|
365
|
+
tc.extra_cxxflags.append(asan_flags)
|
|
366
|
+
tc.extra_sharedlinkflag.append("LDFLAGS", "-fsanitize=address")
|
|
367
|
+
tc.extra_exelinkflag.append("LDFLAGS", "-fsanitize=address")
|
|
368
|
+
|
|
369
|
+
# GCOV 标志设置
|
|
370
|
+
if self.options.get_safe("gcov", False):
|
|
371
|
+
print("Enable gcov flags")
|
|
372
|
+
gcov_flags = "-ftest-coverage -fprofile-arcs -fprofile-update=atomic"
|
|
373
|
+
tc.extra_cflags.append(gcov_flags)
|
|
374
|
+
tc.extra_cxxflags.append(gcov_flags)
|
|
375
|
+
# 配合generate添加宏定义
|
|
376
|
+
tc.variables["CMAKE_TOOLCHAIN_FILE"] = "conan_toolchain.cmake"
|
|
377
|
+
# rpath配置
|
|
378
|
+
tc.variables["CMAKE_SKIP_BUILD_RPATH"] = True
|
|
379
|
+
tc.variables["CMAKE_SKIP_RPATH"] = True
|
|
380
|
+
tc.variables["CMAKE_SKIP_INSTALL_RPATH"] = True
|
|
381
|
+
tc.variables["CMAKE_BUILD_WITH_INSTALL_RPATH"] = False
|
|
382
|
+
tc.variables["CMAKE_INSTALL_RPATH_USE_LINK_PATH"] = False
|
|
383
|
+
return tc
|