Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion WORKSPACE.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,12 @@ load("@rules_rust//rust:repositories.bzl", "rules_rust_dependencies", "rust_regi

rules_rust_dependencies()

rust_register_toolchains(include_rustc_srcs = True)
rust_register_toolchains(
dev_components = True,
include_rustc_srcs = True,
iso_date = "2022-01-09",
version = "nightly",
)

load("@rules_rust//proto:repositories.bzl", "rust_proto_repositories")

Expand Down
7 changes: 4 additions & 3 deletions docs/flatten.md
Original file line number Diff line number Diff line change
Expand Up @@ -1110,9 +1110,9 @@ Run the test with `bazel build //hello_lib:hello_lib_test`.

<pre>
rust_toolchain(<a href="#rust_toolchain-name">name</a>, <a href="#rust_toolchain-allocator_library">allocator_library</a>, <a href="#rust_toolchain-binary_ext">binary_ext</a>, <a href="#rust_toolchain-cargo">cargo</a>, <a href="#rust_toolchain-clippy_driver">clippy_driver</a>, <a href="#rust_toolchain-debug_info">debug_info</a>,
<a href="#rust_toolchain-default_edition">default_edition</a>, <a href="#rust_toolchain-dylib_ext">dylib_ext</a>, <a href="#rust_toolchain-exec_triple">exec_triple</a>, <a href="#rust_toolchain-opt_level">opt_level</a>, <a href="#rust_toolchain-os">os</a>, <a href="#rust_toolchain-rust_doc">rust_doc</a>, <a href="#rust_toolchain-rust_lib">rust_lib</a>, <a href="#rust_toolchain-rust_std">rust_std</a>,
<a href="#rust_toolchain-rustc">rustc</a>, <a href="#rust_toolchain-rustc_lib">rustc_lib</a>, <a href="#rust_toolchain-rustc_srcs">rustc_srcs</a>, <a href="#rust_toolchain-rustfmt">rustfmt</a>, <a href="#rust_toolchain-staticlib_ext">staticlib_ext</a>, <a href="#rust_toolchain-stdlib_linkflags">stdlib_linkflags</a>, <a href="#rust_toolchain-target_json">target_json</a>,
<a href="#rust_toolchain-target_triple">target_triple</a>)
<a href="#rust_toolchain-default_edition">default_edition</a>, <a href="#rust_toolchain-dylib_ext">dylib_ext</a>, <a href="#rust_toolchain-exec_triple">exec_triple</a>, <a href="#rust_toolchain-llvm_tools">llvm_tools</a>, <a href="#rust_toolchain-opt_level">opt_level</a>, <a href="#rust_toolchain-os">os</a>, <a href="#rust_toolchain-rust_doc">rust_doc</a>, <a href="#rust_toolchain-rust_lib">rust_lib</a>,
<a href="#rust_toolchain-rust_std">rust_std</a>, <a href="#rust_toolchain-rustc">rustc</a>, <a href="#rust_toolchain-rustc_lib">rustc_lib</a>, <a href="#rust_toolchain-rustc_srcs">rustc_srcs</a>, <a href="#rust_toolchain-rustfmt">rustfmt</a>, <a href="#rust_toolchain-staticlib_ext">staticlib_ext</a>, <a href="#rust_toolchain-stdlib_linkflags">stdlib_linkflags</a>,
<a href="#rust_toolchain-target_json">target_json</a>, <a href="#rust_toolchain-target_triple">target_triple</a>)
</pre>

Declares a Rust toolchain for use.
Expand Down Expand Up @@ -1170,6 +1170,7 @@ See @rules_rust//rust:repositories.bzl for examples of defining the @rust_cpuX r
| <a id="rust_toolchain-default_edition"></a>default_edition | The edition to use for rust_* rules that don't specify an edition. | String | optional | "2018" |
| <a id="rust_toolchain-dylib_ext"></a>dylib_ext | The extension for dynamic libraries created from rustc. | String | required | |
| <a id="rust_toolchain-exec_triple"></a>exec_triple | The platform triple for the toolchains execution environment. For more details see: https://docs.bazel.build/versions/master/skylark/rules.html#configurations | String | required | |
| <a id="rust_toolchain-llvm_tools"></a>llvm_tools | llvm-tools | <a href="https://bazel.build/docs/build-ref.html#labels">List of labels</a> | optional | [] |
| <a id="rust_toolchain-opt_level"></a>opt_level | Rustc optimization levels. | <a href="https://bazel.build/docs/skylark/lib/dict.html">Dictionary: String -> String</a> | optional | {"dbg": "0", "fastbuild": "0", "opt": "3"} |
| <a id="rust_toolchain-os"></a>os | The operating system for the current toolchain | String | required | |
| <a id="rust_toolchain-rust_doc"></a>rust_doc | The location of the <code>rustdoc</code> binary. Can be a direct source or a filegroup containing one item. | <a href="https://bazel.build/docs/build-ref.html#labels">Label</a> | required | |
Expand Down
7 changes: 4 additions & 3 deletions docs/rust_repositories.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,9 @@ A dedicated filegroup-like rule for Rust stdlib artifacts.

<pre>
rust_toolchain(<a href="#rust_toolchain-name">name</a>, <a href="#rust_toolchain-allocator_library">allocator_library</a>, <a href="#rust_toolchain-binary_ext">binary_ext</a>, <a href="#rust_toolchain-cargo">cargo</a>, <a href="#rust_toolchain-clippy_driver">clippy_driver</a>, <a href="#rust_toolchain-debug_info">debug_info</a>,
<a href="#rust_toolchain-default_edition">default_edition</a>, <a href="#rust_toolchain-dylib_ext">dylib_ext</a>, <a href="#rust_toolchain-exec_triple">exec_triple</a>, <a href="#rust_toolchain-opt_level">opt_level</a>, <a href="#rust_toolchain-os">os</a>, <a href="#rust_toolchain-rust_doc">rust_doc</a>, <a href="#rust_toolchain-rust_lib">rust_lib</a>, <a href="#rust_toolchain-rust_std">rust_std</a>,
<a href="#rust_toolchain-rustc">rustc</a>, <a href="#rust_toolchain-rustc_lib">rustc_lib</a>, <a href="#rust_toolchain-rustc_srcs">rustc_srcs</a>, <a href="#rust_toolchain-rustfmt">rustfmt</a>, <a href="#rust_toolchain-staticlib_ext">staticlib_ext</a>, <a href="#rust_toolchain-stdlib_linkflags">stdlib_linkflags</a>, <a href="#rust_toolchain-target_json">target_json</a>,
<a href="#rust_toolchain-target_triple">target_triple</a>)
<a href="#rust_toolchain-default_edition">default_edition</a>, <a href="#rust_toolchain-dylib_ext">dylib_ext</a>, <a href="#rust_toolchain-exec_triple">exec_triple</a>, <a href="#rust_toolchain-llvm_tools">llvm_tools</a>, <a href="#rust_toolchain-opt_level">opt_level</a>, <a href="#rust_toolchain-os">os</a>, <a href="#rust_toolchain-rust_doc">rust_doc</a>, <a href="#rust_toolchain-rust_lib">rust_lib</a>,
<a href="#rust_toolchain-rust_std">rust_std</a>, <a href="#rust_toolchain-rustc">rustc</a>, <a href="#rust_toolchain-rustc_lib">rustc_lib</a>, <a href="#rust_toolchain-rustc_srcs">rustc_srcs</a>, <a href="#rust_toolchain-rustfmt">rustfmt</a>, <a href="#rust_toolchain-staticlib_ext">staticlib_ext</a>, <a href="#rust_toolchain-stdlib_linkflags">stdlib_linkflags</a>,
<a href="#rust_toolchain-target_json">target_json</a>, <a href="#rust_toolchain-target_triple">target_triple</a>)
</pre>

Declares a Rust toolchain for use.
Expand Down Expand Up @@ -95,6 +95,7 @@ See @rules_rust//rust:repositories.bzl for examples of defining the @rust_cpuX r
| <a id="rust_toolchain-default_edition"></a>default_edition | The edition to use for rust_* rules that don't specify an edition. | String | optional | "2018" |
| <a id="rust_toolchain-dylib_ext"></a>dylib_ext | The extension for dynamic libraries created from rustc. | String | required | |
| <a id="rust_toolchain-exec_triple"></a>exec_triple | The platform triple for the toolchains execution environment. For more details see: https://docs.bazel.build/versions/master/skylark/rules.html#configurations | String | required | |
| <a id="rust_toolchain-llvm_tools"></a>llvm_tools | llvm-tools | <a href="https://bazel.build/docs/build-ref.html#labels">List of labels</a> | optional | [] |
| <a id="rust_toolchain-opt_level"></a>opt_level | Rustc optimization levels. | <a href="https://bazel.build/docs/skylark/lib/dict.html">Dictionary: String -> String</a> | optional | {"dbg": "0", "fastbuild": "0", "opt": "3"} |
| <a id="rust_toolchain-os"></a>os | The operating system for the current toolchain | String | required | |
| <a id="rust_toolchain-rust_doc"></a>rust_doc | The location of the <code>rustdoc</code> binary. Can be a direct source or a filegroup containing one item. | <a href="https://bazel.build/docs/build-ref.html#labels">Label</a> | required | |
Expand Down
7 changes: 6 additions & 1 deletion examples/WORKSPACE.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,12 @@ load("@rules_rust//rust:repositories.bzl", "rules_rust_dependencies", "rust_regi

rules_rust_dependencies()

rust_register_toolchains(include_rustc_srcs = True)
rust_register_toolchains(
dev_components = True,
include_rustc_srcs = True,
iso_date = "2022-01-09",
version = "nightly",
)

load("@rules_rust//bindgen:repositories.bzl", "rust_bindgen_repositories")

Expand Down
18 changes: 18 additions & 0 deletions examples/rustc_driver_symlink_example/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
load("@rules_rust//rust:defs.bzl", "rust_binary")
load("@bazel_skylib//rules:build_test.bzl", "build_test")

package(default_visibility = ["//visibility:public"])

rust_binary(
name = "bin",
srcs = [
"bin.rs",
],
)

build_test(
name = "build_test",
targets = [
":bin",
],
)
5 changes: 5 additions & 0 deletions examples/rustc_driver_symlink_example/bin.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#![feature(rustc_private)]

extern crate rustc_driver;

fn main() {}
8 changes: 3 additions & 5 deletions rust/private/rustc.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -407,19 +407,16 @@ def collect_inputs(

nolinkstamp_compile_inputs = depset(
getattr(files, "data", []) +
[toolchain.rustc] +
toolchain.crosstool_files +
([build_info.rustc_env, build_info.flags] if build_info else []) +
([toolchain.target_json] if toolchain.target_json else []) +
([] if linker_script == None else [linker_script]),
transitive = [
toolchain.rustc_lib,
toolchain.rust_std,
linker_depset,
crate_info.srcs,
dep_info.transitive_crate_outputs,
depset(additional_transitive_inputs),
crate_info.compile_data,
toolchain.all_files,
],
)

Expand Down Expand Up @@ -681,8 +678,9 @@ def construct_arguments(
data_paths,
))

# Set the SYSROOT to the directory of the rust_std files passed to the toolchain
# Ensure the sysroot is set for the target platform
env["SYSROOT"] = toolchain.sysroot
rustc_flags.add("--sysroot", "${pwd}/" + toolchain.sysroot)

# extra_rustc_flags apply to the target configuration, not the exec configuration.
if hasattr(ctx.attr, "_extra_rustc_flags") and not is_exec_configuration(ctx):
Expand Down
5 changes: 5 additions & 0 deletions rust/private/rustdoc_test.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,11 @@ def _construct_writer_arguments(ctx, test_runner, action, crate_info, rust_toolc
for var in action.env.keys():
writer_args.add("--action_env={}".format(var))

# Ensure the rustdoc binary is always accessed via a relative path
writer_args.add("--strip_substring={}/".format(
rust_toolchain.rust_doc.root.path,
))

# Since the test runner will be running from a runfiles directory, the
# paths originally generated for the build action will not map to any
# files. To ensure rustdoc can find the appropriate dependencies, the
Expand Down
166 changes: 166 additions & 0 deletions rust/private/toolchain_utils.bzl
Original file line number Diff line number Diff line change
@@ -1,5 +1,171 @@
"""A module defining toolchain utilities"""

def _symlink_sysroot_tree(ctx, name, target):
"""Generate a set of symlinks to files from another target

Args:
ctx (ctx): The toolchain's context object
name (str): The name of the sysroot directory (typically `ctx.label.name`)
target (Target): A target owning files to symlink

Returns:
depset[File]: A depset of the generated symlink files
"""
tree_files = []
for file in target.files.to_list():
# Parse the path to the file relative to the workspace root so a
# symlink matching this path can be created within the sysroot.

# The code blow attempts to parse any workspace names out of the
# path. For local targets, this code is a noop.
if target.label.workspace_root:
file_path = file.path.split(target.label.workspace_root, 1)[-1]
else:
file_path = file.path

symlink = ctx.actions.declare_file("{}/{}".format(name, file_path.lstrip("/")))

ctx.actions.symlink(
output = symlink,
target_file = file,
)

tree_files.append(symlink)

return depset(tree_files)

def _symlink_sysroot_bin(ctx, name, dir, target):
"""Crete a symlink to a target file.

Args:
ctx (ctx): The rule's context object
name (str): A common name for the output directory
dir (str): The directory under `name` to put the file in
target (File): A File object to symlink to

Returns:
File: A newly generated symlink file
"""
symlink = ctx.actions.declare_file("{}/{}/{}".format(
name,
dir.lstrip("/"),
target.basename,
))

ctx.actions.symlink(
output = symlink,
target_file = target,
is_executable = True,
)

return symlink

def generate_sysroot(
ctx,
rustc,
rustdoc,
rustc_lib,
cargo = None,
clippy = None,
llvm_tools = None,
rust_std = None,
rustfmt = None):
"""Generate a rust sysroot from an exec and target toolchain

Args:
ctx (ctx): A context object from a `rust_toolchain` rule.
rustc (File): The path to a `rustc` executable.
rustdoc (File): The path to a `rustdoc` executable.
rustc_lib (Target): A collection of Files containing dependencies of `rustc`.
cargo (File, optional): The path to a `cargo` executable.
clippy (File, optional): The path to a `clippy-driver` executable.
llvm_tools (Target, optional): A collection of llvm tools used by `rustc`.
rust_std (Target, optional): A collection of Files containing Rust standard library components.
rustfmt (File, optional): The path to a `rustfmt` executable.

Returns:
struct: A struct of generated files representing the new sysroot
"""
name = ctx.label.name

# Define runfiles
direct_files = []
transitive_file_sets = []

# Rustc
sysroot_rustc = _symlink_sysroot_bin(ctx, name, "/bin", rustc)
direct_files.extend([sysroot_rustc, rustc])

# Rustc dependencies
sysroot_rustc_lib = _symlink_sysroot_tree(ctx, name, rustc_lib) if rustc_lib else None
if sysroot_rustc_lib:
transitive_file_sets.extend([sysroot_rustc_lib, rustc_lib.files])

# Rustdoc
sysroot_rustdoc = _symlink_sysroot_bin(ctx, name, "/bin", rustdoc)
direct_files.extend([sysroot_rustdoc, rustdoc])

# Clippy
sysroot_clippy = _symlink_sysroot_bin(ctx, name, "/bin", clippy) if clippy else None
if sysroot_clippy:
direct_files.extend([sysroot_clippy, clippy])

# Cargo
sysroot_cargo = _symlink_sysroot_bin(ctx, name, "/bin", cargo) if cargo else None
if sysroot_cargo:
direct_files.extend([sysroot_cargo, cargo])

# Rustfmt
sysroot_rustfmt = _symlink_sysroot_bin(ctx, name, "/bin", rustfmt) if rustfmt else None
if sysroot_rustfmt:
direct_files.extend([sysroot_rustfmt, rustfmt])

# Llvm tools
sysroot_llvm_tools = _symlink_sysroot_tree(ctx, name, llvm_tools) if llvm_tools else None
if sysroot_llvm_tools:
transitive_file_sets.extend([sysroot_llvm_tools, llvm_tools.files])

# Rust standard library
sysroot_rust_std = _symlink_sysroot_tree(ctx, name, rust_std) if rust_std else None
if sysroot_rust_std:
transitive_file_sets.extend([sysroot_rust_std, rust_std.files])

# Symlink rust-stdlib
sysroot_rust_std = _symlink_sysroot_tree(ctx, name, rust_std) if rust_std else None
if sysroot_rust_std:
transitive_file_sets.extend([sysroot_rust_std, rust_std.files])

# Declare a file in the root of the sysroot to make locating the sysroot easy
sysroot_anchor = ctx.actions.declare_file("{}/rust.sysroot".format(name))
ctx.actions.write(
output = sysroot_anchor,
content = "\n".join([
"cargo: {}".format(cargo),
"clippy: {}".format(clippy),
"llvm_tools: {}".format(llvm_tools),
"rust_std: {}".format(rust_std),
"rustc_lib: {}".format(rustc_lib),
"rustc: {}".format(rustc),
"rustdoc: {}".format(rustdoc),
"rustfmt: {}".format(rustfmt),
]),
)

# Create a depset of all sysroot files (symlinks and their real paths)
all_files = depset(direct_files, transitive = transitive_file_sets)

return struct(
all_files = all_files,
cargo = sysroot_cargo,
clippy = sysroot_clippy,
rust_std = sysroot_rust_std,
rustc = sysroot_rustc,
rustc_lib = sysroot_rustc_lib,
rustdoc = sysroot_rustdoc,
rustfmt = sysroot_rustfmt,
sysroot_anchor = sysroot_anchor,
)

def _toolchain_files_impl(ctx):
toolchain = ctx.toolchains[str(Label("//rust:toolchain"))]

Expand Down
47 changes: 29 additions & 18 deletions rust/toolchain.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

load("@bazel_skylib//rules:common_settings.bzl", "BuildSettingInfo")
load("//rust/private:common.bzl", "rust_common")
load("//rust/private:toolchain_utils.bzl", "generate_sysroot")
load("//rust/private:utils.bzl", "dedent", "find_cc_toolchain", "make_static_lib_symlink")
load("//rust/settings:incompatible.bzl", "IncompatibleFlagInfo")

Expand Down Expand Up @@ -246,6 +247,18 @@ def _rust_toolchain_impl(ctx):
else:
rust_std = ctx.attr.rust_std

sysroot = generate_sysroot(
ctx = ctx,
rustc = ctx.file.rustc,
rustdoc = ctx.file.rust_doc,
rustc_lib = ctx.attr.rustc_lib,
rust_std = rust_std,
rustfmt = ctx.file.rustfmt,
clippy = ctx.file.clippy_driver,
cargo = ctx.file.cargo,
llvm_tools = ctx.attr.llvm_tools,
)

expanded_stdlib_linkflags = []
for flag in ctx.attr.stdlib_linkflags:
expanded_stdlib_linkflags.append(
Expand All @@ -268,29 +281,23 @@ def _rust_toolchain_impl(ctx):
linking_context = linking_context,
)

# In cases where the toolchain uses the Rust standard library, calculate sysroot path
sysroot_path = None
if rust_std:
# Calculate the rustc sysroot path by using a file from the rust-std bundle
rust_std_files_list = rust_std.files.to_list()
if not rust_std_files_list:
fail("The `rust_std` cannot be represented by an empty list")
sysroot_path = rust_std_files_list[0].dirname
all_files = depset(ctx.files._crosstool, transitive = [sysroot.all_files])

toolchain = platform_common.ToolchainInfo(
rustc = ctx.file.rustc,
rust_doc = ctx.file.rust_doc,
rustfmt = ctx.file.rustfmt,
cargo = ctx.file.cargo,
clippy_driver = ctx.file.clippy_driver,
all_files = all_files,
rustc = sysroot.rustc,
rust_doc = sysroot.rustdoc,
rustfmt = sysroot.rustfmt,
cargo = sysroot.cargo,
clippy_driver = sysroot.clippy,
target_json = ctx.file.target_json,
target_flag_value = ctx.file.target_json.path if ctx.file.target_json else ctx.attr.target_triple,
rustc_lib = depset(ctx.files.rustc_lib),
rustc_lib = sysroot.rustc_lib,
rustc_srcs = ctx.attr.rustc_srcs,
rust_std = rust_std.files,
rust_std_paths = depset([file.dirname for file in rust_std_files_list]),
rust_lib = rust_std.files, # `rust_lib` is deprecated and only exists for legacy support.
sysroot = sysroot_path,
rust_std = sysroot.rust_std,
rust_std_paths = depset([file.dirname for file in sysroot.rust_std.to_list()]),
rust_lib = sysroot.rust_std, # `rust_lib` is deprecated and only exists for legacy support.
sysroot = sysroot.sysroot_anchor.dirname,
binary_ext = ctx.attr.binary_ext,
staticlib_ext = ctx.attr.staticlib_ext,
dylib_ext = ctx.attr.dylib_ext,
Expand Down Expand Up @@ -358,6 +365,10 @@ rust_toolchain = rule(
),
mandatory = True,
),
"llvm_tools": attr.label_list(
doc = "llvm-tools",
allow_files = True,
),
"opt_level": attr.string_dict(
doc = "Rustc optimization levels.",
default = {
Expand Down