Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix argfile length rustc bug (Windows) #2116

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
57 changes: 49 additions & 8 deletions rust/private/rustc.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -1008,7 +1008,7 @@ def construct_arguments(
use_metadata = _depend_on_metadata(crate_info, force_depend_on_objects)

# These always need to be added, even if not linking this crate.
add_crate_link_flags(rustc_flags, dep_info, force_all_deps_direct, use_metadata)
add_crate_link_flags(rustc_flags, dep_info, crate_info, force_all_deps_direct, use_metadata, toolchain.target_os == "windows")

needs_extern_proc_macro_flag = _is_proc_macro(crate_info) and crate_info.edition != "2015"
if needs_extern_proc_macro_flag:
Expand Down Expand Up @@ -1151,6 +1151,10 @@ def rustc_compile_action(
experimental_use_cc_common_link = experimental_use_cc_common_link,
)

if toolchain.target_os == "windows":
symlink_deps = windows_symlink_transitive_deps(ctx, crate_info, dep_info)
compile_inputs = depset(symlink_deps, transitive = [compile_inputs])

# The types of rustc outputs to emit.
# If we build metadata, we need to keep the command line of the two invocations
# (rlib and rmeta) as similar as possible, otherwise rustc rejects the rmeta as
Expand Down Expand Up @@ -1686,15 +1690,46 @@ def _get_dir_names(files):
dirs[f.dirname] = None
return dirs.keys()

def add_crate_link_flags(args, dep_info, force_all_deps_direct = False, use_metadata = False):
def windows_symlink_transitive_deps(ctx, crate_info, dep_info):
"""Symlinks in transitive dependencies to fix rustc bug on Windows: https://github.com/rust-lang/rust/issues/79923

Args:
ctx (ctx): The source rule's context object
crate_info (CrateInfo): A CrateInfo provider
dep_info (DepInfo): The current target's dependency info

Returns:
list: A list of all symlinked transitive dependencies
"""
symlink_deps = []
if crate_info.output == None:
return []
for dep in (dep_info.direct_crates.to_list() + dep_info.transitive_crates.to_list()):
if hasattr(dep, "dep"):
dep = dep.dep

if dep.output == None:
continue

symlink_dir = ctx.actions.declare_file("rlib_sym/" + dep.output.basename, sibling = crate_info.output)
ctx.actions.symlink(
output = symlink_dir,
target_file = dep.output,
)
symlink_deps.append(symlink_dir)
return symlink_deps

def add_crate_link_flags(args, dep_info, crate_info, force_all_deps_direct = False, use_metadata = False, for_windows = False):
"""Adds link flags to an Args object reference

Args:
args (Args): An arguments object reference
dep_info (DepInfo): The current target's dependency info
crate_info (CrateInfo): A CrateInfo provider
force_all_deps_direct (bool, optional): Whether to pass the transitive rlibs with --extern
to the commandline as opposed to -L.
use_metadata (bool, optional): Build command line arugments using metadata for crates that provide it.
for_windows (bool, optional): Whether to add the rlib_sym directory to the linker search path.
"""

direct_crates = depset(
Expand All @@ -1707,12 +1742,18 @@ def add_crate_link_flags(args, dep_info, force_all_deps_direct = False, use_meta
crate_to_link_flags = _crate_to_link_flag_metadata if use_metadata else _crate_to_link_flag
args.add_all(direct_crates, uniquify = True, map_each = crate_to_link_flags)

args.add_all(
dep_info.transitive_crates,
map_each = _get_crate_dirname,
uniquify = True,
format_each = "-Ldependency=%s",
)
# crate_info.output is None when building rust_doc targets
if for_windows and crate_info.output != None:
args.add(
"-Ldependency={}".format(crate_info.output.dirname + "/rlib_sym"),
)
else:
args.add_all(
dep_info.transitive_crates,
map_each = _get_crate_dirname,
uniquify = True,
format_each = "-Ldependency=%s",
)

def _crate_to_link_flag_metadata(crate):
"""A helper macro used by `add_crate_link_flags` for adding crate link flags to a Arg object
Expand Down