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