Skip to content

Commit

Permalink
Add Rust libstd GN bindings generated by gnrt
Browse files Browse the repository at this point in the history
This extends gnrt to output GN rules for Rust's libstd, checks in the
newly generated bindings, and adds a small Rust build test that uses
the newly-build std instead of the prebuilt one.

The GN libstd build is not used for all Rust targets yet.

Bug: 1368806
Change-Id: I079a0f703d28938fac2cea9b8684f91aa2909f97

Cq-Include-Trybots: luci.chromium.try:linux-rust-x64-rel,linux-rust-x64-dbg,android-rust-arm-rel,android-rust-arm-dbg
Change-Id: I079a0f703d28938fac2cea9b8684f91aa2909f97
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4150272
Reviewed-by: danakj <danakj@chromium.org>
Auto-Submit: Collin Baker <collinbaker@chromium.org>
Commit-Queue: Collin Baker <collinbaker@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1099576}
  • Loading branch information
chbaker0 authored and Chromium LUCI CQ committed Feb 1, 2023
1 parent d5aa724 commit e7607ff
Show file tree
Hide file tree
Showing 93 changed files with 1,320 additions and 184 deletions.
33 changes: 33 additions & 0 deletions build/config/rust.gni
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,12 @@ declare_args() {
# TODO(https://crbug.com/1245714): fix std handling and check `current_os`.
use_chromium_rust_toolchain = target_os == "linux" && host_os == "linux"

# 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.
Expand Down Expand Up @@ -180,6 +186,33 @@ if (is_linux) {

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 != "")

# Determine whether the local libstd can and should be built.
local_libstd_supported = enable_local_libstd && use_chromium_rust_toolchain

# 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
Expand Down
6 changes: 4 additions & 2 deletions build/rust/rust_target.gni
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ template("rust_target") {
# target that depends on a rust target directly may need access to Cxx
# as well, which means it must appear in public_deps.
public_deps += [ "//build/rust:cxx_cppdeps" ]
} else {
} else if (!defined(invoker.no_std) || !invoker.no_std) {
# If C++ depends on and links in the library, we need to make sure C++
# links in the Rust stdlib. This is orthogonal to if the library exports
# bindings for C++ to use.
Expand All @@ -259,7 +259,9 @@ template("rust_target") {
_rust_public_deps += [ ":${_target_name}_cxx_generated" ]
}

_rust_deps += [ "//build/rust/std:std_for_rustc" ]
if (!defined(invoker.no_std) || !invoker.no_std) {
_rust_deps += [ "//build/rust/std:prebuilt_std_for_rustc" ]
}

# You must go through the groups above to get to these targets.
_visibility = []
Expand Down
60 changes: 51 additions & 9 deletions build/rust/std/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -155,28 +155,68 @@ if (toolchain_has_rust) {
}
}

if (local_libstd_supported) {
# Builds the Rust standard library and creates a sysroot that can be
# supplied to rustc.
copy("local_rustc_sysroot") {
deps = []
sources = []

foreach(libname, stdlib_files + skip_stdlib_files) {
rule = "rules:$libname"
deps += [ rule ]
outdir = get_label_info(rule, "target_out_dir")
sources += [ "$outdir/$libname/lib${libname}.rlib" ]
}

outputs = [ "$target_out_dir/local_rustc_sysroot/lib/rustlib/$rust_abi_target/lib/{{source_file_part}}" ]
}
}

# Create a sysroot containing our std rlibs to pass to rustc invocations. This
# gives better control of where rustc may pick libraries from.
copy("rustc_sysroot") {
copy("prebuilt_rustc_sysroot") {
deps = [ ":find_stdlib" ]
sources = get_target_outputs(":find_stdlib")
outputs = [ "$target_out_dir/rustc_sysroot/lib/rustlib/$rust_abi_target/lib/{{source_file_part}}" ]
outputs = [ "$target_out_dir/prebuilt_rustc_sysroot/lib/rustlib/$rust_abi_target/lib/{{source_file_part}}" ]
}

config("rust_stdlib_for_rustc") {
# Match the output directory of :rustc_sysroot
sysroot = rebase_path("$target_out_dir/rustc_sysroot", root_build_dir)
if (local_libstd_supported) {
config("local_stdlib_for_rustc") {
# Match the output directory of :local_rustc_sysroot
sysroot =
rebase_path("$target_out_dir/local_rustc_sysroot", root_build_dir)
rustflags = [ "--sysroot=$sysroot" ]
}
}

config("prebuilt_stdlib_for_rustc") {
# Match the output directory of :prebuilt_rustc_sysroot
sysroot =
rebase_path("$target_out_dir/prebuilt_rustc_sysroot", root_build_dir)
rustflags = [ "--sysroot=$sysroot" ]
}

# Use the sysroot generated by :rustc_sysroot. All Rust targets should depend
if (local_libstd_supported) {
# Use the sysroot generated by :local_rustc_sysroot, which transitively builds
# std. Only for use in specific tests for now.
group("local_std_for_rustc") {
assert(
enable_rust,
"Some C++ target is including Rust code even though enable_rust=false")
all_dependent_configs = [ ":local_stdlib_for_rustc" ]
deps = [ ":local_rustc_sysroot" ]
}
}

# Use the sysroot generated by :prebuilt_rustc_sysroot. Almost all Rust targets should depend
# on this.
group("std_for_rustc") {
group("prebuilt_std_for_rustc") {
assert(
enable_rust,
"Some C++ target is including Rust code even though enable_rust=false")
all_dependent_configs = [ ":rust_stdlib_for_rustc" ]
deps = [ ":rustc_sysroot" ]
all_dependent_configs = [ ":prebuilt_stdlib_for_rustc" ]
deps = [ ":prebuilt_rustc_sysroot" ]
}

config("rust_stdlib_config") {
Expand All @@ -195,6 +235,8 @@ if (toolchain_has_rust) {
]
}

# TODO(crbug.com/1368806): rework this so when using locally-built std, we
# don't link the prebuilt std as well.
group("std") {
assert(
enable_rust,
Expand Down
5 changes: 5 additions & 0 deletions build/rust/std/fake_root/.cargo/config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[source.crates-io]
replace-with = 'vendored-sources'

[source.vendored-sources]
directory = '../../../../third_party/rust-toolchain/lib/rustlib/src/rust/vendor'
2 changes: 2 additions & 0 deletions build/rust/std/fake_root/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/target/
/Cargo.lock
16 changes: 16 additions & 0 deletions build/rust/std/fake_root/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
[package]
name = "fake_root"
version = "0.1.0"
edition = "2021"

[dependencies]
test = { path = "../../../../third_party/rust-toolchain/lib/rustlib/src/rust/library/test" }

[dependencies.std]
path = "../../../../third_party/rust-toolchain/lib/rustlib/src/rust/library/std"
features = ["backtrace", "profiler"]

[patch.crates-io]
rustc-std-workspace-core = { path = '../../../../third_party/rust-toolchain/lib/rustlib/src/rust/library/rustc-std-workspace-core' }
rustc-std-workspace-alloc = { path = '../../../../third_party/rust-toolchain/lib/rustlib/src/rust/library/rustc-std-workspace-alloc' }
rustc-std-workspace-std = { path = '../../../../third_party/rust-toolchain/lib/rustlib/src/rust/library/rustc-std-workspace-std' }
2 changes: 2 additions & 0 deletions build/rust/std/fake_root/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
This package is used to discover the libstd deps using `cargo metadata`. gnrt
uses it when generating libstd GN bindings.
3 changes: 3 additions & 0 deletions build/rust/std/fake_root/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

0 comments on commit e7607ff

Please sign in to comment.