lbkit 0.5.2__tar.gz → 0.5.5__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 (52) hide show
  1. {lbkit-0.5.2/lbkit.egg-info → lbkit-0.5.5}/PKG-INFO +2 -1
  2. lbkit-0.5.5/lbkit/__init__.py +2 -0
  3. {lbkit-0.5.2 → lbkit-0.5.5}/lbkit/codegen/codegen.py +2 -1
  4. {lbkit-0.5.2 → lbkit-0.5.5}/lbkit/codegen/idf_interface.py +57 -33
  5. {lbkit-0.5.2 → lbkit-0.5.5}/lbkit/codegen/template/public.c.mako +9 -0
  6. {lbkit-0.5.2 → lbkit-0.5.5}/lbkit/codegen/template/public.h.mako +3 -1
  7. lbkit-0.5.5/lbkit/codegen/template/server.c.mako +357 -0
  8. {lbkit-0.5.2 → lbkit-0.5.5}/lbkit/component/arg_parser.py +2 -2
  9. {lbkit-0.5.2 → lbkit-0.5.5}/lbkit/component/build.py +28 -7
  10. {lbkit-0.5.2 → lbkit-0.5.5}/lbkit/component/template/conanbase.mako +22 -0
  11. lbkit-0.5.5/lbkit/component/template/deploy.mako +42 -0
  12. {lbkit-0.5.2 → lbkit-0.5.5}/lbkit/misc.py +39 -1
  13. {lbkit-0.5.2 → lbkit-0.5.5/lbkit.egg-info}/PKG-INFO +2 -1
  14. {lbkit-0.5.2 → lbkit-0.5.5}/lbkit.egg-info/requires.txt +1 -0
  15. {lbkit-0.5.2 → lbkit-0.5.5}/setup.py +1 -1
  16. lbkit-0.5.2/lbkit/__init__.py +0 -2
  17. lbkit-0.5.2/lbkit/codegen/template/server.c.mako +0 -113
  18. lbkit-0.5.2/lbkit/component/template/deploy.mako +0 -20
  19. {lbkit-0.5.2 → lbkit-0.5.5}/AUTHORS +0 -0
  20. {lbkit-0.5.2 → lbkit-0.5.5}/LICENSE +0 -0
  21. {lbkit-0.5.2 → lbkit-0.5.5}/MANIFEST.in +0 -0
  22. {lbkit-0.5.2 → lbkit-0.5.5}/README.md +0 -0
  23. {lbkit-0.5.2 → lbkit-0.5.5}/lbkit/ci_robot/__init__.py +0 -0
  24. {lbkit-0.5.2 → lbkit-0.5.5}/lbkit/ci_robot/gitee.py +0 -0
  25. {lbkit-0.5.2 → lbkit-0.5.5}/lbkit/cli.py +0 -0
  26. {lbkit-0.5.2 → lbkit-0.5.5}/lbkit/codegen/__init__.py +0 -0
  27. {lbkit-0.5.2 → lbkit-0.5.5}/lbkit/codegen/ctype_defination.py +0 -0
  28. {lbkit-0.5.2 → lbkit-0.5.5}/lbkit/codegen/renderer.py +0 -0
  29. {lbkit-0.5.2 → lbkit-0.5.5}/lbkit/codegen/template/client.c.mako +0 -0
  30. {lbkit-0.5.2 → lbkit-0.5.5}/lbkit/codegen/template/client.h.mako +0 -0
  31. {lbkit-0.5.2 → lbkit-0.5.5}/lbkit/codegen/template/interface.c.mako +0 -0
  32. {lbkit-0.5.2 → lbkit-0.5.5}/lbkit/codegen/template/interface.introspect.xml.mako +0 -0
  33. {lbkit-0.5.2 → lbkit-0.5.5}/lbkit/codegen/template/server.h.mako +0 -0
  34. {lbkit-0.5.2 → lbkit-0.5.5}/lbkit/component/__init__.py +0 -0
  35. {lbkit-0.5.2 → lbkit-0.5.5}/lbkit/component/test.py +0 -0
  36. {lbkit-0.5.2 → lbkit-0.5.5}/lbkit/errors.py +0 -0
  37. {lbkit-0.5.2 → lbkit-0.5.5}/lbkit/helper.py +0 -0
  38. {lbkit-0.5.2 → lbkit-0.5.5}/lbkit/integration/__init__.py +0 -0
  39. {lbkit-0.5.2 → lbkit-0.5.5}/lbkit/integration/build_manifest.py +0 -0
  40. {lbkit-0.5.2 → lbkit-0.5.5}/lbkit/integration/build_prepare.py +0 -0
  41. {lbkit-0.5.2 → lbkit-0.5.5}/lbkit/integration/build_rootfs.py +0 -0
  42. {lbkit-0.5.2 → lbkit-0.5.5}/lbkit/integration/config.py +0 -0
  43. {lbkit-0.5.2 → lbkit-0.5.5}/lbkit/integration/task.py +0 -0
  44. {lbkit-0.5.2 → lbkit-0.5.5}/lbkit/integration/template/conanfile.py.mako +0 -0
  45. {lbkit-0.5.2 → lbkit-0.5.5}/lbkit/lbkit.py +0 -0
  46. {lbkit-0.5.2 → lbkit-0.5.5}/lbkit/log.py +0 -0
  47. {lbkit-0.5.2 → lbkit-0.5.5}/lbkit/tools.py +0 -0
  48. {lbkit-0.5.2 → lbkit-0.5.5}/lbkit.egg-info/SOURCES.txt +0 -0
  49. {lbkit-0.5.2 → lbkit-0.5.5}/lbkit.egg-info/dependency_links.txt +0 -0
  50. {lbkit-0.5.2 → lbkit-0.5.5}/lbkit.egg-info/entry_points.txt +0 -0
  51. {lbkit-0.5.2 → lbkit-0.5.5}/lbkit.egg-info/top_level.txt +0 -0
  52. {lbkit-0.5.2 → lbkit-0.5.5}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: lbkit
3
- Version: 0.5.2
3
+ Version: 0.5.5
4
4
  Summary: Tools provided by litebmc.com
5
5
  Home-page: https://www.litebmc.com
6
6
  Author: xuhj@litebmc.com
@@ -19,5 +19,6 @@ Requires-Dist: jsonschema
19
19
  Requires-Dist: conan==2.1
20
20
  Requires-Dist: requests
21
21
  Requires-Dist: gitpython
22
+ Requires-Dist: inflection
22
23
 
23
24
  build and code generate tools
@@ -0,0 +1,2 @@
1
+
2
+ __version__ = '0.5.5'
@@ -16,6 +16,7 @@ from lbkit.misc import SmartFormatter
16
16
  lb_cwd = os.path.split(os.path.realpath(__file__))[0]
17
17
  log = Logger("codegen")
18
18
 
19
+ __version__=1
19
20
 
20
21
  class CodeGen(object):
21
22
  def __init__(self, args):
@@ -66,7 +67,7 @@ class CodeGen(object):
66
67
  sys.exit(-1)
67
68
  outdir = cfg.get("outdir", os.getcwd())
68
69
  self._gen(file, outdir)
69
- return
70
+ return
70
71
 
71
72
  parser = argparse.ArgumentParser(description=self.run.__doc__,
72
73
  prog="lbkit gen",
@@ -1,12 +1,11 @@
1
1
  import yaml
2
2
  import os
3
- import json
4
3
  import re
5
4
  import hashlib
6
- from jsonschema import validate, ValidationError
7
5
  from lbkit.log import Logger
8
6
  from lbkit.codegen.renderer import Renderer
9
- from lbkit.codegen.ctype_defination import CTYPE_OBJS, CTypeBase
7
+ from lbkit.codegen.ctype_defination import CTYPE_OBJS
8
+ from lbkit.misc import validate_yml_with_json_schema
10
9
 
11
10
  log = Logger("gen_interface")
12
11
 
@@ -67,7 +66,8 @@ STRU_NAME_REGEX = METHOD_NAME_REGEX
67
66
  ENUM_NAME_REGEX = METHOD_NAME_REGEX
68
67
  DICT_NAME_REGEX = METHOD_NAME_REGEX
69
68
 
70
- CTYPE_REGEX = "boolean|byte|int16|uint16|int32|uint32|int64|uint64|size|ssize|double|string|object_path|signature|unixfd|variant"
69
+ CTYPE_BASE_REG = "boolean|byte|int16|uint16|int32|uint32|int64|uint64|size|ssize|double|string|object_path|signature|unixfd"
70
+ CTYPE_REGEX = CTYPE_BASE_REG + "|variant"
71
71
 
72
72
  CTYPE_SIGNATURE_MAP = {
73
73
  "boolean": "b",
@@ -137,7 +137,7 @@ class IdfCtypeRender():
137
137
  def declare(self):
138
138
  """变量申明,用于结构体(接口类、方法请求和响应、信号消息等)申明"""
139
139
  log.debug(f"Get declare info, name: {self.name}, ctype: {self.ctype}")
140
- match = re.match(f"^array\[({CTYPE_REGEX})\]$", self.ctype)
140
+ match = re.match(f"^array\[({CTYPE_BASE_REG})\]$", self.ctype)
141
141
  if match:
142
142
  ctype_obj = CTYPE_OBJS.get(self.ctype)
143
143
  return ctype_obj.declare
@@ -177,7 +177,7 @@ class IdfCtypeRender():
177
177
  def free_func(self):
178
178
  """生成释放数据的C函数,如果是结构体、字典需要生成对象的释放函数"""
179
179
  log.debug(f"Get free function info, name: {self.name}, ctype: {self.ctype}")
180
- match = re.match(f"^array\[({CTYPE_REGEX})\]$", self.ctype)
180
+ match = re.match(f"^array\[({CTYPE_BASE_REG})\]$", self.ctype)
181
181
  if match:
182
182
  ctype_obj = CTYPE_OBJS.get(self.ctype)
183
183
  return ctype_obj.free_func
@@ -206,7 +206,7 @@ class IdfCtypeRender():
206
206
 
207
207
  def encode_func(self):
208
208
  log.debug(f"Get encode function info, name: {self.name}, ctype: {self.ctype}")
209
- match = re.match(f"^array\[({CTYPE_REGEX})\]$", self.ctype)
209
+ match = re.match(f"^array\[({CTYPE_BASE_REG})\]$", self.ctype)
210
210
  if match:
211
211
  ctype_obj = CTYPE_OBJS.get(self.ctype)
212
212
  return ctype_obj.encode_func
@@ -239,7 +239,7 @@ class IdfCtypeRender():
239
239
 
240
240
  def decode_func(self):
241
241
  log.debug(f"Get decode info, name: {self.name}, ctype: {self.ctype}")
242
- match = re.match(f"^array\[({CTYPE_REGEX})\]$", self.ctype)
242
+ match = re.match(f"^array\[({CTYPE_BASE_REG})\]$", self.ctype)
243
243
  if match:
244
244
  ctype_obj = CTYPE_OBJS.get(self.ctype)
245
245
  return ctype_obj.decode_func
@@ -269,6 +269,47 @@ class IdfCtypeRender():
269
269
  else:
270
270
  return [f"<arg_in> = {stru_name}_decode(<arg_name>)"]
271
271
 
272
+ def odf_load_func(self):
273
+ log.debug(f"Get odf_load function, name: {self.name}, ctype: {self.ctype}")
274
+ # odf不支持gariant
275
+ match = re.match(f"^array\[(variant)\]$", self.ctype)
276
+ if match:
277
+ return None
278
+ match = re.match(f"^variant$", self.ctype)
279
+ if match:
280
+ return None
281
+ # 字符串数组由结束NULL表示,不需要长度
282
+ match = re.match(f"^array\[(string|object_path|signature)\]$", self.ctype)
283
+ if match:
284
+ return "<arg_name> = load_odf_as_" + match.group(1) + "_v(doc, <node>)"
285
+ match = re.match(f"^array\[({CTYPE_BASE_REG})\]$", self.ctype)
286
+ if match:
287
+ return "<arg_name> = load_odf_as_" + match.group(1) + "_v(doc, <node>, &n_<arg_name>)"
288
+ match = re.match(f"^({CTYPE_REGEX})$", self.ctype)
289
+ if match:
290
+ return "<arg_name> = load_odf_as_" + match.group(1) + "(doc, <node>)"
291
+ # 非基础类型
292
+ is_array = False
293
+ ctype = self.ctype
294
+ match = re.match(f"^array\[(.*)\]$", ctype)
295
+ if match:
296
+ is_array = True
297
+ ctype = match.group(1)
298
+ match = re.match(f"^(struct|enum|dict)\[(.*)\]$", ctype)
299
+ _, stru_name = get_intfname_and_ctype(match.group(2))
300
+ if match.group(1) == "enum":
301
+ if is_array:
302
+ # 入参为二级指针
303
+ return f"<arg_name> = _load_odf_as_{stru_name}_v(doc, <node>, &n_<arg_name>)"
304
+ else:
305
+ return f"<arg_name> = _load_odf_as_{stru_name}(doc, <node>)"
306
+ else:
307
+ if is_array:
308
+ # 入参为二级指针
309
+ return f"<arg_name> = _load_odf_as_{stru_name}_v(doc, <node>)"
310
+ else:
311
+ return f"<arg_name> = _load_odf_as_{stru_name}(doc, <node>)"
312
+
272
313
  class IdfProperty(IdfCtypeRender):
273
314
  def __init__(self, intf: IdfInterfaceBase, prop_data):
274
315
  self.intf = intf
@@ -279,8 +320,12 @@ class IdfProperty(IdfCtypeRender):
279
320
  self.annotations: list[IdfAnnotation] = []
280
321
  self.description = prop_data.get("description", "")
281
322
  flags = prop_data.get("flags", "").split(",")
323
+ self.flags = flags
282
324
  self.private = True if ("private" in flags) else False
283
325
  self.deprecated = True if ("deprecated" in flags) else False
326
+ # refobj的ctype只能是s或as
327
+ if "refobj" in flags and self.ctype != "string" and self.ctype != "array[string]":
328
+ raise IDFException(f"property {self.name} with refobj flag but type is neither s nor as")
284
329
  for k, v in ACCESS_MAP.items():
285
330
  if k in flags:
286
331
  self.access = v
@@ -487,34 +532,13 @@ class IdfInterface(IdfInterfaceBase):
487
532
  sig += prop.signature
488
533
  return "(" + sig + ")"
489
534
 
490
- def _validate(self, idf):
491
- schema_file = None
492
- with open(self.file, "r") as fp:
493
- for line in fp:
494
- match = re.search(r"#[ ]*yaml-language-server:[ ]*\$schema=(.*)\n", line)
495
- if match is not None:
496
- schema_file = match.group(1)
497
- break
498
- if schema_file is None:
499
- schema_file = "/usr/share/litebmc/schema/metadata/interfaces/idf.v1.yaml"
500
- with open(schema_file, "r") as fp:
501
- tmp = fp.read()
502
- schema = json.loads(tmp)
503
- try:
504
- validate(idf, schema)
505
- except ValidationError as exc:
506
- log.error(f"validate {self.file} failed, schema file is {schema_file}, message:")
507
- log.error(str(exc))
508
- return False
509
- log.info(f"validate {self.file} successfully")
510
- return True
511
-
512
535
  def load_elements(self):
536
+ # 使用schema校验数据,确保IDF文件符合格式要求,减少程序处理过程中的异常处理
537
+ # 验证失败时抛异常,此处不用处理,由外层处理
538
+ validate_yml_with_json_schema(self.file, "/usr/share/litebmc/schema/idf.v1.json")
539
+ log.info(f"validate {self.file} successfully")
513
540
  with open(self.file, "r") as fp:
514
541
  idf = yaml.load(fp, yaml.FullLoader)
515
- # 使用schema校验数据,确保IDF文件符合格式要求,减少程序处理过程中的异常处理
516
- if not self._validate(idf):
517
- return -1
518
542
  self.version = idf.get("version")
519
543
  self.description = idf.get("description", "")
520
544
  # 别名
@@ -140,6 +140,14 @@ static const gchar *_${name}StrMap[] = {
140
140
  % endfor
141
141
  };
142
142
 
143
+ const gchar *${name}_as_string(${name} value)
144
+ {
145
+ if (value >= _${name}Invalid) {
146
+ return "com.litebmc.Errors.Enum.Invalid";
147
+ }
148
+ return _${name}StrMap[value];
149
+ }
150
+
143
151
  /* ${name}枚举类型序列化(enum转string)函数 */
144
152
  GVariant *${name}_encode(${name} value)
145
153
  {
@@ -165,6 +173,7 @@ ${name} ${name}_decode(GVariant *in)
165
173
  }
166
174
  return _${name}Invalid;
167
175
  }
176
+
168
177
  /* ${name}枚举类型序列化(enum转string)函数 */
169
178
  GVariant *${name}_encode_v(const ${name} *values, gsize n)
170
179
  {
@@ -50,6 +50,8 @@ enum _${name} {
50
50
  _${name}Invalid,
51
51
  };
52
52
 
53
+ const gchar *${name}_as_string(${name} value);
54
+
53
55
  % endfor
54
56
  % for name, dictionary in intf.dictionaries.items():
55
57
 
@@ -82,7 +84,7 @@ ${name} *${name}_new(void);
82
84
 
83
85
  ## 定义结构体编解码和释放函数
84
86
  % for name, stru in intf.structures.items():
85
- /* ${name} dictionary object */
87
+ /* ${name} structure object */
86
88
  /* START: 结构体${name}及其数组类型的序列化、反序列化、释放函数 */
87
89
  GVariant *${name}_encode(const ${name} *value);
88
90
  ${name} *${name}_decode(GVariant *in);
@@ -0,0 +1,357 @@
1
+ #include "gcl_base.h"
2
+ #include "${intf.name}.h"
3
+
4
+ <%
5
+ class_name = intf.alias
6
+ properties = "_" + class_name + "_properties"
7
+ signal_processer = "_" + class_name + "_signals"
8
+ %>\
9
+ ## 定义结构体ODF加载函数
10
+ % for name, stru in intf.structures.items():
11
+ /* ${name} structure object */
12
+ /* START: 结构体${name}及其数组类型的ODF加载函数 */
13
+ ${name} *_load_odf_as_${name}(yaml_document_t *doc, yaml_node_t *node);
14
+ ${name} **_load_odf_as_${name}_v(yaml_document_t *doc, yaml_node_t *node);
15
+
16
+ % endfor
17
+ ## 定义枚举ODF加载函数
18
+ % for name, enum in intf.enumerations.items():
19
+ /* START: 枚举${name}及其数组类型的ODF加载函数 */
20
+ ${name} _load_odf_as_${name}(yaml_document_t *doc, yaml_node_t *node);
21
+ ${name} *_load_odf_as_${name}_v(yaml_document_t *doc, yaml_node_t *node, gsize *n);
22
+
23
+ % endfor
24
+ ## 定义字典ODF加载函数
25
+ % for name, dictionary in intf.dictionaries.items():
26
+ /* START: 字典${name}及其数组类型的ODF加载函数 */
27
+ ${name} *_load_odf_as_${name}(yaml_document_t *doc, yaml_node_t *node);
28
+ ${name} **_load_odf_as_${name}_v(yaml_document_t *doc, yaml_node_t *node);
29
+
30
+ % endfor
31
+ ## 定义结构体ODF加载函数
32
+ % for name, stru in intf.structures.items():
33
+ /* ${name} structure object */
34
+ /* START: 结构体${name}及其数组类型的ODF加载函数 */
35
+
36
+ ${name} *_load_odf_as_${name}(yaml_document_t *doc, yaml_node_t *node)
37
+ {
38
+ <% cnt = 0 %>\
39
+ % for prop in stru.values.parameters:
40
+ % if prop.odf_load_func() is not None:
41
+ <% cnt = cnt + 1 %>\
42
+ % endif
43
+ % endfor
44
+ % if cnt == 0:
45
+ return g_new0(${name}, 1);
46
+ % else:
47
+ yaml_node_t *val;
48
+ ${name} *output = g_new0(${name}, 1);
49
+ GHashTable *prop_table = load_yaml_mapping_to_hash_table(doc, node);
50
+ % for prop in stru.values.parameters:
51
+ % if prop.odf_load_func() is not None:
52
+ /* process ${prop.name} */
53
+ val = g_hash_table_lookup(prop_table, "${prop.name}");
54
+ if (val)
55
+ ${prop.odf_load_func().replace("n_<arg_name>", "output->n_" + prop.name).replace("<arg_name>", "output->" + prop.name).replace("<node>", "val")};
56
+ % endif
57
+ % endfor
58
+
59
+ g_hash_table_destroy(prop_table);
60
+ return output;
61
+ % endif
62
+ }
63
+
64
+ ${name} **_load_odf_as_${name}_v(yaml_document_t *doc, yaml_node_t *node)
65
+ {
66
+ yaml_node_t *val;
67
+ gint i = 0;
68
+ if (node->type != YAML_SEQUENCE_NODE) {
69
+ log_warn("Load array ${name} failed because node type error, need type 1(sequence), get type %d", node->type);
70
+ return g_new0(${name} *, 1);
71
+ }
72
+ yaml_node_item_t *top = node->data.sequence.items.top;
73
+ yaml_node_item_t *start = node->data.sequence.items.start;
74
+ gsize cnt = ((gsize)top - (gsize)start) / sizeof(yaml_node_item_t);
75
+ ${name} **output = g_new0(${name} *, cnt + 1);
76
+
77
+ for (yaml_node_item_t *item = start; item < top; item++) {
78
+ val = yaml_document_get_node(doc, *item);
79
+ output[i++] = _load_odf_as_${name}(doc, val);
80
+ }
81
+ return output;
82
+ }
83
+
84
+ % endfor
85
+ ## 定义枚举ODF加载函数
86
+ % for name, enum in intf.enumerations.items():
87
+
88
+ ${name} _load_odf_as_${name}(yaml_document_t *doc, yaml_node_t *node)
89
+ {
90
+ g_assert(node->type == YAML_SCALAR_NODE);
91
+ if (node->type != YAML_SCALAR_NODE) {
92
+ return _${name}Invalid;
93
+ }
94
+
95
+ for (int i = 0; i <= ${len(enum.values.parameters)}; i++) {
96
+ if (g_strcmp0(node->data.scalar.value, ${name}_as_string(i)) == 0) {
97
+ return (${name})i;
98
+ }
99
+ }
100
+ return _${name}Invalid;
101
+ }
102
+
103
+ ${name} *_load_odf_as_${name}_v(yaml_document_t *doc, yaml_node_t *node, gsize *n)
104
+ {
105
+ g_assert(doc && node && n);
106
+ yaml_node_t *val;
107
+ gint i = 0;
108
+ if (node->type != YAML_SEQUENCE_NODE) {
109
+ log_warn("Load array ${name} failed because node type error, need type 1(sequence), get type %d", node->type);
110
+ return g_new0(${name}, 1);
111
+ }
112
+ yaml_node_item_t *top = node->data.sequence.items.top;
113
+ yaml_node_item_t *start = node->data.sequence.items.start;
114
+ *n = ((gsize)top - (gsize)start) / sizeof(yaml_node_item_t);
115
+ ${name} *output = g_new0(${name}, *n);
116
+
117
+ for (yaml_node_item_t *item = start; item < top; item++) {
118
+ val = yaml_document_get_node(doc, *item);
119
+ output[i++] = _load_odf_as_${name}(doc, val);
120
+ }
121
+ return output;
122
+ }
123
+
124
+ % endfor
125
+ ## 定义字典ODF加载函数
126
+ % for name, dictionary in intf.dictionaries.items():
127
+
128
+ ${name} *_load_odf_as_${name}(yaml_document_t *doc, yaml_node_t *node)
129
+ {
130
+ GHashTable *prop_table = NULL;
131
+ yaml_node_t *val = NULL;
132
+ ${name} *dict = ${name}_new();
133
+ yaml_node_item_t *top = node->data.sequence.items.top;
134
+ yaml_node_item_t *start = node->data.sequence.items.start;
135
+ for (yaml_node_item_t *item = start; item < top; item++) {
136
+ val = yaml_document_get_node(doc, *item);
137
+ ## 转换成hash表以获取key和properties
138
+ prop_table = load_yaml_mapping_to_hash_table(doc, val);
139
+ yaml_node_t *key = g_hash_table_lookup(prop_table, "key");
140
+ yaml_node_t *properties = g_hash_table_lookup(prop_table, "properties");
141
+ g_hash_table_destroy(prop_table);
142
+
143
+ ${", ".join(dictionary.key_obj.declare()).replace("<arg_name>", "key_val").replace("<const>", "")};
144
+ ${dictionary.key_obj.odf_load_func().replace("<arg_name>", "key_val").replace("<node>", "key")};
145
+
146
+ ## 创建一个新的字典成员
147
+ ${name}${dictionary.key} *item = g_new0(${name}${dictionary.key}, 1);
148
+ ## 转换成hash表
149
+ prop_table = load_yaml_mapping_to_hash_table(doc, properties);
150
+ ## 迭代所有成员并从odf中还原数据
151
+ % for prop in dictionary.values.parameters:
152
+ % if prop.odf_load_func() is not None:
153
+ val = g_hash_table_lookup(prop_table, "${prop.name}");
154
+ if (val)
155
+ ${prop.odf_load_func().replace("n_<arg_name>", "item->n_" + prop.name).replace("<arg_name>", "item->" + prop.name).replace("<node>", "val")};
156
+ % endif
157
+ % endfor
158
+ g_hash_table_destroy(prop_table);
159
+ dict->insert(dict, key_val, &item);
160
+ % for line in dictionary.key_obj.free_func():
161
+ ${line.replace("<arg_name>", "key_val")};
162
+ % endfor
163
+ }
164
+ return dict;
165
+ }
166
+
167
+ ${name} **_load_odf_as_${name}_v(yaml_document_t *doc, yaml_node_t *node)
168
+ {
169
+ yaml_node_t *val;
170
+ gint i = 0;
171
+ if (node->type != YAML_SEQUENCE_NODE) {
172
+ log_warn("Load array ${name} failed because node type error, need type 1(sequence), get type %d", node->type);
173
+ return g_new0(${name} *, 1);
174
+ }
175
+ yaml_node_item_t *top = node->data.sequence.items.top;
176
+ yaml_node_item_t *start = node->data.sequence.items.start;
177
+ gsize cnt = ((gsize)top - (gsize)start) / sizeof(yaml_node_item_t);
178
+ ${name} **output = g_new0(${name} *, cnt + 1);
179
+
180
+ for (yaml_node_item_t *item = start; item < top; item++) {
181
+ val = yaml_document_get_node(doc, *item);
182
+ output[i++] = _load_odf_as_${name}(doc, val);
183
+ }
184
+ return output;
185
+ }
186
+
187
+ % endfor
188
+ static ${class_name}_Properties ${properties};
189
+ static const ${class_name}_Signals *${signal_processer} = NULL;
190
+
191
+ % for prop in intf.properties:
192
+ /* ${prop.description} */
193
+ % if prop.deprecated:
194
+ __attribute__((__deprecated__)) void ${class_name}_set_${prop.name}(const ${class_name} *object,
195
+ ${", ".join(prop.declare()).replace("<arg_name>", "value").replace("<const>", "const ")})
196
+ % else:
197
+ void ${class_name}_set_${prop.name}(const ${class_name} *object,
198
+ ${", ".join(prop.declare()).replace("<arg_name>", "value").replace("<const>", "const ")})
199
+ % endif
200
+ {
201
+ GVariant *tmp = NULL;
202
+ % for line in prop.encode_func():
203
+ ${line.replace("<arg_out>", "tmp").replace("n_<arg_name>", "n_value").replace("<arg_name>", "value")};
204
+ % endfor
205
+ gcl_set_value((GclObject *)object, &_${class_name}_properties.${prop.name}, tmp);
206
+ g_variant_unref(tmp);
207
+ }
208
+
209
+ % endfor
210
+ % for signal in intf.signals:
211
+ /*
212
+ * Signal: ${signal.name}
213
+ * ${signal.description}
214
+ */
215
+ % if signal.deprecated:
216
+ __attribute__((__deprecated__)) gboolean ${class_name}_${signal.name}_Signal(const ${class_name} *object,
217
+ const gchar *destination, const ${class_name}_${signal.name}_Msg *msg, GError **error)
218
+ % else:
219
+ gboolean ${class_name}_${signal.name}_Signal(const ${class_name} *object, const gchar *destination,
220
+ const ${class_name}_${signal.name}_Msg *msg, GError **error)
221
+ % endif
222
+ {
223
+ if (error == NULL) {
224
+ log_error("Emit ${signal.name} with parameter error, error is NULL");
225
+ return FALSE;
226
+ }
227
+ if (object == NULL) {
228
+ *error = g_error_new(G_DBUS_ERROR, G_DBUS_ERROR_FAILED, "Emit ${signal.name} with parameter error, object is NULL");
229
+ return FALSE;
230
+ }
231
+ return gcl_impl.emit_signal((GclObject *)object, destination,
232
+ (const GclSignal *)&${signal_processer}->${signal.name}, msg, error);
233
+ }
234
+
235
+ % endfor
236
+ static GclObject *_${class_name}_create(const gchar *obj_name, gpointer opaque);
237
+ static void _load_from_odf(yaml_document_t *doc, yaml_node_t *node, GclObject *gcl_obj,
238
+ property_reference_loaded ref_loaded, gpointer user_data);
239
+ /*
240
+ * interface: ${intf.name}
241
+ % for c in intf.description.split("\n"):
242
+ * ${c}
243
+ % endfor
244
+ */
245
+ static GclInterface _${class_name}_interface = {
246
+ .create = _${intf.alias}_create,
247
+ .load_from_odf = (object_load_from_odf)_load_from_odf,
248
+ .is_remote = 0,
249
+ .name = "${intf.name}",
250
+ .properties = (GclProperty *)&${properties},
251
+ .interface = NULL, /* load from usr/share/dbus-1/interfaces/${intf.name} by gcl_init */
252
+ };
253
+
254
+ % for prop in intf.properties:
255
+ static void _load_odf_as_prop_${prop.name}(yaml_document_t *doc, GHashTable *prop_table,
256
+ ${class_name} *obj, property_reference_loaded ref_loaded, gpointer user_data)
257
+ {
258
+ const gchar *flags = NULL;
259
+ yaml_node_t *val = g_hash_table_lookup(prop_table, "_${prop.name}_flags");
260
+ if (val && val->type == YAML_SCALAR_NODE) {
261
+ flags = val->data.scalar.value;
262
+ }
263
+ val = g_hash_table_lookup(prop_table, "${prop.name}");
264
+ if (!val) {
265
+ if (flags) {
266
+ ref_loaded(obj, &${properties}.${prop.name}, NULL, NULL, user_data, flags);
267
+ }
268
+ return;
269
+ }
270
+ % if "refobj" in prop.flags:
271
+ ref_loaded(obj, &${properties}.${prop.name}, doc, val, user_data, flags);
272
+ % else:
273
+ if (val->type == YAML_SCALAR_NODE && val->data.scalar.value[0] == '$' &&
274
+ g_regex_match(gcl_ref_prop_regex(), val->data.scalar.value, 0, NULL)) {
275
+ ref_loaded(obj, &${properties}.${prop.name}, doc, val, user_data, flags);
276
+ } else {
277
+ % if prop.odf_load_func() is not None:
278
+ ${prop.odf_load_func().replace("n_<arg_name>", "obj->n_" + prop.name).replace("<arg_name>", "obj->" + prop.name).replace("<node>", "val")};
279
+ % endif
280
+ if (flags) {
281
+ ref_loaded(obj, &${properties}.${prop.name}, NULL, NULL, user_data, flags);
282
+ }
283
+ }
284
+ % endif
285
+ }
286
+
287
+ % endfor
288
+ static void _load_from_odf(yaml_document_t *doc, yaml_node_t *node, GclObject *gcl_obj,
289
+ property_reference_loaded ref_loaded, gpointer user_data)
290
+ {
291
+ g_assert(doc && node && gcl_obj);
292
+ if (!gcl_obj) {
293
+ return;
294
+ }
295
+ <% cnt = 0 %>\
296
+ % for prop in intf.properties:
297
+ % if prop.odf_load_func() is not None:
298
+ <% cnt = cnt + 1 %>\
299
+ % endif
300
+ % endfor
301
+ % if cnt == 0:
302
+ return;
303
+ % else:
304
+ ${class_name} *obj = (${class_name} *)gcl_obj;
305
+ ${class_name}_clean(obj);
306
+ GHashTable *prop_table = load_yaml_mapping_to_hash_table(doc, node);
307
+ % for prop in intf.properties:
308
+ _load_odf_as_prop_${prop.name}(doc, prop_table, obj, ref_loaded, user_data);
309
+ % endfor
310
+
311
+ g_hash_table_destroy(prop_table);
312
+ % endif
313
+ }
314
+
315
+ /**
316
+ * @brief 分配对象
317
+ *
318
+ * @param obj_name 对象名,需要由调用者分配内存
319
+ * @param opaque 上层应用需要写入对象的用户数据,由上层应用使用
320
+ */
321
+ GclObject *_${class_name}_create(const gchar *obj_name, gpointer opaque)
322
+ {
323
+ ${class_name} *obj = g_new0(${class_name}, 1);
324
+ memcpy(obj->_base.magic, GCL_MAGIC, strlen(GCL_MAGIC) + 1);
325
+ obj->_base.lock = g_new0(GRecMutex, 1);
326
+ g_rec_mutex_init(obj->_base.lock);
327
+ obj->_base.name = obj_name;
328
+ obj->_base.intf = &_${class_name}_interface;
329
+ obj->_base.opaque = opaque;
330
+ return (GclObject *)obj;
331
+ }
332
+
333
+ GclInterface *${class_name}_interface(void)
334
+ {
335
+ return &_${class_name}_interface;
336
+ }
337
+
338
+ ${class_name}_Properties *${class_name}_properties(void)
339
+ {
340
+ return &${properties};
341
+ }
342
+
343
+ static void __attribute__((constructor(150))) ${class_name}_register(void)
344
+ {
345
+
346
+ // 从公共库中复制信号处理函数
347
+ ${signal_processer} = ${class_name}_signals();
348
+ // 从公共库中复制方法处理函数
349
+ _${class_name}_interface.methods = (GclMethod *)${class_name}_methods();
350
+ _${class_name}_interface.signals = (GclSignal *)${class_name}_signals();
351
+
352
+ // 从公共库中复制属性信息
353
+ memcpy(&${properties}, ${class_name}_properties_const(), sizeof(${properties}));
354
+ gcl_interface_register(&_${class_name}_interface,
355
+ "${intf.introspect_xml_sha256}",
356
+ "/usr/share/dbus-1/interfaces/${intf.name}.xml");
357
+ }
@@ -33,6 +33,6 @@ class ArgParser():
33
33
  parser.add_argument(
34
34
  "-r", "--remote", default="litebmc", help="Conan仓别名(等同conan的-r选项)")
35
35
  parser.add_argument(
36
- "-c", "--channel", help='Provide a channel if not specified in conanfile', default="dev")
37
- parser.add_argument('-o','--pkg_options', action='append', help='Define options values (host machine), e.g.: -o pkg/*:shared=true', required=False, default=[])
36
+ "-c", "--channel", help='Provide a channel if not specified in mds/package.yml\ndefault value: dev', default="dev")
37
+ parser.add_argument('-o','--pkg_options', action='append', help='Define options values (host machine), e.g.: -o pkg/*:shared=True', required=False, default=[])
38
38
  return parser
@@ -8,7 +8,7 @@ from argparse import ArgumentParser
8
8
  from git import Repo
9
9
  from git.exc import InvalidGitRepositoryError
10
10
  from mako.lookup import TemplateLookup
11
- from lbkit.misc import Color
11
+ from lbkit.misc import Color, validate_yml_with_json_schema
12
12
  from lbkit import errors
13
13
  from lbkit.codegen.codegen import CodeGen
14
14
  from lbkit.tools import Tools
@@ -53,6 +53,7 @@ class BuildComponent():
53
53
  shutil.rmtree(self.rootfs_dir, ignore_errors=True)
54
54
  os.makedirs(self.rootfs_dir, exist_ok=True)
55
55
 
56
+ self.pkg = None
56
57
  self.gen_conaninfo()
57
58
  self.base_cmd = f" --user {self.user} --channel {self.channel}"
58
59
  self.base_cmd += f" -pr {self.profile} -s build_type={self.build_type} -r " + self.options.remote
@@ -94,6 +95,10 @@ class BuildComponent():
94
95
  package_yml = os.path.join(cwd, "metadata/package.yml")
95
96
  if not os.path.isfile(package_yml):
96
97
  raise FileNotFoundError("metadata/package.yml文件不存在")
98
+ # 验证失败时抛异常,此处不用处理,由外层处理
99
+ validate_yml_with_json_schema(package_yml, "/usr/share/litebmc/schema/cdf.v1.json")
100
+ log.info(f"validate {package_yml} successfully")
101
+
97
102
  # 加载package.yml文件
98
103
  fp = open(package_yml, "r")
99
104
  pkg = yaml.safe_load(fp)
@@ -104,13 +109,10 @@ class BuildComponent():
104
109
  # 构建命令未指定channel时从package.yml中读取
105
110
  pkg["channel"] = self.channel
106
111
  pkg["version"] = self.get_package_version()
112
+ self.pkg = pkg
107
113
  # 从package.yml加载基础信息
108
114
  self.name = pkg.get("name")
109
- if self.name is None:
110
- raise errors.PackageConfigException("metadata/package.yml未配置name属性")
111
115
  self.version = pkg.get("version")
112
- if self.version is None:
113
- raise errors.PackageConfigException("metadata/package.yml未配置version属性")
114
116
 
115
117
  self.package = self.name + "/" + self.version + \
116
118
  "@" + self.user + "/" + self.channel
@@ -156,7 +158,7 @@ class BuildComponent():
156
158
  # 生成部署deploy命令
157
159
  lookup = TemplateLookup(directories=os.path.join(lb_cwd, "template"))
158
160
  template = lookup.get_template("deploy.mako")
159
- deploy = template.render(lookup=lookup, packages=self.runtime_packages)
161
+ deploy = template.render(lookup=lookup, pkg=self.pkg, packages=self.runtime_packages)
160
162
  dir = os.path.join(cwd, ".temp", "deploy")
161
163
  # 创建临时目录并写入conanfile.py文件
162
164
  os.makedirs(dir, exist_ok=True)
@@ -178,7 +180,7 @@ class BuildComponent():
178
180
  template = lookup.get_template("deploy.mako")
179
181
  packages = self.runtime_packages
180
182
  packages.append(self.package)
181
- deploy = template.render(lookup=lookup, packages=packages)
183
+ deploy = template.render(lookup=lookup, pkg=self.pkg, packages=packages)
182
184
  dir = os.path.join(cwd, ".temp", "deploy")
183
185
  # 创建临时目录并写入conanfile.py文件
184
186
  os.makedirs(dir, exist_ok=True)
@@ -202,7 +204,26 @@ class BuildComponent():
202
204
  # 设置ROOTFS_DIR环境变量,为DT测试提供相对路径
203
205
  os.environ["ROOTFS_DIR"] = self.rootfs_dir
204
206
 
207
+ def _validate_odf_files(self):
208
+ odf_dirs = self.pkg.get("odf_dirs", [])
209
+ for dir in odf_dirs:
210
+ for filename in os.listdir(dir):
211
+ filename = os.path.join(dir, filename)
212
+ if not os.path.isfile(filename):
213
+ continue
214
+ if not filename.endswith(".yaml"):
215
+ log.debug(f"file {filename} not endswith .yaml, skip validate")
216
+ continue
217
+
218
+ log.info(f"start validate {filename}")
219
+ validate_yml_with_json_schema(filename, "/usr/share/litebmc/schema/odf.v1.json")
220
+
205
221
  def run(self):
222
+ # start validate all odf(Object Description file) files
223
+ self._validate_odf_files()
224
+
225
+ cmd = f"conan remove {self.package} -c"
226
+ tools.exec(cmd)
206
227
  gen = CodeGen([])
207
228
  gen.run("./metadata/package.yml")
208
229
  self._build_dependencies()
@@ -114,6 +114,28 @@ class LiteBmcConan(ConanFile):
114
114
  % endif
115
115
  pass
116
116
 
117
+ def configure(self):
118
+ % if len(pkg.get("requires", {})) > 0:
119
+ % for conan in pkg["requires"].get("compile", []):
120
+ % if conan.get("option") is not None:
121
+ % for k, v in conan.get("option").items():
122
+ self.options["${conan.get("conan").split("/")[0]}"].${k} = ${("\"" + v + "\"") if isinstance(v, str) else str(v)}
123
+ % endfor
124
+ % endif
125
+ % endfor
126
+ <%test_requires=pkg["requires"].get("test", [])%>\
127
+ % if len(test_requires):
128
+ % for conan in test_requires:
129
+ % if conan.get("option") is not None:
130
+ % for k, v in conan.get("option").items():
131
+ self.options["${conan.get("conan").split("/")[0]}"].${k} = ${("\"" + v + "\"") if isinstance(v, str) else str(v)}
132
+ % endfor
133
+ % endif
134
+ % endfor
135
+ % endif
136
+ % endif
137
+ pass
138
+
117
139
  def _append_default_flags(self):
118
140
  flags = []
119
141
  if self.options.gcov:
@@ -0,0 +1,42 @@
1
+ from conan import ConanFile
2
+
3
+
4
+ class DeployConan(ConanFile):
5
+ name = "deploy"
6
+ settings = "os", "arch", "compiler", "build_type"
7
+ description = "部署组件"
8
+ url = "https://litebmc.com"
9
+ homepage = ""
10
+ generators = "CMakeDeps"
11
+ package_type = "application"
12
+ version = "0.0.1"
13
+ license = "MulanPSL v2"
14
+
15
+ def requirements(self):
16
+ % for package in packages:
17
+ self.requires("${package}")
18
+ % endfor
19
+ pass
20
+
21
+ def configure(self):
22
+ % if len(pkg.get("requires", {})) > 0:
23
+ % for conan in pkg["requires"].get("compile", []):
24
+ % if conan.get("option") is not None:
25
+ % for k, v in conan.get("option").items():
26
+ self.options["${conan.get("conan").split("/")[0]}"].${k} = ${("\"" + v + "\"") if isinstance(v, str) else str(v)}
27
+ % endfor
28
+ % endif
29
+ % endfor
30
+ <%test_requires=pkg["requires"].get("test", [])%>\
31
+ % if len(test_requires):
32
+ % for conan in test_requires:
33
+ % if conan.get("option") is not None:
34
+ % for k, v in conan.get("option").items():
35
+ self.options["${conan.get("conan").split("/")[0]}"].${k} = ${("\"" + v + "\"") if isinstance(v, str) else str(v)}
36
+ % endfor
37
+ % endif
38
+ % endfor
39
+ % endif
40
+ % endif
41
+ pass
42
+
@@ -1,11 +1,17 @@
1
1
  import os
2
2
  import argparse
3
3
  import textwrap
4
+ import json
5
+ import yaml
6
+ import re
7
+ import requests
4
8
  from colorama import Fore, Style
5
-
9
+ from jsonschema import validate, ValidationError
10
+ from lbkit.errors import PackageConfigException, HttpRequestException
6
11
 
7
12
  LOG_DIR = "/tmp/lbkit/log"
8
13
 
14
+
9
15
  class Color(object):
10
16
  """ Wrapper around colorama colors that are undefined in importing
11
17
  """
@@ -43,3 +49,35 @@ class SmartFormatter(argparse.HelpFormatter):
43
49
  """重写HelpFormatter"""
44
50
  text = textwrap.dedent(text)
45
51
  return ''.join(indent + line for line in text.splitlines(True))
52
+
53
+
54
+ def validate_yml_with_json_schema(yml_file, default_json_schema_file):
55
+ """使用json schema文件校验yml_file配置文件"""
56
+ schema_file = None
57
+ with open(yml_file, "r") as fp:
58
+ for line in fp:
59
+ match = re.search(r"#[ ]*yaml-language-server:[ ]*\$schema=(.*)\n", line)
60
+ if match is not None:
61
+ schema_file = match.group(1)
62
+ break
63
+ if schema_file is None:
64
+ schema_file = default_json_schema_file
65
+ if schema_file.startswith("https://litebmc.com/"):
66
+ resp = requests.get(schema_file)
67
+ if resp.status_code != 200:
68
+ raise HttpRequestException(f"Get {schema_file} failed, status code: {resp.status_code}")
69
+ schema = json.loads(resp.content)
70
+ elif not os.path.isfile(schema_file):
71
+ raise FileNotFoundError(f"schemafile {schema_file} not exist")
72
+ else:
73
+ with open(schema_file, "r") as fp:
74
+ tmp = fp.read()
75
+ schema = json.loads(tmp)
76
+ try:
77
+ fp = open(yml_file, "r")
78
+ data = yaml.safe_load(fp)
79
+ validate(data, schema)
80
+ except ValidationError as exc:
81
+ raise PackageConfigException(f"validate {yml_file} failed, schema file is {schema_file}, "
82
+ f"message: {exc.message}\n"
83
+ "installing redhat.vscode-yaml plugin in vscode will help you write odf files")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: lbkit
3
- Version: 0.5.2
3
+ Version: 0.5.5
4
4
  Summary: Tools provided by litebmc.com
5
5
  Home-page: https://www.litebmc.com
6
6
  Author: xuhj@litebmc.com
@@ -19,5 +19,6 @@ Requires-Dist: jsonschema
19
19
  Requires-Dist: conan==2.1
20
20
  Requires-Dist: requests
21
21
  Requires-Dist: gitpython
22
+ Requires-Dist: inflection
22
23
 
23
24
  build and code generate tools
@@ -6,3 +6,4 @@ jsonschema
6
6
  conan==2.1
7
7
  requests
8
8
  gitpython
9
+ inflection
@@ -19,7 +19,7 @@ setup(
19
19
  description="Tools provided by litebmc.com",
20
20
  long_description="build and code generate tools",
21
21
  long_description_content_type="text/markdown",
22
- install_requires=["pyyaml", "colorama", "mako", "node-semver==0.6.1", "jsonschema", "conan==2.1", "requests", "gitpython"],
22
+ install_requires=["pyyaml", "colorama", "mako", "node-semver==0.6.1", "jsonschema", "conan==2.1", "requests", "gitpython", "inflection"],
23
23
  url="https://www.litebmc.com",
24
24
  packages=find_packages(),
25
25
  include_package_data=True,
@@ -1,2 +0,0 @@
1
-
2
- __version__ = '0.5.2'
@@ -1,113 +0,0 @@
1
- #include "gcl_base.h"
2
- #include "${intf.name}.h"
3
-
4
- <%
5
- class_name = intf.alias
6
- properties = "_" + class_name + "_properties"
7
- signal_processer = "_" + class_name + "_signals"
8
- %>\
9
- static ${class_name}_Properties ${properties};
10
- static const ${class_name}_Signals *${signal_processer} = NULL;
11
-
12
- % for prop in intf.properties:
13
- /* ${prop.description} */
14
- % if prop.deprecated:
15
- __attribute__((__deprecated__)) void ${class_name}_set_${prop.name}(const ${class_name} *object,
16
- ${", ".join(prop.declare()).replace("<arg_name>", "value").replace("<const>", "const ")})
17
- % else:
18
- void ${class_name}_set_${prop.name}(const ${class_name} *object,
19
- ${", ".join(prop.declare()).replace("<arg_name>", "value").replace("<const>", "const ")})
20
- % endif
21
- {
22
- GVariant *tmp = NULL;
23
- % for line in prop.encode_func():
24
- ${line.replace("<arg_out>", "tmp").replace("n_<arg_name>", "n_value").replace("<arg_name>", "value")};
25
- % endfor
26
- gcl_set_value((GclObject *)object, &_${class_name}_properties.${prop.name}, tmp);
27
- g_variant_unref(tmp);
28
- }
29
-
30
- % endfor
31
- % for signal in intf.signals:
32
- /*
33
- * Signal: ${signal.name}
34
- * ${signal.description}
35
- */
36
- % if signal.deprecated:
37
- __attribute__((__deprecated__)) gboolean ${class_name}_${signal.name}_Signal(const ${class_name} *object,
38
- const gchar *destination, const ${class_name}_${signal.name}_Msg *msg, GError **error)
39
- % else:
40
- gboolean ${class_name}_${signal.name}_Signal(const ${class_name} *object, const gchar *destination,
41
- const ${class_name}_${signal.name}_Msg *msg, GError **error)
42
- % endif
43
- {
44
- if (error == NULL) {
45
- log_error("Emit ${signal.name} with parameter error, error is NULL");
46
- return FALSE;
47
- }
48
- if (object == NULL) {
49
- *error = g_error_new(G_DBUS_ERROR, G_DBUS_ERROR_FAILED, "Emit ${signal.name} with parameter error, object is NULL");
50
- return FALSE;
51
- }
52
- return gcl_impl.emit_signal((GclObject *)object, destination,
53
- (const GclSignal *)&${signal_processer}->${signal.name}, msg, error);
54
- }
55
-
56
- % endfor
57
- static GclObject *_${class_name}_create(const gchar *obj_name, gpointer opaque);
58
- /*
59
- * interface: ${intf.name}
60
- % for c in intf.description.split("\n"):
61
- * ${c}
62
- % endfor
63
- */
64
- static GclInterface _${class_name}_interface = {
65
- .create = _${intf.alias}_create,
66
- .is_remote = 0,
67
- .name = "${intf.name}",
68
- .properties = (GclProperty *)&${properties},
69
- .interface = NULL, /* load from usr/share/dbus-1/interfaces/${intf.name} by gcl_init */
70
- };
71
-
72
- /**
73
- * @brief 分配对象
74
- *
75
- * @param obj_name 对象名,需要由调用者分配内存
76
- * @param opaque 上层应用需要写入对象的用户数据,由上层应用使用
77
- */
78
- GclObject *_${class_name}_create(const gchar *obj_name, gpointer opaque)
79
- {
80
- ${class_name} *obj = g_new0(${class_name}, 1);
81
- memcpy(obj->_base.magic, GCL_MAGIC, strlen(GCL_MAGIC) + 1);
82
- obj->_base.lock = g_new0(GRecMutex, 1);
83
- g_rec_mutex_init(obj->_base.lock);
84
- obj->_base.name = obj_name;
85
- obj->_base.intf = &_${class_name}_interface;
86
- obj->_base.opaque = opaque;
87
- return (GclObject *)obj;
88
- }
89
-
90
- GclInterface *${class_name}_interface(void)
91
- {
92
- return &_${class_name}_interface;
93
- }
94
-
95
- ${class_name}_Properties *${class_name}_properties(void)
96
- {
97
- return &${properties};
98
- }
99
-
100
- static void __attribute__((constructor(150))) ${class_name}_register(void)
101
- {
102
- // 从公共库中复制信号处理函数
103
- ${signal_processer} = ${class_name}_signals();
104
- // 从公共库中复制方法处理函数
105
- _${class_name}_interface.methods = (GclMethod *)${class_name}_methods();
106
- _${class_name}_interface.signals = (GclSignal *)${class_name}_signals();
107
-
108
- // 从公共库中复制属性信息
109
- memcpy(&${properties}, ${class_name}_properties_const(), sizeof(${properties}));
110
- gcl_interface_register(&_${class_name}_interface,
111
- "${intf.introspect_xml_sha256}",
112
- "/usr/share/dbus-1/interfaces/${intf.name}.xml");
113
- }
@@ -1,20 +0,0 @@
1
- from conan import ConanFile
2
-
3
-
4
- class DeployConan(ConanFile):
5
- name = "deploy"
6
- settings = "os", "arch", "compiler", "build_type"
7
- description = "部署组件"
8
- url = "https://litebmc.com"
9
- homepage = ""
10
- generators = "CMakeDeps"
11
- package_type = "application"
12
- version = "0.0.1"
13
- license = "MulanPSL v2"
14
-
15
- def requirements(self):
16
- % for package in packages:
17
- self.requires("${package}")
18
- % endfor
19
- pass
20
-
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