• 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}
26
27ndk_os_irrelevant_out_dir = "$root_out_dir/${sdk_native}/os-irrelevant"
28ndk_os_specific_out_dir = "$root_out_dir/${sdk_native}/os-specific"
29ndk_signature_out_dir = "$root_out_dir/${sdk_native}/signature"
30
31ndk_headers_out_dir = "$ndk_os_irrelevant_out_dir/sysroot/usr/include"
32ndk_libraries_out_dir = "$ndk_os_irrelevant_out_dir/sysroot/usr/lib"
33ndk_docs_out_dir = "$ndk_os_irrelevant_out_dir/docs"
34
35windows_system = "windows"
36linux_system = "linux"
37darwin_system = "darwin"
38
39ndk_windows_specific_out_dir = "${ndk_os_specific_out_dir}/${windows_system}"
40ndk_darwin_specific_out_dir = "${ndk_os_specific_out_dir}/${darwin_system}"
41ndk_linux_specific_out_dir = "${ndk_os_specific_out_dir}/${linux_system}"
42
43ndk_windows_toolchains_out_dir = "${ndk_windows_specific_out_dir}/llvm"
44ndk_windows_tools_out_dir = "${ndk_windows_specific_out_dir}/build-tools"
45
46ndk_darwin_toolchains_out_dir = "${ndk_darwin_specific_out_dir}/llvm"
47ndk_darwin_tools_out_dir = "${ndk_darwin_specific_out_dir}/build-tools"
48
49ndk_linux_toolchains_out_dir = "${ndk_linux_specific_out_dir}/llvm"
50ndk_linux_tools_out_dir = "${ndk_linux_specific_out_dir}/build-tools"
51
52# Generate NDK library from NDK description file.
53#
54# Variables:
55#  ndk_description_file:
56#  min_compact_version: string specifies the minimal compactible version of NDK.
57#    set to major_version in default.
58#
59template("ohos_ndk_library") {
60  forward_variables_from(invoker, [ "testonly" ])
61  assert(defined(invoker.ndk_description_file),
62         "ndk description file is necessary ")
63
64  _ndk_description_file = invoker.ndk_description_file
65
66  _system_capability = ""
67  if (defined(invoker.system_capability)) {
68    _system_capability = invoker.system_capability
69  }
70
71  _system_capability_headers = ""
72  if (defined(invoker.system_capability_headers)) {
73    _system_capability_headers = invoker.system_capability_headers
74  }
75
76  _deps = []
77  if (defined(invoker.deps)) {
78    _deps += invoker.deps
79  }
80
81  _ndk_config_output = "$target_gen_dir/$target_name.build_config"
82  _sdk_version = exec_script("//build/ohos/version.py",
83                             [
84                               "--version",
85                               sdk_version,
86                             ],
87                             "list lines")
88  _min_compact_version = _sdk_version[0]
89  if (defined(invoker.min_compact_version)) {
90    _min_compact_version = invoker.min_compact_version
91  }
92  assert(_min_compact_version != "0")  # mark as used
93
94  _output_name = target_name
95  if (defined(invoker.output_name)) {
96    _output_name = invoker.output_name
97  }
98
99  _output_extension = "z.so"
100  if (defined(invoker.output_extension)) {
101    _output_extension = invoker.output_extension
102  }
103
104  _ndk_stub_target = "${target_name}__ndk_stub"
105  _generated_ndk_stub_file = target_gen_dir + "/${target_name}.ndk/" +
106                             get_path_info(_ndk_description_file, "name") + ".c"
107  _current_label = get_label_info(":${target_name}", "label_with_toolchain")
108  action_with_pydeps(_ndk_stub_target) {
109    deps = _deps
110    script = "//build/ohos/ndk/generate_ndk_stub_file.py"
111    depfile = "${target_gen_dir}/${target_name}.d"
112    args = [
113      "--output",
114      rebase_path(_generated_ndk_stub_file, root_build_dir),
115      "--ndk-description-file",
116      rebase_path(_ndk_description_file, root_build_dir),
117      "--depfile",
118      rebase_path(depfile, root_build_dir),
119    ]
120    inputs = [ _ndk_description_file ]
121    outputs = [ _generated_ndk_stub_file ]
122
123    _ndk_config_info = {
124      label = _current_label
125      lib_name = _output_name
126      system_capability = _system_capability
127      system_capability_headers = _system_capability_headers
128    }
129    metadata = {
130      ndk_config = [ _ndk_config_info ]
131    }
132  }
133
134  _ndk_config_target = "${target_name}__ndk_config"
135  generated_file(_ndk_config_target) {
136    deps = [ ":$_ndk_stub_target" ]
137    output_conversion = "json"
138    outputs = [ _ndk_config_output ]
139
140    data_keys = [ "ndk_config" ]
141  }
142
143  if (build_ohos_ndk) {
144    ndk_toolchains = [
145      "//build/toolchain/ohos:ohos_clang_arm",
146      "//build/toolchain/ohos:ohos_clang_arm64",
147    ]
148  } else {
149    # Don't enable cross compile if build_ohos_ndk is false.
150    # Cross compiling in this case may cause build failure in some scenario,
151    # such as build for ASAN.
152    ndk_toolchains = [ "//build/toolchain/ohos:ohos_clang_${target_cpu}" ]
153  }
154
155  _accumulated_deps = []
156
157  foreach(_toolchain, ndk_toolchains) {
158    if (_toolchain == "//build/toolchain/ohos:ohos_clang_arm") {
159      _ndk_shlib_directory = "arm-linux-ohos"
160    } else if (_toolchain == "//build/toolchain/ohos:ohos_clang_arm64") {
161      _ndk_shlib_directory = "aarch64-linux-ohos"
162    } else if (_toolchain == "//build/toolchain/ohos:ohos_clang_x86_64") {
163      _ndk_shlib_directory = "x86_64-linux-ohos"
164    }
165
166    assert(defined(_ndk_shlib_directory))
167    _output_dir = "$ndk_libraries_out_dir/$_ndk_shlib_directory"
168    _output_ndk_shlib = "${_output_dir}/lib${_output_name}.${_output_extension}"
169
170    _toolchain_name = get_label_info(_toolchain, "name")
171
172    _ndk_shlib_target = "${target_name}_${_toolchain_name}__ndk_shlib"
173
174    shared_library(_ndk_shlib_target) {
175      forward_variables_from(invoker,
176                             [
177                               "cflags",
178                               "ldflags",
179                               "configs",
180                               "libs",
181                               "include_dirs",
182                             ])
183      deps = [ ":$_ndk_stub_target" ]
184      sources = [ _generated_ndk_stub_file ]
185      output_dir = target_out_dir + "/$_toolchain_name"
186      output_name = _output_name
187      output_extension = _output_extension
188    }
189
190    _ndk_shlib_copy_target = "${target_name}_${_toolchain_name}__copy"
191    copy(_ndk_shlib_copy_target) {
192      deps = [ ":$_ndk_shlib_target($_toolchain)" ]
193      sources = [ get_label_info(":$_ndk_shlib_target($_toolchain)",
194                                 "target_out_dir") +
195                  "/$_toolchain_name/lib$_output_name.$_output_extension" ]
196      outputs = [ _output_ndk_shlib ]
197    }
198    _accumulated_deps += [ ":$_ndk_shlib_copy_target" ]
199    _accumulated_deps += [ ":$_ndk_shlib_target" ]
200  }
201
202  _ndk_version_script_target = target_name
203  if (current_toolchain == default_toolchain) {
204    # Notice file for different toolchains are the same, it's enough to
205    # collect notice file for default toolchain.
206    _notice_target = "${target_name}__ndk_libraries_notice"
207    collect_notice(_notice_target) {
208      forward_variables_from(invoker,
209                             [
210                               "testonly",
211                               "license_as_sources",
212                               "license_file",
213                             ])
214      module_source_dir =
215          get_label_info(":${_ndk_version_script_target}", "dir")
216      outputs = [ "$ndk_notice_dir/sysroot/usr/lib/lib$_output_name.$_output_extension.txt" ]
217    }
218    _accumulated_deps += [ ":$_notice_target" ]
219  }
220  if (defined(invoker.license_file)) {
221    not_needed(invoker, [ "license_file" ])
222  }
223  if (defined(invoker.license_as_sources)) {
224    not_needed(invoker, [ "license_as_sources" ])
225  }
226
227  _generated_version_script =
228      target_gen_dir + "/$target_name" + version_script_suffix
229  action_with_pydeps(_ndk_version_script_target) {
230    deps = _accumulated_deps
231    script = "//build/ohos/ndk/generate_version_script.py"
232    depfile = "${target_gen_dir}/${target_name}.d"
233    args = [
234      "--output",
235      rebase_path(_generated_version_script, root_build_dir),
236      "--ndk-description-file",
237      rebase_path(_ndk_description_file, root_build_dir),
238      "--shlib-name",
239      _output_name,
240      "--depfile",
241      rebase_path(depfile, root_build_dir),
242    ]
243    outputs = [ _generated_version_script ]
244  }
245}
246
247# Specify an ndk copy target
248# NOTE: It's an internal template, not designed for everyone use.
249#
250# Input variables:
251#   dest_dir: Root directory where sources are copied to.
252#   sources: List of files and directories to copy to ${dest_dir}.
253#
254template("ohos_ndk_copy") {
255  assert(defined(invoker.sources) && defined(invoker.dest_dir),
256         "sources and dest_dir are necessary ")
257
258  _deps = []
259  if (defined(invoker.deps)) {
260    _deps += invoker.deps
261  }
262  _dest = invoker.dest_dir
263
264  set_sources_assignment_filter([ "*os-irrelevant*" ])
265  sources = [ _dest ]
266  if (sources == []) {
267    _notice_rel_dir = ndk_os_irrelevant_out_dir
268  } else {
269    _notice_rel_dir = ndk_os_specific_out_dir
270  }
271  set_sources_assignment_filter([])
272  sources = []
273
274  _main_target_name = target_name
275  _notice_target = "${target_name}__notice"
276  collect_notice(_notice_target) {
277    forward_variables_from(invoker,
278                           [
279                             "testonly",
280                             "license_as_sources",
281                             "license_file",
282                           ])
283    module_source_dir = get_label_info(":${_main_target_name}", "dir")
284    outputs = []
285
286    foreach(s, invoker.sources) {
287      outputs += [ ndk_notice_dir + "/" + rebase_path(_dest, _notice_rel_dir) +
288                   "/" + get_path_info(s, "file") + ".txt" ]
289    }
290  }
291  _deps += [ ":$_notice_target" ]
292
293  copy_ex(target_name) {
294    forward_variables_from(invoker,
295                           [
296                             "testonly",
297                             "visibility",
298                           ])
299    forward_variables_from(invoker, [ "outputs" ])
300    deps = _deps
301    sources = invoker.sources
302
303    if (!defined(outputs)) {
304      outputs = []
305      foreach(src, invoker.sources) {
306        _all_files = []
307        _all_files =
308            exec_script("//build/scripts/find.py",
309                        [
310                          rebase_path(src, root_build_dir),
311                          "--base-dir=" + rebase_path(src, root_build_dir),
312                          "--return-relpath",
313                          "--follow-symlinks",
314                        ],
315                        "list lines")
316
317        if (_all_files == [ "." ]) {
318          outputs += [ _dest + "/" + get_path_info(src, "file") ]
319        } else {
320          foreach(f, _all_files) {
321            outputs += [ _dest + "/" + get_path_info(src, "name") + "/$f" ]
322          }
323        }
324      }
325    }
326
327    dest = _dest
328    depfile = "$target_gen_dir/$target_name.d"
329    args = [
330      "--clear",
331      "--follow-outside-symlinks",
332      "--depfile",
333      rebase_path(depfile, root_build_dir),
334      "--stamp",
335      rebase_path("$target_gen_dir/$target_name.stamp", root_build_dir),
336    ]
337    if (defined(invoker.args)) {
338      args += invoker.args
339    }
340  }
341}
342
343# Specify ndk header files
344#
345# Input variables:
346#   dest_dir: Root directory where sources are copied to.
347#   sources: List of files and directories to copy to ${dest_dir}.
348#
349template("ohos_ndk_headers") {
350  assert(defined(invoker.sources), "sources are necessary ")
351
352  if (defined(invoker.dest_dir)) {
353    _dest_dir = invoker.dest_dir
354  } else {
355    _dest_dir = "$ndk_headers_out_dir"
356  }
357
358  _ndk_header_signature_target = "${target_name}__ndk_signature_check"
359  _target_name = target_name
360  action_with_pydeps(_ndk_header_signature_target) {
361    if (defined(invoker.deps)) {
362      deps = invoker.deps
363    }
364
365    script = "//build/ohos/ndk/check_ndk_header_signature.py"
366    depfile = "${target_gen_dir}/${target_name}.d"
367
368    inputs = []
369    foreach(src, invoker.sources) {
370      _all_files = []
371      _all_files = exec_script("//build/scripts/find.py",
372                               [ rebase_path(src) ],
373                               "list lines")
374
375      inputs += _all_files
376    }
377
378    _output = "$target_gen_dir/$target_name.stamp"
379
380    args = [
381      "--depfile",
382      rebase_path(depfile, root_build_dir),
383      "--generated-signature",
384      rebase_path("$ndk_signature_out_dir/$_target_name/signature.txt",
385                  root_build_dir),
386      "--saved-signature",
387      rebase_path("$ndk_signature_save_dir/$_target_name/signature.txt",
388                  root_build_dir),
389      "--output",
390      rebase_path(_output, root_build_dir),
391    ]
392    foreach(f, inputs) {
393      args += [
394        "--headers",
395        rebase_path(f, root_build_dir),
396        "--root-build-dir",
397        rebase_path("//", root_build_dir),
398      ]
399    }
400
401    if (check_ndk_signature) {
402      args += [ "--check-signature" ]
403    }
404
405    outputs = [ _output ]
406  }
407
408  ohos_ndk_copy(target_name) {
409    forward_variables_from(invoker,
410                           "*",
411                           [
412                             "deps",
413                             "args",
414                             "dest_dir",
415                           ])
416    deps = [ ":$_ndk_header_signature_target" ]
417
418    if (defined(invoker.deps)) {
419      deps += invoker.deps
420    }
421    dest_dir = _dest_dir
422
423    args = [ "--ignore-stale" ]
424    if (defined(invoker.args)) {
425      args += invoker.args
426    }
427  }
428}
429
430# Specify ndk toolchains
431#
432# Input variables:
433#   dest_dir: Root directory where sources are copied to.
434#   sources: List of files and directories to copy to ${dest_dir}.
435#
436template("ohos_ndk_toolchains") {
437  ohos_ndk_copy(target_name) {
438    forward_variables_from(invoker, "*")
439  }
440}
441
442# Specify ndk prebuilt library
443#
444# Input variables:
445#   dest_dir: Root directory where sources are copied to.
446#   sources: List of files and directories to copy to ${dest_dir}.
447#
448template("ohos_ndk_prebuilt_library") {
449  if (defined(invoker.dest_dir)) {
450    _dest_dir = invoker.dest_dir
451  } else {
452    _dest_dir = "$ndk_libraries_out_dir"
453  }
454
455  ohos_ndk_copy(target_name) {
456    forward_variables_from(invoker,
457                           "*",
458                           [
459                             "args",
460                             "dest_dir",
461                           ])
462    dest_dir = _dest_dir
463
464    args = [ "--ignore-stale" ]
465    if (defined(invoker.args)) {
466      args += invoker.args
467    }
468  }
469}
470