• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/ohos/copy_ex.gni")
15import("//build/config/python.gni")
16import("//build/ohos/build_var.gni")
17import("//build/ohos/notice/notice.gni")
18import("//build/ohos_var.gni")
19
20declare_args() {
21  sdk_native = "sdk-native"
22  version_script_suffix = ".map.txt"
23  ndk_signature_save_dir = "//interface/sdk-native"
24  ndk_zip_prefix = "native"
25  enable_ndk_doxygen = true
26}
27
28if (use_current_sdk) {
29  # native_dir is native current-sdk release dir, all things redefine base the value.
30  native_dir = "base-current-sdk/linux/${api_version}/native"
31
32  ndk_os_irrelevant_out_dir = "$root_out_dir/${native_dir}"
33  ndk_os_specific_out_dir = "$root_out_dir/${native_dir}"
34  ndk_signature_out_dir = "$root_out_dir/${native_dir}/.others/signature"
35} else {
36  ndk_os_irrelevant_out_dir = "$root_out_dir/${sdk_native}/os-irrelevant"
37  ndk_os_specific_out_dir = "$root_out_dir/${sdk_native}/os-specific"
38  ndk_signature_out_dir = "$root_out_dir/${sdk_native}/signature"
39}
40
41ndk_headers_out_dir = "$ndk_os_irrelevant_out_dir/sysroot/usr/include"
42ndk_libraries_out_dir = "$ndk_os_irrelevant_out_dir/sysroot/usr/lib"
43ndk_docs_out_dir = "$ndk_os_irrelevant_out_dir/docs"
44
45windows_system = "windows"
46linux_system = "linux"
47darwin_system = "darwin"
48ohos_system = "ohos"
49
50if (use_current_sdk) {
51  ndk_windows_specific_out_dir =
52      "${ndk_os_specific_out_dir}/.others/${windows_system}"
53  ndk_darwin_specific_out_dir =
54      "${ndk_os_specific_out_dir}/.others/${darwin_system}"
55  ndk_linux_specific_out_dir = "${ndk_os_specific_out_dir}"
56  ndk_ohos_specific_out_dir =
57      "${ndk_os_specific_out_dir}/.others/${ohos_system}"
58} else {
59  ndk_windows_specific_out_dir = "${ndk_os_specific_out_dir}/${windows_system}"
60  ndk_darwin_specific_out_dir = "${ndk_os_specific_out_dir}/${darwin_system}"
61  ndk_linux_specific_out_dir = "${ndk_os_specific_out_dir}/${linux_system}"
62  ndk_ohos_specific_out_dir = "${ndk_os_specific_out_dir}/${ohos_system}"
63}
64
65ndk_windows_toolchains_out_dir = "${ndk_windows_specific_out_dir}/llvm"
66ndk_windows_tools_out_dir = "${ndk_windows_specific_out_dir}/build-tools"
67
68ndk_darwin_toolchains_out_dir = "${ndk_darwin_specific_out_dir}/llvm"
69ndk_darwin_tools_out_dir = "${ndk_darwin_specific_out_dir}/build-tools"
70
71ndk_linux_toolchains_out_dir = "${ndk_linux_specific_out_dir}/llvm"
72ndk_linux_tools_out_dir = "${ndk_linux_specific_out_dir}/build-tools"
73
74ndk_ohos_toolchains_out_dir = "${ndk_ohos_specific_out_dir}/llvm"
75ndk_ohos_tools_out_dir = "${ndk_ohos_specific_out_dir}/build-tools"
76
77# Generate NDK library from NDK description file.
78#
79# Variables:
80#  ndk_description_file:
81#  min_compact_version: string specifies the minimal compactible version of NDK.
82#    set to major_version in default.
83#
84template("ohos_ndk_library") {
85  forward_variables_from(invoker, [ "testonly" ])
86  assert(defined(invoker.ndk_description_file),
87         "ndk description file is necessary ")
88
89  _ndk_description_file = invoker.ndk_description_file
90
91  _system_capability = ""
92  if (defined(invoker.system_capability)) {
93    _system_capability = invoker.system_capability
94  }
95
96  _system_capability_headers = ""
97  if (defined(invoker.system_capability_headers)) {
98    _system_capability_headers = invoker.system_capability_headers
99  }
100
101  _deps = []
102  if (defined(invoker.deps)) {
103    _deps += invoker.deps
104  }
105
106  _ndk_config_output = "$target_gen_dir/$target_name.build_config"
107  _sdk_version = exec_script("//build/ohos/version.py",
108                             [
109                               "--version",
110                               sdk_version,
111                             ],
112                             "list lines")
113  _min_compact_version = _sdk_version[0]
114  if (defined(invoker.min_compact_version)) {
115    _min_compact_version = invoker.min_compact_version
116  }
117  assert(_min_compact_version != "0")  # mark as used
118
119  _output_name = target_name
120  if (defined(invoker.output_name)) {
121    _output_name = invoker.output_name
122  }
123
124  _output_extension = "z.so"
125  if (defined(invoker.output_extension)) {
126    _output_extension = invoker.output_extension
127  }
128
129  _ndk_stub_target = "${target_name}__ndk_stub"
130  _generated_ndk_stub_file = target_gen_dir + "/${target_name}.ndk/" +
131                             get_path_info(_ndk_description_file, "name") + ".c"
132  _current_label = get_label_info(":${target_name}", "label_with_toolchain")
133  action_with_pydeps(_ndk_stub_target) {
134    deps = _deps
135    script = "//build/ohos/ndk/generate_ndk_stub_file.py"
136    depfile = "${target_gen_dir}/${target_name}.d"
137    args = [
138      "--output",
139      rebase_path(_generated_ndk_stub_file, root_build_dir),
140      "--ndk-description-file",
141      rebase_path(_ndk_description_file, root_build_dir),
142      "--depfile",
143      rebase_path(depfile, root_build_dir),
144    ]
145    inputs = [ _ndk_description_file ]
146    outputs = [ _generated_ndk_stub_file ]
147
148    _ndk_config_info = {
149      label = _current_label
150      lib_name = _output_name
151      system_capability = _system_capability
152      system_capability_headers = _system_capability_headers
153    }
154    metadata = {
155      ndk_config = [ _ndk_config_info ]
156    }
157  }
158
159  _ndk_config_target = "${target_name}__ndk_config"
160  generated_file(_ndk_config_target) {
161    deps = [ ":$_ndk_stub_target" ]
162    output_conversion = "json"
163    outputs = [ _ndk_config_output ]
164
165    data_keys = [ "ndk_config" ]
166  }
167
168  ndk_toolchains = []
169  if (build_ohos_ndk || use_current_sdk) {
170    if (host_os == "linux" && host_cpu == "arm64") {
171      ndk_toolchains = [ "//build/toolchain/ohos:ohos_clang_arm64" ]
172    } else {
173      ndk_toolchains = [
174        "//build/toolchain/ohos:ohos_clang_arm",
175        "//build/toolchain/ohos:ohos_clang_arm64",
176        "//build/toolchain/ohos:ohos_clang_x86_64",
177      ]
178    }
179  } else if (!is_arkui_x) {
180    # Don't enable cross compile if build_ohos_ndk is false.
181    # Cross compiling in this case may cause build failure in some scenario,
182    # such as build for ASAN.
183    ndk_toolchains = [ "//build/toolchain/ohos:ohos_clang_${target_cpu}" ]
184  }
185
186  if (ndk_toolchains == []) {
187    not_needed([ "_output_extension" ])
188  }
189
190  _accumulated_deps = []
191
192  foreach(_toolchain, ndk_toolchains) {
193    if (_toolchain == "//build/toolchain/ohos:ohos_clang_arm") {
194      _ndk_shlib_directory = "arm-linux-ohos"
195    } else if (_toolchain == "//build/toolchain/ohos:ohos_clang_arm64") {
196      _ndk_shlib_directory = "aarch64-linux-ohos"
197    } else if (_toolchain == "//build/toolchain/ohos:ohos_clang_x86_64") {
198      _ndk_shlib_directory = "x86_64-linux-ohos"
199    }
200
201    assert(defined(_ndk_shlib_directory))
202    _output_dir = "$ndk_libraries_out_dir/$_ndk_shlib_directory"
203    if (defined(invoker.current_ndk_outpath) &&
204        invoker.current_ndk_outpath != "" && use_current_sdk) {
205      _output_dir = "${invoker.current_ndk_outpath}/${_ndk_shlib_directory}"
206    }
207    _output_ndk_shlib = "${_output_dir}/lib${_output_name}.${_output_extension}"
208
209    _toolchain_name = get_label_info(_toolchain, "name")
210
211    _ndk_shlib_target = "${target_name}_${_toolchain_name}__ndk_shlib"
212
213    shared_library(_ndk_shlib_target) {
214      forward_variables_from(invoker,
215                             [
216                               "cflags",
217                               "ldflags",
218                               "configs",
219                               "libs",
220                               "include_dirs",
221                             ])
222      deps = [ ":$_ndk_stub_target" ]
223      sources = [ _generated_ndk_stub_file ]
224      output_dir = target_out_dir + "/$_toolchain_name"
225      output_name = _output_name
226      output_extension = _output_extension
227    }
228
229    _ndk_shlib_copy_target = "${target_name}_${_toolchain_name}__copy"
230    copy(_ndk_shlib_copy_target) {
231      deps = [ ":$_ndk_shlib_target($_toolchain)" ]
232      sources = [ get_label_info(":$_ndk_shlib_target($_toolchain)",
233                                 "target_out_dir") +
234                  "/$_toolchain_name/lib$_output_name.$_output_extension" ]
235      outputs = [ _output_ndk_shlib ]
236    }
237    _accumulated_deps += [ ":$_ndk_shlib_copy_target" ]
238    _accumulated_deps += [ ":$_ndk_shlib_target" ]
239  }
240
241  _ndk_version_script_target = target_name
242  if (current_toolchain == default_toolchain) {
243    # Notice file for different toolchains are the same, it's enough to
244    # collect notice file for default toolchain.
245    _notice_target = "${target_name}__ndk_libraries_notice"
246    collect_notice(_notice_target) {
247      forward_variables_from(invoker,
248                             [
249                               "testonly",
250                               "license_as_sources",
251                               "license_file",
252                             ])
253      module_source_dir =
254          get_label_info(":${_ndk_version_script_target}", "dir")
255      outputs = [ "$ndk_notice_dir/sysroot/usr/lib/lib$_output_name.$_output_extension.txt" ]
256    }
257    _accumulated_deps += [ ":$_notice_target" ]
258  }
259  if (defined(invoker.license_file)) {
260    not_needed(invoker, [ "license_file" ])
261  }
262  if (defined(invoker.license_as_sources)) {
263    not_needed(invoker, [ "license_as_sources" ])
264  }
265
266  _generated_version_script =
267      target_gen_dir + "/$target_name" + version_script_suffix
268  action_with_pydeps(_ndk_version_script_target) {
269    deps = _accumulated_deps
270    script = "//build/ohos/ndk/generate_version_script.py"
271    depfile = "${target_gen_dir}/${target_name}.d"
272    args = [
273      "--output",
274      rebase_path(_generated_version_script, root_build_dir),
275      "--ndk-description-file",
276      rebase_path(_ndk_description_file, root_build_dir),
277      "--shlib-name",
278      _output_name,
279      "--depfile",
280      rebase_path(depfile, root_build_dir),
281    ]
282    outputs = [ _generated_version_script ]
283  }
284}
285
286# Specify an ndk copy target
287# NOTE: It's an internal template, not designed for everyone use.
288#
289# Input variables:
290#   dest_dir: Root directory where sources are copied to.
291#   sources: List of files and directories to copy to ${dest_dir}.
292#
293template("ohos_ndk_copy") {
294  assert(defined(invoker.sources) && defined(invoker.dest_dir),
295         "sources and dest_dir are necessary ")
296
297  _deps = []
298  if (defined(invoker.deps)) {
299    _deps += invoker.deps
300  }
301  _dest = invoker.dest_dir
302
303  if (defined(invoker.current_ndk_outpath) &&
304      invoker.current_ndk_outpath != "" && use_current_sdk) {
305    _dest = invoker.current_ndk_outpath
306  }
307
308  sources = filter_exclude([ _dest ], [ "*os-irrelevant*" ])
309  if (sources == []) {
310    _notice_rel_dir = ndk_os_irrelevant_out_dir
311  } else {
312    _notice_rel_dir = ndk_os_specific_out_dir
313  }
314  sources = []
315
316  _main_target_name = target_name
317  _notice_target = "${target_name}__notice"
318  collect_notice(_notice_target) {
319    forward_variables_from(invoker,
320                           [
321                             "testonly",
322                             "license_as_sources",
323                             "license_file",
324                           ])
325    module_source_dir = get_label_info(":${_main_target_name}", "dir")
326    outputs = []
327
328    foreach(s, invoker.sources) {
329      outputs += [ ndk_notice_dir + "/" + rebase_path(_dest, _notice_rel_dir) +
330                   "/" + get_path_info(s, "file") + ".txt" ]
331    }
332  }
333  _deps += [ ":$_notice_target" ]
334  _clear_dest = true
335  if (defined(invoker.clear_dest) && !invoker.clear_dest) {
336    _clear_dest = false
337  }
338
339  copy_ex(target_name) {
340    forward_variables_from(invoker,
341                           [
342                             "testonly",
343                             "visibility",
344                           ])
345    forward_variables_from(invoker, [ "outputs" ])
346    deps = _deps
347    sources = invoker.sources
348
349    if (!defined(outputs)) {
350      outputs = []
351      foreach(src, invoker.sources) {
352        _all_files = []
353        _all_files =
354            exec_script("//build/scripts/find.py",
355                        [
356                          rebase_path(src, root_build_dir),
357                          "--base-dir=" + rebase_path(src, root_build_dir),
358                          "--return-relpath",
359                          "--follow-symlinks",
360                        ],
361                        "list lines")
362
363        if (_all_files == [ "." ]) {
364          outputs += [ _dest + "/" + get_path_info(src, "file") ]
365        } else {
366          foreach(f, _all_files) {
367            outputs += [ _dest + "/" + get_path_info(src, "name") + "/$f" ]
368          }
369        }
370      }
371    }
372
373    dest = _dest
374    depfile = "$target_gen_dir/$target_name.d"
375    args = [
376      "--clear",
377      "--follow-outside-symlinks",
378      "--depfile",
379      rebase_path(depfile, root_build_dir),
380      "--stamp",
381      rebase_path("$target_gen_dir/$target_name.stamp", root_build_dir),
382    ]
383    if (!_clear_dest) {
384      args -= [ "--clear" ]
385    }
386    if (defined(invoker.args)) {
387      args += invoker.args
388    }
389  }
390}
391
392# Specify ndk header files
393#
394# Input variables:
395#   dest_dir: Root directory where sources are copied to.
396#   sources: List of files and directories to copy to ${dest_dir}.
397#
398template("ohos_ndk_headers") {
399  assert(defined(invoker.sources), "sources are necessary ")
400
401  if (defined(invoker.dest_dir)) {
402    _dest_dir = invoker.dest_dir
403  } else {
404    _dest_dir = "$ndk_headers_out_dir"
405  }
406
407  if (defined(invoker.current_ndk_outpath) &&
408      invoker.current_ndk_outpath != "" && use_current_sdk) {
409    _dest_dir = invoker.current_ndk_outpath
410  }
411
412  _ndk_header_signature_target = "${target_name}__ndk_signature_check"
413  _target_name = target_name
414  action_with_pydeps(_ndk_header_signature_target) {
415    if (defined(invoker.deps)) {
416      deps = invoker.deps
417    }
418
419    script = "//build/ohos/ndk/check_ndk_header_signature.py"
420    depfile = "${target_gen_dir}/${target_name}.d"
421
422    inputs = []
423    foreach(src, invoker.sources) {
424      _all_files = []
425      _all_files = exec_script("//build/scripts/find.py",
426                               [ rebase_path(src) ],
427                               "list lines")
428
429      inputs += _all_files
430    }
431
432    _output = "$target_gen_dir/$target_name.stamp"
433
434    args = [
435      "--depfile",
436      rebase_path(depfile, root_build_dir),
437      "--generated-signature",
438      rebase_path("$ndk_signature_out_dir/$_target_name/signature.txt",
439                  root_build_dir),
440      "--saved-signature",
441      rebase_path("$ndk_signature_save_dir/$_target_name/signature.txt",
442                  root_build_dir),
443      "--output",
444      rebase_path(_output, root_build_dir),
445    ]
446    foreach(f, inputs) {
447      args += [
448        "--headers",
449        rebase_path(f, root_build_dir),
450        "--root-build-dir",
451        rebase_path("//", root_build_dir),
452      ]
453    }
454
455    if (check_ndk_signature) {
456      args += [ "--check-signature" ]
457    }
458
459    outputs = [ _output ]
460  }
461
462  _ndk_header_check_target = "${target_name}__ndk_header_check"
463  action_with_pydeps(_ndk_header_check_target) {
464    script = "//build/ohos/ndk/check_ndk_header.py"
465    inputs = []
466    foreach(src, invoker.sources) {
467      _all_files = []
468      _all_files = exec_script("//build/scripts/find.py",
469                               [ rebase_path(src) ],
470                               "list lines")
471
472      inputs += _all_files
473    }
474
475    _output = "$target_gen_dir/$target_name.gch"
476    args = [
477      "--output",
478      rebase_path(_output, root_build_dir),
479    ]
480    foreach(f, inputs) {
481      args += [
482        "--headers",
483        rebase_path(f, root_build_dir),
484      ]
485    }
486
487    outputs = [ _output ]
488  }
489  ohos_ndk_copy(target_name) {
490    forward_variables_from(invoker,
491                           "*",
492                           [
493                             "deps",
494                             "args",
495                             "dest_dir",
496                           ])
497    deps = [ ":$_ndk_header_signature_target" ]
498    if (defined(ndk_check_header) && target_name != "libuv_uv_header") {
499      deps += [ ":$_ndk_header_check_target" ]
500    }
501
502    if (defined(invoker.deps)) {
503      deps += invoker.deps
504    }
505    dest_dir = _dest_dir
506
507    args = [ "--ignore-stale" ]
508    if (defined(invoker.args)) {
509      args += invoker.args
510    }
511  }
512}
513
514# Specify ndk toolchains
515#
516# Input variables:
517#   dest_dir: Root directory where sources are copied to.
518#   sources: List of files and directories to copy to ${dest_dir}.
519#
520template("ohos_ndk_toolchains") {
521  ohos_ndk_copy(target_name) {
522    forward_variables_from(invoker, "*")
523  }
524}
525
526# Specify ndk prebuilt library
527#
528# Input variables:
529#   dest_dir: Root directory where sources are copied to.
530#   sources: List of files and directories to copy to ${dest_dir}.
531#
532template("ohos_ndk_prebuilt_library") {
533  if (defined(invoker.dest_dir)) {
534    _dest_dir = invoker.dest_dir
535  } else {
536    _dest_dir = "$ndk_libraries_out_dir"
537  }
538
539  if (defined(invoker.current_ndk_outpath) &&
540      invoker.current_ndk_outpath != "" && use_current_sdk) {
541    _dest_dir = invoker.current_ndk_outpath
542  }
543
544  ohos_ndk_copy(target_name) {
545    forward_variables_from(invoker,
546                           "*",
547                           [
548                             "args",
549                             "dest_dir",
550                           ])
551    dest_dir = _dest_dir
552
553    args = [ "--ignore-stale" ]
554    if (defined(invoker.args)) {
555      args += invoker.args
556    }
557  }
558}
559
560template("current_ndk") {
561  forward_variables_from(invoker,
562                         [
563                           "ndk_class",
564                           "all_ndk_targets",
565                           "ndk_out_dir",
566                         ])
567
568  package_info_name = "oh-uni-package"
569  if (ndk_class != "base") {
570    package_info_name = "uni-package"
571  }
572  package_info_file = "$ndk_out_dir/$package_info_name.json"
573
574  package_info = {
575    path = "native"
576    displayName = "Native"
577    version = current_ndk_version
578    if (release_type != "") {
579      releaseType = release_type
580    }
581    if (meta_version != "") {
582      meta = {
583        metaVersion = meta_version
584      }
585    }
586    if (defined(ext_ndk_config_file) && ext_ndk_config_file != "") {
587      platformVersion = platform_version
588    }
589    apiVersion = api_version
590  }
591  write_file(package_info_file, package_info, "json")
592
593  action_with_pydeps(target_name) {
594    deps = all_ndk_targets
595    script = "//build/ohos/ndk/collect_ndk_syscap.py"
596    depfile = "$target_gen_dir/$target_name.d"
597    _ndk_syscap_desc_file = "${ndk_out_dir}/ndk_system_capability.json"
598    _native_syscap_config_file = "${ndk_out_dir}/nativeapi_syscap_config.json"
599    outputs = [ _ndk_syscap_desc_file ]
600    args = [
601      "--depfile",
602      rebase_path(depfile, root_build_dir),
603      "--system-capability-file",
604      rebase_path(_ndk_syscap_desc_file, root_build_dir),
605      "--system-capability-header-config",
606      rebase_path(_native_syscap_config_file, root_build_dir),
607      "--targets-build-config",
608    ]
609    foreach(_ndk_target, all_ndk_targets) {
610      _target_bc_file = get_label_info(_ndk_target, "target_gen_dir") + "/" +
611                        get_label_info(_ndk_target, "name") + ".build_config"
612      args += [ rebase_path(_target_bc_file, root_build_dir) ]
613    }
614  }
615}
616