Rust的发布配置

我爱海鲸 2024-03-05 17:44:12 rust学习

简介cargo、库、

在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

来源: https://crates.io

限制:只能安装具有二进制目标(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来安装扩展,像内置工具一样来运行

你好:我的2025

上一篇:Rust的迭代器

下一篇:Rust的智能指针