Skip to content

libstd.so removal breaks external proc_macro with -Cprefer-dynamic #141958

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

Closed
10ne1 opened this issue Jun 3, 2025 · 4 comments
Closed

libstd.so removal breaks external proc_macro with -Cprefer-dynamic #141958

10ne1 opened this issue Jun 3, 2025 · 4 comments
Labels
A-linkage Area: linking into static, shared libraries and binaries C-discussion Category: Discussion or questions that doesn't represent real issues. T-bootstrap Relevant to the bootstrap subteam: Rust's build system (x.py and src/bootstrap) T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@10ne1
Copy link

10ne1 commented Jun 3, 2025

Hello,

I hope I'm explaining this correctly, please let me know if more info or clarifications are necessary.

In ChromeOS we are building external proc_macro crates with -Cprefer-dynamic, like this one. By this I mean non rustc_driver and outside the scope of the rustc_private feature, which modifies the linking behavior such that libstd.so is not dynalically linked if its already statically linked.

This results in binaries which dynamically link against libstd.so, however libstd.so got removed in 2cf1559, so now the binaries fail:

$ ldd /build/amd64-generic/.../spdm_proc_macros-6621385a8bfa4491
        linux-vdso.so.1 (0x00007ffe9954c000)
        libstd-024445ba29c0123d.so => not found
        libm.so.6 => /lib64/libm.so.6 (0x00007fc7c5c65000)
        libc.so.6 => /lib64/libc.so.6 (0x00007fc7c5a85000)
        /lib64/ld-linux-x86-64.so.2 (0x00007fc7c5dda000)

$ readelf -d /build/amd64-generic/.../spdm_proc_macros-6621385a8bfa4491 | grep NEEDED
 0x0000000000000001 (NEEDED)             Shared library: [libstd-024445ba29c0123d.so]
 0x0000000000000001 (NEEDED)             Shared library: [libm.so.6]
 0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]
 0x0000000000000001 (NEEDED)             Shared library: [ld-linux-x86-64.so.2]

Perhaps commit 2cf1559 was too eager in removing libstd.so from the sysroot? AFAIU it incorrectly assumes libstd is always statically linked?

Code

If I remove the can_be_rustc_dynamic_dep check added in commit 2cf1559, the binaries start working again because libstd.so is not gated behind link_std_into_rustc_driver(target_compiler.host) anymore.

Any ideas how to proceed? I can send a PR undoing the can_be_rustc_dynamic_dep check, however maybe the check can somehow be improved? Or is it just an incorrect assumption that libstd is always statically linked?

Version it worked on

Worked fine in 1.82 or earlier, before commit 2cf1559 landed.

If I undo or revert that commit like I mention in the Code section above, binaries work fine again on all versions 1.83 and later.

@rustbot modify labels: +regression-from-stable-to-stable -regression-untriaged

@10ne1 10ne1 added C-bug Category: This is a bug. regression-untriaged Untriaged performance or correctness regression. labels Jun 3, 2025
@rustbot rustbot added needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. I-prioritize Issue: Indicates that prioritization has been requested for this issue. regression-from-stable-to-stable Performance or correctness regression from one stable version to another. and removed regression-untriaged Untriaged performance or correctness regression. labels Jun 3, 2025
@jieyouxu
Copy link
Member

jieyouxu commented Jun 3, 2025

Maybe this is #132202 (cf. relnotes #133352)?

cc @Kobzol

@jieyouxu jieyouxu added T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-bootstrap Relevant to the bootstrap subteam: Rust's build system (x.py and src/bootstrap) A-linkage Area: linking into static, shared libraries and binaries and removed needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. labels Jun 3, 2025
@bjorn3
Copy link
Member

bjorn3 commented Jun 3, 2025

You can add the output of rustc --print target-libdir to LD_LIBRARY_PATH. This is what cargo also does: https://github.com/rust-lang/cargo/blob/f6bebc3abbd9b273a457f77c31f8e93bc77f93fc/src/cargo/core/compiler/compilation.rs#L322

Perhaps commit 2cf1559 was too eager in removing libstd.so from the sysroot? AFAIU it incorrectly assumes libstd is always statically linked?

The copy of libstd.so in lib/ was only meant to be used by rustc. The one to be used by user code is the directory shown by rustc --print target-libdir.

@jieyouxu jieyouxu added C-discussion Category: Discussion or questions that doesn't represent real issues. and removed regression-from-stable-to-stable Performance or correctness regression from one stable version to another. C-bug Category: This is a bug. I-prioritize Issue: Indicates that prioritization has been requested for this issue. labels Jun 3, 2025
@Kobzol
Copy link
Contributor

Kobzol commented Jun 3, 2025

Yeah, this is an instance of Hyrum's Law, this libstd.so shouldn't have ever been used by anything else than rustc, but since it was in the sysroot, some other libraries might have linked to it "by accident".

@10ne1
Copy link
Author

10ne1 commented Jun 3, 2025

Thank you @bjorn3 and @Kobzol for the clarifications

After the initial breakage, ChromeOS applied this workaround in the rust-host ebuild which installed the libstd.so from rustc --print target-libdir in place of the one which you removed (yes, it hardcoded the path and it worked):

doins "${obj}/lib64/rustlib/x86_64-pc-linux-gnu/lib/libstd-"*".so"

I'll replace that with adding rustc --print target-libdir to LD_LIBRARY_PATH.

If it's good enough for cargo, then it's good enough for us as well. 😂

@10ne1 10ne1 closed this as completed Jun 3, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-linkage Area: linking into static, shared libraries and binaries C-discussion Category: Discussion or questions that doesn't represent real issues. T-bootstrap Relevant to the bootstrap subteam: Rust's build system (x.py and src/bootstrap) T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

5 participants