tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

rust.gni (16002B)


      1 # Copyright 2021 The Chromium Project. All rights reserved.
      2 # Use of this source code is governed by a BSD-style license that can be
      3 # found in the LICENSE file.
      4 
      5 import("//chromium/build/config/chrome_build.gni")
      6 import("//chromium/build/config/compiler/compiler.gni")
      7 import("//chromium/build/config/sanitizers/sanitizers.gni")
      8 import("//chromium/build/toolchain/toolchain.gni")
      9 
     10 if (is_android) {
     11   import("//chromium/build/config/android/config.gni")
     12 }
     13 
     14 if (is_ios) {
     15   # For `target_environment` and `target_platform`.
     16   import("//chromium/build/config/apple/mobile_config.gni")
     17 }
     18 
     19 declare_args() {
     20   # Rust is available in the Chromium build but 3p repos that use //build may
     21   # not use Rust and thus won't want to depend on having the Rust toolchain
     22   # present, so this defaults to off in those cases.
     23   #
     24   # Chromium-based projects that are built for for architectures Chrome does not
     25   # support may need to disable this as well, though they may need to replace
     26   # code with C/C++ to get a functional product.
     27   #
     28   # Based on the above:
     29   #
     30   # * `enable_rust` may be consulted under `//build` and `//testing` directories
     31   #   (which may be used outside of Chromium build)
     32   # * `enable_rust` should *not* be consulted in other Chromium directories
     33   #   (including `//base`, `//net`, etc.)
     34   enable_rust = build_with_chromium
     35 
     36   # The CXX tool is in //third_party/rust which is not shared with downstream
     37   # projects yet. So they need to copy the required dependencies and GN files
     38   # into their project to enable CXX there.
     39   #
     40   # We do not support disabling this flag in Chromium code.
     41   enable_rust_cxx = build_with_chromium
     42 
     43   # The chromium prelude crate provides the `chromium::import!` macro which
     44   # is needed to depend on first-party rust libraries. Third-party libraries
     45   # are specified with cargo_crate and do not get imported through this macro.
     46   #
     47   # The macro requires //third_party/rust for syn, quote, and proc_macro2.
     48   # Downstream projects that want to use //build for the rust GN templates but
     49   # don't want to enable the chromium prelude can disable it here, and should
     50   # specify a globally unique `crate_name` in their rust library GN rules
     51   # instead. Note that using a `crate_name` is strongly discouraged inside
     52   # Chromium, and is also discouraged for downstream projects when possible.
     53   #
     54   # We do not support disabling this flag in Chromium code.
     55   enable_chromium_prelude = build_with_chromium
     56 
     57   # Chromium provides a Rust toolchain in //third_party/rust-toolchain.
     58   #
     59   # To use a custom toolchain instead, specify an absolute path to the root of
     60   # a Rust sysroot, which will have a 'bin' directory and others. Commonly
     61   # <home dir>/.rustup/toolchains/nightly-<something>-<something>
     62   rust_sysroot_absolute = ""
     63 
     64   # Directory under which to find `bin/bindgen` (a `bin` directory containing
     65   # the bindgen exectuable).
     66   rust_bindgen_root = "//third_party/rust-toolchain"
     67 
     68   # If you're using a Rust toolchain as specified by rust_sysroot_absolute,
     69   # set this to the output of `rustc -V`. Changing this string will cause all
     70   # Rust targets to be rebuilt, which allows you to update your toolchain and
     71   # not break incremental builds.
     72   rustc_version = ""
     73 
     74   # If you're using a Rust toolchain as specified by rust_sysroot_absolute,
     75   # you can specify whether it supports nacl here.
     76   rust_toolchain_supports_nacl = false
     77 
     78   # Whether artifacts produced by the Rust compiler can participate in ThinLTO.
     79   #
     80   # One important consideration is whether the linker uses the same LLVM
     81   # version as `rustc` (i.e. if it can understand the LLVM-IR from the
     82   # compilation artifacts produced by `rustc`).  In LaCrOS and ash builds this
     83   # may not be true - see b/299483903.
     84   #
     85   # TODO(crbug.com/40281834): Re-enable ThinLTO for Rust on LaCrOS
     86   # TODO(b/300937673): Re-enable ThinLTO for Rust on ash-chrome
     87   toolchain_supports_rust_thin_lto = !is_chromeos
     88 
     89   # Any extra std rlibs in your Rust toolchain, relative to the standard
     90   # Rust toolchain. Typically used with 'rust_sysroot_absolute'
     91   added_rust_stdlib_libs = []
     92 
     93   # Any removed std rlibs in your Rust toolchain, relative to the standard
     94   # Rust toolchain. Typically used with 'rust_sysroot_absolute'
     95   removed_rust_stdlib_libs = []
     96 
     97   # Non-rlib libs provided in the toolchain sysroot. Usually this is empty, but
     98   # e.g. the Android Rust Toolchain provides a libunwind.a that rustc expects.
     99   extra_sysroot_libs = []
    100 
    101   # Force-enable `--color=always` for rustc, even when it would be disabled for
    102   # a platform. Mostly applicable to Windows, where new versions can handle ANSI
    103   # escape sequences but it's not reliable in general.
    104   force_rustc_color_output = false
    105 }
    106 
    107 # Use the Rust toolchain built in-tree. When false, we use the prebuilt Rust
    108 # stdlibs that come with the specified custom toolchain.
    109 use_chromium_rust_toolchain = rust_sysroot_absolute == ""
    110 
    111 # Platform support for the Rust toolchain.
    112 chromium_toolchain_supports_platform = !is_nacl && !is_wasm
    113 custom_toolchain_supports_platform = !is_nacl || rust_toolchain_supports_nacl
    114 
    115 # Not all target triples (GN toolchains) are supported by the Rust compiler.
    116 # Define if we support the current GN toolchain.
    117 toolchain_has_rust = false
    118 
    119 # The rustc_revision is used to introduce a dependency on the toolchain version
    120 # (so e.g. rust targets are rebuilt, and the standard library is re-copied when
    121 # the toolchain changes). It is left empty for custom toolchains.
    122 rustc_revision = ""
    123 
    124 if (enable_rust) {
    125   if (use_chromium_rust_toolchain) {
    126     toolchain_has_rust = chromium_toolchain_supports_platform
    127     if (toolchain_has_rust) {
    128       update_rust_args = [ "--print-package-version" ]
    129       rustc_revision = exec_script("//tools/rust/update_rust.py",
    130                                    update_rust_args,
    131                                    "trim string")
    132     }
    133 
    134     # The same as written in `config.toml.template`.
    135     rust_channel = "dev"
    136   } else {
    137     toolchain_has_rust = custom_toolchain_supports_platform
    138     rustc_revision = rustc_version
    139   }
    140 }
    141 
    142 # TODO(crbug.com/40809974): To build unit tests for Android we need to build
    143 # them as a dylib and put them into an APK. We should reuse all the same logic
    144 # for gtests from the `//testing/test:test` template.
    145 can_build_rust_unit_tests = toolchain_has_rust && !is_android
    146 
    147 # We want to store rust_sysroot as a source-relative variable for ninja
    148 # portability. In practice if an external toolchain was specified, it might
    149 # be an absolute path, but we'll do our best.
    150 if (enable_rust) {
    151   if (use_chromium_rust_toolchain) {
    152     rust_sysroot = "//third_party/rust-toolchain"
    153   } else {
    154     rust_sysroot = get_path_info(rust_sysroot_absolute, "abspath")
    155   }
    156 }
    157 
    158 # Figure out the Rust target triple (aka 'rust_abi_target')
    159 #
    160 # This is here rather than in the toolchain files because it's used also by
    161 # //build/rust/std to find the Rust standard library and construct a sysroot for
    162 # rustc invocations.
    163 #
    164 # The list of architectures supported by Rust is here:
    165 # https://doc.rust-lang.org/nightly/rustc/platform-support.html. We map Chromium
    166 # targets to Rust targets comprehensively despite not having official support
    167 # (see '*_toolchain_supports_platform above') to enable experimentation with
    168 # other toolchains.
    169 #
    170 # The `cargo_target_abi` is the `target_abi` given by Cargo to build scripts
    171 # as the `CARGO_CFG_TARGET_ABI` environment variable. It is determined for
    172 # each `rust_abi_target` by doing `cargo build --target $rust_abi_target` with
    173 # a cargo project that dumps the `CARGO_CFG_TARGET_ABI` from its build.rs. See
    174 # https://issues.chromium.org/u/1/issues/372512092#comment5 for an example.
    175 rust_abi_target = ""
    176 if (is_linux || is_chromeos) {
    177   if (target_cpu == "arm64") {
    178     rust_abi_target = "aarch64-unknown-linux-gnu"
    179     cargo_target_abi = ""
    180   } else if (target_cpu == "x86") {
    181     rust_abi_target = "i686-unknown-linux-gnu"
    182     cargo_target_abi = ""
    183   } else if (target_cpu == "x64") {
    184     rust_abi_target = "x86_64-unknown-linux-gnu"
    185     cargo_target_abi = ""
    186   } else if (target_cpu == "arm") {
    187     if (arm_float_abi == "hard") {
    188       float_suffix = "hf"
    189     } else {
    190       float_suffix = ""
    191     }
    192     if (arm_arch == "armv7-a" || arm_arch == "armv7") {
    193       # We have no way to inform Rust about the -a suffix, so we end up
    194       # targeting armv7 in both cases.
    195       #
    196       # We also try to propagate the availability of NEON without feature
    197       # detection; in C++ this is done by -mfpu=neon, but in Rust we need to
    198       # use a different ABI target.
    199       #
    200       # The thumbv7 vs. armv7 distinction is for legacy reasons and both
    201       # targets in fact target Thumb, see:
    202       # https://github.com/rust-lang/rust/issues/44722
    203       if (arm_use_neon) {
    204         rust_abi_target = "thumbv7neon-unknown-linux-gnueabi" + float_suffix
    205       } else {
    206         rust_abi_target = "armv7-unknown-linux-gnueabi" + float_suffix
    207       }
    208       cargo_target_abi = "eabi" + float_suffix
    209     } else {
    210       rust_abi_target = "arm-unknown-linux-gnueabi" + float_suffix
    211       cargo_target_abi = "eabi" + float_suffix
    212     }
    213   } else if (target_cpu == "riscv64") {
    214     rust_abi_target = "riscv64gc-unknown-linux-gnu"
    215     cargo_target_abi = ""
    216   } else {
    217     # Best guess for other future platforms.
    218     rust_abi_target = target_cpu + "-unknown-linux-gnu"
    219     cargo_target_abi = ""
    220   }
    221 } else if (is_android) {
    222   import("//chromium/build/config/android/abi.gni")
    223   if (android_abi_target == "i686-linux-android") {
    224     rust_abi_target = android_abi_target
    225     cargo_target_abi = ""
    226   } else if (android_abi_target == "arm-linux-androideabi") {
    227     # Android clang target specifications mostly match Rust, but this
    228     # is an exception.
    229     # See section above for Linux for thumbv7neon vs. armv7.
    230     # Note that on Android, NEON is enabled for all builds except Cronet.
    231     if (arm_use_neon) {
    232       rust_abi_target = "thumbv7neon-linux-androideabi"
    233     } else {
    234       rust_abi_target = "armv7-linux-androideabi"
    235     }
    236     cargo_target_abi = "eabi"
    237   } else if (android_abi_target == "mipsel-linux-android") {
    238     # There is no MIPS android target.
    239     rust_abi_target = ""
    240     cargo_target_abi = ""
    241   } else if (android_abi_target == "x86_64-linux-android") {
    242     rust_abi_target = android_abi_target
    243     cargo_target_abi = ""
    244   } else if (android_abi_target == "aarch64-linux-android") {
    245     rust_abi_target = android_abi_target
    246     cargo_target_abi = ""
    247   } else if (android_abi_target == "mips64el-linux-android") {
    248     # There is no MIPS android target.
    249     rust_abi_target = ""
    250     cargo_target_abi = ""
    251   } else if (android_abi_target == "riscv64-linux-android") {
    252     rust_abi_target = android_abi_target
    253     cargo_target_abi = ""
    254   } else {
    255     assert(false, "Unknown Android ABI: " + android_abi_target)
    256   }
    257 } else if (is_fuchsia) {
    258   if (target_cpu == "arm64") {
    259     rust_abi_target = "aarch64-unknown-fuchsia"
    260     cargo_target_abi = ""
    261   } else if (target_cpu == "x64") {
    262     rust_abi_target = "x86_64-unknown-fuchsia"
    263     cargo_target_abi = ""
    264   } else {
    265     assert(false, "Architecture not supported")
    266   }
    267 } else if (is_ios) {
    268   if (target_cpu == "arm64") {
    269     if (target_platform == "iphoneos") {
    270       if (target_environment == "simulator") {
    271         rust_abi_target = "aarch64-apple-ios-sim"
    272         cargo_target_abi = "sim"
    273       } else if (target_environment == "device") {
    274         rust_abi_target = "aarch64-apple-ios"
    275         cargo_target_abi = ""
    276       } else if (target_environment == "catalyst") {
    277         rust_abi_target = "aarch64-apple-ios-macabi"
    278         cargo_target_abi = "macabi"
    279       } else {
    280         assert(false, "unsupported target_environment=$target_environment")
    281       }
    282     } else if (target_platform == "tvos") {
    283       if (target_environment == "simulator") {
    284         rust_abi_target = "aarch64-apple-tvos-sim"
    285         cargo_target_abi = "sim"
    286       } else if (target_environment == "device") {
    287         rust_abi_target = "aarch64-apple-tvos"
    288         cargo_target_abi = ""
    289       } else {
    290         assert(false, "unsupported target_environment=$target_environment")
    291       }
    292     } else {
    293       assert(false, "unsupported target_platform=$target_platform")
    294     }
    295   } else if (target_cpu == "arm") {
    296     rust_abi_target = "armv7s-apple-ios"
    297     cargo_target_abi = ""
    298   } else if (target_cpu == "x64") {
    299     if (target_platform == "iphoneos") {
    300       if (target_environment == "simulator") {
    301         rust_abi_target = "x86_64-apple-ios"
    302         cargo_target_abi = "sim"
    303       } else if (target_environment == "catalyst") {
    304         rust_abi_target = "x86_64-apple-ios-macabi"
    305         cargo_target_abi = "macabi"
    306       } else {
    307         assert(false, "unsupported target_environment=$target_environment")
    308       }
    309     } else if (target_platform == "tvos") {
    310       if (target_environment == "simulator") {
    311         rust_abi_target = "x86_64-apple-tvos"
    312         cargo_target_abi = "sim"
    313       } else {
    314         assert(false, "unsupported target_environment=$target_environment")
    315       }
    316     } else {
    317       assert(false, "unsupported target_platform=$target_platform")
    318     }
    319   } else if (target_cpu == "x86") {
    320     rust_abi_target = "i386-apple-ios"
    321   } else {
    322     assert(false, "Architecture not supported")
    323   }
    324 } else if (is_mac) {
    325   if (target_cpu == "arm64") {
    326     rust_abi_target = "aarch64-apple-darwin"
    327     cargo_target_abi = ""
    328   } else if (target_cpu == "x64") {
    329     rust_abi_target = "x86_64-apple-darwin"
    330     cargo_target_abi = ""
    331   } else {
    332     assert(false, "Architecture not supported")
    333   }
    334 } else if (is_win) {
    335   if (target_cpu == "arm64") {
    336     rust_abi_target = "aarch64-pc-windows-msvc"
    337     cargo_target_abi = ""
    338   } else if (target_cpu == "x64") {
    339     rust_abi_target = "x86_64-pc-windows-msvc"
    340     cargo_target_abi = ""
    341   } else if (target_cpu == "x86") {
    342     rust_abi_target = "i686-pc-windows-msvc"
    343     cargo_target_abi = ""
    344   } else {
    345     assert(false, "Architecture not supported")
    346   }
    347 }
    348 
    349 assert(!toolchain_has_rust || rust_abi_target != "")
    350 
    351 # This variable is passed to the Rust libstd build.
    352 rust_target_arch = ""
    353 if (target_cpu == "x86") {
    354   rust_target_arch = "x86"
    355 } else if (target_cpu == "x64") {
    356   rust_target_arch = "x86_64"
    357 } else if (target_cpu == "arm") {
    358   rust_target_arch = "arm"
    359 } else if (target_cpu == "arm64") {
    360   rust_target_arch = "aarch64"
    361 } else if (target_cpu == "mipsel") {
    362   rust_target_arch = "mips"
    363 } else if (target_cpu == "mips64el") {
    364   rust_target_arch = "mips64"
    365 } else if (target_cpu == "s390x") {
    366   rust_target_arch = "s390x"
    367 } else if (target_cpu == "ppc64") {
    368   rust_target_arch = "powerpc64"
    369 } else if (target_cpu == "riscv64") {
    370   rust_target_arch = "riscv64"
    371 }
    372 
    373 assert(!toolchain_has_rust || rust_target_arch != "")
    374 
    375 # Arguments for Rust invocation.
    376 # This is common between gcc/clang, Mac and Windows toolchains so specify once,
    377 # here. This is not the complete command-line: toolchains should add -o
    378 # and probably --emit arguments too.
    379 rustc_common_args = "--crate-name {{crate_name}} {{source}} --crate-type {{crate_type}} {{rustflags}}"
    380 
    381 # Rust procedural macros are shared objects loaded into a prebuilt host rustc
    382 # binary. To build them, we obviously need to build for the host. Not only
    383 # that, but because the host rustc is prebuilt, it lacks the machinery to be
    384 # able to load shared objects built using sanitizers (ASAN etc.). For that
    385 # reason, we need to use a host toolchain that lacks sanitizers. Additionally,
    386 # proc macros should use panic=unwind, which means they need a stdlib that is
    387 # compiled the same way, as is the stdlib that we ship with the compiler.
    388 if (toolchain_for_rust_host_build_tools) {
    389   rust_macro_toolchain = current_toolchain
    390 } else {
    391   rust_macro_toolchain = "${host_toolchain}_for_rust_host_build_tools"
    392 }
    393 
    394 # When this is true, a prebuilt Rust stdlib will be used. This has implications
    395 # such as that the panic strategy (unwind, abort) must match how the stdlib is
    396 # compiled, which is typically as unwind.
    397 rust_prebuilt_stdlib =
    398     !use_chromium_rust_toolchain || toolchain_for_rust_host_build_tools