Таким образом, в настоящее время мы пытаемся скомпилировать некоторый код Rust, который мы затем можем связать с некоторым кодом C.Для этого мы используем Bindgen для генерации FFI, а затем мы будем использовать его для вызова некоторых функций C из Rust.
Однако сначала мы должны иметь ящик "libc" в качестве зависимости в Cargo.Томль файл проекта.Проект, над которым мы сейчас работаем, требует использования атрибута crate wide! # [No_std], так как нам не нужен весь stdlib из Rust.Нам нужно только ядро. libc crate говорит, что мы можем "запросить", чтобы он не был связан со стандартной библиотекой, добавив некоторые параметры в файл Cargo.toml, а именно:
[dependencies]
libc = { version = "0.2", default-features = false }
Это все нормально иДенди, но когда мы пытаемся скомпилировать, мы получаем следующее сообщение об ошибке.
Ubuntu:~/nautilus/src/rust/example# cargo build
Compiling example v0.0.0 (/home/me/nautilus/src/rust/example)
error[E0152]: duplicate lang item found: `panic_impl`.
--> src/lib.rs:33:1
|
33 | / pub fn nk_rust_panic(_info: &PanicInfo) -> !
34 | | {
35 | | // should call nk_panic here...
36 | | loop { }
37 | | }
| |_^
|
= note: first defined in crate `std`.
error: aborting due to previous error
For more information about this error, try `rustc --explain E0152`.
error: Could not compile `example`.
To learn more, run the command again with --verbose.
E0152 - это следующее
A lang item was redefined.
Erroneous code example:
```
#![feature(lang_items)]
#[lang = "arc"]
struct Foo; // error: duplicate lang item found: `arc`
```
Lang items are already implemented in the standard library. Unless you are
writing a free-standing application (e.g. a kernel), you do not need to provide
them yourself.
You can build a free-standing crate by adding `#![no_std]` to the crate
attributes:
```
#![no_std]
```
В нашем файле lib.rs уже есть #! [No_std], но, похоже, что поскольку libc обычно ссылается на stdlib, товозможно, Rust считает, что у нас не может быть собственного обработчика паники, если мы используем libc.
Проблема устраняется, когда мы удаляем libc из файла Cargo.toml и удаляем extern crate lib
из lib.rs.
lib.rs
// no stdlib
#![no_std]
// Give us this feature to override?
#![feature(start)]
#![feature(lang_items)]
// avoid buildins - we want it to use our library
#![no_builtins]
// The following cruft is here to handle Rust->OS dependencies
// currently only one: Rust needs to know how to panic
use core::panic::PanicInfo;
extern crate libc;
#[panic_handler]
#[no_mangle]
pub fn nk_rust_panic(_info: &PanicInfo) -> !
{
// should call nk_panic here... (panic handler of OS)
loop { }
}
Cargo.toml
[package]
name = "example" # this is for core-kernel
version = "0.0.0"
[lib]
crate-type = ["staticlib"]
[dependencies]
libc = { version = "0.2", default-features = false }
[build-dependencies]
bindgen = "0.42.2"
[profile.dev]
panic = "abort" # no stack unwind on rust panic
[profile.release]
panic = "abort" # no stuck unwind on rust panic
Итак, в итоге, делает ли использование libc зависимостью, что мы не можем использовать наш собственный обработчик паники?Есть ли какие-нибудь шаткие флаги компилятора, которые мы можем передать напрямую rustc для устранения этой проблемы?
Компилятор - 1.32.0 - ночная версия Libc - libc v0.2.44