Add cc_runtime_linkage setting for static C++ runtime in shared libs#25
Merged
dzbarsky merged 1 commit intoJun 10, 2026
Merged
Conversation
rust_shared_library links the cc toolchain's C++ runtime (libstdc++/libc++ and the unwinder) dynamically, so it becomes an external DT_NEEDED on the produced shared library. When shipping a self-contained .so to a consumer that uses a different C++ stdlib, that dynamic dependency is undesirable. Add a `cc_runtime_linkage` attribute on rust_shared_library (dynamic|static, default dynamic so existing behavior is unchanged). When static, the C++ runtime is linked via cc_toolchain.static_runtime_lib so it is embedded in the shared library and no libstdc++/libc++/libunwind DT_NEEDED is emitted. get_cc_toolchain_runtime_libs gains a `linkage` parameter resolved from the attribute. Non-shared crate types are unchanged.
9f60d26 to
e3b36f3
Compare
dzbarsky
approved these changes
Jun 10, 2026
dzbarsky
pushed a commit
that referenced
this pull request
Jun 14, 2026
#25) rust_shared_library links the cc toolchain's C++ runtime (libstdc++/libc++ and the unwinder) dynamically, so it becomes an external DT_NEEDED on the produced shared library. When shipping a self-contained .so to a consumer that uses a different C++ stdlib, that dynamic dependency is undesirable. Add a `cc_runtime_linkage` attribute on rust_shared_library (dynamic|static, default dynamic so existing behavior is unchanged). When static, the C++ runtime is linked via cc_toolchain.static_runtime_lib so it is embedded in the shared library and no libstdc++/libc++/libunwind DT_NEEDED is emitted. get_cc_toolchain_runtime_libs gains a `linkage` parameter resolved from the attribute. Non-shared crate types are unchanged.
|
@walter-zeromatter Thank you so much for this, I faced the same issue and was working around it with a dirty patch, really appreciate the work you did here 🙏🏼 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation
cdylib/dylibtargets link the cc toolchain's C++ runtime (libstdc++/libc++ and the unwinder) dynamically —get_cc_toolchain_runtime_libscallscc_toolchain.dynamic_runtime_lib()for these crate types. The runtime therefore becomes an externalDT_NEEDEDon the produced.so.When shipping a self-contained shared library to a consumer that uses a different C++ stdlib (e.g. a GCC
libstdc++environment consuming a library built with an LLVM/libc++ toolchain), forcing a dynamiclibc++/libc++abi/libunwinddependency is undesirable — the consumer would have to ship the producer's C++ runtime.What this adds
An opt-in way to link the C++ runtime statically into shared libraries, so they carry no external C++ runtime dependency and the unwinder is embedded:
//rust/settings:cc_runtime_linkagestring flag —dynamic | static, defaultdynamic(no behavior change for existing users).cc_runtime_linkageattribute onrust_shared_library—auto | dynamic | static,auto(default) defers to the flag, so individual targets can opt in without flipping the global default.get_cc_toolchain_runtime_libsgains alinkageparameter; whenstatic, it returnscc_toolchain.static_runtime_lib(...)forcdylib/dylib(the same call already used for all non-shared crate types). Both call sites resolve linkage viaresolve_cc_runtime_linkage(ctx)(per-target attr overriding the flag).Non-shared crate types are unchanged.
Effect (with
cc_runtime_linkage = "static")A Rust
cdylibbuilt against an LLVM/libc++ toolchain goes from:to a self-contained
.so: thoseNEEDEDentries gone,_Unwind_*defined in-binary.