Skip to content
Open
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
2 changes: 1 addition & 1 deletion extensions/prost/private/prost.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ def _compile_rust(
extension = ".rmeta",
)
rmeta = ctx.actions.declare_file(rmeta_name)
rustc_rmeta_output = generate_output_diagnostics(ctx, rmeta)
rustc_rmeta_output = generate_output_diagnostics(ctx, toolchain, rmeta)
metadata_supports_pipelining = can_use_metadata_for_pipelining(toolchain, "rlib")

providers = rustc_compile_action(
Expand Down
2 changes: 1 addition & 1 deletion extensions/protobuf/proto.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ def _rust_proto_compile(protos, descriptor_sets, imports, crate_name, ctx, is_gr
crate_name,
output_hash,
))
rustc_rmeta_output = generate_output_diagnostics(ctx, rust_metadata)
rustc_rmeta_output = generate_output_diagnostics(ctx, toolchain, rust_metadata)
metadata_supports_pipelining = can_use_metadata_for_pipelining(toolchain, "rlib")

# Gather all dependencies for compilation
Expand Down
2 changes: 1 addition & 1 deletion extensions/wasm_bindgen/private/wasm_bindgen_test.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ def _rust_wasm_bindgen_test_impl(ctx):
proc_macro_deps = depset(proc_macro_deps, transitive = [crate.proc_macro_deps]).to_list(),
aliases = {},
output = output,
rustc_output = generate_output_diagnostics(ctx, output),
rustc_output = generate_output_diagnostics(ctx, toolchain, output),
edition = crate.edition,
rustc_env = rustc_env,
rustc_env_files = rustc_env_files,
Expand Down
24 changes: 24 additions & 0 deletions rust/private/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
load("@bazel_skylib//:bzl_library.bzl", "bzl_library")
load("@bazel_skylib//rules:common_settings.bzl", "bool_setting")
load("//rust/private:rust_analyzer.bzl", "rust_analyzer_detect_sysroot")
load("//rust/private:rustc.bzl", "is_proc_macro_dep", "is_proc_macro_dep_enabled")
load("//rust/private:stamp.bzl", "stamp_build_setting")
Expand Down Expand Up @@ -57,3 +58,26 @@ rust_analyzer_detect_sysroot(
name = "rust_analyzer_detect_sysroot",
visibility = ["//visibility:public"],
)

# This setting lets us configure a bootstrap toolchain to build the process_wrapper
# and a "full" toolchain (that uses process_wrapper) to build user code.
bool_setting(
name = "bootstrap_setting",
build_setting_default = False,
)

config_setting(
name = "bootstrapped",
flag_values = {
":bootstrap_setting": "0",
},
visibility = ["//visibility:public"],
)

config_setting(
name = "bootstrapping",
flag_values = {
":bootstrap_setting": "1",
},
visibility = ["//visibility:public"],
)
50 changes: 48 additions & 2 deletions rust/private/repository_utils.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,39 @@ rust_toolchain(
strip_level = {strip_level},
tags = ["rust_version={version}"],
)

rust_toolchain(
name = "{toolchain_name}_bootstrap",
bootstrapping = True,
rust_doc = "//:rustdoc",
rust_std = "//:rust_std-{target_triple}",
rustc = "//:rustc",
linker = {linker_label},
linker_type = {linker_type},
rustfmt = {rustfmt_label},
cargo = "//:cargo",
clippy_driver = "//:clippy_driver_bin",
cargo_clippy = "//:cargo_clippy_bin",
llvm_cov = {llvm_cov_label},
llvm_profdata = {llvm_profdata_label},
llvm_lib = {llvm_lib_label},
rustc_lib = "//:rustc_lib",
allocator_library = {allocator_library},
global_allocator_library = {global_allocator_library},
binary_ext = "{binary_ext}",
staticlib_ext = "{staticlib_ext}",
dylib_ext = "{dylib_ext}",
stdlib_linkflags = [{stdlib_linkflags}],
default_edition = "{default_edition}",
exec_triple = "{exec_triple}",
target_triple = "{target_triple}",
visibility = ["//visibility:public"],
extra_rustc_flags = {extra_rustc_flags},
extra_exec_rustc_flags = {extra_exec_rustc_flags},
opt_level = {opt_level},
strip_level = {strip_level},
tags = ["rust_version={version}"],
)
"""

def BUILD_for_rust_toolchain(
Expand Down Expand Up @@ -449,7 +482,20 @@ toolchain(
target_compatible_with = {target_constraint_sets_serialized},
toolchain = "{toolchain}",
toolchain_type = "{toolchain_type}",
{target_settings}
target_settings = [
"@rules_rust//rust/private:bootstrapped",{target_settings}
],
)

toolchain(
name = "{name}_bootstrap",
exec_compatible_with = {exec_constraint_sets_serialized},
target_compatible_with = {target_constraint_sets_serialized},
toolchain = "{toolchain}_bootstrap",
toolchain_type = "{toolchain_type}",
target_settings = [
"@rules_rust//rust/private:bootstrapping",{target_settings}
],
)
"""

Expand All @@ -460,7 +506,7 @@ def BUILD_for_toolchain(
target_settings,
target_compatible_with,
exec_compatible_with):
target_settings_value = "target_settings = {},".format(json.encode(target_settings)) if target_settings else "# target_settings = []"
target_settings_value = ",\n ".join([repr(setting) for setting in target_settings])

return _build_file_for_toolchain_template.format(
name = name,
Expand Down
57 changes: 23 additions & 34 deletions rust/private/rust.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ def _rust_library_common(ctx, crate_type):
paths.replace_extension(rust_lib_name, ".rmeta"),
sibling = rust_lib,
)
rustc_rmeta_output = generate_output_diagnostics(ctx, rust_metadata)
rustc_rmeta_output = generate_output_diagnostics(ctx, toolchain, rust_metadata)
metadata_supports_pipelining = (
can_use_metadata_for_pipelining(toolchain, crate_type) and
not ctx.attr.disable_pipelining
Expand All @@ -232,7 +232,7 @@ def _rust_library_common(ctx, crate_type):
proc_macro_deps = proc_macro_deps,
aliases = ctx.attr.aliases,
output = rust_lib,
rustc_output = generate_output_diagnostics(ctx, rust_lib),
rustc_output = generate_output_diagnostics(ctx, toolchain, rust_lib),
metadata = rust_metadata,
metadata_supports_pipelining = metadata_supports_pipelining,
rustc_rmeta_output = rustc_rmeta_output,
Expand Down Expand Up @@ -282,7 +282,7 @@ def _rust_binary_impl(ctx):
paths.replace_extension("lib" + crate_name, ".rmeta"),
sibling = output,
)
rustc_rmeta_output = generate_output_diagnostics(ctx, rust_metadata)
rustc_rmeta_output = generate_output_diagnostics(ctx, toolchain, rust_metadata)

providers = rustc_compile_action(
ctx = ctx,
Expand All @@ -297,7 +297,7 @@ def _rust_binary_impl(ctx):
proc_macro_deps = proc_macro_deps,
aliases = ctx.attr.aliases,
output = output,
rustc_output = generate_output_diagnostics(ctx, output),
rustc_output = generate_output_diagnostics(ctx, toolchain, output),
metadata = rust_metadata,
rustc_rmeta_output = rustc_rmeta_output,
edition = get_edition(ctx.attr, toolchain, ctx.label),
Expand Down Expand Up @@ -394,7 +394,7 @@ def _rust_test_impl(ctx):
paths.replace_extension("lib" + crate_name, ".rmeta"),
sibling = output,
)
rustc_rmeta_output = generate_output_diagnostics(ctx, rust_metadata)
rustc_rmeta_output = generate_output_diagnostics(ctx, toolchain, rust_metadata)

# Need to consider all src files together when transforming
srcs = depset(ctx.files.srcs, transitive = [crate.srcs]).to_list()
Expand Down Expand Up @@ -429,7 +429,7 @@ def _rust_test_impl(ctx):
proc_macro_deps = depset(proc_macro_deps, transitive = [crate.proc_macro_deps]).to_list(),
aliases = aliases,
output = output,
rustc_output = generate_output_diagnostics(ctx, output),
rustc_output = generate_output_diagnostics(ctx, toolchain, output),
metadata = rust_metadata,
rustc_rmeta_output = rustc_rmeta_output,
edition = crate.edition,
Expand Down Expand Up @@ -473,7 +473,7 @@ def _rust_test_impl(ctx):
paths.replace_extension("lib" + crate_name, ".rmeta"),
sibling = output,
)
rustc_rmeta_output = generate_output_diagnostics(ctx, rust_metadata)
rustc_rmeta_output = generate_output_diagnostics(ctx, toolchain, rust_metadata)

if ctx.attr.rustc_env:
rustc_env = expand_dict_value_locations(
Expand All @@ -495,7 +495,7 @@ def _rust_test_impl(ctx):
proc_macro_deps = proc_macro_deps,
aliases = ctx.attr.aliases,
output = output,
rustc_output = generate_output_diagnostics(ctx, output),
rustc_output = generate_output_diagnostics(ctx, toolchain, output),
metadata = rust_metadata,
rustc_rmeta_output = rustc_rmeta_output,
edition = get_edition(ctx.attr, toolchain, ctx.label),
Expand Down Expand Up @@ -645,13 +645,6 @@ RUSTC_ATTRS = {
"_per_crate_rustc_flag": attr.label(
default = Label("//rust/settings:experimental_per_crate_rustc_flag"),
),
"_process_wrapper": attr.label(
doc = "A process wrapper for running rustc on all platforms.",
default = Label("//util/process_wrapper"),
executable = True,
allow_single_file = True,
cfg = "exec",
),
"_rustc_output_diagnostics": attr.label(
default = Label("//rust/settings:rustc_output_diagnostics"),
),
Expand Down Expand Up @@ -1318,21 +1311,6 @@ rust_binary = rule(
def _common_attrs_for_binary_without_process_wrapper(attrs):
new_attr = dict(attrs)

# use a fake process wrapper
new_attr["_process_wrapper"] = attr.label(
default = None,
executable = True,
allow_single_file = True,
cfg = "exec",
)

new_attr["_bootstrap_process_wrapper"] = attr.label(
default = Label("//util/process_wrapper:bootstrap_process_wrapper"),
executable = True,
allow_single_file = True,
cfg = "exec",
)

# fix stamp = 0
new_attr["stamp"] = attr.int(
doc = dedent("""\
Expand All @@ -1350,20 +1328,31 @@ _RustBuiltWithoutProcessWrapperInfo = provider(
fields = {},
)

def _bootstrap_process_wrapper_transition_impl(_settings, _attr):
return {str(Label("//rust/private:bootstrap_setting")): True}

_bootstrap_process_wrapper_transition = transition(
implementation = _bootstrap_process_wrapper_transition_impl,
inputs = [],
outputs = [str(Label("//rust/private:bootstrap_setting"))],
)

def _rust_binary_without_process_wrapper_impl(ctx):
providers = _rust_binary_impl(ctx)
return providers + [_RustBuiltWithoutProcessWrapperInfo()]

# Provides an internal rust_{binary,library} to use that we can use to build the process
# wrapper, this breaks the dependency of rust_* on the process wrapper by
# setting it to None, which the functions in rustc detect and build accordingly.
rust_binary_without_process_wrapper = rule(
implementation = _rust_binary_without_process_wrapper_impl,
doc = "A variant of `rust_binary` that uses a minimal process wrapper for `Rustc` actions.",
provides = COMMON_PROVIDERS + [_RustBuiltWithoutProcessWrapperInfo],
attrs = _common_attrs_for_binary_without_process_wrapper(_common_attrs | _rust_binary_attrs),
attrs = _common_attrs_for_binary_without_process_wrapper(_common_attrs | _rust_binary_attrs) | {
"_allowlist_function_transition": attr.label(
default = Label("//tools/allowlists/function_transition_allowlist"),
),
},
executable = True,
fragments = ["cpp"],
cfg = _bootstrap_process_wrapper_transition,
toolchains = [
str(Label("//rust:toolchain_type")),
config_common.toolchain_type("@bazel_tools//tools/cpp:toolchain_type", mandatory = False),
Expand Down
14 changes: 7 additions & 7 deletions rust/private/rustc.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -1502,10 +1502,12 @@ def rustc_compile_action(
dsym_folder = ctx.actions.declare_directory(crate_info.output.basename + ".dSYM", sibling = crate_info.output)
action_outputs.append(dsym_folder)

if ctx.executable._process_wrapper:
process_wrapper = toolchain.process_wrapper

if process_wrapper:
# Run as normal
ctx.actions.run(
executable = ctx.executable._process_wrapper,
executable = process_wrapper,
inputs = compile_inputs,
outputs = action_outputs,
env = env,
Expand All @@ -1523,7 +1525,7 @@ def rustc_compile_action(
)
if args_metadata:
ctx.actions.run(
executable = ctx.executable._process_wrapper,
executable = process_wrapper,
inputs = compile_inputs,
outputs = [build_metadata] + [x for x in [rustc_rmeta_output] if x],
env = env,
Expand All @@ -1538,12 +1540,12 @@ def rustc_compile_action(
),
toolchain = "@rules_rust//rust:toolchain_type",
)
elif hasattr(ctx.executable, "_bootstrap_process_wrapper"):
else:
# Run without process_wrapper
if build_env_files or build_flags_files or stamp or build_metadata:
fail("build_env_files, build_flags_files, stamp, build_metadata are not supported when building without process_wrapper")
ctx.actions.run(
executable = ctx.executable._bootstrap_process_wrapper,
executable = toolchain.bootstrap_process_wrapper,
inputs = compile_inputs,
outputs = action_outputs,
env = env,
Expand All @@ -1559,8 +1561,6 @@ def rustc_compile_action(
toolchain = "@rules_rust//rust:toolchain_type",
resource_set = get_rustc_resource_set(toolchain),
)
else:
fail("No process wrapper was defined for {}".format(ctx.label))

if experimental_use_cc_common_link:
# Wrap the main `.o` file into a compilation output suitable for
Expand Down
2 changes: 1 addition & 1 deletion rust/private/unpretty.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ def _rust_unpretty_aspect_impl(target, ctx):
args.rustc_flags.add("-Zunpretty={}".format(mode))

ctx.actions.run(
executable = ctx.executable._process_wrapper,
executable = toolchain.process_wrapper,
inputs = compile_inputs,
outputs = [unpretty_out],
env = env,
Expand Down
7 changes: 4 additions & 3 deletions rust/private/utils.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -736,7 +736,7 @@ def can_build_metadata(toolchain, ctx, crate_type, *, disable_pipelining = False
# 2) either:
# * always_enable_metadata_output_groups is set
# * this target can use metadata for pipelined compilation
return bool(ctx.attr._process_wrapper) and (
return bool(toolchain.process_wrapper) and (
ctx.attr._always_enable_metadata_output_groups[AlwaysEnableMetadataOutputGroupsInfo].always_enable_metadata_output_groups or
(not disable_pipelining and
can_use_metadata_for_pipelining(toolchain, crate_type))
Expand Down Expand Up @@ -943,11 +943,12 @@ def _symlink_for_non_generated_source(ctx, src_file, package_root):
else:
return src_file

def generate_output_diagnostics(ctx, sibling, require_process_wrapper = True):
def generate_output_diagnostics(ctx, toolchain, sibling, require_process_wrapper = True):
"""Generates a .rustc-output file if it's required.

Args:
ctx: (ctx): The current rule's context object
toolchain: (Rust toolchain): The current rust toolchain
sibling: (File): The file to generate the diagnostics for.
require_process_wrapper: (bool): Whether to require the process wrapper
in order to generate the .rustc-output file.
Expand All @@ -958,7 +959,7 @@ def generate_output_diagnostics(ctx, sibling, require_process_wrapper = True):
# Since this feature requires error_format=json, we usually need
# process_wrapper, since it can write the json here, then convert it to the
# regular error format so the user can see the error properly.
if require_process_wrapper and not ctx.attr._process_wrapper:
if require_process_wrapper and not toolchain.process_wrapper:
return None
provider = ctx.attr._rustc_output_diagnostics[RustcOutputDiagnosticsInfo]
if not provider.rustc_output_diagnostics:
Expand Down
Loading