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/rust/rust_target.gni") 6*8975f5c5SAndroid Build Coastguard Worker 7*8975f5c5SAndroid Build Coastguard Worker# Defines a Rust static library which can be used by downstream Rust or C++ 8*8975f5c5SAndroid Build Coastguard Worker# targets. This is a single Rust compilation unit consisting of potentially 9*8975f5c5SAndroid Build Coastguard Worker# multiple .rs files. 10*8975f5c5SAndroid Build Coastguard Worker# 11*8975f5c5SAndroid Build Coastguard Worker# We term this 'rust_static_library' because it is used most analogously 12*8975f5c5SAndroid Build Coastguard Worker# to a C++ 'static_library' in Chromium. Like the C++ one, it can be compiled 13*8975f5c5SAndroid Build Coastguard Worker# independently into an intermediate linking target. The output contains the 14*8975f5c5SAndroid Build Coastguard Worker# object file(s) of the GN target's sources, and not its dependencies. 15*8975f5c5SAndroid Build Coastguard Worker# 16*8975f5c5SAndroid Build Coastguard Worker# Parameters 17*8975f5c5SAndroid Build Coastguard Worker# 18*8975f5c5SAndroid Build Coastguard Worker# sources 19*8975f5c5SAndroid Build Coastguard Worker# List of source files which this crate is allowed to compile, which is 20*8975f5c5SAndroid Build Coastguard Worker# used to determine the impact of source code changes on other GN targets. 21*8975f5c5SAndroid Build Coastguard Worker# This is not used by the Rust compiler, as it discovers source files by 22*8975f5c5SAndroid Build Coastguard Worker# following `mod` declarations starting at the `crate_root`. The 23*8975f5c5SAndroid Build Coastguard Worker# discovered source files must match this list. (This is not yet enforced, 24*8975f5c5SAndroid Build Coastguard Worker# but will be.) 25*8975f5c5SAndroid Build Coastguard Worker# 26*8975f5c5SAndroid Build Coastguard Worker# edition (optional) 27*8975f5c5SAndroid Build Coastguard Worker# Edition of the Rust language to be used. 28*8975f5c5SAndroid Build Coastguard Worker# Options are "2015", "2018" and "2021". Defaults to "2021". 29*8975f5c5SAndroid Build Coastguard Worker# 30*8975f5c5SAndroid Build Coastguard Worker# allow_unsafe (optional) 31*8975f5c5SAndroid Build Coastguard Worker# Set to true to allow unsafe code in this target. Defaults to false. 32*8975f5c5SAndroid Build Coastguard Worker# 33*8975f5c5SAndroid Build Coastguard Worker# configs (optional) 34*8975f5c5SAndroid Build Coastguard Worker# A list of config labels (in the GN meaning) applying to this target. 35*8975f5c5SAndroid Build Coastguard Worker# 36*8975f5c5SAndroid Build Coastguard Worker# rustflags (optional) 37*8975f5c5SAndroid Build Coastguard Worker# Explicit flags for rustc command line. (Use 'edition' or 'features' 38*8975f5c5SAndroid Build Coastguard Worker# where possible). 39*8975f5c5SAndroid Build Coastguard Worker# 40*8975f5c5SAndroid Build Coastguard Worker# deps (optional) 41*8975f5c5SAndroid Build Coastguard Worker# List of GN targets on which this crate depends. These may be Rust 42*8975f5c5SAndroid Build Coastguard Worker# or non-Rust targets. 43*8975f5c5SAndroid Build Coastguard Worker# 44*8975f5c5SAndroid Build Coastguard Worker# public_deps (optional) 45*8975f5c5SAndroid Build Coastguard Worker# List of GN targets on which this crate depends, and which are exported 46*8975f5c5SAndroid Build Coastguard Worker# into the dependency list of any crate that depends on it. Dependency 47*8975f5c5SAndroid Build Coastguard Worker# crates that appear in the public API should be included here. 48*8975f5c5SAndroid Build Coastguard Worker# 49*8975f5c5SAndroid Build Coastguard Worker# test_deps (optional) 50*8975f5c5SAndroid Build Coastguard Worker# List of GN targets on which this crate's tests depend, in addition 51*8975f5c5SAndroid Build Coastguard Worker# to deps. 52*8975f5c5SAndroid Build Coastguard Worker# 53*8975f5c5SAndroid Build Coastguard Worker# is_gtest_unittests (optional) 54*8975f5c5SAndroid Build Coastguard Worker# Should only be set to true for rlibs of gtest unit tests. This ensures 55*8975f5c5SAndroid Build Coastguard Worker# all objects in the rlib are linked into the final target, rather than 56*8975f5c5SAndroid Build Coastguard Worker# pruning dead code, so that the tests themselves are not discarded by the 57*8975f5c5SAndroid Build Coastguard Worker# linker. 58*8975f5c5SAndroid Build Coastguard Worker# 59*8975f5c5SAndroid Build Coastguard Worker# mutually_dependent_target (optional) 60*8975f5c5SAndroid Build Coastguard Worker# mutually_dependent_public_deps (optional) 61*8975f5c5SAndroid Build Coastguard Worker# These is for use by the mixed_target() template. 62*8975f5c5SAndroid Build Coastguard Worker# 63*8975f5c5SAndroid Build Coastguard Worker# If this Rust code is intrinsically paired with some C/C++ code, 64*8975f5c5SAndroid Build Coastguard Worker# with bidirectional calls between the two, then this would 65*8975f5c5SAndroid Build Coastguard Worker# be a circular dependency. GN does not allow circular dependencies, 66*8975f5c5SAndroid Build Coastguard Worker# (other than for header files per allow_circular_includes_from). 67*8975f5c5SAndroid Build Coastguard Worker# But this is common for a 'component' which has both Rust and C++ 68*8975f5c5SAndroid Build Coastguard Worker# code. You should structure things such that the C++ code depends 69*8975f5c5SAndroid Build Coastguard Worker# on the Rust code in the normal way: 70*8975f5c5SAndroid Build Coastguard Worker# static_library("cpp_stuff") { 71*8975f5c5SAndroid Build Coastguard Worker# deps = [ "rust_stuff" ] 72*8975f5c5SAndroid Build Coastguard Worker# # .. 73*8975f5c5SAndroid Build Coastguard Worker# } 74*8975f5c5SAndroid Build Coastguard Worker# but that the Rust target also notes the C++ target using this 75*8975f5c5SAndroid Build Coastguard Worker# 'mutually_dependent_target' parameter. 76*8975f5c5SAndroid Build Coastguard Worker# rust_static_library("rust_stuff") { 77*8975f5c5SAndroid Build Coastguard Worker# mutually_dependent_target = "cpp_stuff" 78*8975f5c5SAndroid Build Coastguard Worker# mutually_dependent_public_deps = _cpp_stuff_public_deps 79*8975f5c5SAndroid Build Coastguard Worker# # .. 80*8975f5c5SAndroid Build Coastguard Worker# } 81*8975f5c5SAndroid Build Coastguard Worker# 82*8975f5c5SAndroid Build Coastguard Worker# This causes the Rust unit tests, if generated, to depend on the mutually 83*8975f5c5SAndroid Build Coastguard Worker# dependent target, since depending on the Rust code only would be 84*8975f5c5SAndroid Build Coastguard Worker# insufficient. And it allows any C++ bindings generated from the Rust code 85*8975f5c5SAndroid Build Coastguard Worker# to include headers from the mutually_dependent_target by depending on its 86*8975f5c5SAndroid Build Coastguard Worker# public_deps. 87*8975f5c5SAndroid Build Coastguard Worker# 88*8975f5c5SAndroid Build Coastguard Worker# build_native_rust_unit_tests (optional) 89*8975f5c5SAndroid Build Coastguard Worker# Builds native unit tests (under #[cfg(test)]) written inside the Rust 90*8975f5c5SAndroid Build Coastguard Worker# crate. This will create a `<name>_unittests` executable in the output 91*8975f5c5SAndroid Build Coastguard Worker# directory when set to true. 92*8975f5c5SAndroid Build Coastguard Worker# 93*8975f5c5SAndroid Build Coastguard Worker# unit_test_target (optional) 94*8975f5c5SAndroid Build Coastguard Worker# Overrides the default name for the unit tests target 95*8975f5c5SAndroid Build Coastguard Worker# 96*8975f5c5SAndroid Build Coastguard Worker# crate_root (optional) 97*8975f5c5SAndroid Build Coastguard Worker# Location of the crate root. 98*8975f5c5SAndroid Build Coastguard Worker# This defaults to `./src/lib.rs` and should only be changed when 99*8975f5c5SAndroid Build Coastguard Worker# absolutely necessary (such as in the case of generated code). 100*8975f5c5SAndroid Build Coastguard Worker# 101*8975f5c5SAndroid Build Coastguard Worker# features (optional) 102*8975f5c5SAndroid Build Coastguard Worker# A list of conditional compilation flags to enable. This can be used 103*8975f5c5SAndroid Build Coastguard Worker# to set features for crates built in-tree which are also published to 104*8975f5c5SAndroid Build Coastguard Worker# crates.io. Each feature in the list will be passed to rustc as 105*8975f5c5SAndroid Build Coastguard Worker# '--cfg feature=XXX' 106*8975f5c5SAndroid Build Coastguard Worker# 107*8975f5c5SAndroid Build Coastguard Worker# cxx_bindings (optional) 108*8975f5c5SAndroid Build Coastguard Worker# A list of Rust files which contain #[cxx::bridge] mods and should 109*8975f5c5SAndroid Build Coastguard Worker# therefore have C++ bindings generated. See https://cxx.rs. 110*8975f5c5SAndroid Build Coastguard Worker# This will automatically add appropriate dependencies: there's no 111*8975f5c5SAndroid Build Coastguard Worker# need to depend on the cxx crate or any generated bindings. 112*8975f5c5SAndroid Build Coastguard Worker# 113*8975f5c5SAndroid Build Coastguard Worker# data, testonly, visibility (optional) 114*8975f5c5SAndroid Build Coastguard Worker# Same meaning as in other GN targets. 115*8975f5c5SAndroid Build Coastguard Worker# 116*8975f5c5SAndroid Build Coastguard Worker# crate_name (optional) 117*8975f5c5SAndroid Build Coastguard Worker# Discouraged - first-party code should prefer to use the auto-generated, 118*8975f5c5SAndroid Build Coastguard Worker# target-based crate name which is guaranteed to be globally unique (and 119*8975f5c5SAndroid Build Coastguard Worker# still ergonomic to import and use via the `chromium::import!` macro). 120*8975f5c5SAndroid Build Coastguard Worker# 121*8975f5c5SAndroid Build Coastguard Worker# inputs (optional) 122*8975f5c5SAndroid Build Coastguard Worker# Additional input files needed for compilation (such as `include!`ed files) 123*8975f5c5SAndroid Build Coastguard Worker# 124*8975f5c5SAndroid Build Coastguard Worker# test_inputs (optional) 125*8975f5c5SAndroid Build Coastguard Worker# Same as above but for the unit tests target 126*8975f5c5SAndroid Build Coastguard Worker# 127*8975f5c5SAndroid Build Coastguard Worker# rustc_metadata (optional) 128*8975f5c5SAndroid Build Coastguard Worker# Override the metadata identifying the target's version. This allows e.g. 129*8975f5c5SAndroid Build Coastguard Worker# linking otherwise conflicting versions of the same Rust library. The 130*8975f5c5SAndroid Build Coastguard Worker# metadata string will also be appended to the output library names. 131*8975f5c5SAndroid Build Coastguard Worker# Should be used sparingly, since generally we should have one version and 132*8975f5c5SAndroid Build Coastguard Worker# build of each target. 133*8975f5c5SAndroid Build Coastguard Worker# 134*8975f5c5SAndroid Build Coastguard Worker# Example of usage: 135*8975f5c5SAndroid Build Coastguard Worker# 136*8975f5c5SAndroid Build Coastguard Worker# rust_static_library("foo_bar") { 137*8975f5c5SAndroid Build Coastguard Worker# deps = [ 138*8975f5c5SAndroid Build Coastguard Worker# "//boo/public/rust/bar", 139*8975f5c5SAndroid Build Coastguard Worker# "//third_party/rust/crates:argh", 140*8975f5c5SAndroid Build Coastguard Worker# "//third_party/rust/crates:serde", 141*8975f5c5SAndroid Build Coastguard Worker# "//third_party/rust/crates:slab", 142*8975f5c5SAndroid Build Coastguard Worker# ] 143*8975f5c5SAndroid Build Coastguard Worker# sources = [ "src/lib.rs" ] 144*8975f5c5SAndroid Build Coastguard Worker# } 145*8975f5c5SAndroid Build Coastguard Worker# 146*8975f5c5SAndroid Build Coastguard Worker# This template is intended to serve the same purpose as 'rustc_library' 147*8975f5c5SAndroid Build Coastguard Worker# in Fuchsia. 148*8975f5c5SAndroid Build Coastguard Workertemplate("rust_static_library") { 149*8975f5c5SAndroid Build Coastguard Worker _target_name = target_name 150*8975f5c5SAndroid Build Coastguard Worker 151*8975f5c5SAndroid Build Coastguard Worker _configs = [] 152*8975f5c5SAndroid Build Coastguard Worker _all_dependent_configs = [] 153*8975f5c5SAndroid Build Coastguard Worker 154*8975f5c5SAndroid Build Coastguard Worker if (defined(invoker.configs)) { 155*8975f5c5SAndroid Build Coastguard Worker _configs += invoker.configs 156*8975f5c5SAndroid Build Coastguard Worker } 157*8975f5c5SAndroid Build Coastguard Worker 158*8975f5c5SAndroid Build Coastguard Worker # TODO(dcheng): Is there any value in allowing rust_shared_library() to also 159*8975f5c5SAndroid Build Coastguard Worker # set `is_gtest_unittest` to true? 160*8975f5c5SAndroid Build Coastguard Worker if (defined(invoker.is_gtest_unittests) && invoker.is_gtest_unittests) { 161*8975f5c5SAndroid Build Coastguard Worker _output_dir = rebase_path(target_out_dir, root_build_dir) 162*8975f5c5SAndroid Build Coastguard Worker 163*8975f5c5SAndroid Build Coastguard Worker config("${_target_name}_alwayslink") { 164*8975f5c5SAndroid Build Coastguard Worker # Targets using the #[gtest(...)] proc macro register their tests with 165*8975f5c5SAndroid Build Coastguard Worker # static initializers. A rust library target generates a .rlib, which is 166*8975f5c5SAndroid Build Coastguard Worker # a regular static library with extra metadata. However, if nothing 167*8975f5c5SAndroid Build Coastguard Worker # outside the .rlib references functions in the .rlib—as is often the 168*8975f5c5SAndroid Build Coastguard Worker # case with a target containing only tests—the linker will not pull in 169*8975f5c5SAndroid Build Coastguard Worker # the .rlib into the final test binary at all, so the tests won't run. 170*8975f5c5SAndroid Build Coastguard Worker # 171*8975f5c5SAndroid Build Coastguard Worker # C++ works around this by using source sets and directly pass the .o 172*8975f5c5SAndroid Build Coastguard Worker # files to the linker, but Rust does not have a parallel to this. Instead, 173*8975f5c5SAndroid Build Coastguard Worker # force the linker to always include the whole archive. 174*8975f5c5SAndroid Build Coastguard Worker 175*8975f5c5SAndroid Build Coastguard Worker # NOTE: TargetName=>CrateName mangling algorithm should be updated 176*8975f5c5SAndroid Build Coastguard Worker # simultaneously in 3 places: here, //build/rust/rust_target.gni, 177*8975f5c5SAndroid Build Coastguard Worker # //build/rust/chromium_prelude/import_attribute.rs 178*8975f5c5SAndroid Build Coastguard Worker if (defined(invoker.crate_name)) { 179*8975f5c5SAndroid Build Coastguard Worker _crate_name = invoker.crate_name 180*8975f5c5SAndroid Build Coastguard Worker } else { 181*8975f5c5SAndroid Build Coastguard Worker # Not using `get_label_info(..., "label_no_toolchain")` to consistently 182*8975f5c5SAndroid Build Coastguard Worker # use `//foo/bar:baz` instead of the alternative shorter `//foo/bar` form. 183*8975f5c5SAndroid Build Coastguard Worker _dir = get_label_info(":${_target_name}", "dir") 184*8975f5c5SAndroid Build Coastguard Worker _dir = string_replace(_dir, "//", "") 185*8975f5c5SAndroid Build Coastguard Worker _crate_name = "${_dir}:${_target_name}" 186*8975f5c5SAndroid Build Coastguard Worker 187*8975f5c5SAndroid Build Coastguard Worker # The `string_replace` calls below replicate the escaping algorithm 188*8975f5c5SAndroid Build Coastguard Worker # from the `escape_non_identifier_chars` function in 189*8975f5c5SAndroid Build Coastguard Worker # //build/rust/chromium_prelude/import_attribute.rs. Note that the 190*8975f5c5SAndroid Build Coastguard Worker # ordering of `match` branches within the Rust function doesn't matter, 191*8975f5c5SAndroid Build Coastguard Worker # but the ordering of `string_replace` calls *does* matter - the escape 192*8975f5c5SAndroid Build Coastguard Worker # character `_` needs to be handled first to meet the injectivity 193*8975f5c5SAndroid Build Coastguard Worker # requirement (otherwise we would get `/` => `_s` => `_us` and the same 194*8975f5c5SAndroid Build Coastguard Worker # result for `_s` => `_us`). 195*8975f5c5SAndroid Build Coastguard Worker _crate_name = string_replace(_crate_name, "_", "_u") 196*8975f5c5SAndroid Build Coastguard Worker _crate_name = string_replace(_crate_name, "/", "_s") 197*8975f5c5SAndroid Build Coastguard Worker _crate_name = string_replace(_crate_name, ":", "_c") 198*8975f5c5SAndroid Build Coastguard Worker _crate_name = string_replace(_crate_name, "-", "_d") 199*8975f5c5SAndroid Build Coastguard Worker } 200*8975f5c5SAndroid Build Coastguard Worker 201*8975f5c5SAndroid Build Coastguard Worker _rlib_path = "${_output_dir}/lib${_crate_name}.rlib" 202*8975f5c5SAndroid Build Coastguard Worker if (current_os == "aix") { 203*8975f5c5SAndroid Build Coastguard Worker # The AIX linker does not implement an option for this. 204*8975f5c5SAndroid Build Coastguard Worker } else if (is_win) { 205*8975f5c5SAndroid Build Coastguard Worker ldflags = [ "/WHOLEARCHIVE:${_rlib_path}" ] 206*8975f5c5SAndroid Build Coastguard Worker } else { 207*8975f5c5SAndroid Build Coastguard Worker ldflags = [ "-LinkWrapper,add-whole-archive=${_rlib_path}" ] 208*8975f5c5SAndroid Build Coastguard Worker } 209*8975f5c5SAndroid Build Coastguard Worker } 210*8975f5c5SAndroid Build Coastguard Worker _all_dependent_configs += [ ":${target_name}_alwayslink" ] 211*8975f5c5SAndroid Build Coastguard Worker _configs += [ "//build/rust:is_gtest_unittests" ] 212*8975f5c5SAndroid Build Coastguard Worker } 213*8975f5c5SAndroid Build Coastguard Worker 214*8975f5c5SAndroid Build Coastguard Worker rust_target(_target_name) { 215*8975f5c5SAndroid Build Coastguard Worker forward_variables_from(invoker, 216*8975f5c5SAndroid Build Coastguard Worker "*", 217*8975f5c5SAndroid Build Coastguard Worker TESTONLY_AND_VISIBILITY + [ "configs" ]) 218*8975f5c5SAndroid Build Coastguard Worker forward_variables_from(invoker, TESTONLY_AND_VISIBILITY) 219*8975f5c5SAndroid Build Coastguard Worker library_configs = _configs 220*8975f5c5SAndroid Build Coastguard Worker all_dependent_configs = _all_dependent_configs 221*8975f5c5SAndroid Build Coastguard Worker target_type = "rust_library" 222*8975f5c5SAndroid Build Coastguard Worker } 223*8975f5c5SAndroid Build Coastguard Worker} 224*8975f5c5SAndroid Build Coastguard Worker 225*8975f5c5SAndroid Build Coastguard Workerset_defaults("rust_static_library") { 226*8975f5c5SAndroid Build Coastguard Worker configs = default_compiler_configs 227*8975f5c5SAndroid Build Coastguard Worker} 228