lbkit 0.9.6__tar.gz → 0.9.8__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 (68) hide show
  1. {lbkit-0.9.6/lbkit.egg-info → lbkit-0.9.8}/PKG-INFO +1 -1
  2. lbkit-0.9.8/lbkit/__init__.py +2 -0
  3. {lbkit-0.9.6 → lbkit-0.9.8}/lbkit/build_conan_parallel.py +2 -1
  4. {lbkit-0.9.6 → lbkit-0.9.8}/lbkit/codegen/codegen.py +48 -30
  5. {lbkit-0.9.6 → lbkit-0.9.8}/lbkit/codegen/ctype_defination.py +71 -29
  6. {lbkit-0.9.6 → lbkit-0.9.8}/lbkit/codegen/idf_interface.py +39 -7
  7. {lbkit-0.9.6 → lbkit-0.9.8}/lbkit/codegen/template/client.c.mako +1 -1
  8. {lbkit-0.9.6 → lbkit-0.9.8}/lbkit/codegen/template/public.c.mako +8 -2
  9. {lbkit-0.9.6 → lbkit-0.9.8}/lbkit/codegen/template/server.c.mako +49 -2
  10. {lbkit-0.9.6 → lbkit-0.9.8}/lbkit/codegen/template/server.h.mako +125 -0
  11. {lbkit-0.9.6 → lbkit-0.9.8}/lbkit/component/build.py +22 -0
  12. {lbkit-0.9.6 → lbkit-0.9.8}/lbkit/tasks/task_build_prepare.py +43 -3
  13. {lbkit-0.9.6 → lbkit-0.9.8/lbkit.egg-info}/PKG-INFO +1 -1
  14. {lbkit-0.9.6 → lbkit-0.9.8}/test/test_codegen.py +192 -0
  15. lbkit-0.9.6/lbkit/__init__.py +0 -2
  16. {lbkit-0.9.6 → lbkit-0.9.8}/AUTHORS +0 -0
  17. {lbkit-0.9.6 → lbkit-0.9.8}/LICENSE +0 -0
  18. {lbkit-0.9.6 → lbkit-0.9.8}/MANIFEST.in +0 -0
  19. {lbkit-0.9.6 → lbkit-0.9.8}/README.md +0 -0
  20. {lbkit-0.9.6 → lbkit-0.9.8}/lbkit/ci_robot/__init__.py +0 -0
  21. {lbkit-0.9.6 → lbkit-0.9.8}/lbkit/cli.py +0 -0
  22. {lbkit-0.9.6 → lbkit-0.9.8}/lbkit/codegen/__init__.py +0 -0
  23. {lbkit-0.9.6 → lbkit-0.9.8}/lbkit/codegen/renderer.py +0 -0
  24. {lbkit-0.9.6 → lbkit-0.9.8}/lbkit/codegen/template/client.h.mako +0 -0
  25. {lbkit-0.9.6 → lbkit-0.9.8}/lbkit/codegen/template/interface.c.mako +0 -0
  26. {lbkit-0.9.6 → lbkit-0.9.8}/lbkit/codegen/template/interface.introspect.xml.mako +0 -0
  27. {lbkit-0.9.6 → lbkit-0.9.8}/lbkit/codegen/template/public.h.mako +0 -0
  28. {lbkit-0.9.6 → lbkit-0.9.8}/lbkit/component/__init__.py +0 -0
  29. {lbkit-0.9.6 → lbkit-0.9.8}/lbkit/component/arg_parser.py +0 -0
  30. {lbkit-0.9.6 → lbkit-0.9.8}/lbkit/component/template/conanbase.mako +0 -0
  31. {lbkit-0.9.6 → lbkit-0.9.8}/lbkit/component/template/deploy.mako +0 -0
  32. {lbkit-0.9.6 → lbkit-0.9.8}/lbkit/component/test.py +0 -0
  33. {lbkit-0.9.6 → lbkit-0.9.8}/lbkit/errors.py +0 -0
  34. {lbkit-0.9.6 → lbkit-0.9.8}/lbkit/helper.py +0 -0
  35. {lbkit-0.9.6 → lbkit-0.9.8}/lbkit/lbkit.py +0 -0
  36. {lbkit-0.9.6 → lbkit-0.9.8}/lbkit/log.py +0 -0
  37. {lbkit-0.9.6 → lbkit-0.9.8}/lbkit/misc.py +0 -0
  38. {lbkit-0.9.6 → lbkit-0.9.8}/lbkit/tasks/__init__.py +0 -0
  39. {lbkit-0.9.6 → lbkit-0.9.8}/lbkit/tasks/config.py +0 -0
  40. {lbkit-0.9.6 → lbkit-0.9.8}/lbkit/tasks/executor.py +0 -0
  41. {lbkit-0.9.6 → lbkit-0.9.8}/lbkit/tasks/image_maker/__init__.py +0 -0
  42. {lbkit-0.9.6 → lbkit-0.9.8}/lbkit/tasks/image_maker/make_image.py +0 -0
  43. {lbkit-0.9.6 → lbkit-0.9.8}/lbkit/tasks/image_maker/make_qemu_image.py +0 -0
  44. {lbkit-0.9.6 → lbkit-0.9.8}/lbkit/tasks/image_maker/make_rockchip_image.py +0 -0
  45. {lbkit-0.9.6 → lbkit-0.9.8}/lbkit/tasks/task.py +0 -0
  46. {lbkit-0.9.6 → lbkit-0.9.8}/lbkit/tasks/task_build_image.py +0 -0
  47. {lbkit-0.9.6 → lbkit-0.9.8}/lbkit/tasks/task_build_manifest.py +0 -0
  48. {lbkit-0.9.6 → lbkit-0.9.8}/lbkit/tasks/task_build_rootfs.py +0 -0
  49. {lbkit-0.9.6 → lbkit-0.9.8}/lbkit/tasks/task_download.py +0 -0
  50. {lbkit-0.9.6 → lbkit-0.9.8}/lbkit/tasks/template/conanfile.py.mako +0 -0
  51. {lbkit-0.9.6 → lbkit-0.9.8}/lbkit/tasks/template/rootfs.py.mako +0 -0
  52. {lbkit-0.9.6 → lbkit-0.9.8}/lbkit/tools.py +0 -0
  53. {lbkit-0.9.6 → lbkit-0.9.8}/lbkit/ukr/__init__.py +0 -0
  54. {lbkit-0.9.6 → lbkit-0.9.8}/lbkit/ukr/build.py +0 -0
  55. {lbkit-0.9.6 → lbkit-0.9.8}/lbkit/utils/__init__.py +0 -0
  56. {lbkit-0.9.6 → lbkit-0.9.8}/lbkit/utils/env_detector.py +0 -0
  57. {lbkit-0.9.6 → lbkit-0.9.8}/lbkit/utils/images/__init__.py +0 -0
  58. {lbkit-0.9.6 → lbkit-0.9.8}/lbkit/utils/images/emmc.py +0 -0
  59. {lbkit-0.9.6 → lbkit-0.9.8}/lbkit.egg-info/SOURCES.txt +0 -0
  60. {lbkit-0.9.6 → lbkit-0.9.8}/lbkit.egg-info/dependency_links.txt +0 -0
  61. {lbkit-0.9.6 → lbkit-0.9.8}/lbkit.egg-info/entry_points.txt +0 -0
  62. {lbkit-0.9.6 → lbkit-0.9.8}/lbkit.egg-info/requires.txt +0 -0
  63. {lbkit-0.9.6 → lbkit-0.9.8}/lbkit.egg-info/top_level.txt +0 -0
  64. {lbkit-0.9.6 → lbkit-0.9.8}/setup.cfg +0 -0
  65. {lbkit-0.9.6 → lbkit-0.9.8}/setup.py +0 -0
  66. {lbkit-0.9.6 → lbkit-0.9.8}/test/__init__.py +0 -0
  67. {lbkit-0.9.6 → lbkit-0.9.8}/test/test_config.py +0 -0
  68. {lbkit-0.9.6 → lbkit-0.9.8}/test/test_helper.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: lbkit
3
- Version: 0.9.6
3
+ Version: 0.9.8
4
4
  Summary: Tools provided by litebmc.com
5
5
  Home-page: https://www.litebmc.com
6
6
  Author: xuhj@litebmc.com
@@ -0,0 +1,2 @@
1
+
2
+ __version__ = '0.9.8'
@@ -19,7 +19,8 @@ class BuildConanParallel(object):
19
19
  self.lockfile = lockfile
20
20
 
21
21
  def _build_package(self, logfile, build_args, public_args):
22
- cmd = f"conan install {build_args} {public_args} --lockfile={self.lockfile} --lockfile-partial"
22
+ lockfile_out = logfile + ".lock"
23
+ cmd = f"conan install {build_args} {public_args} --lockfile={self.lockfile} --lockfile-out={lockfile_out}"
23
24
  log.info("{}build start: '{}".format(Color.GREEN, Color.RESET_ALL) + cmd + ' log file: ' + logfile)
24
25
  tools.exec(cmd, log_name=logfile, echo_cmd=False)
25
26
  log.info("{}build finished: '{}".format(Color.GREEN, Color.RESET_ALL) + cmd + ' log file: ' + logfile)
@@ -7,6 +7,7 @@ import re
7
7
  import json
8
8
  import yaml
9
9
  import argparse
10
+ from concurrent.futures import ProcessPoolExecutor, as_completed
10
11
  from lbkit.codegen.idf_interface import IdfInterface
11
12
 
12
13
  from mako.lookup import TemplateLookup
@@ -100,43 +101,53 @@ def codegen_version_arg(parser: argparse.ArgumentParser, default=__version__.str
100
101
  parser.add_argument(short_arg, full_arg, help=help, type=str, default=__version__.str)
101
102
 
102
103
 
104
+ def _gen_interface(idf_file, directory=".", code_type="all", codegen_version_str="5.4", log_level="NOTSET"):
105
+ """模块级函数,供多进程调用"""
106
+ directory = os.path.realpath(directory)
107
+ codegen_version = Version(codegen_version_str)
108
+ lookup = TemplateLookup(directories=os.path.join(lb_cwd, "template"))
109
+ interface = IdfInterface(lookup, idf_file, codegen_version, log_level)
110
+ code_types = ["server", "client", "public"]
111
+ if code_type != "all":
112
+ code_types = [code_type]
113
+ for ct in code_types:
114
+ os.makedirs(os.path.join(directory, ct), exist_ok=True)
115
+ out_file = os.path.join(directory, ct, interface.name + ".xml")
116
+ interface.render_dbus_xml("interface.introspect.xml.mako", out_file)
117
+ # 确保生成xml的日志只打印一次
118
+ if ct == "public" or code_type == ct:
119
+ log.info("The sha256sum of interface {} is {}".format(out_file, interface.introspect_xml_sha256))
120
+ out_file = os.path.join(directory, ct, interface.alias + ".h")
121
+ interface.render_c_source(ct + ".h.mako", out_file)
122
+ out_file = os.path.join(directory, ct, interface.alias + ".c")
123
+ interface.render_c_source(ct + ".c.mako", out_file)
124
+ if "server" == ct:
125
+ # 生成接口schema文件
126
+ odf_file = os.path.join(directory, "server", "schema", f"{interface.alias}.json")
127
+ os.makedirs(os.path.dirname(odf_file), exist_ok=True)
128
+ odf_data = interface.odf_schema
129
+ with open(odf_file, "w", encoding="utf-8") as fp:
130
+ json.dump(odf_data, fp, sort_keys=False, indent=4)
131
+ json_file = os.path.join(directory, "package.yml")
132
+ data = {
133
+ "version": interface.version,
134
+ "name": interface.name,
135
+ "alias": interface.alias
136
+ }
137
+ with open(json_file, "w", encoding="utf-8") as fp:
138
+ yaml.dump(data, fp, encoding='utf-8', allow_unicode=True)
139
+
140
+
103
141
  class CodeGen(object):
104
142
  def __init__(self, args):
105
143
  Logger("codegen.log")
106
144
  self.args = args
107
145
  self.codegen_version = __version__
146
+ log.info(f"Codegen version: {self.codegen_version.str}")
108
147
  self.log_level = "NOTSET"
109
148
 
110
149
  def _gen(self, idf_file, directory=".", code_type="all"):
111
- directory = os.path.realpath(directory)
112
- interface = self.get_interface(idf_file)
113
- code_types = ["server", "client", "public"]
114
- if code_type != "all":
115
- code_types = [code_type]
116
- log.info(f"Codegen version: {self.codegen_version.str}")
117
- for ct in code_types:
118
- os.makedirs(os.path.join(directory, ct), exist_ok=True)
119
- out_file = os.path.join(directory, ct, interface.name + ".xml")
120
- interface.render_dbus_xml("interface.introspect.xml.mako", out_file)
121
- out_file = os.path.join(directory, ct, interface.alias + ".h")
122
- interface.render_c_source(ct + ".h.mako", out_file)
123
- out_file = os.path.join(directory, ct, interface.alias + ".c")
124
- interface.render_c_source(ct + ".c.mako", out_file)
125
- if "server" == ct:
126
- # 生成接口schema文件
127
- odf_file = os.path.join(directory, "server", "schema", f"{interface.alias}.json")
128
- os.makedirs(os.path.dirname(odf_file), exist_ok=True)
129
- odf_data = interface.odf_schema
130
- with open(odf_file, "w", encoding="utf-8") as fp:
131
- json.dump(odf_data, fp, sort_keys=False, indent=4)
132
- json_file = os.path.join(directory, "package.yml")
133
- data = {
134
- "version": interface.version,
135
- "name": interface.name,
136
- "alias": interface.alias
137
- }
138
- with open(json_file, "w", encoding="utf-8") as fp:
139
- yaml.dump(data, fp, encoding='utf-8', allow_unicode=True)
150
+ _gen_interface(idf_file, directory, code_type, self.codegen_version.str, self.log_level)
140
151
 
141
152
  def get_interface(self, idf_file):
142
153
  lookup = TemplateLookup(directories=os.path.join(lb_cwd, "template"))
@@ -171,6 +182,8 @@ class CodeGen(object):
171
182
  ver_str = Helper.read_yaml(args.cdf_file, "codegen_version", args.codegen_version)
172
183
  version_check(ver_str)
173
184
  self.codegen_version = Version(ver_str)
185
+ # 校验阶段:顺序检查所有配置项
186
+ gen_tasks = []
174
187
  for cfg in configs:
175
188
  file = cfg.get("file")
176
189
  if file is None:
@@ -183,7 +196,12 @@ class CodeGen(object):
183
196
  log.error("%s的自动代码生成配置不正确, %s不是一个文件", args.cdf_file, file)
184
197
  sys.exit(-1)
185
198
  outdir = cfg.get("outdir", os.getcwd())
186
- self._gen(file, outdir)
199
+ gen_tasks.append((file, outdir))
200
+ # 并行生成阶段
201
+ with ProcessPoolExecutor(max_workers=os.cpu_count()) as executor:
202
+ futures = {executor.submit(_gen_interface, file, outdir, "all", self.codegen_version.str, self.log_level): file for file, outdir in gen_tasks}
203
+ for future in as_completed(futures):
204
+ future.result()
187
205
  return
188
206
  else:
189
207
  ver_str = os.environ.get("CODEGEN_VERSION")
@@ -694,7 +694,8 @@ class CTypeBase(object):
694
694
  validator: IdfValidator = None,
695
695
  const_declare = None,
696
696
  const_free_func = None,
697
- const_decode_func = None):
697
+ const_decode_func = None,
698
+ copy_func = None):
698
699
  self.declare = declare
699
700
  # 作为函数出参时的变量申明
700
701
  self.out_declare = out_declare
@@ -712,9 +713,19 @@ class CTypeBase(object):
712
713
  self.const_free_func = self.free_func
713
714
  if const_decode_func is None:
714
715
  self.const_decode_func = self.decode_func
716
+ # 直接复制数据的C代码,用于server端属性getter函数
717
+ # 占位符: <src>=源, <dst>=目标指针, <n_src>=源数组长度, <n_dst>=目标数组长度指针
718
+ self.copy_func = copy_func if copy_func is not None else []
715
719
 
716
720
 
717
721
  """定义支持的C语言类型"""
722
+ # 值类型直接复制模板
723
+ _COPY_VALUE = ["*<dst> = <src>"]
724
+ # 字符串类型复制模板
725
+ _COPY_STRING = ["*<dst> = g_strdup(<src>)"]
726
+ # variant类型复制模板
727
+ _COPY_VARIANT = ["*<dst> = g_variant_ref(<src>)"]
728
+
718
729
  CTYPE_OBJS = {
719
730
  "boolean": CTypeBase(
720
731
  ["gboolean <arg_name>"],
@@ -722,7 +733,8 @@ CTYPE_OBJS = {
722
733
  [],
723
734
  ["<arg_out> = g_variant_new_boolean(<arg_name>)"],
724
735
  ["<arg_in> = g_variant_get_boolean(<arg_name>)"],
725
- BoolValidator("boolean")
736
+ BoolValidator("boolean"),
737
+ copy_func=_COPY_VALUE
726
738
  ),
727
739
  "byte": CTypeBase(
728
740
  ["guint8 <arg_name>"],
@@ -730,7 +742,8 @@ CTYPE_OBJS = {
730
742
  [],
731
743
  ["<arg_out> = g_variant_new_byte(<arg_name>)"],
732
744
  ["<arg_in> = g_variant_get_byte(<arg_name>)"],
733
- IntegerValidator("uint8", 0xff, 0)
745
+ IntegerValidator("uint8", 0xff, 0),
746
+ copy_func=_COPY_VALUE
734
747
  ),
735
748
  "int16": CTypeBase(
736
749
  ["gint16 <arg_name>"],
@@ -738,7 +751,8 @@ CTYPE_OBJS = {
738
751
  [],
739
752
  ["<arg_out> = g_variant_new_int16(<arg_name>)"],
740
753
  ["<arg_in> = g_variant_get_int16(<arg_name>)"],
741
- IntegerValidator("int16", 0x7fff, -(0x8000), True)
754
+ IntegerValidator("int16", 0x7fff, -(0x8000), True),
755
+ copy_func=_COPY_VALUE
742
756
  ),
743
757
  "uint16": CTypeBase(
744
758
  ["guint16 <arg_name>"],
@@ -746,7 +760,8 @@ CTYPE_OBJS = {
746
760
  [],
747
761
  ["<arg_out> = g_variant_new_uint16(<arg_name>)"],
748
762
  ["<arg_in> = g_variant_get_uint16(<arg_name>)"],
749
- IntegerValidator("uint16", 0xffff, 0)
763
+ IntegerValidator("uint16", 0xffff, 0),
764
+ copy_func=_COPY_VALUE
750
765
  ),
751
766
  "int32": CTypeBase(
752
767
  ["gint32 <arg_name>"],
@@ -754,7 +769,8 @@ CTYPE_OBJS = {
754
769
  [],
755
770
  ["<arg_out> = g_variant_new_int32(<arg_name>)"],
756
771
  ["<arg_in> = g_variant_get_int32(<arg_name>)"],
757
- IntegerValidator("int32", 0x7fff_ffff, -(0x8000_0000), True)
772
+ IntegerValidator("int32", 0x7fff_ffff, -(0x8000_0000), True),
773
+ copy_func=_COPY_VALUE
758
774
  ),
759
775
  "uint32": CTypeBase(
760
776
  ["guint32 <arg_name>"],
@@ -762,7 +778,8 @@ CTYPE_OBJS = {
762
778
  [],
763
779
  ["<arg_out> = g_variant_new_uint32(<arg_name>)"],
764
780
  ["<arg_in> = g_variant_get_uint32(<arg_name>)"],
765
- IntegerValidator("uint32", 0xffff_ffff, 0)
781
+ IntegerValidator("uint32", 0xffff_ffff, 0),
782
+ copy_func=_COPY_VALUE
766
783
  ),
767
784
  "int64": CTypeBase(
768
785
  ["gint64 <arg_name>"],
@@ -770,7 +787,8 @@ CTYPE_OBJS = {
770
787
  [],
771
788
  ["<arg_out> = g_variant_new_int64(<arg_name>)"],
772
789
  ["<arg_in> = g_variant_get_int64(<arg_name>)"],
773
- IntegerValidator("int64", 0x7fff_ffff_ffff_ffff, -(0x8000_0000_0000_0000), True)
790
+ IntegerValidator("int64", 0x7fff_ffff_ffff_ffff, -(0x8000_0000_0000_0000), True),
791
+ copy_func=_COPY_VALUE
774
792
  ),
775
793
  "uint64": CTypeBase(
776
794
  ["guint64 <arg_name>"],
@@ -778,7 +796,8 @@ CTYPE_OBJS = {
778
796
  [],
779
797
  ["<arg_out> = g_variant_new_uint64(<arg_name>)"],
780
798
  ["<arg_in> = g_variant_get_uint64(<arg_name>)"],
781
- IntegerValidator("uint64", 0xffff_ffff_ffff_ffff, 0)
799
+ IntegerValidator("uint64", 0xffff_ffff_ffff_ffff, 0),
800
+ copy_func=_COPY_VALUE
782
801
  ),
783
802
  "size": CTypeBase(
784
803
  ["gsize <arg_name>"],
@@ -786,7 +805,8 @@ CTYPE_OBJS = {
786
805
  [],
787
806
  ["<arg_out> = g_variant_new_tsize(<arg_name>)"],
788
807
  ["<arg_in> = g_variant_get_tsize(<arg_name>)"],
789
- IntegerValidator("size", 0xffff_ffff_ffff_ffff, 0)
808
+ IntegerValidator("size", 0xffff_ffff_ffff_ffff, 0),
809
+ copy_func=_COPY_VALUE
790
810
  ),
791
811
  "ssize": CTypeBase(
792
812
  ["gssize <arg_name>"],
@@ -794,7 +814,8 @@ CTYPE_OBJS = {
794
814
  [],
795
815
  ["<arg_out> = g_variant_new_tssize(<arg_name>)"],
796
816
  ["<arg_in> = g_variant_get_tssize(<arg_name>)"],
797
- IntegerValidator("ssize", 0x7fff_ffff_ffff_ffff, -(0x8000_0000_0000_0000), True)
817
+ IntegerValidator("ssize", 0x7fff_ffff_ffff_ffff, -(0x8000_0000_0000_0000), True),
818
+ copy_func=_COPY_VALUE
798
819
  ),
799
820
  "double": CTypeBase(
800
821
  ["gdouble <arg_name>"],
@@ -802,7 +823,8 @@ CTYPE_OBJS = {
802
823
  [],
803
824
  ["<arg_out> = g_variant_new_double(<arg_name>)"],
804
825
  ["<arg_in> = g_variant_get_double(<arg_name>)"],
805
- FloatValidator("double")
826
+ FloatValidator("double"),
827
+ copy_func=_COPY_VALUE
806
828
  ),
807
829
  "unixfd": CTypeBase(
808
830
  ["gint32 <arg_name>"],
@@ -810,7 +832,8 @@ CTYPE_OBJS = {
810
832
  [],
811
833
  ["<arg_out> = g_variant_new_handle(<arg_name>)"],
812
834
  ["<arg_in> = g_variant_get_handle(<arg_name>)"],
813
- IntegerValidator("int32", 0x7fff_ffff_ffff_ffff, 0, True)
835
+ IntegerValidator("int32", 0x7fff_ffff_ffff_ffff, 0, True),
836
+ copy_func=_COPY_VALUE
814
837
  ),
815
838
  "string": CTypeBase(
816
839
  ["<const>gchar *<arg_name>"],
@@ -822,6 +845,7 @@ CTYPE_OBJS = {
822
845
  ["const gchar *<arg_name>"],
823
846
  [],
824
847
  ["<arg_in> = g_variant_get_string(<arg_name>, NULL)"],
848
+ copy_func=_COPY_STRING
825
849
  ),
826
850
  "object_path": CTypeBase(
827
851
  ["<const>gchar *<arg_name>"],
@@ -833,6 +857,7 @@ CTYPE_OBJS = {
833
857
  ["const gchar *<arg_name>"],
834
858
  [],
835
859
  ["<arg_in> = g_variant_get_string(<arg_name>, NULL)"],
860
+ copy_func=_COPY_STRING
836
861
  ),
837
862
  "signature": CTypeBase(
838
863
  ["<const>gchar *<arg_name>"],
@@ -844,6 +869,7 @@ CTYPE_OBJS = {
844
869
  ["const gchar *<arg_name>"],
845
870
  [],
846
871
  ["<arg_in> = g_variant_get_string(<arg_name>, NULL)"],
872
+ copy_func=_COPY_STRING
847
873
  ),
848
874
  "variant": CTypeBase(
849
875
  ["GVariant *<arg_name>"],
@@ -851,7 +877,8 @@ CTYPE_OBJS = {
851
877
  ["lb_unref_p((GVariant **)&<arg_name>)"],
852
878
  ["g_variant_take_ref(<arg_name>)", "<arg_out> = g_variant_new_variant(<arg_name>)"],
853
879
  ["<arg_in> = g_variant_get_variant(<arg_name>)"],
854
- IdfValidator(None)
880
+ IdfValidator(None),
881
+ copy_func=_COPY_VARIANT
855
882
  ),
856
883
  "array[boolean]": CTypeBase(
857
884
  ["gsize n_<arg_name>" ,"<const>gboolean *<arg_name>"],
@@ -859,7 +886,8 @@ CTYPE_OBJS = {
859
886
  ["lb_free_p((void **)&<arg_name>)"],
860
887
  ["<arg_out> = lb_array_boolean_encode(<arg_name>, n_<arg_name>)"],
861
888
  ["<arg_in> = lb_array_boolean_decode(<arg_name>, &n_<arg_in>)"],
862
- BoolArrayValidator("boolean")
889
+ BoolArrayValidator("boolean"),
890
+ copy_func=["*<n_dst> = <n_src>", "*<dst> = g_memdup2(<src>, sizeof(gboolean) * <n_src>)"]
863
891
  ),
864
892
  "array[byte]": CTypeBase(
865
893
  ["gsize n_<arg_name>" ,"<const>guint8 *<arg_name>"],
@@ -867,7 +895,8 @@ CTYPE_OBJS = {
867
895
  ["lb_free_p((void **)&<arg_name>)"],
868
896
  ["<arg_out> = lb_array_byte_encode(<arg_name>, n_<arg_name>)"],
869
897
  ["<arg_in> = lb_array_byte_decode(<arg_name>, &n_<arg_in>)"],
870
- IntegerArrayValidator("uint8", 0xff, 0)
898
+ IntegerArrayValidator("uint8", 0xff, 0),
899
+ copy_func=["*<n_dst> = <n_src>", "*<dst> = g_memdup2(<src>, sizeof(guint8) * <n_src>)"]
871
900
  ),
872
901
  "array[int16]": CTypeBase(
873
902
  ["gsize n_<arg_name>" ,"<const>gint16 *<arg_name>"],
@@ -875,7 +904,8 @@ CTYPE_OBJS = {
875
904
  ["lb_free_p((void **)&<arg_name>)"],
876
905
  ["<arg_out> = lb_array_int16_encode(<arg_name>, n_<arg_name>)"],
877
906
  ["<arg_in> = lb_array_int16_decode(<arg_name>, &n_<arg_in>)"],
878
- IntegerArrayValidator("int16", 0x7fff, -(0x8000), True)
907
+ IntegerArrayValidator("int16", 0x7fff, -(0x8000), True),
908
+ copy_func=["*<n_dst> = <n_src>", "*<dst> = g_memdup2(<src>, sizeof(gint16) * <n_src>)"]
879
909
  ),
880
910
  "array[uint16]": CTypeBase(
881
911
  ["gsize n_<arg_name>" ,"<const>guint16 *<arg_name>"],
@@ -883,7 +913,8 @@ CTYPE_OBJS = {
883
913
  ["lb_free_p((void **)&<arg_name>)"],
884
914
  ["<arg_out> = lb_array_uint16_encode(<arg_name>, n_<arg_name>)"],
885
915
  ["<arg_in> = lb_array_uint16_decode(<arg_name>, &n_<arg_in>)"],
886
- IntegerArrayValidator("uint16", 0xffff, 0)
916
+ IntegerArrayValidator("uint16", 0xffff, 0),
917
+ copy_func=["*<n_dst> = <n_src>", "*<dst> = g_memdup2(<src>, sizeof(guint16) * <n_src>)"]
887
918
  ),
888
919
  "array[int32]": CTypeBase(
889
920
  ["gsize n_<arg_name>" ,"<const>gint32 *<arg_name>"],
@@ -891,7 +922,8 @@ CTYPE_OBJS = {
891
922
  ["lb_free_p((void **)&<arg_name>)"],
892
923
  ["<arg_out> = lb_array_int32_encode(<arg_name>, n_<arg_name>)"],
893
924
  ["<arg_in> = lb_array_int32_decode(<arg_name>, &n_<arg_in>)"],
894
- IntegerArrayValidator("int32", 0x7fff_ffff, -(0x80000000), True)
925
+ IntegerArrayValidator("int32", 0x7fff_ffff, -(0x80000000), True),
926
+ copy_func=["*<n_dst> = <n_src>", "*<dst> = g_memdup2(<src>, sizeof(gint32) * <n_src>)"]
895
927
  ),
896
928
  "array[uint32]": CTypeBase(
897
929
  ["gsize n_<arg_name>" ,"<const>guint32 *<arg_name>"],
@@ -899,7 +931,8 @@ CTYPE_OBJS = {
899
931
  ["lb_free_p((void **)&<arg_name>)"],
900
932
  ["<arg_out> = lb_array_uint32_encode(<arg_name>, n_<arg_name>)"],
901
933
  ["<arg_in> = lb_array_uint32_decode(<arg_name>, &n_<arg_in>)"],
902
- IntegerArrayValidator("uint32", 0xffff_ffff, 0)
934
+ IntegerArrayValidator("uint32", 0xffff_ffff, 0),
935
+ copy_func=["*<n_dst> = <n_src>", "*<dst> = g_memdup2(<src>, sizeof(guint32) * <n_src>)"]
903
936
  ),
904
937
  "array[int64]": CTypeBase(
905
938
  ["gsize n_<arg_name>" ,"<const>gint64 *<arg_name>"],
@@ -907,7 +940,8 @@ CTYPE_OBJS = {
907
940
  ["lb_free_p((void **)&<arg_name>)"],
908
941
  ["<arg_out> = lb_array_int64_encode(<arg_name>, n_<arg_name>)"],
909
942
  ["<arg_in> = lb_array_int64_decode(<arg_name>, &n_<arg_in>)"],
910
- IntegerArrayValidator("int64", 0x7fff_ffff_ffff_ffff, -(0x8000_0000_0000_0000), True)
943
+ IntegerArrayValidator("int64", 0x7fff_ffff_ffff_ffff, -(0x8000_0000_0000_0000), True),
944
+ copy_func=["*<n_dst> = <n_src>", "*<dst> = g_memdup2(<src>, sizeof(gint64) * <n_src>)"]
911
945
  ),
912
946
  "array[uint64]": CTypeBase(
913
947
  ["gsize n_<arg_name>" ,"<const>guint64 *<arg_name>"],
@@ -915,7 +949,8 @@ CTYPE_OBJS = {
915
949
  ["lb_free_p((void **)&<arg_name>)"],
916
950
  ["<arg_out> = lb_array_uint64_encode(<arg_name>, n_<arg_name>)"],
917
951
  ["<arg_in> = lb_array_uint64_decode(<arg_name>, &n_<arg_in>)"],
918
- IntegerArrayValidator("uint64",0xffff_ffff_ffff_ffff, 0)
952
+ IntegerArrayValidator("uint64",0xffff_ffff_ffff_ffff, 0),
953
+ copy_func=["*<n_dst> = <n_src>", "*<dst> = g_memdup2(<src>, sizeof(guint64) * <n_src>)"]
919
954
  ),
920
955
  "array[ssize]": CTypeBase(
921
956
  ["gsize n_<arg_name>" ,"<const>gssize *<arg_name>"],
@@ -923,7 +958,8 @@ CTYPE_OBJS = {
923
958
  ["lb_free_p((void **)&<arg_name>)"],
924
959
  ["<arg_out> = lb_array_ssize_encode(<arg_name>, n_<arg_name>)"],
925
960
  ["<arg_in> = lb_array_ssize_decode(<arg_name>, &n_<arg_in>)"],
926
- IntegerArrayValidator("ssize",0x7fff_ffff_ffff_ffff, -(0x8000_0000_0000_0000), True)
961
+ IntegerArrayValidator("ssize",0x7fff_ffff_ffff_ffff, -(0x8000_0000_0000_0000), True),
962
+ copy_func=["*<n_dst> = <n_src>", "*<dst> = g_memdup2(<src>, sizeof(gssize) * <n_src>)"]
927
963
  ),
928
964
  "array[size]": CTypeBase(
929
965
  ["gsize n_<arg_name>" ,"<const>gsize *<arg_name>"],
@@ -931,7 +967,8 @@ CTYPE_OBJS = {
931
967
  ["lb_free_p((void **)&<arg_name>)"],
932
968
  ["<arg_out> = lb_array_size_encode(<arg_name>, n_<arg_name>)"],
933
969
  ["<arg_in> = lb_array_size_decode(<arg_name>, &n_<arg_in>)"],
934
- IntegerArrayValidator("size", 0xffff_ffff_ffff_ffff, 0)
970
+ IntegerArrayValidator("size", 0xffff_ffff_ffff_ffff, 0),
971
+ copy_func=["*<n_dst> = <n_src>", "*<dst> = g_memdup2(<src>, sizeof(gsize) * <n_src>)"]
935
972
  ),
936
973
  "array[double]": CTypeBase(
937
974
  ["gsize n_<arg_name>" ,"<const>gdouble *<arg_name>"],
@@ -939,7 +976,8 @@ CTYPE_OBJS = {
939
976
  ["lb_free_p((void **)&<arg_name>)"],
940
977
  ["<arg_out> = lb_array_double_encode(<arg_name>, n_<arg_name>)"],
941
978
  ["<arg_in> = lb_array_double_decode(<arg_name>, &n_<arg_in>)"],
942
- FloatArrayValidator("double")
979
+ FloatArrayValidator("double"),
980
+ copy_func=["*<n_dst> = <n_src>", "*<dst> = g_memdup2(<src>, sizeof(gdouble) * <n_src>)"]
943
981
  ),
944
982
  "array[unixfd]": CTypeBase(
945
983
  ["gsize n_<arg_name>" ,"<const>gint32 *<arg_name>"],
@@ -947,7 +985,8 @@ CTYPE_OBJS = {
947
985
  ["lb_free_p((void **)&<arg_name>)"],
948
986
  ["<arg_out> = lb_array_handle_encode(<arg_name>, n_<arg_name>)"],
949
987
  ["<arg_in> = lb_array_handle_decode(<arg_name>, &n_<arg_in>)"],
950
- IntegerArrayValidator("int32", 0x7fff_ffff_ffff_ffff, 0, True)
988
+ IntegerArrayValidator("int32", 0x7fff_ffff_ffff_ffff, 0, True),
989
+ copy_func=["*<n_dst> = <n_src>", "*<dst> = g_memdup2(<src>, sizeof(gint32) * <n_src>)"]
951
990
  ),
952
991
  "array[string]": CTypeBase(
953
992
  ["gchar *<const>*<arg_name>"],
@@ -955,7 +994,8 @@ CTYPE_OBJS = {
955
994
  ["lb_strfreev_p(&<arg_name>)"],
956
995
  ["<arg_out> = lb_array_string_encode(<arg_name>)"],
957
996
  ["<arg_in> = lb_array_string_decode(<arg_name>)"],
958
- StringArrayValidator("string", "")
997
+ StringArrayValidator("string", ""),
998
+ copy_func=["*<dst> = g_strdupv(<src>)"]
959
999
  ),
960
1000
  "array[object_path]": CTypeBase(
961
1001
  ["gchar *<const>*<arg_name>"],
@@ -963,7 +1003,8 @@ CTYPE_OBJS = {
963
1003
  ["lb_strfreev_p(&<arg_name>)"],
964
1004
  ["<arg_out> = lb_array_object_path_encode(<arg_name>)"],
965
1005
  ["<arg_in> = lb_array_object_path_decode(<arg_name>)"],
966
- StringArrayValidator("string", "^(/[A-Z0-9a-z_]+)*$")
1006
+ StringArrayValidator("string", "^(/[A-Z0-9a-z_]+)*$"),
1007
+ copy_func=["*<dst> = g_strdupv(<src>)"]
967
1008
  ),
968
1009
  "array[signature]": CTypeBase(
969
1010
  ["gchar *<const>*<arg_name>"],
@@ -971,6 +1012,7 @@ CTYPE_OBJS = {
971
1012
  ["lb_strfreev_p(&<arg_name>)"],
972
1013
  ["<arg_out> = lb_array_signature_encode(<arg_name>)"],
973
1014
  ["<arg_in> = lb_array_signature_decode(<arg_name>)"],
974
- StringArrayValidator("string", "^([abynqiuxtdsogvh\\\\{\\\\}\\\\(\\\\)])+$")
1015
+ StringArrayValidator("string", "^([abynqiuxtdsogvh\\\\{\\\\}\\\\(\\\\)])+$"),
1016
+ copy_func=["*<dst> = g_strdupv(<src>)"]
975
1017
  )
976
1018
  }
@@ -12,7 +12,6 @@ from lbkit.errors import OdfValidateException, LiteBmcException
12
12
  from lbkit.helper import SigInvalidException, validate_glib_signature
13
13
 
14
14
  log = Logger()
15
- alias = None
16
15
 
17
16
  class IDFException(Exception):
18
17
  pass
@@ -41,6 +40,7 @@ class IdfInterfaceBase(Renderer):
41
40
  self.name = None
42
41
  self.object_path = None
43
42
  self.codegen_version = None
43
+ self.introspect_xml_sha256 = None
44
44
 
45
45
  class IdfAnnotation():
46
46
  def __init__(self, name, value):
@@ -541,6 +541,36 @@ class IdfCtypeRender():
541
541
  else:
542
542
  return [f"<arg_in> = {stru_name}_decode(<arg_name>)"]
543
543
 
544
+ def copy_func(self):
545
+ """生成直接复制数据的C代码,用于server端属性getter函数
546
+ 返回None表示该类型需要通过GVariant编解码进行深拷贝
547
+ 占位符: <src>=源(obj->prop), <dst>=目标指针(value), <n_src>=源数组长度, <n_dst>=目标数组长度指针
548
+ """
549
+ # 基础类型(含数组和variant)
550
+ match = re.match(f"^array\[({CTYPE_BASE_REG})\]$", self.ctype)
551
+ if match:
552
+ return CTYPE_OBJS.get(self.ctype).copy_func
553
+ match = re.match(f"^({CTYPE_REGEX})$", self.ctype)
554
+ if match:
555
+ return CTYPE_OBJS.get(self.ctype).copy_func
556
+ # 非基础类型
557
+ is_array = False
558
+ ctype = self.ctype
559
+ match = re.match(f"^array\[(.*)\]$", ctype)
560
+ if match:
561
+ is_array = True
562
+ ctype = match.group(1)
563
+ # 枚举类型可以直接复制
564
+ match = re.match(f"^enum\[(.*)\]$", ctype)
565
+ if match:
566
+ _, stru_name = get_intfname_and_ctype(self.intf.alias, match.group(1))
567
+ if is_array:
568
+ return ["*<n_dst> = <n_src>", f"*<dst> = g_memdup2(<src>, sizeof({stru_name}) * <n_src>)"]
569
+ else:
570
+ return ["*<dst> = <src>"]
571
+ # 结构体和字典类型需要通过GVariant编解码进行深拷贝
572
+ return None
573
+
544
574
  def const_declare(self):
545
575
  """常量申明,用于方法请求和信号消息结构体顶层成员申明"""
546
576
  log.debug(f"Get const_declare info, name: {self.name}, ctype: {self.ctype}")
@@ -1270,8 +1300,6 @@ class IdfInterface(IdfInterfaceBase):
1270
1300
  log.debug(f"validate {self.file} successfully")
1271
1301
  self.version = idf.get("version")
1272
1302
  self.description = idf.get("description", "")
1273
- global alias
1274
- alias = self.alias
1275
1303
  # 注释
1276
1304
  flags = idf.get("flags", "").split(",")
1277
1305
  for k, v in ANNOTATION_MAP.items():
@@ -1291,7 +1319,7 @@ class IdfInterface(IdfInterfaceBase):
1291
1319
  items = idf.get("structures", [])
1292
1320
  for item in items:
1293
1321
  obj = IdfStructure(self, item)
1294
- obj.name = alias + "_" + obj.name
1322
+ obj.name = self.alias + "_" + obj.name
1295
1323
  self.structures[obj.name] = obj
1296
1324
  items = idf.get("errors", [])
1297
1325
  for item in items:
@@ -1301,12 +1329,12 @@ class IdfInterface(IdfInterfaceBase):
1301
1329
  items = idf.get("dictionaries", [])
1302
1330
  for item in items:
1303
1331
  obj = IdfDictionary(self, item)
1304
- obj.name = alias + "_" + obj.name
1332
+ obj.name = self.alias + "_" + obj.name
1305
1333
  self.dictionaries[obj.name] = obj
1306
1334
  items = idf.get("enumerations", [])
1307
1335
  for item in items:
1308
1336
  obj = IdfEnumeration(self, item)
1309
- obj.name = alias + "_" + obj.name
1337
+ obj.name = self.alias + "_" + obj.name
1310
1338
  self.enumerations[obj.name] = obj
1311
1339
  plugin = idf.get("plugin", None)
1312
1340
  self.plugin = IdfInterfacePlugin()
@@ -1325,7 +1353,11 @@ class IdfInterface(IdfInterfaceBase):
1325
1353
  hash = hashlib.sha256()
1326
1354
  hash.update(out.encode('utf-8'))
1327
1355
  self.introspect_xml_sha256 = hash.hexdigest()
1328
- log.info("The sha256sum of interface {} is {}".format(out_file, self.introspect_xml_sha256))
1356
+ # TODO: 2026-10-19 删除此兼容写法,仅保留带 sha256 后缀的输出
1357
+ with open(out_file, "w") as fd:
1358
+ fd.write(out)
1359
+ base, ext = os.path.splitext(out_file)
1360
+ out_file = f"{base}-{self.introspect_xml_sha256[:6]}{ext}"
1329
1361
  with open(out_file, "w") as fd:
1330
1362
  fd.write(out)
1331
1363
 
@@ -322,7 +322,7 @@ static void __constructor(150) ${class_name}_register(void)
322
322
  _${class_name}_interface.signals = (LBSignal *)${intf.alias}_signals();
323
323
  ${method_processer} = ${intf.alias}_methods();
324
324
 
325
- // 从公共库中复制属性信息
325
+ // 从公共库中复制属性信息。虽然生成了带sha值的xml文件,但注册接口时文件名不带sha,由lb_base在加载时自动兼容
326
326
  memcpy(&${properties}, ${intf.alias}_properties_const(), sizeof(${properties}));
327
327
  lb_interface_register(&_${class_name}_interface,
328
328
  "${intf.introspect_xml_sha256}",
@@ -930,23 +930,29 @@ static gboolean ${class_name}_check_${prop.name}_variant(LBO *obj, GVariant *val
930
930
  static void ${class_name}_set_${prop.name}_variant(LBO *obj, GVariant *value)
931
931
  {
932
932
  g_assert(value && obj);
933
- struct _${class_name} *real_obj = (struct _${class_name} *)_get_real_object(obj);
933
+ LBBase *base = _get_real_object(obj);
934
+ struct _${class_name} *real_obj = (struct _${class_name} *)base;
935
+ g_rec_mutex_lock(base->lock);
934
936
  % for line in prop.free_func():
935
937
  ${line.replace("<arg_name>", "real_obj->" + prop.name)};
936
938
  % endfor
937
939
  % for line in prop.decode_func():
938
940
  ${line.replace("n_<arg_in>", "real_obj->n_" + prop.name).replace("<arg_in>", "real_obj->" + prop.name).replace("<arg_name>", "value")};
939
941
  % endfor
942
+ g_rec_mutex_unlock(base->lock);
940
943
  }
941
944
 
942
945
  static GVariant *${class_name}_get_${prop.name}_variant(LBO *obj)
943
946
  {
944
947
  g_assert(obj);
945
948
  GVariant *out = NULL;
946
- struct _${class_name} *real_obj = (struct _${class_name} *)_get_real_object(obj);
949
+ LBBase *base = _get_real_object(obj);
950
+ struct _${class_name} *real_obj = (struct _${class_name} *)base;
951
+ g_rec_mutex_lock(base->lock);
947
952
  % for line in prop.encode_func():
948
953
  ${line.replace("<arg_out>", "out").replace("n_<arg_name>", "real_obj->n_" + prop.name).replace("<arg_name>", "real_obj->" + prop.name)};
949
954
  % endfor
955
+ g_rec_mutex_unlock(base->lock);
950
956
  return out;
951
957
  }
952
958