Rust 二进制文件和库无法找到彼此

Vic*_*voy 1 rust

我有一个静态库(Rust 中的操作系统内核),所以我有一个文件树:

  • 源代码/
  • src/lib.rs

我添加了一个二进制文件,以便我可以实际运行我的内核(内核函数在库中实现)。这是项目的一个功能,一旦启用,它就会“启用”附加src/main.rs文件来编译和运行内核,并使项目依赖于bootloadercrate;如果未启用该功能,则src/main.rs不会编译该文件,该bootloader包也不会用于该项目,并且我src/lib.rs自己通过链接 rustc 稍后生成的静态库直接从汇编文件中调用这些函数:

[package]
name = "myos"
version = "0.1.0"
edition = "2018"

[lib]
crate-type = ["staticlib"]

# This is for the case of `src/bin/main.rs` which doesn't work as well.
#[[bin]]
#name = "main"
#required-features = ["bootloader"]

[dependencies.bootloader]
version = "0.10"
optional = true

[profile.dev]
panic = "abort"

[profile.release]
panic = "abort"

[features]
default = ["bootloader"]
Run Code Online (Sandbox Code Playgroud)

问题是无论我如何尝试main.rs都看不到lib.rs

库文件

[package]
name = "myos"
version = "0.1.0"
edition = "2018"

[lib]
crate-type = ["staticlib"]

# This is for the case of `src/bin/main.rs` which doesn't work as well.
#[[bin]]
#name = "main"
#required-features = ["bootloader"]

[dependencies.bootloader]
version = "0.10"
optional = true

[profile.dev]
panic = "abort"

[profile.release]
panic = "abort"

[features]
default = ["bootloader"]
Run Code Online (Sandbox Code Playgroud)

主程序.rs

#![no_std]

#[no_mangle]
pub extern "C" fn main() -> i32 {
    0
}

#[no_mangle]
pub extern "C" fn kernel_early() {

}

pub fn myos_panic(info: &core::panic::PanicInfo<'_>) -> ! {
    loop {}
}
Run Code Online (Sandbox Code Playgroud)

该项目的板条箱名称是myos。这是我迄今为止尝试使用的模块中的kernel_earlymain函数:lib.rsmain.rs

#![no_std]
#![no_main]

use myos::{kernel_early, main};

#[no_mangle]
pub extern "C" fn _start() -> ! {
    kernel_early();
    main();

    loop {}
}

use core::panic::PanicInfo;

#[panic_handler]
fn panic(info: &PanicInfo<'_>) -> ! {
    crate::myos_panic(info);
}
Run Code Online (Sandbox Code Playgroud)

mod lib; use lib::*当然,甚至尝试过玩,这只会让事情变得更糟。

如何使二进制文件真正与我的库一起使用?我制作了大量的货物示例,我知道它们是如何工作的,但它似乎不适用于这样一种项目结构,其中二进制文件和库都在一个箱子中。我也尝试过将其移至src/main.rssrc/bin/main.rs效果完全相同。

我的错误是:

 --> src/main.rs:4:5
  |
4 | use myos::{kernel_early, main};
  |     ^^^^ use of undeclared crate or module `myos`

error[E0432]: unresolved imports `crate::kernel_early`, `crate::main`
 --> src/main.rs:4:13
  |
4 | use crate::{kernel_early, main};
  |             ^^^^^^^^^^^^  ^^^^ no `main` in the root
  |             |
  |             no `kernel_early` in the root

error[E0425]: cannot find function `myos_panic` in the crate root
  --> src/main.rs:18:12
   |
18 |     crate::myos_panic(info);
   |            ^^^^^^^^^^ not found in the crate root
Run Code Online (Sandbox Code Playgroud)

PS 问题不在于名称修改,因为我也尝试在不禁用它的情况下调用函数。

Kev*_*eid 7

您已经指定了crate-type = ["staticlib"]您的库,该库仅生成目标本机静态库格式的库。您不能将这样的库用作普通的 Rust 板条箱 ( use myos::),因为这需要一个"rlib"(或暂时等效的"lib")板条箱类型。

我认为如果你像 C 函数一样声明库中的函数,它可能会起作用,即

extern {
   fn main() -> i32;
   fn kernel_early();
}
Run Code Online (Sandbox Code Playgroud)

并链接到已编译的 staticlib,就像链接到 C 库一样。(我不知道它实际上是如何工作的;我自己只使用过-sys板条箱。)

但是,如果您想做任何 Rusty 无法通过 C ABI 完成的事情(如泛型函数),这对您没有帮助。如果我理解正确,您的二进制文件只是用于测试库代码。在这种情况下,您可以将目标配置更改为

[lib]
crate-type = ["staticlib", "lib"]
Run Code Online (Sandbox Code Playgroud)

然后 Cargo 将构建这两种格式;用于lib您的测试二进制文件和staticlib用于您的裸机引导加载程序。