| # 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) { |
| import("//build/config/ios/config.gni") # For `target_environment` |
| import("//build/config/ios/ios_sdk.gni") # For `xcode_version_int` |
| } |
| |
| 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. |
| enable_rust = build_with_chromium |
| |
| # 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. |
| enable_cxx = 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. |
| enable_chromium_prelude = 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 |
| |
| # 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 = "" |
| |
| # 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(https://crbug.com/1482525): 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 |
| } |
| |
| # Use a separate declare_args so these variables' defaults can depend on the |
| # ones above. |
| declare_args() { |
| # Individual Rust components. |
| |
| # Conversions between Rust types and C++ types. |
| enable_rust_base_conversions = enable_rust |
| |
| # The base::JSONReader implementation. Requires base conversions. |
| enable_rust_json = enable_rust && enable_all_rust_features |
| |
| # Support for chrome://crash-rust to check crash dump collection works. |
| enable_rust_crash = enable_rust |
| |
| # Support for Rust mojo bindings. |
| enable_rust_mojo = enable_rust && enable_all_rust_features |
| |
| # Rust gtest interop. |
| enable_rust_gtest_interop = enable_rust |
| |
| # Enable experimental Fontations Rust font stack. |
| use_typeface_fontations = 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 |
| 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) { |
| update_rust_args = [ "--print-package-version" ] |
| rustc_revision = exec_script("//tools/rust/update_rust.py", |
| update_rust_args, |
| "trim string") |
| } |
| |
| # 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/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 |
| |
| # 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") |
| } |
| |
| # Prebuilt toolchains won't come with bindgen, so we unconditionally use the |
| # bindgen we ship with the Rust toolchain. This could be made configurable |
| # if folks want to supply a bindgen with their toolchain. |
| rust_bindgen_root = "//third_party/rust-toolchain" |
| } |
| |
| # 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) { |
| if (current_cpu == "arm64") { |
| rust_abi_target = "aarch64-unknown-linux-gnu" |
| } else if (current_cpu == "x86") { |
| rust_abi_target = "i686-unknown-linux-gnu" |
| } else if (current_cpu == "x64") { |
| rust_abi_target = "x86_64-unknown-linux-gnu" |
| } else if (current_cpu == "arm") { |
| if (arm_float_abi == "hard") { |
| float_suffix = "hf" |
| } else { |
| float_suffix = "" |
| } |
| if (arm_arch == "armv7-a" || arm_arch == "armv7") { |
| # No way to inform Rust about the -a suffix. |
| rust_abi_target = "armv7-unknown-linux-gnueabi" + float_suffix |
| } else { |
| rust_abi_target = "arm-unknown-linux-gnueabi" + float_suffix |
| } |
| } else { |
| # Best guess for other future platforms. |
| rust_abi_target = current_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") { |
| if (target_environment == "simulator") { |
| rust_abi_target = "aarch64-apple-ios-sim" |
| } else if (target_environment == "catalyst") { |
| rust_abi_target = "aarch64-apple-ios-macabi" |
| } else { |
| 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") { |
| if (target_environment == "catalyst") { |
| rust_abi_target = "x86_64-apple-ios-macabi" |
| } else { |
| 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 == "x64") { |
| rust_abi_target = "x86_64-pc-windows-msvc" |
| } else if (current_cpu == "x86") { |
| rust_abi_target = "i686-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 != "") |
| |
| # 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 |