Skip to content
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

Unable to build 'no_std' crate into dylib #104159

Open
crazyboycjr opened this issue Nov 8, 2022 · 2 comments
Open

Unable to build 'no_std' crate into dylib #104159

crazyboycjr opened this issue Nov 8, 2022 · 2 comments
Labels
A-lang-item Area: Language items A-linkage Area: linking into static, shared libraries and binaries A-runtime Area: std's runtime and "pre-main" init for handling backtraces, unwinds, stack overflows

Comments

@crazyboycjr
Copy link

crazyboycjr commented Nov 8, 2022

Hi folks,

I am having an issue of building a dylib with no_std.

$ cat src/lib.rs
#[no_std]

$ rustc src/lib.rs --crate-type dylib -C prefer-dynamic -o libnostd_dylib.so
error: language item required, but not found: `eh_personality`

error: `#[panic_handler]` function required, but not found

error: aborting due to 2 previous errors

After adding the missing language items, the compilation is fine.

$ cat src/lib.rs
#![no_std]
#![feature(lang_items)]
#[lang = "eh_personality"] extern fn eh_personality() {}
#[panic_handler] fn panic(_info: &core::panic::PanicInfo) -> ! { loop {} }

But linking the product (libnostd_dylib.so) into an executable gives me duplicate language items.

$ cat src/main.rs
use nostd_dylib;
fn main() { }

$ rustc --edition=2021 src/main.rs --crate-type bin -L . --extern nostd_dylib=libnostd_dylib.so -C prefer-dynamic # cargo build also works the same way
warning: unused import: `nostd_dylib`
 --> src/main.rs:1:5
  |
1 | use nostd_dylib;
  |     ^^^^^^^^^^^
  |
  = note: `#[warn(unused_imports)]` on by default

error: duplicate lang item in crate `lib` (which `main` depends on): `panic_impl`.
  |
  = note: the lang item is first defined in crate `std` (which `main` depends on)
  = note: first definition in `std` loaded from /home/cjr/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libstd-d6566390077dd5f5.so, /home/cjr/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libstd-d6566390077dd5f5.rlib
  = note: second definition in `lib` loaded from /home/cjr/misc/nostd-dylib/libnostd_dylib.so

error: duplicate lang item in crate `lib` (which `main` depends on): `eh_personality`.
  |
  = note: the lang item is first defined in crate `panic_unwind` (which `std` depends on)
  = note: first definition in `panic_unwind` loaded from /home/cjr/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libpanic_unwind-a8f484438681c15e.rlib
  = note: second definition in `lib` loaded from /home/cjr/misc/nostd-dylib/libnostd_dylib.so

error: aborting due to 2 previous errors; 1 warning emitted

As others have pointed out (https://stackoverflow.com/questions/43097676/how-to-build-a-standard-linux-so-library-with-stable-rust-without-using-std), an end product such as a binary executable needs panic handlers and exception handling routines to run. I can understand that. I may also partially get/accept the point that a shared library could be an end product (perhaps it would be better if someone could name an example).

But what I feel quite confusing is that, most of the time, the dylib could be intermediate (I know it will be linked by other crates/executables), and those crates (or libstd) will ultimately provide these language items, so how can I produce a no_std dylib without providing these two language items in this crate itself?

@crazyboycjr
Copy link
Author

crazyboycjr commented Nov 9, 2022

Is it possible to define weak symbols for those functions related to panic and unwind handling so that these two lang items could be optionally in a dylib?

@jyn514 jyn514 added A-lang-item Area: Language items A-linkage Area: linking into static, shared libraries and binaries A-runtime Area: std's runtime and "pre-main" init for handling backtraces, unwinds, stack overflows labels Apr 11, 2023
@bjorn3
Copy link
Member

bjorn3 commented May 17, 2023

For ELF every function exported by a dylib effectively has weak linkage. This means there is no way to ensure that libstd's copy of the panic handler will be chosen as opposed to the dummy one in libnostd_dylib.so.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-lang-item Area: Language items A-linkage Area: linking into static, shared libraries and binaries A-runtime Area: std's runtime and "pre-main" init for handling backtraces, unwinds, stack overflows
Projects
None yet
Development

No branches or pull requests

3 participants