153 lines
4.6 KiB
Text
153 lines
4.6 KiB
Text
# Copyright 2021 The Chromium Authors. All rights reserved.
|
|
# Use of this source code is governed by a BSD-style license that can be
|
|
# found in the LICENSE file.
|
|
|
|
# This file provides the ability for our C++ toolchain to successfully
|
|
# link binaries containing arbitrary Rust code.
|
|
#
|
|
# By "arbitrary Rust code" I mean .rlib archives full of Rust code, which
|
|
# is actually a static archive.
|
|
#
|
|
# Those static libraries don't link as-is into a final executable because
|
|
# they're designed for downstream processing by further invocations of rustc
|
|
# which link into a final binary. That final invocation of rustc knows how
|
|
# to do two things:
|
|
# * Find the Rust standard library.
|
|
# * Remap some generic allocator symbols to the specific allocator symbols
|
|
# in use.
|
|
# This file does both those things. Any C++ target containing Rust .rlibs
|
|
# should simply depend on :std within this file and it will be taken care of.
|
|
# In practice, this will in future be taken care of by a standard template
|
|
# used for each Rust source set, so that a typical user of Rust need not
|
|
# think about it.
|
|
#
|
|
# This is obviously a bit fragile - rustc might do other magic in future.
|
|
# But, linking with a final C++ toolchain is something often needed, and
|
|
# https://github.com/rust-lang/rust/issues/64191 aims to make this
|
|
# officially possible.
|
|
|
|
import("//chromium/build/config/compiler/compiler.gni")
|
|
import("//chromium/build/config/rust.gni")
|
|
|
|
stdlib_files = [
|
|
"std", # List first because it makes depfiles more debuggable (see below)
|
|
"addr2line",
|
|
"adler",
|
|
"alloc",
|
|
"cfg_if",
|
|
"compiler_builtins",
|
|
"core",
|
|
"getopts",
|
|
"gimli",
|
|
"hashbrown",
|
|
"libc",
|
|
"miniz_oxide",
|
|
"object",
|
|
"panic_abort",
|
|
"panic_unwind",
|
|
"proc_macro",
|
|
"rustc_demangle",
|
|
"std_detect",
|
|
"term",
|
|
"test",
|
|
"unicode_width",
|
|
"unwind",
|
|
]
|
|
|
|
if (!use_unverified_rust_toolchain) {
|
|
# rlib files which are distributed alongside Rust's prebuilt stdlib, but we
|
|
# don't need to pass to the C++ linker because they're used for specialized
|
|
# purposes.
|
|
skip_stdlib_files = [
|
|
"profiler_builtins",
|
|
"rustc_std_workspace_alloc",
|
|
"rustc_std_workspace_core",
|
|
"rustc_std_workspace_std",
|
|
]
|
|
}
|
|
|
|
if (toolchain_has_rust) {
|
|
action("find_stdlib") {
|
|
# Specifics of what we're doing here.
|
|
#
|
|
# We are using prebuilt Rust rlibs supplied along with the toolchain.
|
|
# The Rust standard library consists of rlibs with roughly all the names
|
|
# above.
|
|
#
|
|
# However, their filenames are not predictable, and therefore we can't
|
|
# have ninja rules which depend upon them. (gn offers a facility to
|
|
# build rules dynamically, but it's frowned upon because a script needs
|
|
# to run each time).
|
|
#
|
|
# Instead therefore we copy these unpredictable .rlib paths to apredictable
|
|
# location. That's what this script does. Furthermore, it generates a
|
|
# .d file in order to teach Ninja that it only needs to do this copying
|
|
# once, unless the source .rlibs change.
|
|
#
|
|
# The script accepts the list of known libraries and will raise an
|
|
# exception if the list on disk differs. (Either 'Found stdlib rlib
|
|
# that wasn't expected' or 'We failed to find all expected stdlib
|
|
# rlibs').
|
|
script = "find_std_rlibs.py"
|
|
depfile = "$target_out_dir/stdlib.d"
|
|
out_libdir = rebase_path(target_out_dir, root_build_dir)
|
|
out_depfile = rebase_path(depfile, root_build_dir)
|
|
args = [
|
|
"--rust-bin-dir",
|
|
rust_prefix,
|
|
"--output",
|
|
out_libdir,
|
|
"--depfile",
|
|
out_depfile,
|
|
|
|
# Due to limitations in Ninja's handling of .d files, we have to pick
|
|
# *the first* of our outputs. To make diagnostics more obviously
|
|
# related to the Rust standard library, we ensure libstd.rlib is first.
|
|
"--depfile-target",
|
|
stdlib_files[0],
|
|
]
|
|
if (!use_unverified_rust_toolchain) {
|
|
args += [
|
|
"--stdlibs",
|
|
string_join(",", stdlib_files),
|
|
"--skip",
|
|
string_join(",", skip_stdlib_files),
|
|
]
|
|
}
|
|
if (rust_abi_target != "") {
|
|
args += [
|
|
"--target",
|
|
rust_abi_target,
|
|
]
|
|
}
|
|
|
|
outputs = []
|
|
foreach(lib, stdlib_files) {
|
|
outputs += [ "$target_out_dir/lib$lib.rlib" ]
|
|
}
|
|
}
|
|
|
|
config("rust_stdlib_config") {
|
|
ldflags = []
|
|
out_libdir = rebase_path(target_out_dir, root_build_dir)
|
|
foreach(lib, stdlib_files) {
|
|
this_file = "$out_libdir/lib$lib.rlib"
|
|
ldflags += [ this_file ]
|
|
}
|
|
}
|
|
|
|
source_set("remap_alloc") {
|
|
sources = [
|
|
"immediate_crash.h",
|
|
"remap_alloc.c",
|
|
]
|
|
}
|
|
|
|
group("std") {
|
|
all_dependent_configs = [ ":rust_stdlib_config" ]
|
|
deps = [
|
|
":find_stdlib",
|
|
":remap_alloc",
|
|
]
|
|
}
|
|
}
|