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