• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3# Copyright (c) 2024 Huawei Device Co., Ltd.
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8#     http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15import subprocess
16import sys
17import stat
18import os
19import argparse
20import shutil
21import json
22import time
23import re
24import urllib.request
25
26
27def _get_args():
28    parser = argparse.ArgumentParser(add_help=True)
29    parser.add_argument("-op", "--out_path", default=r"./", type=str,
30                        help="path of out.", )
31    parser.add_argument("-rp", "--root_path", default=r"./", type=str,
32                        help="path of root. default: ./", )
33    parser.add_argument("-cl", "--components_list", default="", type=str,
34                        help="components_list , "
35                             "pass in the components' name, separated by commas , "
36                             "example: A,B,C . "
37                             "default: none", )
38    parser.add_argument("-bt", "--build_type", default=0, type=int,
39                        help="build_type ,default: 0", )
40    parser.add_argument("-on", "--organization_name", default='ohos', type=str,
41                        help="organization_name ,default: '' ", )
42    parser.add_argument("-os", "--os_arg", default=r"linux", type=str,
43                        help="path of output file. default: linux", )
44    parser.add_argument("-ba", "--build_arch", default=r"x86", type=str,
45                        help="build_arch_arg. default: x86", )
46    parser.add_argument("-lt", "--local_test", default=0, type=int,
47                        help="local test ,default: not local , 0", )
48    args = parser.parse_args()
49    return args
50
51
52def create_directories(paths):
53    for path in paths:
54        os.makedirs(path, exist_ok=True)
55
56
57def copy_files(src_dst_pairs):
58    for src, dst in src_dst_pairs:
59        shutil.copy2(src, dst)
60
61
62def generate_common_configs():
63    return """import("//build/ohos.gni")
64
65
66config("musl_common_configs") {
67  visibility = [ ":*" ]
68  include_dirs = [
69    "//prebuilts/clang/ohos/linux-x86_64/15.0.4/llvm/include",
70    "//prebuilts/clang/ohos/linux-x86_64/15.0.4/llvm/include/c++/v1",
71    "//prebuilts/clang/ohos/linux-x86_64/15.0.4/llvm/include/c++/v1/__algorithm",
72    "//prebuilts/clang/ohos/linux-x86_64/15.0.4/llvm/include/c++/v1/__bit",
73    "//prebuilts/clang/ohos/linux-x86_64/15.0.4/llvm/include/c++/v1/__charconv",
74    "//prebuilts/clang/ohos/linux-x86_64/15.0.4/llvm/include/c++/v1/__chrono",
75    "//prebuilts/clang/ohos/linux-x86_64/15.0.4/llvm/include/c++/v1/__compare",
76    "//prebuilts/clang/ohos/linux-x86_64/15.0.4/llvm/include/c++/v1/__concepts",
77    "//prebuilts/clang/ohos/linux-x86_64/15.0.4/llvm/include/c++/v1/__debug_utils",
78    "//prebuilts/clang/ohos/linux-x86_64/15.0.4/llvm/include/c++/v1/__concepts",
79    "//prebuilts/clang/ohos/linux-x86_64/15.0.4/llvm/include/c++/v1/__filesystem",
80    "//prebuilts/clang/ohos/linux-x86_64/15.0.4/llvm/include/c++/v1/__format",
81    "//prebuilts/clang/ohos/linux-x86_64/15.0.4/llvm/include/c++/v1/__functional",
82    "//prebuilts/clang/ohos/linux-x86_64/15.0.4/llvm/include/c++/v1/__fwd",
83    "//prebuilts/clang/ohos/linux-x86_64/15.0.4/llvm/include/c++/v1/__ios",
84    "//prebuilts/clang/ohos/linux-x86_64/15.0.4/llvm/include/c++/v1/__iterator",
85    "//prebuilts/clang/ohos/linux-x86_64/15.0.4/llvm/include/c++/v1/__memory",
86    "//prebuilts/clang/ohos/linux-x86_64/15.0.4/llvm/include/c++/v1/__numeric",
87    "//prebuilts/clang/ohos/linux-x86_64/15.0.4/llvm/include/c++/v1/__random",
88    "//prebuilts/clang/ohos/linux-x86_64/15.0.4/llvm/include/c++/v1/__ranges",
89    "//prebuilts/clang/ohos/linux-x86_64/15.0.4/llvm/include/c++/v1/__string",
90    "//prebuilts/clang/ohos/linux-x86_64/15.0.4/llvm/include/c++/v1/__support",
91    "//prebuilts/clang/ohos/linux-x86_64/15.0.4/llvm/include/c++/v1/__thread",
92    "//prebuilts/clang/ohos/linux-x86_64/15.0.4/llvm/include/c++/v1/__type_traits",
93    "//prebuilts/clang/ohos/linux-x86_64/15.0.4/llvm/include/c++/v1/__utility",
94    "//prebuilts/clang/ohos/linux-x86_64/15.0.4/llvm/include/c++/v1/__variant",
95    "//prebuilts/clang/ohos/linux-x86_64/15.0.4/llvm/include/c++/v1/experimental",
96    "//prebuilts/clang/ohos/linux-x86_64/15.0.4/llvm/include/c++/v1/ext",
97    "//prebuilts/clang/ohos/linux-x86_64/15.0.4/llvm/include/arm-linux-ohos/c++/v1",
98  ]
99
100   cflags_c = [
101      "-Wno-error=bitwise-op-parentheses",
102      "-Wno-error=shift-op-parentheses",
103    ]
104}
105    """
106
107
108def generate_soft_libc_musl_shared_configs():
109    return """
110config("soft_libc_musl_shared_configs") {
111  visibility = [ ":*" ]
112  include_dirs = [
113    "innerapis/includes",
114  ]
115}
116
117ohos_prebuilt_shared_library("soft_libc_musl_shared") {
118  public_configs = [":soft_libc_musl_shared_configs",":musl_common_configs"]
119  public_external_deps = [
120  ]
121  source = "innerapis/libs/libc.so"
122  part_name = "musl"
123  subsystem_name = "thirdparty"
124}
125    """
126
127
128def generate_soft_libcrypt_configs():
129    return """
130config("soft_libcrypt_configs") {
131  visibility = [ ":*" ]
132  include_dirs = [
133    "innerapis/includes",
134  ]
135}
136
137ohos_prebuilt_static_library("soft_libcrypt") {
138  public_configs = [":soft_libcrypt_configs",":musl_common_configs"]
139  public_external_deps = [
140  ]
141  source = "innerapis/libs/libcrypt.a"
142  part_name = "musl"
143  subsystem_name = "thirdparty"
144}
145    """
146
147
148def generate_soft_libdl_configs():
149    return """
150config("soft_libdl_configs") {
151  visibility = [ ":*" ]
152  include_dirs = [
153    "innerapis/includes",
154  ]
155}
156
157ohos_prebuilt_static_library("soft_libdl") {
158  public_configs = [":soft_libdl_configs",":musl_common_configs"]
159  public_external_deps = [
160  ]
161  source = "innerapis/libs/libdl.a"
162  part_name = "musl"
163  subsystem_name = "thirdparty"
164}
165    """
166
167
168def generate_soft_libm_configs():
169    return """
170config("soft_libm_configs") {
171  visibility = [ ":*" ]
172  include_dirs = [
173    "innerapis/includes",
174  ]
175}
176
177ohos_prebuilt_static_library("soft_libm") {
178  public_configs = [":soft_libm_configs",":musl_common_configs"]
179  public_external_deps = [
180  ]
181  source = "innerapis/libs/libm.a"
182  part_name = "musl"
183  subsystem_name = "thirdparty"
184}
185    """
186
187
188def generate_soft_libpthread_configs():
189    return """
190config("soft_libpthread_configs") {
191  visibility = [ ":*" ]
192  include_dirs = [
193    "innerapis/includes",
194  ]
195}
196
197ohos_prebuilt_static_library("soft_libpthread") {
198  public_configs = [":soft_libpthread_configs",":musl_common_configs"]
199  public_external_deps = [
200  ]
201  source = "innerapis/libs/libpthread.a"
202  part_name = "musl"
203  subsystem_name = "thirdparty"
204}
205    """
206
207
208def generate_soft_libresolv_configs():
209    return """
210config("soft_libresolv_configs") {
211  visibility = [ ":*" ]
212  include_dirs = [
213    "innerapis/includes",
214  ]
215}
216
217ohos_prebuilt_static_library("soft_libresolv") {
218  public_configs = [":soft_libresolv_configs",":musl_common_configs"]
219  public_external_deps = [
220  ]
221  source = "innerapis/libs/libresolv.a"
222  part_name = "musl"
223  subsystem_name = "thirdparty"
224}
225    """
226
227
228def generate_soft_librt_configs():
229    return """
230config("soft_librt_configs") {
231  visibility = [ ":*" ]
232  include_dirs = [
233    "innerapis/includes",
234  ]
235}
236
237ohos_prebuilt_static_library("soft_librt") {
238  public_configs = [":soft_librt_configs",":musl_common_configs"]
239  public_external_deps = [
240  ]
241  source = "innerapis/libs/librt.a"
242  part_name = "musl"
243  subsystem_name = "thirdparty"
244}
245    """
246
247
248def generate_soft_libutil_configs():
249    return """
250config("soft_libutil_configs") {
251  visibility = [ ":*" ]
252  include_dirs = [
253    "innerapis/includes",
254  ]
255}
256
257ohos_prebuilt_static_library("soft_libutil") {
258  public_configs = [":soft_libutil_configs",":musl_common_configs"]
259  public_external_deps = [
260  ]
261  source = "innerapis/libs/libutil.a"
262  part_name = "musl"
263  subsystem_name = "thirdparty"
264}
265    """
266
267
268def generate_soft_libxnet_configs():
269    return """
270config("soft_libxnet_configs") {
271  visibility = [ ":*" ]
272  include_dirs = [
273    "innerapis/includes",
274  ]
275}
276
277ohos_prebuilt_static_library("soft_libxnet") {
278  public_configs = [":soft_libxnet_configs",":musl_common_configs"]
279  public_external_deps = [
280  ]
281  source = "innerapis/libs/libxnet.a"
282  part_name = "musl"
283  subsystem_name = "thirdparty"
284}
285    """
286
287
288def generate_group_copy_libs_block():
289    return """
290group("copy_libs") {
291    lib_files = [
292      "libc.a",
293      "libc.so",
294      "libcrypt.a",
295      "libdl.a",
296      "libm.a",
297      "libpthread.a",
298      "libresolv.a",
299      "librt.a",
300      "libutil.a",
301      "libxnet.a",
302      "crtn.o",
303      "crti.o",
304      "crt1.o",
305      "rcrt1.o",
306      "Scrt1.o",
307    ]
308    sources = []
309    outputs = []
310    deps = []
311    foreach(file, lib_files) {
312      copy("copy_${file}") {
313        sources += [ "innerapis/libs/${file}" ]
314        outputs += [ "${target_out_dir}/usr/lib/arm-linux-ohos/${file}" ]
315      }
316      deps += [ ":copy_${file}" ]
317    }
318}
319group("soft_shared_libs") {
320  public_configs = [":musl_common_configs", ":soft_libxnet_configs"]
321  deps = [
322    ":soft_libc_musl_shared",
323    ":soft_libcrypt",
324    ":soft_libdl",
325    ":soft_libm",
326    ":soft_libpthread",
327    ":soft_libresolv",
328    ":soft_librt",
329    ":soft_libutil",
330    ":soft_libxnet",
331  ]
332}
333    """
334
335
336def generate_group_musl_headers_block():
337    return """
338group("musl_headers") {
339  public_deps = [
340    ":musl_common_configs",
341  ]
342}
343    """
344
345
346def generate_gn_file_content(part_data):
347    gn_content = []
348    gn_content.append(generate_common_configs())
349    gn_content.append(generate_soft_libc_musl_shared_configs())
350    gn_content.append(generate_soft_libcrypt_configs())
351    gn_content.append(generate_soft_libdl_configs())
352    gn_content.append(generate_soft_libm_configs())
353    gn_content.append(generate_soft_libpthread_configs())
354    gn_content.append(generate_soft_libresolv_configs())
355    gn_content.append(generate_soft_librt_configs())
356    gn_content.append(generate_soft_libutil_configs())
357    gn_content.append(generate_soft_libxnet_configs())
358    gn_content.append(generate_group_copy_libs_block())
359    gn_content.append(generate_group_musl_headers_block())
360    return '\n'.join(gn_content)
361
362
363def write_gn_file(gn_path, content):
364    with open(gn_path, 'w') as gn_file:
365        gn_file.write(content)
366
367
368def copy_musl_libs_includes(musl_obj_path, innerapi_target_path):
369    for folder_name in ['include', 'lib']:
370        src_folder_path = os.path.join(musl_obj_path, folder_name, 'arm-linux-ohos')
371        dst_folder_path = os.path.join(innerapi_target_path, folder_name + 's')
372        dst_folder_path_1 = os.path.join(innerapi_target_path, 'musl_headers', folder_name + 's')
373        dst_folder_path_2 = os.path.join(innerapi_target_path, 'soft_libc_musl_static', folder_name + 's')
374        dst_folder_path_3 = os.path.join(innerapi_target_path, 'soft_shared_libs', folder_name + 's')
375        if os.path.exists(src_folder_path):
376            shutil.copytree(src_folder_path, dst_folder_path, dirs_exist_ok=True)
377            shutil.copytree(src_folder_path, dst_folder_path_1, dirs_exist_ok=True)
378            shutil.copytree(src_folder_path, dst_folder_path_2, dirs_exist_ok=True)
379            shutil.copytree(src_folder_path, dst_folder_path_3, dirs_exist_ok=True)
380
381
382def process_musl(part_data, parts_path_info, part_name, subsystem_name, components_json):
383    musl_obj_path = os.path.join(part_data.get('out_path'), 'obj', 'third_party', 'musl', 'usr')
384    musl_dst_path = os.path.join(part_data.get('out_path'), 'component_package', 'third_party', 'musl')
385    musl_src_path = os.path.join(part_data.get('root_path'), 'third_party', 'musl')
386    create_directories([musl_dst_path])
387
388    # Copy necessary files to the musl destination path
389    files_to_copy = [
390        'configure',
391        'dynamic.list',
392        'libc.map.txt',
393        'musl_config.gni'
394    ]
395    copy_files([(os.path.join(musl_src_path, file_name), os.path.join(musl_dst_path, file_name)) for file_name in
396                files_to_copy])
397
398    # Generate and write the GN file
399    gn_path = os.path.join(musl_dst_path, 'BUILD.gn')
400    gn_content = generate_gn_file_content(part_data)
401    write_gn_file(gn_path, gn_content)
402    innerapi_target_path = os.path.join(musl_dst_path, 'innerapis')
403    copy_musl_libs_includes(musl_obj_path, innerapi_target_path)
404    modules = _parse_module_list(part_data)
405    print('modules', modules)
406    if len(modules) == 0:
407        return
408    _public_deps_list = []
409    # ... Additional logic for processing modules, copying docs, and finishing the component build ...
410    _copy_required_docs(part_data, _public_deps_list)
411    _finish_component_build(part_data)
412
413
414def _create_bundle_json(bundle_path, bundle_content):
415    bundle = {}
416    with open(bundle_path, "w", encoding="utf-8") as f1:
417        json.dump(bundle_content, f1, indent=2)
418
419
420def _generate_rust_bundle_content():
421    bundle_content = {
422        "name": "@ohos/rust",
423        "description": "third party rust tools, provide multiply functions about compiler",
424        "version": "3.1.0-snapshot",
425        "license": "Apache License 2.0",
426        "publishAs": "binary",
427        "segment": {"destPath": "third_party/rust/crates"},
428        "dirs": {"./": ["*"]},
429        "scripts": {},
430        "component": {
431            "name": "rust",
432            "subsystem": "thirdparty",
433            "syscap": [],
434            "features": [],
435            "adapted_system_type": ["standard"],
436            "rom": "",
437            "ram": "",
438            "hisysevent_config": [],
439            "deps": {
440                "components": [],
441                "third_party": []
442            },
443            "build": {
444                "sub_component": [],
445                "inner_api": [],
446                "test": []
447            }
448        },
449        "os": "linux",
450        "buildArch": "x86"
451    }
452    return bundle_content
453
454
455def process_rust(part_data, parts_path_info, part_name, subsystem_name, components_json):
456    rust_src_path = os.path.join(part_data.get('root_path'), 'third_party', 'rust', 'crates')
457    dst_path = os.path.join(part_data.get("out_path"), "component_package", part_data.get("part_path"))
458    copy_directory_contents(rust_src_path, dst_path)
459
460    gn_path = os.path.join(dst_path, "bundle.json")
461    bundle_content = _generate_rust_bundle_content()
462    _create_bundle_json(gn_path, bundle_content)
463
464    _copy_license(part_data)
465    _copy_readme(part_data)
466
467
468def copy_directory_contents(src_path, dst_path):
469    if not os.path.exists(dst_path):
470        os.makedirs(dst_path)
471    for item in os.listdir(src_path):
472        src = os.path.join(src_path, item)
473        dst = os.path.join(dst_path, item)
474        if os.path.isdir(src):
475            if os.path.exists(dst):
476                shutil.rmtree(dst)
477            shutil.copytree(src, dst)
478        elif os.path.isfile(src):
479            shutil.copy2(src, dst)
480
481
482def generate_developer_test_bundle_base_info():
483    return {
484        "name": "@ohos/developer_test",
485        "description": "developer_test",
486        "version": "3.1.0-snapshot",
487        "license": "Apache License 2.0",
488        "publishAs": "binary",
489        "segment": {"destPath": "test/testfwk/developer_test"},
490        "repository": "",
491        "dirs": {"./": ["*"]},
492        "scripts": {},
493        "os": "linux",
494        "buildArch": "x86"
495    }
496
497
498def generate_developer_test_component_info():
499    return {
500        "name": "developer_test",
501        "subsystem": "testfwk",
502        "syscap": [],
503        "features": [],
504        "adapted_system_type": ["mini", "small", "standard"],
505        "rom": "0KB",
506        "ram": "0KB",
507        "deps": {}
508    }
509
510
511def generate_developer_test_build_info():
512    return {
513        "sub_component": [
514            "//test/testfwk/developer_test/examples/app_info:app_info",
515            "//test/testfwk/developer_test/examples/detector:detector",
516            "//test/testfwk/developer_test/examples/calculator:calculator",
517            "//test/testfwk/developer_test/examples/calculator:calculator_static"
518        ],
519        "inner_kits": [
520            {
521                "name": "//test/testfwk/developer_test/aw/cxx/distributed:distributedtest_lib",
522                "header": {
523                    "header_base": [
524                        "//test/testfwk/developer_test/aw/cxx/distributed/utils",
525                        "//test/testfwk/developer_test/aw/cxx/distributed"
526                    ],
527                    "header_files": [
528                        "csv_transform_xml.h",
529                        "distributed.h",
530                        "distributed_agent.h",
531                        "distributed_cfg.h",
532                        "distributed_major.h"
533                    ]
534                }
535            },
536            {
537                "name": "//test/testfwk/developer_test/aw/cxx/hwext:performance_test_static",
538                "header": {
539                    "header_base": "//test/testfwk/developer_test/aw/cxx/hwext",
540                    "header_files": "perf.h"
541                }
542            }
543        ],
544        "test": [
545            "//test/testfwk/developer_test/examples/app_info/test:unittest",
546            "//test/testfwk/developer_test/examples/calculator/test:unittest",
547            "//test/testfwk/developer_test/examples/calculator/test:fuzztest",
548            "//test/testfwk/developer_test/examples/calculator/test:benchmarktest",
549            "//test/testfwk/developer_test/examples/detector/test:unittest",
550            "//test/testfwk/developer_test/examples/sleep/test:performance",
551            "//test/testfwk/developer_test/examples/distributedb/test:distributedtest",
552            "//test/testfwk/developer_test/examples/stagetest/actsbundlemanagerstagetest:unittest"
553        ]
554    }
555
556
557def _generate_developer_test_bundle_content():
558    bundle_content = generate_developer_test_bundle_base_info()
559    component_info = generate_developer_test_component_info()
560    build_info = generate_developer_test_build_info()
561
562    bundle_content["component"] = component_info
563    component_info["build"] = build_info
564
565    return bundle_content
566
567
568def process_developer_test(part_data, parts_path_info, part_name, subsystem_name, components_json):
569    developer_test_src_path = os.path.join(part_data.get('root_path'), 'test', 'testfwk', 'developer_test')
570    dst_path = os.path.join(part_data.get("out_path"), "component_package", part_data.get("part_path"))
571
572    copy_directory_contents(developer_test_src_path, dst_path)
573
574    gn_path = os.path.join(dst_path, "bundle.json")
575
576    bundle_content = _generate_developer_test_bundle_content()
577    _create_bundle_json(gn_path, bundle_content)
578
579    _copy_license(part_data)
580    _copy_readme(part_data)
581    _finish_component_build(part_data)
582
583
584def write_hilog_gn(part_data, module):
585    gn_path = os.path.join(part_data.get("out_path"), "component_package", part_data.get("part_path"),
586                           "innerapis", module, "BUILD.gn")
587    if os.path.exists(gn_path):
588        os.remove(gn_path)
589    fd = os.open(gn_path, os.O_WRONLY | os.O_CREAT, mode=0o640)
590    fp = os.fdopen(fd, 'w')
591    fp.write("""import("//build/ohos.gni")
592
593    config("hilog_rust_configs") {
594      visibility = [ ":*" ]
595      include_dirs = [
596        "includes",
597      ]
598      }
599
600
601    ohos_rust_shared_library("hilog_rust") {
602      sources = [ "src/lib.rs" ]
603
604      deps = [ "../libhilog:libhilog" ]
605      crate_name = "hilog_rust"
606      crate_type = "dylib"
607      rustflags = [ "-Zstack-protector=all" ]
608
609      subsystem_name = "hiviewdfx"
610      part_name = "hilog"
611    }""")
612    print("_generate_build_gn has done ")
613    fp.close()
614
615
616def _hilog_rust_handle(part_data, module, components_json):
617    public_deps_list = []
618    if not _is_innerkit(components_json, part_data.get("part_name"), module):
619        return public_deps_list
620    json_data = _get_json_data(part_data, module)
621    _lib_special_handler(part_data.get("part_name"), module, part_data)
622    lib_exists = _copy_lib(part_data, json_data, module)
623    if lib_exists is False:
624        return public_deps_list
625    includes = _handle_includes_data(json_data)
626    deps = _handle_deps_data(json_data)
627    _copy_includes(part_data, module, includes)
628    _list = _generate_build_gn(part_data, module, json_data, deps, components_json, public_deps_list)
629    write_hilog_gn(part_data, module)
630    _toolchain_gn_copy(part_data, module, json_data['out_name'])
631    hilog_rust_out = os.path.join(part_data.get("out_path"), "component_package", part_data.get("part_path"),
632                                  "innerapis", module)
633    hilog_rust_dir = os.path.join(part_data.get("root_path"), part_data.get("part_path"), "interfaces", "rust")
634    folder_to_copy = os.path.join(hilog_rust_dir, "src")  # 替换为实际的文件夹名称
635    file_to_copy = os.path.join(hilog_rust_dir, "Cargo.toml")  # 替换为实际的文件名称
636    # 检查文件夹和文件是否存在
637    if os.path.exists(folder_to_copy) and os.path.exists(file_to_copy):
638        # 复制文件夹
639        shutil.copytree(folder_to_copy, os.path.join(hilog_rust_out, os.path.basename(folder_to_copy)))
640        # 复制文件
641        shutil.copy(file_to_copy, os.path.join(hilog_rust_out, os.path.basename(file_to_copy)))
642    else:
643        print("文件夹或文件不存在,无法复制。")
644
645    return _list
646
647
648def process_hilog(part_data, parts_path_info, part_name, subsystem_name, components_json):
649    # 只处理一个模块
650    # 处理分类B的逻辑
651    part_path = _get_parts_path(parts_path_info, part_name)
652    if part_path is None:
653        return
654    part_data.update({"subsystem_name": subsystem_name, "part_name": part_name,
655                      "part_path": part_path})
656    modules = _parse_module_list(part_data)
657    print('modules', modules)
658    if len(modules) == 0:
659        return
660    is_component_build = False
661    _public_deps_list = []
662    for module in modules:
663        module_deps_list = _handle_module(part_data, components_json, module)
664        if module == 'hilog_rust':
665            _hilog_rust_handle(part_data, module, components_json)
666        if module_deps_list:
667            _public_deps_list.extend(module_deps_list)
668        is_component_build = True
669    if is_component_build:
670        _copy_required_docs(part_data, _public_deps_list)
671        _finish_component_build(part_data)
672
673
674def generate_hisysevent_gn(part_data, module):
675    gn_path = os.path.join(part_data.get("out_path"), "component_package", part_data.get("part_path"),
676                           "innerapis", module, "BUILD.gn")
677    if os.path.exists(gn_path):
678        os.remove(gn_path)
679    fd = os.open(gn_path, os.O_WRONLY | os.O_CREAT, mode=0o640)
680    fp = os.fdopen(fd, 'w')
681    fp.write("""import("//build/ohos.gni")
682
683    ohos_rust_shared_library("hisysevent_rust") {
684      sources = [
685        "src/lib.rs",
686        "src/macros.rs",
687        "src/sys_event.rs",
688        "src/sys_event_manager.rs",
689        "src/utils.rs",
690      ]
691
692      external_deps = [
693        "hisysevent:hisysevent_c_wrapper",
694        "hisysevent:libhisysevent",
695        "hisysevent:libhisyseventmanager",
696      ]
697
698      crate_name = "hisysevent"
699      crate_type = "dylib"
700      rustflags = [ "-Zstack-protector=all" ]
701
702      part_name = "hisysevent"
703      subsystem_name = "hiviewdfx"
704    }
705    """)
706    print("_generate_build_gn has done ")
707    fp.close()
708
709
710def _hisysevent_rust_handle(part_data, module, components_json):
711    public_deps_list = []
712    if not _is_innerkit(components_json, part_data.get("part_name"), module):
713        return public_deps_list
714    json_data = _get_json_data(part_data, module)
715    _lib_special_handler(part_data.get("part_name"), module, part_data)
716    lib_exists = _copy_lib(part_data, json_data, module)
717    if lib_exists is False:
718        return public_deps_list
719    includes = _handle_includes_data(json_data)
720    deps = _handle_deps_data(json_data)
721    _copy_includes(part_data, module, includes)
722    _list = _generate_build_gn(part_data, module, json_data, deps, components_json, public_deps_list)
723    generate_hisysevent_gn(part_data, module)
724    _toolchain_gn_copy(part_data, module, json_data['out_name'])
725    hisysevent_rust_out = os.path.join(part_data.get("out_path"), "component_package", part_data.get("part_path"),
726                                       "innerapis", module)
727    hisysevent_rust_dir = os.path.join(part_data.get("root_path"), part_data.get("part_path"), "interfaces",
728                                       "innerkits", "rust")
729    folder_to_copy = os.path.join(hisysevent_rust_dir, "src")  # 替换为实际的文件夹名称
730    file_to_copy = os.path.join(hisysevent_rust_dir, "Cargo.toml")  # 替换为实际的文件名称
731    # 检查文件夹和文件是否存在
732    if os.path.exists(folder_to_copy) and os.path.exists(file_to_copy):
733        # 复制文件夹
734        shutil.copytree(folder_to_copy, os.path.join(hisysevent_rust_out, os.path.basename(folder_to_copy)))
735        # 复制文件
736        shutil.copy(file_to_copy, os.path.join(hisysevent_rust_out, os.path.basename(file_to_copy)))
737    else:
738        print("文件夹或文件不存在,无法复制。")
739
740    return _list
741
742
743def process_hisysevent(part_data, parts_path_info, part_name, subsystem_name, components_json):
744    # 只处理一个模块
745    part_path = _get_parts_path(parts_path_info, part_name)
746    if part_path is None:
747        return
748    part_data.update({"subsystem_name": subsystem_name, "part_name": part_name,
749                      "part_path": part_path})
750    modules = _parse_module_list(part_data)
751    print('modules', modules)
752    if len(modules) == 0:
753        return
754    is_component_build = False
755    _public_deps_list = []
756    for module in modules:
757        module_deps_list = _handle_module(part_data, components_json, module)
758        if module == 'hisysevent_rust':
759            _hisysevent_rust_handle(part_data, module, components_json)
760        if module_deps_list:
761            _public_deps_list.extend(module_deps_list)
762        is_component_build = True
763    if is_component_build:
764        _copy_required_docs(part_data, _public_deps_list)
765        _finish_component_build(part_data)
766
767
768def _generate_runtime_core_build_gn():
769    gn_path = os.path.join(args.get("out_path"), "component_package", args.get("part_path"),
770                           "innerapis", module, "BUILD.gn")
771    fd = os.open(gn_path, os.O_WRONLY | os.O_CREAT, mode=0o640)
772    fp = os.fdopen(fd, 'w')
773    _generate_import(fp)
774    _generate_configs(fp, module)
775    _generate_prebuilt_shared_library(fp, json_data.get('type'), module)
776    _generate_public_configs(fp, module)
777    _list = _generate_public_deps(fp, module, deps, components_json, public_deps_list)
778    _generate_other(fp, args, json_data, module)
779    _generate_end(fp)
780    print("_generate_build_gn has done ")
781    fp.close()
782    return _list
783
784
785def _handle_module_runtime_core(args, components_json, module):
786    public_deps_list = []
787    if _is_innerkit(components_json, args.get("part_name"), module) == False:
788        return public_deps_list
789    json_data = _get_json_data(args, module)
790    _lib_special_handler(args.get("part_name"), module, args)
791    lib_exists = _copy_lib(args, json_data, module)
792    if lib_exists is False:
793        return public_deps_list
794    includes = _handle_includes_data(json_data)
795    deps = _handle_deps_data(json_data)
796    _copy_includes(args, module, includes)
797    _list = _generate_build_gn(args, module, json_data, deps, components_json, public_deps_list)
798    _toolchain_gn_copy(args, module, json_data['out_name'])
799    return _list
800
801
802def process_runtime_core(part_data, parts_path_info, part_name, subsystem_name, components_json):
803    # 处理分类runtime_core的逻辑
804    part_path = _get_parts_path(parts_path_info, part_name)
805    if part_path is None:
806        return
807    part_data.update({"subsystem_name": subsystem_name, "part_name": part_name,
808                      "part_path": part_path})
809    modules = _parse_module_list(part_data)
810    print('modules', modules)
811    if len(modules) == 0:
812        return
813    is_component_build = False
814    _public_deps_list = []
815    for module in modules:
816        module_deps_list = _handle_module_runtime_core(part_data, components_json, module)
817        if module_deps_list:
818            _public_deps_list.extend(module_deps_list)
819            is_component_build = True
820    if is_component_build:
821        _copy_required_docs(part_data, _public_deps_list)
822        _finish_component_build(part_data)
823
824
825def process_drivers_interface_display(part_data, parts_path_info, part_name, subsystem_name, components_json):
826    part_path = _get_parts_path(parts_path_info, part_name)
827    if part_path is None:
828        return
829    part_data.update({"subsystem_name": subsystem_name, "part_name": part_name,
830                      "part_path": part_path})
831    modules = _parse_module_list(part_data)
832    print('modules', modules)
833    if len(modules) == 0:
834        return
835    is_component_build = False
836    _public_deps_list = []
837    for module in modules:
838        module_deps_list = _handle_module(part_data, components_json, module)
839        if module_deps_list:
840            _public_deps_list.extend(module_deps_list)
841            is_component_build = True
842    lib_out_dir = os.path.join(part_data.get("out_path"), "component_package",
843                               part_data.get("part_path"), "innerapis", "display_commontype_idl_headers", "libs")
844    if not os.path.exists(lib_out_dir):
845        os.makedirs(lib_out_dir)
846    file_path = os.path.join(lib_out_dir, 'libdisplay_commontype_idl_headers')
847    with open(file_path, 'wb') as file:
848        pass
849    if is_component_build:
850        _copy_required_docs(part_data, _public_deps_list)
851        _finish_component_build(part_data)
852
853
854def process_drivers_interface_usb(part_data, parts_path_info, part_name, subsystem_name, components_json):
855    part_path = _get_parts_path(parts_path_info, part_name)
856    if part_path is None:
857        return
858    part_data.update({"subsystem_name": subsystem_name, "part_name": part_name,
859                      "part_path": part_path})
860    modules = _parse_module_list(part_data)
861    print('modules', modules)
862    if len(modules) == 0:
863        return
864    is_component_build = False
865    _public_deps_list = []
866    for module in modules:
867        module_deps_list = _handle_module(part_data, components_json, module)
868        if module_deps_list:
869            _public_deps_list.extend(module_deps_list)
870            is_component_build = True
871    lib_out_dir = os.path.join(part_data.get("out_path"), "component_package",
872                               part_data.get("part_path"), "innerapis", "usb_idl_headers_1.1", "libs")
873    if not os.path.exists(lib_out_dir):
874        os.makedirs(lib_out_dir)
875    file_path = os.path.join(lib_out_dir, 'libusb_idl_headers_1.1')
876    with open(file_path, 'wb') as file:
877        pass
878    if is_component_build:
879        _copy_required_docs(part_data, _public_deps_list)
880        _finish_component_build(part_data)
881
882
883def process_drivers_interface_ril(part_data, parts_path_info, part_name, subsystem_name, components_json):
884    part_path = _get_parts_path(parts_path_info, part_name)
885    if part_path is None:
886        return
887    part_data.update({"subsystem_name": subsystem_name, "part_name": part_name,
888                      "part_path": part_path})
889    modules = _parse_module_list(part_data)
890    print('modules', modules)
891    if len(modules) == 0:
892        return
893    is_component_build = False
894    _public_deps_list = []
895    for module in modules:
896        module_deps_list = _handle_module(part_data, components_json, module)
897        if module_deps_list:
898            _public_deps_list.extend(module_deps_list)
899            is_component_build = True
900    lib_out_dir = os.path.join(part_data.get("out_path"), "component_package",
901                               part_data.get("part_path"), "innerapis", "ril_idl_headers", "libs")
902    if not os.path.exists(lib_out_dir):
903        os.makedirs(lib_out_dir)
904    file_path = os.path.join(lib_out_dir, 'libril_idl_headers')
905    with open(file_path, 'wb') as file:
906        pass
907    if is_component_build:
908        _copy_required_docs(part_data, _public_deps_list)
909        _finish_component_build(part_data)
910
911
912# 函数映射字典
913function_map = {
914    'musl': process_musl,
915    "developer_test": process_developer_test,  # 同rust
916    "drivers_interface_display": process_drivers_interface_display,  # 驱动的, 新建一个libs目录/ innerapi同名文件
917    "runtime_core": process_runtime_core,  # 编译参数, 所有下面的innerapi的cflags都不
918    "drivers_interface_usb": process_drivers_interface_usb,  # 同驱动
919    "drivers_interface_ril": process_drivers_interface_ril,  # 同驱动
920}
921
922
923def _process_part(args, parts_path_info, part_name, subsystem_name, components_json):
924    # 使用映射字典来调用对应的函数
925    if part_name in function_map.keys():
926        function_map[part_name](args, parts_path_info, part_name, subsystem_name, components_json)
927    else:
928        print(f"没有找到处理分类{part_name}的函数。")
929
930
931def _check_label(public_deps, value):
932    innerapis = value["innerapis"]
933    for _innerapi in innerapis:
934        if _innerapi:
935            label = _innerapi.get("label")
936            if public_deps == label:
937                return label.split(':')[-1]
938            continue
939    return ""
940
941
942def _get_public_external_deps(data, public_deps):
943    if not isinstance(data, dict):
944        return ""
945    for key, value in data.items():
946        if not isinstance(value, dict):
947            continue
948        _data = _check_label(public_deps, value)
949        if _data:
950            return f"{key}:{_data}"
951        continue
952    return ""
953
954
955def _is_innerkit(data, part, module):
956    if not isinstance(data, dict):
957        return False
958
959    part_data = data.get(part)
960    if not isinstance(part_data, dict):
961        return False
962    module_list = []
963    for i in part_data["innerapis"]:
964        if i:
965            module_list.append(i["name"])
966    if module in module_list:
967        return True
968    return False
969
970
971def _get_components_json(out_path):
972    jsondata = ""
973    json_path = os.path.join(out_path + "/build_configs/parts_info/components.json")
974    with os.fdopen(os.open(json_path, os.O_RDWR | os.O_CREAT, stat.S_IWUSR | stat.S_IRUSR),
975                   'r', encoding='utf-8') as f:
976        try:
977            jsondata = json.load(f)
978        except Exception as e:
979            print('--_get_components_json parse json error--')
980    return jsondata
981
982
983def _handle_one_layer_json(json_key, json_data, desc_list):
984    data_list = json_data.get(json_key)
985    if isinstance(data_list, list) and len(json_data.get(json_key)) >= 1:
986        desc_list.extend(data_list)
987    else:
988        desc_list.append(json_data.get(json_key))
989
990
991def _get_external_public_config(_path, _config_name):
992    py_args = _get_args()
993    out_path = py_args.out_path
994    _json_path = os.path.join(out_path, 'external_public_configs', _path, f'{_config_name}.json')
995    try:
996        with os.fdopen(os.open(_json_path, os.O_RDWR | os.O_CREAT, stat.S_IWUSR | stat.S_IRUSR),
997                       'r', encoding='utf-8') as f:
998            jsondata = json.load(f)
999    except Exception as e:
1000        print('_json_path: ', _json_path)
1001        print('--_get_external_public_config parse json error--')
1002        return []
1003
1004    include_dirs = jsondata.get('include_dirs')
1005    return include_dirs
1006
1007
1008def _handle_two_layer_json(json_key, json_data, desc_list):
1009    value_depth = len(json_data.get(json_key))
1010    for i in range(value_depth):
1011        _label = json_data.get(json_key)[i].get('label')
1012        _include_dirs = json_data.get(json_key)[i].get('include_dirs')
1013        if _include_dirs:
1014            desc_list.extend(_include_dirs)
1015        else:
1016            full_path = _label.split('//')[-1]
1017            _path = full_path.split(':')[0]
1018            _config_name = full_path.split(':')[-1]
1019            _include_dirs = _get_external_public_config(_path, _config_name)
1020            if _include_dirs:
1021                desc_list.extend(_include_dirs)
1022
1023
1024def _get_json_data(args, module):
1025    json_path = os.path.join(args.get("out_path"),
1026                             args.get("subsystem_name"), args.get("part_name"), "publicinfo", module + ".json")
1027    with os.fdopen(os.open(json_path, os.O_RDWR | os.O_CREAT, stat.S_IWUSR | stat.S_IRUSR),
1028                   'r', encoding='utf-8') as f:
1029        try:
1030            file_content = f.read()
1031            jsondata = json.loads(file_content)
1032        except Exception as e:
1033            print(json_path)
1034            print('--_get_json_data parse json error--', e)
1035    return jsondata
1036
1037
1038def _handle_deps_data(json_data):
1039    dep_list = []
1040    if json_data.get('public_deps'):
1041        _handle_one_layer_json('public_deps', json_data, dep_list)
1042    return dep_list
1043
1044
1045def _handle_includes_data(json_data):
1046    include_list = []
1047    if json_data.get('public_configs'):
1048        _handle_two_layer_json('public_configs', json_data, include_list)
1049    if json_data.get('all_dependent_configs'):
1050        _handle_two_layer_json('all_dependent_configs', json_data, include_list)
1051    return include_list
1052
1053
1054def _get_static_lib_path(args, json_data):
1055    label = json_data.get('label')
1056    split_label = label.split("//")[1].split(":")[0]
1057    real_static_lib_path = os.path.join(args.get("out_path"), "obj",
1058                                        split_label, json_data.get('out_name'))
1059    return real_static_lib_path
1060
1061
1062def _copy_dir(src_path, target_path):
1063    if not os.path.isdir(src_path):
1064        return False
1065    for file in os.listdir(src_path):
1066        path = os.path.join(src_path, file)
1067        if os.path.isdir(path):
1068            if file.startswith("."):
1069                continue
1070            path1 = os.path.join(target_path, file)
1071            _copy_dir(path, path1)
1072        else:
1073            _, file_extension = os.path.splitext(file)
1074            if file_extension not in [".h", ".hpp", ".in", ".inc", ".inl"]:
1075                continue
1076            if not os.path.exists(target_path):
1077                os.makedirs(target_path)
1078            shutil.copy2(path, os.path.join(target_path, file))
1079    return True
1080
1081
1082
1083def _copy_includes(args, module, includes: list):
1084    if module == 'ipc_single':
1085        includes = [
1086            "//foundation/communication/ipc/interfaces/innerkits/ipc_core/include",
1087            "//foundation/communication/ipc/ipc/native/src/core/include",
1088            "//foundation/communication/ipc/ipc/native/src/mock/include",
1089        ]
1090    includes_out_dir = os.path.join(args.get("out_path"), "component_package",
1091                                    args.get("part_path"), "innerapis", module, "includes")
1092    for i in args.get("toolchain_info").keys():
1093        toolchain_includes_out_dir = os.path.join(args.get("out_path"), "component_package",
1094                                                  args.get("part_path"), "innerapis", module, i, "includes")
1095        toolchain_lib_out_dir = os.path.join(args.get("out_path"), "component_package",
1096                                             args.get("part_path"), "innerapis", module, i, "libs")
1097        if not os.path.exists(toolchain_includes_out_dir) and os.path.exists(toolchain_lib_out_dir):
1098            os.makedirs(toolchain_includes_out_dir)
1099        else:
1100            continue
1101        for include in includes:
1102            part_path = args.get("part_path")
1103            _sub_include = include.split(f"{part_path}/")[-1]
1104            split_include = include.split("//")[1]
1105            real_include_path = os.path.join(args.get("root_path"), split_include)
1106            if args.get('part_name') == 'libunwind':
1107                _out_dir = os.path.join(toolchain_includes_out_dir, _sub_include)
1108                _copy_dir(real_include_path, _out_dir)
1109                continue
1110            _copy_dir(real_include_path, toolchain_includes_out_dir)
1111    if not os.path.exists(includes_out_dir):
1112        os.makedirs(includes_out_dir)
1113    for include in includes:
1114        part_path = args.get("part_path")
1115        _sub_include = include.split(f"{part_path}/")[-1]
1116        split_include = include.split("//")[1]
1117        real_include_path = os.path.join(args.get("root_path"), split_include)
1118        if args.get('part_name') == 'libunwind':
1119            _out_dir = os.path.join(includes_out_dir, _sub_include)
1120            _copy_dir(real_include_path, _out_dir)
1121            continue
1122        _copy_dir(real_include_path, includes_out_dir)
1123    print("_copy_includes has done ")
1124
1125
1126def _copy_toolchain_lib(file_name, root, _name, lib_out_dir):
1127    if not file_name.startswith('.') and file_name.startswith(_name):
1128        if not os.path.exists(lib_out_dir):
1129            os.makedirs(lib_out_dir)
1130        file = os.path.join(root, file_name)
1131        shutil.copy(file, lib_out_dir)
1132
1133
1134def _toolchain_lib_handler(args, toolchain_path, _name, module, toolchain_name):
1135    lib_out_dir = os.path.join(args.get("out_path"), "component_package",
1136                                       args.get("part_path"), "innerapis", module, toolchain_name, "libs")
1137    if os.path.isfile(toolchain_path):
1138        if not os.path.exists(lib_out_dir):
1139            os.makedirs(lib_out_dir)
1140        shutil.copy(toolchain_path, lib_out_dir)
1141    else:
1142        for root, dirs, files in os.walk(toolchain_path):
1143            for file_name in files:
1144                _copy_toolchain_lib(file_name, root, _name, lib_out_dir)
1145
1146
1147def _toolchain_static_file_path_mapping(subsystem_name, args, i):
1148    if subsystem_name == "thirdparty":
1149        subsystem_name = "third_party"
1150    toolchain_path = os.path.join(args.get("out_path"), i, 'obj', subsystem_name,
1151                                  args.get("part_name"))
1152    return toolchain_path
1153
1154
1155def replace_default_toolchains_in_output(path, default_toolchain="ohos_clang_arm64/"):
1156    return path.replace(default_toolchain, "")
1157
1158
1159def _copy_lib(args, json_data, module):
1160    so_path = ""
1161    lib_status = False
1162    _target_type = json_data.get('type')
1163    subsystem_name = args.get("subsystem_name")
1164
1165    # 根据 type 字段和 module 选择正确的 so_path
1166    if _target_type == 'copy' and module == 'ipc_core':
1167        so_path = os.path.join(subsystem_name, args.get("part_name"), 'libipc_single.z.so')
1168    elif _target_type == "rust_library" or _target_type == "rust_proc_macro":
1169        # 选择包含 'lib.unstripped' 的路径
1170        outputs = json_data.get('outputs', [])
1171        for output in outputs:
1172            if 'lib.unstripped' in output:
1173                output = replace_default_toolchains_in_output(output)
1174                so_path = output
1175                break
1176        # 如果没有找到包含 'lib.unstripped' 的路径,则选择最后一个路径
1177        if not so_path and outputs:
1178            so_path = outputs[-1]
1179    else:
1180        # 对于非 rust_library 类型,选择不包含 'lib.unstripped' 的路径
1181        outputs = json_data.get('outputs', [])
1182        for output in outputs:
1183            if '.unstripped' not in output:
1184                output = replace_default_toolchains_in_output(output)
1185                so_path = output
1186                break
1187        # 如果所有路径都包含 'lib.unstripped' 或者没有 outputs,则使用 out_name
1188        if not so_path:
1189            so_path = json_data.get('out_name')
1190    if so_path:
1191        lib_status = lib_status or copy_so_file(args, module, so_path)
1192
1193    return lib_status
1194
1195
1196def copy_so_file(args, module, so_path):
1197    lib_status = False
1198    out_path = args.get("out_path")
1199    so_path_with_out_path = os.path.join(out_path, so_path)
1200    lib_out_dir = os.path.join(out_path, "component_package",
1201                                   args.get("part_path"), "innerapis", module, "libs")
1202    if args.get("toolchain_info").keys():
1203        for toolchain_name in args.get("toolchain_info").keys():
1204            lib_out_dir_with_toolchain = os.path.join(args.get("out_path"), "component_package",
1205                                       args.get("part_path"), "innerapis", module, toolchain_name, "libs")
1206            so_path_with_toolchain = os.path.join(args.get("out_path"), toolchain_name, so_path)
1207            if toolchain_name in so_path :
1208                lib_status = _copy_file(so_path_with_out_path, lib_out_dir_with_toolchain) or lib_status
1209            elif os.path.isfile(so_path_with_toolchain):
1210                lib_status = _copy_file(so_path_with_toolchain, lib_out_dir_with_toolchain) or lib_status
1211    lib_status = _copy_file(so_path_with_out_path, lib_out_dir) or lib_status
1212    return lib_status
1213
1214
1215def _copy_file(so_path, lib_out_dir):
1216    if not os.path.isfile(so_path):
1217        print("WARNING: {} is not a file!".format(so_path))
1218        return False
1219    if not os.path.exists(lib_out_dir):
1220        os.makedirs(lib_out_dir)
1221    shutil.copy(so_path, lib_out_dir)
1222    return True
1223
1224
1225def _dirs_handler(bundlejson_out):
1226    dirs = dict()
1227    dirs['./'] = []
1228    directory = bundlejson_out
1229    for filename in os.listdir(directory):
1230        filepath = os.path.join(directory, filename)
1231        if os.path.isfile(filepath):
1232            dirs['./'].append(filename)
1233        else:
1234            dirs[filename] = [f"{filename}/*"]
1235    delete_list = ['LICENSE', 'README.md', 'README_zh.md', 'README_en.md', 'bundle.json']
1236    for delete_txt in delete_list:
1237        if delete_txt in dirs['./']:
1238            dirs['./'].remove(delete_txt)
1239    if dirs['./'] == []:
1240        del dirs['./']
1241    return dirs
1242
1243
1244def _copy_bundlejson(args, public_deps_list):
1245    bundlejson_out = os.path.join(args.get("out_path"), "component_package", args.get("part_path"))
1246    print("bundlejson_out : ", bundlejson_out)
1247    if not os.path.exists(bundlejson_out):
1248        os.makedirs(bundlejson_out)
1249    bundlejson = os.path.join(args.get("root_path"), args.get("part_path"), "bundle.json")
1250    dependencies_dict = {}
1251    sorted_dict = {}
1252    for public_deps in public_deps_list:
1253        _public_dep_part_name = public_deps.split(':')[0]
1254        if _public_dep_part_name != args.get("part_name"):
1255            _public_dep = f"@{args.get('organization_name')}/{_public_dep_part_name}"
1256            dependencies_dict.update({_public_dep: "*"})
1257            sorted_dict = dict(sorted(dependencies_dict.items()))
1258    if os.path.isfile(bundlejson):
1259        with open(bundlejson, 'r') as f:
1260            bundle_data = json.load(f)
1261            bundle_data['publishAs'] = 'binary'
1262            bundle_data.update({'os': args.get('os')})
1263            bundle_data.update({'buildArch': args.get('buildArch')})
1264            dirs = _dirs_handler(bundlejson_out)
1265            bundle_data['dirs'] = dirs
1266            bundle_data['version'] = str(bundle_data['version'])
1267            if bundle_data['version'] == '':
1268                bundle_data['version'] = '1.0.0'
1269            pattern = r'^(\d+)\.(\d+)(-[a-zA-Z]+)?$'  # 正则表达式匹配a.b[-后缀]格式的字符串
1270            match = re.match(pattern, bundle_data['version'])
1271            if match:
1272                a = match.group(1)
1273                b = match.group(2)
1274                suffix = match.group(3) if match.group(3) else ""
1275                bundle_data['version'] = f"{a}.{b}.0{suffix}"
1276            if args.get('build_type') in [0, 1]:
1277                bundle_data['version'] += '-snapshot'
1278            if args.get('organization_name'):
1279                _name_pattern = r'@(.*.)/'
1280                bundle_data['name'] = re.sub(_name_pattern, '@' + args.get('organization_name') + '/',
1281                                             bundle_data['name'])
1282            if bundle_data.get('scripts'):
1283                bundle_data.update({'scripts': {}})
1284            if bundle_data.get('licensePath'):
1285                del bundle_data['licensePath']
1286            if bundle_data.get('readmePath'):
1287                del bundle_data['readmePath']
1288            bundle_data['dependencies'] = sorted_dict
1289            if os.path.isfile(os.path.join(bundlejson_out, "bundle.json")):
1290                os.remove(os.path.join(bundlejson_out, "bundle.json"))
1291            with os.fdopen(os.open(os.path.join(bundlejson_out, "bundle.json"), os.O_WRONLY | os.O_CREAT, mode=0o640),
1292                           "w",
1293                           encoding='utf-8') as fd:
1294                json.dump(bundle_data, fd, indent=4, ensure_ascii=False)
1295
1296
1297def _copy_license(args):
1298    license_out = os.path.join(args.get("out_path"), "component_package", args.get("part_path"))
1299    print("license_out : ", license_out)
1300    if not os.path.exists(license_out):
1301        os.makedirs(license_out)
1302    license_file = os.path.join(args.get("root_path"), args.get("part_path"), "LICENSE")
1303    if os.path.isfile(license_file):
1304        shutil.copy(license_file, license_out)
1305    else:
1306        license_default = os.path.join(args.get("root_path"), "build", "LICENSE")
1307        shutil.copy(license_default, license_out)
1308        bundlejson_out = os.path.join(args.get("out_path"), "component_package", args.get("part_path"), 'bundle.json')
1309        with open(bundlejson_out, 'r') as f:
1310            bundle_data = json.load(f)
1311            bundle_data.update({"license": "Apache License 2.0"})
1312        if os.path.isfile(bundlejson_out):
1313            os.remove(bundlejson_out)
1314        with os.fdopen(os.open(bundlejson_out, os.O_WRONLY | os.O_CREAT, mode=0o640), "w",
1315                       encoding='utf-8') as fd:
1316            json.dump(bundle_data, fd, indent=4, ensure_ascii=False)
1317
1318
1319def _copy_readme(args):
1320    readme_out = os.path.join(args.get("out_path"), "component_package", args.get("part_path"))
1321    print("readme_out : ", readme_out)
1322    if not os.path.exists(readme_out):
1323        os.makedirs(readme_out)
1324    readme = os.path.join(args.get("root_path"), args.get("part_path"), "README.md")
1325    readme_zh = os.path.join(args.get("root_path"), args.get("part_path"), "README_zh.md")
1326    readme_en = os.path.join(args.get("root_path"), args.get("part_path"), "README_en.md")
1327    readme_out_file = os.path.join(readme_out, "README.md")
1328    if os.path.isfile(readme):
1329        shutil.copy(readme, readme_out)
1330    elif os.path.isfile(readme_zh):
1331        shutil.copy(readme_zh, readme_out_file)
1332    elif os.path.isfile(readme_en):
1333        shutil.copy(readme_en, readme_out_file)
1334    else:
1335        try:
1336            with os.fdopen(os.open(readme_out_file, os.O_WRONLY | os.O_CREAT, mode=0o640), 'w') as fp:
1337                fp.write('READ.ME')
1338        except FileExistsError:
1339            pass
1340
1341
1342def _generate_import(fp):
1343    fp.write('import("//build/ohos.gni")\n')
1344
1345
1346def _gcc_flags_info_handle(json_data):
1347    def should_process_key(k):
1348        return k not in ["label", "include_dirs"]
1349
1350    def process_config(config):
1351        result = {}
1352        for k, v in config.items():
1353            if should_process_key(k):
1354                result.setdefault(k, []).extend(v)
1355        return result
1356
1357    _flags_info = {}
1358    _public_configs = json_data.get('public_configs')
1359    if _public_configs:
1360        for config in _public_configs:
1361            config_info = process_config(config)
1362            for k, v in config_info.items():
1363                _flags_info.setdefault(k, []).extend(v)
1364    return _flags_info
1365
1366
1367def _generate_configs(fp, module, json_data, _part_name):
1368    fp.write('\nconfig("' + module + '_configs") {\n')
1369    fp.write('  visibility = [ ":*" ]\n')
1370    fp.write('  include_dirs = [\n')
1371    fp.write('    "includes",\n')
1372    if module == 'libunwind':
1373        fp.write('    "includes/libunwind-1.6.2",\n')
1374        fp.write('    "includes/libunwind-1.6.2/src",\n')
1375        fp.write('    "includes/libunwind-1.6.2/include",\n')
1376        fp.write('    "includes/libunwind-1.6.2/include/tdep-arm",\n')
1377    if module == 'ability_runtime':
1378        fp.write('    "includes/context",\n')
1379        fp.write('    "includes/app",\n')
1380    fp.write('  ]\n')
1381    if _part_name == 'runtime_core':
1382        fp.write('  }\n')
1383        return
1384    _flags_info = _gcc_flags_info_handle(json_data)
1385    if _flags_info:
1386        for k, _list in _flags_info.items():
1387            fp.write(f'  {k} = [\n')
1388            for j in _list:
1389                # 保留所有 \ 转义符号
1390                j_escaped = j.replace('"', '\\"')
1391                fp.write(f'  "{j_escaped}",\n')
1392            fp.write('  ]\n')
1393    fp.write('  }\n')
1394
1395
1396def _generate_prebuilt_target(fp, target_type, module):
1397    if target_type == 'static_library':
1398        fp.write('ohos_prebuilt_static_library("' + module + '") {\n')
1399    elif target_type == 'executable':
1400        fp.write('ohos_prebuilt_executable("' + module + '") {\n')
1401    elif module != 'ipc_core' and (target_type == 'etc' or target_type == 'copy'):
1402        fp.write('ohos_prebuilt_etc("' + module + '") {\n')
1403    elif target_type == 'rust_library' or target_type == 'rust_proc_macro':
1404        fp.write('ohos_prebuilt_rust_library("' + module + '") {\n')
1405    else:
1406        fp.write('ohos_prebuilt_shared_library("' + module + '") {\n')
1407
1408
1409def _generate_public_configs(fp, module):
1410    fp.write(f'  public_configs = [":{module}_configs"]\n')
1411
1412
1413# 目前特殊处理的依赖关系映射
1414_DEPENDENCIES_MAP = {
1415    ('bundle_framework', 'appexecfwk_core'): ["ability_base:want", "samgr:samgr_proxy"],
1416    ('graphic_surface', 'surface'): ["ipc:ipc_core"],
1417    ('netmanager_base', 'net_conn_manager_if'): ["ipc:ipc_core"],
1418    ('ability_base', 'want'): ["ipc:ipc_core", "json:nlohmann_json_static"],
1419    ('ability_base', 'session_info'): ["bundle_framework:appexecfwk_base"],
1420    ('window_manager', 'libdm'): ["graphic_2d:librender_service_base"],
1421    ('enterprise_device_management', 'edmservice_kits'): ["ability_base:want"],
1422    ('ability_runtime', 'appkit_native'): ["ets_runtime:libark_jsruntime"],
1423    ('samgr', 'samgr_proxy'): ["ipc:ipc_core"],
1424    ('napi', 'ace_napi'): ["ets_runtime:libark_jsruntime", "runtime_core:libarkfile_static",
1425                           "runtime_core:libarkbase_static"],
1426    ('ability_runtime', 'ability_context_native'): ["eventhandler:libeventhandler"],
1427    ('ability_runtime', 'abilitykit_native'): ["ipc:ipc_napi", "ability_runtime:ability_manager",
1428                                               "eventhandler:libeventhandler"],
1429    ('ipc', 'ipc_core'): ["c_utils:utils"],
1430    ('ipc', 'ipc_single'): ["c_utils:utils"],
1431    ('graphic_2d', 'libcomposer'): ["eventhandler:libeventhandler"],
1432    ('ability_runtime', 'napi_common'): ["ability_runtime:runtime"],
1433    ('graphic_2d', 'librender_service_client'): ["graphic_2d:2d_graphics", "graphic_2d:libcomposer",
1434                                                 "image_framework:pixelconvertadapter", "eventhandler:libeventhandler"],
1435    ('graphic_2d', 'librender_service_base'): ["opengles:libGLES"],
1436    ('graphic_2d', '2d_graphics'): ["skia:skia_canvaskit", "opengles:libGLES"],
1437    ('input', 'libmmi-client'): ["eventhandler:libeventhandler"],
1438    ('resource_schedule_service', 'ressched_client'): ["samgr:samgr_proxy"],
1439    ('relational_store', 'native_rdb'): ["c_utils:utils"],
1440    ('opengles', 'libGLES'): ["egl:libEGL"],
1441    ('ability_runtime', 'ability_manager'): ["bundle_framework:libappexecfwk_common"],
1442    ('ability_runtime', 'napi_common'): ["ability_runtime:runtime"],
1443    ('access_token', 'libnativetoken'): ["cJSON:cjson_static", "selinux_adapter:librestorecon"],
1444    ('bundle_framework', 'bundlemgr_mini'): ["bundle_framework:appexecfwk_base"],
1445    ('media_foundation', 'media_monitor_client'): ["samgr:samgr_proxy"],
1446}
1447
1448
1449def _public_deps_special_handler(module, args):
1450    _part_name = args.get('part_name')
1451    # 使用映射字典来获取依赖列表
1452    return _DEPENDENCIES_MAP.get((_part_name, module), [])
1453
1454
1455def _generate_public_deps(fp, module, deps: list, components_json, public_deps_list: list, args):
1456    fp.write('  public_external_deps = [\n')
1457    for dep in deps:
1458        public_external_deps = _get_public_external_deps(components_json, dep)
1459        if len(public_external_deps) > 0:
1460            fp.write(f"""    "{public_external_deps}",\n""")
1461            public_deps_list.append(public_external_deps)
1462    for _public_external_deps in _public_deps_special_handler(module, args):
1463        fp.write(f"""    "{_public_external_deps}",\n""")
1464        public_deps_list.append(_public_external_deps)
1465    fp.write('  ]\n')
1466
1467    return public_deps_list
1468
1469
1470def _generate_other(fp, args, json_data, module):
1471    outputs = json_data.get('outputs', [])
1472    if json_data.get('type') == 'copy' and module == 'ipc_core':
1473        so_name = 'libipc_single.z.so'
1474    else:
1475        so_name = json_data.get('out_name')
1476        for output in outputs:
1477            so_name = output.split('/')[-1]
1478    if json_data.get('type') == 'copy':
1479        fp.write('  copy_linkable_file = true \n')
1480    fp.write('  source = "libs/' + so_name + '"\n')
1481    fp.write('  part_name = "' + args.get("part_name") + '"\n')
1482    fp.write('  subsystem_name = "' + args.get("subsystem_name") + '"\n')
1483
1484
1485def _generate_end(fp):
1486    fp.write('}')
1487
1488
1489def convert_rustdeps_to_innerapi(dep, components_json):
1490    # 分割路径和模块名
1491    dep_parts = dep.split(':', 1)
1492    if len(dep_parts) != 2:
1493        return False, "" # 格式不正确,不是 innerapi
1494
1495    path, module = dep_parts
1496    path = path.lstrip('//')
1497
1498    # 遍历 components.json 中的每个部件
1499    for component, info in components_json.items():
1500        if path.startswith(info['path']) and _check_dep_in_innerapi(info.get('innerapis', []), dep):
1501            return True, f"{component}:{module}"
1502    return False, ""
1503
1504
1505def _check_dep_in_innerapi(innerapis, dep):
1506    for innerapi in innerapis:
1507        if innerapi['label'] == (dep.split('(')[0] if ('(' in dep) else dep):
1508            return True
1509    return False
1510
1511
1512def _generate_rust_deps(fp, json_data, components_json):
1513    rust_deps = json_data.get("rust_deps")
1514    external_deps = []
1515    for _dep in rust_deps:
1516        has_innerapi, innerapi = convert_rustdeps_to_innerapi(_dep, components_json)
1517        if has_innerapi:
1518            external_deps.append(innerapi)
1519    fp.write('  external_deps = [\n')
1520    for external_dep in external_deps:
1521        fp.write(f"""    "{external_dep}",\n""")
1522    fp.write('  ]\n')
1523
1524
1525def _copy_rust_crate_info(fp, json_data):
1526    fp.write(f'  rust_crate_name = \"{json_data.get("rust_crate_name")}\"\n')
1527    fp.write(f'  rust_crate_type = \"{json_data.get("rust_crate_type")}\"\n')
1528
1529
1530def _generate_build_gn(args, module, json_data, deps: list, components_json, public_deps_list):
1531    gn_path = os.path.join(args.get("out_path"), "component_package", args.get("part_path"),
1532                           "innerapis", module, "BUILD.gn")
1533    fd = os.open(gn_path, os.O_WRONLY | os.O_CREAT, mode=0o640)
1534    fp = os.fdopen(fd, 'w')
1535    _generate_import(fp)
1536    _generate_configs(fp, module, json_data, args.get('part_name'))
1537    _target_type = json_data.get('type')
1538    _generate_prebuilt_target(fp, _target_type, module)
1539    _generate_public_configs(fp, module)
1540    _list = _generate_public_deps(fp, module, deps, components_json, public_deps_list, args)
1541    if _target_type == "rust_library" or _target_type == "rust_proc_macro":
1542        _copy_rust_crate_info(fp, json_data)
1543        _generate_rust_deps(fp, json_data, components_json)
1544    _generate_other(fp, args, json_data, module)
1545    _generate_end(fp)
1546    print(f"{module}_generate_build_gn has done ")
1547    fp.close()
1548    return _list
1549
1550
1551def _toolchain_gn_modify(gn_path, file_name, toolchain_gn_file):
1552    if os.path.isfile(gn_path) and file_name:
1553        with open(gn_path, 'r') as f:
1554            _gn = f.read()
1555            pattern = r"libs/(.*.)"
1556            toolchain_gn = re.sub(pattern, 'libs/' + file_name + '\"', _gn)
1557        fd = os.open(toolchain_gn_file, os.O_WRONLY | os.O_CREAT, mode=0o640)
1558        fp = os.fdopen(fd, 'w')
1559        fp.write(toolchain_gn)
1560        fp.close()
1561
1562
1563def _get_toolchain_gn_file(lib_out_dir, out_name):
1564    if os.path.exists(os.path.join(lib_out_dir, out_name)):
1565        return out_name
1566    else:
1567        print('Output file not found in toolchain dir.')
1568        return ''
1569
1570
1571def _toolchain_gn_copy(args, module, out_name):
1572    gn_path = os.path.join(args.get("out_path"), "component_package", args.get("part_path"),
1573                           "innerapis", module, "BUILD.gn")
1574    for i in args.get("toolchain_info").keys():
1575        lib_out_dir = os.path.join(args.get("out_path"), "component_package",
1576                                   args.get("part_path"), "innerapis", module, i, "libs")
1577        file_name = _get_toolchain_gn_file(lib_out_dir, out_name)
1578        if not file_name:
1579            continue
1580        toolchain_gn_file = os.path.join(args.get("out_path"), "component_package",
1581                                         args.get("part_path"), "innerapis", module, i, "BUILD.gn")
1582        if not os.path.exists(toolchain_gn_file):
1583            os.mknod(toolchain_gn_file)
1584        _toolchain_gn_modify(gn_path, file_name, toolchain_gn_file)
1585
1586
1587def _parse_module_list(args):
1588    module_list = []
1589    publicinfo_path = os.path.join(args.get("out_path"),
1590                                   args.get("subsystem_name"), args.get("part_name"), "publicinfo")
1591    print('publicinfo_path', publicinfo_path)
1592    if os.path.exists(publicinfo_path) is False:
1593        return module_list
1594    publicinfo_dir = os.listdir(publicinfo_path)
1595    for filename in publicinfo_dir:
1596        if filename.endswith(".json"):
1597            module_name = filename.split(".json")[0]
1598            module_list.append(module_name)
1599            print('filename', filename)
1600    print('module_list', module_list)
1601    return module_list
1602
1603
1604def _lib_special_handler(part_name, module, args):
1605    if part_name == 'mksh':
1606        mksh_file_path = os.path.join(args.get('out_path'), 'startup', 'init', 'sh')
1607        sh_out = os.path.join(args.get("out_path"), "thirdparty", "mksh")
1608        if os.path.isfile(mksh_file_path):
1609            shutil.copy(mksh_file_path, sh_out)
1610    if module == 'blkid':
1611        blkid_file_path = os.path.join(args.get('out_path'), 'filemanagement', 'storage_service', 'blkid')
1612        blkid_out = os.path.join(args.get("out_path"), "thirdparty", "e2fsprogs")
1613        if os.path.isfile(blkid_file_path):
1614            shutil.copy(blkid_file_path, blkid_out)
1615    if module == 'grpc_cpp_plugin':
1616        blkid_file_path = os.path.join(args.get('out_path'), 'clang_x64', 'thirdparty', 'grpc', 'grpc_cpp_plugin')
1617        blkid_out = os.path.join(args.get("out_path"), "thirdparty", "grpc")
1618        if os.path.isfile(blkid_file_path):
1619            shutil.copy(blkid_file_path, blkid_out)
1620
1621
1622def _handle_module(args, components_json, module):
1623    public_deps_list = []
1624    if _is_innerkit(components_json, args.get("part_name"), module) == False:
1625        return public_deps_list
1626    json_data = _get_json_data(args, module)
1627    _lib_special_handler(args.get("part_name"), module, args)
1628    _copy_lib(args, json_data, module)
1629    includes = _handle_includes_data(json_data)
1630    deps = _handle_deps_data(json_data)
1631    _copy_includes(args, module, includes)
1632    _list = _generate_build_gn(args, module, json_data, deps, components_json, public_deps_list)
1633    _toolchain_gn_copy(args, module, json_data['out_name'])
1634    return _list
1635
1636
1637def _copy_required_docs(args, public_deps_list):
1638    _copy_bundlejson(args, public_deps_list)
1639    _copy_license(args)
1640    _copy_readme(args)
1641
1642
1643def _finish_component_build(args):
1644    if args.get("build_type") in [0, 1]:
1645        _hpm_status = _hpm_pack(args)
1646        if _hpm_status:
1647            _copy_hpm_pack(args)
1648
1649
1650def _generate_component_package(args, components_json):
1651    modules = _parse_module_list(args)
1652    print('modules', modules)
1653    if len(modules) == 0:
1654        return
1655    is_component_build = False
1656    _public_deps_list = []
1657    for module in modules:
1658        module_deps_list = _handle_module(args, components_json, module)
1659        if module_deps_list:
1660            _public_deps_list.extend(module_deps_list)
1661        is_component_build = True
1662    if is_component_build:
1663        _copy_required_docs(args, _public_deps_list)
1664        _finish_component_build(args)
1665
1666
1667def _get_part_subsystem(components_json: dict):
1668    jsondata = dict()
1669    try:
1670        for component, v in components_json.items():
1671            jsondata[component] = v.get('subsystem')
1672    except Exception as e:
1673        print('--_get_part_subsystem parse json error--')
1674    return jsondata
1675
1676
1677def _get_parts_path_info(components_json):
1678    jsondata = dict()
1679    try:
1680        for component, v in components_json.items():
1681            jsondata[component] = v.get('path')
1682    except Exception as e:
1683        print('--_get_part_subsystem parse json error--')
1684    return jsondata
1685
1686
1687def _get_toolchain_info(root_path):
1688    jsondata = ""
1689    json_path = os.path.join(root_path + "/build/indep_configs/variants/common/toolchain.json")
1690    with os.fdopen(os.open(json_path, os.O_RDWR | os.O_CREAT, stat.S_IWUSR | stat.S_IRUSR),
1691                   'r', encoding='utf-8') as f:
1692        try:
1693            jsondata = json.load(f)
1694        except Exception as e:
1695            print('--_get_toolchain_info parse json error--')
1696    return jsondata
1697
1698
1699def _get_parts_path(json_data, part_name):
1700    parts_path = None
1701    if json_data.get(part_name) is not None:
1702        parts_path = json_data[part_name]
1703    return parts_path
1704
1705
1706def _hpm_pack(args):
1707    part_path = os.path.join(args.get("out_path"), "component_package", args.get("part_path"))
1708    cmd = ['hpm', 'pack']
1709    try:
1710        subprocess.run(cmd, shell=False, cwd=part_path)
1711    except Exception as e:
1712        print("{} pack fail".format(args.get("part_name")))
1713        return 0
1714    print("{} pack succ".format(args.get("part_name")))
1715    return 1
1716
1717
1718def _copy_hpm_pack(args):
1719    hpm_packages_path = args.get('hpm_packages_path')
1720    part_path = os.path.join(args.get("out_path"), "component_package", args.get("part_path"))
1721    dirs = os.listdir(part_path)
1722    tgz_file_name = ''
1723    for file in dirs:
1724        if file.endswith(".tgz"):
1725            tgz_file_name = file
1726    tgz_file_out = os.path.join(part_path, tgz_file_name)
1727    if tgz_file_name:
1728        shutil.copy(tgz_file_out, hpm_packages_path)
1729
1730
1731def _make_hpm_packages_dir(root_path):
1732    _out_path = os.path.join(root_path, 'out')
1733    hpm_packages_path = os.path.join(_out_path, 'hpm_packages')
1734    os.makedirs(hpm_packages_path, exist_ok=True)
1735    return hpm_packages_path
1736
1737
1738def _del_exist_component_package(out_path):
1739    _component_package_path = os.path.join(out_path, 'component_package')
1740    if os.path.isdir(_component_package_path):
1741        try:
1742            print('del dir component_package start..')
1743            shutil.rmtree(_component_package_path)
1744            print('del dir component_package end..')
1745        except Exception as e:
1746            print('del dir component_package FAILED')
1747
1748
1749def _get_component_check(local_test) -> list:
1750    check_list = []
1751    if local_test == 0:
1752        contents = urllib.request.urlopen(
1753            "https://ci.openharmony.cn/api/daily_build/component/check/list").read().decode(
1754            encoding="utf-8")
1755        _check_json = json.loads(contents)
1756        try:
1757            check_list.extend(_check_json["data"]["dep_list"])
1758            check_list.extend(_check_json["data"]["indep_list"])
1759        except Exception as e:
1760            print("Call the component check API something wrong, plz check the API return..")
1761    check_list = list(set(check_list))
1762    check_list = sorted(check_list)
1763    return check_list
1764
1765
1766def _package_interface(args, parts_path_info, part_name, subsystem_name, components_json):
1767    part_path = _get_parts_path(parts_path_info, part_name)
1768    if part_path is None:
1769        return
1770    args.update({"subsystem_name": subsystem_name, "part_name": part_name,
1771                 "part_path": part_path})
1772    if part_name in [
1773        "musl",  # 从obj/third_party/musl/usr 下提取到includes和libs
1774        "developer_test",  # 同rust
1775        "drivers_interface_display",  # 驱动的, 新建一个libs目录/ innerapi同名文件
1776        "runtime_core",  # 编译参数, 所有下面的innerapi的cflags都不
1777        "drivers_interface_usb",  # 同驱动
1778        "drivers_interface_ril",  # 同驱动
1779    ]:
1780        _process_part(args, parts_path_info, part_name, subsystem_name, components_json)
1781    else:
1782        _generate_component_package(args, components_json)
1783
1784
1785def _get_exclusion_list(root_path):
1786    part_black_list_path = os.path.join(root_path, "build", "indep_configs", "config",
1787                                        "binary_package_exclusion_list.json")
1788    data = []
1789    try:
1790        with open(part_black_list_path, 'r') as f:
1791            data = json.load(f)
1792    except FileNotFoundError:
1793        print(f"can not find file: {part_black_list_path}.")
1794    except Exception as e:
1795        print(f"{part_black_list_path}: \n {e}")
1796    return data
1797
1798
1799def generate_component_package(out_path, root_path, components_list=None, build_type=0, organization_name='ohos',
1800                               os_arg='linux', build_arch_arg='x86', local_test=0):
1801    """
1802
1803    Args:
1804        out_path: output path of code default : out/rk3568
1805        root_path: root path of code default : oh/
1806        components_list: list of all components that need to be built
1807        build_type: build type
1808            0: default pack,do not change organization_name
1809            1: pack ,change organization_name
1810            2: do not pack,do not change organization_name
1811        organization_name: default ohos, if diff then change
1812        os_arg: default : linux
1813        build_arch_arg:  default : x86
1814        local_test: 1 to open local test , default 0 to close
1815    Returns:
1816
1817    """
1818    start_time = time.time()
1819    components_json = _get_components_json(out_path)
1820    components_json.update({"rust": {
1821        "innerapis": [],
1822        "path": "third_party/rust",
1823        "subsystem": "thirdparty",
1824        "variants": []
1825    },
1826        "developer_test": {
1827            "innerapis": [],
1828            "path": "test/testfwk/developer_test",
1829            "subsystem": "testfwk",
1830            "variants": []
1831        }
1832    })
1833    part_subsystem = _get_part_subsystem(components_json)
1834    parts_path_info = _get_parts_path_info(components_json)
1835    hpm_packages_path = _make_hpm_packages_dir(root_path)
1836    toolchain_info = _get_toolchain_info(root_path)
1837
1838    ### add
1839    exclusion_list = _get_exclusion_list(root_path)  # 黑名单列表
1840    # 如果没有提供 components_list,则默认为所有非黑名单组件
1841    all_components = components_json.keys()
1842    if local_test == 1:
1843        components_list = components_list.split(",") if components_list else all_components
1844    elif local_test == 0:
1845        if components_list:
1846            components_list = [component for component in components_list.split(",") if component not in exclusion_list]
1847        else:
1848            components_list = [component for component in all_components if component not in exclusion_list]
1849        # 如果 components_list 为空,则退出程序
1850        if not components_list:
1851            sys.exit("stop for no target to pack..")
1852    print('components_list', components_list)
1853
1854    # del component_package
1855    _del_exist_component_package(out_path)
1856    args = {"out_path": out_path, "root_path": root_path,
1857            "os": os_arg, "buildArch": build_arch_arg, "hpm_packages_path": hpm_packages_path,
1858            "build_type": build_type, "organization_name": organization_name,
1859            "toolchain_info": toolchain_info
1860            }
1861    for key, value in part_subsystem.items():
1862        part_name = key
1863        subsystem_name = value
1864        if not components_list or part_name in components_list:
1865            _package_interface(args, parts_path_info, part_name, subsystem_name, components_json)
1866    end_time = time.time()
1867    run_time = end_time - start_time
1868    print("generate_component_package out_path", out_path)
1869    print(f"Generating binary product package takes time:{run_time}")
1870
1871
1872def main():
1873    py_args = _get_args()
1874    generate_component_package(py_args.out_path,
1875                               py_args.root_path,
1876                               components_list=py_args.components_list,
1877                               build_type=py_args.build_type,
1878                               organization_name=py_args.organization_name,
1879                               os_arg=py_args.os_arg,
1880                               build_arch_arg=py_args.build_arch,
1881                               local_test=py_args.local_test)
1882
1883
1884if __name__ == '__main__':
1885    main()
1886