How safe link C library twice?

Let's suppose I have crate A that link library foo v1.0 and uses it, but doesn't pub use anything from foo.
And I have crate B that link the same library foo, but version 2.0 and uses it, but again doesnt' pub use anything from foo. And I build executable with dependicies on "crate A" and "crate B".
I don't get any link errors.

But I wonder what happend with "C" symbols that have the same name in "foo v 1.0" and "foo v 2.0"? rustc hide it somehow, or linker just take the first one from the symbols with the same name (what would be really bad)?

For Rust functions it's not a problem, because function names include crate version. When you call foo::bar() it's actually calling something like crate_foo_version_1.0_function_bar() (the actual symbol name is mangled and hashed, but has all this info).

For crates that use C code, Rust can't do anything. It's the same old C, with the same old C linker. It's going to be a pain, as all versions will likely export conflicting unprefixed symbol names. Usually there's no way around this, which is why Cargo has a links property to detect this problem and prevent use of conflicting C crates (but this attribute just shows the error early, it can't fix it).

So if you have Rust libs, don't worry. If you have C libs, try hard to avoid mixing versions.

uaually trying to do so will give a 'duplicate symbo' error when linking the binary

some dynamic linkers (such as linux's) have support for versioned symbols (glibc uses this quite heavily), but even so i don't think it's ever safe to link two different versions of the same c or c++ library

(if you really need this, it's possible to do tricks at runtime like dlopen with RTLD_LOCAL, but, it's a deep rabbit hole … it can still give problems with dependencies of dependencies, absolutely better to avoid it)

To introduce the worst case, it is possible to linker links random functions with same symbol. For example when you call the function with the conflicting name, this function is called if you built the executable at even millisecond, but that function is called if built at odd millisecond, really.

1 Like

As others have already suggested, you shouldn't link two versions of the same C library to a single executable. This is just not going to work.

Try to avoid that at all costs. I wonder what your use case is, though.

I wonder what your use case is

Ordinary issue, I use sqlite, and target OS (Linux) doesn't contain suitable sqlite,
sqlite version is too old. So I use rust crate rusqlite with feature bundle, so sqlite build as static library and linked into my project. At the same time I depend on huge C++ library that embedded sqlite into itself.
The bad thing, that C++ have several patches for sqlite and I am not sure how good it for me.