bazelbuild / bazelbuild/rules_rust
PIC `cc_library` dependencies for PIE binary emit does not satisfy link attributes
- Dominant language
- Starlark
- Stars
- 843
- Forks
- 651
- Avg merge
- 2d 18h
- Merged PRs (30d)
- 15
Description
**Description**
Since #4062 (included in 0.71.0) `rules_rust` will pick PIC (position independent code) dependency variants when compiling a PIE (position independent executable) binary.
However PIC produced by `rules_cc` have a `.pic` infix (e.g. `libseccomp.pic.a` vs. `libseccemp.a`) that won't satisfy link attributes (e.g. `#[link(name = "seccomp")`). This is a problem when manually providing `link_deps` to third party crates (e.g. `libseccomp-sys`), as the link attribute must be removed for compilation to succeed under `--compilation_mode=opt`.
PIC dependencies should be resolvable by the linker without needing to remove the link attribute or adding the `.pic` infix.
**Reproduction steps**
1. Download and extract repro tarball. [repro.tar.gz](https://github.com/user-attachments/files/29873179/repro.tar.gz)
2. `bazel build //:main` (successful)
3. `bazel build -c opt //:main` (fails, outputs something like below)
```
❯ bazel build -c opt //:main
INFO: Analyzed target //:main (95 packages loaded, 1194 targets configured).
ERROR: /___/rules-rust-pic-link-repro/BUILD.bazel:9:12: Compiling Rust bin main (1 file) failed: (Exit 1): process_wrapper failed: error executing Rustc command (from rust_binary rule target //:main) bazel-out/k8-opt-exec/bin/external/rules_rust+/util/process_wrapper/process_wrapper --subst 'pwd=${pwd}' --subst 'exec_root=${exec_root}' --subst 'output_base=${output_base}' -- ... (remaining 2 arguments skipped)
Use --sandbox_debug to see verbose messages from the sandbox and retain the sandbox build root for debugging
error: linking with `/usr/bin/gcc` failed: exit status: 1
|
= note: "/usr/bin/gcc" "-m64" "/tmp/rustcHgpswx/symbols.o" "<2 object files omitted>" "-Wl,--as-needed" "-Wl,-Bdynamic" "-lfoo" "-Wl,-Bstatic" "-lfoo.pic" "/lib/rustlib/x86_64-unknown-linux-gnu/lib/{libstd-*,libpanic_unwind-*,libobject-*,libmemchr-*,libaddr2line-*,libgimli-*,libcfg_if-*,librustc_demangle-*,libstd_detect-*,libhashbrown-*,librustc_std_workspace_alloc-*,libminiz_oxide-*,libadler2-*,libunwind-*,liblibc-*,librustc_std_workspace_core-*,liballoc-*,libcore-*,libcompiler_builtins-*}.rlib" "-Wl,-Bdynamic" "-lgcc_s" "-lutil" "-lrt" "-lpthread" "-lm" "-ldl" "-lc" "-L" "/tmp/rustcHgpswx/raw-dylibs" "-Wl,--eh-frame-hdr" "-Wl,-z,noexecstack" "-L" "/lib/rustlib/x86_64-unknown-linux-gnu/lib" "-L" "bazel-out/k8-opt/bin" "-L" "/lib/rustlib/x86_64-unknown-linux-gnu/lib" "-o" "bazel-out/k8-opt/bin/main" "-Wl,--gc-sections" "-pie" "-Wl,-z,relro,-z,now" "-Wl,-O1" "-Wl,--strip-debug" "-nodefaultlibs" "-fuse-ld=lld" "-B/usr/bin" "-Wl,-no-as-needed" "-Wl,-z,relro,-z,now" "-pass-exit-codes" "-Wl,--gc-sections" "-Wl,--push-state,-as-needed" "-lstdc++" "-Wl,--pop-state" "-Wl,--push-state,-as-needed" "-lm" "-Wl,--pop-state" "-lfoo.pic"
= note: some arguments are omitted. use `--verbose` to show all linker arguments
= note: ld.lld: error: unable to find library -lfoo
collect2: error: ld returned 1 exit status
error: aborting due to 1 previous error
Target //:main failed to build
Use --verbose_failures to see the command lines of failed build steps.
INFO: Elapsed time: 0.905s, Critical Path: 0.29s
INFO: 59 processes: 63 action cache hit, 57 internal, 2 linux-sandbox.
ERROR: Build did NOT complete successfully
```
**Additional context**
NA
**Impact**
Impact heavily depends on the code used, but if affected it causes compilation to fail as no suitable library is found to link against.
e.g.
```
ld.lld: error: unable to find library -lseccomp
```
A workaround for this issue is to patch `rules_rust` to symlink the PIC library _without_ the `.pic` infix (building off existing logic designed to disambiguate libraries with the same filename).
**Bazel and rules_rust version**
Bazel: 9.1.1
`rules_rust`: 0.71.2 (with 9 unrelated patches)
Contributor guide
Assessment
This issue has not been assessed yet.