< 返回版块

xiaoyureed 发表于 2020-12-20 10:58

Tags:cargo, dependency

我在用 cargo 使用 workspace 创建多模块项目, 结构像这个样子

blockchain
├── Cargo.lock
├── Cargo.toml
├── core
│   ├── Cargo.toml
│   └── src
│       ├── block.rs
│       └── lib.rs
├── main
│   ├── Cargo.toml
│   └── src
│       └── main.rs
└── util
    ├── Cargo.toml
    └── src
        ├── codec.rs
        └── lib.rs

我在 util 下面使用了一个 依赖 a, 然后在 core 里面也想使用 a, 可以只导入 util 就实现依赖传递吗? 类似 maven 中 的 optional 属性

我试了一下好像不行, 必须在 core 里面再次导入一遍 a.

评论区

写评论
作者 xiaoyureed 2020-12-20 21:29

谢谢解答 我了解了

--
👇
Cupnfish: 除此之外,cargo有个RFC是继承workspace根目录依赖的,不过还没有完成,看了roadmap已经完成九成了,估计在过段时间就可以在nightly使用了。 使用流程大概是这样的: workspace的根目录添加上多个子目录可能会使用的依赖, 然后子目录的Cargo.toml的依赖项依然需要表明需要哪个依赖,但是可以知名该依赖继承自根目录。

Cupnfish 2020-12-20 15:22

除此之外,cargo有个RFC是继承workspace根目录依赖的,不过还没有完成,看了roadmap已经完成九成了,估计在过段时间就可以在nightly使用了。 使用流程大概是这样的: workspace的根目录添加上多个子目录可能会使用的依赖, 然后子目录的Cargo.toml的依赖项依然需要表明需要哪个依赖,但是可以知名该依赖继承自根目录。

Cupnfish 2020-12-20 15:12

serde这个比较特殊,因为有过程宏,所以导出的时候必须把实现这两个trait的过程宏一起导出 在#2这个地方可以试着改成:

pub mod Re_serde {
    pub use serde::*;
}

不过,我试了一下,发现目前stable用不了这种方法,会报这样的错误:

use of unstable library feature 'rustc_private': this crate is being loaded from the sysroot, an unstable location; did you mean to load this crate from crates.io via `Cargo.toml` instead?

正如错误所说,最好的方法是通过Cargo.toml加入新依赖。 当然执意要使用的话,开启的方法也很简单,在#2里面使用这个就可以了,不过需要nightly版的rust:

#![feature(rustc_private)]

--
👇
xiaoyureed: 我按照您说的, 做了下面 1, 2, 3 ,4, 但是碰到一个错误, 不知道是不是这么做的

blockchain
├── Cargo.lock
├── Cargo.toml
├── core
│   ├── Cargo.toml # 3 util = { path = "../util" }
│   └── src
│       ├── block.rs # 4 
│       └── lib.rs
├── main
│   ├── Cargo.toml
│   └── src
│       └── main.rs
├── target
└── util
    ├── Cargo.toml # 1. serde = {version = "1.0.118", features = ["derive"]}
    └── src
        ├── codec.rs
        └── lib.rs # 2.  pub use serde;

4 处的代码是这样:


use util::serde::{Deserialize, Serialize};

#[derive(Debug, Deserialize, Serialize)] // 这里 error: 
pub struct BlockHeader {
    pub a: i64,
}

错误提示 cannot find crate for "serde" (截图 https://sm.ms/image/H7hDxyqupjcAdQi)

Cupnfish: 首先想象一下,如果你在core里面突然就使用a了,看你代码的人发现Cargo.toml里面不存在a的依赖,这是多么荒唐?解决方法你可以在util里面重新导出a,在core里面导入util里面导出的a就可以了。

whfuyn 2020-12-20 14:57

这是因为#[derive(Serialize)]里面的过程宏依赖了你当前crate的依赖里有serde这件事。 不要这么搞,直接在当前crate的Cargo.toml里加依赖就好。

下面是分析:

如果当前crate里没有serde,那么会提示找不到它而无法展开,我们把它加上后展开宏。

cargo rustc -- -Z unstable-options -Z macro-backtrace --pretty=expanded

可以看到

    use util::serde::{Deserialize, Serialize};
    pub struct BlockHeader {
        pub a: i64,
    }
    #[doc(hidden)]
    #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
    const _: () =
        {
            #[allow(rust_2018_idioms, clippy :: useless_attribute)]
            extern crate serde as _serde;  // <-------------------------------- 这行依赖了`serde`

// ....

--
👇
xiaoyureed: 我按照您说的, 做了下面 1, 2, 3 ,4, 但是碰到一个错误, 不知道是不是这么做的

blockchain
├── Cargo.lock
├── Cargo.toml
├── core
│   ├── Cargo.toml # 3 util = { path = "../util" }
│   └── src
│       ├── block.rs # 4 
│       └── lib.rs
├── main
│   ├── Cargo.toml
│   └── src
│       └── main.rs
├── target
└── util
    ├── Cargo.toml # 1. serde = {version = "1.0.118", features = ["derive"]}
    └── src
        ├── codec.rs
        └── lib.rs # 2.  pub use serde;

4 处的代码是这样:


use util::serde::{Deserialize, Serialize};

#[derive(Debug, Deserialize, Serialize)] // 这里 error: 
pub struct BlockHeader {
    pub a: i64,
}

错误提示 cannot find crate for "serde" (截图 https://sm.ms/image/H7hDxyqupjcAdQi)

--
👇
Cupnfish:

--
👇
Cupnfish: 首先想象一下,如果你在core里面突然就使用a了,看你代码的人发现Cargo.toml里面不存在a的依赖,这是多么荒唐?解决方法你可以在util里面重新导出a,在core里面导入util里面导出的a就可以了。

作者 xiaoyureed 2020-12-20 12:59

我按照您说的, 做了下面 1, 2, 3 ,4, 但是碰到一个错误, 不知道是不是这么做的

blockchain
├── Cargo.lock
├── Cargo.toml
├── core
│   ├── Cargo.toml # 3 util = { path = "../util" }
│   └── src
│       ├── block.rs # 4 
│       └── lib.rs
├── main
│   ├── Cargo.toml
│   └── src
│       └── main.rs
├── target
└── util
    ├── Cargo.toml # 1. serde = {version = "1.0.118", features = ["derive"]}
    └── src
        ├── codec.rs
        └── lib.rs # 2.  pub use serde;

4 处的代码是这样:


use util::serde::{Deserialize, Serialize};

#[derive(Debug, Deserialize, Serialize)] // 这里 error: 
pub struct BlockHeader {
    pub a: i64,
}

错误提示 cannot find crate for "serde" (截图 https://sm.ms/image/H7hDxyqupjcAdQi)

--
👇
Cupnfish:

--
👇
Cupnfish: 首先想象一下,如果你在core里面突然就使用a了,看你代码的人发现Cargo.toml里面不存在a的依赖,这是多么荒唐?解决方法你可以在util里面重新导出a,在core里面导入util里面导出的a就可以了。

Cupnfish 2020-12-20 12:00

--
👇
Cupnfish: 首先想象一下,如果你在core里面突然就使用a了,看你代码的人发现Cargo.toml里面不存在a的依赖,这是多么荒唐?解决方法你可以在util里面重新导出a,在core里面导入util里面导出的a就可以了。

1 共 6 条评论, 1 页