• 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      foreach(config, configs) {
306        if (config == "//build/config/compiler:no_exceptions") {
307          configs -= [ "//build/config/compiler:no_exceptions" ]
308        }
309      }
310      configs += [ "//build/config/compiler:exceptions" ]
311    }
312
313    if (defined(invoker.use_rtti) && invoker.use_rtti) {
314      foreach(config, configs) {
315        if (config == "//build/config/compiler:no_rtti") {
316          configs -= [ "//build/config/compiler:no_rtti" ]
317        }
318      }
319      configs += [ "//build/config/compiler:rtti" ]
320    }
321
322    if (!defined(cflags)) {
323      cflags = []
324    }
325
326    # Enable branch protection.
327    pac_ret = false
328    bti = false
329    if (defined(invoker.branch_protector_ret)) {
330      if (invoker.branch_protector_ret == "pac_ret" ||
331          invoker.branch_protector_ret == "stack_protector_ret_all") {
332        if (support_branch_protector_pac_ret) {
333          pac_ret = true
334        } else if (support_stack_protector_ret) {
335          foreach(config, configs) {
336            if (config ==
337                "//build/config/security:stack_protector_ret_strong_config") {
338              configs -= [
339                "//build/config/security:stack_protector_ret_strong_config",
340              ]
341            }
342          }
343          configs +=
344              [ "//build/config/security:stack_protector_ret_all_config" ]
345        }
346      }
347
348      # Nothing to do, supported by default.
349      if (support_stack_protector_ret &&
350          invoker.branch_protector_ret == "stack_protector_ret_strong") {
351      }
352    } else {
353      if (defined(invoker.stack_protector_ret)) {
354        if (invoker.stack_protector_ret) {
355          if (support_branch_protector_pac_ret) {
356            pac_ret = true
357          } else if (support_stack_protector_ret) {
358            foreach(config, configs) {
359              if (config ==
360                  "//build/config/security:stack_protector_ret_strong_config") {
361                configs -= [
362                  "//build/config/security:stack_protector_ret_strong_config",
363                ]
364              }
365            }
366            configs +=
367                [ "//build/config/security:stack_protector_ret_all_config" ]
368          }
369        } else {
370          foreach(config, configs) {
371            if (config ==
372                "//build/config/security:stack_protector_ret_strong_config") {
373              configs -= [
374                "//build/config/security:stack_protector_ret_strong_config",
375              ]
376            }
377          }
378          configs += [ "//build/config/security:stack_protector_config" ]
379        }
380      }
381    }
382
383    if (defined(cflags)) {
384      foreach(cflag, cflags) {
385        if (cflag == "-fstack-protector-strong") {
386          cflags -= [ "-fstack-protector-strong" ]
387        }
388      }
389    }
390
391    if (defined(cflags_c)) {
392      foreach(cflag_c, cflags_c) {
393        if (cflag_c == "-fstack-protector-strong") {
394          cflags_c -= [ "-fstack-protector-strong" ]
395        }
396      }
397    }
398
399    if (defined(cflags_cc)) {
400      foreach(cflag_cc, cflags_cc) {
401        if (cflag_cc == "-fstack-protector-strong") {
402          cflags_cc -= [ "-fstack-protector-strong" ]
403        }
404      }
405    }
406
407    if (defined(invoker.branch_protector_frt)) {
408      if (invoker.branch_protector_frt == "bti" &&
409          support_branch_protector_bti) {
410        bti = true
411      }
412    }
413
414    if (!defined(ldflags)) {
415      ldflags = []
416    }
417
418    if (bti && pac_ret) {
419      cflags += [ "-mbranch-protection=pac-ret+b-key+bti" ]
420      ldflags += [ "-Wl,-z,force-bti" ]
421    } else if (bti && !pac_ret) {
422      cflags += [ "-mbranch-protection=bti" ]
423      ldflags += [ "-Wl,-z,force-bti" ]
424    } else if (!bti && pac_ret) {
425      cflags += [ "-mbranch-protection=pac-ret+b-key" ]
426    }
427
428    if (!defined(deps)) {
429      deps = []
430    }
431    if (is_use_check_deps && !_test_target) {
432      deps += [ ":$_check_target" ]
433    }
434    if (!_ohos_test && !skip_gen_module_info) {
435      deps += [ ":$_module_info_target" ]
436    }
437
438    deps += [ ":${_collect_target}" ]
439
440    if (!defined(libs)) {
441      libs = []
442    }
443    if (!defined(include_dirs)) {
444      include_dirs = []
445    }
446
447    if (defined(visibility) && visibility != []) {
448      visibility += [ "//build/*" ]
449      if (defined(build_ext_path)) {
450        visibility += [ "${build_ext_path}/*" ]
451      }
452    }
453
454    if (defined(invoker.static_link) && invoker.static_link) {
455      no_default_deps = true
456      configs -= [ "//build/config:executable_config" ]
457      ldflags += [ "-static" ]
458      if (is_ohos && use_musl) {
459        import("//build/config/ohos/musl.gni")
460        if (defined(external_deps)) {
461          external_deps += [ "musl:soft_libc_musl_static" ]
462        } else {
463          external_deps = [ "musl:soft_libc_musl_static" ]
464        }
465      }
466    } else if (is_ohos) {
467      if (current_cpu == "arm" || current_cpu == "arm64" ||
468          current_cpu == "riscv64" || current_cpu == "loongarch64") {
469        libs += [ "unwind" ]
470      }
471      libs += [
472        rebase_path(libclang_rt_file),
473        "c++",
474      ]
475    }
476
477    if (!defined(output_name)) {
478      output_name = target_name
479    }
480
481    if (defined(invoker.version_script)) {
482      _version_script = rebase_path(invoker.version_script, root_build_dir)
483      if (!defined(ldflags)) {
484        ldflags = []
485      }
486      ldflags += [
487        "-rdynamic",
488        "-Wl,--version-script=${_version_script}",
489      ]
490    }
491
492    # We don't need to change config when "is_debug==true"
493    # "enable_debug_components" isn't blank means some components using debug level compilation
494    if (defined(is_debug) && !is_debug && enable_debug_components != "") {
495      foreach(component_name, debug_components) {
496        if (part_name == component_name) {
497          configs -= default_opt_configs
498          configs += debug_level_configs
499        }
500      }
501    }
502    if (target_toolchain == "${current_toolchain}") {
503      install_module_info = {
504        module_def = target_label
505        part_name = part_name
506        module_info_file =
507            rebase_path(get_label_info(module_def, "target_out_dir"),
508                        root_build_dir) + "/${target_name}_module_info.json"
509        subsystem_name = subsystem_name
510        part_name = part_name
511        toolchain = current_toolchain
512        toolchain_out_dir = rebase_path(root_out_dir, root_build_dir)
513      }
514      metadata = {
515        install_modules = [ install_module_info ]
516      }
517    }
518    if (!_test_target) {
519      deps += [ ":$_notice_target" ]
520    }
521
522    module_label = get_label_info(":${target_name}", "label_with_toolchain")
523
524    deps_info = []
525    foreach(dep, deps) {
526      info = {
527      }
528      info = {
529        target_out_dir =
530            rebase_path(get_label_info(dep, "target_out_dir"), root_build_dir)
531        target_name = get_label_info(dep, "name")
532      }
533      deps_info += [ info ]
534    }
535    target_deps_data = {
536      label = module_label
537      module_deps_info = deps_info
538      module_libs = libs
539      type = "executable"
540      prebuilt = false
541      stable = stable
542      toolchain = get_label_info(":${target_name}", "toolchain")
543    }
544    write_file("${target_out_dir}/${target_name}_deps_data.json",
545               target_deps_data,
546               "json")
547  }
548}
549
550# Defines a shared_library
551#
552# The shared_library template is used to generated so file.
553#
554# Parameters
555#
556#   subsystem_name (required)
557#   [string]
558#   configs (optional)
559#   [list]
560#   remove_cnofigs (optional)
561#   [list]
562#   version_script (optional)
563#   [string]
564template("ohos_shared_library") {
565  assert(!defined(invoker.output_dir),
566         "output_dir is not allowed to be defined.")
567
568  _test_target = defined(invoker.testonly) && invoker.testonly
569  if (defined(invoker.subsystem_name) && defined(invoker.part_name)) {
570    subsystem_name = invoker.subsystem_name
571    part_name = invoker.part_name
572  } else if (defined(invoker.part_name)) {
573    part_name = invoker.part_name
574    _part_subsystem_info_file =
575        "$root_build_dir/build_configs/parts_info/part_subsystem.json"
576    _arguments = [
577      "--part-name",
578      part_name,
579      "--part-subsystem-info-file",
580      rebase_path(_part_subsystem_info_file, root_build_dir),
581    ]
582    get_subsystem_script = "//build/templates/common/get_subsystem_name.py"
583    subsystem_name =
584        exec_script(get_subsystem_script, _arguments, "trim string")
585    if (is_use_check_deps && !_test_target) {
586      skip_check_subsystem = true
587    }
588  } else if (defined(invoker.subsystem_name)) {
589    subsystem_name = invoker.subsystem_name
590    part_name = subsystem_name
591  } else {
592    subsystem_name = "build"
593    part_name = "build_framework"
594  }
595  assert(subsystem_name != "")
596  assert(part_name != "")
597
598  module_label = get_label_info(":${target_name}", "label_with_toolchain")
599  _collect_target = "${target_name}__collect"
600  collect_module_target(_collect_target) {
601    forward_variables_from(invoker, [ "install_images" ])
602  }
603
604  if (is_use_check_deps && !_test_target) {
605    _check_target = "${target_name}__check"
606    target_path = get_label_info(":${target_name}", "label_no_toolchain")
607    check_target(_check_target) {
608      module_deps = []
609      module_ex_deps = []
610      if (defined(invoker.deps)) {
611        module_deps += invoker.deps
612      }
613      if (defined(invoker.public_deps)) {
614        module_deps += invoker.public_deps
615      }
616      if (defined(invoker.external_deps)) {
617        module_ex_deps += invoker.external_deps
618      }
619      if (defined(invoker.public_external_deps)) {
620        module_ex_deps += invoker.public_external_deps
621      }
622    }
623  }
624
625  # auto set auto_relative_install_dir by innerapi_tags
626  if (defined(invoker.innerapi_tags)) {
627    is_chipsetsdk = false
628    is_platformsdk = false
629    is_platformsdk_indirect = false
630    is_passthrough = false
631    is_passthrough_indirect = false
632    is_llndk = false
633    is_chipsetsdk_indirect = false
634    is_chipsetsdk_sp = false
635    is_chipsetsdk_sp_indirect = false
636
637    foreach(tag, filter_include(invoker.innerapi_tags, [ "llndk" ])) {
638      is_llndk = true
639    }
640    foreach(tag, filter_include(invoker.innerapi_tags, [ "chipsetsdk" ])) {
641      is_chipsetsdk = true
642    }
643    foreach(tag,
644            filter_include(invoker.innerapi_tags, [ "chipsetsdk_indirect" ])) {
645      is_chipsetsdk_indirect = true
646    }
647    foreach(tag, filter_include(invoker.innerapi_tags, [ "chipsetsdk_sp" ])) {
648      is_chipsetsdk_sp = true
649    }
650    foreach(
651        tag,
652        filter_include(invoker.innerapi_tags, [ "chipsetsdk_sp_indirect" ])) {
653      is_chipsetsdk_sp_indirect = true
654    }
655    foreach(tag, filter_include(invoker.innerapi_tags, [ "platformsdk" ])) {
656      is_platformsdk = true
657    }
658    foreach(tag,
659            filter_include(invoker.innerapi_tags, [ "platformsdk_indirect" ])) {
660      is_platformsdk_indirect = true
661    }
662    foreach(tag, filter_include(invoker.innerapi_tags, [ "passthrough" ])) {
663      is_passthrough = true
664    }
665    foreach(tag,
666            filter_include(invoker.innerapi_tags, [ "passthrough_indirect" ])) {
667      is_passthrough_indirect = true
668    }
669
670    if (is_chipsetsdk && (is_chipsetsdk_indirect || is_chipsetsdk_sp || is_chipsetsdk_sp_indirect)) {
671      assert(false, "chipsetsdk tags cannot coexist with [chipsetsdk_indirect,chipsetsdk_sp,chipsetsdk_sp_indirect]")
672    } else if (is_chipsetsdk_indirect && (is_chipsetsdk || is_chipsetsdk_sp || is_chipsetsdk_sp_indirect)) {
673      assert(false, "chipsetsdk_indirect tags cannot coexist with [chipsetsdk,chipsetsdk_sp,chipsetsdk_sp_indirect]")
674    } else if (is_chipsetsdk_sp && (is_chipsetsdk || is_chipsetsdk_indirect || is_chipsetsdk_sp_indirect)) {
675      assert(false, "chipsetsdk_sp tags cannot coexist with [chipsetsdk,chipsetsdk_indirect,chipsetsdk_sp_indirect]")
676    } else if (is_chipsetsdk_sp_indirect && (is_chipsetsdk || is_chipsetsdk_sp || is_chipsetsdk_indirect)) {
677      assert(false, "chipsetsdk_sp_indirect tags cannot coexist with [chipsetsdk,chipsetsdk_indirect,chipsetsdk_sp]")
678    }
679
680    if (is_platformsdk) {
681      auto_relative_install_dir = platformsdk_dir
682    }
683
684    if (is_platformsdk_indirect) {
685      auto_relative_install_dir = platformsdk_dir
686    }
687
688    if (is_chipsetsdk) {
689      auto_relative_install_dir = chipset_sdk_dir
690      if (is_platformsdk || is_platformsdk_indirect) {
691        softlink_path = platformsdk_dir
692      }
693    }
694
695    if (is_chipsetsdk_indirect) {
696      auto_relative_install_dir = chipset_sdk_dir
697      if (is_platformsdk || is_platformsdk_indirect) {
698        softlink_path = platformsdk_dir
699      }
700    }
701
702    if (is_chipsetsdk_sp) {
703      auto_relative_install_dir = chipset_sdk_sp_dir
704      if (is_platformsdk || is_platformsdk_indirect) {
705        softlink_path = platformsdk_dir
706      }
707    }
708
709    if (is_chipsetsdk_sp_indirect) {
710      auto_relative_install_dir = chipset_sdk_sp_dir
711      if (is_platformsdk || is_platformsdk_indirect) {
712        softlink_path = platformsdk_dir
713      }
714    }
715
716    if (is_passthrough) {
717      auto_relative_install_dir = passthrough_dir
718    }
719    if (is_passthrough_indirect) {
720      auto_relative_install_dir = passthrough_indirect_dir
721    }
722
723    if (is_llndk) {
724      auto_relative_install_dir = llndk_dir
725    }
726    is_ndk = false
727    foreach(tag, filter_include(invoker.innerapi_tags, [ "ndk" ])) {
728      is_ndk = true
729    }
730    if (is_ndk) {
731      if (is_llndk) {
732        softlink_path = ndk_dir
733        auto_relative_install_dir = llndk_dir
734      } else {
735        auto_relative_install_dir = ndk_dir
736      }
737    }
738  }
739
740  if (check_deps) {
741    deps_data = {
742    }
743    module_label = get_label_info(":${target_name}", "label_with_toolchain")
744    module_deps = []
745    if (defined(invoker.deps)) {
746      foreach(dep, invoker.deps) {
747        module_deps += [ get_label_info(dep, "label_no_toolchain") ]
748      }
749    }
750    module_ex_deps = []
751    if (defined(invoker.external_deps) && invoker.external_deps != []) {
752      module_ex_deps = invoker.external_deps
753    }
754    deps_data = {
755      part_name = part_name
756      module_label = module_label
757      deps = module_deps
758      external_deps = module_ex_deps
759    }
760    write_file("${root_out_dir}/deps_files/${part_name}__${target_name}.json",
761               deps_data,
762               "json")
763  }
764
765  if (is_standard_system) {
766    output_dir = "${root_out_dir}/${subsystem_name}/${part_name}"
767  } else {
768    output_dir = "${root_out_dir}"
769  }
770
771  _security_config_target = "${target_name}__security_config"
772  ohos_security_config(_security_config_target) {
773    forward_variables_from(invoker, [ "auto_var_init" ])
774  }
775
776  if (!allow_sanitize_debug && !build_xts &&
777      defined(ext_sanitizer_check_list_path)) {
778    build_name = "${target_name}"
779    ohos_sanitizer_check("${target_name}_sanitizer_check") {
780      forward_variables_from(invoker, [ "sanitize" ])
781    }
782  }
783
784  _sanitize_config_target = "${target_name}__sanitizer_config"
785  ohos_sanitizer_config(_sanitize_config_target) {
786    forward_variables_from(invoker, [ "sanitize" ])
787  }
788
789  if (!_test_target) {
790    _notice_target = "${target_name}__notice"
791    _main_target_name = target_name
792    collect_notice(_notice_target) {
793      forward_variables_from(invoker,
794                             [
795                               "testonly",
796                               "license_as_sources",
797                               "license_file",
798                             ])
799
800      module_name = _main_target_name
801      module_source_dir = get_label_info(":${_main_target_name}", "dir")
802    }
803  }
804
805  target_label = get_label_info(":${target_name}", "label_with_toolchain")
806  target_toolchain = get_label_info(target_label, "toolchain")
807
808  if (target_toolchain == "${current_toolchain}") {
809    ohos_module_name = target_name
810    _module_info_target = "${target_name}_info"
811    generate_module_info(_module_info_target) {
812      forward_variables_from(invoker, [ "testonly" ])
813      module_name = ohos_module_name
814      module_type = "lib"
815      module_source_dir = "$root_out_dir"
816      if (defined(output_dir)) {
817        module_source_dir = output_dir
818      }
819
820      module_install_name = ohos_module_name
821      if (defined(invoker.output_name)) {
822        module_install_name = invoker.output_name
823      }
824
825      module_install_images = [ "system" ]
826      if (defined(invoker.install_images)) {
827        module_install_images = []
828        module_install_images += invoker.install_images
829      }
830
831      module_output_extension = shlib_extension
832      if (defined(invoker.output_extension)) {
833        module_output_extension = "." + invoker.output_extension
834      }
835
836      install_enable = true
837      if (defined(invoker.install_enable)) {
838        install_enable = invoker.install_enable
839      }
840
841      if (defined(invoker.module_install_dir)) {
842        module_install_dir = invoker.module_install_dir
843      }
844
845      if (defined(invoker.symlink_target_name)) {
846        symlink_target_name = invoker.symlink_target_name
847      }
848
849      if (defined(invoker.output_prefix_override)) {
850        output_prefix_override = invoker.output_prefix_override
851      }
852      notice = "$target_out_dir/$ohos_module_name.notice.txt"
853
854      # update relative_install_dir if auto_relative_install_dir defined
855      if (defined(auto_relative_install_dir)) {
856        relative_install_dir = auto_relative_install_dir
857      }
858
859      # update relative_install_dir if relative_install_dir defined in BUILD.gn
860      if (defined(invoker.relative_install_dir)) {
861        relative_install_dir = invoker.relative_install_dir
862      }
863
864      if (defined(invoker.innerapi_tags)) {
865        if (defined(softlink_path) && softlink_path != "") {
866          softlink_create_path = softlink_path
867        }
868      }
869
870      # Passing shlib_type and innerapi_tags to generate_module_info
871      if (defined(invoker.shlib_type)) {
872        invalid = true
873        valid_types = [
874          "sa",
875          "sa_stub",
876          "sa_proxy",
877          "hdi",
878          "hdi_stub",
879          "hdi_proxy",
880          "innerapi",
881          "napi",
882          "ani",
883        ]
884        foreach(t, filter_include(valid_types, [ invoker.shlib_type ])) {
885          if (t == invoker.shlib_type) {
886            invalid = false
887          }
888        }
889        shlib_type = invoker.shlib_type
890        assert(
891            invalid != true,
892            "$target_label has invalid shlib_type value: $shlib_type, allowed values: $valid_types")
893      }
894      if (defined(invoker.innerapi_tags)) {
895        invalid = false
896        valid_tags = [
897          "ndk",
898          "llndk",
899          "chipsetsdk",
900          "chipsetsdk_indirect",
901          "chipsetsdk_sp",
902          "chipsetsdk_sp_indirect",
903          "platformsdk",
904          "platformsdk_indirect",
905          "passthrough",
906          "passthrough_indirect",
907          "sasdk",
908        ]
909        foreach(tag, filter_exclude(invoker.innerapi_tags, valid_tags)) {
910          if (tag != "") {
911            invalid = true
912          }
913        }
914        innerapi_tags = invoker.innerapi_tags
915        assert(
916            invalid != true,
917            "$target_label has invalid innerapi_tags $innerapi_tags, allowed values: $valid_tags")
918      }
919
920      if (defined(invoker.version_script)) {
921        version_script = rebase_path(invoker.version_script, root_build_dir)
922      }
923    }
924  }
925
926  if (!defined(invoker.stable)) {
927    stable = false
928  }
929
930  if (defined(invoker.kernel_permission_path)) {
931    kernel_permission_info = []
932    _kernel_permission_path =
933        rebase_path(invoker.kernel_permission_path, root_build_dir)
934    _module_info_file =
935        rebase_path(get_label_info(target_label, "target_out_dir"),
936                    root_build_dir) + "/${target_name}_module_info.json"
937    kernel_permission_info_file = "${root_build_dir}/build_configs/kernel_permission/${target_name}_info_file.json"
938    _output_name = ""
939    if (defined(invoker.output_name)) {
940      _output_name = invoker.output_name
941    }
942    _output_extension = ""
943    if (defined(invoker.output_extension)) {
944      _output_extension = "." + invoker.output_extension
945    }
946    kernel_permission_info += [
947      {
948        module_info_file = _module_info_file
949        kernel_permission_path = _kernel_permission_path
950        target_name = target_name
951        subsystem_name = subsystem_name
952        target_label = target_label
953        part_name = part_name
954        type = "lib"
955        gn_output_name = _output_name
956        gn_output_extension = _output_extension
957      },
958    ]
959    write_file("${kernel_permission_info_file}", kernel_permission_info, "json")
960  }
961
962  shared_library("${target_name}") {
963    forward_variables_from(invoker,
964                           "*",
965                           [
966                             "configs",
967                             "remove_configs",
968                             "no_default_deps",
969                             "install_images",
970                             "module_install_dir",
971                             "relative_install_dir",
972                             "symlink_target_name",
973                             "output_dir",
974                             "install_enable",
975                             "version_script",
976                             "exported_symbols_list",
977                             "license_file",
978                             "license_as_sources",
979                             "use_exceptions",
980                             "use_rtti",
981                             "stl",
982
983                             # Sanitizer variables
984                             "sanitize",
985                             "stack_protector_ret",
986                             "branch_protector_ret",
987                             "branch_protector_frt",
988                           ])
989    output_dir = output_dir
990
991    if (!defined(inputs)) {
992      inputs = []
993    }
994
995    if (!defined(ldflags)) {
996      ldflags = []
997    }
998
999    if (defined(invoker.configs)) {
1000      configs += invoker.configs
1001    }
1002    if (defined(invoker.remove_configs)) {
1003      configs -= invoker.remove_configs
1004    }
1005
1006    configs += [ ":$_sanitize_config_target" ]
1007    configs += [ ":$_security_config_target" ]
1008
1009    if (defined(invoker.use_exceptions) && invoker.use_exceptions) {
1010      foreach(config, configs) {
1011        if (config == "//build/config/compiler:no_exceptions") {
1012          configs -= [ "//build/config/compiler:no_exceptions" ]
1013        }
1014      }
1015      configs += [ "//build/config/compiler:exceptions" ]
1016    }
1017
1018    if (defined(invoker.use_rtti) && invoker.use_rtti) {
1019      foreach(config, configs) {
1020        if (config == "//build/config/compiler:no_rtti") {
1021          configs -= [ "//build/config/compiler:no_rtti" ]
1022        }
1023      }
1024      configs += [ "//build/config/compiler:rtti" ]
1025    }
1026
1027    if (!defined(cflags)) {
1028      cflags = []
1029    }
1030
1031    if (defined(visibility) && visibility != []) {
1032      visibility += [ "//build/*" ]
1033      if (defined(build_ext_path)) {
1034        visibility += [ "${build_ext_path}/*" ]
1035      }
1036    }
1037
1038    # Enable branch protection.
1039    pac_ret = false
1040    bti = false
1041    if (defined(invoker.branch_protector_ret)) {
1042      if (invoker.branch_protector_ret == "pac_ret" ||
1043          invoker.branch_protector_ret == "stack_protector_ret_all") {
1044        if (support_branch_protector_pac_ret) {
1045          pac_ret = true
1046        } else if (support_stack_protector_ret) {
1047          foreach(config, configs) {
1048            if (config ==
1049                "//build/config/security:stack_protector_ret_strong_config") {
1050              configs -= [
1051                "//build/config/security:stack_protector_ret_strong_config",
1052              ]
1053            }
1054          }
1055          configs +=
1056              [ "//build/config/security:stack_protector_ret_all_config" ]
1057        }
1058      }
1059
1060      # Nothing to do, supported by default.
1061      if (support_stack_protector_ret &&
1062          invoker.branch_protector_ret == "stack_protector_ret_strong") {
1063      }
1064    } else {
1065      if (defined(invoker.stack_protector_ret)) {
1066        if (invoker.stack_protector_ret) {
1067          if (support_branch_protector_pac_ret) {
1068            pac_ret = true
1069          } else if (support_stack_protector_ret) {
1070            foreach(config, configs) {
1071              if (config ==
1072                  "//build/config/security:stack_protector_ret_strong_config") {
1073                configs -= [
1074                  "//build/config/security:stack_protector_ret_strong_config",
1075                ]
1076              }
1077            }
1078            configs +=
1079                [ "//build/config/security:stack_protector_ret_all_config" ]
1080          }
1081        } else {
1082          foreach(config, configs) {
1083            if (config ==
1084                "//build/config/security:stack_protector_ret_strong_config") {
1085              configs -= [
1086                "//build/config/security:stack_protector_ret_strong_config",
1087              ]
1088            }
1089          }
1090          configs += [ "//build/config/security:stack_protector_config" ]
1091        }
1092      }
1093    }
1094
1095    if (defined(invoker.branch_protector_frt)) {
1096      if (invoker.branch_protector_frt == "bti" &&
1097          support_branch_protector_bti) {
1098        bti = true
1099      }
1100    }
1101
1102    if (defined(cflags)) {
1103      foreach(cflag, cflags) {
1104        if (cflag == "-fstack-protector-strong") {
1105          cflags -= [ "-fstack-protector-strong" ]
1106        }
1107      }
1108    }
1109
1110    if (defined(cflags_c)) {
1111      foreach(cflag_c, cflags_c) {
1112        if (cflag_c == "-fstack-protector-strong") {
1113          cflags_c -= [ "-fstack-protector-strong" ]
1114        }
1115      }
1116    }
1117
1118    if (defined(cflags_cc)) {
1119      foreach(cflag_cc, cflags_cc) {
1120        if (cflag_cc == "-fstack-protector-strong") {
1121          cflags_cc -= [ "-fstack-protector-strong" ]
1122        }
1123      }
1124    }
1125
1126    if (bti && pac_ret) {
1127      cflags += [ "-mbranch-protection=pac-ret+b-key+bti" ]
1128      ldflags += [ "-Wl,-z,force-bti" ]
1129    } else if (bti && !pac_ret) {
1130      cflags += [ "-mbranch-protection=bti" ]
1131      ldflags += [ "-Wl,-z,force-bti" ]
1132    } else if (!bti && pac_ret) {
1133      cflags += [ "-mbranch-protection=pac-ret+b-key" ]
1134    }
1135
1136    # check whether to add adlt configs
1137    install_enable = true
1138    if (defined(invoker.install_enable)) {
1139      install_enable = invoker.install_enable
1140    }
1141    if (install_enable && enable_adlt && is_standard_system &&
1142        target_toolchain == "${current_toolchain}" && is_ohos) {
1143      inputs_args = []
1144      if (target_cpu == "arm64" || target_cpu == "x86_64") {
1145        module_type = "lib64"
1146      } else if (target_cpu == "arm" || target_cpu == "x86") {
1147        module_type = "lib"
1148      } else {
1149        assert(false, "Unsupported target_cpu: $target_cpu")
1150      }
1151      inputs_args += [
1152        "--type",
1153        module_type,
1154        "--system-base-dir",
1155        system_base_dir,
1156      ]
1157
1158      module_install_name = target_name
1159      if (defined(invoker.output_name)) {
1160        module_install_name = invoker.output_name
1161      }
1162      inputs_args += [
1163        "--install-name",
1164        module_install_name,
1165      ]
1166
1167      module_install_images = [ "system" ]
1168      if (defined(invoker.install_images)) {
1169        module_install_images = []
1170        module_install_images += invoker.install_images
1171      }
1172      inputs_args += [ "--install-images" ]
1173      inputs_args += module_install_images
1174
1175      if (defined(invoker.module_install_dir) &&
1176          invoker.module_install_dir != "") {
1177        inputs_args += [
1178          "--module-install-dir",
1179          invoker.module_install_dir,
1180        ]
1181      }
1182      if (defined(invoker.relative_install_dir)) {
1183        relative_install_dir = invoker.relative_install_dir
1184      }
1185      if (defined(auto_relative_install_dir)) {
1186        relative_install_dir = auto_relative_install_dir
1187      }
1188      if (defined(relative_install_dir) && relative_install_dir != "") {
1189        inputs_args += [
1190          "--relative-install-dir",
1191          relative_install_dir,
1192        ]
1193      }
1194
1195      module_output_extension = shlib_extension
1196      if (defined(invoker.output_extension)) {
1197        module_output_extension = "." + invoker.output_extension
1198      }
1199      if (module_output_extension != "") {
1200        inputs_args += [
1201          "--suffix",
1202          module_output_extension,
1203        ]
1204      }
1205
1206      if (defined(invoker.output_prefix_override) &&
1207          invoker.output_prefix_override) {
1208        inputs_args += [ "--prefix-override" ]
1209      }
1210      inputs_args += [
1211        "--allowed-lib-list",
1212        rebase_path(allowed_lib_list),
1213      ]
1214      result = exec_script("//build/ohos/images/get_module_install_dest.py",
1215                           inputs_args,
1216                           "string")
1217      if (result == "") {
1218        configs += [ "//build/config/ohos:adlt_config" ]
1219      }
1220    }
1221
1222    if (!defined(output_name)) {
1223      output_name = target_name
1224    }
1225
1226    if (defined(invoker.no_default_deps)) {
1227      no_default_deps = invoker.no_default_deps
1228    }
1229
1230    if (defined(invoker.version_script)) {
1231      _version_script = rebase_path(invoker.version_script, root_build_dir)
1232      inputs += [ invoker.version_script ]
1233      ldflags += [ "-Wl,--version-script=${_version_script}" ]
1234    }
1235
1236    if (target_os == "ios" && defined(invoker.exported_symbols_list)) {
1237      _exported_symbols_list =
1238          rebase_path(invoker.exported_symbols_list, root_build_dir)
1239      inputs += [ invoker.exported_symbols_list ]
1240      ldflags += [
1241        "-exported_symbols_list",
1242        "${_exported_symbols_list}",
1243      ]
1244    }
1245
1246    if (!defined(libs)) {
1247      libs = []
1248    }
1249    if (!defined(cflags_cc)) {
1250      cflags_cc = []
1251    }
1252    if (!defined(deps)) {
1253      deps = []
1254    }
1255    if (is_use_check_deps && !_test_target) {
1256      deps += [ ":$_check_target" ]
1257    }
1258    if (target_toolchain == "${current_toolchain}" && !skip_gen_module_info) {
1259      deps += [ ":$_module_info_target" ]
1260    }
1261
1262    deps += [ ":${_collect_target}" ]
1263    if (is_ohos) {
1264      if (defined(invoker.stl)) {
1265        cflags_cc += [
1266          "-nostdinc++",
1267          "-I" + rebase_path(
1268                  "${toolchains_dir}/${host_platform_dir}/llvm_ndk/include/libcxx-ohos/include/c++/v1",
1269                  root_build_dir),
1270        ]
1271        ldflags += [
1272          "-nostdlib++",
1273          "-L" + rebase_path("${clang_stl_path}/${abi_target}", root_build_dir),
1274        ]
1275
1276        libs += [ invoker.stl ]
1277      } else {
1278        if (current_cpu == "arm" || current_cpu == "arm64" ||
1279            current_cpu == "riscv64" || current_cpu == "loongarch64") {
1280          libs += [ "unwind" ]
1281        }
1282
1283        if (target_name != "libpcre2" && target_name != "libselinux" &&
1284            target_name != "libsec_shared" && target_name != "libsepol") {
1285          libs += [ "c++" ]
1286        }
1287      }
1288    }
1289
1290    if (!_test_target) {
1291      deps += [ ":$_notice_target" ]
1292    }
1293    if (!defined(include_dirs)) {
1294      include_dirs = []
1295    }
1296
1297    install_module_info = {
1298      module_def = target_label
1299      module_info_file =
1300          rebase_path(get_label_info(module_def, "target_out_dir"),
1301                      root_build_dir) + "/${target_name}_module_info.json"
1302      subsystem_name = subsystem_name
1303      part_name = part_name
1304      toolchain = current_toolchain
1305      toolchain_out_dir = rebase_path(root_out_dir, root_build_dir)
1306    }
1307    metadata = {
1308      install_modules = [ install_module_info ]
1309    }
1310    if (defined(is_debug) && !is_debug && enable_debug_components != "") {
1311      foreach(component_name, debug_components) {
1312        if (part_name == component_name) {
1313          configs -= default_opt_configs
1314          configs += debug_level_configs
1315        }
1316      }
1317    }
1318
1319    # Hide symbols for all sa libraries if not specified by version_script
1320    if (defined(invoker.shlib_type) && invoker.shlib_type == "sa") {
1321      if (!defined(invoker.version_script)) {
1322        _version_script =
1323            rebase_path("//build/templates/cxx/singleton.versionscript")
1324        inputs += [ _version_script ]
1325        ldflags += [ "-Wl,--version-script=${_version_script}" ]
1326      }
1327    }
1328
1329    # Set version_script for hdi service libraries
1330    if (defined(invoker.shlib_type) && invoker.shlib_type == "hdi") {
1331      if (!defined(invoker.version_script)) {
1332        _version_script = rebase_path("//build/templates/cxx/hdi.versionscript")
1333        inputs += [ _version_script ]
1334        ldflags += [ "-Wl,--version-script=${_version_script}" ]
1335      }
1336    }
1337
1338    module_type_napi = false
1339    if (defined(invoker.relative_install_dir) &&
1340        (build_ohos_sdk != true && build_ohos_ndk != true)) {
1341      relative_paths = string_split(invoker.relative_install_dir, "/")
1342      foreach(p, relative_paths) {
1343        if (p == "module") {
1344          module_type_napi = true
1345        }
1346      }
1347      if (module_type_napi) {
1348        foreach(m, filter_include(napi_white_list, [ target_name ])) {
1349          if (m == target_name) {
1350            module_type_napi = false
1351          }
1352        }
1353      }
1354    }
1355    if (module_type_napi) {
1356      if (!defined(invoker.version_script)) {
1357        _version_script =
1358            rebase_path("//build/templates/cxx/napi.versionscript")
1359        inputs += [ _version_script ]
1360        ldflags += [ "-Wl,--version-script=${_version_script}" ]
1361      }
1362    }
1363
1364    # Set version_script for ani libraries
1365    if (defined(invoker.shlib_type) && invoker.shlib_type == "ani") {
1366      if (!defined(invoker.version_script)) {
1367        _version_script = rebase_path("//build/templates/cxx/ani.versionscript")
1368        inputs += [ _version_script ]
1369        ldflags += [ "-Wl,--version-script=${_version_script}" ]
1370      }
1371    }
1372
1373    deps_info = []
1374    foreach(dep, deps) {
1375      info = {
1376      }
1377      info = {
1378        target_out_dir =
1379            rebase_path(get_label_info(dep, "target_out_dir"), root_build_dir)
1380        target_name = get_label_info(dep, "name")
1381      }
1382      deps_info += [ info ]
1383    }
1384    module_label = get_label_info(":${target_name}", "label_with_toolchain")
1385    target_deps_data = {
1386      label = module_label
1387      module_deps_info = deps_info
1388      module_libs = libs
1389      type = "shared_library"
1390      prebuilt = false
1391      stable = stable
1392      toolchain = get_label_info(":${target_name}", "toolchain")
1393    }
1394    write_file("${target_out_dir}/${target_name}_deps_data.json",
1395               target_deps_data,
1396               "json")
1397  }
1398}
1399
1400template("ohos_static_library") {
1401  _test_target = defined(invoker.testonly) && invoker.testonly
1402  if (defined(invoker.subsystem_name) && defined(invoker.part_name)) {
1403    subsystem_name = invoker.subsystem_name
1404    part_name = invoker.part_name
1405  } else if (defined(invoker.part_name)) {
1406    part_name = invoker.part_name
1407    _part_subsystem_info_file =
1408        "$root_build_dir/build_configs/parts_info/part_subsystem.json"
1409    _arguments = [
1410      "--part-name",
1411      part_name,
1412      "--part-subsystem-info-file",
1413      rebase_path(_part_subsystem_info_file, root_build_dir),
1414    ]
1415    get_subsystem_script = "//build/templates/common/get_subsystem_name.py"
1416    subsystem_name =
1417        exec_script(get_subsystem_script, _arguments, "trim string")
1418    if (is_use_check_deps && !_test_target) {
1419      skip_check_subsystem = true
1420    }
1421  } else if (defined(invoker.subsystem_name)) {
1422    subsystem_name = invoker.subsystem_name
1423    part_name = subsystem_name
1424  } else {
1425    subsystem_name = "build"
1426    part_name = "build_framework"
1427  }
1428  assert(subsystem_name != "")
1429  assert(part_name != "")
1430
1431  if (is_use_check_deps && !_test_target) {
1432    _check_target = "${target_name}__check"
1433    target_path = get_label_info(":${target_name}", "label_no_toolchain")
1434    check_target(_check_target) {
1435      module_deps = []
1436      module_ex_deps = []
1437      if (defined(invoker.deps)) {
1438        module_deps += invoker.deps
1439      }
1440      if (defined(invoker.public_deps)) {
1441        module_deps += invoker.public_deps
1442      }
1443      if (defined(invoker.external_deps)) {
1444        module_ex_deps += invoker.external_deps
1445      }
1446      if (defined(invoker.public_external_deps)) {
1447        module_ex_deps += invoker.public_external_deps
1448      }
1449    }
1450  }
1451  if (check_deps) {
1452    deps_data = {
1453    }
1454    module_label = get_label_info(":${target_name}", "label_with_toolchain")
1455    module_deps = []
1456    if (defined(invoker.deps)) {
1457      foreach(dep, invoker.deps) {
1458        module_deps += [ get_label_info(dep, "label_no_toolchain") ]
1459      }
1460    }
1461    module_ex_deps = []
1462    if (defined(invoker.external_deps) && invoker.external_deps != []) {
1463      module_ex_deps = invoker.external_deps
1464    }
1465    deps_data = {
1466      part_name = part_name
1467      module_label = module_label
1468      deps = module_deps
1469      external_deps = module_ex_deps
1470    }
1471
1472    write_file("${root_out_dir}/deps_files/${part_name}__${target_name}.json",
1473               deps_data,
1474               "json")
1475  }
1476
1477  _security_config_target = "${target_name}__security_config"
1478  ohos_security_config(_security_config_target) {
1479    forward_variables_from(invoker, [ "auto_var_init" ])
1480  }
1481
1482  if (!allow_sanitize_debug && !build_xts &&
1483      defined(ext_sanitizer_check_list_path)) {
1484    build_name = "${target_name}"
1485    ohos_sanitizer_check("${target_name}_sanitizer_check") {
1486      forward_variables_from(invoker, [ "sanitize" ])
1487    }
1488  }
1489
1490  _sanitize_config_target = "${target_name}__sanitizer_config"
1491  ohos_sanitizer_config(_sanitize_config_target) {
1492    forward_variables_from(invoker, [ "sanitize" ])
1493  }
1494
1495  if (!_test_target) {
1496    _notice_target = "${target_name}__notice"
1497    _main_target_name = target_name
1498    collect_notice(_notice_target) {
1499      forward_variables_from(invoker,
1500                             [
1501                               "testonly",
1502                               "license_as_sources",
1503                               "license_file",
1504                             ])
1505      module_type = "static_library"
1506      module_name = _main_target_name
1507      module_source_dir = get_label_info(":${_main_target_name}", "dir")
1508    }
1509  }
1510
1511  static_library(target_name) {
1512    forward_variables_from(invoker,
1513                           "*",
1514                           [
1515                             "configs",
1516                             "remove_configs",
1517                             "no_default_deps",
1518                             "license_file",
1519                             "license_as_sources",
1520                             "use_exceptions",
1521                             "use_rtti",
1522                             "subsystem_name",
1523
1524                             # Sanitizer variables
1525                             "sanitize",
1526                             "stack_protector_ret",
1527                             "branch_protector_ret",
1528                             "branch_protector_frt",
1529                           ])
1530    if (defined(invoker.configs)) {
1531      configs += invoker.configs
1532    }
1533    if (defined(invoker.remove_configs)) {
1534      configs -= invoker.remove_configs
1535    }
1536    if (is_standard_system) {
1537      configs -= [ "//build/config/compiler:thin_archive" ]
1538    }
1539    configs += [ ":$_sanitize_config_target" ]
1540    configs += [ ":$_security_config_target" ]
1541
1542    if (defined(invoker.use_exceptions) && invoker.use_exceptions) {
1543      foreach(config, configs) {
1544        if (config == "//build/config/compiler:no_exceptions") {
1545          configs -= [ "//build/config/compiler:no_exceptions" ]
1546        }
1547      }
1548      configs += [ "//build/config/compiler:exceptions" ]
1549    }
1550
1551    if (defined(invoker.use_rtti) && invoker.use_rtti) {
1552      foreach(config, configs) {
1553        if (config == "//build/config/compiler:no_rtti") {
1554          configs -= [ "//build/config/compiler:no_rtti" ]
1555        }
1556      }
1557      configs += [ "//build/config/compiler:rtti" ]
1558    }
1559
1560    if (!defined(cflags)) {
1561      cflags = []
1562    }
1563
1564    # Enable branch protection.
1565    pac_ret = false
1566    bti = false
1567    if (defined(invoker.branch_protector_ret)) {
1568      if (invoker.branch_protector_ret == "pac_ret" ||
1569          invoker.branch_protector_ret == "stack_protector_ret_all") {
1570        if (support_branch_protector_pac_ret) {
1571          pac_ret = true
1572        } else if (support_stack_protector_ret) {
1573          foreach(config, configs) {
1574            if (config ==
1575                "//build/config/security:stack_protector_ret_strong_config") {
1576              configs -= [
1577                "//build/config/security:stack_protector_ret_strong_config",
1578              ]
1579            }
1580          }
1581          configs +=
1582              [ "//build/config/security:stack_protector_ret_all_config" ]
1583        }
1584      }
1585
1586      # Nothing to do, supported by default.
1587      if (support_stack_protector_ret &&
1588          invoker.branch_protector_ret == "stack_protector_ret_strong") {
1589      }
1590    } else {
1591      if (defined(invoker.stack_protector_ret)) {
1592        if (invoker.stack_protector_ret) {
1593          if (support_branch_protector_pac_ret) {
1594            pac_ret = true
1595          } else if (support_stack_protector_ret) {
1596            foreach(config, configs) {
1597              if (config ==
1598                  "//build/config/security:stack_protector_ret_strong_config") {
1599                configs -= [
1600                  "//build/config/security:stack_protector_ret_strong_config",
1601                ]
1602              }
1603            }
1604            configs +=
1605                [ "//build/config/security:stack_protector_ret_all_config" ]
1606          }
1607        } else {
1608          foreach(config, configs) {
1609            if (config ==
1610                "//build/config/security:stack_protector_ret_strong_config") {
1611              configs -= [
1612                "//build/config/security:stack_protector_ret_strong_config",
1613              ]
1614            }
1615          }
1616          configs += [ "//build/config/security:stack_protector_config" ]
1617        }
1618      }
1619    }
1620
1621    if (defined(cflags)) {
1622      foreach(cflag, cflags) {
1623        if (cflag == "-fstack-protector-strong") {
1624          cflags -= [ "-fstack-protector-strong" ]
1625        }
1626      }
1627    }
1628
1629    if (defined(cflags_c)) {
1630      foreach(cflag_c, cflags_c) {
1631        if (cflag_c == "-fstack-protector-strong") {
1632          cflags_c -= [ "-fstack-protector-strong" ]
1633        }
1634      }
1635    }
1636
1637    if (defined(cflags_cc)) {
1638      foreach(cflag_cc, cflags_cc) {
1639        if (cflag_cc == "-fstack-protector-strong") {
1640          cflags_cc -= [ "-fstack-protector-strong" ]
1641        }
1642      }
1643    }
1644
1645    if (defined(invoker.branch_protector_frt)) {
1646      if (invoker.branch_protector_frt == "bti" &&
1647          support_branch_protector_bti) {
1648        bti = true
1649      }
1650    }
1651
1652    if (!defined(ldflags)) {
1653      ldflags = []
1654    }
1655
1656    if (bti && pac_ret) {
1657      cflags += [ "-mbranch-protection=pac-ret+b-key+bti" ]
1658      ldflags += [ "-Wl,-z,force-bti" ]
1659    } else if (bti && !pac_ret) {
1660      cflags += [ "-mbranch-protection=bti" ]
1661      ldflags += [ "-Wl,-z,force-bti" ]
1662    } else if (!bti && pac_ret) {
1663      cflags += [ "-mbranch-protection=pac-ret+b-key" ]
1664    }
1665
1666    if (defined(invoker.no_default_deps)) {
1667      no_default_deps = invoker.no_default_deps
1668    }
1669
1670    if (!defined(deps)) {
1671      deps = []
1672    }
1673    if (is_use_check_deps && !_test_target) {
1674      deps += [ ":$_check_target" ]
1675    }
1676    if (!_test_target) {
1677      deps += [ ":$_notice_target" ]
1678    }
1679
1680    if (!defined(libs)) {
1681      libs = []
1682    }
1683    if (!defined(include_dirs)) {
1684      include_dirs = []
1685    }
1686
1687    if (defined(is_debug) && !is_debug && enable_debug_components != "") {
1688      foreach(component_name, debug_components) {
1689        if (part_name == component_name) {
1690          configs -= default_opt_configs
1691          configs += debug_level_configs
1692        }
1693      }
1694    }
1695
1696    deps_info = []
1697    foreach(dep, deps) {
1698      info = {
1699      }
1700      info = {
1701        target_out_dir =
1702            rebase_path(get_label_info(dep, "target_out_dir"), root_build_dir)
1703        target_name = get_label_info(dep, "name")
1704      }
1705      deps_info += [ info ]
1706    }
1707    module_label = get_label_info(":${target_name}", "label_with_toolchain")
1708    target_deps_data = {
1709      label = module_label
1710      module_deps_info = deps_info
1711      module_libs = libs
1712      type = "static_library"
1713      prebuilt = false
1714      toolchain = get_label_info(":${target_name}", "toolchain")
1715    }
1716    write_file("${target_out_dir}/${target_name}_deps_data.json",
1717               target_deps_data,
1718               "json")
1719  }
1720}
1721
1722template("ohos_source_set") {
1723  _test_target = defined(invoker.testonly) && invoker.testonly
1724  if (defined(invoker.subsystem_name) && defined(invoker.part_name)) {
1725    subsystem_name = invoker.subsystem_name
1726    part_name = invoker.part_name
1727  } else if (defined(invoker.part_name)) {
1728    part_name = invoker.part_name
1729    _part_subsystem_info_file =
1730        "$root_build_dir/build_configs/parts_info/part_subsystem.json"
1731    _arguments = [
1732      "--part-name",
1733      part_name,
1734      "--part-subsystem-info-file",
1735      rebase_path(_part_subsystem_info_file, root_build_dir),
1736    ]
1737    get_subsystem_script = "//build/templates/common/get_subsystem_name.py"
1738    subsystem_name =
1739        exec_script(get_subsystem_script, _arguments, "trim string")
1740    if (is_use_check_deps && !_test_target) {
1741      skip_check_subsystem = true
1742    }
1743  } else if (defined(invoker.subsystem_name)) {
1744    subsystem_name = invoker.subsystem_name
1745    part_name = subsystem_name
1746  } else {
1747    subsystem_name = "build"
1748    part_name = "build_framework"
1749  }
1750  assert(subsystem_name != "")
1751  assert(part_name != "")
1752
1753  if (is_use_check_deps && !_test_target) {
1754    _check_target = "${target_name}__check"
1755    target_path = get_label_info(":${target_name}", "label_no_toolchain")
1756    check_target(_check_target) {
1757      module_deps = []
1758      module_ex_deps = []
1759      if (defined(invoker.deps)) {
1760        module_deps += invoker.deps
1761      }
1762      if (defined(invoker.public_deps)) {
1763        module_deps += invoker.public_deps
1764      }
1765      if (defined(invoker.external_deps)) {
1766        module_ex_deps += invoker.external_deps
1767      }
1768      if (defined(invoker.public_external_deps)) {
1769        module_ex_deps += invoker.public_external_deps
1770      }
1771    }
1772  }
1773
1774  if (check_deps) {
1775    deps_data = {
1776    }
1777    module_label = get_label_info(":${target_name}", "label_with_toolchain")
1778    module_deps = []
1779    if (defined(invoker.deps)) {
1780      foreach(dep, invoker.deps) {
1781        module_deps += [ get_label_info(dep, "label_no_toolchain") ]
1782      }
1783    }
1784    module_ex_deps = []
1785    if (defined(invoker.external_deps) && invoker.external_deps != []) {
1786      module_ex_deps = invoker.external_deps
1787    }
1788    deps_data = {
1789      part_name = part_name
1790      module_label = module_label
1791      deps = module_deps
1792      external_deps = module_ex_deps
1793    }
1794    write_file("${root_out_dir}/deps_files/${part_name}__${target_name}.json",
1795               deps_data,
1796               "json")
1797  }
1798
1799  _security_config_target = "${target_name}__security_config"
1800  ohos_security_config(_security_config_target) {
1801    forward_variables_from(invoker, [ "auto_var_init" ])
1802  }
1803
1804  if (!allow_sanitize_debug && !build_xts &&
1805      defined(ext_sanitizer_check_list_path)) {
1806    build_name = "${target_name}"
1807    ohos_sanitizer_check("${target_name}_sanitizer_check") {
1808      forward_variables_from(invoker, [ "sanitize" ])
1809    }
1810  }
1811
1812  _sanitize_config_target = "${target_name}__sanitizer_config"
1813  ohos_sanitizer_config(_sanitize_config_target) {
1814    forward_variables_from(invoker, [ "sanitize" ])
1815  }
1816
1817  if (!_test_target) {
1818    _main_target_name = target_name
1819    _notice_target = "${_main_target_name}__notice"
1820    collect_notice(_notice_target) {
1821      forward_variables_from(invoker,
1822                             [
1823                               "testonly",
1824                               "license_as_sources",
1825                               "license_file",
1826                             ])
1827
1828      module_type = "source_set"
1829      module_name = _main_target_name
1830      module_source_dir = get_label_info(":${_main_target_name}", "dir")
1831    }
1832  }
1833
1834  source_set(target_name) {
1835    forward_variables_from(invoker,
1836                           "*",
1837                           [
1838                             "configs",
1839                             "remove_configs",
1840                             "no_default_deps",
1841                             "license_file",
1842                             "license_as_sources",
1843                             "use_exceptions",
1844                             "use_rtti",
1845                             "subsystem_name",
1846
1847                             # Sanitizer variables
1848                             "sanitize",
1849                             "stack_protector_ret",
1850                             "branch_protector_ret",
1851                             "branch_protector_frt",
1852                           ])
1853    if (defined(invoker.configs)) {
1854      configs += invoker.configs
1855    }
1856    if (defined(invoker.remove_configs)) {
1857      configs -= invoker.remove_configs
1858    }
1859
1860    configs += [ ":$_sanitize_config_target" ]
1861    configs += [ ":$_security_config_target" ]
1862
1863    if (defined(invoker.use_exceptions) && invoker.use_exceptions) {
1864      foreach(config, configs) {
1865        if (config == "//build/config/compiler:no_exceptions") {
1866          configs -= [ "//build/config/compiler:no_exceptions" ]
1867        }
1868      }
1869      configs += [ "//build/config/compiler:exceptions" ]
1870    }
1871
1872    if (defined(invoker.use_rtti) && invoker.use_rtti) {
1873      foreach(config, configs) {
1874        if (config == "//build/config/compiler:no_rtti") {
1875          configs -= [ "//build/config/compiler:no_rtti" ]
1876        }
1877      }
1878      configs += [ "//build/config/compiler:rtti" ]
1879    }
1880
1881    if (!defined(cflags)) {
1882      cflags = []
1883    }
1884
1885    # Enable branch protection.
1886    pac_ret = false
1887    bti = false
1888    if (defined(invoker.branch_protector_ret)) {
1889      if (invoker.branch_protector_ret == "pac_ret" ||
1890          invoker.branch_protector_ret == "stack_protector_ret_all") {
1891        if (support_branch_protector_pac_ret) {
1892          pac_ret = true
1893        } else if (support_stack_protector_ret) {
1894          foreach(config, configs) {
1895            if (config ==
1896                "//build/config/security:stack_protector_ret_strong_config") {
1897              configs -= [
1898                "//build/config/security:stack_protector_ret_strong_config",
1899              ]
1900            }
1901          }
1902          configs +=
1903              [ "//build/config/security:stack_protector_ret_all_config" ]
1904        }
1905      }
1906
1907      # Nothing to do, supported by default.
1908      if (support_stack_protector_ret &&
1909          invoker.branch_protector_ret == "stack_protector_ret_strong") {
1910      }
1911    } else {
1912      if (defined(invoker.stack_protector_ret)) {
1913        if (invoker.stack_protector_ret) {
1914          if (support_branch_protector_pac_ret) {
1915            pac_ret = true
1916          } else if (support_stack_protector_ret) {
1917            foreach(config, configs) {
1918              if (config ==
1919                  "//build/config/security:stack_protector_ret_strong_config") {
1920                configs -= [
1921                  "//build/config/security:stack_protector_ret_strong_config",
1922                ]
1923              }
1924            }
1925            configs +=
1926                [ "//build/config/security:stack_protector_ret_all_config" ]
1927          }
1928        } else {
1929          foreach(config, configs) {
1930            if (config ==
1931                "//build/config/security:stack_protector_ret_strong_config") {
1932              configs -= [
1933                "//build/config/security:stack_protector_ret_strong_config",
1934              ]
1935            }
1936          }
1937          configs += [ "//build/config/security:stack_protector_config" ]
1938        }
1939      }
1940    }
1941
1942    if (defined(cflags)) {
1943      foreach(cflag, cflags) {
1944        if (cflag == "-fstack-protector-strong") {
1945          cflags -= [ "-fstack-protector-strong" ]
1946        }
1947      }
1948    }
1949
1950    if (defined(cflags_c)) {
1951      foreach(cflag_c, cflags_c) {
1952        if (cflag_c == "-fstack-protector-strong") {
1953          cflags_c -= [ "-fstack-protector-strong" ]
1954        }
1955      }
1956    }
1957
1958    if (defined(cflags_cc)) {
1959      foreach(cflag_cc, cflags_cc) {
1960        if (cflag_cc == "-fstack-protector-strong") {
1961          cflags_cc -= [ "-fstack-protector-strong" ]
1962        }
1963      }
1964    }
1965
1966    if (defined(invoker.branch_protector_frt)) {
1967      if (invoker.branch_protector_frt == "bti" &&
1968          support_branch_protector_bti) {
1969        bti = true
1970      }
1971    }
1972
1973    if (!defined(ldflags)) {
1974      ldflags = []
1975    }
1976
1977    if (bti && pac_ret) {
1978      cflags += [ "-mbranch-protection=pac-ret+b-key+bti" ]
1979      ldflags += [ "-Wl,-z,force-bti" ]
1980    } else if (bti && !pac_ret) {
1981      cflags += [ "-mbranch-protection=bti" ]
1982      ldflags += [ "-Wl,-z,force-bti" ]
1983    } else if (!bti && pac_ret) {
1984      cflags += [ "-mbranch-protection=pac-ret+b-key" ]
1985    }
1986
1987    if (defined(invoker.no_default_deps)) {
1988      no_default_deps = invoker.no_default_deps
1989    }
1990
1991    if (!defined(deps)) {
1992      deps = []
1993    }
1994    if (is_use_check_deps && !_test_target) {
1995      deps += [ ":$_check_target" ]
1996    }
1997    if (!_test_target) {
1998      deps += [ ":$_notice_target" ]
1999    }
2000
2001    if (!defined(libs)) {
2002      libs = []
2003    }
2004    if (!defined(include_dirs)) {
2005      include_dirs = []
2006    }
2007
2008    if (defined(is_debug) && !is_debug && enable_debug_components != "") {
2009      foreach(component_name, debug_components) {
2010        if (part_name == component_name) {
2011          configs -= default_opt_configs
2012          configs += debug_level_configs
2013        }
2014      }
2015    }
2016
2017    deps_info = []
2018    foreach(dep, deps) {
2019      info = {
2020      }
2021      info = {
2022        target_out_dir =
2023            rebase_path(get_label_info(dep, "target_out_dir"), root_build_dir)
2024        target_name = get_label_info(dep, "name")
2025      }
2026      deps_info += [ info ]
2027    }
2028    module_label = get_label_info(":${target_name}", "label_with_toolchain")
2029    target_deps_data = {
2030      label = module_label
2031      module_deps_info = deps_info
2032      module_libs = libs
2033      type = "source_set"
2034      toolchain = get_label_info(":${target_name}", "toolchain")
2035    }
2036    write_file("${target_out_dir}/${target_name}_deps_data.json",
2037               target_deps_data,
2038               "json")
2039  }
2040}
2041
2042template("ohos_shared_headers") {
2043  assert(!defined(invoker.sources), "sources is not allowed to be defined.")
2044  assert(defined(invoker.include_dirs), "include_dirs is must to be defined.")
2045  assert(defined(invoker.subsystem_name), "subsystem_name is must to be defined.")
2046  assert(defined(invoker.part_name), "part_name is must to be defined.")
2047
2048  deps_inner = []
2049  if (defined(invoker.deps)) {
2050    foreach(dep, invoker.deps) {
2051      deps_inner += [ dep ]
2052    }
2053  }
2054
2055  if (defined(invoker.subsystem_name)) {
2056    subsystem_name = invoker.subsystem_name
2057  }
2058
2059  if (defined(invoker.part_name)) {
2060    part_name = invoker.part_name
2061  }
2062
2063  not_needed([ "subsystem_name", "part_name" ])
2064
2065  include_inner = []
2066  foreach(include_dir, invoker.include_dirs) {
2067    include_inner += [ include_dir ]
2068  }
2069  config("${target_name}_public_config") {
2070    include_dirs = include_inner
2071  }
2072
2073  group("${target_name}") {
2074    check_flag = false
2075    deps = deps_inner
2076    public_configs = [ ":${target_name}_public_config" ]
2077  }
2078}
2079