Skip to content

Commit

Permalink
add a stopgap experimental_use_whole_archive_for_native_deps attribute (
Browse files Browse the repository at this point in the history
#1269)

This adds a new stopgap attribute enabling us to fall back to the old rustc behavior wrt whole-archive handling, see #1268.
  • Loading branch information
krasimirgg authored Apr 20, 2022
1 parent 34fd467 commit f6e7e0a
Show file tree
Hide file tree
Showing 7 changed files with 95 additions and 45 deletions.
29 changes: 18 additions & 11 deletions docs/defs.md

Large diffs are not rendered by default.

36 changes: 23 additions & 13 deletions docs/flatten.md

Large diffs are not rendered by default.

7 changes: 5 additions & 2 deletions docs/rust_doc.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
## rust_doc

<pre>
rust_doc(<a href="#rust_doc-name">name</a>, <a href="#rust_doc-crate">crate</a>, <a href="#rust_doc-html_after_content">html_after_content</a>, <a href="#rust_doc-html_before_content">html_before_content</a>, <a href="#rust_doc-html_in_header">html_in_header</a>, <a href="#rust_doc-markdown_css">markdown_css</a>)
rust_doc(<a href="#rust_doc-name">name</a>, <a href="#rust_doc-crate">crate</a>, <a href="#rust_doc-experimental_use_whole_archive_for_native_deps">experimental_use_whole_archive_for_native_deps</a>, <a href="#rust_doc-html_after_content">html_after_content</a>,
<a href="#rust_doc-html_before_content">html_before_content</a>, <a href="#rust_doc-html_in_header">html_in_header</a>, <a href="#rust_doc-markdown_css">markdown_css</a>)
</pre>

Generates code documentation.
Expand Down Expand Up @@ -56,6 +57,7 @@ Running `bazel build //hello_lib:hello_lib_doc` will build a zip file containing
| :------------- | :------------- | :------------- | :------------- | :------------- |
| <a id="rust_doc-name"></a>name | A unique name for this target. | <a href="https://bazel.build/docs/build-ref.html#name">Name</a> | required | |
| <a id="rust_doc-crate"></a>crate | The label of the target to generate code documentation for.<br><br><code>rust_doc</code> can generate HTML code documentation for the source files of <code>rust_library</code> or <code>rust_binary</code> targets. | <a href="https://bazel.build/docs/build-ref.html#labels">Label</a> | required | |
| <a id="rust_doc-experimental_use_whole_archive_for_native_deps"></a>experimental_use_whole_archive_for_native_deps | Whether to use +whole-archive linking modifier for native dependencies.<br><br>TODO: This is a stopgap feature and will be removed, see https://github.com/bazelbuild/rules_rust/issues/1268. | Boolean | optional | False |
| <a id="rust_doc-html_after_content"></a>html_after_content | File to add in <code>&lt;body&gt;</code>, after content. | <a href="https://bazel.build/docs/build-ref.html#labels">Label</a> | optional | None |
| <a id="rust_doc-html_before_content"></a>html_before_content | File to add in <code>&lt;body&gt;</code>, before content. | <a href="https://bazel.build/docs/build-ref.html#labels">Label</a> | optional | None |
| <a id="rust_doc-html_in_header"></a>html_in_header | File to add to <code>&lt;head&gt;</code>. | <a href="https://bazel.build/docs/build-ref.html#labels">Label</a> | optional | None |
Expand All @@ -67,7 +69,7 @@ Running `bazel build //hello_lib:hello_lib_doc` will build a zip file containing
## rust_doc_test

<pre>
rust_doc_test(<a href="#rust_doc_test-name">name</a>, <a href="#rust_doc_test-crate">crate</a>)
rust_doc_test(<a href="#rust_doc_test-name">name</a>, <a href="#rust_doc_test-crate">crate</a>, <a href="#rust_doc_test-experimental_use_whole_archive_for_native_deps">experimental_use_whole_archive_for_native_deps</a>)
</pre>

Runs Rust documentation tests.
Expand Down Expand Up @@ -115,5 +117,6 @@ Running `bazel test //hello_lib:hello_lib_doc_test` will run all documentation t
| :------------- | :------------- | :------------- | :------------- | :------------- |
| <a id="rust_doc_test-name"></a>name | A unique name for this target. | <a href="https://bazel.build/docs/build-ref.html#name">Name</a> | required | |
| <a id="rust_doc_test-crate"></a>crate | The label of the target to generate code documentation for. <code>rust_doc_test</code> can generate HTML code documentation for the source files of <code>rust_library</code> or <code>rust_binary</code> targets. | <a href="https://bazel.build/docs/build-ref.html#labels">Label</a> | required | |
| <a id="rust_doc_test-experimental_use_whole_archive_for_native_deps"></a>experimental_use_whole_archive_for_native_deps | Whether to use +whole-archive linking modifier for native dependencies.<br><br>TODO: This is a stopgap feature and will be removed, see https://github.com/bazelbuild/rules_rust/issues/1268. | Boolean | optional | False |


9 changes: 9 additions & 0 deletions rust/private/rust.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -494,6 +494,15 @@ _common_attrs = {
"edition": attr.string(
doc = "The rust edition to use for this crate. Defaults to the edition specified in the rust_toolchain.",
),
"experimental_use_whole_archive_for_native_deps": attr.bool(
doc = dedent("""\
Whether to use +whole-archive linking modifier for native dependencies.
TODO: This is a stopgap feature and will be removed,
see https://github.com/bazelbuild/rules_rust/issues/1268.
"""),
default = False,
),
# Previously `proc_macro_deps` were a part of `deps`, and then proc_macro_host_transition was
# used into cfg="host" using `@local_config_platform//:host`.
# This fails for remote execution, which needs cfg="exec", and there isn't anything like
Expand Down
41 changes: 22 additions & 19 deletions rust/private/rustc.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -780,7 +780,7 @@ def construct_arguments(
rustc_flags.add("--codegen=linker=" + ld)
rustc_flags.add_joined("--codegen", link_args, join_with = " ", format_joined = "link-args=%s")

_add_native_link_flags(rustc_flags, dep_info, linkstamp_outs, ambiguous_libs, crate_info.type, toolchain, cc_toolchain, feature_configuration)
_add_native_link_flags(rustc_flags, dep_info, linkstamp_outs, ambiguous_libs, crate_info.type, toolchain, cc_toolchain, feature_configuration, attr.experimental_use_whole_archive_for_native_deps)

# These always need to be added, even if not linking this crate.
add_crate_link_flags(rustc_flags, dep_info, force_all_deps_direct)
Expand Down Expand Up @@ -1259,13 +1259,16 @@ def _get_crate_dirname(crate):
"""
return crate.output.dirname

def _portable_link_flags(lib, use_pic, ambiguous_libs):
def _portable_link_flags(lib, use_pic, ambiguous_libs, experimental_use_whole_archive_for_native_deps):
artifact = get_preferred_artifact(lib, use_pic)
if ambiguous_libs and artifact.path in ambiguous_libs:
artifact = ambiguous_libs[artifact.path]
if lib.static_library or lib.pic_static_library:
modifiers = ""
if experimental_use_whole_archive_for_native_deps:
modifiers = ":+whole-archive"
return [
"-lstatic=%s" % get_lib_name(artifact),
"-lstatic%s=%s" % (modifiers, get_lib_name(artifact)),
]
elif _is_dylib(lib):
return [
Expand All @@ -1274,18 +1277,18 @@ def _portable_link_flags(lib, use_pic, ambiguous_libs):

return []

def _make_link_flags_windows(linker_input_and_use_pic_and_ambiguous_libs):
linker_input, use_pic, ambiguous_libs = linker_input_and_use_pic_and_ambiguous_libs
def _make_link_flags_windows(linker_input_and_use_pic_and_ambiguous_libs_and_experimental_use_whole_archive_for_native_deps):
linker_input, use_pic, ambiguous_libs, experimental_use_whole_archive_for_native_deps = linker_input_and_use_pic_and_ambiguous_libs_and_experimental_use_whole_archive_for_native_deps
ret = []
for lib in linker_input.libraries:
if lib.alwayslink:
ret.extend(["-C", "link-arg=/WHOLEARCHIVE:%s" % get_preferred_artifact(lib, use_pic).path])
else:
ret.extend(_portable_link_flags(lib, use_pic, ambiguous_libs))
ret.extend(_portable_link_flags(lib, use_pic, ambiguous_libs, experimental_use_whole_archive_for_native_deps))
return ret

def _make_link_flags_darwin(linker_input_and_use_pic_and_ambiguous_libs):
linker_input, use_pic, ambiguous_libs = linker_input_and_use_pic_and_ambiguous_libs
def _make_link_flags_darwin(linker_input_and_use_pic_and_ambiguous_libs_and_experimental_use_whole_archive_for_native_deps):
linker_input, use_pic, ambiguous_libs, experimental_use_whole_archive_for_native_deps = linker_input_and_use_pic_and_ambiguous_libs_and_experimental_use_whole_archive_for_native_deps
ret = []
for lib in linker_input.libraries:
if lib.alwayslink:
Expand All @@ -1294,11 +1297,11 @@ def _make_link_flags_darwin(linker_input_and_use_pic_and_ambiguous_libs):
("link-arg=-Wl,-force_load,%s" % get_preferred_artifact(lib, use_pic).path),
])
else:
ret.extend(_portable_link_flags(lib, use_pic, ambiguous_libs))
ret.extend(_portable_link_flags(lib, use_pic, ambiguous_libs, experimental_use_whole_archive_for_native_deps))
return ret

def _make_link_flags_default(linker_input_and_use_pic_and_ambiguous_libs):
linker_input, use_pic, ambiguous_libs = linker_input_and_use_pic_and_ambiguous_libs
def _make_link_flags_default(linker_input_and_use_pic_and_ambiguous_libs_and_experimental_use_whole_archive_for_native_deps):
linker_input, use_pic, ambiguous_libs, experimental_use_whole_archive_for_native_deps = linker_input_and_use_pic_and_ambiguous_libs_and_experimental_use_whole_archive_for_native_deps
ret = []
for lib in linker_input.libraries:
if lib.alwayslink:
Expand All @@ -1311,16 +1314,16 @@ def _make_link_flags_default(linker_input_and_use_pic_and_ambiguous_libs):
"link-arg=-Wl,--no-whole-archive",
])
else:
ret.extend(_portable_link_flags(lib, use_pic, ambiguous_libs))
ret.extend(_portable_link_flags(lib, use_pic, ambiguous_libs, experimental_use_whole_archive_for_native_deps))
return ret

def _libraries_dirnames(linker_input_and_use_pic_and_ambiguous_libs):
link_input, use_pic, _ = linker_input_and_use_pic_and_ambiguous_libs
def _libraries_dirnames(linker_input_and_use_pic_and_ambiguous_libs_and_experimental_use_whole_archive_for_native_deps):
link_input, use_pic, _, _ = linker_input_and_use_pic_and_ambiguous_libs_and_experimental_use_whole_archive_for_native_deps

# De-duplicate names.
return depset([get_preferred_artifact(lib, use_pic).dirname for lib in link_input.libraries]).to_list()

def _add_native_link_flags(args, dep_info, linkstamp_outs, ambiguous_libs, crate_type, toolchain, cc_toolchain, feature_configuration):
def _add_native_link_flags(args, dep_info, linkstamp_outs, ambiguous_libs, crate_type, toolchain, cc_toolchain, feature_configuration, experimental_use_whole_archive_for_native_deps):
"""Adds linker flags for all dependencies of the current target.
Args:
Expand All @@ -1332,7 +1335,7 @@ def _add_native_link_flags(args, dep_info, linkstamp_outs, ambiguous_libs, crate
toolchain (rust_toolchain): The current `rust_toolchain`
cc_toolchain (CcToolchainInfo): The current `cc_toolchain`
feature_configuration (FeatureConfiguration): feature configuration to use with cc_toolchain
experimental_use_whole_archive_for_native_deps (bool): Whether to use the whole-archive link modifier for native deps, see https://github.com/bazelbuild/rules_rust/issues/1268
"""
if crate_type in ["lib", "rlib"]:
return
Expand All @@ -1347,15 +1350,15 @@ def _add_native_link_flags(args, dep_info, linkstamp_outs, ambiguous_libs, crate
make_link_flags = _make_link_flags_default

# TODO(hlopko): Remove depset flattening by using lambdas once we are on >=Bazel 5.0
args_and_pic_and_ambiguous_libs = [(arg, use_pic, ambiguous_libs) for arg in dep_info.transitive_noncrates.to_list()]
args.add_all(args_and_pic_and_ambiguous_libs, map_each = _libraries_dirnames, uniquify = True, format_each = "-Lnative=%s")
args_and_pic_and_ambiguous_libs_and_use_whole_archive_for_native_deps = [(arg, use_pic, ambiguous_libs, experimental_use_whole_archive_for_native_deps) for arg in dep_info.transitive_noncrates.to_list()]
args.add_all(args_and_pic_and_ambiguous_libs_and_use_whole_archive_for_native_deps, map_each = _libraries_dirnames, uniquify = True, format_each = "-Lnative=%s")
if ambiguous_libs:
# If there are ambiguous libs, the disambiguation symlinks to them are
# all created in the same directory. Add it to the library search path.
ambiguous_libs_dirname = ambiguous_libs.values()[0].dirname
args.add("-Lnative={}".format(ambiguous_libs_dirname))

args.add_all(args_and_pic_and_ambiguous_libs, map_each = make_link_flags)
args.add_all(args_and_pic_and_ambiguous_libs_and_use_whole_archive_for_native_deps, map_each = make_link_flags)

for linkstamp_out in linkstamp_outs:
args.add_all(["-C", "link-arg=%s" % linkstamp_out.path])
Expand Down
9 changes: 9 additions & 0 deletions rust/private/rustdoc.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,15 @@ rust_doc = rule(
providers = [rust_common.crate_info],
mandatory = True,
),
"experimental_use_whole_archive_for_native_deps": attr.bool(
doc = dedent("""\
Whether to use +whole-archive linking modifier for native dependencies.
TODO: This is a stopgap feature and will be removed,
see https://github.com/bazelbuild/rules_rust/issues/1268.
"""),
default = False,
),
"html_after_content": attr.label(
doc = "File to add in `<body>`, after content.",
allow_single_file = [".html", ".md"],
Expand Down
9 changes: 9 additions & 0 deletions rust/private/rustdoc_test.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,15 @@ rust_doc_test = rule(
providers = [rust_common.crate_info],
mandatory = True,
),
"experimental_use_whole_archive_for_native_deps": attr.bool(
doc = dedent("""\
Whether to use +whole-archive linking modifier for native dependencies.
TODO: This is a stopgap feature and will be removed,
see https://github.com/bazelbuild/rules_rust/issues/1268.
"""),
default = False,
),
"_cc_toolchain": attr.label(
doc = (
"In order to use find_cc_toolchain, your rule has to depend " +
Expand Down

0 comments on commit f6e7e0a

Please sign in to comment.