1*8975f5c5SAndroid Build Coastguard Worker# Copyright 2021 The Chromium Authors 2*8975f5c5SAndroid Build Coastguard Worker# Use of this source code is governed by a BSD-style license that can be 3*8975f5c5SAndroid Build Coastguard Worker# found in the LICENSE file. 4*8975f5c5SAndroid Build Coastguard Worker 5*8975f5c5SAndroid Build Coastguard Workerimport("//build/config/rust.gni") 6*8975f5c5SAndroid Build Coastguard Workerimport("//build/rust/rust_unit_test.gni") 7*8975f5c5SAndroid Build Coastguard Worker 8*8975f5c5SAndroid Build Coastguard Worker# The //build directory is re-used for non-Chromium projects. Do not support 9*8975f5c5SAndroid Build Coastguard Worker# cxx bindings in such contexts by default, because //third_party may be 10*8975f5c5SAndroid Build Coastguard Worker# missing. Projects that wish to use cxx bindings must explicitly set the 11*8975f5c5SAndroid Build Coastguard Worker# enable_rust_cxx GN arg to true. 12*8975f5c5SAndroid Build Coastguard Workerif (enable_rust_cxx) { 13*8975f5c5SAndroid Build Coastguard Worker import("//third_party/rust/cxx/chromium_integration/rust_cxx.gni") 14*8975f5c5SAndroid Build Coastguard Worker} 15*8975f5c5SAndroid Build Coastguard Worker 16*8975f5c5SAndroid Build Coastguard Worker# Creates a Rust target (rlib, executable, proc macro etc.) with ability to 17*8975f5c5SAndroid Build Coastguard Worker# understand some handy variables such as "edition" and "features" and also to 18*8975f5c5SAndroid Build Coastguard Worker# build any associated unit tests. 19*8975f5c5SAndroid Build Coastguard Worker# 20*8975f5c5SAndroid Build Coastguard Worker# `bindgen_deps` field exists only for 3P cargo sys crates that uses 21*8975f5c5SAndroid Build Coastguard Worker# `rust_bindgen_generator` templates. For 1P code, `rust_bindgen` should 22*8975f5c5SAndroid Build Coastguard Worker# be used and should go directly in the `deps` field. 23*8975f5c5SAndroid Build Coastguard Worker# 24*8975f5c5SAndroid Build Coastguard Worker# Normally, you should not use this directly. Use either 25*8975f5c5SAndroid Build Coastguard Worker# - cargo_crate.gni - for 3p crates only 26*8975f5c5SAndroid Build Coastguard Worker# - rust_static_library.gni - for 1p Rust code 27*8975f5c5SAndroid Build Coastguard Worker# 28*8975f5c5SAndroid Build Coastguard Worker# Because the common use of this is rust_static_library, all the documentation 29*8975f5c5SAndroid Build Coastguard Worker# for the supported options is given in rust_static_library.gni. Please refer 30*8975f5c5SAndroid Build Coastguard Worker# over there. 31*8975f5c5SAndroid Build Coastguard Worker# 32*8975f5c5SAndroid Build Coastguard Worker# If you're using rust_target directly, you will also need to specify: 33*8975f5c5SAndroid Build Coastguard Worker# target_type executable, rust_library etc. per GN norms 34*8975f5c5SAndroid Build Coastguard Worker# 35*8975f5c5SAndroid Build Coastguard Worker# There is one area where this differs from `rust_static_library`: configs. 36*8975f5c5SAndroid Build Coastguard Worker# Here, you must specify `executable_configs` or `library_configs` depending on 37*8975f5c5SAndroid Build Coastguard Worker# the type of thing you're generating. This is so that different defaults can 38*8975f5c5SAndroid Build Coastguard Worker# be provided. 39*8975f5c5SAndroid Build Coastguard Worker 40*8975f5c5SAndroid Build Coastguard Workertemplate("rust_target") { 41*8975f5c5SAndroid Build Coastguard Worker _target_name = target_name 42*8975f5c5SAndroid Build Coastguard Worker 43*8975f5c5SAndroid Build Coastguard Worker # NOTE: TargetName=>CrateName mangling algorithm should be updated 44*8975f5c5SAndroid Build Coastguard Worker # simultaneously in 3 places: here, //build/rust/rust_static_library.gni, 45*8975f5c5SAndroid Build Coastguard Worker # //build/rust/chromium_prelude/import_attribute.rs 46*8975f5c5SAndroid Build Coastguard Worker if (defined(invoker.crate_name)) { 47*8975f5c5SAndroid Build Coastguard Worker _crate_name = invoker.crate_name 48*8975f5c5SAndroid Build Coastguard Worker } else { 49*8975f5c5SAndroid Build Coastguard Worker # Not using `get_label_info(..., "label_no_toolchain")` to consistently 50*8975f5c5SAndroid Build Coastguard Worker # use `//foo/bar:baz` instead of the alternative shorter `//foo/bar` form. 51*8975f5c5SAndroid Build Coastguard Worker _dir = get_label_info(":${_target_name}", "dir") 52*8975f5c5SAndroid Build Coastguard Worker _dir = string_replace(_dir, "//", "") 53*8975f5c5SAndroid Build Coastguard Worker _crate_name = "${_dir}:${_target_name}" 54*8975f5c5SAndroid Build Coastguard Worker 55*8975f5c5SAndroid Build Coastguard Worker # The `string_replace` calls below replicate the escaping algorithm 56*8975f5c5SAndroid Build Coastguard Worker # from the `escape_non_identifier_chars` function in 57*8975f5c5SAndroid Build Coastguard Worker # //build/rust/chromium_prelude/import_attribute.rs. Note that the 58*8975f5c5SAndroid Build Coastguard Worker # ordering of `match` branches within the Rust function doesn't matter, 59*8975f5c5SAndroid Build Coastguard Worker # but the ordering of `string_replace` calls *does* matter - the escape 60*8975f5c5SAndroid Build Coastguard Worker # character `_` needs to be handled first to meet the injectivity 61*8975f5c5SAndroid Build Coastguard Worker # requirement (otherwise we would get `/` => `_s` => `_us` and the same 62*8975f5c5SAndroid Build Coastguard Worker # result for `_s` => `_us`). 63*8975f5c5SAndroid Build Coastguard Worker _crate_name = string_replace(_crate_name, "_", "_u") 64*8975f5c5SAndroid Build Coastguard Worker _crate_name = string_replace(_crate_name, "/", "_s") 65*8975f5c5SAndroid Build Coastguard Worker _crate_name = string_replace(_crate_name, ":", "_c") 66*8975f5c5SAndroid Build Coastguard Worker _crate_name = string_replace(_crate_name, "-", "_d") 67*8975f5c5SAndroid Build Coastguard Worker } 68*8975f5c5SAndroid Build Coastguard Worker _generate_crate_root = 69*8975f5c5SAndroid Build Coastguard Worker defined(invoker.generate_crate_root) && invoker.generate_crate_root 70*8975f5c5SAndroid Build Coastguard Worker 71*8975f5c5SAndroid Build Coastguard Worker # Only one of `crate_root` or `generate_crate_root` can be specified, or 72*8975f5c5SAndroid Build Coastguard Worker # neither. 73*8975f5c5SAndroid Build Coastguard Worker assert(!defined(invoker.crate_root) || !_generate_crate_root) 74*8975f5c5SAndroid Build Coastguard Worker 75*8975f5c5SAndroid Build Coastguard Worker # This is where the OUT_DIR environment variable points to when running a 76*8975f5c5SAndroid Build Coastguard Worker # build script and when compiling the build target, for consuming generated 77*8975f5c5SAndroid Build Coastguard Worker # files. 78*8975f5c5SAndroid Build Coastguard Worker _env_out_dir = "$target_gen_dir/$_target_name" 79*8975f5c5SAndroid Build Coastguard Worker 80*8975f5c5SAndroid Build Coastguard Worker _allow_unsafe = false 81*8975f5c5SAndroid Build Coastguard Worker if (defined(invoker.allow_unsafe)) { 82*8975f5c5SAndroid Build Coastguard Worker _allow_unsafe = invoker.allow_unsafe 83*8975f5c5SAndroid Build Coastguard Worker } 84*8975f5c5SAndroid Build Coastguard Worker 85*8975f5c5SAndroid Build Coastguard Worker if (_generate_crate_root) { 86*8975f5c5SAndroid Build Coastguard Worker generated_file("${_target_name}_crate_root") { 87*8975f5c5SAndroid Build Coastguard Worker outputs = [ "${target_gen_dir}/${target_name}.rs" ] 88*8975f5c5SAndroid Build Coastguard Worker contents = [ 89*8975f5c5SAndroid Build Coastguard Worker "// Generated crate root for ${_target_name}.", 90*8975f5c5SAndroid Build Coastguard Worker "// @generated", 91*8975f5c5SAndroid Build Coastguard Worker "", 92*8975f5c5SAndroid Build Coastguard Worker ] 93*8975f5c5SAndroid Build Coastguard Worker foreach(rs, invoker.sources) { 94*8975f5c5SAndroid Build Coastguard Worker rs_path_from_root = rebase_path(rs, target_gen_dir) 95*8975f5c5SAndroid Build Coastguard Worker contents += [ "#[path = \"${rs_path_from_root}\"]" ] 96*8975f5c5SAndroid Build Coastguard Worker 97*8975f5c5SAndroid Build Coastguard Worker # Drop the file extension from the module name. 98*8975f5c5SAndroid Build Coastguard Worker rs_modname = string_replace(rs, ".rs", "") 99*8975f5c5SAndroid Build Coastguard Worker 100*8975f5c5SAndroid Build Coastguard Worker # Replace invalid "/" chars in the source file path. 101*8975f5c5SAndroid Build Coastguard Worker rs_modname = string_replace(rs_modname, "/", "_") 102*8975f5c5SAndroid Build Coastguard Worker 103*8975f5c5SAndroid Build Coastguard Worker # Since source files are specified relative to the BUILD.gn they may 104*8975f5c5SAndroid Build Coastguard Worker # also have ".." path components. 105*8975f5c5SAndroid Build Coastguard Worker rs_modname = string_replace(rs_modname, "..", "dotdot") 106*8975f5c5SAndroid Build Coastguard Worker contents += [ 107*8975f5c5SAndroid Build Coastguard Worker "mod ${rs_modname};", 108*8975f5c5SAndroid Build Coastguard Worker "", 109*8975f5c5SAndroid Build Coastguard Worker ] 110*8975f5c5SAndroid Build Coastguard Worker } 111*8975f5c5SAndroid Build Coastguard Worker } 112*8975f5c5SAndroid Build Coastguard Worker _generated_crate_root = get_target_outputs(":${_target_name}_crate_root") 113*8975f5c5SAndroid Build Coastguard Worker _crate_root = _generated_crate_root[0] 114*8975f5c5SAndroid Build Coastguard Worker } else if (defined(invoker.crate_root)) { 115*8975f5c5SAndroid Build Coastguard Worker _crate_root = invoker.crate_root 116*8975f5c5SAndroid Build Coastguard Worker } else if (invoker.target_type == "executable") { 117*8975f5c5SAndroid Build Coastguard Worker _crate_root = "src/main.rs" 118*8975f5c5SAndroid Build Coastguard Worker } else { 119*8975f5c5SAndroid Build Coastguard Worker _crate_root = "src/lib.rs" 120*8975f5c5SAndroid Build Coastguard Worker } 121*8975f5c5SAndroid Build Coastguard Worker 122*8975f5c5SAndroid Build Coastguard Worker _testonly = false 123*8975f5c5SAndroid Build Coastguard Worker if (defined(invoker.testonly)) { 124*8975f5c5SAndroid Build Coastguard Worker _testonly = invoker.testonly 125*8975f5c5SAndroid Build Coastguard Worker } 126*8975f5c5SAndroid Build Coastguard Worker if (defined(invoker.visibility)) { 127*8975f5c5SAndroid Build Coastguard Worker _visibility = invoker.visibility 128*8975f5c5SAndroid Build Coastguard Worker } 129*8975f5c5SAndroid Build Coastguard Worker 130*8975f5c5SAndroid Build Coastguard Worker _rustflags = [] 131*8975f5c5SAndroid Build Coastguard Worker if (defined(invoker.rustflags)) { 132*8975f5c5SAndroid Build Coastguard Worker _rustflags += invoker.rustflags 133*8975f5c5SAndroid Build Coastguard Worker } 134*8975f5c5SAndroid Build Coastguard Worker if (defined(invoker.features)) { 135*8975f5c5SAndroid Build Coastguard Worker foreach(i, invoker.features) { 136*8975f5c5SAndroid Build Coastguard Worker _rustflags += [ "--cfg=feature=\"${i}\"" ] 137*8975f5c5SAndroid Build Coastguard Worker } 138*8975f5c5SAndroid Build Coastguard Worker } 139*8975f5c5SAndroid Build Coastguard Worker _edition = "2021" 140*8975f5c5SAndroid Build Coastguard Worker if (defined(invoker.edition)) { 141*8975f5c5SAndroid Build Coastguard Worker _edition = invoker.edition 142*8975f5c5SAndroid Build Coastguard Worker } 143*8975f5c5SAndroid Build Coastguard Worker 144*8975f5c5SAndroid Build Coastguard Worker assert(!defined(configs)) 145*8975f5c5SAndroid Build Coastguard Worker _configs = [ "//build/rust:edition_${_edition}" ] 146*8975f5c5SAndroid Build Coastguard Worker _test_configs = [] 147*8975f5c5SAndroid Build Coastguard Worker if (invoker.target_type == "executable") { 148*8975f5c5SAndroid Build Coastguard Worker _configs += invoker.executable_configs 149*8975f5c5SAndroid Build Coastguard Worker } else if (invoker.target_type == "rust_proc_macro") { 150*8975f5c5SAndroid Build Coastguard Worker _configs += invoker.proc_macro_configs 151*8975f5c5SAndroid Build Coastguard Worker _test_configs += [ "//build/rust:proc_macro_extern" ] 152*8975f5c5SAndroid Build Coastguard Worker } else if (invoker.target_type == "shared_library") { 153*8975f5c5SAndroid Build Coastguard Worker _configs += invoker.shared_library_configs 154*8975f5c5SAndroid Build Coastguard Worker } else { 155*8975f5c5SAndroid Build Coastguard Worker _configs += invoker.library_configs 156*8975f5c5SAndroid Build Coastguard Worker } 157*8975f5c5SAndroid Build Coastguard Worker 158*8975f5c5SAndroid Build Coastguard Worker if (invoker.target_type == "rust_proc_macro") { 159*8975f5c5SAndroid Build Coastguard Worker _main_target_suffix = "__proc_macro" 160*8975f5c5SAndroid Build Coastguard Worker } else if (invoker.target_type == "shared_library") { 161*8975f5c5SAndroid Build Coastguard Worker _main_target_suffix = "__proc_macro" 162*8975f5c5SAndroid Build Coastguard Worker } else { 163*8975f5c5SAndroid Build Coastguard Worker _main_target_suffix = "" 164*8975f5c5SAndroid Build Coastguard Worker } 165*8975f5c5SAndroid Build Coastguard Worker 166*8975f5c5SAndroid Build Coastguard Worker _deps = [] 167*8975f5c5SAndroid Build Coastguard Worker if (defined(invoker.deps)) { 168*8975f5c5SAndroid Build Coastguard Worker _deps += invoker.deps 169*8975f5c5SAndroid Build Coastguard Worker } 170*8975f5c5SAndroid Build Coastguard Worker if (defined(invoker.bindgen_deps)) { 171*8975f5c5SAndroid Build Coastguard Worker _bindgen_inputs = [] 172*8975f5c5SAndroid Build Coastguard Worker 173*8975f5c5SAndroid Build Coastguard Worker # This iteration assumes that no targets have the same name which is 174*8975f5c5SAndroid Build Coastguard Worker # very rare to happen and if it does. An error will be thrown as we 175*8975f5c5SAndroid Build Coastguard Worker # try to create two targets with the same name, the error might not 176*8975f5c5SAndroid Build Coastguard Worker # be descriptive enough so maybe adding a check action would be better. 177*8975f5c5SAndroid Build Coastguard Worker foreach(bindgen_dep, invoker.bindgen_deps) { 178*8975f5c5SAndroid Build Coastguard Worker _copy_target_name = 179*8975f5c5SAndroid Build Coastguard Worker target_name + "_" + get_label_info(bindgen_dep, "name") + "_copy" 180*8975f5c5SAndroid Build Coastguard Worker copy(_copy_target_name) { 181*8975f5c5SAndroid Build Coastguard Worker _bindgen_output_files = get_target_outputs(bindgen_dep) 182*8975f5c5SAndroid Build Coastguard Worker 183*8975f5c5SAndroid Build Coastguard Worker # `rust_bindgen_generator` promises that the first output file is always .rs. 184*8975f5c5SAndroid Build Coastguard Worker sources = [ _bindgen_output_files[0] ] 185*8975f5c5SAndroid Build Coastguard Worker outputs = [ "$_env_out_dir/{{source_name_part}}.rs" ] 186*8975f5c5SAndroid Build Coastguard Worker deps = [ bindgen_dep ] 187*8975f5c5SAndroid Build Coastguard Worker } 188*8975f5c5SAndroid Build Coastguard Worker 189*8975f5c5SAndroid Build Coastguard Worker # The bindgen-generated rs files are inputs to this library for the library 190*8975f5c5SAndroid Build Coastguard Worker # to `include!` them. 191*8975f5c5SAndroid Build Coastguard Worker # The output of the copy action is always a single file so just copy everything. 192*8975f5c5SAndroid Build Coastguard Worker _bindgen_inputs += get_target_outputs(":$_copy_target_name") 193*8975f5c5SAndroid Build Coastguard Worker 194*8975f5c5SAndroid Build Coastguard Worker # Depend on the bindgen generation to make the above `_bindgen_inputs`. 195*8975f5c5SAndroid Build Coastguard Worker _deps += [ ":$_copy_target_name" ] 196*8975f5c5SAndroid Build Coastguard Worker } 197*8975f5c5SAndroid Build Coastguard Worker } 198*8975f5c5SAndroid Build Coastguard Worker _public_deps = [] 199*8975f5c5SAndroid Build Coastguard Worker if (defined(invoker.public_deps)) { 200*8975f5c5SAndroid Build Coastguard Worker _public_deps += invoker.public_deps 201*8975f5c5SAndroid Build Coastguard Worker } 202*8975f5c5SAndroid Build Coastguard Worker if (defined(invoker.aliased_deps)) { 203*8975f5c5SAndroid Build Coastguard Worker _aliased_deps = invoker.aliased_deps 204*8975f5c5SAndroid Build Coastguard Worker } else { 205*8975f5c5SAndroid Build Coastguard Worker _aliased_deps = { 206*8975f5c5SAndroid Build Coastguard Worker } 207*8975f5c5SAndroid Build Coastguard Worker } 208*8975f5c5SAndroid Build Coastguard Worker 209*8975f5c5SAndroid Build Coastguard Worker _build_unit_tests = false 210*8975f5c5SAndroid Build Coastguard Worker if (defined(invoker.build_native_rust_unit_tests)) { 211*8975f5c5SAndroid Build Coastguard Worker _build_unit_tests = 212*8975f5c5SAndroid Build Coastguard Worker invoker.build_native_rust_unit_tests && can_build_rust_unit_tests 213*8975f5c5SAndroid Build Coastguard Worker } 214*8975f5c5SAndroid Build Coastguard Worker 215*8975f5c5SAndroid Build Coastguard Worker # Declares that the Rust crate generates bindings between C++ and Rust via the 216*8975f5c5SAndroid Build Coastguard Worker # Cxx crate. It may generate C++ headers and/or use the cxx crate macros to 217*8975f5c5SAndroid Build Coastguard Worker # generate Rust code internally, depending on what bindings are declared. If 218*8975f5c5SAndroid Build Coastguard Worker # set, it's a set of rust files that include Cxx bindings declarations. 219*8975f5c5SAndroid Build Coastguard Worker _cxx_bindings = [] 220*8975f5c5SAndroid Build Coastguard Worker assert(!defined(invoker.cxx_bindings) || enable_rust_cxx, 221*8975f5c5SAndroid Build Coastguard Worker "cxx bindings are not supported when building rust targets " + 222*8975f5c5SAndroid Build Coastguard Worker "outside the Chromium build.") 223*8975f5c5SAndroid Build Coastguard Worker if (defined(invoker.cxx_bindings)) { 224*8975f5c5SAndroid Build Coastguard Worker _cxx_bindings = invoker.cxx_bindings 225*8975f5c5SAndroid Build Coastguard Worker } 226*8975f5c5SAndroid Build Coastguard Worker _rustenv = [ "OUT_DIR=" + 227*8975f5c5SAndroid Build Coastguard Worker rebase_path(_env_out_dir, get_path_info(_crate_root, "dir")) ] 228*8975f5c5SAndroid Build Coastguard Worker if (defined(invoker.rustenv)) { 229*8975f5c5SAndroid Build Coastguard Worker _rustenv += invoker.rustenv 230*8975f5c5SAndroid Build Coastguard Worker } 231*8975f5c5SAndroid Build Coastguard Worker 232*8975f5c5SAndroid Build Coastguard Worker # We require that all source files are listed, even though this is 233*8975f5c5SAndroid Build Coastguard Worker # not a requirement for rustc. The reason is to ensure that tools 234*8975f5c5SAndroid Build Coastguard Worker # such as `gn deps` give the correct answer, and thus we trigger 235*8975f5c5SAndroid Build Coastguard Worker # the right test suites etc. on code change. 236*8975f5c5SAndroid Build Coastguard Worker # TODO(crbug.com/40200431) - verify this is correct 237*8975f5c5SAndroid Build Coastguard Worker assert(defined(invoker.sources), "sources must be listed") 238*8975f5c5SAndroid Build Coastguard Worker 239*8975f5c5SAndroid Build Coastguard Worker if (invoker.target_type == "rust_proc_macro" && 240*8975f5c5SAndroid Build Coastguard Worker !toolchain_for_rust_host_build_tools) { 241*8975f5c5SAndroid Build Coastguard Worker # Redirect to the proc macro toolchain, which uses prebuilt stdlib libraries 242*8975f5c5SAndroid Build Coastguard Worker # that are not built with panic=abort. 243*8975f5c5SAndroid Build Coastguard Worker group(_target_name) { 244*8975f5c5SAndroid Build Coastguard Worker testonly = _testonly 245*8975f5c5SAndroid Build Coastguard Worker if (defined(_visibility)) { 246*8975f5c5SAndroid Build Coastguard Worker visibility = _visibility 247*8975f5c5SAndroid Build Coastguard Worker } 248*8975f5c5SAndroid Build Coastguard Worker public_deps = 249*8975f5c5SAndroid Build Coastguard Worker [ ":${_target_name}${_main_target_suffix}($rust_macro_toolchain)" ] 250*8975f5c5SAndroid Build Coastguard Worker } 251*8975f5c5SAndroid Build Coastguard Worker 252*8975f5c5SAndroid Build Coastguard Worker not_needed(invoker, "*") 253*8975f5c5SAndroid Build Coastguard Worker not_needed([ 254*8975f5c5SAndroid Build Coastguard Worker "_aliased_deps", 255*8975f5c5SAndroid Build Coastguard Worker "_allow_unsafe", 256*8975f5c5SAndroid Build Coastguard Worker "_build_unit_tests", 257*8975f5c5SAndroid Build Coastguard Worker "_crate_root", 258*8975f5c5SAndroid Build Coastguard Worker "_crate_name", 259*8975f5c5SAndroid Build Coastguard Worker "_cxx_bindings", 260*8975f5c5SAndroid Build Coastguard Worker "_deps", 261*8975f5c5SAndroid Build Coastguard Worker "_rustc_metadata", 262*8975f5c5SAndroid Build Coastguard Worker "_out_dir", 263*8975f5c5SAndroid Build Coastguard Worker "_public_deps", 264*8975f5c5SAndroid Build Coastguard Worker "_rustenv", 265*8975f5c5SAndroid Build Coastguard Worker "_rustflags", 266*8975f5c5SAndroid Build Coastguard Worker "_support_use_from_cpp", 267*8975f5c5SAndroid Build Coastguard Worker "_testonly", 268*8975f5c5SAndroid Build Coastguard Worker ]) 269*8975f5c5SAndroid Build Coastguard Worker } else { 270*8975f5c5SAndroid Build Coastguard Worker # These are dependencies that must be included into the C++ target that 271*8975f5c5SAndroid Build Coastguard Worker # depends on this Rust one, and into the Rust target itself, respectively. 272*8975f5c5SAndroid Build Coastguard Worker # 273*8975f5c5SAndroid Build Coastguard Worker # For an rlib or exe, it's enough to add all these as dependencies of the 274*8975f5c5SAndroid Build Coastguard Worker # Rust target alone, and they will get included into the final link step. 275*8975f5c5SAndroid Build Coastguard Worker # 276*8975f5c5SAndroid Build Coastguard Worker # But when then Rust target is a shared library, the C++ target needs to 277*8975f5c5SAndroid Build Coastguard Worker # link the C++ thunks that are used to call the cxx bridge functions. And 278*8975f5c5SAndroid Build Coastguard Worker # Cxx library itself needs to be in both. 279*8975f5c5SAndroid Build Coastguard Worker _cxx_generated_deps_for_cpp = [] 280*8975f5c5SAndroid Build Coastguard Worker _cxx_generated_deps_for_rust = [] 281*8975f5c5SAndroid Build Coastguard Worker if (_cxx_bindings != []) { 282*8975f5c5SAndroid Build Coastguard Worker _cxx_generated_deps_for_cpp += [ 283*8975f5c5SAndroid Build Coastguard Worker # The Cxx-generated thunks, which have the public C++ names and bounce 284*8975f5c5SAndroid Build Coastguard Worker # over to the Rust code. 285*8975f5c5SAndroid Build Coastguard Worker ":${_target_name}_cxx_generated", 286*8975f5c5SAndroid Build Coastguard Worker 287*8975f5c5SAndroid Build Coastguard Worker # Additionally, C++ bindings generated by Cxx can include C++ types 288*8975f5c5SAndroid Build Coastguard Worker # that come from the Cxx library, such as `rust::Str`. The header and 289*8975f5c5SAndroid Build Coastguard Worker # implementation of these types are provided in the cxx_cppdeps target. 290*8975f5c5SAndroid Build Coastguard Worker # The C++ targets depending on this Rust target need the headers, while 291*8975f5c5SAndroid Build Coastguard Worker # the Rust target needs the implementation. 292*8975f5c5SAndroid Build Coastguard Worker "//build/rust:cxx_cppdeps", 293*8975f5c5SAndroid Build Coastguard Worker ] 294*8975f5c5SAndroid Build Coastguard Worker _cxx_generated_deps_for_rust = [ 295*8975f5c5SAndroid Build Coastguard Worker # The implementation of the Cxx library needs to be in the Rust target. 296*8975f5c5SAndroid Build Coastguard Worker "//build/rust:cxx_cppdeps", 297*8975f5c5SAndroid Build Coastguard Worker ] 298*8975f5c5SAndroid Build Coastguard Worker } 299*8975f5c5SAndroid Build Coastguard Worker 300*8975f5c5SAndroid Build Coastguard Worker # Proc macros and shared libraries have a group for the target name and 301*8975f5c5SAndroid Build Coastguard Worker # redirect to a suffixed target for the actual library. 302*8975f5c5SAndroid Build Coastguard Worker if (_main_target_suffix != "") { 303*8975f5c5SAndroid Build Coastguard Worker group(_target_name) { 304*8975f5c5SAndroid Build Coastguard Worker testonly = _testonly 305*8975f5c5SAndroid Build Coastguard Worker if (defined(_visibility)) { 306*8975f5c5SAndroid Build Coastguard Worker visibility = _visibility 307*8975f5c5SAndroid Build Coastguard Worker } 308*8975f5c5SAndroid Build Coastguard Worker public_deps = [ ":${_target_name}${_main_target_suffix}" ] 309*8975f5c5SAndroid Build Coastguard Worker public_deps += _cxx_generated_deps_for_cpp 310*8975f5c5SAndroid Build Coastguard Worker } 311*8975f5c5SAndroid Build Coastguard Worker } 312*8975f5c5SAndroid Build Coastguard Worker 313*8975f5c5SAndroid Build Coastguard Worker _rustc_metadata = "" 314*8975f5c5SAndroid Build Coastguard Worker if (defined(invoker.rustc_metadata)) { 315*8975f5c5SAndroid Build Coastguard Worker _rustc_metadata = invoker.rustc_metadata 316*8975f5c5SAndroid Build Coastguard Worker } 317*8975f5c5SAndroid Build Coastguard Worker 318*8975f5c5SAndroid Build Coastguard Worker _rust_deps = _deps 319*8975f5c5SAndroid Build Coastguard Worker _rust_aliased_deps = _aliased_deps 320*8975f5c5SAndroid Build Coastguard Worker _rust_public_deps = _public_deps 321*8975f5c5SAndroid Build Coastguard Worker _cxx_deps = _deps 322*8975f5c5SAndroid Build Coastguard Worker 323*8975f5c5SAndroid Build Coastguard Worker # Include the `chromium` crate in all first-party code. Third-party code 324*8975f5c5SAndroid Build Coastguard Worker # (and the `chromium` crate itself) opts out by setting 325*8975f5c5SAndroid Build Coastguard Worker # `no_chromium_prelude`. 326*8975f5c5SAndroid Build Coastguard Worker if (!defined(invoker.no_chromium_prelude) || !invoker.no_chromium_prelude) { 327*8975f5c5SAndroid Build Coastguard Worker if (enable_chromium_prelude) { 328*8975f5c5SAndroid Build Coastguard Worker _rust_deps += [ "//build/rust/chromium_prelude" ] 329*8975f5c5SAndroid Build Coastguard Worker } 330*8975f5c5SAndroid Build Coastguard Worker } 331*8975f5c5SAndroid Build Coastguard Worker 332*8975f5c5SAndroid Build Coastguard Worker if (_cxx_bindings != []) { 333*8975f5c5SAndroid Build Coastguard Worker # The Rust target (and unit tests) need the Cxx crate when using it to 334*8975f5c5SAndroid Build Coastguard Worker # generate bindings. 335*8975f5c5SAndroid Build Coastguard Worker _rust_deps += [ "//build/rust:cxx_rustdeps" ] 336*8975f5c5SAndroid Build Coastguard Worker } 337*8975f5c5SAndroid Build Coastguard Worker 338*8975f5c5SAndroid Build Coastguard Worker if (!defined(invoker.no_std) || !invoker.no_std) { 339*8975f5c5SAndroid Build Coastguard Worker _rust_deps += [ "//build/rust/std" ] 340*8975f5c5SAndroid Build Coastguard Worker } 341*8975f5c5SAndroid Build Coastguard Worker 342*8975f5c5SAndroid Build Coastguard Worker if (_build_unit_tests) { 343*8975f5c5SAndroid Build Coastguard Worker _unit_test_target = "${_target_name}_unittests" 344*8975f5c5SAndroid Build Coastguard Worker if (defined(invoker.unit_test_target)) { 345*8975f5c5SAndroid Build Coastguard Worker _unit_test_target = invoker.unit_test_target 346*8975f5c5SAndroid Build Coastguard Worker } 347*8975f5c5SAndroid Build Coastguard Worker 348*8975f5c5SAndroid Build Coastguard Worker rust_unit_test(_unit_test_target) { 349*8975f5c5SAndroid Build Coastguard Worker testonly = true 350*8975f5c5SAndroid Build Coastguard Worker crate_name = _unit_test_target 351*8975f5c5SAndroid Build Coastguard Worker crate_root = _crate_root 352*8975f5c5SAndroid Build Coastguard Worker sources = invoker.sources + [ crate_root ] 353*8975f5c5SAndroid Build Coastguard Worker rustflags = _rustflags 354*8975f5c5SAndroid Build Coastguard Worker env_out_dir = _env_out_dir 355*8975f5c5SAndroid Build Coastguard Worker if (defined(invoker.unit_test_output_dir)) { 356*8975f5c5SAndroid Build Coastguard Worker output_dir = invoker.unit_test_output_dir 357*8975f5c5SAndroid Build Coastguard Worker } 358*8975f5c5SAndroid Build Coastguard Worker deps = _rust_deps + _public_deps 359*8975f5c5SAndroid Build Coastguard Worker aliased_deps = _rust_aliased_deps 360*8975f5c5SAndroid Build Coastguard Worker public_deps = [ ":${_target_name}" ] 361*8975f5c5SAndroid Build Coastguard Worker if (defined(invoker.test_deps)) { 362*8975f5c5SAndroid Build Coastguard Worker deps += invoker.test_deps 363*8975f5c5SAndroid Build Coastguard Worker } 364*8975f5c5SAndroid Build Coastguard Worker inputs = [] 365*8975f5c5SAndroid Build Coastguard Worker if (defined(invoker.inputs)) { 366*8975f5c5SAndroid Build Coastguard Worker inputs += invoker.inputs 367*8975f5c5SAndroid Build Coastguard Worker } 368*8975f5c5SAndroid Build Coastguard Worker if (defined(_bindgen_inputs)) { 369*8975f5c5SAndroid Build Coastguard Worker inputs += _bindgen_inputs 370*8975f5c5SAndroid Build Coastguard Worker } 371*8975f5c5SAndroid Build Coastguard Worker if (defined(invoker.test_inputs)) { 372*8975f5c5SAndroid Build Coastguard Worker inputs += invoker.test_inputs 373*8975f5c5SAndroid Build Coastguard Worker } 374*8975f5c5SAndroid Build Coastguard Worker if (defined(invoker.executable_configs)) { 375*8975f5c5SAndroid Build Coastguard Worker configs = [] 376*8975f5c5SAndroid Build Coastguard Worker configs += invoker.executable_configs 377*8975f5c5SAndroid Build Coastguard Worker } 378*8975f5c5SAndroid Build Coastguard Worker configs += _test_configs 379*8975f5c5SAndroid Build Coastguard Worker rustenv = _rustenv 380*8975f5c5SAndroid Build Coastguard Worker 381*8975f5c5SAndroid Build Coastguard Worker if (!_allow_unsafe) { 382*8975f5c5SAndroid Build Coastguard Worker configs += [ "//build/rust:forbid_unsafe" ] 383*8975f5c5SAndroid Build Coastguard Worker } 384*8975f5c5SAndroid Build Coastguard Worker } 385*8975f5c5SAndroid Build Coastguard Worker } else { 386*8975f5c5SAndroid Build Coastguard Worker not_needed([ 387*8975f5c5SAndroid Build Coastguard Worker "_crate_root", 388*8975f5c5SAndroid Build Coastguard Worker "_crate_name", 389*8975f5c5SAndroid Build Coastguard Worker "_rustc_metadata", 390*8975f5c5SAndroid Build Coastguard Worker "_test_configs", 391*8975f5c5SAndroid Build Coastguard Worker ]) 392*8975f5c5SAndroid Build Coastguard Worker not_needed(invoker, [ "executable_configs" ]) 393*8975f5c5SAndroid Build Coastguard Worker } 394*8975f5c5SAndroid Build Coastguard Worker 395*8975f5c5SAndroid Build Coastguard Worker target(invoker.target_type, "${_target_name}${_main_target_suffix}") { 396*8975f5c5SAndroid Build Coastguard Worker forward_variables_from(invoker, 397*8975f5c5SAndroid Build Coastguard Worker "*", 398*8975f5c5SAndroid Build Coastguard Worker TESTONLY_AND_VISIBILITY + [ 399*8975f5c5SAndroid Build Coastguard Worker "features", 400*8975f5c5SAndroid Build Coastguard Worker "deps", 401*8975f5c5SAndroid Build Coastguard Worker "aliased_deps", 402*8975f5c5SAndroid Build Coastguard Worker "public_deps", 403*8975f5c5SAndroid Build Coastguard Worker "rustflags", 404*8975f5c5SAndroid Build Coastguard Worker "rustenv", 405*8975f5c5SAndroid Build Coastguard Worker "configs", 406*8975f5c5SAndroid Build Coastguard Worker "unit_test_output_dir", 407*8975f5c5SAndroid Build Coastguard Worker "unit_test_target", 408*8975f5c5SAndroid Build Coastguard Worker "test_inputs", 409*8975f5c5SAndroid Build Coastguard Worker ]) 410*8975f5c5SAndroid Build Coastguard Worker 411*8975f5c5SAndroid Build Coastguard Worker if (_main_target_suffix != "") { 412*8975f5c5SAndroid Build Coastguard Worker # There's a group that depends on this target, and dependencies must 413*8975f5c5SAndroid Build Coastguard Worker # be through that group. 414*8975f5c5SAndroid Build Coastguard Worker visibility = [ ":$_target_name" ] 415*8975f5c5SAndroid Build Coastguard Worker not_needed([ "_visibility" ]) 416*8975f5c5SAndroid Build Coastguard Worker } else if (defined(_visibility)) { 417*8975f5c5SAndroid Build Coastguard Worker visibility = _visibility 418*8975f5c5SAndroid Build Coastguard Worker } 419*8975f5c5SAndroid Build Coastguard Worker 420*8975f5c5SAndroid Build Coastguard Worker testonly = _testonly 421*8975f5c5SAndroid Build Coastguard Worker crate_name = _crate_name 422*8975f5c5SAndroid Build Coastguard Worker crate_root = _crate_root 423*8975f5c5SAndroid Build Coastguard Worker configs = [] 424*8975f5c5SAndroid Build Coastguard Worker configs = _configs 425*8975f5c5SAndroid Build Coastguard Worker deps = _rust_deps + _cxx_generated_deps_for_rust 426*8975f5c5SAndroid Build Coastguard Worker aliased_deps = _rust_aliased_deps 427*8975f5c5SAndroid Build Coastguard Worker public_deps = _rust_public_deps 428*8975f5c5SAndroid Build Coastguard Worker if (_main_target_suffix == "") { 429*8975f5c5SAndroid Build Coastguard Worker # When these are not provided by a wrapper group target, they are added 430*8975f5c5SAndroid Build Coastguard Worker # to the Rust target itself. 431*8975f5c5SAndroid Build Coastguard Worker public_deps += _cxx_generated_deps_for_cpp 432*8975f5c5SAndroid Build Coastguard Worker } 433*8975f5c5SAndroid Build Coastguard Worker rustflags = _rustflags 434*8975f5c5SAndroid Build Coastguard Worker if (_rustc_metadata != "") { 435*8975f5c5SAndroid Build Coastguard Worker rustflags += [ "-Cmetadata=${_rustc_metadata}" ] 436*8975f5c5SAndroid Build Coastguard Worker } 437*8975f5c5SAndroid Build Coastguard Worker rustenv = _rustenv 438*8975f5c5SAndroid Build Coastguard Worker 439*8975f5c5SAndroid Build Coastguard Worker if (_generate_crate_root) { 440*8975f5c5SAndroid Build Coastguard Worker deps += [ ":${_target_name}_crate_root" ] 441*8975f5c5SAndroid Build Coastguard Worker sources += [ _crate_root ] 442*8975f5c5SAndroid Build Coastguard Worker } 443*8975f5c5SAndroid Build Coastguard Worker 444*8975f5c5SAndroid Build Coastguard Worker if (!defined(inputs)) { 445*8975f5c5SAndroid Build Coastguard Worker inputs = [] 446*8975f5c5SAndroid Build Coastguard Worker } 447*8975f5c5SAndroid Build Coastguard Worker 448*8975f5c5SAndroid Build Coastguard Worker if (defined(_bindgen_inputs)) { 449*8975f5c5SAndroid Build Coastguard Worker inputs += _bindgen_inputs 450*8975f5c5SAndroid Build Coastguard Worker } 451*8975f5c5SAndroid Build Coastguard Worker 452*8975f5c5SAndroid Build Coastguard Worker if (!defined(output_name)) { 453*8975f5c5SAndroid Build Coastguard Worker # Note that file names of libraries must start with the crate name in 454*8975f5c5SAndroid Build Coastguard Worker # order for the compiler to find transitive dependencies in the 455*8975f5c5SAndroid Build Coastguard Worker # directory search paths (since they are not all explicitly specified). 456*8975f5c5SAndroid Build Coastguard Worker # 457*8975f5c5SAndroid Build Coastguard Worker # For bin targets, we expect the target name to be unique, and the name 458*8975f5c5SAndroid Build Coastguard Worker # of the exe should not add magic stuff to it. And bin crates can not be 459*8975f5c5SAndroid Build Coastguard Worker # transitive dependencies. 460*8975f5c5SAndroid Build Coastguard Worker if (invoker.target_type == "executable") { 461*8975f5c5SAndroid Build Coastguard Worker output_name = _target_name 462*8975f5c5SAndroid Build Coastguard Worker } else { 463*8975f5c5SAndroid Build Coastguard Worker # TODO(danakj): Since the crate name includes the whole path for 1p 464*8975f5c5SAndroid Build Coastguard Worker # libraries, we could move the output_dir to `root_out_dir` here for 465*8975f5c5SAndroid Build Coastguard Worker # them, which would make for shorter file paths. But we need to not 466*8975f5c5SAndroid Build Coastguard Worker # do the same for 3p crates or those with a `crate_name` set 467*8975f5c5SAndroid Build Coastguard Worker # explicitly. 468*8975f5c5SAndroid Build Coastguard Worker output_name = _crate_name 469*8975f5c5SAndroid Build Coastguard Worker } 470*8975f5c5SAndroid Build Coastguard Worker } 471*8975f5c5SAndroid Build Coastguard Worker 472*8975f5c5SAndroid Build Coastguard Worker if (!_allow_unsafe) { 473*8975f5c5SAndroid Build Coastguard Worker configs += [ "//build/rust:forbid_unsafe" ] 474*8975f5c5SAndroid Build Coastguard Worker } 475*8975f5c5SAndroid Build Coastguard Worker } 476*8975f5c5SAndroid Build Coastguard Worker 477*8975f5c5SAndroid Build Coastguard Worker if (_cxx_bindings != []) { 478*8975f5c5SAndroid Build Coastguard Worker rust_cxx("${_target_name}_cxx_generated") { 479*8975f5c5SAndroid Build Coastguard Worker testonly = _testonly 480*8975f5c5SAndroid Build Coastguard Worker visibility = [ ":${_target_name}" ] 481*8975f5c5SAndroid Build Coastguard Worker if (defined(_visibility)) { 482*8975f5c5SAndroid Build Coastguard Worker visibility += _visibility 483*8975f5c5SAndroid Build Coastguard Worker } 484*8975f5c5SAndroid Build Coastguard Worker sources = _cxx_bindings 485*8975f5c5SAndroid Build Coastguard Worker deps = _cxx_deps + _public_deps 486*8975f5c5SAndroid Build Coastguard Worker configs = _configs 487*8975f5c5SAndroid Build Coastguard Worker 488*8975f5c5SAndroid Build Coastguard Worker # In a component_build the cxx bindings may be linked into a shared 489*8975f5c5SAndroid Build Coastguard Worker # library at any point up the dependency tree, so always export. 490*8975f5c5SAndroid Build Coastguard Worker export_symbols = is_component_build 491*8975f5c5SAndroid Build Coastguard Worker } 492*8975f5c5SAndroid Build Coastguard Worker } else { 493*8975f5c5SAndroid Build Coastguard Worker not_needed([ "_cxx_deps" ]) 494*8975f5c5SAndroid Build Coastguard Worker } 495*8975f5c5SAndroid Build Coastguard Worker } 496*8975f5c5SAndroid Build Coastguard Worker} 497