Safe to link to static libstdc++ from shared library?
Jonathan Wakely
jwakely@redhat.com
Fri Nov 14 14:18:02 GMT 2025
On Fri, 14 Nov 2025 at 14:10, Fredrik Orderud <forderud@gmail.com> wrote:
>
> On Fri, Nov 14, 2025 at 2:52 PM Jonathan Wakely <jwakely@redhat.com> wrote:
> > On Fri, 14 Nov 2025 at 13:45, Fredrik Orderud <forderud@gmail.com> wrote:
> > > I'm working on a project developing a Linux shared library (.so) with
> > > a pure "C" interface that we want to be as widely compatible as
> > > possible with multiple distros of various age. The -static-libstdc++
> > > option therefore seemed attractive, since it appear to eliminate
> > > run-time dependencies to libstdc++. We've therefore used
> > > -static-libstdc++ together with -Wl,--exclude-libs,ALL in an attempt
> > > to encapsulate all C++ dependencies (and other 3rd party libraries),
> > > so that callers doesn't need to know about the C++ stuff inside the
> > > shared library.
> > >
> > > This worked fine for a while, but now we suddenly started experiencing
> > > segmentation faults when calling std::async from the shared lib. I'm
> > > not sure if this is a caused by a bug, a known limitation or our
> > > misunderstanding of the libstdc++ documentation. A minimal reproducer
> > > is available on
> > > https://github.com/forderud/UnixSharedLib/tree/main/static-libstdc%2B%2B
> > >
> > > ASK: Are there any documented or undocumented limitations on
> > > -static-libstdc++ usage when building shared libraries on Linux?
> >
> > The problem is your use of --exclude-libs - that won't work.
> >
> > You can't pretend there are no dependencies on the C++ runtime like
> > that, the symbols in libstdc++ need to be globally visible so that the
> > linker can properly resolve them across different ELF objects.
>
> Ok, so what we're doing is supported if we just let the libstdc++
> symbols "leak out" from our shared library?
>
> If so, then will we still avoid run-time dependencies to the
> distro-provided libstdc++?
I don't recommend trying to avoid those dependencies. See below.
> Also, will it be safe for the client executable to potentially use a
> different libstdc++ version than what's used in our shared library?
In general, no.
I don't recommend trying to do this at all. The approach I would
recommend is deciding on a minimum version of libstdc++.so.6 that you
support (based on the oldest distro you need to support) and then
building against that, and not trying to bundle libstdc++ symbols in
your library at all. Just let them be resolved by the system
libstdc++.so.6 provided by the target system.
On RHEL-like systems this is trivial, by using the GCC Toolset
packages. If you're trying to support a wider range of distros with a
single binary, that's going to be harder. But if you build against the
oldest libstdc++.so.6 that you need to support (e.g. in a VM or
container running the old distro) then your library should be able to
run on any distro that provides a libstdc++.so.6 that is no older than
the one you built against.
Since you're using C++11 features, you should not try to use anything
older than the libstdc++ that came with GCC 5, as that's when C++11
support became ABI-stable.
More information about the Libstdc++
mailing list