How can i build a binary linked with libstd sharedly

i'm trying to build a shared binary:
cargo rustc -- -C prefer-dynamic

but the binary dont build

Cargo.toml:
[package]
name = "test-shared"
version = "0.1.0"
edition = "2021"

[profile.release]
panic = "abort"
lto = true

lto and panic

dylib

Although I dont know what "cannot use" means, but I guess you may need some configuration in Cargo.toml.

Cargo run directly, and I guess you can find the result in target folder.

(I did not compile dylib, but I guess this may work)

first of all, is threre a reason you use cargo rustc instead of cargo build? it'll be much easier to do if you use cargo the usual way, e.g., add these to the cargo manifest:

# Cargo.toml
[lib]
crate-type = ["cdylib"]

# `dev` is for debug builds, `release` is for release builds
[profile.dev]
panic = "abort"
lto = true

note, -C prefer-dynamic does NOT build your crate as a shared library. instead, it tells the compiler to choose shared libraries (instead of static libraries) for dependency crates, including std.

the command line option for rustc to generate shared library is --crate-type cdylib (or maybe --crate-type dylib if you understand what it means).

what do you mean by "cant use"? panic='abort' has nothing to do with crate types. you just add panic = 'abort' to cargo manifest's profile section and it just works.

note, this only affects your crate, it doesn't affect dependencies like std.

same as panic = 'abort'

rust doesn't guarantee stable ABI, it's not recommend to dynamically link to std, because that'll tie your program to libstd of the exact same version of the compiler. the hash of the library file can be used to uniquely identify the version of libstd (it is generated using more information, such as the compile flags, than just the version, but the exact algorithm is internal to rustc and should be treated opaquely)

but if you do use dynamic linkage, the library file is located in some subdirectory of the rust toolchain (which, by default, is not in LD_LIBRARY_PATH).

  • on linux, it should be $(toolchain)/lib/rustlib/x86_64-unknown-linux-gnu/lib/libstd-$(hash).so
  • on windows, it should be similar, but I think it is also available at $(toolchain)/bin/std-$(hash).dll
2 Likes

libstd.so links in the panic runtime for panic=unwind. There can be only one panic runtime in the entire program, so you can't use panic=abort while also linking to libstd.so.

You can't do is building a rust dylib with LTO if you are on stable. But building an executable or cdylib that links against a rust dylib with LTO should work.

You need to tell the dynamic linker to search in the directory returned by rustc --print target-libdir. For example by setting LD_LIBRARY_PATH (most Unixes), DYLD_LIBRARY_PATH (macOS) or PATH (Windows)

Rust doesn't have a stable abi. As such you have to use the exact libstd.so that matches the rustc version with which your program was compiled. Without this hash it wouldn't be possible to install multiple different versions of libstd.so next to each other.

Not anymore. This copy was for use by rustc itself only. Nowadays the copy of libstd used by rustc is linked directly into rustc_driver.dll.

so, what does it mean? I think its simply a rust link to shared libstd