bazelbuild / rules_rust

Rust rules for Bazel
https://bazelbuild.github.io/rules_rust/
Apache License 2.0
661 stars 426 forks source link

proc-macro crate_type build fails with --force-pic #587

Open dfreese opened 3 years ago

dfreese commented 3 years ago

We, incorrectly or otherwise, been using --force-pic in our builds. This triggered a build failure with the following as a min repro:

WORKSPACE

load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")

http_archive(
    name = "rules_rust",
    sha256 = "a3c6d6f8ddb6ba6dfc7cfdd274998153df8f2b057cd0cbb2bd5ca00a0f2bb9e5",
    strip_prefix = "rules_rust-6267c267bee6bb869e381130b92922ee2c07e275",
    urls = [
        # main branch as of 2021-02-09
        "https://github.com/bazelbuild/rules_rust/archive/6267c267bee6bb869e381130b92922ee2c07e275.tar.gz",
    ],
)

load("@rules_rust//rust:repositories.bzl", "rust_repositories")

rust_repositories()

BUILD

load("@rules_rust//rust:rust.bzl", "rust_library")

rust_library(
    name = "fails_with_force_pic",
    srcs = ["lib.rs"],
    crate_type = "proc-macro",
)

lib.rs (is empty)

When running with bazel 3.5.0, I see that:

bazel build --force_pic //...  #fails
bazel build //...  #works

Incidentally, we can still depend on a proc-macro target, and still build correctly. So I could, in theory, mark fails_with_force_pic with a manual tag, and still use any code in it just fine.

The only difference in the compilation step is that -pie is added to the link-args when --force-pic is enabled. This appears to be related to the use of CPP_LINK_EXECUTABLE_ACTION_NAME in get_linker_and_args(). Using CPP_LINK_NODEPS_DYNAMIC_LIBRARY_ACTION_NAME doesn't add -pie, for example.

@hlopko, given the type of extensions selected here, do you think that should be switch up based on crate type?

ikalchev commented 2 years ago

@dfreese the proposed solution may "regress" rust_binary targets where -pie is maybe what we want.

But building on that, I think one option is that we can use different action names depending on the crate type. I don't know the actions well enough to say if these can be mapped nicely to crate types though.

My solution is a bit "ad-hoc", adding code just after get_linker_and_args.

# remove the -pie flag if this is not a bin crate
if crate_info.type != "bin":
   link_args = [arg for arg in link_args if arg != "-pie"]

@illicitonion, @hlopko any thoughts?