Skip to content

Unable to build 'no_std' crate into dylib #104159

@crazyboycjr

Description

@crazyboycjr

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?

Activity

crazyboycjr

crazyboycjr commented on Nov 9, 2022

@crazyboycjr
Author

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?

added
A-linkageArea: linking into static, shared libraries and binaries
A-runtimeArea: std's runtime and "pre-main" init for handling backtraces, unwinds, stack overflows
on Apr 11, 2023
bjorn3

bjorn3 commented on May 17, 2023

@bjorn3
Member

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-lang-itemArea: Language itemsA-linkageArea: linking into static, shared libraries and binariesA-runtimeArea: std's runtime and "pre-main" init for handling backtraces, unwinds, stack overflows

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @crazyboycjr@bjorn3@jyn514

        Issue actions

          Unable to build 'no_std' crate into dylib · Issue #104159 · rust-lang/rust