【问题标题】:Rust binary and library can't find each otherRust 二进制文件和库找不到彼此
【发布时间】:2021-10-16 04:15:53
【问题描述】:

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

  • src/
  • src/lib.rs

我添加了一个二进制文件,以便我可以实际运行我的内核(内核函数在库中实现)。这是项目的一个特性,一旦启用,它就会“启用”附加的src/main.rs 文件来编译和运行内核,并使项目依赖于bootloader crate;如果未启用该功能,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"]

问题是main.rs不管我怎么尝试都看不到lib.rs

lib.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 {}
}

ma​​in.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);
}

项目的箱子名称是myos。这是我迄今为止尝试使用main.rslib.rs 模块中的kernel_earlymain 函数:

use myos::{kernel_early, main};
use crate::{kernel_early, main};
use super::{kernel_early, main};

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

如何使二进制文件真正与我的库一起使用?我制作了大量的货物示例,我知道它们是如何工作的,但它似乎不适用于这样一个二进制文件和一个库都在一个箱子中的项目结构。我也试过把src/main.rs移到src/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

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

【问题讨论】:

    标签: rust


    【解决方案1】:

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

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

    extern {
       fn main() -> i32;
       fn kernel_early();
    }
    

    并像链接到 C 库一样链接到已编译的静态库。 (我不知道这实际上是如何工作的;我自己只使用过-sys crates。)

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

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

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

    【讨论】:

      猜你喜欢
      • 2015-01-12
      • 2021-10-07
      • 2013-10-05
      • 2013-03-24
      • 1970-01-01
      • 1970-01-01
      • 2013-05-10
      • 2015-02-14
      相关资源
      最近更新 更多