• 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      "//build/toolchain/ohos:ohos_clang_x86_64",
148    ]
149  } else {
150    # Don't enable cross compile if build_ohos_ndk is false.
151    # Cross compiling in this case may cause build failure in some scenario,
152    # such as build for ASAN.
153    ndk_toolchains = [ "//build/toolchain/ohos:ohos_clang_${target_cpu}" ]
154  }
155
156  _accumulated_deps = []
157
158  foreach(_toolchain, ndk_toolchains) {
159    if (_toolchain == "//build/toolchain/ohos:ohos_clang_arm") {
160      _ndk_shlib_directory = "arm-linux-ohos"
161    } else if (_toolchain == "//build/toolchain/ohos:ohos_clang_arm64") {
162      _ndk_shlib_directory = "aarch64-linux-ohos"
163    } else if (_toolchain == "//build/toolchain/ohos:ohos_clang_x86_64") {
164      _ndk_shlib_directory = "x86_64-linux-ohos"
165    }
166
167    assert(defined(_ndk_shlib_directory))
168    _output_dir = "$ndk_libraries_out_dir/$_ndk_shlib_directory"
169    _output_ndk_shlib = "${_output_dir}/lib${_output_name}.${_output_extension}"
170
171    _toolchain_name = get_label_info(_toolchain, "name")
172
173    _ndk_shlib_target = "${target_name}_${_toolchain_name}__ndk_shlib"
174
175    shared_library(_ndk_shlib_target) {
176      forward_variables_from(invoker,
177                             [
178                               "cflags",
179                               "ldflags",
180                               "configs",
181                               "libs",
182                               "include_dirs",
183                             ])
184      deps = [ ":$_ndk_stub_target" ]
185      sources = [ _generated_ndk_stub_file ]
186      output_dir = target_out_dir + "/$_toolchain_name"
187      output_name = _output_name
188      output_extension = _output_extension
189    }
190
191    _ndk_shlib_copy_target = "${target_name}_${_toolchain_name}__copy"
192    copy(_ndk_shlib_copy_target) {
193      deps = [ ":$_ndk_shlib_target($_toolchain)" ]
194      sources = [ get_label_info(":$_ndk_shlib_target($_toolchain)",
195                                 "target_out_dir") +
196                  "/$_toolchain_name/lib$_output_name.$_output_extension" ]
197      outputs = [ _output_ndk_shlib ]
198    }
199    _accumulated_deps += [ ":$_ndk_shlib_copy_target" ]
200    _accumulated_deps += [ ":$_ndk_shlib_target" ]
201  }
202
203  _ndk_version_script_target = target_name
204  if (current_toolchain == default_toolchain) {
205    # Notice file for different toolchains are the same, it's enough to
206    # collect notice file for default toolchain.
207    _notice_target = "${target_name}__ndk_libraries_notice"
208    collect_notice(_notice_target) {
209      forward_variables_from(invoker,
210                             [
211                               "testonly",
212                               "license_as_sources",
213                               "license_file",
214                             ])
215      module_source_dir =
216          get_label_info(":${_ndk_version_script_target}", "dir")
217      outputs = [ "$ndk_notice_dir/sysroot/usr/lib/lib$_output_name.$_output_extension.txt" ]
218    }
219    _accumulated_deps += [ ":$_notice_target" ]
220  }
221  if (defined(invoker.license_file)) {
222    not_needed(invoker, [ "license_file" ])
223  }
224  if (defined(invoker.license_as_sources)) {
225    not_needed(invoker, [ "license_as_sources" ])
226  }
227
228  _generated_version_script =
229      target_gen_dir + "/$target_name" + version_script_suffix
230  action_with_pydeps(_ndk_version_script_target) {
231    deps = _accumulated_deps
232    script = "//build/ohos/ndk/generate_version_script.py"
233    depfile = "${target_gen_dir}/${target_name}.d"
234    args = [
235      "--output",
236      rebase_path(_generated_version_script, root_build_dir),
237      "--ndk-description-file",
238      rebase_path(_ndk_description_file, root_build_dir),
239      "--shlib-name",
240      _output_name,
241      "--depfile",
242      rebase_path(depfile, root_build_dir),
243    ]
244    outputs = [ _generated_version_script ]
245  }
246}
247
248# Specify an ndk copy target
249# NOTE: It's an internal template, not designed for everyone use.
250#
251# Input variables:
252#   dest_dir: Root directory where sources are copied to.
253#   sources: List of files and directories to copy to ${dest_dir}.
254#
255template("ohos_ndk_copy") {
256  assert(defined(invoker.sources) && defined(invoker.dest_dir),
257         "sources and dest_dir are necessary ")
258
259  _deps = []
260  if (defined(invoker.deps)) {
261    _deps += invoker.deps
262  }
263  _dest = invoker.dest_dir
264
265  set_sources_assignment_filter([ "*os-irrelevant*" ])
266  sources = [ _dest ]
267  if (sources == []) {
268    _notice_rel_dir = ndk_os_irrelevant_out_dir
269  } else {
270    _notice_rel_dir = ndk_os_specific_out_dir
271  }
272  set_sources_assignment_filter([])
273  sources = []
274
275  _main_target_name = target_name
276  _notice_target = "${target_name}__notice"
277  collect_notice(_notice_target) {
278    forward_variables_from(invoker,
279                           [
280                             "testonly",
281                             "license_as_sources",
282                             "license_file",
283                           ])
284    module_source_dir = get_label_info(":${_main_target_name}", "dir")
285    outputs = []
286
287    foreach(s, invoker.sources) {
288      outputs += [ ndk_notice_dir + "/" + rebase_path(_dest, _notice_rel_dir) +
289                   "/" + get_path_info(s, "file") + ".txt" ]
290    }
291  }
292  _deps += [ ":$_notice_target" ]
293
294  copy_ex(target_name) {
295    forward_variables_from(invoker,
296                           [
297                             "testonly",
298                             "visibility",
299                           ])
300    forward_variables_from(invoker, [ "outputs" ])
301    deps = _deps
302    sources = invoker.sources
303
304    if (!defined(outputs)) {
305      outputs = []
306      foreach(src, invoker.sources) {
307        _all_files = []
308        _all_files =
309            exec_script("//build/scripts/find.py",
310                        [
311                          rebase_path(src, root_build_dir),
312                          "--base-dir=" + rebase_path(src, root_build_dir),
313                          "--return-relpath",
314                          "--follow-symlinks",
315                        ],
316                        "list lines")
317
318        if (_all_files == [ "." ]) {
319          outputs += [ _dest + "/" + get_path_info(src, "file") ]
320        } else {
321          foreach(f, _all_files) {
322            outputs += [ _dest + "/" + get_path_info(src, "name") + "/$f" ]
323          }
324        }
325      }
326    }
327
328    dest = _dest
329    depfile = "$target_gen_dir/$target_name.d"
330    args = [
331      "--clear",
332      "--follow-outside-symlinks",
333      "--depfile",
334      rebase_path(depfile, root_build_dir),
335      "--stamp",
336      rebase_path("$target_gen_dir/$target_name.stamp", root_build_dir),
337    ]
338    if (defined(invoker.args)) {
339      args += invoker.args
340    }
341  }
342}
343
344# Specify ndk header files
345#
346# Input variables:
347#   dest_dir: Root directory where sources are copied to.
348#   sources: List of files and directories to copy to ${dest_dir}.
349#
350template("ohos_ndk_headers") {
351  assert(defined(invoker.sources), "sources are necessary ")
352
353  if (defined(invoker.dest_dir)) {
354    _dest_dir = invoker.dest_dir
355  } else {
356    _dest_dir = "$ndk_headers_out_dir"
357  }
358
359  _ndk_header_signature_target = "${target_name}__ndk_signature_check"
360  _target_name = target_name
361  action_with_pydeps(_ndk_header_signature_target) {
362    if (defined(invoker.deps)) {
363      deps = invoker.deps
364    }
365
366    script = "//build/ohos/ndk/check_ndk_header_signature.py"
367    depfile = "${target_gen_dir}/${target_name}.d"
368
369    inputs = []
370    foreach(src, invoker.sources) {
371      _all_files = []
372      _all_files = exec_script("//build/scripts/find.py",
373                               [ rebase_path(src) ],
374                               "list lines")
375
376      inputs += _all_files
377    }
378
379    _output = "$target_gen_dir/$target_name.stamp"
380
381    args = [
382      "--depfile",
383      rebase_path(depfile, root_build_dir),
384      "--generated-signature",
385      rebase_path("$ndk_signature_out_dir/$_target_name/signature.txt",
386                  root_build_dir),
387      "--saved-signature",
388      rebase_path("$ndk_signature_save_dir/$_target_name/signature.txt",
389                  root_build_dir),
390      "--output",
391      rebase_path(_output, root_build_dir),
392    ]
393    foreach(f, inputs) {
394      args += [
395        "--headers",
396        rebase_path(f, root_build_dir),
397        "--root-build-dir",
398        rebase_path("//", root_build_dir),
399      ]
400    }
401
402    if (check_ndk_signature) {
403      args += [ "--check-signature" ]
404    }
405
406    outputs = [ _output ]
407  }
408
409  ohos_ndk_copy(target_name) {
410    forward_variables_from(invoker,
411                           "*",
412                           [
413                             "deps",
414                             "args",
415                             "dest_dir",
416                           ])
417    deps = [ ":$_ndk_header_signature_target" ]
418
419    if (defined(invoker.deps)) {
420      deps += invoker.deps
421    }
422    dest_dir = _dest_dir
423
424    args = [ "--ignore-stale" ]
425    if (defined(invoker.args)) {
426      args += invoker.args
427    }
428  }
429}
430
431# Specify ndk toolchains
432#
433# Input variables:
434#   dest_dir: Root directory where sources are copied to.
435#   sources: List of files and directories to copy to ${dest_dir}.
436#
437template("ohos_ndk_toolchains") {
438  ohos_ndk_copy(target_name) {
439    forward_variables_from(invoker, "*")
440  }
441}
442
443# Specify ndk prebuilt library
444#
445# Input variables:
446#   dest_dir: Root directory where sources are copied to.
447#   sources: List of files and directories to copy to ${dest_dir}.
448#
449template("ohos_ndk_prebuilt_library") {
450  if (defined(invoker.dest_dir)) {
451    _dest_dir = invoker.dest_dir
452  } else {
453    _dest_dir = "$ndk_libraries_out_dir"
454  }
455
456  ohos_ndk_copy(target_name) {
457    forward_variables_from(invoker,
458                           "*",
459                           [
460                             "args",
461                             "dest_dir",
462                           ])
463    dest_dir = _dest_dir
464
465    args = [ "--ignore-stale" ]
466    if (defined(invoker.args)) {
467      args += invoker.args
468    }
469  }
470}
471