rust项目中的组织关系

组织关系定义在Cargo.toml文件中,内容如下:

  • workspace,包含多个project
  • project,包含多个crate
  • crate,包含多个mod

需要注意的是,project中也可以包含workspace,形成套娃关系。

workspace

workspace可以包含多个member,一个member就是一个project,Cargo.toml定义如下:

[lib]
path = "parity/lib.rs"

[[bin]]
path = "parity/main.rs"
name = "parity"

[workspace]
# This should only list projects that are not
# in the dependency tree in any other way
# (i.e. pretty much only standalone CLI tools)
members = [
   "accounts/ethkey/cli",
   "accounts/ethstore/cli",
   "chainspec",
   "ethcore/wasm/run",
   "evmbin",
]

上面配置的意思就是:

  • 本项目中自身是一个父project,其中包含一个lib,一个bin
  • 本项目还包含子project,定义在workspace中,需要一起编译

project

project中也有Cargo.toml中,会包含多个bin,或者lib,如下:

[lib]
path = "lib/lib.rs"

[[bin]]
path = "bin/main.rs"
name = "parity"

使用Cargo build时,会生成一个库和一个二进制文件。

Crate

一个Crate对应一个bin,或者一个lib,比如下面的project中就有3个create:

[lib]
path = "lib/lib.rs"

[[bin]]
name = "client"
path = "cmd/client/x.rs"

[[bin]]
name = "server"
path = "cmd/server/main.rs"

Crate是一个单独的编译项,可以通过cargo build –bin binname来编译对应的bin crate

也可以通过cargo build –lib libname来编译对应的libcrate

如果使用cargo build,会编译所有的crate

mod

Crate是最小的编译单元,在Crate中一般会包含多个目录和多个文件,这就通过mod管理,下期再讲mod。

项目实战

现在有一个multimod项目,目录结构如下:

项目multimod中包含一个库mylib,两个bin:client和server

其中multimod中的Cargo.toml配置如下:

[package]
name = "multimod"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
mylib = {path="mylib"}

[[bin]]
name = "server"
path = "cmd/server/src/main.rs"

[workspace]
members = [
    "cmd/client"
]

其中bin字段配置了server为一个二进制crate,dependencies描述本项目依赖于mylib库,也就是说编译server的时候,需要先编译mylib库。这里注意两点:

  1. mylib这个库,虽然是在multimod目录下,但实际上是一个独立的project,也就说它只是被multimod project引用而已。与multimod没有任何关系,比如multimod project中的配置dependencies等,不会影响到mylib。事实上,mylib可以放在项目外任意目录下,只需要被正确的引用到就可以。
  2. server这个crate的配置,是定义在multimod/Cargo.toml中。为什么要强调这点,是因为在使用Cargo IDE添加crate的时候,他会在创建的Crate下面一个Cargo.toml文件,比如这样:

事实上,server/Cargo.toml是不起任何作用的。server本身是作为multimod的crate,其配置项是在multimod/Cargo.toml中,而不是server/Cargo.toml中。

明白了project和crate的关系后,我们再来看看client,他是作为workspace中的members被包含在multimod中的,目录结构和Server类似:

但client的意义和server却完全不一样,client是一个独立的project,需要在client/Cargo.toml中配置其属性,比如依赖项,假设client也依赖于mylib,那么multimod/Cargo.toml中的配置对client不生效,需要在client/Cargo.toml中做单独配置:

通过cargo run运行server和client的方式也有所不同:

  • server: cargo run –bin server
  • client: cargo run -p client。-p指的project


发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

About Me

一位程序员,会弹吉他,喜欢读诗。
有一颗感恩的心,一位美丽的妻子,两个可爱的女儿
mail: geraldlee0825@gmail.com
github: https://github.com/lisuxiaoqi
medium: https://medium.com/@geraldlee0825