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