311 lines
12 KiB
Plaintext
311 lines
12 KiB
Plaintext
# 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")
|
|
}
|
|
|
|
declare_args() {
|
|
# Whether to allow Rust code to be part of the Chromium *build process*.
|
|
# This can be used to create Rust test binaries, even if the flag below
|
|
# is false.
|
|
# This only applies to Chromium itself, so the build_with_chromium check
|
|
# should not be removed.
|
|
# TODO(crbug.com/1386212): Mac
|
|
# TODO(crbug.com/1271215): Windows
|
|
# TODO(crbug.com/1426472): use_clang_coverage
|
|
# TODO(crbug.com/1427362): using_sanitizer
|
|
# TODO(crbug.com/1427364): target_cpu != "x86"
|
|
# There is no specific bug for !is_official_build or other platforms, since
|
|
# this is just a matter of rolling things out slowly and carefully and there
|
|
# may be no actual bugs there.
|
|
enable_rust = (is_linux || is_android) && !is_official_build &&
|
|
!using_sanitizer && target_cpu != "x86" &&
|
|
!use_clang_coverage && is_clang && build_with_chromium
|
|
|
|
# As we incrementally enable Rust on mainstream builders, we want to enable
|
|
# the toolchain (by switching 'enable_rust' to true) while still disabling
|
|
# almost all Rust features). Yet we still want to have some builders with
|
|
# all Rust features enabled.
|
|
enable_all_rust_features = false
|
|
|
|
# Use the Rust toolchain built in-tree. See //tools/rust.
|
|
use_chromium_rust_toolchain = true
|
|
|
|
# Build libstd locally with GN and use that instead of the prebuilts, where
|
|
# applicable. If this is false the prebuilt libstd will always be used. If
|
|
# true, the local build is only used with the Chromium Rust toolchain and only
|
|
# on supported platforms and GN targets.
|
|
enable_local_libstd = true
|
|
|
|
# Chromium currently has a Rust toolchain for Android and Linux, but
|
|
# if you wish to experiment on more platforms you can use this
|
|
# argument to specify an alternative toolchain.
|
|
# This should be an absolute path to a directory
|
|
# containing a 'bin' directory and others. Commonly
|
|
# <home dir>/.rustup/toolchains/nightly-<something>-<something>
|
|
rust_sysroot_absolute = ""
|
|
|
|
# If you're using an external Rust toolchain, set this to a Rust
|
|
# the output of rustc -V.
|
|
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
|
|
|
|
# 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 = []
|
|
|
|
# Use goma for Rust builds. Experimental. The only known problem is
|
|
# b/193072381, but then again, we don't expect a build speedup before much
|
|
# more work is done.
|
|
use_goma_rust = false
|
|
|
|
# The host toolchain to use when you don't want sanitizers enabled. By default
|
|
# it is the regular toolchain, but when that toolchain has sanitizers, then
|
|
# this variable is changed to avoid them.
|
|
host_toolchain_no_sanitizers = host_toolchain
|
|
}
|
|
|
|
declare_args() {
|
|
# Use a separate declare_args so these variables' defaults can depend on the
|
|
# ones above.
|
|
|
|
# When true, uses the locally-built std in all Rust targets.
|
|
#
|
|
# As an internal implementation detail this can be overridden on specific
|
|
# targets (e.g. to run build.rs scripts while building std), but this
|
|
# generally should not be done.
|
|
use_local_std_by_default = enable_local_libstd && use_chromium_rust_toolchain
|
|
|
|
# Individual Rust components.
|
|
|
|
# Conversions between Rust types and C++ types.
|
|
enable_rust_base_conversions = enable_all_rust_features
|
|
|
|
# The base::JSONReader implementation. Requires base conversions.
|
|
enable_rust_json = enable_all_rust_features
|
|
|
|
# Support for chrome://crash-rust to check crash dump collection works.
|
|
enable_rust_crash = enable_all_rust_features
|
|
|
|
# Support for Rust mojo bindings.
|
|
enable_rust_mojo = enable_all_rust_features
|
|
|
|
# Support for the 'gnrt' Rust tool.
|
|
enable_rust_gnrt = enable_all_rust_features
|
|
|
|
# Rust gtest interop
|
|
enable_rust_gtest_interop = enable_all_rust_features
|
|
|
|
# Enable Boringssl Rust bindings generation
|
|
enable_rust_boringssl = enable_all_rust_features
|
|
}
|
|
|
|
# Platform support for "official" toolchains (Android or Chromium)
|
|
android_toolchain_supports_platform =
|
|
(!is_nacl &&
|
|
(is_android && (current_cpu == "arm" || current_cpu == "arm64" ||
|
|
current_cpu == "x64" || current_cpu == "x86"))) ||
|
|
(is_linux && current_cpu == "x64")
|
|
chromium_toolchain_supports_platform = !is_nacl
|
|
custom_toolchain_supports_platform = !is_nacl || rust_toolchain_supports_nacl
|
|
|
|
toolchain_has_rust =
|
|
enable_rust &&
|
|
((use_chromium_rust_toolchain && chromium_toolchain_supports_platform) ||
|
|
(!use_chromium_rust_toolchain && android_toolchain_supports_platform) ||
|
|
(rust_sysroot_absolute != "" && custom_toolchain_supports_platform))
|
|
|
|
# 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 (toolchain_has_rust) {
|
|
if (use_chromium_rust_toolchain) {
|
|
update_rust_args = [ "--print-package-version" ]
|
|
rustc_revision = exec_script("//tools/rust/update_rust.py",
|
|
update_rust_args,
|
|
"trim string")
|
|
} else if (rust_sysroot_absolute != "") {
|
|
rustc_revision = rustc_version
|
|
} else {
|
|
# Android toolchain version.
|
|
rustc_revision = "rustc 1.64.0-dev (Android Rust Toolchain version 9099361)"
|
|
}
|
|
}
|
|
|
|
# TODO(crbug.com/1278030): 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
|
|
|
|
# Whether to build chrome://crash/rust support.
|
|
build_rust_crash = toolchain_has_rust && enable_rust_crash
|
|
|
|
# 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 (rust_sysroot_absolute != "") {
|
|
rust_sysroot = get_path_info(rust_sysroot_absolute, "abspath")
|
|
use_unverified_rust_toolchain = true
|
|
} else if (use_chromium_rust_toolchain) {
|
|
rust_sysroot = "//third_party/rust-toolchain"
|
|
use_unverified_rust_toolchain = false
|
|
} else {
|
|
if (host_os != "linux") {
|
|
assert(false,
|
|
"Attempt to use Android Rust toolchain on an unsupported platform")
|
|
}
|
|
|
|
rust_sysroot = "//third_party/android_rust_toolchain/toolchain"
|
|
use_unverified_rust_toolchain = false
|
|
extra_sysroot_libs += [ "libunwind.a" ]
|
|
}
|
|
}
|
|
|
|
# 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.
|
|
rust_abi_target = ""
|
|
if (is_linux || is_chromeos) {
|
|
cpu = current_cpu
|
|
if (cpu == "arm64") {
|
|
cpu = "aarch64"
|
|
} else if (cpu == "x64") {
|
|
cpu = "x86_64"
|
|
}
|
|
rust_abi_target = cpu + "-unknown-linux-gnu"
|
|
} else if (is_android) {
|
|
import("//build/config/android/abi.gni")
|
|
rust_abi_target = android_abi_target
|
|
if (rust_abi_target == "arm-linux-androideabi") {
|
|
# Android clang target specifications mostly match Rust, but this
|
|
# is an exception
|
|
rust_abi_target = "armv7-linux-androideabi"
|
|
}
|
|
} else if (is_fuchsia) {
|
|
if (current_cpu == "arm64") {
|
|
rust_abi_target = "aarch64-fuchsia"
|
|
} else if (current_cpu == "x64") {
|
|
rust_abi_target = "x86_64-fuchsia"
|
|
} else {
|
|
assert(false, "Architecture not supported")
|
|
}
|
|
} else if (is_ios) {
|
|
if (current_cpu == "arm64") {
|
|
rust_abi_target = "aarch64-apple-ios"
|
|
} else if (current_cpu == "arm") {
|
|
# There's also an armv7s-apple-ios, which targets a more recent ARMv7
|
|
# generation CPU found in later iPhones. We'll go with the older one for
|
|
# maximal compatibility. As we come to support all the different platforms
|
|
# with Rust, we might want to be more precise here.
|
|
rust_abi_target = "armv7-apple-ios"
|
|
} else if (current_cpu == "x64") {
|
|
rust_abi_target = "x86_64-apple-ios"
|
|
} 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"
|
|
} else if (current_cpu == "x64") {
|
|
rust_abi_target = "x86_64-apple-darwin"
|
|
} else {
|
|
assert(false, "Architecture not supported")
|
|
}
|
|
} else if (is_win) {
|
|
if (current_cpu == "arm64") {
|
|
rust_abi_target = "aarch64-pc-windows-msvc"
|
|
} else if (current_cpu == "x86" || current_cpu == "x64") {
|
|
rust_abi_target = "x86_64-pc-windows-msvc"
|
|
} else {
|
|
assert(false, "Architecture not supported")
|
|
}
|
|
}
|
|
|
|
assert(!toolchain_has_rust || rust_abi_target != "")
|
|
|
|
# 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 == "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"
|
|
}
|
|
|
|
assert(!toolchain_has_rust || rust_target_arch != "")
|
|
|
|
# Must use Chromium Rust toolchain to get precisely matching LLVM versions
|
|
# in order to enable LTO. Some say that LTO probably works if LLVM is "close
|
|
# enough", but we don't want to take that risk.
|
|
assert(!use_thin_lto || !enable_rust || use_chromium_rust_toolchain ||
|
|
use_unverified_rust_toolchain,
|
|
"Must use Chromium Rust toolchain for LTO")
|
|
|
|
# Determine whether the local libstd can and should be built.
|
|
local_libstd_supported = enable_local_libstd && use_chromium_rust_toolchain
|
|
|
|
# Determine whether the prebuilt libstd can be used
|
|
prebuilt_libstd_supported = !use_chromium_rust_toolchain ||
|
|
(target_os == "linux" && target_cpu == "x64")
|
|
|
|
# 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. This is only strictly necessary
|
|
# for procedural macros, but we may also choose to build standalone Rust host
|
|
# executable tools using the same toolchain, as they're likely to depend upon
|
|
# similar dependencies (syn, quote etc.) and it saves a little build time.
|
|
if (using_sanitizer || toolchain_disables_sanitizers) {
|
|
host_toolchain_no_sanitizers = "${host_toolchain}_no_sanitizers"
|
|
}
|