• 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    rustenv = _rustenv
85    if (defined(invoker.rustc_lints)) {
86      rustc_lints = invoker.rustc_lints
87    }
88    if (defined(invoker.clippy_lints)) {
89      clippy_lints = invoker.clippy_lints
90    }
91
92    if (!defined(rustc_lints) && !defined(clippy_lints)) {
93      file_path =
94          get_path_info(get_path_info(invoker.sources, "dir"), "abspath")
95      file_path_split = string_split(file_path[0], "/")
96      source_dir_begin = file_path_split[2]
97
98      if (source_dir_begin == "third_party") {
99        _rustflags += allowAllLints
100      } else if (source_dir_begin == "prebuilts") {
101        _rustflags += allowAllLints
102      } else if (source_dir_begin == "vendor") {
103        _rustflags += rustcVendorLints
104        _rustflags += clippyVendorLints
105      } else if (source_dir_begin == "device") {
106        _rustflags += rustcVendorLints
107        _rustflags += clippyVendorLints
108      } else {
109        _rustflags += rustcOhosLints
110        _rustflags += clippyOhosLints
111      }
112    }
113
114    if (defined(rustc_lints)) {
115      if (invoker.rustc_lints == "openharmony") {
116        _rustflags += rustcOhosLints
117      } else if (rustc_lints == "vendor") {
118        _rustflags += rustcVendorLints
119      } else if (rustc_lints == "none") {
120        _rustflags += allowAllLints
121      }
122    }
123    if (defined(clippy_lints)) {
124      if (invoker.clippy_lints == "openharmony") {
125        _rustflags += clippyOhosLints
126      } else if (clippy_lints == "vendor") {
127        _rustflags += clippyVendorLints
128      } else if (clippy_lints == "none") {
129        _rustflags += allowAllLints
130      }
131    }
132    if (!defined(rustflags)) {
133      rustflags = _rustflags
134    } else {
135      rustflags += _rustflags
136    }
137
138    crate_type = "rlib"
139    if (defined(invoker.crate_type)) {
140      crate_type = invoker.crate_type
141    }
142    if (crate_type == "bin") {
143      target_type = "ohos_executable"
144      assert(!defined(invoker.epoch))
145    } else if (crate_type == "proc-macro") {
146      target_type = "rust_proc_macro"
147    } else {
148      assert(crate_type == "rlib" || crate_type == "dylib")
149      target_type = "ohos_rust_library"
150    }
151
152    output_dir = "${target_out_dir}/${orig_target_name}"
153
154    if (defined(invoker.build_root)) {
155      if (!defined(deps)) {
156        deps = []
157      }
158      if (!defined(sources)) {
159        sources = []
160      }
161
162      _build_script_target_out_dir =
163          get_label_info(":${build_script_name}_output", "target_out_dir")
164      _build_script_out_dir = "$_build_script_target_out_dir/$orig_target_name"
165
166      flags_file = "$_build_script_out_dir/cargo_flags.rs"
167      rustflags += [ "@" + rebase_path(flags_file, root_build_dir) ]
168      sources += [ flags_file ]
169      if (defined(invoker.build_script_outputs)) {
170        inputs = []
171        foreach(extra_source,
172                filter_exclude(invoker.build_script_outputs, [ "*.rs" ])) {
173          inputs += [ "$_build_script_out_dir/$extra_source" ]
174        }
175
176        foreach(extra_source,
177                filter_include(invoker.build_script_outputs, [ "*.rs" ])) {
178          sources += [ "$_build_script_out_dir/$extra_source" ]
179        }
180      }
181      deps += [ ":${build_script_name}_output" ]
182    } else {
183      not_needed([ "orig_target_name" ])
184    }
185  }
186
187  if (defined(invoker.build_root)) {
188    action("${build_script_name}_output") {
189      script = rebase_path("//build/templates/rust/run_build_script.py")
190      build_script_target = ":${build_script_name}($host_toolchain)"
191      deps = [ build_script_target ]
192
193      if (defined(invoker.subsystem_name) && defined(invoker.part_name)) {
194        subsystem_name = invoker.subsystem_name
195        part_name = invoker.part_name
196      } else if (defined(invoker.part_name)) {
197        part_name = invoker.part_name
198        _part_subsystem_info_file =
199            "$root_build_dir/build_configs/parts_info/part_subsystem.json"
200        _arguments = [
201          "--part-name",
202          part_name,
203          "--part-subsystem-info-file",
204          rebase_path(_part_subsystem_info_file, root_build_dir),
205        ]
206        get_subsystem_script = "//build/templates/common/get_subsystem_name.py"
207        subsystem_name =
208            exec_script(get_subsystem_script, _arguments, "trim string")
209      } else if (defined(invoker.subsystem_name)) {
210        subsystem_name = invoker.subsystem_name
211        part_name = subsystem_name
212      } else {
213        subsystem_name = "common"
214        part_name = subsystem_name
215      }
216      assert(subsystem_name != "")
217      assert(part_name != "")
218
219      if (current_toolchain == host_toolchain) {
220        _build_script_build_dir = "${root_out_dir}"
221      } else {
222        _build_script_build_dir = "${root_out_dir}/clang_x64"
223      }
224      if (is_standard_system) {
225        _build_script_exe_dir =
226            "${_build_script_build_dir}/${subsystem_name}/${part_name}"
227      } else {
228        _build_script_exe_dir = "${_build_script_build_dir}"
229      }
230      build_script = "$_build_script_exe_dir/${build_script_name}"
231
232      if (is_win) {
233        build_script = "$_build_script_exe_dir/${build_script_name}.exe"
234      }
235
236      _build_script_out_dir = "$target_out_dir/$orig_target_name"
237      flags_file = "$_build_script_out_dir/cargo_flags.rs"
238
239      args = [
240        "--build-script",
241        rebase_path(build_script, root_build_dir),
242        "--rust-prefix",
243        rebase_path(
244            "//prebuilts/rustc/${host_platform_dir}/${rust_version}/bin",
245            root_build_dir),
246        "--output",
247        rebase_path(flags_file, root_build_dir),
248        "--src-dir",
249        rebase_path(get_path_info(invoker.build_root, "dir"), root_build_dir),
250        "--out-dir",
251        rebase_path(_build_script_out_dir, root_build_dir),
252      ]
253      if (defined(rust_abi_target) && rust_abi_target != "") {
254        args += [
255          "--target",
256          rust_abi_target,
257        ]
258      }
259
260      if (_rustenv != []) {
261        args += [ "--env" ]
262        args += _rustenv
263      }
264
265      if (defined(invoker.features)) {
266        args += [ "--features" ]
267        args += invoker.features
268      }
269      outputs = [ flags_file ]
270      inputs = [ build_script ]
271      if (defined(invoker.build_script_outputs)) {
272        foreach(generated_file, invoker.build_script_outputs) {
273          outputs += [ "$_build_script_out_dir/$generated_file" ]
274        }
275        args += [ "--generated-files" ]
276        args += invoker.build_script_outputs
277      }
278
279      if (defined(invoker.build_script_inputs)) {
280        inputs += invoker.build_script_inputs
281      }
282    }
283
284    if (current_toolchain == host_toolchain) {
285      rust_target(build_script_name) {
286        target_type = "ohos_executable"
287        sources = invoker.build_sources
288        crate_root = invoker.build_root
289        if (defined(invoker.build_deps)) {
290          deps = invoker.build_deps
291        }
292        rustenv = _rustenv
293        forward_variables_from(invoker,
294                               [
295                                 "features",
296                                 "edition",
297                                 "rustflags",
298                               ])
299      }
300    } else {
301      not_needed(invoker,
302                 [
303                   "build_root",
304                   "build_sources",
305                   "build_deps",
306                   "build_script_inputs",
307                   "build_script_outputs",
308                 ])
309    }
310  }
311}
312