lbkit 0.8.6__tar.gz → 0.8.7__tar.gz
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.
- {lbkit-0.8.6/lbkit.egg-info → lbkit-0.8.7}/PKG-INFO +4 -2
- lbkit-0.8.7/lbkit/__init__.py +2 -0
- {lbkit-0.8.6 → lbkit-0.8.7}/lbkit/cli.py +6 -2
- {lbkit-0.8.6 → lbkit-0.8.7}/lbkit/codegen/codegen.py +2 -1
- {lbkit-0.8.6 → lbkit-0.8.7}/lbkit/codegen/ctype_defination.py +14 -14
- {lbkit-0.8.6 → lbkit-0.8.7}/lbkit/codegen/template/public.c.mako +3 -3
- {lbkit-0.8.6 → lbkit-0.8.7}/lbkit/component/build.py +9 -9
- {lbkit-0.8.6 → lbkit-0.8.7}/lbkit/component/test.py +3 -3
- {lbkit-0.8.6 → lbkit-0.8.7}/lbkit/tasks/config.py +0 -3
- {lbkit-0.8.6 → lbkit-0.8.7}/lbkit/tasks/executor.py +18 -5
- lbkit-0.8.7/lbkit/tasks/image_maker/make_image.py +17 -0
- lbkit-0.8.7/lbkit/tasks/image_maker/make_qemu_image.py +75 -0
- lbkit-0.8.7/lbkit/tasks/image_maker/make_rockchip_image.py +78 -0
- {lbkit-0.8.6 → lbkit-0.8.7}/lbkit/tasks/task.py +1 -45
- lbkit-0.8.7/lbkit/tasks/task_build_image.py +29 -0
- {lbkit-0.8.6 → lbkit-0.8.7}/lbkit/tasks/task_build_manifest.py +1 -23
- {lbkit-0.8.6 → lbkit-0.8.7}/lbkit/tasks/task_build_prepare.py +28 -17
- {lbkit-0.8.6 → lbkit-0.8.7}/lbkit/tasks/task_build_rootfs.py +116 -13
- {lbkit-0.8.6 → lbkit-0.8.7}/lbkit/tasks/task_download.py +15 -1
- {lbkit-0.8.6 → lbkit-0.8.7}/lbkit/tools.py +8 -4
- {lbkit-0.8.6 → lbkit-0.8.7}/lbkit/utils/env_detector.py +1 -1
- {lbkit-0.8.6 → lbkit-0.8.7}/lbkit/utils/images/emmc.py +11 -6
- {lbkit-0.8.6 → lbkit-0.8.7/lbkit.egg-info}/PKG-INFO +4 -2
- {lbkit-0.8.6 → lbkit-0.8.7}/lbkit.egg-info/SOURCES.txt +4 -1
- {lbkit-0.8.6 → lbkit-0.8.7}/lbkit.egg-info/requires.txt +1 -0
- {lbkit-0.8.6 → lbkit-0.8.7}/setup.py +1 -1
- lbkit-0.8.7/test/__init__.py +0 -0
- lbkit-0.8.6/lbkit/__init__.py +0 -2
- lbkit-0.8.6/lbkit/tasks/task_build_image.py +0 -45
- lbkit-0.8.6/lbkit/tasks/task_test.py +0 -29
- {lbkit-0.8.6 → lbkit-0.8.7}/AUTHORS +0 -0
- {lbkit-0.8.6 → lbkit-0.8.7}/LICENSE +0 -0
- {lbkit-0.8.6 → lbkit-0.8.7}/MANIFEST.in +0 -0
- {lbkit-0.8.6 → lbkit-0.8.7}/README.md +0 -0
- {lbkit-0.8.6 → lbkit-0.8.7}/lbkit/build_conan_parallel.py +0 -0
- {lbkit-0.8.6 → lbkit-0.8.7}/lbkit/ci_robot/__init__.py +0 -0
- {lbkit-0.8.6 → lbkit-0.8.7}/lbkit/ci_robot/gitee.py +0 -0
- {lbkit-0.8.6 → lbkit-0.8.7}/lbkit/codegen/__init__.py +0 -0
- {lbkit-0.8.6 → lbkit-0.8.7}/lbkit/codegen/idf_interface.py +0 -0
- {lbkit-0.8.6 → lbkit-0.8.7}/lbkit/codegen/renderer.py +0 -0
- {lbkit-0.8.6 → lbkit-0.8.7}/lbkit/codegen/template/client.c.mako +0 -0
- {lbkit-0.8.6 → lbkit-0.8.7}/lbkit/codegen/template/client.h.mako +0 -0
- {lbkit-0.8.6 → lbkit-0.8.7}/lbkit/codegen/template/interface.c.mako +0 -0
- {lbkit-0.8.6 → lbkit-0.8.7}/lbkit/codegen/template/interface.introspect.xml.mako +0 -0
- {lbkit-0.8.6 → lbkit-0.8.7}/lbkit/codegen/template/public.h.mako +0 -0
- {lbkit-0.8.6 → lbkit-0.8.7}/lbkit/codegen/template/server.c.mako +0 -0
- {lbkit-0.8.6 → lbkit-0.8.7}/lbkit/codegen/template/server.h.mako +0 -0
- {lbkit-0.8.6 → lbkit-0.8.7}/lbkit/component/__init__.py +0 -0
- {lbkit-0.8.6 → lbkit-0.8.7}/lbkit/component/arg_parser.py +0 -0
- {lbkit-0.8.6 → lbkit-0.8.7}/lbkit/component/template/conanbase.mako +0 -0
- {lbkit-0.8.6 → lbkit-0.8.7}/lbkit/component/template/deploy.mako +0 -0
- {lbkit-0.8.6 → lbkit-0.8.7}/lbkit/errors.py +0 -0
- {lbkit-0.8.6 → lbkit-0.8.7}/lbkit/helper.py +0 -0
- {lbkit-0.8.6 → lbkit-0.8.7}/lbkit/lbkit.py +0 -0
- {lbkit-0.8.6 → lbkit-0.8.7}/lbkit/log.py +0 -0
- {lbkit-0.8.6 → lbkit-0.8.7}/lbkit/misc.py +0 -0
- {lbkit-0.8.6 → lbkit-0.8.7}/lbkit/tasks/__init__.py +0 -0
- {lbkit-0.8.6/test → lbkit-0.8.7/lbkit/tasks/image_maker}/__init__.py +0 -0
- {lbkit-0.8.6 → lbkit-0.8.7}/lbkit/tasks/template/conanfile.py.mako +0 -0
- {lbkit-0.8.6 → lbkit-0.8.7}/lbkit/tasks/template/rootfs.py.mako +0 -0
- {lbkit-0.8.6 → lbkit-0.8.7}/lbkit/utils/__init__.py +0 -0
- {lbkit-0.8.6 → lbkit-0.8.7}/lbkit/utils/images/__init__.py +0 -0
- {lbkit-0.8.6 → lbkit-0.8.7}/lbkit.egg-info/dependency_links.txt +0 -0
- {lbkit-0.8.6 → lbkit-0.8.7}/lbkit.egg-info/entry_points.txt +0 -0
- {lbkit-0.8.6 → lbkit-0.8.7}/lbkit.egg-info/top_level.txt +0 -0
- {lbkit-0.8.6 → lbkit-0.8.7}/setup.cfg +0 -0
- {lbkit-0.8.6 → lbkit-0.8.7}/test/test_codegen.py +0 -0
- {lbkit-0.8.6 → lbkit-0.8.7}/test/test_config.py +0 -0
- {lbkit-0.8.6 → lbkit-0.8.7}/test/test_helper.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: lbkit
|
|
3
|
-
Version: 0.8.
|
|
3
|
+
Version: 0.8.7
|
|
4
4
|
Summary: Tools provided by litebmc.com
|
|
5
5
|
Home-page: https://www.litebmc.com
|
|
6
6
|
Author: xuhj@litebmc.com
|
|
@@ -21,12 +21,14 @@ Requires-Dist: requests
|
|
|
21
21
|
Requires-Dist: gitpython
|
|
22
22
|
Requires-Dist: inflection
|
|
23
23
|
Requires-Dist: meson>=1.4.0
|
|
24
|
+
Requires-Dist: psutil
|
|
24
25
|
Dynamic: author
|
|
25
26
|
Dynamic: author-email
|
|
26
27
|
Dynamic: classifier
|
|
27
28
|
Dynamic: description
|
|
28
29
|
Dynamic: description-content-type
|
|
29
30
|
Dynamic: home-page
|
|
31
|
+
Dynamic: license-file
|
|
30
32
|
Dynamic: requires-dist
|
|
31
33
|
Dynamic: summary
|
|
32
34
|
|
|
@@ -79,6 +79,8 @@ class Command(object):
|
|
|
79
79
|
"""
|
|
80
80
|
env = EnvDetector()
|
|
81
81
|
if env.component:
|
|
82
|
+
os.chdir(env.component.folder)
|
|
83
|
+
print(os.getcwd())
|
|
82
84
|
arg_parser = ArgParser.new()
|
|
83
85
|
build = BuildComponent(arg_parser, sys.argv[2:])
|
|
84
86
|
build.run()
|
|
@@ -101,6 +103,10 @@ class Command(object):
|
|
|
101
103
|
|
|
102
104
|
组件DT用例执行
|
|
103
105
|
"""
|
|
106
|
+
env = EnvDetector()
|
|
107
|
+
if not env.component:
|
|
108
|
+
raise Exception("The metadata/package.yml file was not detected, not a valid litebmc component.")
|
|
109
|
+
os.chdir(env.component.folder)
|
|
104
110
|
argv = sys.argv[2:]
|
|
105
111
|
build = TestComponent(argv)
|
|
106
112
|
build.run()
|
|
@@ -239,11 +245,9 @@ def main(args):
|
|
|
239
245
|
shutil.rmtree(misc.LOG_DIR, ignore_errors=True)
|
|
240
246
|
os.makedirs(misc.LOG_DIR, exist_ok=True)
|
|
241
247
|
def ctrl_c_handler(_, __):
|
|
242
|
-
print('You pressed Ctrl+C!')
|
|
243
248
|
sys.exit(-3)
|
|
244
249
|
|
|
245
250
|
def sigterm_handler(_, __):
|
|
246
|
-
print('Received SIGTERM!')
|
|
247
251
|
sys.exit(-4)
|
|
248
252
|
|
|
249
253
|
signal.signal(signal.SIGINT, ctrl_c_handler)
|
|
@@ -67,8 +67,9 @@ history_versions = {
|
|
|
67
67
|
"5.0": CodeGenHistory("lb_base/[>=0.8.1 <0.9.0]", "简化接口类名定义;简化枚举变量在接口间传递时的字符串定义", "0"),
|
|
68
68
|
"5.1": CodeGenHistory("lb_base/[>=0.8.3 <0.9.0]", "方法和信号添加保留字段用于功能扩展,同时设置请求和响应为空标志位", "8002"),
|
|
69
69
|
"5.2": CodeGenHistory("lb_base/[>=0.8.4 <0.9.0]", "支持校验数值边界、字符串正则以及数组匹配等规则", "8004"),
|
|
70
|
+
"5.3": CodeGenHistory("lb_base/[>=0.8.5 <0.9.0]", "支持32位操作系统", "8004"),
|
|
70
71
|
}
|
|
71
|
-
__version__=Version("5.
|
|
72
|
+
__version__=Version("5.3")
|
|
72
73
|
|
|
73
74
|
|
|
74
75
|
def version_check(ver_str: str):
|
|
@@ -93,9 +93,9 @@ class IdfValidator():
|
|
|
93
93
|
val_str = f"static const gchar *_items[] = {{"
|
|
94
94
|
val_str += '"' + '", "'.join(self.matches) + '", NULL'
|
|
95
95
|
else:
|
|
96
|
-
if self.ctype in ["int16", "int32", "int64"]:
|
|
96
|
+
if self.ctype in ["int16", "int32", "int64", "ssize"]:
|
|
97
97
|
val_str = f"static gint64 _items[] = {{"
|
|
98
|
-
elif self.ctype in ["uint8", "uint16", "uint32", "uint64"]:
|
|
98
|
+
elif self.ctype in ["uint8", "uint16", "uint32", "uint64", "size"]:
|
|
99
99
|
val_str = f"static guint64 _items[] = {{"
|
|
100
100
|
elif self.ctype in ["double"]:
|
|
101
101
|
val_str = f"static gdouble _items[] = {{"
|
|
@@ -784,17 +784,17 @@ CTYPE_OBJS = {
|
|
|
784
784
|
["gsize <arg_name>"],
|
|
785
785
|
["gsize *<arg_name>"],
|
|
786
786
|
[],
|
|
787
|
-
["<arg_out> =
|
|
788
|
-
["<arg_in> =
|
|
789
|
-
IntegerValidator("
|
|
787
|
+
["<arg_out> = g_variant_new_tsize(<arg_name>)"],
|
|
788
|
+
["<arg_in> = g_variant_get_tsize(<arg_name>)"],
|
|
789
|
+
IntegerValidator("size", 0xffff_ffff_ffff_ffff, 0)
|
|
790
790
|
),
|
|
791
791
|
"ssize": CTypeBase(
|
|
792
792
|
["gssize <arg_name>"],
|
|
793
793
|
["gssize *<arg_name>"],
|
|
794
794
|
[],
|
|
795
|
-
["<arg_out> =
|
|
796
|
-
["<arg_in> =
|
|
797
|
-
IntegerValidator("
|
|
795
|
+
["<arg_out> = g_variant_new_tssize(<arg_name>)"],
|
|
796
|
+
["<arg_in> = g_variant_get_tssize(<arg_name>)"],
|
|
797
|
+
IntegerValidator("ssize", 0x7fff_ffff_ffff_ffff, -(0x8000_0000_0000_0000), True)
|
|
798
798
|
),
|
|
799
799
|
"double": CTypeBase(
|
|
800
800
|
["gdouble <arg_name>"],
|
|
@@ -921,17 +921,17 @@ CTYPE_OBJS = {
|
|
|
921
921
|
["gsize n_<arg_name>" ,"<const>gssize *<arg_name>"],
|
|
922
922
|
["gsize *n_<arg_name>" ,"gssize **<arg_name>"],
|
|
923
923
|
["lb_free_p((void **)&<arg_name>)"],
|
|
924
|
-
["<arg_out> =
|
|
925
|
-
["<arg_in> =
|
|
926
|
-
IntegerArrayValidator("
|
|
924
|
+
["<arg_out> = lb_array_ssize_encode(<arg_name>, n_<arg_name>)"],
|
|
925
|
+
["<arg_in> = lb_array_ssize_decode(<arg_name>, &n_<arg_in>)"],
|
|
926
|
+
IntegerArrayValidator("ssize",0x7fff_ffff_ffff_ffff, -(0x8000_0000_0000_0000), True)
|
|
927
927
|
),
|
|
928
928
|
"array[size]": CTypeBase(
|
|
929
929
|
["gsize n_<arg_name>" ,"<const>gsize *<arg_name>"],
|
|
930
930
|
["gsize *n_<arg_name>" ,"gsize **<arg_name>"],
|
|
931
931
|
["lb_free_p((void **)&<arg_name>)"],
|
|
932
|
-
["<arg_out> =
|
|
933
|
-
["<arg_in> =
|
|
934
|
-
IntegerArrayValidator("
|
|
932
|
+
["<arg_out> = lb_array_size_encode(<arg_name>, n_<arg_name>)"],
|
|
933
|
+
["<arg_in> = lb_array_size_decode(<arg_name>, &n_<arg_in>)"],
|
|
934
|
+
IntegerArrayValidator("size", 0xffff_ffff_ffff_ffff, 0)
|
|
935
935
|
),
|
|
936
936
|
"array[double]": CTypeBase(
|
|
937
937
|
["gsize n_<arg_name>" ,"<const>gdouble *<arg_name>"],
|
|
@@ -526,7 +526,7 @@ static ${name}${dictionary.key} *${name}_lookup(const ${name} *dict, ${key_decla
|
|
|
526
526
|
}
|
|
527
527
|
|
|
528
528
|
const ${name}Real *dict_real = CONTAINER_OF(dict, ${name}Real, dict);
|
|
529
|
-
return (${name}${dictionary.key} *)g_hash_table_lookup(dict_real->_hash, GUINT_TO_POINTER(
|
|
529
|
+
return (${name}${dictionary.key} *)g_hash_table_lookup(dict_real->_hash, GUINT_TO_POINTER(key));
|
|
530
530
|
}
|
|
531
531
|
|
|
532
532
|
/**
|
|
@@ -547,7 +547,7 @@ static gboolean ${name}_insert(const ${name} *dict, ${key_declare}, ${name}${dic
|
|
|
547
547
|
% if dictionary.key_type in ["string", "object_path", "signature"]:
|
|
548
548
|
gboolean ret = g_hash_table_insert(dict_real->_hash, g_strdup(key), *value);
|
|
549
549
|
% else:
|
|
550
|
-
gboolean ret = g_hash_table_insert(dict_real->_hash, GUINT_TO_POINTER(
|
|
550
|
+
gboolean ret = g_hash_table_insert(dict_real->_hash, GUINT_TO_POINTER(key), *value);
|
|
551
551
|
% endif
|
|
552
552
|
if (ret) {
|
|
553
553
|
*value = NULL;
|
|
@@ -571,7 +571,7 @@ static gboolean ${name}_remove(const ${name} *dict, ${key_declare})
|
|
|
571
571
|
}
|
|
572
572
|
|
|
573
573
|
const ${name}Real *dict_real = CONTAINER_OF(dict, ${name}Real, dict);
|
|
574
|
-
return g_hash_table_remove(dict_real->_hash, GUINT_TO_POINTER(
|
|
574
|
+
return g_hash_table_remove(dict_real->_hash, GUINT_TO_POINTER(key));
|
|
575
575
|
}
|
|
576
576
|
|
|
577
577
|
/**
|
|
@@ -20,7 +20,6 @@ from lbkit.codegen.codegen import Version
|
|
|
20
20
|
|
|
21
21
|
tools = Tools("comp_build")
|
|
22
22
|
log = tools.log
|
|
23
|
-
cwd = os.getcwd()
|
|
24
23
|
lb_cwd = os.path.split(os.path.realpath(__file__))[0]
|
|
25
24
|
|
|
26
25
|
|
|
@@ -52,6 +51,7 @@ class DeployComponent():
|
|
|
52
51
|
|
|
53
52
|
class BuildComponent():
|
|
54
53
|
def __init__(self, args_parser: ArgumentParser, args=None):
|
|
54
|
+
self.cwd = os.getcwd()
|
|
55
55
|
self.deploy_success = True
|
|
56
56
|
self.options = args_parser.parse_args(args)
|
|
57
57
|
self.options.build_type = self.options.build_type.capitalize()
|
|
@@ -64,7 +64,7 @@ class BuildComponent():
|
|
|
64
64
|
self.verbose = False if self.options.summary else True
|
|
65
65
|
self.from_source = self.options.from_source
|
|
66
66
|
# 当前组件及其依赖将被部署到rootfs目录
|
|
67
|
-
self.rootfs_dir = os.path.join(cwd, ".temp", "rootfs")
|
|
67
|
+
self.rootfs_dir = os.path.join(self.cwd, ".temp", "rootfs")
|
|
68
68
|
shutil.rmtree(self.rootfs_dir, ignore_errors=True)
|
|
69
69
|
os.makedirs(self.rootfs_dir, exist_ok=True)
|
|
70
70
|
|
|
@@ -117,7 +117,7 @@ class BuildComponent():
|
|
|
117
117
|
return False
|
|
118
118
|
|
|
119
119
|
def gen_conaninfo(self):
|
|
120
|
-
package_yml = os.path.join(cwd, "metadata/package.yml")
|
|
120
|
+
package_yml = os.path.join(self.cwd, "metadata/package.yml")
|
|
121
121
|
if not os.path.isfile(package_yml):
|
|
122
122
|
raise FileNotFoundError("metadata/package.yml文件不存在")
|
|
123
123
|
# 验证失败时抛异常,此处不用处理,由外层处理
|
|
@@ -155,10 +155,10 @@ class BuildComponent():
|
|
|
155
155
|
self.base_cmd += f" -o {conan}/*:{k}={v}"
|
|
156
156
|
|
|
157
157
|
# 生成conan构建脚本
|
|
158
|
-
conanfile = os.path.join(cwd, "conanbase.py")
|
|
158
|
+
conanfile = os.path.join(self.cwd, "conanbase.py")
|
|
159
159
|
# 当git未跟踪conanfile.py时生成新的conanfile.py
|
|
160
160
|
if not self._is_conanfile_tracked:
|
|
161
|
-
conanfile = os.path.join(cwd, "conanfile.py")
|
|
161
|
+
conanfile = os.path.join(self.cwd, "conanfile.py")
|
|
162
162
|
|
|
163
163
|
# 使用litebmc.conanfile.mako模板生成基础litebmc公共conanfile
|
|
164
164
|
lookup = TemplateLookup(directories=os.path.join(lb_cwd, "template"))
|
|
@@ -210,8 +210,8 @@ class BuildComponent():
|
|
|
210
210
|
# import sys
|
|
211
211
|
# sys.exit(-1)
|
|
212
212
|
|
|
213
|
-
lockfile = os.path.join(cwd, ".temp", "conan.lock")
|
|
214
|
-
graphfile = os.path.join(cwd, ".temp", "graph.info")
|
|
213
|
+
lockfile = os.path.join(self.cwd, ".temp", "conan.lock")
|
|
214
|
+
graphfile = os.path.join(self.cwd, ".temp", "graph.info")
|
|
215
215
|
lock_cmd = f"conan lock create . {self.base_cmd} --lockfile-out={lockfile}"
|
|
216
216
|
tools.run(lock_cmd, capture_output=False)
|
|
217
217
|
graph_cmd = f"conan graph info . {self.base_cmd} -f json --lockfile={lockfile}"
|
|
@@ -232,7 +232,7 @@ class BuildComponent():
|
|
|
232
232
|
|
|
233
233
|
# 设置ROOTFS_DIR环境变量,为DT测试提供相对路径
|
|
234
234
|
os.environ["ROOTFS_DIR"] = self.rootfs_dir
|
|
235
|
-
os.chdir(cwd)
|
|
235
|
+
os.chdir(self.cwd)
|
|
236
236
|
|
|
237
237
|
def _validate_odf_object(self, name, obj):
|
|
238
238
|
properties = obj.get("properties")
|
|
@@ -276,7 +276,7 @@ class BuildComponent():
|
|
|
276
276
|
for root, _, files in os.walk(self.rootfs_dir):
|
|
277
277
|
for file in files:
|
|
278
278
|
file = os.path.join(root, file)
|
|
279
|
-
file = os.path.relpath(file, cwd)
|
|
279
|
+
file = os.path.relpath(file, self.cwd)
|
|
280
280
|
if not file.endswith(".yaml"):
|
|
281
281
|
log.debug(f"file {file} not endswith .yaml, skip validate")
|
|
282
282
|
continue
|
|
@@ -12,11 +12,11 @@ from lbkit.misc import Color
|
|
|
12
12
|
|
|
13
13
|
tool = Tools("comp_test")
|
|
14
14
|
log = tool.log
|
|
15
|
-
cwd = os.getcwd()
|
|
16
15
|
|
|
17
16
|
|
|
18
17
|
class TestComponent():
|
|
19
18
|
def __init__(self, args=None):
|
|
19
|
+
self.cwd = os.getcwd()
|
|
20
20
|
self.build_parser = ArgParser.new(True)
|
|
21
21
|
self.build_parser.parse_args(args) # 共享命令参数
|
|
22
22
|
self.origin_args = args
|
|
@@ -95,13 +95,13 @@ class TestComponent():
|
|
|
95
95
|
self._make_ld_library_path(build.rootfs_dir)
|
|
96
96
|
|
|
97
97
|
# 为确保路径正确,切换到初始路径
|
|
98
|
-
os.chdir(cwd)
|
|
98
|
+
os.chdir(self.cwd)
|
|
99
99
|
# 必须存在test.py时才测试
|
|
100
100
|
if not os.path.isfile("test.py"):
|
|
101
101
|
log.warn("Test file(test.py) not exist, skip test")
|
|
102
102
|
return 0
|
|
103
103
|
# 从test.py加载LiteBmcComponentTest实例并运行用命
|
|
104
|
-
loader = importlib.machinery.SourceFileLoader("test", os.path.join(cwd, "test.py"))
|
|
104
|
+
loader = importlib.machinery.SourceFileLoader("test", os.path.join(self.cwd, "test.py"))
|
|
105
105
|
mod = loader.load_module()
|
|
106
106
|
klass = getattr(mod, "LiteBmcComponentTest")
|
|
107
107
|
if klass is None:
|
|
@@ -55,9 +55,6 @@ class Config(object):
|
|
|
55
55
|
self.mnt_path = os.path.join(self.temp_path, "mnt_path")
|
|
56
56
|
self.rootfs_img = os.path.join(self.output_path, "rootfs.img")
|
|
57
57
|
# rootfs、uboot和kernel关键文件路径
|
|
58
|
-
self.uboot_bin = None
|
|
59
|
-
self.linux_bin = None
|
|
60
|
-
self.rootfs_tar = None
|
|
61
58
|
os.makedirs(self.temp_path, exist_ok=True)
|
|
62
59
|
os.makedirs(self.tool_path, exist_ok=True)
|
|
63
60
|
os.makedirs(self.output_path, exist_ok=True)
|
|
@@ -5,6 +5,7 @@ import os
|
|
|
5
5
|
import time
|
|
6
6
|
import traceback
|
|
7
7
|
import sys
|
|
8
|
+
import psutil
|
|
8
9
|
|
|
9
10
|
from multiprocessing import Process
|
|
10
11
|
from multiprocessing import Manager
|
|
@@ -139,7 +140,7 @@ def task_handler(te:TaskExecutor):
|
|
|
139
140
|
try:
|
|
140
141
|
ret = te.run()
|
|
141
142
|
except Exception as e:
|
|
142
|
-
|
|
143
|
+
traceback.print_exc()
|
|
143
144
|
log.error(f"Task {te.status_key} exit with exceiption: {str(e)}")
|
|
144
145
|
with status_lock:
|
|
145
146
|
status_dict[te.status_key] = TASK_STATUS_EXCEPT
|
|
@@ -160,6 +161,19 @@ class TaskInfo():
|
|
|
160
161
|
self.proc = proc
|
|
161
162
|
|
|
162
163
|
|
|
164
|
+
def kill_process_and_children(pid):
|
|
165
|
+
try:
|
|
166
|
+
parent = psutil.Process(pid)
|
|
167
|
+
except psutil.NoSuchProcess:
|
|
168
|
+
return
|
|
169
|
+
|
|
170
|
+
children = parent.children(recursive=True)
|
|
171
|
+
for child in children:
|
|
172
|
+
child.terminate()
|
|
173
|
+
|
|
174
|
+
parent.terminate()
|
|
175
|
+
|
|
176
|
+
|
|
163
177
|
def wait_tasks(tasks: dict[str, TaskInfo], alow_processes_alive=0):
|
|
164
178
|
while True:
|
|
165
179
|
new_results = {}
|
|
@@ -172,13 +186,12 @@ def wait_tasks(tasks: dict[str, TaskInfo], alow_processes_alive=0):
|
|
|
172
186
|
continue
|
|
173
187
|
with status_lock:
|
|
174
188
|
status = status_dict.get(ti.te.status_key)
|
|
175
|
-
if status == TASK_STATUS_EXCEPT:
|
|
189
|
+
if status == TASK_STATUS_EXCEPT or status == TASK_STATUS_FAILED:
|
|
176
190
|
killall = True
|
|
177
191
|
break
|
|
178
192
|
if killall:
|
|
179
193
|
for _, ti in tasks.items():
|
|
180
|
-
|
|
181
|
-
ti.proc.terminate()
|
|
194
|
+
kill_process_and_children(ti.proc.pid)
|
|
182
195
|
return None, False
|
|
183
196
|
tasks = new_results
|
|
184
197
|
if cnt > 0 and cnt >= alow_processes_alive:
|
|
@@ -244,7 +257,7 @@ class Executor(object):
|
|
|
244
257
|
target = config.target
|
|
245
258
|
succ = target_executor(config)
|
|
246
259
|
except Exception as e:
|
|
247
|
-
|
|
260
|
+
traceback.print_exc()
|
|
248
261
|
raise Exception(f"任务 {target} 执行失败")
|
|
249
262
|
if succ:
|
|
250
263
|
log.success(f"任务 {target} 执行成功")
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"""环境准备"""
|
|
2
|
+
import os
|
|
3
|
+
from lbkit.tasks.config import Config
|
|
4
|
+
from lbkit.tasks.task import Task
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class TaskMakeImage(Task):
|
|
8
|
+
def available(self):
|
|
9
|
+
return False
|
|
10
|
+
|
|
11
|
+
def run(self):
|
|
12
|
+
return
|
|
13
|
+
|
|
14
|
+
if __name__ == "__main__":
|
|
15
|
+
config = Config()
|
|
16
|
+
build = TaskMakeImage(config, "test")
|
|
17
|
+
build.run()
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"""环境准备"""
|
|
2
|
+
import os
|
|
3
|
+
import tempfile
|
|
4
|
+
from lbkit.tasks.config import Config
|
|
5
|
+
from lbkit.log import Logger
|
|
6
|
+
from lbkit.utils.images.emmc import MakeImage as MekeEmmcImage
|
|
7
|
+
from lbkit.tasks.image_maker.make_image import TaskMakeImage
|
|
8
|
+
|
|
9
|
+
log = Logger("build_image")
|
|
10
|
+
|
|
11
|
+
src_cwd = os.path.split(os.path.realpath(__file__))[0]
|
|
12
|
+
|
|
13
|
+
class TaskMakeQemuImage(TaskMakeImage):
|
|
14
|
+
def __init__(self, config, name):
|
|
15
|
+
super().__init__(config, name)
|
|
16
|
+
self.chip_model = None
|
|
17
|
+
chip_model = self.config.get_product_config("chip_model")
|
|
18
|
+
if chip_model not in ["qemu_arm64"]:
|
|
19
|
+
return
|
|
20
|
+
self.chip_model = chip_model
|
|
21
|
+
self.uboot = self.config.get_product_config("flash/uboot")
|
|
22
|
+
self.kernel = self.config.get_product_config("flash/kernel")
|
|
23
|
+
self.rootfs = self.config.rootfs_img
|
|
24
|
+
|
|
25
|
+
@staticmethod
|
|
26
|
+
def _trans_to_blk_1m(cfg: str):
|
|
27
|
+
if cfg.endswith("K"):
|
|
28
|
+
return int(cfg[:-1]) / 1024
|
|
29
|
+
elif cfg.endswith("M"):
|
|
30
|
+
return int(cfg[:-1])
|
|
31
|
+
elif cfg.endswith("G"):
|
|
32
|
+
return int(cfg[:-1]) * 1024
|
|
33
|
+
|
|
34
|
+
def available(self):
|
|
35
|
+
if not self.chip_model:
|
|
36
|
+
return False
|
|
37
|
+
if self.config.get_product_config("flash/type") != "emmc":
|
|
38
|
+
return False
|
|
39
|
+
return True
|
|
40
|
+
|
|
41
|
+
def run(self):
|
|
42
|
+
"""任务入口"""
|
|
43
|
+
"""检查manifest文件是否满足schema格式描述"""
|
|
44
|
+
os.chdir(self.config.output_path)
|
|
45
|
+
|
|
46
|
+
mk = MekeEmmcImage(os.path.join(self.config.temp_path, "emmc_tmp_dir"))
|
|
47
|
+
rootfs_size = self.config.get_product_config("rootfs/size")
|
|
48
|
+
if rootfs_size:
|
|
49
|
+
mk.rootfs_blk_1m = self._trans_to_blk_1m(rootfs_size)
|
|
50
|
+
emmc_size = self.config.get_product_config("flash/size")
|
|
51
|
+
if emmc_size:
|
|
52
|
+
mk.size_1m = self._trans_to_blk_1m(emmc_size)
|
|
53
|
+
tmpdir = tempfile.TemporaryDirectory()
|
|
54
|
+
cmd = f"fuse2fs {self.rootfs} {tmpdir.name} -o fakeroot"
|
|
55
|
+
self.exec(cmd)
|
|
56
|
+
# 复制内核文件到boot/extlinux/Image
|
|
57
|
+
cmd = f"cp {self.kernel} {tmpdir.name}/boot/Image"
|
|
58
|
+
self.exec(cmd)
|
|
59
|
+
cmd = f"umount {tmpdir.name}"
|
|
60
|
+
self.exec(cmd)
|
|
61
|
+
mk.run(self.config.rootfs_img, "qemu.img")
|
|
62
|
+
cmd = 'cp /usr/share/litebmc/qemu.conf qemu.conf'
|
|
63
|
+
self.exec(cmd)
|
|
64
|
+
cmd = f'cp {self.uboot} u-boot.bin'
|
|
65
|
+
self.exec(cmd)
|
|
66
|
+
output_img = os.path.join(self.config.output_path, "litebmc_qemu.tar.gz")
|
|
67
|
+
cmd = f'tar -czf {output_img} -C . qemu.img u-boot.bin qemu.conf'
|
|
68
|
+
self.exec(cmd)
|
|
69
|
+
log.success(f"Create litebmc image {output_img} successfully")
|
|
70
|
+
return 0
|
|
71
|
+
|
|
72
|
+
if __name__ == "__main__":
|
|
73
|
+
config = Config()
|
|
74
|
+
build = TaskMakeQemuImage(config, "test")
|
|
75
|
+
build.run()
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
"""环境准备"""
|
|
2
|
+
import os
|
|
3
|
+
import shutil
|
|
4
|
+
from lbkit.tasks.config import Config
|
|
5
|
+
from lbkit.tasks.task import Task
|
|
6
|
+
from lbkit.log import Logger
|
|
7
|
+
|
|
8
|
+
log = Logger("build_image")
|
|
9
|
+
|
|
10
|
+
src_cwd = os.path.split(os.path.realpath(__file__))[0]
|
|
11
|
+
|
|
12
|
+
class TaskMakeRockchipImage(Task):
|
|
13
|
+
def __init__(self, config, name):
|
|
14
|
+
super().__init__(config, name)
|
|
15
|
+
self.chip_model = None
|
|
16
|
+
chip_model = self.config.get_product_config("chip_model")
|
|
17
|
+
if chip_model not in ["rk3506"]:
|
|
18
|
+
return
|
|
19
|
+
self.chip_model = chip_model
|
|
20
|
+
self.uboot = self.config.get_product_config("flash/uboot")
|
|
21
|
+
self.kernel = self.config.get_product_config("flash/kernel")
|
|
22
|
+
self.loader = self.config.get_product_config("flash/loader")
|
|
23
|
+
self.parameter = self.config.get_product_config("flash/parameter")
|
|
24
|
+
self.package_file = self.config.get_product_config("flash/package-file")
|
|
25
|
+
self.rootfs = self.config.rootfs_img
|
|
26
|
+
|
|
27
|
+
def available(self):
|
|
28
|
+
if not self.chip_model:
|
|
29
|
+
return False
|
|
30
|
+
if self.config.get_product_config("flash/type") != "spi_nand":
|
|
31
|
+
return False
|
|
32
|
+
return True
|
|
33
|
+
|
|
34
|
+
def run(self):
|
|
35
|
+
"""任务入口"""
|
|
36
|
+
if not self.available():
|
|
37
|
+
return -1
|
|
38
|
+
cwd = os.getcwd()
|
|
39
|
+
tmpdir = os.path.join(self.config.output_path, "temp_files")
|
|
40
|
+
if os.path.isdir(tmpdir):
|
|
41
|
+
shutil.rmtree(tmpdir)
|
|
42
|
+
os.makedirs(tmpdir)
|
|
43
|
+
os.chdir(tmpdir)
|
|
44
|
+
self.copyfile(self.uboot, os.path.basename(self.uboot))
|
|
45
|
+
self.copyfile(self.kernel, os.path.basename(self.kernel))
|
|
46
|
+
self.copyfile(self.loader, os.path.basename(self.loader))
|
|
47
|
+
self.copyfile(self.parameter, "parameter.txt")
|
|
48
|
+
self.copyfile(self.package_file, "package-file")
|
|
49
|
+
self.copyfile(self.rootfs, os.path.basename(self.rootfs))
|
|
50
|
+
with open(self.package_file) as fp:
|
|
51
|
+
lines = fp.readlines()
|
|
52
|
+
for line in lines:
|
|
53
|
+
line = line.strip()
|
|
54
|
+
if line.startswith("#"):
|
|
55
|
+
continue
|
|
56
|
+
infos = line.split("\t")
|
|
57
|
+
if len(infos) != 2:
|
|
58
|
+
raise Exception("the package-file with format error, each line of text must be in the format of `name\tfile\n`")
|
|
59
|
+
filename = infos[1]
|
|
60
|
+
if not os.path.isfile(filename):
|
|
61
|
+
cmd = f"dd if=/dev/zero of={filename} bs=1K count=1"
|
|
62
|
+
self.exec(cmd)
|
|
63
|
+
cmd = "rk_afptool -pack . firmware.img.raw"
|
|
64
|
+
self.exec(cmd, verbose=True)
|
|
65
|
+
cmds = [f"hexdump -s 21 -n 4 -e '4 \"%c\"' {self.loader}", "rev"]
|
|
66
|
+
tag = "RK" + self.pipe(cmds).decode("utf-8")
|
|
67
|
+
cmd = f"rk_image_maker -{tag} {self.loader} firmware.img.raw firmware.img -os_type:androidos"
|
|
68
|
+
self.exec(cmd, verbose=True)
|
|
69
|
+
cmd = f"mv firmware.img " + os.path.join(self.config.output_path, "firmware.img")
|
|
70
|
+
self.exec(cmd)
|
|
71
|
+
os.chdir(cwd)
|
|
72
|
+
return 0
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
if __name__ == "__main__":
|
|
76
|
+
config = Config()
|
|
77
|
+
build = TaskMakeRockchipImage(config, "test")
|
|
78
|
+
build.run()
|
|
@@ -7,7 +7,6 @@ import shutil
|
|
|
7
7
|
from multiprocessing import Process
|
|
8
8
|
from lbkit.log import Logger
|
|
9
9
|
from lbkit.tools import Tools
|
|
10
|
-
from lbkit.misc import load_yml_with_json_schema_validate, DownloadFlag
|
|
11
10
|
|
|
12
11
|
from lbkit.tasks.config import Config
|
|
13
12
|
|
|
@@ -33,7 +32,7 @@ class Task(Process):
|
|
|
33
32
|
|
|
34
33
|
def pipe(self, cmds: list[str], ignore_error=False, out_file = None, **kwargs):
|
|
35
34
|
kwargs["uptrace"] = kwargs.get("uptrace", 0) + 1
|
|
36
|
-
self.tools.pipe(cmds, ignore_error, out_file, **kwargs)
|
|
35
|
+
return self.tools.pipe(cmds, ignore_error, out_file, **kwargs)
|
|
37
36
|
|
|
38
37
|
def exec_easy(self, cmd, ignore_error=False, **kwargs):
|
|
39
38
|
kwargs["uptrace"] = kwargs.get("uptrace", 0) + 1
|
|
@@ -57,50 +56,7 @@ class Task(Process):
|
|
|
57
56
|
"""加载manifest.yml并验证schema文件"""
|
|
58
57
|
return self.config.load_manifest()
|
|
59
58
|
|
|
60
|
-
def waitfile(self, src, timeout=1):
|
|
61
|
-
src = os.path.realpath(src)
|
|
62
|
-
if os.path.islink(src):
|
|
63
|
-
raise FileNotFoundError(f"Source file {src} is a symlink, copying failed")
|
|
64
|
-
if not os.path.isfile(src):
|
|
65
|
-
if timeout:
|
|
66
|
-
# 如果有timeout的,可能是正在下载的文件,需要等待超时时间再检查一次
|
|
67
|
-
time.sleep(timeout)
|
|
68
|
-
if not os.path.isfile(src):
|
|
69
|
-
raise FileNotFoundError(f"Source file {src} does not exist, copying failed")
|
|
70
|
-
else:
|
|
71
|
-
raise FileNotFoundError(f"Source file {src} does not exist, copying failed")
|
|
72
|
-
|
|
73
|
-
# 检查是否由download下载器下载,如果是,需要检查是否下载完成
|
|
74
|
-
if src.startswith(self.config.download_path):
|
|
75
|
-
timeout_cnt = 0
|
|
76
|
-
timeout_sec = 0
|
|
77
|
-
while True:
|
|
78
|
-
_, hash = DownloadFlag.read(src)
|
|
79
|
-
if hash:
|
|
80
|
-
filehash = self.tools.file_digest_sha256(src)
|
|
81
|
-
if hash != filehash:
|
|
82
|
-
DownloadFlag.clean(src)
|
|
83
|
-
raise Exception(f"The hash of file {src} is {filehash}, not equal to {hash}")
|
|
84
|
-
break
|
|
85
|
-
else:
|
|
86
|
-
time.sleep(0.1)
|
|
87
|
-
timeout_sec += 0.1
|
|
88
|
-
timeout_cnt += 0.1
|
|
89
|
-
# 每10秒打印一次等等日志
|
|
90
|
-
if timeout_sec == 10:
|
|
91
|
-
self.log.info(f"Wait file {src} download success")
|
|
92
|
-
timeout_sec = 0
|
|
93
|
-
# 60秒未创建文件的,判定文件不存在,中止构建
|
|
94
|
-
if timeout_cnt == 60 and not os.path.isfile(src):
|
|
95
|
-
raise Exception(f"Check file {src} failed because source file does not exist")
|
|
96
|
-
if timeout_cnt == 300:
|
|
97
|
-
raise Exception(f"Check file {src} failed because file was not downloaded within 300 seconds")
|
|
98
|
-
|
|
99
59
|
def copyfile(self, src, dst):
|
|
100
|
-
try:
|
|
101
|
-
self.waitfile(src)
|
|
102
|
-
except Exception as e:
|
|
103
|
-
raise Exception(f"Copy file {src} to {dst} failed because source file not ready") from e
|
|
104
60
|
|
|
105
61
|
dst = os.path.realpath(dst)
|
|
106
62
|
if not dst.startswith(self.config.temp_path):
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"""环境准备"""
|
|
2
|
+
import os
|
|
3
|
+
from lbkit.tasks.config import Config
|
|
4
|
+
from lbkit.tasks.task import Task
|
|
5
|
+
from lbkit.log import Logger
|
|
6
|
+
from lbkit.tasks.image_maker.make_rockchip_image import TaskMakeRockchipImage
|
|
7
|
+
from lbkit.tasks.image_maker.make_qemu_image import TaskMakeQemuImage
|
|
8
|
+
|
|
9
|
+
log = Logger("build_image")
|
|
10
|
+
|
|
11
|
+
src_cwd = os.path.split(os.path.realpath(__file__))[0]
|
|
12
|
+
|
|
13
|
+
class TaskClass(Task):
|
|
14
|
+
def run(self):
|
|
15
|
+
"""任务入口"""
|
|
16
|
+
maker = TaskMakeRockchipImage(self.config, self.name)
|
|
17
|
+
if maker.available():
|
|
18
|
+
maker.run()
|
|
19
|
+
return 0
|
|
20
|
+
maker = TaskMakeQemuImage(self.config, self.name)
|
|
21
|
+
if maker.available():
|
|
22
|
+
maker.run()
|
|
23
|
+
return 0
|
|
24
|
+
return -1
|
|
25
|
+
|
|
26
|
+
if __name__ == "__main__":
|
|
27
|
+
config = Config()
|
|
28
|
+
build = TaskClass(config, "test")
|
|
29
|
+
build.run()
|
|
@@ -53,17 +53,6 @@ class TaskClass(Task):
|
|
|
53
53
|
continue
|
|
54
54
|
cmd = f"conan cache path {ref}:{id}"
|
|
55
55
|
package_folder = self.tools.run(cmd).stdout.strip()
|
|
56
|
-
rootfs_tar = os.path.join(package_folder, "rootfs.tar")
|
|
57
|
-
uboot_bin = os.path.join(package_folder, "u-boot.bin")
|
|
58
|
-
linux_bin = os.path.join(package_folder, "boot/Image")
|
|
59
|
-
if os.path.isfile(rootfs_tar):
|
|
60
|
-
self.config.rootfs_tar = rootfs_tar
|
|
61
|
-
continue
|
|
62
|
-
elif os.path.isfile(uboot_bin):
|
|
63
|
-
self.config.uboot_bin = uboot_bin
|
|
64
|
-
continue
|
|
65
|
-
elif os.path.isfile(linux_bin):
|
|
66
|
-
self.config.linux_bin = linux_bin
|
|
67
56
|
self.config.conan_install.append(package_folder)
|
|
68
57
|
|
|
69
58
|
def download_recipe(self, pkg):
|
|
@@ -144,18 +133,7 @@ class TaskClass(Task):
|
|
|
144
133
|
"""任务入口"""
|
|
145
134
|
self.build_rootfs()
|
|
146
135
|
self.build_litebmc()
|
|
147
|
-
|
|
148
|
-
if not self.config.rootfs_tar:
|
|
149
|
-
error = True
|
|
150
|
-
self.log.error("rootfs.tar not found in any conan package")
|
|
151
|
-
if not self.config.uboot_bin:
|
|
152
|
-
error = True
|
|
153
|
-
self.log.error("u-boot.bin not found in any conan package")
|
|
154
|
-
if not self.config.linux_bin:
|
|
155
|
-
error = True
|
|
156
|
-
self.log.error("boot/Image not found in any conan package")
|
|
157
|
-
if error:
|
|
158
|
-
raise FileNotFoundError("Build failed because important files are missing")
|
|
136
|
+
return 0
|
|
159
137
|
|
|
160
138
|
if __name__ == "__main__":
|
|
161
139
|
config = Config()
|