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        if (target_name != "libpcre2" && target_name != "libselinux" &&
1120            target_name != "libsec_shared" && target_name != "libsepol") {
1121          libs += [ "c++" ]
1122        }
1123      }
1124    }
1125
1126    if (!_test_target) {
1127      deps += [ ":$_notice_target" ]
1128    }
1129    if (!defined(include_dirs)) {
1130      include_dirs = []
1131    }
1132
1133    install_module_info = {
1134      module_def = target_label
1135      module_info_file =
1136          rebase_path(get_label_info(module_def, "target_out_dir"),
1137                      root_build_dir) + "/${target_name}_module_info.json"
1138      subsystem_name = subsystem_name
1139      part_name = part_name
1140      toolchain = current_toolchain
1141      toolchain_out_dir = rebase_path(root_out_dir, root_build_dir)
1142    }
1143    metadata = {
1144      install_modules = [ install_module_info ]
1145    }
1146    if (defined(is_debug) && !is_debug && enable_debug_components != "") {
1147      foreach(component_name, debug_components) {
1148        if (part_name == component_name) {
1149          configs -= default_opt_configs
1150          configs += debug_level_configs
1151        }
1152      }
1153    }
1154
1155    # Hide symbols for all sa libraries if not specified by version_script
1156    if (defined(invoker.shlib_type) && invoker.shlib_type == "sa") {
1157      if (!defined(invoker.version_script)) {
1158        _version_script =
1159            rebase_path("//build/templates/cxx/singleton.versionscript")
1160        inputs += [ _version_script ]
1161        ldflags += [ "-Wl,--version-script=${_version_script}" ]
1162      }
1163    }
1164
1165    # Set version_script for hdi service libraries
1166    if (defined(invoker.shlib_type) && invoker.shlib_type == "hdi") {
1167      if (!defined(invoker.version_script)) {
1168        _version_script = rebase_path("//build/templates/cxx/hdi.versionscript")
1169        inputs += [ _version_script ]
1170        ldflags += [ "-Wl,--version-script=${_version_script}" ]
1171      }
1172    }
1173
1174    module_type_napi = false
1175    if (defined(invoker.relative_install_dir) &&
1176        (build_ohos_sdk != true && build_ohos_ndk != true)) {
1177      relative_paths = string_split(invoker.relative_install_dir, "/")
1178      foreach(p, relative_paths) {
1179        if (p == "module") {
1180          module_type_napi = true
1181        }
1182      }
1183      if (module_type_napi) {
1184        foreach(m, filter_include(napi_white_list, [ target_name ])) {
1185          if (m == target_name) {
1186            module_type_napi = false
1187          }
1188        }
1189      }
1190    }
1191    if (module_type_napi) {
1192      if (!defined(invoker.version_script)) {
1193        _version_script =
1194            rebase_path("//build/templates/cxx/napi.versionscript")
1195        inputs += [ _version_script ]
1196        ldflags += [ "-Wl,--version-script=${_version_script}" ]
1197      }
1198    }
1199
1200    deps_info = []
1201    foreach(dep, deps) {
1202      info = {
1203      }
1204      info = {
1205        target_out_dir =
1206            rebase_path(get_label_info(dep, "target_out_dir"), root_build_dir)
1207        target_name = get_label_info(dep, "name")
1208      }
1209      deps_info += [ info ]
1210    }
1211    module_label = get_label_info(":${target_name}", "label_with_toolchain")
1212    target_deps_data = {
1213      label = module_label
1214      module_deps_info = deps_info
1215      module_libs = libs
1216      type = "shared_library"
1217      prebuilt = false
1218      stable = stable
1219      toolchain = get_label_info(":${target_name}", "toolchain")
1220    }
1221    write_file("${target_out_dir}/${target_name}_deps_data.json",
1222               target_deps_data,
1223               "json")
1224  }
1225}
1226
1227template("ohos_static_library") {
1228  _test_target = defined(invoker.testonly) && invoker.testonly
1229  if (defined(invoker.subsystem_name) && defined(invoker.part_name)) {
1230    subsystem_name = invoker.subsystem_name
1231    part_name = invoker.part_name
1232  } else if (defined(invoker.part_name)) {
1233    part_name = invoker.part_name
1234    _part_subsystem_info_file =
1235        "$root_build_dir/build_configs/parts_info/part_subsystem.json"
1236    _arguments = [
1237      "--part-name",
1238      part_name,
1239      "--part-subsystem-info-file",
1240      rebase_path(_part_subsystem_info_file, root_build_dir),
1241    ]
1242    get_subsystem_script = "//build/templates/common/get_subsystem_name.py"
1243    subsystem_name =
1244        exec_script(get_subsystem_script, _arguments, "trim string")
1245    if (is_use_check_deps && !_test_target) {
1246      skip_check_subsystem = true
1247    }
1248  } else if (defined(invoker.subsystem_name)) {
1249    subsystem_name = invoker.subsystem_name
1250    part_name = subsystem_name
1251  } else {
1252    subsystem_name = "build"
1253    part_name = "build_framework"
1254  }
1255  assert(subsystem_name != "")
1256  assert(part_name != "")
1257
1258  if (is_use_check_deps && !_test_target) {
1259    _check_target = "${target_name}__check"
1260    target_path = get_label_info(":${target_name}", "label_no_toolchain")
1261    check_target(_check_target) {
1262      module_deps = []
1263      if (defined(invoker.deps)) {
1264        module_deps += invoker.deps
1265      }
1266      if (defined(invoker.public_deps)) {
1267        module_deps += invoker.public_deps
1268      }
1269      if (defined(invoker.external_deps)) {
1270        module_ex_deps = invoker.external_deps
1271      }
1272    }
1273  }
1274  if (check_deps) {
1275    deps_data = {
1276    }
1277    module_label = get_label_info(":${target_name}", "label_with_toolchain")
1278    module_deps = []
1279    if (defined(invoker.deps)) {
1280      foreach(dep, invoker.deps) {
1281        module_deps += [ get_label_info(dep, "label_no_toolchain") ]
1282      }
1283    }
1284    module_ex_deps = []
1285    if (defined(invoker.external_deps) && invoker.external_deps != []) {
1286      module_ex_deps = invoker.external_deps
1287    }
1288    deps_data = {
1289      part_name = part_name
1290      module_label = module_label
1291      deps = module_deps
1292      external_deps = module_ex_deps
1293    }
1294
1295    write_file("${root_out_dir}/deps_files/${part_name}__${target_name}.json",
1296               deps_data,
1297               "json")
1298  }
1299
1300  _security_config_target = "${target_name}__security_config"
1301  ohos_security_config(_security_config_target) {
1302    forward_variables_from(invoker, [ "auto_var_init" ])
1303  }
1304
1305  if (!allow_sanitize_debug && !build_xts &&
1306      defined(ext_sanitizer_check_list_path)) {
1307    build_name = "${target_name}"
1308    ohos_sanitizer_check("${target_name}_sanitizer_check") {
1309      forward_variables_from(invoker, [ "sanitize" ])
1310    }
1311  }
1312
1313  _sanitize_config_target = "${target_name}__sanitizer_config"
1314  ohos_sanitizer_config(_sanitize_config_target) {
1315    forward_variables_from(invoker, [ "sanitize" ])
1316  }
1317
1318  if (!_test_target) {
1319    _notice_target = "${target_name}__notice"
1320    _main_target_name = target_name
1321    collect_notice(_notice_target) {
1322      forward_variables_from(invoker,
1323                             [
1324                               "testonly",
1325                               "license_as_sources",
1326                               "license_file",
1327                             ])
1328      module_type = "static_library"
1329      module_name = _main_target_name
1330      module_source_dir = get_label_info(":${_main_target_name}", "dir")
1331    }
1332  }
1333
1334  static_library(target_name) {
1335    forward_variables_from(invoker,
1336                           "*",
1337                           [
1338                             "configs",
1339                             "remove_configs",
1340                             "no_default_deps",
1341                             "license_file",
1342                             "license_as_sources",
1343                             "use_exceptions",
1344                             "use_rtti",
1345                             "subsystem_name",
1346
1347                             # Sanitizer variables
1348                             "sanitize",
1349                             "stack_protector_ret",
1350                             "branch_protector_ret",
1351                             "branch_protector_frt",
1352                           ])
1353    if (defined(invoker.configs)) {
1354      configs += invoker.configs
1355    }
1356    if (defined(invoker.remove_configs)) {
1357      configs -= invoker.remove_configs
1358    }
1359    if (is_standard_system) {
1360      configs -= [ "//build/config/compiler:thin_archive" ]
1361    }
1362    configs += [ ":$_sanitize_config_target" ]
1363    configs += [ ":$_security_config_target" ]
1364
1365    if (defined(invoker.use_exceptions) && invoker.use_exceptions) {
1366      configs += [ "//build/config/compiler:exceptions" ]
1367      configs -= [ "//build/config/compiler:no_exceptions" ]
1368    }
1369
1370    if (defined(invoker.use_rtti) && invoker.use_rtti) {
1371      configs += [ "//build/config/compiler:rtti" ]
1372      configs -= [ "//build/config/compiler:no_rtti" ]
1373    }
1374
1375    if (!defined(cflags)) {
1376      cflags = []
1377    }
1378
1379    # Enable branch protection.
1380    pac_ret = false
1381    bti = false
1382    if (defined(invoker.branch_protector_ret)) {
1383      if (invoker.branch_protector_ret == "pac_ret" ||
1384          invoker.branch_protector_ret == "stack_protector_ret_all") {
1385        if (support_branch_protector_pac_ret) {
1386          pac_ret = true
1387        } else if (support_stack_protector_ret) {
1388          foreach(config, configs) {
1389            if (config ==
1390                "//build/config/security:stack_protector_ret_strong_config") {
1391              configs -= [
1392                "//build/config/security:stack_protector_ret_strong_config",
1393              ]
1394            }
1395          }
1396          configs +=
1397              [ "//build/config/security:stack_protector_ret_all_config" ]
1398        }
1399      }
1400
1401      # Nothing to do, supported by default.
1402      if (support_stack_protector_ret &&
1403          invoker.branch_protector_ret == "stack_protector_ret_strong") {
1404      }
1405    } else {
1406      if (defined(invoker.stack_protector_ret)) {
1407        if (invoker.stack_protector_ret) {
1408          if (support_branch_protector_pac_ret) {
1409            pac_ret = true
1410          } else if (support_stack_protector_ret) {
1411            foreach(config, configs) {
1412              if (config ==
1413                  "//build/config/security:stack_protector_ret_strong_config") {
1414                configs -= [
1415                  "//build/config/security:stack_protector_ret_strong_config",
1416                ]
1417              }
1418            }
1419            configs +=
1420                [ "//build/config/security:stack_protector_ret_all_config" ]
1421          }
1422        } else {
1423          foreach(config, configs) {
1424            if (config ==
1425                "//build/config/security:stack_protector_ret_strong_config") {
1426              configs -= [
1427                "//build/config/security:stack_protector_ret_strong_config",
1428              ]
1429            }
1430          }
1431          configs += [ "//build/config/security:stack_protector_config" ]
1432        }
1433      }
1434    }
1435
1436    if (defined(invoker.branch_protector_frt)) {
1437      if (invoker.branch_protector_frt == "bti" &&
1438          support_branch_protector_bti) {
1439        bti = true
1440      }
1441    }
1442
1443    if (bti && pac_ret) {
1444      cflags += [ "-mbranch-protection=pac-ret+b-key+bti" ]
1445    } else if (bti && !pac_ret) {
1446      cflags += [ "-mbranch-protection=bti" ]
1447    } else if (!bti && pac_ret) {
1448      cflags += [ "-mbranch-protection=pac-ret+b-key" ]
1449    }
1450
1451    if (defined(invoker.no_default_deps)) {
1452      no_default_deps = invoker.no_default_deps
1453    }
1454
1455    if (!defined(deps)) {
1456      deps = []
1457    }
1458    if (is_use_check_deps && !_test_target) {
1459      deps += [ ":$_check_target" ]
1460    }
1461    if (!_test_target) {
1462      deps += [ ":$_notice_target" ]
1463    }
1464    if (!defined(libs)) {
1465      libs = []
1466    }
1467    if (!defined(include_dirs)) {
1468      include_dirs = []
1469    }
1470
1471    if (defined(is_debug) && !is_debug && enable_debug_components != "") {
1472      foreach(component_name, debug_components) {
1473        if (part_name == component_name) {
1474          configs -= default_opt_configs
1475          configs += debug_level_configs
1476        }
1477      }
1478    }
1479
1480    deps_info = []
1481    foreach(dep, deps) {
1482      info = {
1483      }
1484      info = {
1485        target_out_dir =
1486            rebase_path(get_label_info(dep, "target_out_dir"), root_build_dir)
1487        target_name = get_label_info(dep, "name")
1488      }
1489      deps_info += [ info ]
1490    }
1491    module_label = get_label_info(":${target_name}", "label_with_toolchain")
1492    target_deps_data = {
1493      label = module_label
1494      module_deps_info = deps_info
1495      module_libs = libs
1496      type = "static_library"
1497      prebuilt = false
1498      toolchain = get_label_info(":${target_name}", "toolchain")
1499    }
1500    write_file("${target_out_dir}/${target_name}_deps_data.json",
1501               target_deps_data,
1502               "json")
1503  }
1504}
1505
1506template("ohos_source_set") {
1507  _test_target = defined(invoker.testonly) && invoker.testonly
1508  if (defined(invoker.subsystem_name) && defined(invoker.part_name)) {
1509    subsystem_name = invoker.subsystem_name
1510    part_name = invoker.part_name
1511  } else if (defined(invoker.part_name)) {
1512    part_name = invoker.part_name
1513    _part_subsystem_info_file =
1514        "$root_build_dir/build_configs/parts_info/part_subsystem.json"
1515    _arguments = [
1516      "--part-name",
1517      part_name,
1518      "--part-subsystem-info-file",
1519      rebase_path(_part_subsystem_info_file, root_build_dir),
1520    ]
1521    get_subsystem_script = "//build/templates/common/get_subsystem_name.py"
1522    subsystem_name =
1523        exec_script(get_subsystem_script, _arguments, "trim string")
1524    if (is_use_check_deps && !_test_target) {
1525      skip_check_subsystem = true
1526    }
1527  } else if (defined(invoker.subsystem_name)) {
1528    subsystem_name = invoker.subsystem_name
1529    part_name = subsystem_name
1530  } else {
1531    subsystem_name = "build"
1532    part_name = "build_framework"
1533  }
1534  assert(subsystem_name != "")
1535  assert(part_name != "")
1536
1537  if (is_use_check_deps && !_test_target) {
1538    _check_target = "${target_name}__check"
1539    target_path = get_label_info(":${target_name}", "label_no_toolchain")
1540    check_target(_check_target) {
1541      module_deps = []
1542      if (defined(invoker.deps)) {
1543        module_deps += invoker.deps
1544      }
1545      if (defined(invoker.public_deps)) {
1546        module_deps += invoker.public_deps
1547      }
1548      if (defined(invoker.external_deps)) {
1549        module_ex_deps = invoker.external_deps
1550      }
1551    }
1552  }
1553
1554  if (check_deps) {
1555    deps_data = {
1556    }
1557    module_label = get_label_info(":${target_name}", "label_with_toolchain")
1558    module_deps = []
1559    if (defined(invoker.deps)) {
1560      foreach(dep, invoker.deps) {
1561        module_deps += [ get_label_info(dep, "label_no_toolchain") ]
1562      }
1563    }
1564    module_ex_deps = []
1565    if (defined(invoker.external_deps) && invoker.external_deps != []) {
1566      module_ex_deps = invoker.external_deps
1567    }
1568    deps_data = {
1569      part_name = part_name
1570      module_label = module_label
1571      deps = module_deps
1572      external_deps = module_ex_deps
1573    }
1574    write_file("${root_out_dir}/deps_files/${part_name}__${target_name}.json",
1575               deps_data,
1576               "json")
1577  }
1578
1579  _security_config_target = "${target_name}__security_config"
1580  ohos_security_config(_security_config_target) {
1581    forward_variables_from(invoker, [ "auto_var_init" ])
1582  }
1583
1584  if (!allow_sanitize_debug && !build_xts &&
1585      defined(ext_sanitizer_check_list_path)) {
1586    build_name = "${target_name}"
1587    ohos_sanitizer_check("${target_name}_sanitizer_check") {
1588      forward_variables_from(invoker, [ "sanitize" ])
1589    }
1590  }
1591
1592  _sanitize_config_target = "${target_name}__sanitizer_config"
1593  ohos_sanitizer_config(_sanitize_config_target) {
1594    forward_variables_from(invoker, [ "sanitize" ])
1595  }
1596
1597  if (!_test_target) {
1598    _main_target_name = target_name
1599    _notice_target = "${_main_target_name}__notice"
1600    collect_notice(_notice_target) {
1601      forward_variables_from(invoker,
1602                             [
1603                               "testonly",
1604                               "license_as_sources",
1605                               "license_file",
1606                             ])
1607
1608      module_type = "source_set"
1609      module_name = _main_target_name
1610      module_source_dir = get_label_info(":${_main_target_name}", "dir")
1611    }
1612  }
1613
1614  source_set(target_name) {
1615    forward_variables_from(invoker,
1616                           "*",
1617                           [
1618                             "configs",
1619                             "remove_configs",
1620                             "no_default_deps",
1621                             "license_file",
1622                             "license_as_sources",
1623                             "use_exceptions",
1624                             "use_rtti",
1625                             "subsystem_name",
1626
1627                             # Sanitizer variables
1628                             "sanitize",
1629                             "stack_protector_ret",
1630                             "branch_protector_ret",
1631                             "branch_protector_frt",
1632                           ])
1633    if (defined(invoker.configs)) {
1634      configs += invoker.configs
1635    }
1636    if (defined(invoker.remove_configs)) {
1637      configs -= invoker.remove_configs
1638    }
1639
1640    configs += [ ":$_sanitize_config_target" ]
1641    configs += [ ":$_security_config_target" ]
1642
1643    if (defined(invoker.use_exceptions) && invoker.use_exceptions) {
1644      configs += [ "//build/config/compiler:exceptions" ]
1645      configs -= [ "//build/config/compiler:no_exceptions" ]
1646    }
1647
1648    if (defined(invoker.use_rtti) && invoker.use_rtti) {
1649      configs += [ "//build/config/compiler:rtti" ]
1650      configs -= [ "//build/config/compiler:no_rtti" ]
1651    }
1652
1653    if (!defined(cflags)) {
1654      cflags = []
1655    }
1656
1657    # Enable branch protection.
1658    pac_ret = false
1659    bti = false
1660    if (defined(invoker.branch_protector_ret)) {
1661      if (invoker.branch_protector_ret == "pac_ret" ||
1662          invoker.branch_protector_ret == "stack_protector_ret_all") {
1663        if (support_branch_protector_pac_ret) {
1664          pac_ret = true
1665        } else if (support_stack_protector_ret) {
1666          foreach(config, configs) {
1667            if (config ==
1668                "//build/config/security:stack_protector_ret_strong_config") {
1669              configs -= [
1670                "//build/config/security:stack_protector_ret_strong_config",
1671              ]
1672            }
1673          }
1674          configs +=
1675              [ "//build/config/security:stack_protector_ret_all_config" ]
1676        }
1677      }
1678
1679      # Nothing to do, supported by default.
1680      if (support_stack_protector_ret &&
1681          invoker.branch_protector_ret == "stack_protector_ret_strong") {
1682      }
1683    } else {
1684      if (defined(invoker.stack_protector_ret)) {
1685        if (invoker.stack_protector_ret) {
1686          if (support_branch_protector_pac_ret) {
1687            pac_ret = true
1688          } else if (support_stack_protector_ret) {
1689            foreach(config, configs) {
1690              if (config ==
1691                  "//build/config/security:stack_protector_ret_strong_config") {
1692                configs -= [
1693                  "//build/config/security:stack_protector_ret_strong_config",
1694                ]
1695              }
1696            }
1697            configs +=
1698                [ "//build/config/security:stack_protector_ret_all_config" ]
1699          }
1700        } else {
1701          foreach(config, configs) {
1702            if (config ==
1703                "//build/config/security:stack_protector_ret_strong_config") {
1704              configs -= [
1705                "//build/config/security:stack_protector_ret_strong_config",
1706              ]
1707            }
1708          }
1709          configs += [ "//build/config/security:stack_protector_config" ]
1710        }
1711      }
1712    }
1713
1714    if (defined(invoker.branch_protector_frt)) {
1715      if (invoker.branch_protector_frt == "bti" &&
1716          support_branch_protector_bti) {
1717        bti = true
1718      }
1719    }
1720
1721    if (bti && pac_ret) {
1722      cflags += [ "-mbranch-protection=pac-ret+b-key+bti" ]
1723    } else if (bti && !pac_ret) {
1724      cflags += [ "-mbranch-protection=bti" ]
1725    } else if (!bti && pac_ret) {
1726      cflags += [ "-mbranch-protection=pac-ret+b-key" ]
1727    }
1728
1729    if (defined(invoker.no_default_deps)) {
1730      no_default_deps = invoker.no_default_deps
1731    }
1732
1733    if (!defined(deps)) {
1734      deps = []
1735    }
1736    if (is_use_check_deps && !_test_target) {
1737      deps += [ ":$_check_target" ]
1738    }
1739    if (!_test_target) {
1740      deps += [ ":$_notice_target" ]
1741    }
1742
1743    if (!defined(libs)) {
1744      libs = []
1745    }
1746    if (!defined(include_dirs)) {
1747      include_dirs = []
1748    }
1749
1750    if (defined(is_debug) && !is_debug && enable_debug_components != "") {
1751      foreach(component_name, debug_components) {
1752        if (part_name == component_name) {
1753          configs -= default_opt_configs
1754          configs += debug_level_configs
1755        }
1756      }
1757    }
1758
1759    deps_info = []
1760    foreach(dep, deps) {
1761      info = {
1762      }
1763      info = {
1764        target_out_dir =
1765            rebase_path(get_label_info(dep, "target_out_dir"), root_build_dir)
1766        target_name = get_label_info(dep, "name")
1767      }
1768      deps_info += [ info ]
1769    }
1770    module_label = get_label_info(":${target_name}", "label_with_toolchain")
1771    target_deps_data = {
1772      label = module_label
1773      module_deps_info = deps_info
1774      module_libs = libs
1775      type = "source_set"
1776      toolchain = get_label_info(":${target_name}", "toolchain")
1777    }
1778    write_file("${target_out_dir}/${target_name}_deps_data.json",
1779               target_deps_data,
1780               "json")
1781  }
1782}
1783