lbkit 0.6.5__tar.gz → 0.6.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.
Files changed (59) hide show
  1. {lbkit-0.6.5/lbkit.egg-info → lbkit-0.6.7}/PKG-INFO +10 -2
  2. lbkit-0.6.7/lbkit/__init__.py +2 -0
  3. {lbkit-0.6.5 → lbkit-0.6.7}/lbkit/codegen/idf_interface.py +76 -6
  4. {lbkit-0.6.5 → lbkit-0.6.7}/lbkit/codegen/template/public.c.mako +58 -0
  5. {lbkit-0.6.5 → lbkit-0.6.7}/lbkit/codegen/template/public.h.mako +41 -14
  6. {lbkit-0.6.5 → lbkit-0.6.7}/lbkit/component/template/conanbase.mako +13 -2
  7. {lbkit-0.6.5 → lbkit-0.6.7}/lbkit/integration/build_image.py +1 -3
  8. {lbkit-0.6.5 → lbkit-0.6.7}/lbkit/integration/build_manifest.py +31 -16
  9. {lbkit-0.6.5 → lbkit-0.6.7}/lbkit/integration/build_rootfs.py +6 -0
  10. {lbkit-0.6.5 → lbkit-0.6.7}/lbkit/integration/config.py +0 -3
  11. {lbkit-0.6.5 → lbkit-0.6.7}/lbkit/integration/template/conanfile.py.mako +1 -1
  12. lbkit-0.6.7/lbkit/integration/template/rootfs.py.mako +27 -0
  13. {lbkit-0.6.5 → lbkit-0.6.7}/lbkit/tools.py +9 -1
  14. {lbkit-0.6.5 → lbkit-0.6.7}/lbkit/utils/images/emmc.py +2 -22
  15. {lbkit-0.6.5 → lbkit-0.6.7/lbkit.egg-info}/PKG-INFO +10 -2
  16. {lbkit-0.6.5 → lbkit-0.6.7}/lbkit.egg-info/SOURCES.txt +1 -0
  17. lbkit-0.6.5/lbkit/__init__.py +0 -2
  18. {lbkit-0.6.5 → lbkit-0.6.7}/AUTHORS +0 -0
  19. {lbkit-0.6.5 → lbkit-0.6.7}/LICENSE +0 -0
  20. {lbkit-0.6.5 → lbkit-0.6.7}/MANIFEST.in +0 -0
  21. {lbkit-0.6.5 → lbkit-0.6.7}/README.md +0 -0
  22. {lbkit-0.6.5 → lbkit-0.6.7}/lbkit/build_conan_parallel.py +0 -0
  23. {lbkit-0.6.5 → lbkit-0.6.7}/lbkit/ci_robot/__init__.py +0 -0
  24. {lbkit-0.6.5 → lbkit-0.6.7}/lbkit/ci_robot/gitee.py +0 -0
  25. {lbkit-0.6.5 → lbkit-0.6.7}/lbkit/cli.py +0 -0
  26. {lbkit-0.6.5 → lbkit-0.6.7}/lbkit/codegen/__init__.py +0 -0
  27. {lbkit-0.6.5 → lbkit-0.6.7}/lbkit/codegen/codegen.py +0 -0
  28. {lbkit-0.6.5 → lbkit-0.6.7}/lbkit/codegen/ctype_defination.py +0 -0
  29. {lbkit-0.6.5 → lbkit-0.6.7}/lbkit/codegen/renderer.py +0 -0
  30. {lbkit-0.6.5 → lbkit-0.6.7}/lbkit/codegen/template/client.c.mako +0 -0
  31. {lbkit-0.6.5 → lbkit-0.6.7}/lbkit/codegen/template/client.h.mako +0 -0
  32. {lbkit-0.6.5 → lbkit-0.6.7}/lbkit/codegen/template/interface.c.mako +0 -0
  33. {lbkit-0.6.5 → lbkit-0.6.7}/lbkit/codegen/template/interface.introspect.xml.mako +0 -0
  34. {lbkit-0.6.5 → lbkit-0.6.7}/lbkit/codegen/template/server.c.mako +0 -0
  35. {lbkit-0.6.5 → lbkit-0.6.7}/lbkit/codegen/template/server.h.mako +0 -0
  36. {lbkit-0.6.5 → lbkit-0.6.7}/lbkit/component/__init__.py +0 -0
  37. {lbkit-0.6.5 → lbkit-0.6.7}/lbkit/component/arg_parser.py +0 -0
  38. {lbkit-0.6.5 → lbkit-0.6.7}/lbkit/component/build.py +0 -0
  39. {lbkit-0.6.5 → lbkit-0.6.7}/lbkit/component/template/deploy.mako +0 -0
  40. {lbkit-0.6.5 → lbkit-0.6.7}/lbkit/component/test.py +0 -0
  41. {lbkit-0.6.5 → lbkit-0.6.7}/lbkit/errors.py +0 -0
  42. {lbkit-0.6.5 → lbkit-0.6.7}/lbkit/helper.py +0 -0
  43. {lbkit-0.6.5 → lbkit-0.6.7}/lbkit/integration/__init__.py +0 -0
  44. {lbkit-0.6.5 → lbkit-0.6.7}/lbkit/integration/build_prepare.py +0 -0
  45. {lbkit-0.6.5 → lbkit-0.6.7}/lbkit/integration/task.py +0 -0
  46. {lbkit-0.6.5 → lbkit-0.6.7}/lbkit/lbkit.py +0 -0
  47. {lbkit-0.6.5 → lbkit-0.6.7}/lbkit/log.py +0 -0
  48. {lbkit-0.6.5 → lbkit-0.6.7}/lbkit/misc.py +0 -0
  49. {lbkit-0.6.5 → lbkit-0.6.7}/lbkit/utils/__init__.py +0 -0
  50. {lbkit-0.6.5 → lbkit-0.6.7}/lbkit/utils/images/__init__.py +0 -0
  51. {lbkit-0.6.5 → lbkit-0.6.7}/lbkit.egg-info/dependency_links.txt +0 -0
  52. {lbkit-0.6.5 → lbkit-0.6.7}/lbkit.egg-info/entry_points.txt +0 -0
  53. {lbkit-0.6.5 → lbkit-0.6.7}/lbkit.egg-info/requires.txt +0 -0
  54. {lbkit-0.6.5 → lbkit-0.6.7}/lbkit.egg-info/top_level.txt +0 -0
  55. {lbkit-0.6.5 → lbkit-0.6.7}/setup.cfg +0 -0
  56. {lbkit-0.6.5 → lbkit-0.6.7}/setup.py +0 -0
  57. {lbkit-0.6.5 → lbkit-0.6.7}/test/__init__.py +0 -0
  58. {lbkit-0.6.5 → lbkit-0.6.7}/test/test_codegen.py +0 -0
  59. {lbkit-0.6.5 → lbkit-0.6.7}/test/test_helper.py +0 -0
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.2
2
2
  Name: lbkit
3
- Version: 0.6.5
3
+ Version: 0.6.7
4
4
  Summary: Tools provided by litebmc.com
5
5
  Home-page: https://www.litebmc.com
6
6
  Author: xuhj@litebmc.com
@@ -21,5 +21,13 @@ Requires-Dist: requests
21
21
  Requires-Dist: gitpython
22
22
  Requires-Dist: inflection
23
23
  Requires-Dist: meson>=1.4.0
24
+ Dynamic: author
25
+ Dynamic: author-email
26
+ Dynamic: classifier
27
+ Dynamic: description
28
+ Dynamic: description-content-type
29
+ Dynamic: home-page
30
+ Dynamic: requires-dist
31
+ Dynamic: summary
24
32
 
25
33
  build and code generate tools
@@ -0,0 +1,2 @@
1
+
2
+ __version__ = '0.6.7'
@@ -7,7 +7,7 @@ from lbkit.log import Logger
7
7
  from lbkit.codegen.renderer import Renderer
8
8
  from lbkit.codegen.ctype_defination import CTYPE_OBJS, RefObjArrayValidator, RefObjValidator
9
9
  from lbkit.misc import load_yml_with_json_schema_validate
10
- from lbkit.errors import OdfValidateException
10
+ from lbkit.errors import OdfValidateException, LiteBmcException
11
11
  from lbkit.helper import SigInvalidException, validate_glib_signature
12
12
 
13
13
  log = Logger("gen_interface")
@@ -16,7 +16,9 @@ class IDFException(Exception):
16
16
  pass
17
17
 
18
18
  class IdfInterfacePlugin(Renderer):
19
- actions = []
19
+ def __init__(self):
20
+ super().__init__()
21
+ self.actions = []
20
22
 
21
23
  class IdfInterfaceBase(Renderer):
22
24
  def __init__(self) -> None:
@@ -65,6 +67,24 @@ ACCESS_FLAG_MAP = {
65
67
  "readwrite": "G_DBUS_PROPERTY_INFO_FLAGS_WRITABLE | G_DBUS_PROPERTY_INFO_FLAGS_READABLE"
66
68
  }
67
69
 
70
+ # 简单类型的格式化符号
71
+ PRINT_FORMATTER_MAP = {
72
+ "byte": "%u",
73
+ "uint16": "G_GUINT16_FORMAT",
74
+ "uint32": "G_GUINT32_FORMAT",
75
+ "uint64": "G_GUINT64_FORMAT",
76
+ "int16": "G_GINT16_FORMAT",
77
+ "int32": "G_GINT32_FORMAT",
78
+ "int64": "G_GINT64_FORMAT",
79
+ "size": "G_GSIZE_FORMAT",
80
+ "ssize": "G_GSSIZE_FORMAT",
81
+ "double": "%d",
82
+ "boolean": "%i",
83
+ "string": "%s",
84
+ "object_path": "%s",
85
+ "signature": "%s"
86
+ }
87
+
68
88
  # ^(byte|uint16|uint32|uint64|int16|int32|int64|double|boolean|string|object_path|signature|unixfd|(array\\[(byte|uint16|uint32|uint64|int16|int32|int64|double|boolean|string|object_path|signature|unixfd)\\])|((struct|enum|dict)\\[[a-zA-Z][A-Za-z0-9.]*\\])|(array\\[(struct|enum|dict)\\[[a-zA-Z][A-Za-z0-9.]*\\]\\]))$"
69
89
 
70
90
  METHOD_NAME_REGEX = "[A-Z][a-zA-Z0-9_]*"
@@ -816,11 +836,12 @@ class IdfBase():
816
836
 
817
837
 
818
838
  class IdfMethod(IdfBase):
819
- is_plugin = False
820
839
  def __init__(self, intf: IdfInterfaceBase, method_data):
840
+ self.is_plugin = False
821
841
  super().__init__(intf, method_data)
822
842
  self.parameters: IdfParameters = IdfParameters(intf, method_data.get("parameters", []))
823
843
  self.returns: IdfParameters = IdfParameters(intf, method_data.get("returns", []))
844
+ self.errors: list[str] = method_data.get("errors", [])
824
845
 
825
846
  @property
826
847
  def in_signature(self):
@@ -835,8 +856,17 @@ class IdfMethod(IdfBase):
835
856
  deps = []
836
857
  deps.extend(self.parameters.dependency_interface)
837
858
  deps.extend(self.returns.dependency_interface)
859
+ deps.extend(self.errors_dependency())
838
860
  return list(set(deps))
839
861
 
862
+ def errors_dependency(self):
863
+ deps = []
864
+ for error in self.errors:
865
+ pos = error.rfind(".Error.")
866
+ if pos > 0:
867
+ deps.append(error[0:pos])
868
+ return deps
869
+
840
870
  class IdfSignal(IdfBase):
841
871
  def __init__(self, intf: IdfInterfaceBase, signal_data):
842
872
  super().__init__(intf, signal_data)
@@ -881,9 +911,8 @@ class IdfStructure(IdfBase):
881
911
 
882
912
 
883
913
  class IdfPluginAction(IdfMethod):
884
- is_plugin = True
885
-
886
914
  def __init__(self, intf: IdfInterfaceBase, method_data):
915
+ self.is_plugin = True
887
916
  self.policy = method_data.get("policy", "continue_always")
888
917
  super().__init__(intf, method_data)
889
918
 
@@ -1012,10 +1041,11 @@ class IdfInterface(IdfInterfaceBase):
1012
1041
  self.methods: list[IdfMethod] = []
1013
1042
  self.signals: list[IdfSignal] = []
1014
1043
  self.structures: dict[str, IdfStructure] = {}
1044
+ self.errors: dict[str, IdfStructure] = {}
1015
1045
  self.dictionaries: dict[str, IdfDictionary] = {}
1016
1046
  self.enumerations: dict[str, IdfEnumeration] = {}
1017
1047
  self.annotations: list[IdfAnnotation] = []
1018
- self.plugin: IdfInterfacePlugin = IdfInterfacePlugin()
1048
+ self.plugin: IdfInterfacePlugin = None
1019
1049
  self.description = None
1020
1050
  self.version = None
1021
1051
  self.alias = None
@@ -1064,6 +1094,8 @@ class IdfInterface(IdfInterfaceBase):
1064
1094
  deps.extend(signal.dependency_interface)
1065
1095
  for method in self.methods:
1066
1096
  deps.extend(method.dependency_interface)
1097
+ for _, error in self.errors.items():
1098
+ deps.extend(error.dependency_interface)
1067
1099
  return list(set(deps))
1068
1100
 
1069
1101
  @property
@@ -1159,12 +1191,18 @@ class IdfInterface(IdfInterfaceBase):
1159
1191
  for item in items:
1160
1192
  self.signals.append(IdfSignal(self, item))
1161
1193
  items = idf.get("methods", [])
1194
+ self.methods = []
1162
1195
  for item in items:
1163
1196
  self.methods.append(IdfMethod(self, item))
1164
1197
  items = idf.get("structures", [])
1165
1198
  for item in items:
1166
1199
  obj = IdfStructure(self, item)
1167
1200
  self.structures[obj.name] = obj
1201
+ items = idf.get("errors", [])
1202
+ for item in items:
1203
+ obj = IdfStructure(self, item, "parameters")
1204
+ self.errors[obj.name] = obj
1205
+ self._check_errors_format()
1168
1206
  items = idf.get("dictionaries", [])
1169
1207
  for item in items:
1170
1208
  obj = IdfDictionary(self, item)
@@ -1174,6 +1212,7 @@ class IdfInterface(IdfInterfaceBase):
1174
1212
  obj = IdfEnumeration(self, item)
1175
1213
  self.enumerations[obj.name] = obj
1176
1214
  plugin = idf.get("plugin", None)
1215
+ self.plugin = IdfInterfacePlugin()
1177
1216
  if plugin is not None:
1178
1217
  items = plugin.get("actions", [])
1179
1218
  for item in items:
@@ -1208,3 +1247,34 @@ class IdfInterface(IdfInterfaceBase):
1208
1247
  out = self.render(self.lookup, template, intf=self, codegen_version=codegen_version)
1209
1248
  with open(out_file, "w") as fd:
1210
1249
  fd.write(out)
1250
+
1251
+ def _check_errors_format(self):
1252
+ for name, error in self.errors.items():
1253
+ desc = error.description
1254
+ chunks = []
1255
+ prev_line = ""
1256
+ for chunk in desc.split("$?"):
1257
+ if prev_line:
1258
+ chunks.append(prev_line + chunk)
1259
+ prev_line = ""
1260
+ elif chunk[-1:] == "\\":
1261
+ prev_line = chunk[:-1] + "$?"
1262
+ else:
1263
+ chunks.append(chunk)
1264
+ # 如果剩余prev_line示处理,表示纯粹剩余一个\
1265
+ if prev_line:
1266
+ chunks.append(prev_line[:-2] + "\\")
1267
+ # 参数个数检验
1268
+ if len(chunks) != len(error.values.parameters) + 1:
1269
+ raise LiteBmcException(f"The number({len(chunks) - 1}) of $? in the description string(Error: ${name}) does not match the number({len(error.values.parameters)}) of parameters")
1270
+ new_desc = chunks[0]
1271
+ id = 1
1272
+ for param in error.values.parameters:
1273
+ formatter = PRINT_FORMATTER_MAP[param.ctype]
1274
+ if formatter.startswith("%"):
1275
+ new_desc += formatter
1276
+ else:
1277
+ new_desc += f"%\"{formatter}\""
1278
+ new_desc += chunks[id]
1279
+ id += 1
1280
+ error.description = new_desc
@@ -2,6 +2,64 @@
2
2
  #include "${intf.name}.h"
3
3
 
4
4
  <% class_name = intf.alias %>\
5
+ ### 生成Errors错误 START
6
+ % if len(intf.errors):
7
+ ### 定义错误码表
8
+ static const GDBusErrorEntry _dbus_error_entries[] =
9
+ {
10
+ % for name, stru in intf.errors.items():
11
+ {
12
+ .error_code = ${class_name}_Error_${name},
13
+ .dbus_error_name = "${intf.name}.Error.${name}"
14
+ },
15
+ % endfor
16
+ };
17
+
18
+ ### 初始化quark表
19
+ static GQuark _dbus_error_quark(void)
20
+ {
21
+ static gsize quark = 0;
22
+ g_dbus_error_register_error_domain("${intf.name.replace(".", "-")}-quark",
23
+ &quark,
24
+ _dbus_error_entries,
25
+ G_N_ELEMENTS (_dbus_error_entries));
26
+ return (GQuark) quark;
27
+ }
28
+ ### 构建参数原型和参数列表
29
+ % for name, stru in intf.errors.items():
30
+
31
+ <% proto_str="" %>\
32
+ <% param_str="" %>\
33
+ % for prop in stru.values.parameters:
34
+ % for dec in prop.declare():
35
+ <% proto_str += dec.replace("<arg_name>", prop.name).replace("<const>", "const ") + ", " %>\
36
+ % endfor
37
+ <% param_str += prop.name + ", " %>\
38
+ % endfor
39
+ % if stru.description:
40
+ /*
41
+ * Error: ${stru.description.strip()}
42
+ */
43
+ % endif
44
+ ### 生成错误消息
45
+ % if len(proto_str):
46
+ GError *${intf.alias}_Error_${name}_new(${proto_str[:-2]})
47
+ {
48
+ return g_error_new(_dbus_error_quark(), ${class_name}_Error_${name},
49
+ "${stru.description.strip()}",
50
+ ${param_str[:-2]});
51
+ }
52
+ % else:
53
+ GError *${intf.alias}_Error_${name}_new(void)
54
+ {
55
+ return g_error_new(_dbus_error_quark(), ${class_name}_Error_${name},
56
+ "${stru.description.strip()}");
57
+ }
58
+ %endif
59
+ %endfor
60
+
61
+ %endif
62
+ ### 生成Errors错误 END
5
63
  ## 定义结构体ODF加载函数
6
64
  % for name, stru in intf.structures.items():
7
65
  /* ${name} structure object */
@@ -15,6 +15,17 @@ extern "C" {
15
15
  /* Interface ${intf.alias} codegen start */
16
16
 
17
17
  <% class_name = intf.alias %>\
18
+ ### 生成Errors错误 START >>>>>
19
+ % if len(intf.errors):
20
+ ### 定义枚举类型
21
+ typedef enum {
22
+ % for name, stru in intf.errors.items():
23
+ ${class_name}_Error_${name},
24
+ % endfor
25
+ } ${class_name}_Error;
26
+
27
+ %endif
28
+ ### 生成Errors错误 END <<<<<
18
29
  % for name, stru in intf.structures.items():
19
30
  /*
20
31
  * structure: ${name}
@@ -41,8 +52,36 @@ typedef struct _${name} ${name};
41
52
  % endfor
42
53
  % endif
43
54
  */
44
- typedef enum _${name} ${name};
55
+ typedef enum {
56
+ % for value in enum.values.parameters:
57
+ ${name}_${value.name},
58
+ % endfor
59
+ _${name}Invalid,
60
+ } ${name};
61
+ const gchar *${name}_as_string(${name} value);
62
+
45
63
  % endfor
64
+ ### 生成Errors错误 START
65
+ % if len(intf.errors):
66
+ % for name, stru in intf.errors.items():
67
+ <% proto_str="" %>\
68
+ % for prop in stru.values.parameters:
69
+ % for dec in prop.declare():
70
+ <% proto_str += dec.replace("<arg_name>", prop.name).replace("<const>", "const ") + ", " %>\
71
+ % endfor
72
+ % endfor
73
+ /*
74
+ * Error: ${stru.description.strip()}
75
+ */
76
+ % if len(proto_str):
77
+ GError *${intf.alias}_Error_${name}_new(${proto_str[:-2]});
78
+ % else:
79
+ GError *${intf.alias}_Error_${name}_new(void);
80
+ %endif
81
+ %endfor
82
+
83
+ %endif
84
+ ### 生成Errors错误 END
46
85
  % for name, dictionary in intf.dictionaries.items():
47
86
  /*
48
87
  * dictionary: ${name}
@@ -57,8 +96,8 @@ typedef enum _${name} ${name};
57
96
  */
58
97
  typedef struct _${name}${dictionary.key} ${name}${dictionary.key};
59
98
  typedef struct _${name} ${name};
60
- % endfor
61
99
 
100
+ % endfor
62
101
  % for name, stru in intf.structures.items():
63
102
  % if name != class_name:
64
103
  /*
@@ -82,18 +121,6 @@ struct _${name} {
82
121
 
83
122
  % endif
84
123
  %endfor
85
- % for name, enum in intf.enumerations.items():
86
- ## 枚举定义
87
- enum _${name} {
88
- % for value in enum.values.parameters:
89
- ${name}_${value.name},
90
- % endfor
91
- _${name}Invalid,
92
- };
93
-
94
- const gchar *${name}_as_string(${name} value);
95
-
96
- % endfor
97
124
  % for name, dictionary in intf.dictionaries.items():
98
125
  struct _${name}${dictionary.key} {
99
126
  % for value in dictionary.values.parameters:
@@ -199,8 +199,19 @@ class LiteBmcConan(ConanFile):
199
199
  tc.variables["BUILD_TEST"] = False
200
200
 
201
201
  % if len(pkg.get("options", [])) > 0:
202
- % for op, _ in pkg["options"].items():
203
- tc.variables["BUILD_${op.upper()}"] = self.options.${op}
202
+ % for op, value in pkg["options"].items():
203
+ % if type(value["default"]) == type(False):
204
+ if self.options.${op}:
205
+ tc.variables["BUILD_${op.upper()}"] = True
206
+ tc.preprocessor_definitions["BUILD_${op.upper()}"] = True
207
+ % elif type(value["default"]) == type(""):
208
+ tc.variables["BUILD_${op.upper()}"] = str(self.options.${op})
209
+ tc.preprocessor_definitions["BUILD_${op.upper()}"] = str(self.options.${op}.value)
210
+ % elif type(value["default"]) == type(123):
211
+ tc.preprocessor_definitions["BUILD_${op.upper()}"] = int(self.options.${op}.value)
212
+ % elif type(value["default"]) == type(123.22):
213
+ tc.preprocessor_definitions["BUILD_${op.upper()}"] = float(self.options.${op}.value)
214
+ % endif
204
215
  % endfor
205
216
  % endif
206
217
  tc.extra_cflags = self._append_default_flags()
@@ -25,8 +25,6 @@ class BuildImage(Task):
25
25
  """任务入口"""
26
26
  """检查manifest文件是否满足schema格式描述"""
27
27
  os.chdir(self.config.output_path)
28
- cmd = "qemu-system-aarch64 -M virt -cpu cortex-a57 -M virt,dumpdtb=virt.dtb"
29
- self.exec(cmd)
30
28
 
31
29
  mk = MekeEmmcImage(os.path.join(self.config.temp_path, "emmc_tmp_dir"))
32
30
  rootfs_size = self.get_manifest_config("metadata/rootfs_size")
@@ -35,7 +33,7 @@ class BuildImage(Task):
35
33
  emmc_size = self.get_manifest_config("metadata/emmc_size")
36
34
  if emmc_size:
37
35
  mk.size_1m = self._trans_to_blk_1m(emmc_size)
38
- mk.run("virt.dtb", self.config.rootfs_img, "qemu.img")
36
+ mk.run(self.config.rootfs_img, "qemu.img")
39
37
  cmd = 'cp /usr/share/litebmc/qemu.conf qemu.conf'
40
38
  self.exec(cmd)
41
39
  output_img = os.path.join(self.config.output_path, "litebmc_qemu.tar.gz")
@@ -68,6 +68,25 @@ class BuildManifest(Task):
68
68
  cmd = f"conan download {pkg} -r {self.config.remote} --only-recipe"
69
69
  self.exec(cmd, ignore_error=True)
70
70
 
71
+ def build_rootfs(self):
72
+ """构建产品rootfs包"""
73
+ log.info("build rootfs")
74
+
75
+ manifest = self.load_manifest()
76
+ # 使用模板生成litebmc组件的配置
77
+ lookup = TemplateLookup(directories=os.path.join(src_cwd, "template"))
78
+ template = lookup.get_template("rootfs.py.mako")
79
+ conanfile = template.render(lookup=lookup, pkg=manifest)
80
+
81
+ recipe = os.path.join(self.conan_build, "rootfs")
82
+ os.makedirs(recipe, exist_ok=True)
83
+ os.chdir(recipe)
84
+ fp = open("conanfile.py", "w", encoding="utf-8")
85
+ fp.write(conanfile)
86
+ fp.close()
87
+
88
+ self.exec("conan create . " + self.common_args)
89
+
71
90
  def build_litebmc(self):
72
91
  """构建产品conan包"""
73
92
  log.info("build litebmc")
@@ -88,23 +107,17 @@ class BuildManifest(Task):
88
107
  fp.close()
89
108
 
90
109
  base_cmd = f"{self.common_args} {self.conan_settings}"
91
- lockfile = os.path.join(self.config.code_path, "conan.lock")
110
+ lockfile = os.path.join(self.config.temp_path, "conan.lock")
92
111
  threadPool = ThreadPoolExecutor(max_workers=16)
93
- # 指定-l参数或conan.lock文件不存在时创建lock文件
94
- if self.config.create_conan_lock or not os.path.isfile(lockfile):
95
- # 创建新的conan.lock文件
96
- for dep in manifest.get("dependencies", []):
97
- pkg = dep.get("package")
98
- threadPool.submit(self.download_recipe, pkg)
99
- lock_cmd = f"conan lock create . {base_cmd} --lockfile-out={lockfile}"
100
- self.exec(lock_cmd)
101
- else:
102
- with open(lockfile, "r") as fp:
103
- lock = json.load(fp)
104
- for key in ["requires", "build_requires", "python_requires", "config_requires"]:
105
- requires = lock.get(key, [])
106
- for require in requires:
107
- threadPool.submit(self.download_recipe, require)
112
+ # 创建新的conan.lock文件
113
+ lock_cmd = f"conan lock create . {base_cmd} --lockfile-out={lockfile}"
114
+ self.exec(lock_cmd)
115
+ with open(lockfile, "r") as fp:
116
+ lock = json.load(fp)
117
+ for key in ["requires", "build_requires", "python_requires", "config_requires"]:
118
+ requires = lock.get(key, [])
119
+ for require in requires:
120
+ threadPool.submit(self.download_recipe, require)
108
121
  threadPool.shutdown(wait=True)
109
122
  graph_cmd = f"conan graph info . {base_cmd} -f json --lockfile={lockfile}"
110
123
  graphfile = os.path.join(self.config.temp_path, "graph.info")
@@ -112,11 +125,13 @@ class BuildManifest(Task):
112
125
  bcp = BuildConanParallel(graphfile, lockfile, self.common_args, self.config.from_source)
113
126
  bcp.build()
114
127
 
128
+ self.exec(f"sed -i 's@rootfs_df190c/0.0.1#.*\"@rootfs_df190c/0.0.1\"@g' {lockfile}")
115
129
  # 部署应用到self.config.conan_install
116
130
  self.deploy(graphfile)
117
131
 
118
132
  def run(self):
119
133
  """任务入口"""
134
+ self.build_rootfs()
120
135
  self.build_litebmc()
121
136
  error = False
122
137
  if not self.config.rootfs_tar:
@@ -127,6 +127,12 @@ class BuildRootfs(Task):
127
127
  if os.path.isdir(product_rootfs):
128
128
  self.copy_conan_install(product_rootfs, mnt_path)
129
129
 
130
+ # 设置boot目录权限
131
+ log.info("设置boot目录权限")
132
+ self.exec(f"chown 0:0 boot/ -R")
133
+ self.exec(f"chmod 600 boot/ -R")
134
+ if os.path.isdir("extlinux"):
135
+ self.exec(f"chmod 700 boot/extlinux/")
130
136
  # 执行rootfs定制化脚本
131
137
  os.chdir(self.config.work_dir)
132
138
  hook_name = "hook.post_rootfs"
@@ -34,8 +34,6 @@ class Config(object):
34
34
  self.profile_build = args.profile_build
35
35
  # 编译目标配置项
36
36
  self.profile_host = args.profile
37
- # 是否创建新的lockfile
38
- self.create_conan_lock = args.create_conan_lock
39
37
 
40
38
  # 设置并创建构建所需目录
41
39
  log.info("Work dir: %s", self.work_dir)
@@ -67,7 +65,6 @@ class Config(object):
67
65
  parser.add_argument("-pr:b", "--profile_build", help="Apply the specified profile to the build machine", default="default")
68
66
  parser.add_argument("-t", "--build_type", type=str, choices=['debug', 'release', 'minsize'], help="Set the build type", default="debug")
69
67
  parser.add_argument("-r", "--remote", help="specified conan server", default="litebmc")
70
- parser.add_argument("-l", "--create_conan_lock", help="Create new conan.lock", action="store_true")
71
68
  return parser
72
69
 
73
70
  def get_manifest_config(self, key: str, default=None):
@@ -20,7 +20,7 @@ class LitebmcConan(ConanFile):
20
20
  % for dep in pkg["dependencies"]:
21
21
  self.requires("${dep["package"]}")
22
22
  % endfor
23
- pass
23
+ self.requires("rootfs_df190c/0.0.1")
24
24
 
25
25
  def configure(self):
26
26
  % for dep in pkg["dependencies"]:
@@ -0,0 +1,27 @@
1
+ import os
2
+ from conan import ConanFile
3
+ <% dts = pkg.get("metadata", {}).get("dts") %>
4
+
5
+ class RootfsConan(ConanFile):
6
+ """用于构建产品的顶层rootfs包"""
7
+ name = "rootfs_df190c"
8
+ settings = "os", "arch", "compiler", "build_type"
9
+ description = "build rootfs component"
10
+ url = "https://litebmc.com"
11
+ extension_properties = {
12
+ "compatibility_cppstd": False,
13
+ "compatibility_cstd": False
14
+ }
15
+ homepage = "https://www.litebmc.com"
16
+ license = "BSL-1.0"
17
+ version = "0.0.1"
18
+
19
+ % if dts:
20
+ def build_requirements(self):
21
+ self.tool_requires("dtc/1.7.0")
22
+
23
+ def build(self):
24
+ os.makedirs(self.package_folder + "/boot")
25
+ self.run(f"dtc -I dts -O dtb ${dts["input"]} -o {self.package_folder}/boot/${dts["output"]}")
26
+
27
+ % endif
@@ -8,6 +8,7 @@ import tempfile
8
8
  import requests
9
9
  import shlex
10
10
  import hashlib
11
+ import re
11
12
  from lbkit.log import Logger
12
13
  from lbkit import errors
13
14
  from lbkit import misc
@@ -170,4 +171,11 @@ class Tools(object):
170
171
  if sha256sum is None or digest == sha256sum:
171
172
  self.log.info("Download %s successfully", url, uptrace=2)
172
173
  return
173
- raise errors.DigestNotMatchError(f"File {dst_file} with sha256 error, need: {sha256sum}, get: {digest}")
174
+ raise errors.DigestNotMatchError(f"File {dst_file} with sha256 error, need: {sha256sum}, get: {digest}")
175
+
176
+ def hump2underline(hunp_str):
177
+ # 匹配正则,匹配小写字母和大写字母的分界位置
178
+ p = re.compile(r'([a-z]|\d)([A-Z])')
179
+ # 这里第二个参数使用了正则分组的后向引用
180
+ sub = re.sub(p, r'\1_\2', hunp_str).lower()
181
+ return sub
@@ -26,7 +26,7 @@ class MakeImage():
26
26
  cmd = "umount " + tmp_dir
27
27
  self.tools.exec(cmd, ignore_error=True, echo_cmd=False)
28
28
 
29
- def run(self, dtb, rootfs, output="emmc.img"):
29
+ def run(self, rootfs, output="emmc.img"):
30
30
  blk_1k = self.misc_blk_1k + self.ubootenv_blk_1k + self.vbmeta_blk_1k
31
31
  blk_1k += self.rootfs_blk_1m * 1024 * 3
32
32
  blk_1k += self.userdata_blk_1m * 1024
@@ -57,26 +57,6 @@ class MakeImage():
57
57
  end += self.rootfs_blk_1m * 1024 * 2
58
58
  self.log.info("创建rootfs镜像区")
59
59
  self.tools.exec(f"parted -s -a none {output} mkpart rootfs_a {start}s {end - 1}s")
60
- self.log.info(f"挂载rootfs分区并复制内容,注意,此时会修改原始{rootfs}镜像并添加dtb以及启动参数")
61
- self.tools.exec(f"fuse2fs {rootfs} {self.tmp_dir} -o fakeroot -o nonempty")
62
- extlinux = os.path.join(self.tmp_dir, "boot/extlinux")
63
- os.makedirs(extlinux, exist_ok=True)
64
- with open(os.path.join(extlinux, "extlinux.conf"), "w+") as fp:
65
- fp.write("menu title U-Boot menu\n")
66
- fp.write("prompt 0\n")
67
- fp.write("timeout 10\n")
68
- fp.write("\n")
69
- fp.write("label litebmc-active\n")
70
- fp.write(" kernel /boot/Image\n")
71
- fp.write(" fdt /boot/litebmc.dtb\n")
72
- fp.write(" append console=ttyAMA0 loglevel=10 rootwait root=/dev/nvme0n1p4 rw\n")
73
- self.tools.exec(f"cp {dtb} {self.tmp_dir}/boot/litebmc.dtb")
74
- self.tools.exec(f"chown 0:0 {self.tmp_dir}/boot/ -R")
75
- self.tools.exec(f"chmod 700 {self.tmp_dir}/boot/extlinux/")
76
- self.tools.exec(f"chmod 600 {self.tmp_dir}/boot/extlinux/extlinux.conf")
77
- self.tools.exec(f"chmod 600 {self.tmp_dir}/boot/Image")
78
- self.tools.exec(f"chmod 600 {self.tmp_dir}/boot/litebmc.dtb")
79
- self.tools.exec(f"umount {self.tmp_dir}")
80
60
  self.log.info("复制镜像文件到rootfs_a区域")
81
61
  self.tools.exec(f"dd if={rootfs} of={output} bs=512 seek={start} conv=notrunc")
82
62
  self.log.info("制作rootfs_b")
@@ -106,4 +86,4 @@ class MakeImage():
106
86
 
107
87
  if __name__ == "__main__":
108
88
  mk = MakeImage()
109
- mk.run("./Image", "./virt.dtb", "./rootfs.img", "./qemu.img")
89
+ mk.run("./rootfs.img", "./qemu.img")
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.2
2
2
  Name: lbkit
3
- Version: 0.6.5
3
+ Version: 0.6.7
4
4
  Summary: Tools provided by litebmc.com
5
5
  Home-page: https://www.litebmc.com
6
6
  Author: xuhj@litebmc.com
@@ -21,5 +21,13 @@ Requires-Dist: requests
21
21
  Requires-Dist: gitpython
22
22
  Requires-Dist: inflection
23
23
  Requires-Dist: meson>=1.4.0
24
+ Dynamic: author
25
+ Dynamic: author-email
26
+ Dynamic: classifier
27
+ Dynamic: description
28
+ Dynamic: description-content-type
29
+ Dynamic: home-page
30
+ Dynamic: requires-dist
31
+ Dynamic: summary
24
32
 
25
33
  build and code generate tools
@@ -47,6 +47,7 @@ lbkit/integration/build_rootfs.py
47
47
  lbkit/integration/config.py
48
48
  lbkit/integration/task.py
49
49
  lbkit/integration/template/conanfile.py.mako
50
+ lbkit/integration/template/rootfs.py.mako
50
51
  lbkit/utils/__init__.py
51
52
  lbkit/utils/images/__init__.py
52
53
  lbkit/utils/images/emmc.py
@@ -1,2 +0,0 @@
1
-
2
- __version__ = '0.6.5'
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes