File: rust.gni

package info (click to toggle)
chromium 139.0.7258.127-2
  • links: PTS, VCS
  • area: main
  • in suites: forky
  • size: 6,122,156 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (447 lines) | stat: -rw-r--r-- 18,020 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
# Copyright 2021 The Chromium Project. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import("//build/config/chrome_build.gni")
import("//build/config/compiler/compiler.gni")
import("//build/config/sanitizers/sanitizers.gni")
import("//build/toolchain/toolchain.gni")

if (is_android) {
  import("//build/config/android/config.gni")
}

if (is_ios) {
  # For `target_environment` and `target_platform`.
  import("//build/config/apple/mobile_config.gni")
}

declare_args() {
  # Rust is available in the Chromium build but 3p repos that use //build may
  # not use Rust and thus won't want to depend on having the Rust toolchain
  # present, so this defaults to off in those cases.
  #
  # Chromium-based projects that are built for for architectures Chrome does not
  # support may need to disable this as well, though they may need to replace
  # code with C/C++ to get a functional product.
  #
  # Based on the above:
  #
  # * `enable_rust` may be consulted under `//build` and `//testing` directories
  #   (which may be used outside of Chromium build)
  # * `enable_rust` should *not* be consulted in other Chromium directories
  #   (including `//base`, `//net`, etc.)
  enable_rust = build_with_chromium

  # The chromium prelude crate provides the `chromium::import!` macro which
  # is needed to depend on first-party rust libraries. Third-party libraries
  # are specified with cargo_crate and do not get imported through this macro.
  #
  # The macro requires //third_party/rust for syn, quote, and proc_macro2.
  # Downstream projects that want to use //build for the rust GN templates but
  # don't want to enable the chromium prelude can disable it here, and should
  # specify a globally unique `crate_name` in their rust library GN rules
  # instead. Note that using a `crate_name` is strongly discouraged inside
  # Chromium, and is also discouraged for downstream projects when possible.
  #
  # We do not support disabling this flag in Chromium code.
  enable_chromium_prelude = build_with_chromium

  # Chromium provides a Rust toolchain in //third_party/rust-toolchain.
  #
  # To use a custom toolchain instead, specify an absolute path to the root of
  # a Rust sysroot, which will have a 'bin' directory and others. Commonly
  # <home dir>/.rustup/toolchains/nightly-<something>-<something>
  rust_sysroot_absolute = ""

  # Directory under which to find `bin/bindgen` (a `bin` directory containing
  # the bindgen exectuable).
  rust_bindgen_root = "//third_party/rust-toolchain"

  # If you're using a Rust toolchain as specified by rust_sysroot_absolute,
  # set this to the output of `rustc -V`. Changing this string will cause all
  # Rust targets to be rebuilt, which allows you to update your toolchain and
  # not break incremental builds.
  rustc_version = ""

  # If you're using a Rust toolchain as specified by rust_sysroot_absolute,
  # you can specify whether it supports nacl here.
  rust_toolchain_supports_nacl = false

  # Whether artifacts produced by the Rust compiler can participate in ThinLTO.
  #
  # One important consideration is whether the linker uses the same LLVM
  # version as `rustc` (i.e. if it can understand the LLVM-IR from the
  # compilation artifacts produced by `rustc`).  In LaCrOS and ash builds this
  # may not be true - see b/299483903.
  #
  # TODO(crbug.com/40281834): Re-enable ThinLTO for Rust on LaCrOS
  # TODO(b/300937673): Re-enable ThinLTO for Rust on ash-chrome
  toolchain_supports_rust_thin_lto = !is_chromeos

  # Any extra std rlibs in your Rust toolchain, relative to the standard
  # Rust toolchain. Typically used with 'rust_sysroot_absolute'
  added_rust_stdlib_libs = []

  # Any removed std rlibs in your Rust toolchain, relative to the standard
  # Rust toolchain. Typically used with 'rust_sysroot_absolute'
  removed_rust_stdlib_libs = []

  # Non-rlib libs provided in the toolchain sysroot. Usually this is empty, but
  # e.g. the Android Rust Toolchain provides a libunwind.a that rustc expects.
  extra_sysroot_libs = []

  # Force-enable `--color=always` for rustc, even when it would be disabled for
  # a platform. Mostly applicable to Windows, where new versions can handle ANSI
  # escape sequences but it's not reliable in general.
  force_rustc_color_output = false
}

declare_args() {
  # The CXX tool is in //third_party/rust which is not shared with downstream
  # projects yet. So they need to copy the required dependencies and GN files
  # into their project to enable CXX there.
  #
  # Currently, cxx is needed to use Rust with an allocator since the Chromium
  # allocator shim uses cxx
  enable_rust_cxx = enable_rust
}

# Use the Rust toolchain built in-tree. When false, we use the prebuilt Rust
# stdlibs that come with the specified custom toolchain.
use_chromium_rust_toolchain = rust_sysroot_absolute == ""

# Platform support for the Rust toolchain.
chromium_toolchain_supports_platform = !is_nacl && !is_wasm
custom_toolchain_supports_platform = !is_nacl || rust_toolchain_supports_nacl

# Not all target triples (GN toolchains) are supported by the Rust compiler.
# Define if we support the current GN toolchain.
toolchain_has_rust = false

# The rustc_revision is used to introduce a dependency on the toolchain version
# (so e.g. rust targets are rebuilt, and the standard library is re-copied when
# the toolchain changes). It is left empty for custom toolchains.
rustc_revision = ""

if (enable_rust) {
  if (use_chromium_rust_toolchain) {
    toolchain_has_rust = chromium_toolchain_supports_platform
    if (toolchain_has_rust) {
      rustc_revision =
          read_file("//third_party/rust-toolchain/VERSION", "trim string")

      # Example:
      # rustc 1.88.0 c8f94230282a8e8c1148f3e657f0199aad909228 (c8f94230282a8e8c1148f3e657f0199aad909228-1-llvmorg-21-init-9266-g09006611 chromium)
      # Trim it down as much as we can using GN.
      rustc_revision = string_replace(rustc_revision, "rustc ", "")
      rustc_revision = string_replace(rustc_revision, " chromium", "")
      rustc_revision = string_replace(rustc_revision, "init-", "")
      rustc_revision = string_replace(rustc_revision, "llvmorg-", "")
      rustc_revision = string_replace(rustc_revision, " ", "")
      rustc_revision = string_replace(rustc_revision, ".", "")
      rustc_revision = string_replace(rustc_revision, "(", "-")
      rustc_revision = string_replace(rustc_revision, ")", "")
    }

    # The same as written in `config.toml.template`.
    rust_channel = "dev"
  } else {
    toolchain_has_rust = custom_toolchain_supports_platform
    rustc_revision = rustc_version
  }
}

# TODO(crbug.com/40809974): To build unit tests for Android we need to build
# them as a dylib and put them into an APK. We should reuse all the same logic
# for gtests from the `//testing/test:test` template.
can_build_rust_unit_tests = toolchain_has_rust && !is_android

# We want to store rust_sysroot as a source-relative variable for ninja
# portability. In practice if an external toolchain was specified, it might
# be an absolute path, but we'll do our best.
if (enable_rust) {
  if (use_chromium_rust_toolchain) {
    rust_sysroot = "//third_party/rust-toolchain"
  } else {
    rust_sysroot = get_path_info(rust_sysroot_absolute, "abspath")
  }
}

# Figure out the Rust target triple (aka 'rust_abi_target')
#
# This is here rather than in the toolchain files because it's used also by
# //build/rust/std to find the Rust standard library and construct a sysroot for
# rustc invocations.
#
# The list of architectures supported by Rust is here:
# https://doc.rust-lang.org/nightly/rustc/platform-support.html. We map Chromium
# targets to Rust targets comprehensively despite not having official support
# (see '*_toolchain_supports_platform above') to enable experimentation with
# other toolchains.
#
# The `cargo_target_abi` is the `target_abi` given by Cargo to build scripts
# as the `CARGO_CFG_TARGET_ABI` environment variable. It is determined for
# each `rust_abi_target` by doing `cargo build --target $rust_abi_target` with
# a cargo project that dumps the `CARGO_CFG_TARGET_ABI` from its build.rs. See
# https://issues.chromium.org/u/1/issues/372512092#comment5 for an example.
rust_abi_target = ""
if (is_linux || is_chromeos) {
  if (current_cpu == "arm64") {
    rust_abi_target = "aarch64-unknown-linux-gnu"
    cargo_target_abi = ""
  } else if (current_cpu == "ppc64") {
    rust_abi_target = "powerpc64le-unknown-linux-gnu"
    cargo_target_abi = ""
  } else if (current_cpu == "x86") {
    rust_abi_target = "i686-unknown-linux-gnu"
    cargo_target_abi = ""
  } else if (current_cpu == "x64") {
    rust_abi_target = "x86_64-unknown-linux-gnu"
    cargo_target_abi = ""
  } else if (current_cpu == "arm") {
    if (arm_float_abi == "hard") {
      float_suffix = "hf"
    } else {
      float_suffix = ""
    }
    if (arm_arch == "armv7-a" || arm_arch == "armv7") {
      # We have no way to inform Rust about the -a suffix, so we end up
      # targeting armv7 in both cases.
      #
      # We also try to propagate the availability of NEON without feature
      # detection; in C++ this is done by -mfpu=neon, but in Rust we need to
      # use a different ABI target.
      #
      # The thumbv7 vs. armv7 distinction is for legacy reasons and both
      # targets in fact target Thumb, see:
      # https://github.com/rust-lang/rust/issues/44722
      if (false && arm_use_neon) {
        rust_abi_target = "thumbv7neon-unknown-linux-gnueabi" + float_suffix
      } else {
        rust_abi_target = "armv7-unknown-linux-gnueabi" + float_suffix
      }
      cargo_target_abi = "eabi" + float_suffix
    } else {
      rust_abi_target = "arm-unknown-linux-gnueabi" + float_suffix
      cargo_target_abi = "eabi" + float_suffix
    }
  } else if (current_cpu == "riscv64") {
    rust_abi_target = "riscv64gc-unknown-linux-gnu"
    cargo_target_abi = ""
  } else if (current_cpu == "ppc64") {
    rust_abi_target = "powerpc64le-unknown-linux-gnu"
    cargo_target_abi = ""
  } else if (current_cpu == "s390x") {
    rust_abi_target = "s390x-unknown-linux-gnu"
    cargo_target_abi = ""
  } else if (current_cpu == "loong64") {
    rust_abi_target = "loongarch64-unknown-linux-gnu"
    cargo_target_abi = ""
  } else {
    # Best guess for other future platforms.
    rust_abi_target = current_cpu + "-unknown-linux-gnu"
    cargo_target_abi = ""
  }
} else if (is_android) {
  import("//build/config/android/abi.gni")
  if (android_abi_target == "i686-linux-android") {
    rust_abi_target = android_abi_target
    cargo_target_abi = ""
  } else if (android_abi_target == "arm-linux-androideabi") {
    # Android clang target specifications mostly match Rust, but this
    # is an exception.
    # See section above for Linux for thumbv7neon vs. armv7.
    # Note that on Android, NEON is enabled for all builds except Cronet.
    if (arm_use_neon) {
      rust_abi_target = "thumbv7neon-linux-androideabi"
    } else {
      rust_abi_target = "armv7-linux-androideabi"
    }
    cargo_target_abi = "eabi"
  } else if (android_abi_target == "mipsel-linux-android") {
    # There is no MIPS android target.
    rust_abi_target = ""
    cargo_target_abi = ""
  } else if (android_abi_target == "x86_64-linux-android") {
    rust_abi_target = android_abi_target
    cargo_target_abi = ""
  } else if (android_abi_target == "aarch64-linux-android") {
    rust_abi_target = android_abi_target
    cargo_target_abi = ""
  } else if (android_abi_target == "mips64el-linux-android") {
    # There is no MIPS android target.
    rust_abi_target = ""
    cargo_target_abi = ""
  } else if (android_abi_target == "riscv64-linux-android") {
    rust_abi_target = android_abi_target
    cargo_target_abi = ""
  } else {
    assert(false, "Unknown Android ABI: " + android_abi_target)
  }
} else if (is_fuchsia) {
  if (current_cpu == "arm64") {
    rust_abi_target = "aarch64-unknown-fuchsia"
    cargo_target_abi = ""
  } else if (current_cpu == "x64") {
    rust_abi_target = "x86_64-unknown-fuchsia"
    cargo_target_abi = ""
  } else {
    assert(false, "Architecture not supported")
  }
} else if (is_ios) {
  if (current_cpu == "arm64e") {
    assert(target_platform == "iphoneos",
           "unsupported target_platform=$target_platform")
    rust_abi_target = "arm64e-apple-ios"
    cargo_target_abi = ""
  } else if (current_cpu == "arm64") {
    if (target_platform == "iphoneos") {
      if (target_environment == "simulator") {
        rust_abi_target = "aarch64-apple-ios-sim"
        cargo_target_abi = "sim"
      } else if (target_environment == "device") {
        rust_abi_target = "aarch64-apple-ios"
        cargo_target_abi = ""
      } else if (target_environment == "catalyst") {
        rust_abi_target = "aarch64-apple-ios-macabi"
        cargo_target_abi = "macabi"
      } else {
        assert(false, "unsupported target_environment=$target_environment")
      }
    } else if (target_platform == "tvos") {
      if (target_environment == "simulator") {
        rust_abi_target = "aarch64-apple-tvos-sim"
        cargo_target_abi = "sim"
      } else if (target_environment == "device") {
        rust_abi_target = "aarch64-apple-tvos"
        cargo_target_abi = ""
      } else {
        assert(false, "unsupported target_environment=$target_environment")
      }
    } else {
      assert(false, "unsupported target_platform=$target_platform")
    }
  } else if (current_cpu == "arm") {
    rust_abi_target = "armv7s-apple-ios"
    cargo_target_abi = ""
  } else if (current_cpu == "x64") {
    if (target_platform == "iphoneos") {
      if (target_environment == "simulator") {
        rust_abi_target = "x86_64-apple-ios"
        cargo_target_abi = "sim"
      } else if (target_environment == "catalyst") {
        rust_abi_target = "x86_64-apple-ios-macabi"
        cargo_target_abi = "macabi"
      } else {
        assert(false, "unsupported target_environment=$target_environment")
      }
    } else if (target_platform == "tvos") {
      if (target_environment == "simulator") {
        rust_abi_target = "x86_64-apple-tvos"
        cargo_target_abi = "sim"
      } else {
        assert(false, "unsupported target_environment=$target_environment")
      }
    } else {
      assert(false, "unsupported target_platform=$target_platform")
    }
  } else if (current_cpu == "x86") {
    rust_abi_target = "i386-apple-ios"
  } else {
    assert(false, "Architecture not supported")
  }
} else if (is_mac) {
  if (current_cpu == "arm64") {
    rust_abi_target = "aarch64-apple-darwin"
    cargo_target_abi = ""
  } else if (current_cpu == "x64") {
    rust_abi_target = "x86_64-apple-darwin"
    cargo_target_abi = ""
  } else {
    assert(false, "Architecture not supported")
  }
} else if (is_win) {
  if (current_cpu == "arm64") {
    rust_abi_target = "aarch64-pc-windows-msvc"
    cargo_target_abi = ""
  } else if (current_cpu == "x64") {
    rust_abi_target = "x86_64-pc-windows-msvc"
    cargo_target_abi = ""
  } else if (current_cpu == "x86") {
    rust_abi_target = "i686-pc-windows-msvc"
    cargo_target_abi = ""
  } else {
    assert(false, "Architecture not supported")
  }
}

if (toolchain_has_rust) {
  assert(rust_abi_target != "")

  _known_rust_target_triples_filepath = "//build/rust/known-target-triples.txt"
  _is_rust_abi_target_a_known_triple = false
  _known_rust_target_triples_ =
      read_file(_known_rust_target_triples_filepath, "list lines")
  foreach(_known_triple, _known_rust_target_triples_) {
    if (_known_triple == rust_abi_target) {
      _is_rust_abi_target_a_known_triple = true
    }
  }
  assert(_is_rust_abi_target_a_known_triple,
         "`${rust_abi_target}` needs to be added to " +
             "`//${_known_rust_target_triples_filepath}`")
}

# This variable is passed to the Rust libstd build.
rust_target_arch = ""
if (current_cpu == "x86") {
  rust_target_arch = "x86"
} else if (current_cpu == "x64") {
  rust_target_arch = "x86_64"
} else if (current_cpu == "arm") {
  rust_target_arch = "arm"
} else if (current_cpu == "arm64") {
  rust_target_arch = "aarch64"
} else if (current_cpu == "arm64e") {
  rust_target_arch = "arm64e"
} else if (current_cpu == "mipsel") {
  rust_target_arch = "mips"
} else if (current_cpu == "mips64el") {
  rust_target_arch = "mips64"
} else if (current_cpu == "s390x") {
  rust_target_arch = "s390x"
} else if (current_cpu == "ppc64") {
  rust_target_arch = "powerpc64"
} else if (current_cpu == "riscv64") {
  rust_target_arch = "riscv64"
} else if (current_cpu == "loong64") {
  rust_target_arch = "loongarch64"
}

assert(!toolchain_has_rust || rust_target_arch != "")

# Arguments for Rust invocation.
# This is common between gcc/clang, Mac and Windows toolchains so specify once,
# here. This is not the complete command-line: toolchains should add -o
# and probably --emit arguments too.
rustc_common_args = "--crate-name {{crate_name}} {{source}} --crate-type {{crate_type}} {{rustflags}}"

# Rust procedural macros are shared objects loaded into a prebuilt host rustc
# binary. To build them, we obviously need to build for the host. Not only
# that, but because the host rustc is prebuilt, it lacks the machinery to be
# able to load shared objects built using sanitizers (ASAN etc.). For that
# reason, we need to use a host toolchain that lacks sanitizers. Additionally,
# proc macros should use panic=unwind, which means they need a stdlib that is
# compiled the same way, as is the stdlib that we ship with the compiler.
if (toolchain_for_rust_host_build_tools) {
  rust_macro_toolchain = current_toolchain
} else {
  rust_macro_toolchain = "${host_toolchain}_for_rust_host_build_tools"
}

# When this is true, a prebuilt Rust stdlib will be used. This has implications
# such as that the panic strategy (unwind, abort) must match how the stdlib is
# compiled, which is typically as unwind.
rust_prebuilt_stdlib =
    !use_chromium_rust_toolchain || toolchain_for_rust_host_build_tools