• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright (c) 2021 Huawei Device Co., Ltd.
2# Licensed under the Apache License, Version 2.0 (the "License");
3# you may not use this file except in compliance with the License.
4# You may obtain a copy of the License at
5#
6#     http://www.apache.org/licenses/LICENSE-2.0
7#
8# Unless required by applicable law or agreed to in writing, software
9# distributed under the License is distributed on an "AS IS" BASIS,
10# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11# See the License for the specific language governing permissions and
12# limitations under the License.
13
14import("//build/config/clang/clang.gni")
15import("//build/config/ohos/config.gni")
16import("//build/config/security/security_config.gni")
17import("//build/ohos/notice/notice.gni")
18import("//build/ohos_var.gni")
19import("//build/templates/common/check_target.gni")
20import("//build/templates/common/collect_target.gni")
21import("//build/templates/metadata/module_info.gni")
22
23declare_args() {
24  # Compile with no sanitize check, for local debug only
25  allow_sanitize_debug = false
26}
27
28default_opt_configs = [
29  "//build/config/compiler:default_symbols",
30  "//build/config/compiler:default_optimization",
31]
32
33debug_level_configs = [
34  "//build/config/compiler:symbols",
35  "//build/config/compiler:no_optimize",
36]
37
38template("ohos_executable") {
39  assert(!defined(invoker.output_dir),
40         "output_dir is not allowed to be defined.")
41
42  _test_target = defined(invoker.testonly) && invoker.testonly
43  if (defined(invoker.subsystem_name) && defined(invoker.part_name)) {
44    subsystem_name = invoker.subsystem_name
45    part_name = invoker.part_name
46  } else if (defined(invoker.part_name)) {
47    part_name = invoker.part_name
48    _part_subsystem_info_file =
49        "$root_build_dir/build_configs/parts_info/part_subsystem.json"
50    _arguments = [
51      "--part-name",
52      part_name,
53      "--part-subsystem-info-file",
54      rebase_path(_part_subsystem_info_file, root_build_dir),
55    ]
56    get_subsystem_script = "//build/templates/common/get_subsystem_name.py"
57    subsystem_name =
58        exec_script(get_subsystem_script, _arguments, "trim string")
59    if (is_use_check_deps && !_test_target) {
60      skip_check_subsystem = true
61    }
62  } else if (defined(invoker.subsystem_name)) {
63    subsystem_name = invoker.subsystem_name
64    part_name = subsystem_name
65  } else {
66    subsystem_name = "build"
67    part_name = "build_framework"
68  }
69  assert(subsystem_name != "")
70  assert(part_name != "")
71
72  module_label = get_label_info(":${target_name}", "label_with_toolchain")
73  _collect_target = "${target_name}__collect"
74  collect_module_target(_collect_target) {
75    forward_variables_from(invoker, [ "install_images" ])
76  }
77
78  if (is_use_check_deps && !_test_target) {
79    _check_target = "${target_name}__check"
80    target_path = get_label_info(":${target_name}", "label_no_toolchain")
81    check_target(_check_target) {
82      module_deps = []
83      module_ex_deps = []
84      if (defined(invoker.deps)) {
85        module_deps += invoker.deps
86      }
87      if (defined(invoker.public_deps)) {
88        module_deps += invoker.public_deps
89      }
90      if (defined(invoker.external_deps)) {
91        module_ex_deps += invoker.external_deps
92      }
93      if (defined(invoker.public_external_deps)) {
94        module_ex_deps += invoker.public_external_deps
95      }
96    }
97  }
98
99  if (check_deps) {
100    deps_data = {
101    }
102    module_label = get_label_info(":${target_name}", "label_with_toolchain")
103    module_deps = []
104    if (defined(invoker.deps)) {
105      foreach(dep, invoker.deps) {
106        module_deps += [ get_label_info(dep, "label_no_toolchain") ]
107      }
108    }
109    module_ex_deps = []
110    if (defined(invoker.external_deps) && invoker.external_deps != []) {
111      module_ex_deps = invoker.external_deps
112    }
113    deps_data = {
114      part_name = part_name
115      module_label = module_label
116      deps = module_deps
117      external_deps = module_ex_deps
118    }
119
120    write_file("${root_out_dir}/deps_files/${part_name}__${target_name}.json",
121               deps_data,
122               "json")
123  }
124
125  _ohos_test = false
126  if (defined(invoker.ohos_test) && invoker.ohos_test) {
127    output_dir = invoker.test_output_dir
128    _ohos_test = true
129  } else {
130    if (is_standard_system) {
131      output_dir = "${root_out_dir}/${subsystem_name}/${part_name}"
132    } else {
133      output_dir = "${root_out_dir}"
134    }
135  }
136
137  _security_config_target = "${target_name}__security_config"
138  ohos_security_config(_security_config_target) {
139    forward_variables_from(invoker, [ "auto_var_init" ])
140  }
141
142  if (!allow_sanitize_debug && !build_xts &&
143      defined(ext_sanitizer_check_list_path)) {
144    build_name = "${target_name}"
145    ohos_sanitizer_check("${target_name}_sanitizer_check") {
146      forward_variables_from(invoker, [ "sanitize" ])
147    }
148  }
149
150  _sanitize_config_target = "${target_name}__sanitizer_config"
151  ohos_sanitizer_config(_sanitize_config_target) {
152    forward_variables_from(invoker, [ "sanitize" ])
153  }
154
155  if (!_test_target) {
156    _main_target_name = target_name
157    _notice_target = "${_main_target_name}__notice"
158    collect_notice(_notice_target) {
159      forward_variables_from(invoker,
160                             [
161                               "testonly",
162                               "license_as_sources",
163                               "license_file",
164                             ])
165
166      module_name = _main_target_name
167      module_source_dir = get_label_info(":${_main_target_name}", "dir")
168    }
169  }
170  target_label = get_label_info(":${target_name}", "label_with_toolchain")
171  target_toolchain = get_label_info(target_label, "toolchain")
172
173  if (!_ohos_test) {
174    ohos_module_name = target_name
175    _module_info_target = "${target_name}_info"
176    generate_module_info(_module_info_target) {
177      forward_variables_from(invoker, [ "testonly" ])
178      module_name = ohos_module_name
179      module_type = "bin"
180
181      module_source_dir = "$root_out_dir"
182      if (defined(output_dir)) {
183        module_source_dir = output_dir
184      }
185
186      module_install_name = ohos_module_name
187      if (defined(invoker.output_name)) {
188        module_install_name = invoker.output_name
189      }
190
191      module_install_images = [ "system" ]
192      if (defined(invoker.install_images)) {
193        module_install_images = []
194        module_install_images += invoker.install_images
195      }
196
197      module_output_extension = executable_extension
198      if (defined(invoker.output_extension)) {
199        module_output_extension = "." + invoker.output_extension
200      }
201
202      if (is_double_framework) {
203        install_enable = false
204      } else {
205        install_enable = true
206      }
207      if (defined(invoker.install_enable)) {
208        install_enable = invoker.install_enable
209      }
210
211      if (defined(invoker.module_install_dir)) {
212        module_install_dir = invoker.module_install_dir
213      }
214
215      if (defined(invoker.relative_install_dir)) {
216        relative_install_dir = invoker.relative_install_dir
217      }
218
219      if (defined(invoker.symlink_target_name)) {
220        symlink_target_name = invoker.symlink_target_name
221      }
222
223      if (defined(invoker.version_script)) {
224        version_script = rebase_path(invoker.version_script, root_build_dir)
225      }
226      notice = "$target_out_dir/$ohos_module_name.notice.txt"
227    }
228    if (defined(invoker.kernel_permission_path)) {
229      kernel_permission_info = []
230      _kernel_permission_path =
231          rebase_path(invoker.kernel_permission_path, root_build_dir)
232      _module_info_file =
233          rebase_path(get_label_info(target_label, "target_out_dir"),
234                      root_build_dir) + "/${target_name}_module_info.json"
235      kernel_permission_info_file = "${root_build_dir}/build_configs/kernel_permission/${target_name}_info_file.json"
236      _output_name = ""
237      if (defined(invoker.output_name)) {
238        _output_name = invoker.output_name
239      }
240      _output_extension = ""
241      if (defined(invoker.output_extension)) {
242        _output_extension = "." + invoker.output_extension
243      }
244      kernel_permission_info += [
245        {
246          module_info_file = _module_info_file
247          kernel_permission_path = _kernel_permission_path
248          target_name = target_name
249          subsystem_name = subsystem_name
250          target_label = target_label
251          part_name = part_name
252          type = "bin"
253          gn_output_name = _output_name
254          gn_output_extension = _output_extension
255        },
256      ]
257      write_file("${kernel_permission_info_file}",
258                 kernel_permission_info,
259                 "json")
260    }
261  }
262
263  if (!defined(invoker.stable)) {
264    stable = false
265  }
266
267  executable("${target_name}") {
268    forward_variables_from(invoker,
269                           "*",
270                           [
271                             "configs",
272                             "remove_configs",
273                             "static_link",
274                             "install_images",
275                             "module_install_dir",
276                             "relative_install_dir",
277                             "symlink_target_name",
278                             "output_dir",
279                             "install_enable",
280                             "version_script",
281                             "license_file",
282                             "license_as_sources",
283                             "use_exceptions",
284                             "use_rtti",
285
286                             # Sanitizer variables
287                             "sanitize",
288                             "crate_type",
289                             "stack_protector_ret",
290                             "branch_protector_ret",
291                             "branch_protector_frt",
292                           ])
293    output_dir = output_dir
294
295    if (defined(invoker.configs)) {
296      configs += invoker.configs
297    }
298    if (defined(invoker.remove_configs)) {
299      configs -= invoker.remove_configs
300    }
301    configs += [ ":$_sanitize_config_target" ]
302    configs += [ ":$_security_config_target" ]
303
304    if (defined(invoker.use_exceptions) && invoker.use_exceptions) {
305      configs += [ "//build/config/compiler:exceptions" ]
306      configs -= [ "//build/config/compiler:no_exceptions" ]
307    }
308
309    if (defined(invoker.use_rtti) && invoker.use_rtti) {
310      configs += [ "//build/config/compiler:rtti" ]
311      configs -= [ "//build/config/compiler:no_rtti" ]
312    }
313
314    if (!defined(cflags)) {
315      cflags = []
316    }
317
318    # Enable branch protection.
319    pac_ret = false
320    bti = false
321    if (defined(invoker.branch_protector_ret)) {
322      if (invoker.branch_protector_ret == "pac_ret" ||
323          invoker.branch_protector_ret == "stack_protector_ret_all") {
324        if (support_branch_protector_pac_ret) {
325          pac_ret = true
326        } else if (support_stack_protector_ret) {
327          foreach(config, configs) {
328            if (config ==
329                "//build/config/security:stack_protector_ret_strong_config") {
330              configs -= [
331                "//build/config/security:stack_protector_ret_strong_config",
332              ]
333            }
334          }
335          configs +=
336              [ "//build/config/security:stack_protector_ret_all_config" ]
337        }
338      }
339
340      # Nothing to do, supported by default.
341      if (support_stack_protector_ret &&
342          invoker.branch_protector_ret == "stack_protector_ret_strong") {
343      }
344    } else {
345      if (defined(invoker.stack_protector_ret)) {
346        if (invoker.stack_protector_ret) {
347          if (support_branch_protector_pac_ret) {
348            pac_ret = true
349          } else if (support_stack_protector_ret) {
350            foreach(config, configs) {
351              if (config ==
352                  "//build/config/security:stack_protector_ret_strong_config") {
353                configs -= [
354                  "//build/config/security:stack_protector_ret_strong_config",
355                ]
356              }
357            }
358            configs +=
359                [ "//build/config/security:stack_protector_ret_all_config" ]
360          }
361        } else {
362          foreach(config, configs) {
363            if (config ==
364                "//build/config/security:stack_protector_ret_strong_config") {
365              configs -= [
366                "//build/config/security:stack_protector_ret_strong_config",
367              ]
368            }
369          }
370          configs += [ "//build/config/security:stack_protector_config" ]
371        }
372      }
373    }
374
375    if (defined(invoker.branch_protector_frt)) {
376      if (invoker.branch_protector_frt == "bti" &&
377          support_branch_protector_bti) {
378        bti = true
379      }
380    }
381
382    if (!defined(ldflags)) {
383      ldflags = []
384    }
385
386    if (bti && pac_ret) {
387      cflags += [ "-mbranch-protection=pac-ret+b-key+bti" ]
388      ldflags += [ "-Wl,-z,force-bti" ]
389    } else if (bti && !pac_ret) {
390      cflags += [ "-mbranch-protection=bti" ]
391      ldflags += [ "-Wl,-z,force-bti" ]
392    } else if (!bti && pac_ret) {
393      cflags += [ "-mbranch-protection=pac-ret+b-key" ]
394    }
395
396    if (!defined(deps)) {
397      deps = []
398    }
399    if (is_use_check_deps && !_test_target) {
400      deps += [ ":$_check_target" ]
401    }
402    if (!_ohos_test && !skip_gen_module_info) {
403      deps += [ ":$_module_info_target" ]
404    }
405
406    deps += [ ":${_collect_target}" ]
407
408    if (!defined(libs)) {
409      libs = []
410    }
411    if (!defined(include_dirs)) {
412      include_dirs = []
413    }
414
415    if (defined(visibility) && visibility != []) {
416      visibility += [ "//build/*" ]
417      if (defined(build_ext_path)) {
418        visibility += [ "${build_ext_path}/*" ]
419      }
420    }
421
422    if (defined(invoker.static_link) && invoker.static_link) {
423      no_default_deps = true
424      configs -= [ "//build/config:executable_config" ]
425      ldflags += [ "-static" ]
426      if (is_ohos && use_musl) {
427        import("//build/config/ohos/musl.gni")
428        if (defined(external_deps)) {
429          external_deps += [ "musl:soft_libc_musl_static" ]
430        } else {
431          external_deps = [ "musl:soft_libc_musl_static" ]
432        }
433      }
434    } else if (is_ohos) {
435      if (current_cpu == "arm" || current_cpu == "arm64" ||
436          current_cpu == "riscv64" || current_cpu == "loongarch64") {
437        libs += [ "unwind" ]
438      }
439      libs += [
440        rebase_path(libclang_rt_file),
441        "c++",
442      ]
443    }
444
445    if (!defined(output_name)) {
446      output_name = target_name
447    }
448
449    if (defined(invoker.version_script)) {
450      _version_script = rebase_path(invoker.version_script, root_build_dir)
451      if (!defined(ldflags)) {
452        ldflags = []
453      }
454      ldflags += [
455        "-rdynamic",
456        "-Wl,--version-script=${_version_script}",
457      ]
458    }
459
460    # We don't need to change config when "is_debug==true"
461    # "enable_debug_components" isn't blank means some components using debug level compilation
462    if (defined(is_debug) && !is_debug && enable_debug_components != "") {
463      foreach(component_name, debug_components) {
464        if (part_name == component_name) {
465          configs -= default_opt_configs
466          configs += debug_level_configs
467        }
468      }
469    }
470    if (target_toolchain == "${current_toolchain}") {
471      install_module_info = {
472        module_def = target_label
473        part_name = part_name
474        module_info_file =
475            rebase_path(get_label_info(module_def, "target_out_dir"),
476                        root_build_dir) + "/${target_name}_module_info.json"
477        subsystem_name = subsystem_name
478        part_name = part_name
479        toolchain = current_toolchain
480        toolchain_out_dir = rebase_path(root_out_dir, root_build_dir)
481      }
482      metadata = {
483        install_modules = [ install_module_info ]
484      }
485    }
486    if (!_test_target) {
487      deps += [ ":$_notice_target" ]
488    }
489
490    module_label = get_label_info(":${target_name}", "label_with_toolchain")
491
492    deps_info = []
493    foreach(dep, deps) {
494      info = {
495      }
496      info = {
497        target_out_dir =
498            rebase_path(get_label_info(dep, "target_out_dir"), root_build_dir)
499        target_name = get_label_info(dep, "name")
500      }
501      deps_info += [ info ]
502    }
503    target_deps_data = {
504      label = module_label
505      module_deps_info = deps_info
506      module_libs = libs
507      type = "executable"
508      prebuilt = false
509      stable = stable
510      toolchain = get_label_info(":${target_name}", "toolchain")
511    }
512    write_file("${target_out_dir}/${target_name}_deps_data.json",
513               target_deps_data,
514               "json")
515  }
516}
517
518# Defines a shared_library
519#
520# The shared_library template is used to generated so file.
521#
522# Parameters
523#
524#   subsystem_name (required)
525#   [string]
526#   configs (optional)
527#   [list]
528#   remove_cnofigs (optional)
529#   [list]
530#   version_script (optional)
531#   [string]
532template("ohos_shared_library") {
533  assert(!defined(invoker.output_dir),
534         "output_dir is not allowed to be defined.")
535
536  _test_target = defined(invoker.testonly) && invoker.testonly
537  if (defined(invoker.subsystem_name) && defined(invoker.part_name)) {
538    subsystem_name = invoker.subsystem_name
539    part_name = invoker.part_name
540  } else if (defined(invoker.part_name)) {
541    part_name = invoker.part_name
542    _part_subsystem_info_file =
543        "$root_build_dir/build_configs/parts_info/part_subsystem.json"
544    _arguments = [
545      "--part-name",
546      part_name,
547      "--part-subsystem-info-file",
548      rebase_path(_part_subsystem_info_file, root_build_dir),
549    ]
550    get_subsystem_script = "//build/templates/common/get_subsystem_name.py"
551    subsystem_name =
552        exec_script(get_subsystem_script, _arguments, "trim string")
553    if (is_use_check_deps && !_test_target) {
554      skip_check_subsystem = true
555    }
556  } else if (defined(invoker.subsystem_name)) {
557    subsystem_name = invoker.subsystem_name
558    part_name = subsystem_name
559  } else {
560    subsystem_name = "build"
561    part_name = "build_framework"
562  }
563  assert(subsystem_name != "")
564  assert(part_name != "")
565
566  module_label = get_label_info(":${target_name}", "label_with_toolchain")
567  _collect_target = "${target_name}__collect"
568  collect_module_target(_collect_target) {
569    forward_variables_from(invoker, [ "install_images" ])
570  }
571
572  if (is_use_check_deps && !_test_target) {
573    _check_target = "${target_name}__check"
574    target_path = get_label_info(":${target_name}", "label_no_toolchain")
575    check_target(_check_target) {
576      module_deps = []
577      module_ex_deps = []
578      if (defined(invoker.deps)) {
579        module_deps += invoker.deps
580      }
581      if (defined(invoker.public_deps)) {
582        module_deps += invoker.public_deps
583      }
584      if (defined(invoker.external_deps)) {
585        module_ex_deps += invoker.external_deps
586      }
587      if (defined(invoker.public_external_deps)) {
588        module_ex_deps += invoker.public_external_deps
589      }
590    }
591  }
592
593  # auto set auto_relative_install_dir by innerapi_tags
594  if (defined(invoker.innerapi_tags)) {
595    is_chipsetsdk = false
596    is_platformsdk = false
597    is_passthrough = false
598    foreach(tag, filter_include(invoker.innerapi_tags, [ "chipsetsdk*" ])) {
599      is_chipsetsdk = true
600    }
601    foreach(tag, filter_include(invoker.innerapi_tags, [ "platformsdk*" ])) {
602      is_platformsdk = true
603    }
604    foreach(tag, filter_include(invoker.innerapi_tags, [ "passthrough*" ])) {
605      is_passthrough = true
606    }
607
608    if (is_chipsetsdk && is_platformsdk) {
609      auto_relative_install_dir = "chipset-pub-sdk"
610    } else if (is_chipsetsdk) {
611      auto_relative_install_dir = "chipset-sdk"
612    } else if (is_platformsdk) {
613      auto_relative_install_dir = "platformsdk"
614    }
615    if (is_passthrough) {
616      auto_relative_install_dir = chipset_passthrough_dir
617    }
618
619    is_ndk = false
620    foreach(tag, filter_include(invoker.innerapi_tags, [ "ndk" ])) {
621      is_ndk = true
622    }
623    if (is_ndk) {
624      auto_relative_install_dir = "ndk"
625    }
626  }
627
628  if (check_deps) {
629    deps_data = {
630    }
631    module_label = get_label_info(":${target_name}", "label_with_toolchain")
632    module_deps = []
633    if (defined(invoker.deps)) {
634      foreach(dep, invoker.deps) {
635        module_deps += [ get_label_info(dep, "label_no_toolchain") ]
636      }
637    }
638    module_ex_deps = []
639    if (defined(invoker.external_deps) && invoker.external_deps != []) {
640      module_ex_deps = invoker.external_deps
641    }
642    deps_data = {
643      part_name = part_name
644      module_label = module_label
645      deps = module_deps
646      external_deps = module_ex_deps
647    }
648    write_file("${root_out_dir}/deps_files/${part_name}__${target_name}.json",
649               deps_data,
650               "json")
651  }
652
653  if (is_standard_system) {
654    output_dir = "${root_out_dir}/${subsystem_name}/${part_name}"
655  } else {
656    output_dir = "${root_out_dir}"
657  }
658
659  _security_config_target = "${target_name}__security_config"
660  ohos_security_config(_security_config_target) {
661    forward_variables_from(invoker, [ "auto_var_init" ])
662  }
663
664  if (!allow_sanitize_debug && !build_xts &&
665      defined(ext_sanitizer_check_list_path)) {
666    build_name = "${target_name}"
667    ohos_sanitizer_check("${target_name}_sanitizer_check") {
668      forward_variables_from(invoker, [ "sanitize" ])
669    }
670  }
671
672  _sanitize_config_target = "${target_name}__sanitizer_config"
673  ohos_sanitizer_config(_sanitize_config_target) {
674    forward_variables_from(invoker, [ "sanitize" ])
675  }
676
677  if (!_test_target) {
678    _notice_target = "${target_name}__notice"
679    _main_target_name = target_name
680    collect_notice(_notice_target) {
681      forward_variables_from(invoker,
682                             [
683                               "testonly",
684                               "license_as_sources",
685                               "license_file",
686                             ])
687
688      module_name = _main_target_name
689      module_source_dir = get_label_info(":${_main_target_name}", "dir")
690    }
691  }
692
693  target_label = get_label_info(":${target_name}", "label_with_toolchain")
694  target_toolchain = get_label_info(target_label, "toolchain")
695
696  if (target_toolchain == "${current_toolchain}") {
697    ohos_module_name = target_name
698    _module_info_target = "${target_name}_info"
699    generate_module_info(_module_info_target) {
700      forward_variables_from(invoker, [ "testonly" ])
701      module_name = ohos_module_name
702      module_type = "lib"
703      module_source_dir = "$root_out_dir"
704      if (defined(output_dir)) {
705        module_source_dir = output_dir
706      }
707
708      module_install_name = ohos_module_name
709      if (defined(invoker.output_name)) {
710        module_install_name = invoker.output_name
711      }
712
713      module_install_images = [ "system" ]
714      if (defined(invoker.install_images)) {
715        module_install_images = []
716        module_install_images += invoker.install_images
717      }
718
719      module_output_extension = shlib_extension
720      if (defined(invoker.output_extension)) {
721        module_output_extension = "." + invoker.output_extension
722      }
723
724      install_enable = true
725      if (defined(invoker.install_enable)) {
726        install_enable = invoker.install_enable
727      }
728
729      if (defined(invoker.module_install_dir)) {
730        module_install_dir = invoker.module_install_dir
731      }
732
733      if (defined(invoker.symlink_target_name)) {
734        symlink_target_name = invoker.symlink_target_name
735      }
736
737      if (defined(invoker.output_prefix_override)) {
738        output_prefix_override = invoker.output_prefix_override
739      }
740      notice = "$target_out_dir/$ohos_module_name.notice.txt"
741
742      # update relative_install_dir if auto_relative_install_dir defined
743      if (defined(auto_relative_install_dir)) {
744        relative_install_dir = auto_relative_install_dir
745      }
746
747      # update relative_install_dir if relative_install_dir defined in BUILD.gn
748      if (defined(invoker.relative_install_dir)) {
749        relative_install_dir = invoker.relative_install_dir
750      }
751
752      # Passing shlib_type and innerapi_tags to generate_module_info
753      if (defined(invoker.shlib_type)) {
754        invalid = true
755        valid_types = [
756          "sa",
757          "sa_stub",
758          "sa_proxy",
759          "hdi",
760          "hdi_stub",
761          "hdi_proxy",
762          "innerapi",
763          "napi",
764        ]
765        foreach(t, filter_include(valid_types, [ invoker.shlib_type ])) {
766          if (t == invoker.shlib_type) {
767            invalid = false
768          }
769        }
770        shlib_type = invoker.shlib_type
771        assert(
772            invalid != true,
773            "$target_label has invalid shlib_type value: $shlib_type, allowed values: $valid_types")
774      }
775      if (defined(invoker.innerapi_tags)) {
776        invalid = false
777        valid_tags = [
778          "ndk",
779          "chipsetsdk",
780          "chipsetsdk_indirect",
781          "platformsdk",
782          "platformsdk_indirect",
783          "passthrough",
784          "passthrough_indirect",
785          "sasdk",
786        ]
787        foreach(tag, filter_exclude(invoker.innerapi_tags, valid_tags)) {
788          if (tag != "") {
789            invalid = true
790          }
791        }
792        innerapi_tags = invoker.innerapi_tags
793        assert(
794            invalid != true,
795            "$target_label has invalid innerapi_tags $innerapi_tags, allowed values: $valid_tags")
796      }
797
798      if (defined(invoker.version_script)) {
799        version_script = rebase_path(invoker.version_script, root_build_dir)
800      }
801    }
802  }
803
804  if (!defined(invoker.stable)) {
805    stable = false
806  }
807
808  if (defined(invoker.kernel_permission_path)) {
809    kernel_permission_info = []
810    _kernel_permission_path =
811        rebase_path(invoker.kernel_permission_path, root_build_dir)
812    _module_info_file =
813        rebase_path(get_label_info(target_label, "target_out_dir"),
814                    root_build_dir) + "/${target_name}_module_info.json"
815    kernel_permission_info_file = "${root_build_dir}/build_configs/kernel_permission/${target_name}_info_file.json"
816    _output_name = ""
817    if (defined(invoker.output_name)) {
818      _output_name = invoker.output_name
819    }
820    _output_extension = ""
821    if (defined(invoker.output_extension)) {
822      _output_extension = "." + invoker.output_extension
823    }
824    kernel_permission_info += [
825      {
826        module_info_file = _module_info_file
827        kernel_permission_path = _kernel_permission_path
828        target_name = target_name
829        subsystem_name = subsystem_name
830        target_label = target_label
831        part_name = part_name
832        type = "lib"
833        gn_output_name = _output_name
834        gn_output_extension = _output_extension
835      },
836    ]
837    write_file("${kernel_permission_info_file}", kernel_permission_info, "json")
838  }
839
840  shared_library("${target_name}") {
841    forward_variables_from(invoker,
842                           "*",
843                           [
844                             "configs",
845                             "remove_configs",
846                             "no_default_deps",
847                             "install_images",
848                             "module_install_dir",
849                             "relative_install_dir",
850                             "symlink_target_name",
851                             "output_dir",
852                             "install_enable",
853                             "version_script",
854                             "exported_symbols_list",
855                             "license_file",
856                             "license_as_sources",
857                             "use_exceptions",
858                             "use_rtti",
859                             "stl",
860
861                             # Sanitizer variables
862                             "sanitize",
863                             "stack_protector_ret",
864                             "branch_protector_ret",
865                             "branch_protector_frt",
866                           ])
867    output_dir = output_dir
868
869    if (!defined(inputs)) {
870      inputs = []
871    }
872
873    if (!defined(ldflags)) {
874      ldflags = []
875    }
876
877    if (defined(invoker.configs)) {
878      configs += invoker.configs
879    }
880    if (defined(invoker.remove_configs)) {
881      configs -= invoker.remove_configs
882    }
883
884    configs += [ ":$_sanitize_config_target" ]
885    configs += [ ":$_security_config_target" ]
886
887    if (defined(invoker.use_exceptions) && invoker.use_exceptions) {
888      configs += [ "//build/config/compiler:exceptions" ]
889      configs -= [ "//build/config/compiler:no_exceptions" ]
890    }
891
892    if (defined(invoker.use_rtti) && invoker.use_rtti) {
893      configs += [ "//build/config/compiler:rtti" ]
894      configs -= [ "//build/config/compiler:no_rtti" ]
895    }
896
897    if (!defined(cflags)) {
898      cflags = []
899    }
900
901    if (defined(visibility) && visibility != []) {
902      visibility += [ "//build/*" ]
903      if (defined(build_ext_path)) {
904        visibility += [ "${build_ext_path}/*" ]
905      }
906    }
907
908    # Enable branch protection.
909    pac_ret = false
910    bti = false
911    if (defined(invoker.branch_protector_ret)) {
912      if (invoker.branch_protector_ret == "pac_ret" ||
913          invoker.branch_protector_ret == "stack_protector_ret_all") {
914        if (support_branch_protector_pac_ret) {
915          pac_ret = true
916        } else if (support_stack_protector_ret) {
917          foreach(config, configs) {
918            if (config ==
919                "//build/config/security:stack_protector_ret_strong_config") {
920              configs -= [
921                "//build/config/security:stack_protector_ret_strong_config",
922              ]
923            }
924          }
925          configs +=
926              [ "//build/config/security:stack_protector_ret_all_config" ]
927        }
928      }
929
930      # Nothing to do, supported by default.
931      if (support_stack_protector_ret &&
932          invoker.branch_protector_ret == "stack_protector_ret_strong") {
933      }
934    } else {
935      if (defined(invoker.stack_protector_ret)) {
936        if (invoker.stack_protector_ret) {
937          if (support_branch_protector_pac_ret) {
938            pac_ret = true
939          } else if (support_stack_protector_ret) {
940            foreach(config, configs) {
941              if (config ==
942                  "//build/config/security:stack_protector_ret_strong_config") {
943                configs -= [
944                  "//build/config/security:stack_protector_ret_strong_config",
945                ]
946              }
947            }
948            configs +=
949                [ "//build/config/security:stack_protector_ret_all_config" ]
950          }
951        } else {
952          foreach(config, configs) {
953            if (config ==
954                "//build/config/security:stack_protector_ret_strong_config") {
955              configs -= [
956                "//build/config/security:stack_protector_ret_strong_config",
957              ]
958            }
959          }
960          configs += [ "//build/config/security:stack_protector_config" ]
961        }
962      }
963    }
964
965    if (defined(invoker.branch_protector_frt)) {
966      if (invoker.branch_protector_frt == "bti" &&
967          support_branch_protector_bti) {
968        bti = true
969      }
970    }
971
972    if (bti && pac_ret) {
973      cflags += [ "-mbranch-protection=pac-ret+b-key+bti" ]
974      ldflags += [ "-Wl,-z,force-bti" ]
975    } else if (bti && !pac_ret) {
976      cflags += [ "-mbranch-protection=bti" ]
977      ldflags += [ "-Wl,-z,force-bti" ]
978    } else if (!bti && pac_ret) {
979      cflags += [ "-mbranch-protection=pac-ret+b-key" ]
980    }
981
982    # check whether to add adlt configs
983    install_enable = true
984    if (defined(invoker.install_enable)) {
985      install_enable = invoker.install_enable
986    }
987    if (install_enable && enable_adlt && is_standard_system &&
988        target_toolchain == "${current_toolchain}" && is_ohos) {
989      inputs_args = []
990      if (target_cpu == "arm64" || target_cpu == "x86_64") {
991        module_type = "lib64"
992      } else if (target_cpu == "arm" || target_cpu == "x86") {
993        module_type = "lib"
994      } else {
995        assert(false, "Unsupported target_cpu: $target_cpu")
996      }
997      inputs_args += [
998        "--type",
999        module_type,
1000        "--system-base-dir",
1001        system_base_dir,
1002      ]
1003
1004      module_install_name = target_name
1005      if (defined(invoker.output_name)) {
1006        module_install_name = invoker.output_name
1007      }
1008      inputs_args += [
1009        "--install-name",
1010        module_install_name,
1011      ]
1012
1013      module_install_images = [ "system" ]
1014      if (defined(invoker.install_images)) {
1015        module_install_images = []
1016        module_install_images += invoker.install_images
1017      }
1018      inputs_args += [ "--install-images" ]
1019      inputs_args += module_install_images
1020
1021      if (defined(invoker.module_install_dir) &&
1022          invoker.module_install_dir != "") {
1023        inputs_args += [
1024          "--module-install-dir",
1025          invoker.module_install_dir,
1026        ]
1027      }
1028      if (defined(invoker.relative_install_dir)) {
1029        relative_install_dir = invoker.relative_install_dir
1030      }
1031      if (defined(auto_relative_install_dir)) {
1032        relative_install_dir = auto_relative_install_dir
1033      }
1034      if (defined(relative_install_dir) && relative_install_dir != "") {
1035        inputs_args += [
1036          "--relative-install-dir",
1037          relative_install_dir,
1038        ]
1039      }
1040
1041      module_output_extension = shlib_extension
1042      if (defined(invoker.output_extension)) {
1043        module_output_extension = "." + invoker.output_extension
1044      }
1045      if (module_output_extension != "") {
1046        inputs_args += [
1047          "--suffix",
1048          module_output_extension,
1049        ]
1050      }
1051
1052      if (defined(invoker.output_prefix_override) &&
1053          invoker.output_prefix_override) {
1054        inputs_args += [ "--prefix-override" ]
1055      }
1056      inputs_args += [
1057        "--allowed-lib-list",
1058        rebase_path(allowed_lib_list),
1059      ]
1060      result = exec_script("//build/ohos/images/get_module_install_dest.py",
1061                           inputs_args,
1062                           "string")
1063      if (result == "") {
1064        configs += [ "//build/config/ohos:adlt_config" ]
1065      }
1066    }
1067
1068    if (!defined(output_name)) {
1069      output_name = target_name
1070    }
1071
1072    if (defined(invoker.no_default_deps)) {
1073      no_default_deps = invoker.no_default_deps
1074    }
1075
1076    if (defined(invoker.version_script)) {
1077      _version_script = rebase_path(invoker.version_script, root_build_dir)
1078      inputs += [ invoker.version_script ]
1079      ldflags += [ "-Wl,--version-script=${_version_script}" ]
1080    }
1081
1082    if (target_os == "ios" && defined(invoker.exported_symbols_list)) {
1083      _exported_symbols_list =
1084          rebase_path(invoker.exported_symbols_list, root_build_dir)
1085      inputs += [ invoker.exported_symbols_list ]
1086      ldflags += [
1087        "-exported_symbols_list",
1088        "${_exported_symbols_list}",
1089      ]
1090    }
1091
1092    if (!defined(libs)) {
1093      libs = []
1094    }
1095    if (!defined(cflags_cc)) {
1096      cflags_cc = []
1097    }
1098    if (!defined(deps)) {
1099      deps = []
1100    }
1101    if (is_use_check_deps && !_test_target) {
1102      deps += [ ":$_check_target" ]
1103    }
1104    if (target_toolchain == "${current_toolchain}" && !skip_gen_module_info) {
1105      deps += [ ":$_module_info_target" ]
1106    }
1107
1108    deps += [ ":${_collect_target}" ]
1109    if (is_ohos) {
1110      if (defined(invoker.stl)) {
1111        cflags_cc += [
1112          "-nostdinc++",
1113          "-I" + rebase_path(
1114                  "${toolchains_dir}/${host_platform_dir}/llvm_ndk/include/libcxx-ohos/include/c++/v1",
1115                  root_build_dir),
1116        ]
1117        ldflags += [
1118          "-nostdlib++",
1119          "-L" + rebase_path("${clang_stl_path}/${abi_target}", root_build_dir),
1120        ]
1121
1122        libs += [ invoker.stl ]
1123      } else {
1124        if (current_cpu == "arm" || current_cpu == "arm64" ||
1125            current_cpu == "riscv64" || current_cpu == "loongarch64") {
1126          libs += [ "unwind" ]
1127        }
1128
1129        if (target_name != "libpcre2" && target_name != "libselinux" &&
1130            target_name != "libsec_shared" && target_name != "libsepol") {
1131          libs += [ "c++" ]
1132        }
1133      }
1134    }
1135
1136    if (!_test_target) {
1137      deps += [ ":$_notice_target" ]
1138    }
1139    if (!defined(include_dirs)) {
1140      include_dirs = []
1141    }
1142
1143    install_module_info = {
1144      module_def = target_label
1145      module_info_file =
1146          rebase_path(get_label_info(module_def, "target_out_dir"),
1147                      root_build_dir) + "/${target_name}_module_info.json"
1148      subsystem_name = subsystem_name
1149      part_name = part_name
1150      toolchain = current_toolchain
1151      toolchain_out_dir = rebase_path(root_out_dir, root_build_dir)
1152    }
1153    metadata = {
1154      install_modules = [ install_module_info ]
1155    }
1156    if (defined(is_debug) && !is_debug && enable_debug_components != "") {
1157      foreach(component_name, debug_components) {
1158        if (part_name == component_name) {
1159          configs -= default_opt_configs
1160          configs += debug_level_configs
1161        }
1162      }
1163    }
1164
1165    # Hide symbols for all sa libraries if not specified by version_script
1166    if (defined(invoker.shlib_type) && invoker.shlib_type == "sa") {
1167      if (!defined(invoker.version_script)) {
1168        _version_script =
1169            rebase_path("//build/templates/cxx/singleton.versionscript")
1170        inputs += [ _version_script ]
1171        ldflags += [ "-Wl,--version-script=${_version_script}" ]
1172      }
1173    }
1174
1175    # Set version_script for hdi service libraries
1176    if (defined(invoker.shlib_type) && invoker.shlib_type == "hdi") {
1177      if (!defined(invoker.version_script)) {
1178        _version_script = rebase_path("//build/templates/cxx/hdi.versionscript")
1179        inputs += [ _version_script ]
1180        ldflags += [ "-Wl,--version-script=${_version_script}" ]
1181      }
1182    }
1183
1184    module_type_napi = false
1185    if (defined(invoker.relative_install_dir) &&
1186        (build_ohos_sdk != true && build_ohos_ndk != true)) {
1187      relative_paths = string_split(invoker.relative_install_dir, "/")
1188      foreach(p, relative_paths) {
1189        if (p == "module") {
1190          module_type_napi = true
1191        }
1192      }
1193      if (module_type_napi) {
1194        foreach(m, filter_include(napi_white_list, [ target_name ])) {
1195          if (m == target_name) {
1196            module_type_napi = false
1197          }
1198        }
1199      }
1200    }
1201    if (module_type_napi) {
1202      if (!defined(invoker.version_script)) {
1203        _version_script =
1204            rebase_path("//build/templates/cxx/napi.versionscript")
1205        inputs += [ _version_script ]
1206        ldflags += [ "-Wl,--version-script=${_version_script}" ]
1207      }
1208    }
1209
1210    deps_info = []
1211    foreach(dep, deps) {
1212      info = {
1213      }
1214      info = {
1215        target_out_dir =
1216            rebase_path(get_label_info(dep, "target_out_dir"), root_build_dir)
1217        target_name = get_label_info(dep, "name")
1218      }
1219      deps_info += [ info ]
1220    }
1221    module_label = get_label_info(":${target_name}", "label_with_toolchain")
1222    target_deps_data = {
1223      label = module_label
1224      module_deps_info = deps_info
1225      module_libs = libs
1226      type = "shared_library"
1227      prebuilt = false
1228      stable = stable
1229      toolchain = get_label_info(":${target_name}", "toolchain")
1230    }
1231    write_file("${target_out_dir}/${target_name}_deps_data.json",
1232               target_deps_data,
1233               "json")
1234  }
1235}
1236
1237template("ohos_static_library") {
1238  _test_target = defined(invoker.testonly) && invoker.testonly
1239  if (defined(invoker.subsystem_name) && defined(invoker.part_name)) {
1240    subsystem_name = invoker.subsystem_name
1241    part_name = invoker.part_name
1242  } else if (defined(invoker.part_name)) {
1243    part_name = invoker.part_name
1244    _part_subsystem_info_file =
1245        "$root_build_dir/build_configs/parts_info/part_subsystem.json"
1246    _arguments = [
1247      "--part-name",
1248      part_name,
1249      "--part-subsystem-info-file",
1250      rebase_path(_part_subsystem_info_file, root_build_dir),
1251    ]
1252    get_subsystem_script = "//build/templates/common/get_subsystem_name.py"
1253    subsystem_name =
1254        exec_script(get_subsystem_script, _arguments, "trim string")
1255    if (is_use_check_deps && !_test_target) {
1256      skip_check_subsystem = true
1257    }
1258  } else if (defined(invoker.subsystem_name)) {
1259    subsystem_name = invoker.subsystem_name
1260    part_name = subsystem_name
1261  } else {
1262    subsystem_name = "build"
1263    part_name = "build_framework"
1264  }
1265  assert(subsystem_name != "")
1266  assert(part_name != "")
1267
1268  if (is_use_check_deps && !_test_target) {
1269    _check_target = "${target_name}__check"
1270    target_path = get_label_info(":${target_name}", "label_no_toolchain")
1271    check_target(_check_target) {
1272      module_deps = []
1273      module_ex_deps = []
1274      if (defined(invoker.deps)) {
1275        module_deps += invoker.deps
1276      }
1277      if (defined(invoker.public_deps)) {
1278        module_deps += invoker.public_deps
1279      }
1280      if (defined(invoker.external_deps)) {
1281        module_ex_deps += invoker.external_deps
1282      }
1283      if (defined(invoker.public_external_deps)) {
1284        module_ex_deps += invoker.public_external_deps
1285      }
1286    }
1287  }
1288  if (check_deps) {
1289    deps_data = {
1290    }
1291    module_label = get_label_info(":${target_name}", "label_with_toolchain")
1292    module_deps = []
1293    if (defined(invoker.deps)) {
1294      foreach(dep, invoker.deps) {
1295        module_deps += [ get_label_info(dep, "label_no_toolchain") ]
1296      }
1297    }
1298    module_ex_deps = []
1299    if (defined(invoker.external_deps) && invoker.external_deps != []) {
1300      module_ex_deps = invoker.external_deps
1301    }
1302    deps_data = {
1303      part_name = part_name
1304      module_label = module_label
1305      deps = module_deps
1306      external_deps = module_ex_deps
1307    }
1308
1309    write_file("${root_out_dir}/deps_files/${part_name}__${target_name}.json",
1310               deps_data,
1311               "json")
1312  }
1313
1314  _security_config_target = "${target_name}__security_config"
1315  ohos_security_config(_security_config_target) {
1316    forward_variables_from(invoker, [ "auto_var_init" ])
1317  }
1318
1319  if (!allow_sanitize_debug && !build_xts &&
1320      defined(ext_sanitizer_check_list_path)) {
1321    build_name = "${target_name}"
1322    ohos_sanitizer_check("${target_name}_sanitizer_check") {
1323      forward_variables_from(invoker, [ "sanitize" ])
1324    }
1325  }
1326
1327  _sanitize_config_target = "${target_name}__sanitizer_config"
1328  ohos_sanitizer_config(_sanitize_config_target) {
1329    forward_variables_from(invoker, [ "sanitize" ])
1330  }
1331
1332  if (!_test_target) {
1333    _notice_target = "${target_name}__notice"
1334    _main_target_name = target_name
1335    collect_notice(_notice_target) {
1336      forward_variables_from(invoker,
1337                             [
1338                               "testonly",
1339                               "license_as_sources",
1340                               "license_file",
1341                             ])
1342      module_type = "static_library"
1343      module_name = _main_target_name
1344      module_source_dir = get_label_info(":${_main_target_name}", "dir")
1345    }
1346  }
1347
1348  static_library(target_name) {
1349    forward_variables_from(invoker,
1350                           "*",
1351                           [
1352                             "configs",
1353                             "remove_configs",
1354                             "no_default_deps",
1355                             "license_file",
1356                             "license_as_sources",
1357                             "use_exceptions",
1358                             "use_rtti",
1359                             "subsystem_name",
1360
1361                             # Sanitizer variables
1362                             "sanitize",
1363                             "stack_protector_ret",
1364                             "branch_protector_ret",
1365                             "branch_protector_frt",
1366                           ])
1367    if (defined(invoker.configs)) {
1368      configs += invoker.configs
1369    }
1370    if (defined(invoker.remove_configs)) {
1371      configs -= invoker.remove_configs
1372    }
1373    if (is_standard_system) {
1374      configs -= [ "//build/config/compiler:thin_archive" ]
1375    }
1376    configs += [ ":$_sanitize_config_target" ]
1377    configs += [ ":$_security_config_target" ]
1378
1379    if (defined(invoker.use_exceptions) && invoker.use_exceptions) {
1380      configs += [ "//build/config/compiler:exceptions" ]
1381      configs -= [ "//build/config/compiler:no_exceptions" ]
1382    }
1383
1384    if (defined(invoker.use_rtti) && invoker.use_rtti) {
1385      configs += [ "//build/config/compiler:rtti" ]
1386      configs -= [ "//build/config/compiler:no_rtti" ]
1387    }
1388
1389    if (!defined(cflags)) {
1390      cflags = []
1391    }
1392
1393    # Enable branch protection.
1394    pac_ret = false
1395    bti = false
1396    if (defined(invoker.branch_protector_ret)) {
1397      if (invoker.branch_protector_ret == "pac_ret" ||
1398          invoker.branch_protector_ret == "stack_protector_ret_all") {
1399        if (support_branch_protector_pac_ret) {
1400          pac_ret = true
1401        } else if (support_stack_protector_ret) {
1402          foreach(config, configs) {
1403            if (config ==
1404                "//build/config/security:stack_protector_ret_strong_config") {
1405              configs -= [
1406                "//build/config/security:stack_protector_ret_strong_config",
1407              ]
1408            }
1409          }
1410          configs +=
1411              [ "//build/config/security:stack_protector_ret_all_config" ]
1412        }
1413      }
1414
1415      # Nothing to do, supported by default.
1416      if (support_stack_protector_ret &&
1417          invoker.branch_protector_ret == "stack_protector_ret_strong") {
1418      }
1419    } else {
1420      if (defined(invoker.stack_protector_ret)) {
1421        if (invoker.stack_protector_ret) {
1422          if (support_branch_protector_pac_ret) {
1423            pac_ret = true
1424          } else if (support_stack_protector_ret) {
1425            foreach(config, configs) {
1426              if (config ==
1427                  "//build/config/security:stack_protector_ret_strong_config") {
1428                configs -= [
1429                  "//build/config/security:stack_protector_ret_strong_config",
1430                ]
1431              }
1432            }
1433            configs +=
1434                [ "//build/config/security:stack_protector_ret_all_config" ]
1435          }
1436        } else {
1437          foreach(config, configs) {
1438            if (config ==
1439                "//build/config/security:stack_protector_ret_strong_config") {
1440              configs -= [
1441                "//build/config/security:stack_protector_ret_strong_config",
1442              ]
1443            }
1444          }
1445          configs += [ "//build/config/security:stack_protector_config" ]
1446        }
1447      }
1448    }
1449
1450    if (defined(invoker.branch_protector_frt)) {
1451      if (invoker.branch_protector_frt == "bti" &&
1452          support_branch_protector_bti) {
1453        bti = true
1454      }
1455    }
1456
1457    if (!defined(ldflags)) {
1458      ldflags = []
1459    }
1460
1461    if (bti && pac_ret) {
1462      cflags += [ "-mbranch-protection=pac-ret+b-key+bti" ]
1463      ldflags += [ "-Wl,-z,force-bti" ]
1464    } else if (bti && !pac_ret) {
1465      cflags += [ "-mbranch-protection=bti" ]
1466      ldflags += [ "-Wl,-z,force-bti" ]
1467    } else if (!bti && pac_ret) {
1468      cflags += [ "-mbranch-protection=pac-ret+b-key" ]
1469    }
1470
1471    if (defined(invoker.no_default_deps)) {
1472      no_default_deps = invoker.no_default_deps
1473    }
1474
1475    if (!defined(deps)) {
1476      deps = []
1477    }
1478    if (is_use_check_deps && !_test_target) {
1479      deps += [ ":$_check_target" ]
1480    }
1481    if (!_test_target) {
1482      deps += [ ":$_notice_target" ]
1483    }
1484    if (!defined(libs)) {
1485      libs = []
1486    }
1487    if (!defined(include_dirs)) {
1488      include_dirs = []
1489    }
1490
1491    if (defined(is_debug) && !is_debug && enable_debug_components != "") {
1492      foreach(component_name, debug_components) {
1493        if (part_name == component_name) {
1494          configs -= default_opt_configs
1495          configs += debug_level_configs
1496        }
1497      }
1498    }
1499
1500    deps_info = []
1501    foreach(dep, deps) {
1502      info = {
1503      }
1504      info = {
1505        target_out_dir =
1506            rebase_path(get_label_info(dep, "target_out_dir"), root_build_dir)
1507        target_name = get_label_info(dep, "name")
1508      }
1509      deps_info += [ info ]
1510    }
1511    module_label = get_label_info(":${target_name}", "label_with_toolchain")
1512    target_deps_data = {
1513      label = module_label
1514      module_deps_info = deps_info
1515      module_libs = libs
1516      type = "static_library"
1517      prebuilt = false
1518      toolchain = get_label_info(":${target_name}", "toolchain")
1519    }
1520    write_file("${target_out_dir}/${target_name}_deps_data.json",
1521               target_deps_data,
1522               "json")
1523  }
1524}
1525
1526template("ohos_source_set") {
1527  _test_target = defined(invoker.testonly) && invoker.testonly
1528  if (defined(invoker.subsystem_name) && defined(invoker.part_name)) {
1529    subsystem_name = invoker.subsystem_name
1530    part_name = invoker.part_name
1531  } else if (defined(invoker.part_name)) {
1532    part_name = invoker.part_name
1533    _part_subsystem_info_file =
1534        "$root_build_dir/build_configs/parts_info/part_subsystem.json"
1535    _arguments = [
1536      "--part-name",
1537      part_name,
1538      "--part-subsystem-info-file",
1539      rebase_path(_part_subsystem_info_file, root_build_dir),
1540    ]
1541    get_subsystem_script = "//build/templates/common/get_subsystem_name.py"
1542    subsystem_name =
1543        exec_script(get_subsystem_script, _arguments, "trim string")
1544    if (is_use_check_deps && !_test_target) {
1545      skip_check_subsystem = true
1546    }
1547  } else if (defined(invoker.subsystem_name)) {
1548    subsystem_name = invoker.subsystem_name
1549    part_name = subsystem_name
1550  } else {
1551    subsystem_name = "build"
1552    part_name = "build_framework"
1553  }
1554  assert(subsystem_name != "")
1555  assert(part_name != "")
1556
1557  if (is_use_check_deps && !_test_target) {
1558    _check_target = "${target_name}__check"
1559    target_path = get_label_info(":${target_name}", "label_no_toolchain")
1560    check_target(_check_target) {
1561      module_deps = []
1562      module_ex_deps = []
1563      if (defined(invoker.deps)) {
1564        module_deps += invoker.deps
1565      }
1566      if (defined(invoker.public_deps)) {
1567        module_deps += invoker.public_deps
1568      }
1569      if (defined(invoker.external_deps)) {
1570        module_ex_deps += invoker.external_deps
1571      }
1572      if (defined(invoker.public_external_deps)) {
1573        module_ex_deps += invoker.public_external_deps
1574      }
1575    }
1576  }
1577
1578  if (check_deps) {
1579    deps_data = {
1580    }
1581    module_label = get_label_info(":${target_name}", "label_with_toolchain")
1582    module_deps = []
1583    if (defined(invoker.deps)) {
1584      foreach(dep, invoker.deps) {
1585        module_deps += [ get_label_info(dep, "label_no_toolchain") ]
1586      }
1587    }
1588    module_ex_deps = []
1589    if (defined(invoker.external_deps) && invoker.external_deps != []) {
1590      module_ex_deps = invoker.external_deps
1591    }
1592    deps_data = {
1593      part_name = part_name
1594      module_label = module_label
1595      deps = module_deps
1596      external_deps = module_ex_deps
1597    }
1598    write_file("${root_out_dir}/deps_files/${part_name}__${target_name}.json",
1599               deps_data,
1600               "json")
1601  }
1602
1603  _security_config_target = "${target_name}__security_config"
1604  ohos_security_config(_security_config_target) {
1605    forward_variables_from(invoker, [ "auto_var_init" ])
1606  }
1607
1608  if (!allow_sanitize_debug && !build_xts &&
1609      defined(ext_sanitizer_check_list_path)) {
1610    build_name = "${target_name}"
1611    ohos_sanitizer_check("${target_name}_sanitizer_check") {
1612      forward_variables_from(invoker, [ "sanitize" ])
1613    }
1614  }
1615
1616  _sanitize_config_target = "${target_name}__sanitizer_config"
1617  ohos_sanitizer_config(_sanitize_config_target) {
1618    forward_variables_from(invoker, [ "sanitize" ])
1619  }
1620
1621  if (!_test_target) {
1622    _main_target_name = target_name
1623    _notice_target = "${_main_target_name}__notice"
1624    collect_notice(_notice_target) {
1625      forward_variables_from(invoker,
1626                             [
1627                               "testonly",
1628                               "license_as_sources",
1629                               "license_file",
1630                             ])
1631
1632      module_type = "source_set"
1633      module_name = _main_target_name
1634      module_source_dir = get_label_info(":${_main_target_name}", "dir")
1635    }
1636  }
1637
1638  source_set(target_name) {
1639    forward_variables_from(invoker,
1640                           "*",
1641                           [
1642                             "configs",
1643                             "remove_configs",
1644                             "no_default_deps",
1645                             "license_file",
1646                             "license_as_sources",
1647                             "use_exceptions",
1648                             "use_rtti",
1649                             "subsystem_name",
1650
1651                             # Sanitizer variables
1652                             "sanitize",
1653                             "stack_protector_ret",
1654                             "branch_protector_ret",
1655                             "branch_protector_frt",
1656                           ])
1657    if (defined(invoker.configs)) {
1658      configs += invoker.configs
1659    }
1660    if (defined(invoker.remove_configs)) {
1661      configs -= invoker.remove_configs
1662    }
1663
1664    configs += [ ":$_sanitize_config_target" ]
1665    configs += [ ":$_security_config_target" ]
1666
1667    if (defined(invoker.use_exceptions) && invoker.use_exceptions) {
1668      configs += [ "//build/config/compiler:exceptions" ]
1669      configs -= [ "//build/config/compiler:no_exceptions" ]
1670    }
1671
1672    if (defined(invoker.use_rtti) && invoker.use_rtti) {
1673      configs += [ "//build/config/compiler:rtti" ]
1674      configs -= [ "//build/config/compiler:no_rtti" ]
1675    }
1676
1677    if (!defined(cflags)) {
1678      cflags = []
1679    }
1680
1681    # Enable branch protection.
1682    pac_ret = false
1683    bti = false
1684    if (defined(invoker.branch_protector_ret)) {
1685      if (invoker.branch_protector_ret == "pac_ret" ||
1686          invoker.branch_protector_ret == "stack_protector_ret_all") {
1687        if (support_branch_protector_pac_ret) {
1688          pac_ret = true
1689        } else if (support_stack_protector_ret) {
1690          foreach(config, configs) {
1691            if (config ==
1692                "//build/config/security:stack_protector_ret_strong_config") {
1693              configs -= [
1694                "//build/config/security:stack_protector_ret_strong_config",
1695              ]
1696            }
1697          }
1698          configs +=
1699              [ "//build/config/security:stack_protector_ret_all_config" ]
1700        }
1701      }
1702
1703      # Nothing to do, supported by default.
1704      if (support_stack_protector_ret &&
1705          invoker.branch_protector_ret == "stack_protector_ret_strong") {
1706      }
1707    } else {
1708      if (defined(invoker.stack_protector_ret)) {
1709        if (invoker.stack_protector_ret) {
1710          if (support_branch_protector_pac_ret) {
1711            pac_ret = true
1712          } else if (support_stack_protector_ret) {
1713            foreach(config, configs) {
1714              if (config ==
1715                  "//build/config/security:stack_protector_ret_strong_config") {
1716                configs -= [
1717                  "//build/config/security:stack_protector_ret_strong_config",
1718                ]
1719              }
1720            }
1721            configs +=
1722                [ "//build/config/security:stack_protector_ret_all_config" ]
1723          }
1724        } else {
1725          foreach(config, configs) {
1726            if (config ==
1727                "//build/config/security:stack_protector_ret_strong_config") {
1728              configs -= [
1729                "//build/config/security:stack_protector_ret_strong_config",
1730              ]
1731            }
1732          }
1733          configs += [ "//build/config/security:stack_protector_config" ]
1734        }
1735      }
1736    }
1737
1738    if (defined(invoker.branch_protector_frt)) {
1739      if (invoker.branch_protector_frt == "bti" &&
1740          support_branch_protector_bti) {
1741        bti = true
1742      }
1743    }
1744
1745    if (!defined(ldflags)) {
1746      ldflags = []
1747    }
1748
1749    if (bti && pac_ret) {
1750      cflags += [ "-mbranch-protection=pac-ret+b-key+bti" ]
1751      ldflags += [ "-Wl,-z,force-bti" ]
1752    } else if (bti && !pac_ret) {
1753      cflags += [ "-mbranch-protection=bti" ]
1754      ldflags += [ "-Wl,-z,force-bti" ]
1755    } else if (!bti && pac_ret) {
1756      cflags += [ "-mbranch-protection=pac-ret+b-key" ]
1757    }
1758
1759    if (defined(invoker.no_default_deps)) {
1760      no_default_deps = invoker.no_default_deps
1761    }
1762
1763    if (!defined(deps)) {
1764      deps = []
1765    }
1766    if (is_use_check_deps && !_test_target) {
1767      deps += [ ":$_check_target" ]
1768    }
1769    if (!_test_target) {
1770      deps += [ ":$_notice_target" ]
1771    }
1772
1773    if (!defined(libs)) {
1774      libs = []
1775    }
1776    if (!defined(include_dirs)) {
1777      include_dirs = []
1778    }
1779
1780    if (defined(is_debug) && !is_debug && enable_debug_components != "") {
1781      foreach(component_name, debug_components) {
1782        if (part_name == component_name) {
1783          configs -= default_opt_configs
1784          configs += debug_level_configs
1785        }
1786      }
1787    }
1788
1789    deps_info = []
1790    foreach(dep, deps) {
1791      info = {
1792      }
1793      info = {
1794        target_out_dir =
1795            rebase_path(get_label_info(dep, "target_out_dir"), root_build_dir)
1796        target_name = get_label_info(dep, "name")
1797      }
1798      deps_info += [ info ]
1799    }
1800    module_label = get_label_info(":${target_name}", "label_with_toolchain")
1801    target_deps_data = {
1802      label = module_label
1803      module_deps_info = deps_info
1804      module_libs = libs
1805      type = "source_set"
1806      toolchain = get_label_info(":${target_name}", "toolchain")
1807    }
1808    write_file("${target_out_dir}/${target_name}_deps_data.json",
1809               target_deps_data,
1810               "json")
1811  }
1812}
1813