xref: /aosp_15_r20/external/cronet/build/rust/cargo_crate.gni (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker# Copyright 2021 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker# Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker# found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker
5*6777b538SAndroid Build Coastguard Workerimport("//build/rust/rust_executable.gni")
6*6777b538SAndroid Build Coastguard Workerimport("//build/rust/rust_macro.gni")
7*6777b538SAndroid Build Coastguard Workerimport("//build/rust/rust_static_library.gni")
8*6777b538SAndroid Build Coastguard Worker
9*6777b538SAndroid Build Coastguard Worker# This template allows for building Cargo crates within gn.
10*6777b538SAndroid Build Coastguard Worker#
11*6777b538SAndroid Build Coastguard Worker# It is intended for use with pre-existing (third party) code and
12*6777b538SAndroid Build Coastguard Worker# is none too efficient. (It will stall the build pipeline whilst
13*6777b538SAndroid Build Coastguard Worker# it runs build scripts to work out what flags are needed). First
14*6777b538SAndroid Build Coastguard Worker# party code should directly use first-class gn targets, such as
15*6777b538SAndroid Build Coastguard Worker# //build/rust/rust_static_library.gni or similar.
16*6777b538SAndroid Build Coastguard Worker#
17*6777b538SAndroid Build Coastguard Worker# Because it's intended for third-party code, it automatically
18*6777b538SAndroid Build Coastguard Worker# defaults to //build/config/compiler:no_chromium_code which
19*6777b538SAndroid Build Coastguard Worker# suppresses some warnings. If you *do* use this for first party
20*6777b538SAndroid Build Coastguard Worker# code, you should remove that config and add the equivalent
21*6777b538SAndroid Build Coastguard Worker# //build/config/compiler:chromium_code config.
22*6777b538SAndroid Build Coastguard Worker#
23*6777b538SAndroid Build Coastguard Worker# Arguments:
24*6777b538SAndroid Build Coastguard Worker#  sources
25*6777b538SAndroid Build Coastguard Worker#  crate_root
26*6777b538SAndroid Build Coastguard Worker#  deps
27*6777b538SAndroid Build Coastguard Worker#  aliased_deps
28*6777b538SAndroid Build Coastguard Worker#  features
29*6777b538SAndroid Build Coastguard Worker#  build_native_rust_unit_tests
30*6777b538SAndroid Build Coastguard Worker#  edition
31*6777b538SAndroid Build Coastguard Worker#  crate_name
32*6777b538SAndroid Build Coastguard Worker#    All just as in rust_static_library.gni
33*6777b538SAndroid Build Coastguard Worker#  library_configs/executable_configs
34*6777b538SAndroid Build Coastguard Worker#    All just as in rust_target.gni
35*6777b538SAndroid Build Coastguard Worker#
36*6777b538SAndroid Build Coastguard Worker#  epoch (optional)
37*6777b538SAndroid Build Coastguard Worker#    The major version of the library, which is used to differentiate between
38*6777b538SAndroid Build Coastguard Worker#    multiple versions of the same library name. This includes all leading 0s
39*6777b538SAndroid Build Coastguard Worker#    and the first non-zero value in the crate's version. This should be left
40*6777b538SAndroid Build Coastguard Worker#    as the default, which is "0", for first-party code unless there are
41*6777b538SAndroid Build Coastguard Worker#    multiple versions of a crate present. For third-party code, the version
42*6777b538SAndroid Build Coastguard Worker#    epoch (matching the directory it is found in) should be specified.
43*6777b538SAndroid Build Coastguard Worker#
44*6777b538SAndroid Build Coastguard Worker#    Examples:
45*6777b538SAndroid Build Coastguard Worker#      1.0.2 => epoch = "1"
46*6777b538SAndroid Build Coastguard Worker#      4.2.0 => epoch = "4"
47*6777b538SAndroid Build Coastguard Worker#      0.2.7 => epoch = "0.2"
48*6777b538SAndroid Build Coastguard Worker#      0.0.3 => epoch = "0.0.3"
49*6777b538SAndroid Build Coastguard Worker#
50*6777b538SAndroid Build Coastguard Worker#  dev_deps
51*6777b538SAndroid Build Coastguard Worker#    Same meaning as test_deps in rust_static_library.gni, but called
52*6777b538SAndroid Build Coastguard Worker#    dev_deps to match Cargo.toml better.
53*6777b538SAndroid Build Coastguard Worker#
54*6777b538SAndroid Build Coastguard Worker#  build_root (optional)
55*6777b538SAndroid Build Coastguard Worker#    Filename of build.rs build script.
56*6777b538SAndroid Build Coastguard Worker#
57*6777b538SAndroid Build Coastguard Worker#  build_deps (optional)
58*6777b538SAndroid Build Coastguard Worker#    Build script dependencies
59*6777b538SAndroid Build Coastguard Worker#
60*6777b538SAndroid Build Coastguard Worker#  build_sources (optional)
61*6777b538SAndroid Build Coastguard Worker#    List of sources for build script. Must be specified if
62*6777b538SAndroid Build Coastguard Worker#    build_root is specified.
63*6777b538SAndroid Build Coastguard Worker#
64*6777b538SAndroid Build Coastguard Worker#  build_script_outputs (optional)
65*6777b538SAndroid Build Coastguard Worker#    List of .rs files generated by the build script, if any.
66*6777b538SAndroid Build Coastguard Worker#    Fine to leave undefined even if you have a build script.
67*6777b538SAndroid Build Coastguard Worker#    This doesn't directly correspond to any Cargo variable,
68*6777b538SAndroid Build Coastguard Worker#    but unfortunately is necessary for gn to build its dependency
69*6777b538SAndroid Build Coastguard Worker#    trees automatically.
70*6777b538SAndroid Build Coastguard Worker#    Many build scripts just output --cfg directives, in which case
71*6777b538SAndroid Build Coastguard Worker#    no source code is generated and this can remain empty.
72*6777b538SAndroid Build Coastguard Worker#
73*6777b538SAndroid Build Coastguard Worker#  build_script_inputs (optional)
74*6777b538SAndroid Build Coastguard Worker#    If the build script reads any files generated by build_deps,
75*6777b538SAndroid Build Coastguard Worker#    as opposed to merely linking against them, add a list of such
76*6777b538SAndroid Build Coastguard Worker#    files here. Again, this doesn't correspond to a Cargo variable
77*6777b538SAndroid Build Coastguard Worker#    but is necessary for gn.
78*6777b538SAndroid Build Coastguard Worker#
79*6777b538SAndroid Build Coastguard Worker#  crate_type "bin", "proc-macro" or "rlib" (optional)
80*6777b538SAndroid Build Coastguard Worker#    Whether to build an executable. The default is "rlib".
81*6777b538SAndroid Build Coastguard Worker#    At present others are not supported.
82*6777b538SAndroid Build Coastguard Worker#
83*6777b538SAndroid Build Coastguard Worker#  cargo_pkg_authors
84*6777b538SAndroid Build Coastguard Worker#  cargo_pkg_version
85*6777b538SAndroid Build Coastguard Worker#  cargo_pkg_name
86*6777b538SAndroid Build Coastguard Worker#  cargo_pkg_description
87*6777b538SAndroid Build Coastguard Worker#    Strings as found within 'version' and similar fields within Cargo.toml.
88*6777b538SAndroid Build Coastguard Worker#    Converted to environment variables passed to rustc, in case the crate
89*6777b538SAndroid Build Coastguard Worker#    uses clap `crate_version!` or `crate_authors!` macros (fairly common in
90*6777b538SAndroid Build Coastguard Worker#    command line tool help)
91*6777b538SAndroid Build Coastguard Worker
92*6777b538SAndroid Build Coastguard Workertemplate("cargo_crate") {
93*6777b538SAndroid Build Coastguard Worker  _orig_target_name = target_name
94*6777b538SAndroid Build Coastguard Worker
95*6777b538SAndroid Build Coastguard Worker  _crate_name = _orig_target_name
96*6777b538SAndroid Build Coastguard Worker  if (defined(invoker.crate_name)) {
97*6777b538SAndroid Build Coastguard Worker    _crate_name = invoker.crate_name
98*6777b538SAndroid Build Coastguard Worker  }
99*6777b538SAndroid Build Coastguard Worker
100*6777b538SAndroid Build Coastguard Worker  # Construct metadata from the crate epoch or an explicitly provided metadata
101*6777b538SAndroid Build Coastguard Worker  # field.
102*6777b538SAndroid Build Coastguard Worker  _rustc_metadata = ""
103*6777b538SAndroid Build Coastguard Worker  if (defined(invoker.rustc_metadata)) {
104*6777b538SAndroid Build Coastguard Worker    _rustc_metadata = invoker.rustc_metadata
105*6777b538SAndroid Build Coastguard Worker  } else if (defined(invoker.epoch)) {
106*6777b538SAndroid Build Coastguard Worker    _rustc_metadata = "${_crate_name}-${invoker.epoch}"
107*6777b538SAndroid Build Coastguard Worker  }
108*6777b538SAndroid Build Coastguard Worker
109*6777b538SAndroid Build Coastguard Worker  # Executables need to have unique names. Work out a prefix.
110*6777b538SAndroid Build Coastguard Worker  if (defined(invoker.build_root)) {
111*6777b538SAndroid Build Coastguard Worker    _epochlabel = "vunknown"
112*6777b538SAndroid Build Coastguard Worker    if (defined(invoker.epoch)) {
113*6777b538SAndroid Build Coastguard Worker      _tempepoch = string_replace(invoker.epoch, ".", "_")
114*6777b538SAndroid Build Coastguard Worker      _epochlabel = "v${_tempepoch}"
115*6777b538SAndroid Build Coastguard Worker    }
116*6777b538SAndroid Build Coastguard Worker
117*6777b538SAndroid Build Coastguard Worker    # This name includes the target name to ensure it's unique for each possible
118*6777b538SAndroid Build Coastguard Worker    # build target in the same BUILD.gn file.
119*6777b538SAndroid Build Coastguard Worker    _build_script_name =
120*6777b538SAndroid Build Coastguard Worker        "${_crate_name}_${target_name}_${_epochlabel}_build_script"
121*6777b538SAndroid Build Coastguard Worker
122*6777b538SAndroid Build Coastguard Worker    # Where the OUT_DIR will point when running the build script exe, and
123*6777b538SAndroid Build Coastguard Worker    # compiling the crate library/binaries. This directory must include the
124*6777b538SAndroid Build Coastguard Worker    # target name to avoid collisions between multiple GN targets that exist
125*6777b538SAndroid Build Coastguard Worker    # in the same BUILD.gn.
126*6777b538SAndroid Build Coastguard Worker    _build_script_env_out_dir = "$target_gen_dir/$target_name"
127*6777b538SAndroid Build Coastguard Worker  }
128*6777b538SAndroid Build Coastguard Worker
129*6777b538SAndroid Build Coastguard Worker  _rustenv = []
130*6777b538SAndroid Build Coastguard Worker  if (defined(invoker.rustenv)) {
131*6777b538SAndroid Build Coastguard Worker    _rustenv = invoker.rustenv
132*6777b538SAndroid Build Coastguard Worker  }
133*6777b538SAndroid Build Coastguard Worker  if (defined(invoker.cargo_pkg_authors)) {
134*6777b538SAndroid Build Coastguard Worker    _rustenv += [ "CARGO_PKG_AUTHORS=${invoker.cargo_pkg_authors}" ]
135*6777b538SAndroid Build Coastguard Worker  }
136*6777b538SAndroid Build Coastguard Worker  if (defined(invoker.cargo_pkg_version)) {
137*6777b538SAndroid Build Coastguard Worker    _rustenv += [ "CARGO_PKG_VERSION=${invoker.cargo_pkg_version}" ]
138*6777b538SAndroid Build Coastguard Worker  }
139*6777b538SAndroid Build Coastguard Worker  if (defined(invoker.cargo_pkg_name)) {
140*6777b538SAndroid Build Coastguard Worker    _rustenv += [ "CARGO_PKG_NAME=${invoker.cargo_pkg_name}" ]
141*6777b538SAndroid Build Coastguard Worker  }
142*6777b538SAndroid Build Coastguard Worker  if (defined(invoker.cargo_pkg_description)) {
143*6777b538SAndroid Build Coastguard Worker    _rustenv += [ "CARGO_PKG_DESCRIPTION=${invoker.cargo_pkg_description}" ]
144*6777b538SAndroid Build Coastguard Worker  }
145*6777b538SAndroid Build Coastguard Worker
146*6777b538SAndroid Build Coastguard Worker  # Try to determine the CARGO_MANIFEST_DIR, preferring the directory
147*6777b538SAndroid Build Coastguard Worker  # with build.rs and otherwise assuming that the target contains a
148*6777b538SAndroid Build Coastguard Worker  # `crate/` subdirectory.
149*6777b538SAndroid Build Coastguard Worker  if (defined(invoker.build_root)) {
150*6777b538SAndroid Build Coastguard Worker    manifest_dir = "."
151*6777b538SAndroid Build Coastguard Worker  } else {
152*6777b538SAndroid Build Coastguard Worker    build_gn_dir = get_label_info(target_name, "dir")
153*6777b538SAndroid Build Coastguard Worker    manifest_dir = rebase_path(build_gn_dir + "/crate", root_build_dir)
154*6777b538SAndroid Build Coastguard Worker  }
155*6777b538SAndroid Build Coastguard Worker  _rustenv += [ "CARGO_MANIFEST_DIR=${manifest_dir}" ]
156*6777b538SAndroid Build Coastguard Worker
157*6777b538SAndroid Build Coastguard Worker  # cargo_crate() should set library_configs, executable_configs,
158*6777b538SAndroid Build Coastguard Worker  # proc_macro_configs. Not configs.
159*6777b538SAndroid Build Coastguard Worker  assert(!defined(invoker.configs))
160*6777b538SAndroid Build Coastguard Worker
161*6777b538SAndroid Build Coastguard Worker  # Work out what we're building.
162*6777b538SAndroid Build Coastguard Worker  _crate_type = "rlib"
163*6777b538SAndroid Build Coastguard Worker  if (defined(invoker.crate_type)) {
164*6777b538SAndroid Build Coastguard Worker    _crate_type = invoker.crate_type
165*6777b538SAndroid Build Coastguard Worker  }
166*6777b538SAndroid Build Coastguard Worker  if (_crate_type == "cdylib") {
167*6777b538SAndroid Build Coastguard Worker    # Crates are rarely cdylibs. The example encountered so far aims
168*6777b538SAndroid Build Coastguard Worker    # to expose a C API to other code. In a Chromium context, we don't
169*6777b538SAndroid Build Coastguard Worker    # want to build that as a dylib for a couple of reasons:
170*6777b538SAndroid Build Coastguard Worker    # * rust_shared_library does not work on Mac. rustc does not know
171*6777b538SAndroid Build Coastguard Worker    #   how to export the __llvm_profile_raw_version symbol.
172*6777b538SAndroid Build Coastguard Worker    # * even if it did work, this might require us to distribute extra
173*6777b538SAndroid Build Coastguard Worker    #   binaries (.so/.dylib etc.)
174*6777b538SAndroid Build Coastguard Worker    # For the only case we've had so far, it makes more sense to build
175*6777b538SAndroid Build Coastguard Worker    # the code as a static library which we can then link into downstream
176*6777b538SAndroid Build Coastguard Worker    # binaries.
177*6777b538SAndroid Build Coastguard Worker    _crate_type = "rlib"
178*6777b538SAndroid Build Coastguard Worker  }
179*6777b538SAndroid Build Coastguard Worker  if (_crate_type == "bin") {
180*6777b538SAndroid Build Coastguard Worker    _target_type = "rust_executable"
181*6777b538SAndroid Build Coastguard Worker    assert(!defined(invoker.epoch))
182*6777b538SAndroid Build Coastguard Worker    if (defined(invoker.executable_configs)) {
183*6777b538SAndroid Build Coastguard Worker      _configs = invoker.executable_configs
184*6777b538SAndroid Build Coastguard Worker    }
185*6777b538SAndroid Build Coastguard Worker  } else if (_crate_type == "proc-macro") {
186*6777b538SAndroid Build Coastguard Worker    _target_type = "rust_macro"
187*6777b538SAndroid Build Coastguard Worker    if (defined(invoker.proc_macro_configs)) {
188*6777b538SAndroid Build Coastguard Worker      _configs = invoker.proc_macro_configs
189*6777b538SAndroid Build Coastguard Worker    }
190*6777b538SAndroid Build Coastguard Worker  } else {
191*6777b538SAndroid Build Coastguard Worker    assert(_crate_type == "rlib")
192*6777b538SAndroid Build Coastguard Worker    _target_type = "rust_static_library"
193*6777b538SAndroid Build Coastguard Worker    if (defined(invoker.library_configs)) {
194*6777b538SAndroid Build Coastguard Worker      _configs = invoker.library_configs
195*6777b538SAndroid Build Coastguard Worker    }
196*6777b538SAndroid Build Coastguard Worker  }
197*6777b538SAndroid Build Coastguard Worker
198*6777b538SAndroid Build Coastguard Worker  if (defined(invoker.output_name)) {
199*6777b538SAndroid Build Coastguard Worker    _output_name = invoker.output_name
200*6777b538SAndroid Build Coastguard Worker  } else if (_crate_type != "bin") {
201*6777b538SAndroid Build Coastguard Worker    # Note that file names of libraries must start with the crate name in
202*6777b538SAndroid Build Coastguard Worker    # order for the compiler to find transitive dependencies in the
203*6777b538SAndroid Build Coastguard Worker    # directory search paths (since they are not all explicitly specified).
204*6777b538SAndroid Build Coastguard Worker    #
205*6777b538SAndroid Build Coastguard Worker    # For bin targets, we expect the target name to be unique, and the name
206*6777b538SAndroid Build Coastguard Worker    # of the exe should not add magic stuff to it. And bin crates can not be
207*6777b538SAndroid Build Coastguard Worker    # transitive dependencies.
208*6777b538SAndroid Build Coastguard Worker    _output_name = "${_crate_name}_${_orig_target_name}"
209*6777b538SAndroid Build Coastguard Worker  }
210*6777b538SAndroid Build Coastguard Worker
211*6777b538SAndroid Build Coastguard Worker  _testonly = false
212*6777b538SAndroid Build Coastguard Worker  if (defined(invoker.testonly)) {
213*6777b538SAndroid Build Coastguard Worker    _testonly = invoker.testonly
214*6777b538SAndroid Build Coastguard Worker  }
215*6777b538SAndroid Build Coastguard Worker
216*6777b538SAndroid Build Coastguard Worker  # The main target, either a Rust source set or an executable.
217*6777b538SAndroid Build Coastguard Worker  target(_target_type, target_name) {
218*6777b538SAndroid Build Coastguard Worker    forward_variables_from(invoker,
219*6777b538SAndroid Build Coastguard Worker                           "*",
220*6777b538SAndroid Build Coastguard Worker                           TESTONLY_AND_VISIBILITY + [
221*6777b538SAndroid Build Coastguard Worker                                 "build_root",
222*6777b538SAndroid Build Coastguard Worker                                 "build_deps",
223*6777b538SAndroid Build Coastguard Worker                                 "build_sources",
224*6777b538SAndroid Build Coastguard Worker                                 "build_script_inputs",
225*6777b538SAndroid Build Coastguard Worker                                 "build_script_outputs",
226*6777b538SAndroid Build Coastguard Worker                                 "epoch",
227*6777b538SAndroid Build Coastguard Worker                                 "unit_test_target",
228*6777b538SAndroid Build Coastguard Worker                                 "configs",
229*6777b538SAndroid Build Coastguard Worker                                 "executable_configs",
230*6777b538SAndroid Build Coastguard Worker                                 "library_configs",
231*6777b538SAndroid Build Coastguard Worker                                 "proc_macro_configs",
232*6777b538SAndroid Build Coastguard Worker                                 "rustenv",
233*6777b538SAndroid Build Coastguard Worker                                 "dev_deps",
234*6777b538SAndroid Build Coastguard Worker                               ])
235*6777b538SAndroid Build Coastguard Worker
236*6777b538SAndroid Build Coastguard Worker    testonly = _testonly
237*6777b538SAndroid Build Coastguard Worker    if (defined(invoker.visibility)) {
238*6777b538SAndroid Build Coastguard Worker      visibility = invoker.visibility
239*6777b538SAndroid Build Coastguard Worker    }
240*6777b538SAndroid Build Coastguard Worker    if (defined(crate_type) && crate_type == "cdylib") {
241*6777b538SAndroid Build Coastguard Worker      # See comments above about cdylib.
242*6777b538SAndroid Build Coastguard Worker      crate_type = "rlib"
243*6777b538SAndroid Build Coastguard Worker    }
244*6777b538SAndroid Build Coastguard Worker    crate_name = _crate_name
245*6777b538SAndroid Build Coastguard Worker
246*6777b538SAndroid Build Coastguard Worker    if (defined(_output_name)) {
247*6777b538SAndroid Build Coastguard Worker      output_name = _output_name
248*6777b538SAndroid Build Coastguard Worker    }
249*6777b538SAndroid Build Coastguard Worker
250*6777b538SAndroid Build Coastguard Worker    # Don't import the `chromium` crate into third-party code.
251*6777b538SAndroid Build Coastguard Worker    no_chromium_prelude = true
252*6777b538SAndroid Build Coastguard Worker
253*6777b538SAndroid Build Coastguard Worker    rustc_metadata = _rustc_metadata
254*6777b538SAndroid Build Coastguard Worker
255*6777b538SAndroid Build Coastguard Worker    # TODO(crbug.com/1422745): don't default to true. This requires changes to
256*6777b538SAndroid Build Coastguard Worker    # third_party.toml and gnrt when generating third-party build targets.
257*6777b538SAndroid Build Coastguard Worker    allow_unsafe = true
258*6777b538SAndroid Build Coastguard Worker
259*6777b538SAndroid Build Coastguard Worker    configs = []
260*6777b538SAndroid Build Coastguard Worker    if (defined(_configs)) {
261*6777b538SAndroid Build Coastguard Worker      configs += _configs
262*6777b538SAndroid Build Coastguard Worker    }
263*6777b538SAndroid Build Coastguard Worker
264*6777b538SAndroid Build Coastguard Worker    if (_crate_type == "rlib") {
265*6777b538SAndroid Build Coastguard Worker      # Forward configs for unit tests.
266*6777b538SAndroid Build Coastguard Worker      if (defined(invoker.executable_configs)) {
267*6777b538SAndroid Build Coastguard Worker        executable_configs = invoker.executable_configs
268*6777b538SAndroid Build Coastguard Worker      }
269*6777b538SAndroid Build Coastguard Worker    }
270*6777b538SAndroid Build Coastguard Worker
271*6777b538SAndroid Build Coastguard Worker    if (!defined(rustflags)) {
272*6777b538SAndroid Build Coastguard Worker      rustflags = []
273*6777b538SAndroid Build Coastguard Worker    }
274*6777b538SAndroid Build Coastguard Worker    rustenv = _rustenv
275*6777b538SAndroid Build Coastguard Worker
276*6777b538SAndroid Build Coastguard Worker    if (!defined(build_native_rust_unit_tests)) {
277*6777b538SAndroid Build Coastguard Worker      build_native_rust_unit_tests = _crate_type != "proc-macro"
278*6777b538SAndroid Build Coastguard Worker    }
279*6777b538SAndroid Build Coastguard Worker    if (build_native_rust_unit_tests) {
280*6777b538SAndroid Build Coastguard Worker      # Unit tests in a proc-macro crate type don't make sense, you can't
281*6777b538SAndroid Build Coastguard Worker      # compile executables against the `proc_macro` crate.
282*6777b538SAndroid Build Coastguard Worker      assert(_crate_type != "proc-macro")
283*6777b538SAndroid Build Coastguard Worker    }
284*6777b538SAndroid Build Coastguard Worker
285*6777b538SAndroid Build Coastguard Worker    # The unit tests for each target, if generated, should be unique as well.
286*6777b538SAndroid Build Coastguard Worker    # a) It needs to be unique even if multiple build targets have the same
287*6777b538SAndroid Build Coastguard Worker    #    `crate_name`, but different target names.
288*6777b538SAndroid Build Coastguard Worker    # b) It needs to be unique even if multiple build targets have the same
289*6777b538SAndroid Build Coastguard Worker    #    `crate_name` and target name, but different epochs.
290*6777b538SAndroid Build Coastguard Worker    _unit_test_unique_target_name = ""
291*6777b538SAndroid Build Coastguard Worker    if (_crate_name != _orig_target_name) {
292*6777b538SAndroid Build Coastguard Worker      _unit_test_unique_target_name = "${_orig_target_name}_"
293*6777b538SAndroid Build Coastguard Worker    }
294*6777b538SAndroid Build Coastguard Worker    _unit_test_unique_epoch = ""
295*6777b538SAndroid Build Coastguard Worker    if (defined(invoker.epoch)) {
296*6777b538SAndroid Build Coastguard Worker      _epoch_str = string_replace(invoker.epoch, ".", "_")
297*6777b538SAndroid Build Coastguard Worker      _unit_test_unique_epoch = "v${_epoch_str}_"
298*6777b538SAndroid Build Coastguard Worker    }
299*6777b538SAndroid Build Coastguard Worker    if (defined(output_dir) && output_dir != "") {
300*6777b538SAndroid Build Coastguard Worker      unit_test_output_dir = output_dir
301*6777b538SAndroid Build Coastguard Worker    }
302*6777b538SAndroid Build Coastguard Worker    unit_test_target = "${_unit_test_unique_target_name}${_crate_name}_${_unit_test_unique_epoch}unittests"
303*6777b538SAndroid Build Coastguard Worker
304*6777b538SAndroid Build Coastguard Worker    if ((!defined(output_dir) || output_dir == "") && _crate_type == "rlib") {
305*6777b538SAndroid Build Coastguard Worker      # Cargo crate rlibs can be compiled differently for tests, and must not
306*6777b538SAndroid Build Coastguard Worker      # collide with the production outputs. This does *not* override the
307*6777b538SAndroid Build Coastguard Worker      # unit_test_output_dir, which is set above, as that target is not an rlib.
308*6777b538SAndroid Build Coastguard Worker      output_dir = "$target_out_dir/$_orig_target_name"
309*6777b538SAndroid Build Coastguard Worker    }
310*6777b538SAndroid Build Coastguard Worker
311*6777b538SAndroid Build Coastguard Worker    if (defined(invoker.dev_deps)) {
312*6777b538SAndroid Build Coastguard Worker      test_deps = invoker.dev_deps
313*6777b538SAndroid Build Coastguard Worker    }
314*6777b538SAndroid Build Coastguard Worker
315*6777b538SAndroid Build Coastguard Worker    if (defined(invoker.build_root)) {
316*6777b538SAndroid Build Coastguard Worker      # Uh-oh, we have a build script
317*6777b538SAndroid Build Coastguard Worker      if (!defined(deps)) {
318*6777b538SAndroid Build Coastguard Worker        deps = []
319*6777b538SAndroid Build Coastguard Worker      }
320*6777b538SAndroid Build Coastguard Worker      if (!defined(sources)) {
321*6777b538SAndroid Build Coastguard Worker        sources = []
322*6777b538SAndroid Build Coastguard Worker      }
323*6777b538SAndroid Build Coastguard Worker      if (!defined(inputs)) {
324*6777b538SAndroid Build Coastguard Worker        inputs = []
325*6777b538SAndroid Build Coastguard Worker      }
326*6777b538SAndroid Build Coastguard Worker
327*6777b538SAndroid Build Coastguard Worker      # This... is a bit weird. We generate a file called cargo_flags.rs which
328*6777b538SAndroid Build Coastguard Worker      # does not actually contain Rust code, but instead some flags to add
329*6777b538SAndroid Build Coastguard Worker      # to the rustc command line. We need it to end in a .rs extension so that
330*6777b538SAndroid Build Coastguard Worker      # we can include it in the 'sources' line and thus have dependency
331*6777b538SAndroid Build Coastguard Worker      # calculation done correctly. data_deps won't work because targets don't
332*6777b538SAndroid Build Coastguard Worker      # require them to be present until runtime.
333*6777b538SAndroid Build Coastguard Worker      flags_file = "$_build_script_env_out_dir/cargo_flags.rs"
334*6777b538SAndroid Build Coastguard Worker      rustflags += [ "@" + rebase_path(flags_file, root_build_dir) ]
335*6777b538SAndroid Build Coastguard Worker      sources += [ flags_file ]
336*6777b538SAndroid Build Coastguard Worker      if (defined(invoker.build_script_outputs)) {
337*6777b538SAndroid Build Coastguard Worker        # Build scripts may output arbitrary files. They are usually included in
338*6777b538SAndroid Build Coastguard Worker        # the main Rust target using include! or include_str! and therefore the
339*6777b538SAndroid Build Coastguard Worker        # filename may be .rs or may be arbitrary. We want to educate ninja
340*6777b538SAndroid Build Coastguard Worker        # about the dependency either way.
341*6777b538SAndroid Build Coastguard Worker        foreach(extra_source,
342*6777b538SAndroid Build Coastguard Worker                filter_include(invoker.build_script_outputs, [ "*.rs" ])) {
343*6777b538SAndroid Build Coastguard Worker          sources += [ "$_build_script_env_out_dir/$extra_source" ]
344*6777b538SAndroid Build Coastguard Worker        }
345*6777b538SAndroid Build Coastguard Worker        foreach(extra_source,
346*6777b538SAndroid Build Coastguard Worker                filter_exclude(invoker.build_script_outputs, [ "*.rs" ])) {
347*6777b538SAndroid Build Coastguard Worker          inputs += [ "$_build_script_env_out_dir/$extra_source" ]
348*6777b538SAndroid Build Coastguard Worker        }
349*6777b538SAndroid Build Coastguard Worker      }
350*6777b538SAndroid Build Coastguard Worker      deps += [ ":${_build_script_name}_output" ]
351*6777b538SAndroid Build Coastguard Worker    }
352*6777b538SAndroid Build Coastguard Worker  }
353*6777b538SAndroid Build Coastguard Worker
354*6777b538SAndroid Build Coastguard Worker  if (defined(invoker.build_root)) {
355*6777b538SAndroid Build Coastguard Worker    # Extra targets required to make build script work
356*6777b538SAndroid Build Coastguard Worker    action("${_build_script_name}_output") {
357*6777b538SAndroid Build Coastguard Worker      script = rebase_path("//build/rust/run_build_script.py")
358*6777b538SAndroid Build Coastguard Worker      build_script_target = ":${_build_script_name}($rust_macro_toolchain)"
359*6777b538SAndroid Build Coastguard Worker      deps = [ build_script_target ]
360*6777b538SAndroid Build Coastguard Worker      testonly = _testonly
361*6777b538SAndroid Build Coastguard Worker      if (defined(invoker.visibility)) {
362*6777b538SAndroid Build Coastguard Worker        visibility = invoker.visibility
363*6777b538SAndroid Build Coastguard Worker      }
364*6777b538SAndroid Build Coastguard Worker
365*6777b538SAndroid Build Coastguard Worker      # The build script may be built with a different toolchain when
366*6777b538SAndroid Build Coastguard Worker      # cross-compiling (the host toolchain) so we must find the path relative
367*6777b538SAndroid Build Coastguard Worker      # to that.
368*6777b538SAndroid Build Coastguard Worker      _build_script_root_out_dir =
369*6777b538SAndroid Build Coastguard Worker          get_label_info(build_script_target, "root_out_dir")
370*6777b538SAndroid Build Coastguard Worker      _build_script_exe = "$_build_script_root_out_dir/$_build_script_name"
371*6777b538SAndroid Build Coastguard Worker
372*6777b538SAndroid Build Coastguard Worker      # The executable is always built with the `rust_macro_toolchain` which
373*6777b538SAndroid Build Coastguard Worker      # targets the `host_os`. The rule here is on the `target_toolchain` which
374*6777b538SAndroid Build Coastguard Worker      # can be different (e.g. compiling on Linux, targeting Windows).
375*6777b538SAndroid Build Coastguard Worker      if (host_os == "win") {
376*6777b538SAndroid Build Coastguard Worker        _build_script_exe = "${_build_script_exe}.exe"
377*6777b538SAndroid Build Coastguard Worker      }
378*6777b538SAndroid Build Coastguard Worker
379*6777b538SAndroid Build Coastguard Worker      _flags_file = "$_build_script_env_out_dir/cargo_flags.rs"
380*6777b538SAndroid Build Coastguard Worker
381*6777b538SAndroid Build Coastguard Worker      inputs = [ _build_script_exe ]
382*6777b538SAndroid Build Coastguard Worker      outputs = [ _flags_file ]
383*6777b538SAndroid Build Coastguard Worker      args = [
384*6777b538SAndroid Build Coastguard Worker        "--build-script",
385*6777b538SAndroid Build Coastguard Worker        rebase_path(_build_script_exe, root_build_dir),
386*6777b538SAndroid Build Coastguard Worker        "--output",
387*6777b538SAndroid Build Coastguard Worker        rebase_path(_flags_file, root_build_dir),
388*6777b538SAndroid Build Coastguard Worker        "--rust-prefix",
389*6777b538SAndroid Build Coastguard Worker        rebase_path("${rust_sysroot}/bin", root_build_dir),
390*6777b538SAndroid Build Coastguard Worker        "--out-dir",
391*6777b538SAndroid Build Coastguard Worker        rebase_path(_build_script_env_out_dir, root_build_dir),
392*6777b538SAndroid Build Coastguard Worker        "--src-dir",
393*6777b538SAndroid Build Coastguard Worker        rebase_path(get_path_info(invoker.build_root, "dir"), root_build_dir),
394*6777b538SAndroid Build Coastguard Worker      ]
395*6777b538SAndroid Build Coastguard Worker      if (defined(rust_abi_target) && rust_abi_target != "") {
396*6777b538SAndroid Build Coastguard Worker        args += [
397*6777b538SAndroid Build Coastguard Worker          "--target",
398*6777b538SAndroid Build Coastguard Worker          rust_abi_target,
399*6777b538SAndroid Build Coastguard Worker        ]
400*6777b538SAndroid Build Coastguard Worker      }
401*6777b538SAndroid Build Coastguard Worker      if (defined(invoker.features)) {
402*6777b538SAndroid Build Coastguard Worker        args += [ "--features" ]
403*6777b538SAndroid Build Coastguard Worker        args += invoker.features
404*6777b538SAndroid Build Coastguard Worker      }
405*6777b538SAndroid Build Coastguard Worker      if (defined(invoker.build_script_outputs)) {
406*6777b538SAndroid Build Coastguard Worker        args += [ "--generated-files" ]
407*6777b538SAndroid Build Coastguard Worker        args += invoker.build_script_outputs
408*6777b538SAndroid Build Coastguard Worker        foreach(generated_file, invoker.build_script_outputs) {
409*6777b538SAndroid Build Coastguard Worker          outputs += [ "$_build_script_env_out_dir/$generated_file" ]
410*6777b538SAndroid Build Coastguard Worker        }
411*6777b538SAndroid Build Coastguard Worker      }
412*6777b538SAndroid Build Coastguard Worker      if (_rustenv != []) {
413*6777b538SAndroid Build Coastguard Worker        args += [ "--env" ]
414*6777b538SAndroid Build Coastguard Worker        args += _rustenv
415*6777b538SAndroid Build Coastguard Worker      }
416*6777b538SAndroid Build Coastguard Worker      if (defined(invoker.build_script_inputs)) {
417*6777b538SAndroid Build Coastguard Worker        inputs += invoker.build_script_inputs
418*6777b538SAndroid Build Coastguard Worker      }
419*6777b538SAndroid Build Coastguard Worker    }
420*6777b538SAndroid Build Coastguard Worker
421*6777b538SAndroid Build Coastguard Worker    if (toolchain_for_rust_host_build_tools) {
422*6777b538SAndroid Build Coastguard Worker      # The build script is only available to be built on the host, and we use
423*6777b538SAndroid Build Coastguard Worker      # the rust_macro_toolchain for it to unblock building them while the
424*6777b538SAndroid Build Coastguard Worker      # Chromium stdlib is still being compiled.
425*6777b538SAndroid Build Coastguard Worker      rust_executable(_build_script_name) {
426*6777b538SAndroid Build Coastguard Worker        crate_name = _build_script_name
427*6777b538SAndroid Build Coastguard Worker        sources = invoker.build_sources
428*6777b538SAndroid Build Coastguard Worker        crate_root = invoker.build_root
429*6777b538SAndroid Build Coastguard Worker        testonly = _testonly
430*6777b538SAndroid Build Coastguard Worker        if (defined(invoker.visibility)) {
431*6777b538SAndroid Build Coastguard Worker          visibility = invoker.visibility
432*6777b538SAndroid Build Coastguard Worker        }
433*6777b538SAndroid Build Coastguard Worker        if (defined(invoker.build_deps)) {
434*6777b538SAndroid Build Coastguard Worker          deps = invoker.build_deps
435*6777b538SAndroid Build Coastguard Worker        }
436*6777b538SAndroid Build Coastguard Worker        if (defined(invoker.build_script_inputs)) {
437*6777b538SAndroid Build Coastguard Worker          inputs = invoker.build_script_inputs
438*6777b538SAndroid Build Coastguard Worker        }
439*6777b538SAndroid Build Coastguard Worker
440*6777b538SAndroid Build Coastguard Worker        # Don't import the `chromium` crate into third-party code.
441*6777b538SAndroid Build Coastguard Worker        no_chromium_prelude = true
442*6777b538SAndroid Build Coastguard Worker
443*6777b538SAndroid Build Coastguard Worker        # The ${_build_script_name}_output target looks for the exe in this
444*6777b538SAndroid Build Coastguard Worker        # location. Due to how the Windows component build works, this has to
445*6777b538SAndroid Build Coastguard Worker        # be $root_out_dir for all EXEs. In component build, C++ links to the
446*6777b538SAndroid Build Coastguard Worker        # CRT as a DLL, and if Rust does not match, we can't link mixed target
447*6777b538SAndroid Build Coastguard Worker        # Rust EXE/DLLs, as the headers in C++ said something different than
448*6777b538SAndroid Build Coastguard Worker        # what Rust links. Since the CRT DLL is placed in the $root_out_dir,
449*6777b538SAndroid Build Coastguard Worker        # an EXE can find it if it's also placed in that dir.
450*6777b538SAndroid Build Coastguard Worker        output_dir = root_out_dir
451*6777b538SAndroid Build Coastguard Worker        rustenv = _rustenv
452*6777b538SAndroid Build Coastguard Worker        forward_variables_from(invoker,
453*6777b538SAndroid Build Coastguard Worker                               [
454*6777b538SAndroid Build Coastguard Worker                                 "features",
455*6777b538SAndroid Build Coastguard Worker                                 "edition",
456*6777b538SAndroid Build Coastguard Worker                                 "rustflags",
457*6777b538SAndroid Build Coastguard Worker                               ])
458*6777b538SAndroid Build Coastguard Worker        configs -= [
459*6777b538SAndroid Build Coastguard Worker          "//build/config/compiler:chromium_code",
460*6777b538SAndroid Build Coastguard Worker
461*6777b538SAndroid Build Coastguard Worker          # Avoid generating profiling data for build scripts.
462*6777b538SAndroid Build Coastguard Worker          #
463*6777b538SAndroid Build Coastguard Worker          # TODO(crbug.com/1426472): determine for sure whether to remove this
464*6777b538SAndroid Build Coastguard Worker          # config. I'm not sure of the overlap between PGO instrumentation and
465*6777b538SAndroid Build Coastguard Worker          # code coverage instrumentation, but we definitely don't want build
466*6777b538SAndroid Build Coastguard Worker          # script coverage for PGO, while we might for test coverage metrics.
467*6777b538SAndroid Build Coastguard Worker          #
468*6777b538SAndroid Build Coastguard Worker          # If we do include build script output in test metrics, it could be
469*6777b538SAndroid Build Coastguard Worker          # misleading: exercising some code from a build script doesn't give us
470*6777b538SAndroid Build Coastguard Worker          # the same signal as an actual test.
471*6777b538SAndroid Build Coastguard Worker          "//build/config/coverage:default_coverage",
472*6777b538SAndroid Build Coastguard Worker        ]
473*6777b538SAndroid Build Coastguard Worker        configs += [ "//build/config/compiler:no_chromium_code" ]
474*6777b538SAndroid Build Coastguard Worker      }
475*6777b538SAndroid Build Coastguard Worker    } else {
476*6777b538SAndroid Build Coastguard Worker      not_needed(invoker,
477*6777b538SAndroid Build Coastguard Worker                 [
478*6777b538SAndroid Build Coastguard Worker                   "build_sources",
479*6777b538SAndroid Build Coastguard Worker                   "build_deps",
480*6777b538SAndroid Build Coastguard Worker                   "build_root",
481*6777b538SAndroid Build Coastguard Worker                   "build_script_inputs",
482*6777b538SAndroid Build Coastguard Worker                   "build_script_outputs",
483*6777b538SAndroid Build Coastguard Worker                 ])
484*6777b538SAndroid Build Coastguard Worker    }
485*6777b538SAndroid Build Coastguard Worker  } else {
486*6777b538SAndroid Build Coastguard Worker    not_needed([
487*6777b538SAndroid Build Coastguard Worker                 "_name_specific_output_dir",
488*6777b538SAndroid Build Coastguard Worker                 "_orig_target_name",
489*6777b538SAndroid Build Coastguard Worker               ])
490*6777b538SAndroid Build Coastguard Worker  }
491*6777b538SAndroid Build Coastguard Worker}
492*6777b538SAndroid Build Coastguard Worker
493*6777b538SAndroid Build Coastguard Workerset_defaults("cargo_crate") {
494*6777b538SAndroid Build Coastguard Worker  library_configs = default_compiler_configs
495*6777b538SAndroid Build Coastguard Worker  executable_configs = default_executable_configs
496*6777b538SAndroid Build Coastguard Worker  proc_macro_configs = default_rust_proc_macro_configs
497*6777b538SAndroid Build Coastguard Worker}
498