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