xref: /aosp_15_r20/external/angle/build/rust/rust_static_library.gni (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
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