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/python.gni")
15import("//build/ohos/kits/kits_check.gni")
16import("//build/ohos_var.gni")
17
18# Defines subsystem_sdk
19#
20# example:
21#
22# subsystem_sdk("examples_sdk") {
23#   sdk_libs = [
24#     {
25#       type = "so"
26#       name = "interfaces/innerkits/{module_name}:{module_name}"
27#       header = {
28#         header_files = [
29#           "calculator.h",
30#           "abc/a.h",
31#           "abc/xyz/b.h"
32#         ]
33#         header_base = "interfaces/innerkits/{module_name}/include/"
34#       }
35#     },
36#     {
37#       type = "jar"
38#       name = "interfaces/innerkits/{module_name}:{module_name}"
39#       header = {
40#         header_files = []
41#       }
42#     },
43#   ]
44#   subsystem_name = "subsystem_examples"
45# }
46
47declare_args() {
48  check_innerkits_path = ""
49}
50
51template("_ohos_subsystem_sdk") {
52  assert(defined(invoker.sdk_libs), "sdk_libs is required.")
53  assert(invoker.variant != "")
54  assert(invoker.origin_name != "")
55
56  part_name = "build_framework"
57  if (defined(invoker.part_name)) {
58    part_name = invoker.part_name
59  }
60  if (defined(invoker.subsystem_name)) {
61    subsystem_name = invoker.subsystem_name
62  } else {
63    subsystem_name = part_name
64  }
65
66  sdk_manifest = []
67  _deps = []
68  _libs_deps = []
69  if (invoker.sdk_libs != [] && check_innerkits_path != "") {
70    allow_list_info = read_file(rebase_path(check_innerkits_path), "json")
71  }
72  foreach(sdk_lib, invoker.sdk_libs) {
73    no_toolchain_deps_label = get_label_info(sdk_lib.name, "label_no_toolchain")
74    if (check_innerkits_path == "" ||
75        filter_include(allow_list_info.allow_list_name,
76                       [ no_toolchain_deps_label ]) != []) {
77      lib_label = get_label_info(sdk_lib.name, "label_with_toolchain")
78      _libs_deps += [ lib_label ]
79
80      lib_type = "so"
81      if (defined(sdk_lib.type)) {
82        lib_type = sdk_lib.type
83      }
84
85      module_out_dir = get_label_info(lib_label, "target_out_dir")
86      module_name = get_label_info(lib_label, "name")
87      module_info_file = "${module_out_dir}/${module_name}_module_info.json"
88
89      lib_header_files = []
90      lib_header_base = "interfaces/innerkits/${module_name}/include/"
91
92      if (defined(sdk_lib.headers)) {
93        if (defined(sdk_lib.header_base)) {
94          lib_header_base = sdk_lib.header_base
95        }
96        foreach(file, sdk_lib.headers) {
97          lib_header_files += [ string_replace(file, lib_header_base, "") ]
98        }
99      } else if (defined(sdk_lib.header)) {
100        header = {
101        }
102        header = sdk_lib.header
103        if (defined(header.header_base)) {
104          lib_header_base = header.header_base
105        }
106        lib_header_files = header.header_files
107      }
108
109      lib_prebuilt_enable = false
110      lib_prebuilt_source = ""
111      if (defined(sdk_lib.prebuilt_source)) {
112        lib_prebuilt_enable = true
113        lib_prebuilt_source = sdk_lib.prebuilt_source
114      }
115
116      sdk_manifest += [
117        {
118          label = lib_label
119          name = module_name
120          type = lib_type
121          header_files = lib_header_files
122          header_base = rebase_path(lib_header_base, "$root_build_dir")
123          source_info = rebase_path(module_info_file, "$root_build_dir")
124          prebuilt_enable = lib_prebuilt_enable
125          prebuilt_source = lib_prebuilt_source
126          subsystem_name = subsystem_name
127          part_name = part_name
128          origin_name = invoker.origin_name
129          current_toolchain = current_toolchain
130          current_toolchain_dir = rebase_path(root_out_dir, root_build_dir)
131        },
132      ]
133    }
134  }
135  _deps += _libs_deps
136
137  if (_deps != []) {
138    not_needed([ "no_toolchain_deps_label" ])
139
140    subsystem_sdk_desc_file =
141        "${target_out_dir}/${subsystem_name}_sdk_desc.json"
142    write_file(subsystem_sdk_desc_file, sdk_manifest, "json")
143
144    if (check_innersdk_interface && !gen_innersdk_interface_signature) {
145      kits_check_remove("${part_name}_innerkit_remove_check_so") {
146        subsystem_name = part_name
147        if (invoker.variant != "phone") {
148          subsystem_name = invoker.origin_name
149        }
150        sign_file_root_dir = "//interface/innersdk/native"
151        sdk_libs_name = []
152        foreach(_sdk_lib, sdk_manifest) {
153          if (_sdk_lib.type == "so") {
154            sdk_libs_name += [ _sdk_lib.name ]
155          }
156        }
157        output_file = "${target_gen_dir}/innerkit_remove_check_so"
158        sdk_type = "so"
159      }
160      _deps += [ ":${part_name}_innerkit_remove_check_so" ]
161    }
162
163    # gen sdk install modules
164    sdk_install_moudles_file =
165        "${target_gen_dir}/${subsystem_name}_sdk_install_modules.json"
166    generated_file("${subsystem_name}_sdk_info") {
167      outputs = [ sdk_install_moudles_file ]
168      data_keys = [ "install_modules" ]
169      output_conversion = "json"
170      deps = _libs_deps
171    }
172
173    sdk_out_dir = "${root_build_dir}/${innersdk_build_out_dir}/"
174    sdk_build_file = "${sdk_out_dir}/${subsystem_name}/BUILD.gn"
175    sdk_info_file = "${sdk_out_dir}/${subsystem_name}/sdk_info.json"
176
177    action_with_pydeps(target_name) {
178      deps = _deps
179      deps += [ ":${subsystem_name}_sdk_info" ]
180      script = "//build/scripts/gen_sdk_build_file.py"
181      sources = [ subsystem_sdk_desc_file ]
182      outputs = [
183        sdk_build_file,
184        sdk_info_file,
185      ]
186      args = [
187        "--input-file",
188        rebase_path(subsystem_sdk_desc_file, root_build_dir),
189        "--sdk-out-dir",
190        rebase_path("${sdk_out_dir}/${subsystem_name}", root_build_dir),
191        "--output-build-file",
192        rebase_path(sdk_build_file, root_build_dir),
193        "--sdk-info-file",
194        rebase_path(sdk_info_file, root_build_dir),
195      ]
196
197      if (check_innersdk_interface && !gen_innersdk_interface_signature) {
198        innersdk_interface_checkfile_dir = "//interface/innersdk/native"
199        args += [
200          "--signature-file-check-dir",
201          rebase_path(innersdk_interface_checkfile_dir, root_build_dir),
202        ]
203      } else if (gen_innersdk_interface_signature) {
204        args += [
205          "--generate-sig",
206          "--signature-file-gen-dir",
207          rebase_path(
208              "${root_build_dir}/innersdk_interface/native/${subsystem_name}",
209              root_build_dir),
210        ]
211      }
212    }
213  } else {
214    group(target_name) {
215      not_needed(invoker, "*")
216      not_needed([
217                   "subsystem_name",
218                   "sdk_manifest",
219                 ])
220    }
221  }
222}
223
224template("ohos_inner_kits") {
225  _ohos_subsystem_sdk(target_name) {
226    part_name = invoker.part_name
227    sdk_libs = invoker.sdk_libs
228    variant = invoker.variant
229    origin_name = invoker.origin_name
230  }
231}
232