Skip to content
Draft
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
11 changes: 11 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
FROM ubuntu
RUN apt-get update && apt-get install -y ca-certificates curl git python3 binutils zstd file clang lld
RUN apt-get install -y build-essential
RUN curl -L https://github.com/bazelbuild/bazelisk/releases/download/v1.18.0/bazelisk-linux-amd64 -o /usr/bin/bazel && chmod +x /usr/bin/bazel
RUN adduser fakeuser
USER fakeuser

WORKDIR /rules_rust
RUN echo "8.4.2" > .bazelversion
RUN touch WORKSPACE && bazel help
RUN echo "bazel test //..." > ~/.bash_history
10 changes: 10 additions & 0 deletions build_docker.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
set -eux

docker stop bazel-builder || true
docker rm bazel-builder || true
docker build --platform=linux/amd64 -t bazel-base-image .
docker run --privileged --shm-size=4G \
--mount type=bind,src="$(realpath $(dirname $0))",dst=/rules_rust \
--mount type=bind,src="$HOME/.bazelrc",dst=/home/fakeuser/.bazelrc \
--mount type=volume,src=bazel-cache,dst=/home/fakeuser/.cache/bazel \
--name bazel-builder -it bazel-base-image bash
3 changes: 1 addition & 2 deletions rust/private/clippy.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ def _clippy_aspect_impl(target, ctx):
ctx.rule.attr.lint_config[LintsInfo].clippy_lint_files + \
ctx.rule.attr.lint_config[LintsInfo].rustc_lint_files

compile_inputs, out_dir, build_env_files, build_flags_files, linkstamp_outs, ambiguous_libs = collect_inputs(
compile_inputs, out_dir, build_env_files, build_flags_files, linkstamp_outs = collect_inputs(
ctx,
ctx.rule.file,
ctx.rule.files,
Expand Down Expand Up @@ -171,7 +171,6 @@ def _clippy_aspect_impl(target, ctx):
crate_info = crate_info,
dep_info = dep_info,
linkstamp_outs = linkstamp_outs,
ambiguous_libs = ambiguous_libs,
output_hash = determine_output_hash(crate_info.root, ctx.label),
rust_flags = [],
out_dir = out_dir,
Expand Down
222 changes: 27 additions & 195 deletions rust/private/rustc.bzl

Large diffs are not rendered by default.

3 changes: 1 addition & 2 deletions rust/private/rustdoc.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ def rustdoc_compile_action(
aliases = crate_info.aliases,
)

compile_inputs, out_dir, build_env_files, build_flags_files, linkstamp_outs, ambiguous_libs = collect_inputs(
compile_inputs, out_dir, build_env_files, build_flags_files, linkstamp_outs = collect_inputs(
ctx = ctx,
file = ctx.file,
files = ctx.files,
Expand Down Expand Up @@ -137,7 +137,6 @@ def rustdoc_compile_action(
crate_info = rustdoc_crate_info,
dep_info = dep_info,
linkstamp_outs = linkstamp_outs,
ambiguous_libs = ambiguous_libs,
output_hash = None,
rust_flags = rustdoc_flags,
out_dir = out_dir,
Expand Down
3 changes: 1 addition & 2 deletions rust/private/unpretty.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ def _rust_unpretty_aspect_impl(target, ctx):
)
lint_files = []

compile_inputs, out_dir, build_env_files, build_flags_files, linkstamp_outs, ambiguous_libs = collect_inputs(
compile_inputs, out_dir, build_env_files, build_flags_files, linkstamp_outs = collect_inputs(
ctx,
ctx.rule.file,
ctx.rule.files,
Expand Down Expand Up @@ -196,7 +196,6 @@ def _rust_unpretty_aspect_impl(target, ctx):
crate_info = crate_info,
dep_info = dep_info,
linkstamp_outs = linkstamp_outs,
ambiguous_libs = ambiguous_libs,
output_hash = determine_output_hash(crate_info.root, ctx.label),
rust_flags = rust_flags,
out_dir = out_dir,
Expand Down
20 changes: 12 additions & 8 deletions test/unit/ambiguous_libs/ambiguous_libs_test.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,22 @@ def _ambiguous_deps_test_impl(ctx):
tut = analysistest.target_under_test(env)
rustc_action = [action for action in tut.actions if action.mnemonic == "Rustc"][0]

for_shared_library = _get_crate_info(tut).type in ("dylib", "cdylib", "proc-macro")
pic_suffix = _get_pic_suffix(ctx, for_shared_library)

# We depend on two C++ libraries named "native_dep", which we need to pass to the command line
# in the form of "-lstatic=native-dep-{hash} "-lstatic=native-dep-{hash}.pic.
link_args = [arg for arg in rustc_action.argv if arg.startswith("-lstatic=native_dep-")]
# in the form of "-Clink-arg=${pwd}/bazel-out/darwin_arm64-fastbuild/bin/test/unit/ambiguous_libs/first_dep/libnative_dep.a"
if ctx.target_platform_has_constraint(
ctx.attr._windows_constraint[platform_common.ConstraintValueInfo],
):
lib_name = "native_dep{}.lib".format(pic_suffix)
else:
lib_name = "libnative_dep{}.a".format(pic_suffix)

link_args = [arg for arg in rustc_action.argv if arg.endswith(lib_name)]
asserts.equals(env, 2, len(link_args))
asserts.false(env, link_args[0] == link_args[1])

for_shared_library = _get_crate_info(tut).type in ("dylib", "cdylib", "proc-macro")
extension = _get_pic_suffix(ctx, for_shared_library)

asserts.true(env, link_args[0].endswith(extension))
asserts.true(env, link_args[1].endswith(extension))

return analysistest.end(env)

def _get_pic_suffix(ctx, for_shared_library):
Expand Down
12 changes: 12 additions & 0 deletions test/unit/common.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,18 @@ def assert_argv_contains_prefix_suffix(env, action, prefix, suffix):
),
)

def assert_argv_contains_prefix_suffix_not(env, action, prefix, suffix):
for found_flag in action.argv:
if found_flag.startswith(prefix) and found_flag.endswith(suffix):
unittest.fail(
env,
"Expected an arg with prefix '{prefix}' and suffix '{suffix}' to not appear in {args}".format(
prefix = prefix,
suffix = suffix,
args = action.argv,
),
)

def assert_argv_contains_prefix(env, action, prefix):
for found_flag in action.argv:
if found_flag.startswith(prefix):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,19 @@ def _dependency_linkopts_are_propagated_test_impl(ctx):
# Expect a library's own linkopts to come after the flags we create to link them.
# This is required, because linkopts are ordered and the linker will only apply later ones when resolving symbols required for earlier ones.
# This means that if one of our transitive deps has a linkopt like `-lfoo`, the dep will see the symbols of foo at link time.
_assert_contains_in_order(env, link_action.argv, ["-lstatic=foo_with_linkopts", "-Clink-arg=-lfoo_with_linkopts", "--codegen=link-arg=-L/doesnotexist"])
link_flag_index = -1
for i, arg in enumerate(link_action.argv):
if arg.startswith("-Clink-arg=bazel-out") and arg.endswith("test/linker_inputs_propagation/libfoo_with_linkopts.a"):
link_flag_index = i
break
if link_flag_index == -1:
unittest.fail(env, "Link flag not found")

linkopt_index = link_action.argv.index("--codegen=link-arg=-L/doesnotexist")

if linkopt_index < link_flag_index:
unittest.fail(env, "Flags out of order")

return analysistest.end(env)

def _assert_contains_input(env, inputs, name):
Expand All @@ -41,12 +53,6 @@ def _assert_contains_input(env, inputs, name):
return
unittest.fail(env, "Expected {} to contain a library starting with {}".format(inputs.to_list(), name))

def _assert_contains_in_order(env, haystack, needle):
for i in range(len(haystack)):
if haystack[i:i + len(needle)] == needle:
return
unittest.fail(env, "Expected {} to contain {}".format(haystack, needle))

def _get_lib_name(ctx, name):
if ctx.target_platform_has_constraint(ctx.attr._windows_constraint[platform_common.ConstraintValueInfo]):
return name
Expand Down
89 changes: 35 additions & 54 deletions test/unit/native_deps/native_deps_test.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ load("//rust:defs.bzl", "rust_binary", "rust_library", "rust_proc_macro", "rust_
load(
"//test/unit:common.bzl",
"assert_argv_contains",
"assert_argv_contains_not",
"assert_argv_contains_prefix",
"assert_argv_contains_prefix_not",
"assert_argv_contains_prefix_suffix",
"assert_argv_contains_prefix_suffix_not",
"assert_list_contains_adjacent_elements",
)

Expand All @@ -28,8 +28,7 @@ def _rlib_has_no_native_libs_test_impl(ctx):
tut = analysistest.target_under_test(env)
action = tut.actions[0]
assert_argv_contains(env, action, "--crate-type=rlib")
assert_argv_contains_not(env, action, "-lstatic=native_dep")
assert_argv_contains_not(env, action, "-ldylib=native_dep")
assert_argv_contains_prefix_suffix_not(env, action, "-Clink-arg=bazel-out/", "test/unit/native_deps/libnative_dep.a")
assert_argv_contains_prefix_not(env, action, "--codegen=linker=")
return analysistest.end(env)

Expand All @@ -40,17 +39,15 @@ def _cdylib_has_native_libs_test_impl(ctx):
toolchain = _get_toolchain(ctx)
compilation_mode = ctx.var["COMPILATION_MODE"]
pic_suffix = _get_pic_suffix(ctx, compilation_mode)
assert_argv_contains_prefix_suffix(env, action, "-Lnative=", "/native_deps")
assert_argv_contains(env, action, "--crate-type=cdylib")
assert_argv_contains(env, action, "-lstatic=native_dep{}".format(pic_suffix))
if toolchain.target_os == "windows":
if toolchain.target_triple.abi == "msvc":
native_link_arg = "-Clink-arg=native_dep.lib"
else:
native_link_arg = "-Clink-arg=-lnative_dep.lib"

if toolchain.target_os == "windows" and toolchain.target_triple.abi == "msvc":
assert_argv_contains_prefix_suffix(env, action, "-Lnative=", "/native_deps")
assert_argv_contains(env, action, "-lstatic=native_dep{}".format(pic_suffix))
assert_argv_contains(env, action, "-Clink-arg=native_dep.lib")
else:
native_link_arg = "-Clink-arg=-lnative_dep{}".format(pic_suffix)
assert_argv_contains(env, action, native_link_arg)
assert_argv_contains_prefix_suffix(env, action, "-Clink-arg=bazel-out/", "test/unit/native_deps/libnative_dep{}.a".format(pic_suffix))

assert_argv_contains_prefix(env, action, "--codegen=linker=")
return analysistest.end(env)

Expand All @@ -59,17 +56,14 @@ def _staticlib_has_native_libs_test_impl(ctx):
tut = analysistest.target_under_test(env)
action = tut.actions[0]
toolchain = _get_toolchain(ctx)
assert_argv_contains_prefix_suffix(env, action, "-Lnative=", "/native_deps")
assert_argv_contains(env, action, "--crate-type=staticlib")
assert_argv_contains(env, action, "-lstatic=native_dep")
if toolchain.target_os == "windows":
if toolchain.target_triple.abi == "msvc":
native_link_arg = "-Clink-arg=native_dep.lib"
else:
native_link_arg = "-Clink-arg=-lnative_dep.lib"

if toolchain.target_os == "windows" and toolchain.target_triple.abi == "msvc":
assert_argv_contains_prefix_suffix(env, action, "-Lnative=", "/native_deps")
assert_argv_contains(env, action, "-lstatic=native_dep")
assert_argv_contains(env, action, "-Clink-arg=native_dep.lib")
else:
native_link_arg = "-Clink-arg=-lnative_dep"
assert_argv_contains(env, action, native_link_arg)
assert_argv_contains_prefix_suffix(env, action, "-Clink-arg=bazel-out/", "test/unit/native_deps/libnative_dep.a")

assert_argv_contains_prefix(env, action, "--codegen=linker=")
return analysistest.end(env)

Expand All @@ -80,17 +74,15 @@ def _proc_macro_has_native_libs_test_impl(ctx):
toolchain = _get_toolchain(ctx)
compilation_mode = ctx.var["COMPILATION_MODE"]
pic_suffix = _get_pic_suffix(ctx, compilation_mode)
assert_argv_contains_prefix_suffix(env, action, "-Lnative=", "/native_deps")
assert_argv_contains(env, action, "--crate-type=proc-macro")
assert_argv_contains(env, action, "-lstatic=native_dep{}".format(pic_suffix))
if toolchain.target_os == "windows":
if toolchain.target_triple.abi == "msvc":
native_link_arg = "-Clink-arg=native_dep.lib"
else:
native_link_arg = "-Clink-arg=-lnative_dep.lib"

if toolchain.target_os == "windows" and toolchain.target_triple.abi == "msvc":
assert_argv_contains_prefix_suffix(env, action, "-Lnative=", "/native_deps")
assert_argv_contains(env, action, "-lstatic=native_dep{}".format(pic_suffix))
assert_argv_contains(env, action, "-Clink-arg=native_dep.lib")
else:
native_link_arg = "-Clink-arg=-lnative_dep{}".format(pic_suffix)
assert_argv_contains(env, action, native_link_arg)
assert_argv_contains_prefix_suffix(env, action, "-Clink-arg=bazel-out/", "test/unit/native_deps/libnative_dep{}.a".format(pic_suffix))

assert_argv_contains_prefix(env, action, "--codegen=linker=")
return analysistest.end(env)

Expand All @@ -99,16 +91,11 @@ def _bin_has_native_libs_test_impl(ctx):
tut = analysistest.target_under_test(env)
action = tut.actions[0]
toolchain = _get_toolchain(ctx)
assert_argv_contains_prefix_suffix(env, action, "-Lnative=", "/native_deps")
assert_argv_contains(env, action, "-lstatic=native_dep")
if toolchain.target_os == "windows":
if toolchain.target_triple.abi == "msvc":
native_link_arg = "-Clink-arg=native_dep.lib"
else:
native_link_arg = "-Clink-arg=-lnative_dep.lib"
if toolchain.target_os == "windows" and toolchain.target_triple.abi == "msvc":
assert_argv_contains(env, action, "-lstatic=native_dep")
assert_argv_contains(env, action, "-Clink-arg=native_dep.lib")
else:
native_link_arg = "-Clink-arg=-lnative_dep"
assert_argv_contains(env, action, native_link_arg)
assert_argv_contains_prefix_suffix(env, action, "-Clink-arg=bazel-out/", "test/unit/native_deps/libnative_dep.a")
assert_argv_contains_prefix(env, action, "--codegen=linker=")
return analysistest.end(env)

Expand Down Expand Up @@ -144,8 +131,7 @@ def _bin_has_native_dep_and_alwayslink_test_impl(ctx):
if toolchain.target_os in ["macos", "darwin"]:
darwin_component = _get_darwin_component(link_args[-1])
want = [
"-lstatic=native_dep",
"-lnative_dep",
"bazel-out/{}-{}/bin/{}test/unit/native_deps/libnative_dep.a".format(darwin_component, compilation_mode, workspace_prefix),
"-Wl,-force_load,bazel-out/{}-{}/bin/{}test/unit/native_deps/libalwayslink.lo".format(darwin_component, compilation_mode, workspace_prefix),
]
assert_list_contains_adjacent_elements(env, link_args, want)
Expand All @@ -158,23 +144,21 @@ def _bin_has_native_dep_and_alwayslink_test_impl(ctx):
]
else:
want = [
"-lstatic=native_dep",
"native_dep.lib",
"bazel-out/x64_windows-{}/bin/{}test/unit/native_deps/libnative_dep.a".format(compilation_mode, workspace_prefix),
"-Wl,--whole-archive",
"bazel-out/x64_windows-{}/bin/{}test/unit/native_deps/alwayslink.lo.lib".format(compilation_mode, workspace_prefix),
"-Wl,--no-whole-archive",
]
elif toolchain.target_arch == "s390x":
want = [
"-lstatic=native_dep",
"bazel-out/s390x-{}/bin/{}test/unit/native_deps/libnative_dep.a".format(compilation_mode, workspace_prefix),
"link-arg=-Wl,--whole-archive",
"link-arg=bazel-out/s390x-{}/bin/{}test/unit/native_deps/libalwayslink.lo".format(compilation_mode, workspace_prefix),
"link-arg=-Wl,--no-whole-archive",
]
else:
want = [
"-lstatic=native_dep",
"-lnative_dep",
"bazel-out/k8-{}/bin/{}test/unit/native_deps/libnative_dep.a".format(compilation_mode, workspace_prefix),
"-Wl,--whole-archive",
"bazel-out/k8-{}/bin/{}test/unit/native_deps/libalwayslink.lo".format(compilation_mode, workspace_prefix),
"-Wl,--no-whole-archive",
Expand All @@ -198,8 +182,7 @@ def _cdylib_has_native_dep_and_alwayslink_test_impl(ctx):
if toolchain.target_os in ["macos", "darwin"]:
darwin_component = _get_darwin_component(linker_args[-1])
want = [
"-lstatic=native_dep{}".format(pic_suffix),
"-lnative_dep{}".format(pic_suffix),
"bazel-out/{}-{}/bin/{}test/unit/native_deps/libnative_dep{}.a".format(darwin_component, compilation_mode, workspace_prefix, pic_suffix),
"-Wl,-force_load,bazel-out/{}-{}/bin/{}test/unit/native_deps/libalwayslink{}.lo".format(darwin_component, compilation_mode, workspace_prefix, pic_suffix),
]
elif toolchain.target_os == "windows":
Expand All @@ -211,23 +194,21 @@ def _cdylib_has_native_dep_and_alwayslink_test_impl(ctx):
]
else:
want = [
"-lstatic=native_dep",
"native_dep.lib",
"bazel-out/x64_windows-{}/bin/{}test/unit/native_deps/libnative_dep{}.a".format(compilation_mode, workspace_prefix, pic_suffix),
"-Wl,--whole-archive",
"bazel-out/x64_windows-{}/bin/{}test/unit/native_deps/alwayslink.lo.lib".format(compilation_mode, workspace_prefix),
"-Wl,--no-whole-archive",
]
elif toolchain.target_arch == "s390x":
want = [
"-lstatic=native_dep{}".format(pic_suffix),
"bazel-out/s390x-{}/bin/{}test/unit/native_deps/libnative_dep{}.a".format(compilation_mode, workspace_prefix, pic_suffix),
"link-arg=-Wl,--whole-archive",
"link-arg=bazel-out/s390x-{}/bin/{}test/unit/native_deps/libalwayslink{}.lo".format(compilation_mode, workspace_prefix, pic_suffix),
"link-arg=-Wl,--no-whole-archive",
]
else:
want = [
"-lstatic=native_dep{}".format(pic_suffix),
"-lnative_dep{}".format(pic_suffix),
"bazel-out/k8-{}/bin/{}test/unit/native_deps/libnative_dep{}.a".format(compilation_mode, workspace_prefix, pic_suffix),
"-Wl,--whole-archive",
"bazel-out/k8-{}/bin/{}test/unit/native_deps/libalwayslink{}.lo".format(compilation_mode, workspace_prefix, pic_suffix),
"-Wl,--no-whole-archive",
Expand Down
16 changes: 2 additions & 14 deletions test/unit/proc_macro/leaks_deps/proc_macro_does_not_leak_deps.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,6 @@
load("@bazel_skylib//lib:unittest.bzl", "analysistest", "asserts")
load("//rust:defs.bzl", "rust_library", "rust_proc_macro", "rust_test")

def _get_toolchain(ctx):
return ctx.attr._toolchain[platform_common.ToolchainInfo]

def _proc_macro_does_not_leak_deps_impl(ctx):
env = analysistest.begin(ctx)
actions = analysistest.target_under_test(env).actions
Expand All @@ -14,7 +11,6 @@ def _proc_macro_does_not_leak_deps_impl(ctx):
if action.mnemonic == "Rustc":
rustc_action = action
break
toolchain = _get_toolchain(ctx)

asserts.false(env, rustc_action == None)

Expand All @@ -29,13 +25,7 @@ def _proc_macro_does_not_leak_deps_impl(ctx):
# Our test target depends on proc_macro_dep:native directly, as well as transitively through the
# proc_macro. The proc_macro should not leak its dependency, so we should only get the "native"
# library once on the command line.
if toolchain.target_os == "windows":
if toolchain.target_triple.abi == "msvc":
native_deps = [arg for arg in rustc_action.argv if arg == "-Clink-arg=native.lib"]
else:
native_deps = [arg for arg in rustc_action.argv if arg == "-Clink-arg=-lnative.lib"]
else:
native_deps = [arg for arg in rustc_action.argv if arg == "-Clink-arg=-lnative"]
native_deps = [arg for arg in rustc_action.argv if arg.endswith("test/unit/proc_macro/leaks_deps/native/libnative.a")]
asserts.equals(env, 1, len(native_deps))

return analysistest.end(env)
Expand Down Expand Up @@ -76,9 +66,7 @@ def _proc_macro_does_not_leak_deps_test():
target_under_test = ":deps_not_leaked",
)

proc_macro_does_not_leak_deps_test = analysistest.make(_proc_macro_does_not_leak_deps_impl, attrs = {
"_toolchain": attr.label(default = Label("//rust/toolchain:current_rust_toolchain")),
})
proc_macro_does_not_leak_deps_test = analysistest.make(_proc_macro_does_not_leak_deps_impl)

# Tests that a lib_a -> proc_macro -> lib_b does not propagate lib_b to the inputs of lib_a
def _proc_macro_does_not_leak_lib_deps_impl(ctx):
Expand Down
Loading
Loading