Я пытаюсь создать дружественный для встраивания исполняемый файл (небольшой размер и не зависящий от стандартной библиотеки Rust), который использует библиотеку (wasmi), которая уже поддерживает сборку no_std
.Новичок в Rust, я просто соединяю воедино инструкции, но суть этого, кажется, , выполните шаги .
Для исполняемого файла:
#![no_std]
#![no_main]
use core::panic::PanicInfo;
/// This function is called on panic.
#[panic_handler]
fn panic(_info: &PanicInfo) -> ! {
loop {}
}
#[no_mangle]
pub extern "C" fn _start(_argc: isize, _argv: *const *const u8) -> ! {
interpret(_argc, _argv);
loop {}
}
То естьto:
- include
#![no_std]
- определить нашу запись (не
main
, поскольку у нас нет среды выполнения, которая будет ее вызывать) - и определитьобработчик паники, поскольку библиотека Rust std не включена для его определения.
Файл My Cargo для компиляции выглядит следующим образом:
[package]
name = "driver"
version = "0.1.0"
edition = "2018"
[dependencies.wasmi]
path = "../../github_dev/wasmi"
features = ["core"]
default-features = false
test=false
bench=false
[profile.release]
panic = "abort"
lto = true
incremental=false
debug=true
opt-level = "z"
test=false
bench=false
и выдает очень маленький файл.двоичный файл, который исключает любые символы стандартной библиотеки (для проверки используется nm
) и работает как положено.
Проблема возникает, когда я на самом деле пытаюсь вызвать функцию из библиотеки wasmi.Он построен с no_std
по линии features=core
.Выполнение nm
для файлов в release/deps/libwasmi-*.rlib
не показывает стандартных символов библиотеки.Однако, когда связывание происходит с этой командой:
rustc --release --verbose -- -C link-arg=-nostartfiles
, это приводит к:
Compiling driver v0.1.0 (/home/my_home/wasmi_embed/driver)
Running rustc --edition=2018 --crate-name driver src/main.rs --color always --crate-type bin --emit=dep-info,link -C opt-level=3 -C panic=abort -C lto -C link-arg=-nostartfiles -C metadata=957eda2e590447ba -C extra-filename=-957eda2e590447ba --out-dir /home/my_home/wasmi_embed/driver/target/release/deps -L dependency=/home/my_home/wasmi_embed/driver/target/release/deps --extern libc=/home/my_home/wasmi_embed/driver/target/release/deps/liblibc-f7fb773c7b059a14.rlib --extern wasmi=/home/my_home/wasmi_embed/driver/target/release/deps/libwasmi-534aef1926b4eb6c.rlib
и возникает ошибка:
error[E0152]: duplicate lang item found: panic_impl.
--> src/main.rs:31:1
|
31 | / pub extern fn panic(_info: &PanicInfo) -> ! {
32 | | loop {}
33 | | }
| |_^
|
= note: first defined in crate `std`.
Кажется, что Rust пытаетсяссылка в стандартной библиотеке поддержки по крайней мере для обработки паники, но я не знаю, почему.
Я хотел бы помочь понять, почему и как предотвратить это.
Если я удалюpanic_impl
атрибут, то мой исполняемый файл компилируется, но он содержит много стандартных библиотечных символов, которые я пытаюсь предотвратить.
Примеры символов, которые я вижу:
my_home@my_puter:~/wasmi_embed/driver/target/release$ nm --demangle -A -a -B -s --line-number test_2018 2>/dev/null | grep std
driver:00000000000264c0 t rust_begin_unwind /rustc/8e2063d02062ee9f088274690a97826333847e17//src/libstd/panicking.rs:311
driver:00000000000264a0 t rust_oom /rustc/8e2063d02062ee9f088274690a97826333847e17//src/libstd/alloc.rs:203
driver:000000000001f490 t rust_panic /rustc/8e2063d02062ee9f088274690a97826333847e17//src/libstd/panicking.rs:524
driver:0000000000025aa0 t _$LT$std..panicking..continue_panic_fmt..PanicPayload$LT$$u27$a$GT$$u20$as$u20$core..panic..BoxMeUp$GT$::get::he4f810e299a2e0b4 /rustc/8e2063d02062ee9f088274690a97826333847e17//src/libstd/panicking.rs:372
driver:00000000000259a0 t _$LT$std..panicking..continue_panic_fmt..PanicPayload$LT$$u27$a$GT$$u20$as$u20$core..panic..BoxMeUp$GT$::box_me_up::hd8430725259668a8 /rustc/8e2063d02062ee9f088274690a97826333847e17//src/libstd/panicking.rs:367
driver:0000000000021520 t _$LT$std..sys_common..process..DefaultEnvKey$u20$as$u20$core..borrow..Borrow$LT$std..ffi..os_str..OsStr$GT$$GT$::borrow::hbacd0cd7d7fbf1c1/rustc/8e2063d02062ee9f088274690a97826333847e17//src/libstd/sys_common/process.rs:27
driver:0000000000021570 t _$LT$std..error..$LT$impl$u20$core..convert..From$LT$alloc..string..String$GT$$u20$for$u20$alloc..boxed..Box$LT$$LP$dyn$u20$std..error..Err
... plus more
Вышеуказанные символы не найдены ни в одном из файлов rlib в каталоге dep
, включая libwasmi, а также в драйвере.исполняется, когда не вызывается код libwasmi.
Я прочитал аналогичную проблему (отсюда мои test=false
и bench=false
в Cargo.toml), но это не помогло.Я пытался собрать только с rustc
с различными командами (исключая Cargo), но ошибка та же.Я пытался скомпилировать wasmi как статическую библиотеку (ar) и связать ее, но, будучи новичком в Rust, я тратил много времени, пытаясь связать его, а этого просто не было.