Rust 之二 各组件工具的源码、构建、配置、使用(二)

概述

Rust 是一种预编译静态类型(ahead-of-time compiled)的编程语言,除了有基本的 Rust 编程语言标准之外,Rust 官方还提供了一系列适用于各个平台的开发辅助工具以及编译工具链来帮助我们处理 Rust 代码。

clippy

Clippy 是 Rust 官方开发的一个基于 LLVM 的 Rust 代码检测及优化工具(类似于 PC-lint 这类工具),它可以自动检测 Rust 代码中的潜在问题,并提供相应的建议。Clippy 使用 Lint 规则来检查代码,这些规则基于 Rust 的编译器插件系统。

使用

clippy 是一个命令行工具,对应的可执程序为 cargo-clippy,详细的使用方法参见下图。需要注意的是,clippy 是需要配合 cargo 来运行的(在当前目录下找不到 Cargo.toml 会报错),因此我们需要在 Rust 源码目录中执行 cargo-clippy 命令!

  1. 当我们使用时实际上是通过 .cargo/bin/cargo-clippy 这个代理来调用 .rustup/toolchains/发行版/bin/cargo-clippy 这个真正的可执行程序。

cargo clippy

通常,cargo-clippy 是作为 cargo 命令的一个子命令 cargo clippy 来间接使用。同样我们需要在 Rust 源码中执行 cargo clippy 命令!

clippy-driver

clippy 本身支持抛开 Cargo 来独立使用,此时需要使用 clippy-driver 命令来运行,其参数则需要与 rustc 的参数相同,例如 clippy-driver --edition 2018 -Cpanic=abort foo.rs

配置

默认情况下,cargo-clippy 会自动查找名为 clippy.toml.clippy.toml 的文件,搜索的位置优先级由高到低为 CLIPPY_CONF_DIRCARGO_MANIFEST_DIR、当前项目目录,并执行其中的规则。

  1. 除了配置文件中存放的部分 Lint 规则外,还可以直接在 cargo-clippy 的命令行中指定一些规则。

  2. 目前,Clippy 中包含了超过 700 条 lints,这些 lints 被划分为了多个类别,每个类别都对应一个默认的 lint level。在 rustc 中,Lint 被分为了 allow、warn、force-warn、deny、forbid 这 5 level。

  3. Cargo.toml 中的 [lints.clippy] 中也可以指定一些规则

  4. 在源代码中也可以使用特定的属性,例如 #![allow(clippy::all)] 来指定规则

源码

Clippy 的源码仓库为 https://github.com/rust-lang/rust-clippy,可以直接通过 git clone https://github.com/rust-lang/rust-clippy.git 获取。

  1. 源码根目录下的 book 目录是官方文档 Clippy Documentation 的源代码,使用的是 mdBook 文档系统,详细介绍参见后文的 mdBook 章节的介绍

构建

Clippy 源码本身就是一个 Rust 项目工程,因此,我们可以使用 cargo build 命令一键编译出名为 cargo-clippyclippy-driver 的可执行程序。

rustfmt

Rustfmt 是 Rust 官方提供的格式化 Rust 代码的工具(类似于 LLVM 的 clang-format 这类工具),它根据一些预定义的规则(括号的使用、缩进的级别、空格的添加等)来自动将 Rust 代码格式化为统一的风格。

使用

rustfmt 是一个命令行工具,对应的可执程序为 rustfmt,使用命令 rustfmt [options] <file>... 来对指定的源码文件来进行格式化。详细使用如下所示。

  1. 当我们使用时实际上是通过 .cargo/bin/rustfmt 这个代理来调用 .rustup/toolchains/发行版/bin/rustfmt 这个真正的可执行程序。

cargo fmt

通常 rustfmt 会被作为 cargo 命令的一个子命令 cargo fmt 来间接使用,完整格式是 cargo fmt [OPTIONS] [-- <rustfmt_options>...],其中的 [-- <rustfmt_options>...] 会直接传递给 rustfmt 来进行使用,因此它的取值就是 rustfmt 的选项。

cargo-fmt

此外,rustfmt 默认还会提供一个名为 cargo-fmt 的可执行程序,这个工具的作用于 cargo fmt 类似,不过它不依赖于 Cargo 这个工具进而实现类似的功能,因此,在不用 Cargo 时,我们可以直接使用 cargo-fmt 来一键格式化整个项目的源文件。

配置

在默认情况下,rustfmt 会自动读取当前项目各级目录下的 rustfmt.toml.rustfmt.toml 文件,并根据其中的规则来进行格式化配置文件所在的目录的代码。如果子目录下没有配置文件,但是它的父级目录有,则根据父级目录的配置文件格式化。

  1. 如果项目目录下不存在 rustfmt.toml.rustfmt.toml,则会尝试读取用户目录

  2. 如果用户目录下也没有,则读取 rustfmt 全局配置目录下的全局配置文件

  3. 配置文件中的各种规则直接查看源码中的 Configurations.md 或者使用在线 https://rust-lang.github.io/rustfmt/ 版本,两者是一样的!

源码

Rustfmt 的源码仓库为 https://github.com/rust-lang/rustfmt,可以直接使用 git clone https://github.com/rust-lang/rustfmt.git 来获取。

  1. 目前,Rustfmt 的文档就是源码里的 Configurations.md,源码目录的 docs 中的 index.thml 中就是通过 JavaScript 调用的 Configurations.md 的内容!直接在 docs 目录中使用 python -m http.server 可以在本地部署启动

  2. 在 Windows 平台上会由于大小写问题而报警告

构建

Rustfmt 的源码本身就是一个 Rust 项目工程,因此,我们可以使用 cargo build 命令一键编译出名为 cargo-fmtrustfmt 的可执行程序。

rust-analyzer

rust-analyzer 是 Rust 编程语言的语言服务器协议的实现。它为许多代码编辑器(VS Code、 Emacs 和 Vim)提供了代码完成、语法高亮和转到定义等特性。它也是一个命令行工具,不过,我们通常不会直接使用它,而是由代码编辑器插件来帮我们调用。

  1. 由于 rust-analyzer 通常不会由我们直接使用,所以,默认安装 Rust 后没有 rust-analyzer

  2. 实际上就是一个模块化编译器前端或者说一个动态分析库,通过 LSP(Language Server Protocol)与 VS Code、 Emacs 和 Vim 等通信

  3. rust-analyzer 依赖 Rust 标准库的源码,通常需要手动执行 rustup component add rust-src 来安装,安装后的位置为 .rustup\toolchains\toolchain_name\lib\rustlib\src\rust

  4. rust-analyzer 提供的功能都是通过调用其他 Rust 工具来实现的,例如,代码格式就会调用 rustfmt

源码

rust-analyzer 的源码仓库为 https://github.com/rust-lang/rust-analyzer,源码本身就是一个 Rust 项目工程,因此,我们可以使用 cargo build 命令一键编译出名为 rust-analyzerrust-analyzer-proc-macro-srv 的可执行程序。

文档

官方在线文档 。

  1. 官方在线文档
  2. 文档的源码位于 rust-analyzer 源码的 docs 目录下,,使用的是 mdBook 文档系统,详细介绍参见后文的 mdBook 章节的介绍

配置

配置项众多,参见 https://rust-analyzer.github.io/manual.html#configuration 即可。

mdBook

mdBook 是一个使用 Markdown 创建出在线文档网站的命令行工具。它是创建产品或 API 文档、教程、课程材料或任何需要简洁、易于导航和可定制的演示文稿的理想工具。Rust 提供的绝大多数文档都是使用 mdBook 来构建的!

安装

默认安装 Rust 后比不会安装 mdbook,我们需要使用 cargo install mdbook 手动进行安装,mdbook 可执行文件会被放到 .cargo/bin 目录中。也可以直接在 https://github.com/rust-lang/mdBook/releases 上下载预编译好的可执行文件来使用!或者直接从源码构建出可执行程序!

目录结构

使用 mdbook init xxx 命令就会创建出名为 xxx 的文档目录结构,自动生成如下所示的目录结构

  • book.toml 文件按是配置文件

  • 新增的 Markdown文章都要放到 src 目录下,可以自行创建子目录来进行分类存放

  • src/SUMMARY.md 是所有文章的目录,新增的 Markdown文章都需要在这里面写一下

  • book 文件夹用于存放 mdBook 构建后产生的 HTML 的文档

发布文档

在文档目录中,执行 mdbook build 就可以一键生成 HTML 格式的静态网页文档,默认存到当前目录的 book 文件夹中。在编写时,可以使用 mdbook serve 命令可以启动本地 Web 服务器,我们可以直接在浏览器中以 localhost 进行预览

源码

mdBook 的源码仓库为 https://github.com/rust-lang/mdBook,源码本身就是一个 Rust 项目工程,因此,我们可以使用 cargo build 命令一键编译出名为 mdbook 的可执行程序。

文档

  1. 官方在线文档
  2. 文档的源码位于 mdBook 源码的 guide 目录下,本身也是使用的 mdBook 文档系统。首先安装 cargo install mbook 或者自己构建后,在 doc\guide中执行 mbook build 或者在 mbook build 指定路径 就可以构建出上面的官方在线文档

rustdoc

rustdoc 是 Rust 官方提供的随附编译工具链发布的文档处理工具,这个工具主要是用来自动收集当前项目源码文件中的各种注释来生成对应文档 ,它接受一个 crate root 文件或者一个 Markdown 文件作为参数,然后生成 HTML,CSS 和 JavaScript 文件等称为一套以静态网页为主的文档。

rustdoc 是一个命令行工具,对应的可执程序为 rustdoc,使用命令 rustfmt [options] <input> 自动收集源码中的注释形成文档。当我们使用时实际上是通过 .cargo/bin/rustdoc 这个代理来调用 .rustup/toolchains/发行版/bin/rustdoc 这个真正的可执行程序。

  1. rustdoc 以 crate root 文件为入口自动遍历所以使用到的源码文件,不用我们手动指定所有源码文件。
  2. 默认的文档名字是 Crate 的名字,可以使用 --crate-name xxx 来进行更改
  3. 文档将存放到 target\doc 目录下,每个 Crate 一个子目录,他们之间会互相引用

cargo doc

通常 rustdoc 会被作为 cargo 命令的一个子命令 cargo doc 来间接使用,完整格式是 cargo doc [OPTIONS]。这个命令需要在我们的 Package 目录下执行,Cargo 将自动查找所有源代码文件(包括我们依赖的 Crate 的源码文件)。

  1. 使用 cargo doc --verbose 可以看到调用 rustdoc 的详细参数

  2. cargo doc 目前不支持独立的 Markdown 文件

  3. cargo doc 命令不止处理我们自己的源码文件,还会处理依赖的 Crate 的源码文件,进而形成一整套的文档。运行 cargo doc --open 命令来构建所有本地依赖项提供的文档,并在浏览器中打开,这样就方便了我们查找需要的接口

源码

rustdoc 稍微有点特殊,它是作为 Rust 的编译工具链中的一个标准组件来发布的。因此,它没有一个单独的源码仓库,而是在 Rust 编译工具链的仓库 https://github.com/rust-lang/rust 中的一个部分

文档

  • 官方文档 The rustdoc book

  • 文档的源码位于 Rust 源码的 src\doc\rustdoc 目录下,可以使用命令 x.py doc src/doc/rustdoc 来构建,使用的是 mdBook 文档系统,详细介绍参见后文的 mdBook 章节的介绍

文档注释

rustdoc 会提取源码文件中特定格式的注释(官方称为文档注释)来生成文档,rustdoc 规定了用于生成的文档的注释必须以 /// 或者 //! 开头,并且注释的内容主要使用 Markdown 语法来进行编写。

  1. /// 用于放在函数、结构体、变量等代码前面以对代码进行注释,称为 outer documentation,示例如下:
  2. //! 用于放到一个源码文件的开头给一个源码文件注释,称为 inner documentation。示例如下:
    1. 当它位于 root crate 文件时,那么它就是文档主页的注释
    2. 其最后面需要加一个空行
  3. 可以在自己的 src/lib.rsmain.rs 的开头添加 #![warn(missing_docs)],而如果是一个要共享的库则可添加 #![deny(missing_docs)]
  4. 使用 #[doc(hidden)] 可以屏蔽将之后的内容提取到文档中

参考

  1. https://aws.github.io/aws-lc-rs/requirements/windows.html
  2. https://blog.csdn.net/fj_Author/article/details/132594546
  3. https://www.andy-pearce.com/blog/posts/2023/May/uncovering-rust-build-and-packaging/
  4. https://aws.github.io/aws-lc-rs/requirements/index.html
相关推荐
ULTRA??2 小时前
Rust的移动语义
c++·算法·rust
沐知全栈开发2 小时前
SQLite Limit 子句详解
开发语言
资深web全栈开发2 小时前
Go语言从1.18到1.25版本功能更新详解
开发语言·后端·golang
YouEmbedded2 小时前
函数模板与类模板——泛型编程
开发语言·c++·函数模板·类模板
听风吟丶2 小时前
微服务性能压测与容量规划实战:从高并发稳定性到精准资源配置
java·开发语言
小此方2 小时前
Re:从零开始学C++(一)基础精讲·上篇:命名空间、输入输出、缺省参数、函数重载
开发语言·c++
行云流水20003 小时前
编程竞赛语言选择:为什么优先学C++?聚焦竞赛属性的语法突破
开发语言·c++
aini_lovee3 小时前
基于边缘图像分割算法详解与MATLAB实现
开发语言·算法·matlab
艾上编程3 小时前
第一章——办公自动化之Excel批量合并工具:Python助力高效办公
开发语言·python·excel