在https://crates.io/上发布库
通过workspaces 组织大工程
从https://crates.io/来安装库
使用自定义命令扩展cargo
1、通过release profile来自定义构建
release profile:
一是预定义的
一可自定义:可使用不同的配置,对代码编译拥有更多的控制
每个profile 的配置都独立于其它的profile
Cargo主要的两个profile:
dev profile:适用于开发,cargo build
release profile:适用于发布,cargo build --release
自定义profile
针对每个profile,Cargo都提供了默认的配置
如果想自定义xxxx profile 的配置:
-可以在Cargo.toml里添加[profile.xxxx]区域,在里面覆盖默认配置的子集
cargo.toml中添加如下:
[package]
name = "closure"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
[profile.dev]
opt-level = 0
[profile.release]
opt-level = 3
如果我们执行cargo build即dev,那么opt-level的参数就等于0
如果我们执行cargo build --release,那么opt-level的参数就等于3
opt-level指的是rust的代码优化从0到3依次升高,值越大优化的层次越高,当然编译的时间也会越来越长,那么我们在开发阶段因为编译的次数比较多,
所以我们一般会设置小一点的值,当真正发布产品的时候我们就设置为3,这样编译的时间会变长,但是代码的优化层次会比较高。
对于每个配置的默认值和完整选项,请参见:Introduction - The Cargo Book (rust-lang.org)
2、发布crate到crates.io(一)
crates.io。
可以通过发布包来共享你的代码
crate 的注册表在 https://crates.io/
一它会分发已注册的包的源代码
一主要托管开源的代码
文档注释
文档注释:用于生成文档
一生成HTML文档
一显式公共API的文档注释:如何使用API
―使用///
-支持 Markdown
―放置在被说明条目之前
///Adds one to the number given.
///# Examples
///```
///let arg = 5;
///let answer = closure::add_one(arg);
///assert_eq!(6, answer);
///```
pub fn add_one(a:u32)->u32 {
a + 1
}
然后我们使用cargo doc来生成文档
我们打开上面路径的html就能够看到生成的文档了:
生成HTML文档的命令
cargo doc
一它会运行rustdoc工具(Rust安装包自带)
―把生成的HTML文档放在 target/doc目录下
cargo doc -open:
一构建当前crate 的文档(也包含crate 依赖项的文档)
一在浏览器打开文档
常用章节
# Examples其它常用的章节:
- Panics:函数可能发生panic的场景
- - Errors:如果函数返回Result,描述可能的错误种类,以及可导致错误的条件
- Safety:如果函数处于unsafe 调用,就应该解释函数unsafe 的原因,以及调用者确保的使用前提。
文档注释作为测试
示例代码块的附加值:
一运行cargo test:将把文档注释中的示例代码作为测试来运行
为包含注释的项添加文档注释
符号://!
这类注释通常用描述crate和模块:
- crate root(按惯例src/lib.rs)
一个模块内,将crate或模块作为一个整体进行记录
这是当前的文档,现在我们在来添加一些注释
//! # 你好这是我发布的一个库
//! 你好这是我发布的一个库
//! 你好这是我发布的一个库
///Adds one to the number given.
///# Examples
///```
///let arg = 5;
///let answer = closure::add_one(arg);
///assert_eq!(6, answer);
///```
pub fn add_one(a:u32)->u32 {
a + 1
}
现在我们就在函数的外层添加了一些注释信息了
3、Pub Use
使用pub use导出方便使用的公共API
问题: crate 的程序结构在开发时对于开发者很合理,但对于它的使用者不够方便
一开发者会把程序结构分为很多层,使用者想找到这种深层结构中的某个类型很费劲
例如:
―麻烦: my_crate::some_module:another_module::UsefulType;
一方便:my_crate::UsefulType;.
解决办法:
不需要重新组织内部代码结构
使用pub use:可以重新导出,创建一个与内部私有结构不同的对外公共结构
libs.rs:
pub mod kinds {
pub enum PrimaryColor {
Red,
Yellow,
Blue
}
pub enum SecondaryColor {
Orange,
Green,
Purple,
}
}
pub mod utils {
use crate::kinds::*;
pub fn mix(c1: PrimaryColor,c2: PrimaryColor)->SecondaryColor {
SecondaryColor::Green
}
}
main.rs:
use closure::utils::mix;
use closure::kinds::PrimaryColor;
fn main() {
let red = PrimaryColor::Red;
let yellow = PrimaryColor::Yellow;
mix(red,yellow);
}
我们可以使用cargo doc --open打开文档:
我们修改lib.rs代码后:
pub use self::kinds::PrimaryColor;
pub use self::kinds::SecondaryColor;
pub use self::utils::mix;
pub mod kinds {
pub enum PrimaryColor {
Red,
Yellow,
Blue
}
pub enum SecondaryColor {
Orange,
Green,
Purple,
}
}
pub mod utils {
use crate::kinds::*;
pub fn mix(c1: PrimaryColor,c2: PrimaryColor)->SecondaryColor {
SecondaryColor::Green
}
}
再次使用cargo doc --open打开文档:
现在我们查找那个些类型就非常方便了,我们可以直接点击即可进入到对应的方法中
然后我们在main.rs中就可以修改:
// use closure::utils::mix;
// use closure::kinds::PrimaryColor;
use closure::mix;
use closure::PrimaryColor;
fn main() {
let red = PrimaryColor::Red;
let yellow = PrimaryColor::Yellow;
mix(red,yellow);
}
这样导入类型和函数就非常的方便了
四、发布crate到crates.io(二)
创建并设置Crates.io 账号
发布 crate前,需要在 crates.io 创建账号并获得API token
运行命令: cargo login[你的APl token]
―通知cargo,你的API token存储在本地~/.cargo/credentials
crates.io: Rust Package Registry
我们直接使用gihub登录授权:
看图进行设置
APl token可以在https://crates.io/进行撤销
搜索一个库名,发现没有后我们在使用cargo new 创建这个项目
为新的crate 添加元数据
在发布crate之前,需要在Cargo.toml的[package]区域为crate添加一些元数据:
- crate需要唯一的名称: name
- description:一两句话即可,会出现在 crate搜索的结果里
- license:需提供许可证标识值(可到SPDX License List | Software Package Data Exchange (SPDX)查找)
可指定多个license:用OR
version
author
发布: cargo publish命令
首先在github上创建一个仓库
发布成功后,我们在搜索即可找到我们发库:
发布到Crates.io
crate一旦发布,就是永久性的:该版本无法覆盖,代码无法删除
目的:依赖于该版本的项目可继续正常工作
发布已存在crate的新版本
修改crate 后,需要先修改Cargo.toml里面的version值,再进行重新发布
参照http://semver.ora/来使用你的语义版本
再执行cargo publish进行发布
使用cargo yank从 Crates.io 撤回版本
不可以删除crate 之前的版本
但可以防止其它项目把它作为新的依赖: yank(撤回)一个crate 版本一防止新项目依赖于该版本
一已经存在项目可继续将其作为依赖(并可下载)
命令:
yank一个版本(不会删除任何代码): cargo yank --vers 1.0.1
取消yank: cargo yank --vers 1.0.1 --undo
5、Cargo工作空间( Workspaces)
cargo工作空间:帮助管理多个相互关联且需要协同开发的crate
cargo工作空间是一套共享同一个Cargo.lock和输出文件夹的包
创建工作空间
有多种方式来组建工作空间例:1个二进制crate,2个库crate
二进制crate: main函数,依赖于其它2个库crate
其中1个库crate提供add_one函数
另外1个库crate提供add_two函数
使用vs code 打开后,在Cargo.toml文件中:
[workspace]
members =[
"adder"
]
打开后然后使用cargo new adder 创建项目,cargo build
这个target就是存放所有成员的编译文件夹,我们进入adder的项目文件夹中,使用cargo build ,生成后的编译文件也会在顶层的target目录中,成员本身就不会再产生target的目录了,这样可以避免重复的编译,还可以让项目之间的依赖更好的协同
下面我们再创建一个项目add-one
[workspace]
members =[
"adder",
"add-one"
]
cargo new add-one --lib
然后再lib.rs中编写:
pub fn add_one(x: i32) -> i32 {
x + 1
}
在adder的main.rs:
use add_one;
fn main() {
let num = 10;
println!(
"Hello,world! {} plus one is {}!",
num,
add_one::add_one(num)
)
}
在adder的Cargo.toml:
[package]
name = "adder"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
add-one = {path="../add-one"}
我们通过cargo run -p adder 来指定运行adder的项目
在工作空间中依赖外部crate
工作空间只有一个Cargo.lock文件,在工作空间的顶层目录
一保证工作空间内所有crate 使用的依赖的版本都相同
——工作空间内所有crate 相互兼容
我们在add-one的Cargo.toml:
[package]
name = "add-one"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
rand="0.3.14"
在adder的Cargo.toml:
[package]
name = "adder"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
add-one = {path="../add-one"}
rand="0.3.15"
然后我们在cargo build一下:
我们Cargo.lock中就能够看到:
这两个项目依赖的rand版本是相同的
我们再cargo new add-two --lib 创建另一个项目
当然别忘了在顶层的Cargo.toml:
[workspace]
members =[
"adder",
"add-one",
"add-two"
]
然后我们可以在add-two项目中使用use rand ,在cargo build,然后发现就报错了。这是因为在其他的项目中依赖rand库,但是在add-two中没有使用。在工作空间中,不能够依赖其他项目里的依赖
为工作空间添加测试
在add-two中的lib.rs:
pub fn add_one(x: i32) -> i32 {
x + 1
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn it_works() {
assert_eq!(3,add_one(2));
}
}
然后通过cargo test 来执行测试,发现所有项目的测试都会执行,在当前的工作空间下
当然我们也可以指定想要测试的项目:cargo test -p add-one
要是我们想要把工作空间下的项目发布到creats.io这个网站上时,就必须一个一个的进行publish
6、安装二进制create
从CRATES.IO安装二进制crate
命令: cargo install
限制:只能安装具有二进制目标(binary target)的 crate
二进制目标 binary target:是一个可运行程序
一由拥有src/main.rs或其它被指定为二进制文件的crate 生成
通常:README里有关于crate 的描述:
―拥有library target
-拥有binary target
-两者都有
cargo install
cargo install安装的二进制存放在根目录的 bin文件夹
如果你用rustup安装的Rust,没有任何自定义配置,那么二进制存放目录是$HOME/.cargo/bin
―要确保该目录在环境变量$PATH中
我们之前有创建过自己的crete
现在我们来安装一下
cargo install haijin_loser
使用自定义命令扩展cargo
cargo被设计成可以使用子命令来扩展
例:如果$PATH中的某个二进制是cargo-something,你可以像子命令一样运行:
- cargo something
类似这样的自定义命令可以通过该命令列出: cargo --list
优点:可使用cargo install来安装扩展,像内置工具一样来运行