1# Copyright (c) 2021-2024 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/ohos.gni")
15
16hdf_fwk_path = "//drivers/hdf_core/framework"
17hdf_uhdf_path = "//drivers/hdf_core/adapter/uhdf2"
18
19template("hdi") {
20  assert(defined(invoker.sources), "sources must be set")
21  assert(defined(invoker.language), "language must be set")
22  assert(defined(invoker.subsystem_name), "subsystem_name must be set")
23  assert(defined(invoker.part_name), "part_name must be set")
24
25  # the module_name is an obsolete option
26  if (defined(invoker.module_name)) {
27    print(invoker.module_name)
28  }
29
30  # system type
31  system = "full"
32
33  # generate mode, the default value is "ipc", the optional values are "ipc" or "passthrough"
34  mode = "ipc"
35  if (defined(invoker.mode)) {
36    assert(invoker.mode == "ipc" || invoker.mode == "passthrough",
37           "hdi mode must be 'ipc' or 'passthrough'")
38    mode = invoker.mode
39  }
40
41  assert(invoker.language == "c" || invoker.language == "cpp",
42         "the language must be set to 'c' or 'cpp'")
43  language = invoker.language
44
45  imports = []
46  if (defined(invoker.imports)) {
47    imports += invoker.imports
48  }
49
50  root_package = "ohos.hdi"
51  root_path = rebase_path("//drivers/interface")
52  if (defined(invoker.root)) {
53    package_path_map = string_split(invoker.root, ":")
54    root_package = package_path_map[0]
55    root_path = rebase_path(package_path_map[1])
56  }
57  root_package_path = "${root_package}:${root_path}"
58
59  # set base directory of hdi files, set this parameter to your component name if you are using external idl files.
60  if (defined(invoker.base_dir)) {
61    root_path += invoker.base_dir
62  }
63
64  sources_gen_dir = get_path_info("${root_path}/", "gen_dir")
65  get_build_info_args = [
66    "-s",
67    system,
68    "-m",
69    mode,
70    "-l",
71    invoker.language,
72    "-o",
73    sources_gen_dir,
74    "-r",
75    root_package_path,
76  ]
77  foreach(idl_file, invoker.sources) {
78    get_build_info_args += [ "-f" ]
79    get_build_info_args += [ rebase_path(idl_file) ]
80  }
81
82  foreach(import_info, imports) {
83    get_build_info_args += [
84      "--import",
85      import_info,
86    ]
87  }
88
89  hdi_build_info =
90      exec_script("$hdf_fwk_path/tools/hdi-gen/build_hdi_files_info.py",
91                  get_build_info_args,
92                  "json")
93  assert(defined(hdi_build_info.include_dirs), "missing include_dirs")
94  assert(defined(hdi_build_info.out_dir), "out_dir")
95  assert(defined(hdi_build_info.version), "missing version")
96  assert(defined(hdi_build_info.sources), "missing sources")
97  assert(defined(hdi_build_info.proxy_sources), "missing proxy_sources")
98  assert(defined(hdi_build_info.stub_sources), "missing stub_sources")
99  assert(defined(hdi_build_info.proxy_deps), "missing proxy_deps")
100  assert(defined(hdi_build_info.stub_deps), "missing stub_deps")
101  assert(defined(hdi_build_info.header_deps), "missing header_deps")
102
103  idl_headers_config = "$target_name" + "_idl_headers_config"
104  config("$idl_headers_config") {
105    include_dirs = [
106      "$hdf_uhdf_path/ipc/include",
107      "//drivers/hdf_core/interfaces/inner_api/utils",
108      "//drivers/hdf_core/interfaces/inner_api/osal/uhdf",
109      "//drivers/hdf_core/interfaces/inner_api/hdi",
110    ]
111    include_dirs += hdi_build_info.include_dirs
112  }
113
114  action("hdi_gen") {
115    deps = [ "$hdf_fwk_path/tools/hdi-gen:build_hdi_gen" ]
116    script = "/usr/bin/env"
117    if (defined(ohos_lite)) {
118      script = "//build/lite/run_shell_cmd.py"
119    }
120
121    idl_sources = invoker.sources
122    inputs = invoker.sources
123    outputs = hdi_build_info.sources
124
125    args = [
126      rebase_path(get_path_info("$hdf_fwk_path/tools/hdi-gen/", "out_dir") +
127                  "/hdi-gen"),
128      "--system",
129      system,
130      "--mode",
131      mode,
132      "--language",
133      language,
134      "-d",
135      rebase_path(hdi_build_info.out_dir),
136    ]
137
138    foreach(idl_file, idl_sources) {
139      args += [ "-c" ]
140      args += [ rebase_path(idl_file) ]
141    }
142    args += [
143      "-r",
144      root_package_path,
145    ]
146  }
147
148  lib_client = "lib" + target_name + "_proxy" + "_" + hdi_build_info.version
149  ohos_shared_library(lib_client) {
150    if (defined(invoker.sources)) {
151      sources = hdi_build_info.proxy_sources
152      public_configs = [ ":$idl_headers_config" ]
153      deps = [ ":hdi_gen" ]
154      if (is_standard_system) {
155        public_deps = []
156        if (defined(invoker.sequenceable_pub_deps)) {
157          public_deps += invoker.sequenceable_pub_deps
158        }
159
160        public_deps += hdi_build_info.proxy_deps
161
162        external_deps = [
163          "c_utils:utils",
164          "hdf_core:libhdi",
165          "hdf_core:libpub_utils",
166          "hilog:libhilog",
167        ]
168        if (defined(invoker.sequenceable_ext_deps)) {
169          external_deps += invoker.sequenceable_ext_deps
170        }
171        if (invoker.language == "c") {
172          external_deps += [ "hdf_core:libhdf_ipc_adapter" ]
173        } else if (invoker.language == "cpp") {
174          external_deps += [ "ipc:ipc_single" ]
175        }
176      } else {
177        external_deps = [ "hilog:libhilog" ]
178      }
179
180      if (defined(invoker.innerapi_tags)) {
181        innerapi_tags = invoker.innerapi_tags
182      }
183      shlib_type = "hdi_proxy"
184      if (defined(invoker.install_images)) {
185        install_images = invoker.install_images
186      } else {
187        install_images = [ system_base_dir ]
188      }
189
190      subsystem_name = invoker.subsystem_name
191      partname_list = string_split(invoker.part_name, "_")
192      if (partname_list[0] == "drivers") {
193        part_name = invoker.part_name
194      } else {
195        part_name = invoker.part_name + "_interface"
196      }
197
198      if (defined(invoker.stack_protector_ret)) {
199        stack_protector_ret = invoker.stack_protector_ret
200      }
201
202      if (defined(invoker.sanitize)) {
203        sanitize = invoker.sanitize
204      }
205
206      if (defined(invoker.cflags)) {
207        cflags = invoker.cflags
208      }
209
210      if (defined(invoker.cflags_cc)) {
211        cflags_cc = invoker.cflags_cc
212      }
213
214      if (defined(invoker.branch_protector_ret)) {
215        branch_protector_ret = invoker.branch_protector_ret
216      }
217    }
218  }
219
220  if (mode == "ipc") {
221    lib_server = "lib" + target_name + "_stub" + "_" + hdi_build_info.version
222    ohos_shared_library(lib_server) {
223      if (defined(invoker.sources)) {
224        sources = hdi_build_info.stub_sources
225        public_configs = [ ":$idl_headers_config" ]
226
227        deps = [ ":hdi_gen" ]
228        if (is_standard_system) {
229          public_deps = []
230          if (defined(invoker.sequenceable_pub_deps)) {
231            public_deps += invoker.sequenceable_pub_deps
232          }
233
234          public_deps += hdi_build_info.stub_deps
235
236          external_deps = [
237            "c_utils:utils",
238            "hdf_core:libhdi",
239            "hilog:libhilog",
240          ]
241          if (defined(invoker.sequenceable_ext_deps)) {
242            external_deps += invoker.sequenceable_ext_deps
243          }
244          if (invoker.language == "c") {
245            external_deps += [
246              "hdf_core:libhdf_ipc_adapter",
247              "hdf_core:libhdf_utils",
248            ]
249          } else if (invoker.language == "cpp") {
250            external_deps += [ "ipc:ipc_single" ]
251          }
252        } else {
253          external_deps = [ "hilog:libhilog" ]
254        }
255
256        shlib_type = "hdi_stub"
257        install_images = [ chipset_base_dir ]
258        subsystem_name = invoker.subsystem_name
259        part_name = invoker.part_name
260
261        if (defined(invoker.stack_protector_ret)) {
262          stack_protector_ret = invoker.stack_protector_ret
263        }
264
265        if (defined(invoker.sanitize)) {
266          sanitize = invoker.sanitize
267        }
268
269        if (defined(invoker.cflags)) {
270          cflags = invoker.cflags
271        }
272
273        if (defined(invoker.cflags_cc)) {
274          cflags_cc = invoker.cflags_cc
275        }
276
277        if (defined(invoker.branch_protector_ret)) {
278          branch_protector_ret = invoker.branch_protector_ret
279        }
280      }
281    }
282  }
283
284  # generate code and shared library
285  group("$target_name" + "_idl_target") {
286    deps = [ ":$lib_client" ]
287    if (mode == "ipc") {
288      deps += [ ":$lib_server" ]
289    }
290  }
291
292  # only generate code and provide header file path
293  # usage example: external_deps = [ "drivers_interface_xxx:xxx_idl_headers" ]
294  # this target has been replaced by 'idl_headers_target', please use 'idl_headers_target'
295  group("$target_name" + "_idl_headers") {
296    public_configs = [ ":$idl_headers_config" ]
297    deps = [ ":hdi_gen" ]
298  }
299
300  # only generate code and provide header file path
301  # usage example: external_deps = [ "drivers_interface_xxx:xxx_idl_headers_1.0" ]
302  idl_headers_target = target_name + "_idl_headers_" + hdi_build_info.version
303  group(idl_headers_target) {
304    public_configs = [ ":$idl_headers_config" ]
305    deps = [ ":hdi_gen" ]
306    public_deps = hdi_build_info.header_deps
307  }
308}
309