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/config/clang/clang.gni") 15import("//build/config/ohos/config.gni") 16import("//build/ohos/notice/notice.gni") 17import("//build/ohos_var.gni") 18import("//build/templates/common/check_target.gni") 19import("//build/templates/common/collect_target.gni") 20import("//build/templates/metadata/module_info.gni") 21 22template("ohos_rust_library") { 23 assert(!defined(invoker.output_dir), 24 "output_dir is not allowed to be defined.") 25 _test_target = defined(invoker.testonly) && invoker.testonly 26 if (defined(invoker.subsystem_name) && defined(invoker.part_name)) { 27 subsystem_name = invoker.subsystem_name 28 part_name = invoker.part_name 29 } else if (defined(invoker.part_name)) { 30 part_name = invoker.part_name 31 _part_subsystem_info_file = 32 "$root_build_dir/build_configs/parts_info/part_subsystem.json" 33 _arguments = [ 34 "--part-name", 35 part_name, 36 "--part-subsystem-info-file", 37 rebase_path(_part_subsystem_info_file, root_build_dir), 38 ] 39 get_subsystem_script = "//build/templates/common/get_subsystem_name.py" 40 subsystem_name = 41 exec_script(get_subsystem_script, _arguments, "trim string") 42 if (is_use_check_deps && !_test_target) { 43 skip_check_subsystem = true 44 } 45 } else if (defined(invoker.subsystem_name)) { 46 subsystem_name = invoker.subsystem_name 47 part_name = subsystem_name 48 } else { 49 subsystem_name = "build" 50 part_name = "build_framework" 51 } 52 assert(subsystem_name != "") 53 assert(part_name != "") 54 if (is_use_check_deps && !_test_target) { 55 _check_target = "${target_name}__check" 56 target_path = get_label_info(":${target_name}", "label_no_toolchain") 57 check_target(_check_target) { 58 module_deps = [] 59 module_ex_deps = [] 60 if (defined(invoker.deps)) { 61 module_deps += invoker.deps 62 } 63 if (defined(invoker.public_deps)) { 64 module_deps += invoker.public_deps 65 } 66 if (defined(invoker.external_deps)) { 67 module_ex_deps += invoker.external_deps 68 } 69 if (defined(invoker.public_external_deps)) { 70 module_ex_deps += invoker.public_external_deps 71 } 72 } 73 } 74 75 if (check_deps) { 76 deps_data = { 77 } 78 module_label = get_label_info(":${target_name}", "label_with_toolchain") 79 module_deps = [] 80 if (defined(invoker.deps)) { 81 foreach(dep, invoker.deps) { 82 module_deps += [ get_label_info(dep, "label_no_toolchain") ] 83 } 84 } 85 module_ex_deps = [] 86 if (defined(invoker.external_deps) && invoker.external_deps != []) { 87 module_ex_deps = invoker.external_deps 88 } 89 deps_data = { 90 part_name = part_name 91 module_label = module_label 92 deps = module_deps 93 external_deps = module_ex_deps 94 } 95 write_file("${root_out_dir}/deps_files/${part_name}__${target_name}.json", 96 deps_data, 97 "json") 98 } 99 100 if (is_standard_system) { 101 output_dir = "${root_out_dir}/${subsystem_name}/${part_name}" 102 } else { 103 output_dir = "${root_out_dir}" 104 } 105 106 if (!_test_target) { 107 module_label = get_label_info(":${target_name}", "label_with_toolchain") 108 _collect_target = "${target_name}__collect" 109 collect_module_target(_collect_target) { 110 forward_variables_from(invoker, [ "install_images" ]) 111 } 112 113 _notice_target = "${target_name}__notice" 114 _main_target_name = target_name 115 collect_notice(_notice_target) { 116 forward_variables_from(invoker, 117 [ 118 "testonly", 119 "license_as_sources", 120 "license_file", 121 ]) 122 module_type = "rust_library" 123 124 module_name = _main_target_name 125 if (defined(invoker.crate_name)) { 126 module_name = invoker.crate_name 127 } 128 module_source_dir = get_label_info(":${_main_target_name}", "dir") 129 } 130 } 131 132 # auto set auto_relative_install_dir by innerapi_tags 133 if (defined(invoker.innerapi_tags)) { 134 is_chipsetsdk = false 135 is_platformsdk = false 136 is_platformsdk_indirect = false 137 is_passthrough = false 138 is_passthrough_indirect = false 139 is_llndk = false 140 is_chipsetsdk_indirect = false 141 is_chipsetsdk_sp = false 142 is_chipsetsdk_sp_indirect = false 143 144 foreach(tag, filter_include(invoker.innerapi_tags, [ "llndk" ])) { 145 is_llndk = true 146 } 147 foreach(tag, filter_include(invoker.innerapi_tags, [ "chipsetsdk" ])) { 148 is_chipsetsdk = true 149 } 150 foreach(tag, 151 filter_include(invoker.innerapi_tags, [ "chipsetsdk_indirect" ])) { 152 is_chipsetsdk_indirect = true 153 } 154 foreach(tag, filter_include(invoker.innerapi_tags, [ "chipsetsdk_sp" ])) { 155 is_chipsetsdk_sp = true 156 } 157 foreach( 158 tag, 159 filter_include(invoker.innerapi_tags, [ "chipsetsdk_sp_indirect" ])) { 160 is_chipsetsdk_sp_indirect = true 161 } 162 foreach(tag, filter_include(invoker.innerapi_tags, [ "platformsdk" ])) { 163 is_platformsdk = true 164 } 165 foreach(tag, 166 filter_include(invoker.innerapi_tags, [ "platformsdk_indirect" ])) { 167 is_platformsdk_indirect = true 168 } 169 foreach(tag, filter_include(invoker.innerapi_tags, [ "passthrough" ])) { 170 is_passthrough = true 171 } 172 foreach(tag, 173 filter_include(invoker.innerapi_tags, [ "passthrough_indirect" ])) { 174 is_passthrough_indirect = true 175 } 176 177 if (is_chipsetsdk && (is_chipsetsdk_indirect || is_chipsetsdk_sp || is_chipsetsdk_sp_indirect)) { 178 assert(false, "chipsetsdk tags cannot coexist with [chipsetsdk_indirect,chipsetsdk_sp,chipsetsdk_sp_indirect]") 179 } else if (is_chipsetsdk_indirect && (is_chipsetsdk || is_chipsetsdk_sp || is_chipsetsdk_sp_indirect)) { 180 assert(false, "chipsetsdk_indirect tags cannot coexist with [chipsetsdk,chipsetsdk_sp,chipsetsdk_sp_indirect]") 181 } else if (is_chipsetsdk_sp && (is_chipsetsdk || is_chipsetsdk_indirect || is_chipsetsdk_sp_indirect)) { 182 assert(false, "chipsetsdk_sp tags cannot coexist with [chipsetsdk,chipsetsdk_indirect,chipsetsdk_sp_indirect]") 183 } else if (is_chipsetsdk_sp_indirect && (is_chipsetsdk || is_chipsetsdk_sp || is_chipsetsdk_indirect)) { 184 assert(false, "chipsetsdk_sp_indirect tags cannot coexist with [chipsetsdk,chipsetsdk_indirect,chipsetsdk_sp]") 185 } 186 187 if (is_platformsdk) { 188 auto_relative_install_dir = platformsdk_dir 189 } 190 191 if (is_platformsdk_indirect) { 192 auto_relative_install_dir = platformsdk_dir 193 } 194 195 if (is_chipsetsdk) { 196 auto_relative_install_dir = chipset_sdk_dir 197 if (is_platformsdk || is_platformsdk_indirect) { 198 softlink_path = platformsdk_dir 199 } 200 } 201 202 if (is_chipsetsdk_indirect) { 203 auto_relative_install_dir = chipset_sdk_dir 204 if (is_platformsdk || is_platformsdk_indirect) { 205 softlink_path = platformsdk_dir 206 } 207 } 208 209 if (is_chipsetsdk_sp) { 210 auto_relative_install_dir = chipset_sdk_sp_dir 211 if (is_platformsdk || is_platformsdk_indirect) { 212 softlink_path = platformsdk_dir 213 } 214 } 215 216 if (is_chipsetsdk_sp_indirect) { 217 auto_relative_install_dir = chipset_sdk_sp_dir 218 if (is_platformsdk || is_platformsdk_indirect) { 219 softlink_path = platformsdk_dir 220 } 221 } 222 223 if (is_passthrough) { 224 auto_relative_install_dir = passthrough_dir 225 } 226 if (is_passthrough_indirect) { 227 auto_relative_install_dir = passthrough_indirect_dir 228 } 229 230 if (is_llndk) { 231 auto_relative_install_dir = llndk_dir 232 } 233 is_ndk = false 234 foreach(tag, filter_include(invoker.innerapi_tags, [ "ndk" ])) { 235 is_ndk = true 236 } 237 if (is_ndk) { 238 if (is_llndk) { 239 softlink_path = ndk_dir 240 auto_relative_install_dir = llndk_dir 241 } else { 242 auto_relative_install_dir = ndk_dir 243 } 244 } 245 } 246 247 target_label = get_label_info(":${target_name}", "label_with_toolchain") 248 target_toolchain = get_label_info(target_label, "toolchain") 249 250 if (target_toolchain == "${current_toolchain}") { 251 ohos_module_name = target_name 252 _module_info_target = "${target_name}_info" 253 generate_module_info(_module_info_target) { 254 module_name = ohos_module_name 255 module_type = "lib" 256 module_source_dir = "$root_out_dir" 257 if (defined(output_dir)) { 258 module_source_dir = output_dir 259 } 260 261 module_install_name = ohos_module_name 262 if (defined(invoker.output_name)) { 263 module_install_name = invoker.output_name 264 } 265 266 module_install_images = [ "system" ] 267 if (defined(invoker.install_images)) { 268 module_install_images = [] 269 module_install_images += invoker.install_images 270 } 271 272 module_output_extension = shlib_extension 273 if (defined(invoker.module_output_extension)) { 274 module_output_extension = invoker.module_output_extension 275 } 276 277 install_enable = true 278 if (defined(invoker.install_enable)) { 279 install_enable = invoker.install_enable 280 } 281 282 if (defined(invoker.module_install_dir)) { 283 module_install_dir = invoker.module_install_dir 284 } 285 286 # update relative_install_dir if auto_relative_install_dir defined 287 if (defined(auto_relative_install_dir)) { 288 relative_install_dir = auto_relative_install_dir 289 } 290 291 if (defined(invoker.relative_install_dir)) { 292 relative_install_dir = invoker.relative_install_dir 293 } 294 295 if (defined(invoker.innerapi_tags)) { 296 if (defined(softlink_path) && softlink_path != "") { 297 softlink_create_path = softlink_path 298 } 299 } 300 301 if (defined(invoker.symlink_target_name)) { 302 symlink_target_name = invoker.symlink_target_name 303 } 304 305 if (defined(invoker.output_prefix_override)) { 306 output_prefix_override = invoker.output_prefix_override 307 } 308 notice = "$target_out_dir/$ohos_module_name.notice.txt" 309 310 if (defined(invoker.innerapi_tags)) { 311 invalid = false 312 valid_tags = [ 313 "ndk", 314 "llndk", 315 "chipsetsdk", 316 "chipsetsdk_indirect", 317 "chipsetsdk_sp", 318 "chipsetsdk_sp_indirect", 319 "platformsdk", 320 "platformsdk_indirect", 321 "passthrough", 322 "passthrough_indirect", 323 "sasdk", 324 ] 325 foreach(tag, filter_exclude(invoker.innerapi_tags, valid_tags)) { 326 if (tag != "") { 327 invalid = true 328 } 329 } 330 innerapi_tags = invoker.innerapi_tags 331 assert( 332 invalid != true, 333 "$target_label has invalid innerapi_tags $innerapi_tags, allowed values: $valid_tags") 334 } 335 } 336 } 337 338 rust_library("${target_name}") { 339 forward_variables_from(invoker, 340 "*", 341 [ 342 "configs", 343 "remove_configs", 344 "no_default_deps", 345 "install_images", 346 "module_install_dir", 347 "relative_install_dir", 348 "symlink_target_name", 349 "output_dir", 350 "install_enable", 351 "version_script", 352 "license_file", 353 "license_as_sources", 354 "use_exceptions", 355 "stl", 356 357 # Sanitizer variables 358 "sanitize", 359 ]) 360 output_dir = output_dir 361 362 if (!defined(inputs)) { 363 inputs = [] 364 } 365 366 if (!defined(ldflags)) { 367 ldflags = [] 368 } 369 370 if (defined(invoker.configs)) { 371 configs += invoker.configs 372 } 373 if (defined(invoker.remove_configs)) { 374 configs -= invoker.remove_configs 375 } 376 377 if (!defined(output_name)) { 378 output_name = target_name 379 } 380 381 if (defined(invoker.no_default_deps)) { 382 no_default_deps = invoker.no_default_deps 383 } 384 385 if (!defined(ldflags)) { 386 ldflags = [] 387 } 388 if (!defined(libs)) { 389 libs = [] 390 } 391 if (!defined(cflags_cc)) { 392 cflags_cc = [] 393 } 394 if (!defined(deps)) { 395 deps = [] 396 } 397 if (is_use_check_deps && !_test_target) { 398 deps += [ ":$_check_target" ] 399 } 400 if (target_toolchain == "${current_toolchain}" && !skip_gen_module_info) { 401 deps += [ ":$_module_info_target" ] 402 } 403 404 if (is_ohos) { 405 if (defined(invoker.stl)) { 406 cflags_cc += [ 407 "-nostdinc++", 408 "-I" + rebase_path( 409 "${}toolchains_dir/${host_platform_dir}/llvm_ndk/include/c++/v1", 410 root_build_dir), 411 ] 412 ldflags += [ 413 "-nostdlib++", 414 "-L" + rebase_path("${clang_stl_path}/${abi_target}/c++", 415 root_build_dir), 416 ] 417 418 libs += [ invoker.stl ] 419 } else { 420 if (current_cpu == "arm" || current_cpu == "arm64") { 421 libs += [ "unwind" ] 422 } 423 ldflags += [ "-L" + rebase_path("${clang_stl_path}/${abi_target}/c++", 424 root_build_dir) ] 425 426 libs += [ "c++" ] 427 } 428 } 429 430 if (defined(visibility) && visibility != []) { 431 visibility += [ "//build/*" ] 432 if (defined(build_ext_path)) { 433 visibility += [ "${build_ext_path}/*" ] 434 } 435 } 436 437 if (!_test_target) { 438 deps += [ 439 ":$_notice_target", 440 ":${_collect_target}", 441 ] 442 } 443 if (!defined(include_dirs)) { 444 include_dirs = [] 445 } 446 447 install_module_info = { 448 module_def = target_label 449 module_info_file = 450 rebase_path(get_label_info(module_def, "target_out_dir"), 451 root_build_dir) + "/${target_name}_module_info.json" 452 subsystem_name = subsystem_name 453 part_name = part_name 454 toolchain = current_toolchain 455 toolchain_out_dir = rebase_path(root_out_dir, root_build_dir) 456 } 457 metadata = { 458 install_modules = [ install_module_info ] 459 } 460 if (defined(is_debug) && !is_debug && enable_debug_components != "") { 461 foreach(component_name, debug_components) { 462 if (part_name == component_name) { 463 configs -= default_opt_configs 464 configs += debug_level_configs 465 } 466 } 467 } 468 } 469} 470