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