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