• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright (c) 2023 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/templates/rust/rust_template.gni")
15template("ohos_cargo_crate") {
16  orig_target_name = target_name
17
18  _crate_name = orig_target_name
19  if (defined(invoker.crate_name)) {
20    _crate_name = invoker.crate_name
21  }
22  assert(_crate_name != "")
23
24  _rustenv = []
25  if (defined(invoker.rustenv)) {
26    _rustenv = invoker.rustenv
27  }
28  if (defined(invoker.cargo_pkg_authors)) {
29    _rustenv += [ string_join("",
30                              [
31                                "CARGO_PKG_AUTHORS=",
32                                invoker.cargo_pkg_authors,
33                              ]) ]
34  }
35  if (defined(invoker.cargo_pkg_version)) {
36    _rustenv += [ string_join("",
37                              [
38                                "CARGO_PKG_VERSION=",
39                                invoker.cargo_pkg_version,
40                              ]) ]
41  }
42  if (defined(invoker.cargo_pkg_name)) {
43    _rustenv += [ string_join("",
44                              [
45                                "CARGO_PKG_NAME=",
46                                invoker.cargo_pkg_name,
47                              ]) ]
48  }
49  if (defined(invoker.cargo_pkg_description)) {
50    _rustenv += [ string_join("",
51                              [
52                                "CARGO_PKG_DESCRIPTION=",
53                                invoker.cargo_pkg_description,
54                              ]) ]
55  }
56
57  if (defined(invoker.build_root)) {
58    _epochlabel = "unknown"
59    if (defined(invoker.epoch)) {
60      _tempepoch = string_replace(invoker.epoch, ".", "_")
61      _epochlabel = "${_tempepoch}"
62    }
63    build_script_name =
64        "${_crate_name}_${target_name}_${_epochlabel}_build_script"
65  }
66  _rustflags = []
67  rust_target(target_name) {
68    forward_variables_from(invoker,
69                           "*",
70                           [
71                             "testonly",
72                             "visibility",
73                             "build_root",
74                             "build_sources",
75                             "build_deps",
76                             "build_script_inputs",
77                             "build_script_outputs",
78                             "output_dir",
79                             "target_type",
80                             "configs",
81                             "rustenv",
82                           ])
83
84    if (defined(invoker.subsystem_name) && defined(invoker.part_name)) {
85      subsystem_name = invoker.subsystem_name
86      part_name = invoker.part_name
87    } else if (defined(invoker.part_name)) {
88      part_name = invoker.part_name
89      _part_subsystem_info_file =
90          "$root_build_dir/build_configs/parts_info/part_subsystem.json"
91      _arguments = [
92        "--part-name",
93        part_name,
94        "--part-subsystem-info-file",
95        rebase_path(_part_subsystem_info_file, root_build_dir),
96      ]
97      get_subsystem_script = "//build/templates/common/get_subsystem_name.py"
98      subsystem_name =
99          exec_script(get_subsystem_script, _arguments, "trim string")
100    } else if (defined(invoker.subsystem_name)) {
101      subsystem_name = invoker.subsystem_name
102      part_name = subsystem_name
103    } else {
104      subsystem_name = "build"
105      part_name = "build_framework"
106    }
107    assert(subsystem_name != "")
108    assert(part_name != "")
109
110    if (defined(invoker.install_enable)) {
111      install_enable = invoker.install_enable
112    }
113
114    rustenv = _rustenv
115    if (defined(invoker.rustc_lints)) {
116      rustc_lints = invoker.rustc_lints
117    }
118    if (defined(invoker.clippy_lints)) {
119      clippy_lints = invoker.clippy_lints
120    }
121
122    if (!defined(rustc_lints) && !defined(clippy_lints)) {
123      file_path =
124          get_path_info(get_path_info(invoker.sources, "dir"), "abspath")
125      file_path_split = string_split(file_path[0], "/")
126      source_dir_begin = file_path_split[2]
127
128      if (source_dir_begin == "third_party") {
129        _rustflags += allowAllLints
130      } else if (source_dir_begin == "prebuilts") {
131        _rustflags += allowAllLints
132      } else if (source_dir_begin == "vendor" &&
133                 file_path_split[3] == "open_source") {
134        _rustflags += allowAllLints
135      } else if (source_dir_begin == "vendor") {
136        _rustflags += rustcVendorLints
137        _rustflags += clippyVendorLints
138      } else if (source_dir_begin == "device") {
139        _rustflags += rustcVendorLints
140        _rustflags += clippyVendorLints
141      } else {
142        _rustflags += rustcOhosLints
143        _rustflags += clippyOhosLints
144      }
145    }
146
147    if (defined(rustc_lints)) {
148      if (invoker.rustc_lints == "openharmony") {
149        _rustflags += rustcOhosLints
150      } else if (rustc_lints == "vendor") {
151        _rustflags += rustcVendorLints
152      } else if (rustc_lints == "none") {
153        _rustflags += allowAllLints
154      }
155    }
156    if (defined(clippy_lints)) {
157      if (invoker.clippy_lints == "openharmony") {
158        _rustflags += clippyOhosLints
159      } else if (clippy_lints == "vendor") {
160        _rustflags += clippyVendorLints
161      } else if (clippy_lints == "none") {
162        _rustflags += allowAllLints
163      }
164    }
165    if (!defined(rustflags)) {
166      rustflags = _rustflags
167    } else {
168      rustflags += _rustflags
169    }
170
171    crate_type = "rlib"
172    if (defined(invoker.crate_type)) {
173      crate_type = invoker.crate_type
174    }
175    if (crate_type == "bin") {
176      target_type = "ohos_executable"
177      assert(!defined(invoker.epoch))
178    } else if (crate_type == "proc-macro") {
179      target_type = "rust_proc_macro"
180    } else {
181      assert(crate_type == "rlib" || crate_type == "dylib")
182      target_type = "ohos_rust_library"
183    }
184
185    if (is_standard_system && defined(invoker.subsystem_name) &&
186        defined(invoker.part_name)) {
187      output_dir = "${root_out_dir}/${subsystem_name}/${part_name}"
188    } else {
189      output_dir = "${target_out_dir}/${orig_target_name}"
190    }
191
192    if (defined(invoker.build_root)) {
193      if (!defined(deps)) {
194        deps = []
195      }
196      if (!defined(sources)) {
197        sources = []
198      }
199
200      _build_script_target_out_dir =
201          get_label_info(":${build_script_name}_output", "target_out_dir")
202      _build_script_out_dir = "$_build_script_target_out_dir/$orig_target_name"
203
204      flags_file = "$_build_script_out_dir/cargo_flags.rs"
205      rustflags += [ "@" + rebase_path(flags_file, root_build_dir) ]
206      sources += [ flags_file ]
207      if (defined(invoker.build_script_outputs)) {
208        inputs = []
209        foreach(extra_source,
210                filter_exclude(invoker.build_script_outputs, [ "*.rs" ])) {
211          inputs += [ "$_build_script_out_dir/$extra_source" ]
212        }
213
214        foreach(extra_source,
215                filter_include(invoker.build_script_outputs, [ "*.rs" ])) {
216          sources += [ "$_build_script_out_dir/$extra_source" ]
217        }
218      }
219      deps += [ ":${build_script_name}_output" ]
220    } else {
221      not_needed([ "orig_target_name" ])
222    }
223  }
224
225  if (defined(invoker.build_root)) {
226    action("${build_script_name}_output") {
227      script = rebase_path("//build/templates/rust/run_build_script.py")
228      build_script_target = ":${build_script_name}($host_toolchain)"
229      deps = [ build_script_target ]
230
231      if (defined(invoker.subsystem_name) && defined(invoker.part_name)) {
232        subsystem_name = invoker.subsystem_name
233        part_name = invoker.part_name
234      } else if (defined(invoker.part_name)) {
235        part_name = invoker.part_name
236        _part_subsystem_info_file =
237            "$root_build_dir/build_configs/parts_info/part_subsystem.json"
238        _arguments = [
239          "--part-name",
240          part_name,
241          "--part-subsystem-info-file",
242          rebase_path(_part_subsystem_info_file, root_build_dir),
243        ]
244        get_subsystem_script = "//build/templates/common/get_subsystem_name.py"
245        subsystem_name =
246            exec_script(get_subsystem_script, _arguments, "trim string")
247      } else if (defined(invoker.subsystem_name)) {
248        subsystem_name = invoker.subsystem_name
249        part_name = subsystem_name
250      } else {
251        subsystem_name = "build"
252        part_name = "build_framework"
253      }
254      assert(subsystem_name != "")
255      assert(part_name != "")
256
257      if (current_toolchain == host_toolchain) {
258        _build_script_build_dir = "${root_out_dir}"
259      } else if (is_mingw) {
260        _build_script_build_dir = "${root_out_dir}/../clang_x64"
261      } else {
262        if (host_cpu == "arm64") {
263          _build_script_build_dir = "${root_out_dir}/clang_arm64"
264        } else {
265          _build_script_build_dir = "${root_out_dir}/clang_x64"
266        }
267      }
268
269      if (is_standard_system) {
270        _build_script_exe_dir =
271            "${_build_script_build_dir}/${subsystem_name}/${part_name}"
272      } else {
273        _build_script_exe_dir = "${_build_script_build_dir}"
274      }
275      build_script = "$_build_script_exe_dir/${build_script_name}"
276
277      if (is_win) {
278        build_script = "$_build_script_exe_dir/${build_script_name}.exe"
279      }
280
281      _build_script_out_dir = "$target_out_dir/$orig_target_name"
282      flags_file = "$_build_script_out_dir/cargo_flags.rs"
283
284      args = [
285        "--build-script",
286        rebase_path(build_script, root_build_dir),
287        "--rust-prefix",
288        rebase_path(
289            "//prebuilts/rustc/${host_platform_dir}/${rust_version}/bin",
290            root_build_dir),
291        "--output",
292        rebase_path(flags_file, root_build_dir),
293        "--src-dir",
294        rebase_path(get_path_info(invoker.build_root, "dir"), root_build_dir),
295        "--out-dir",
296        rebase_path(_build_script_out_dir, root_build_dir),
297      ]
298      if (defined(rust_abi_target) && rust_abi_target != "") {
299        args += [
300          "--target",
301          rust_abi_target,
302        ]
303      }
304
305      if (_rustenv != []) {
306        args += [ "--env" ]
307        args += _rustenv
308      }
309
310      if (defined(invoker.features)) {
311        args += [ "--features" ]
312        args += invoker.features
313      }
314      outputs = [ flags_file ]
315      inputs = [ build_script ]
316      if (defined(invoker.build_script_outputs)) {
317        foreach(generated_file, invoker.build_script_outputs) {
318          outputs += [ "$_build_script_out_dir/$generated_file" ]
319        }
320        args += [ "--generated-files" ]
321        args += invoker.build_script_outputs
322      }
323
324      if (defined(invoker.build_script_inputs)) {
325        inputs += invoker.build_script_inputs
326      }
327    }
328
329    rust_target(build_script_name) {
330      target_type = "ohos_executable"
331      sources = invoker.build_sources
332      crate_root = invoker.build_root
333      if (defined(invoker.build_deps)) {
334        deps = invoker.build_deps
335      }
336      rustenv = _rustenv
337      forward_variables_from(invoker,
338                             [
339                               "features",
340                               "edition",
341                               "rustflags",
342                               "subsystem_name",
343                               "part_name",
344                             ])
345    }
346  }
347}
348