基本概念
Rust 语言在项目管理上整了一套自己的名词workspace
、package
、crate
、module
。特别是crate
,很多刚入门的人搞不清它们之间的关系。
如果用过 Visual Studio 开发过项目,那么就可以这么理解:
Visual Studio | Rust | 说明 |
---|---|---|
Solution | workspace | 管理多个项目 |
Project | package | 一个项目 |
crate | 可编译的单元 | |
namespace | module | 组织代码 |
区别从crate
这里开始,在 VS 中,一个Project
对应一个可编译的单元(exe、dll、lib),但是在 Rust 中多出了一个crate
的概念,它表示一个可编译的单元(exe、dll、lib、rlib),也就是说在 Rust 中一个项目可以编译出多个文件。
但是有个限制,每个项目(package)可以有多个可执行文件(exe)的crate
,但是最多只能有一个lib
类型的crate
,
项目的目录结构
不如直接看看各种可能的目录结构。
单个可执行文件
当我们从cargo new
命令创建项目(package)后,默认的目录结构是这样:
1 | Cargo.toml |
main.rs
就是入口文件,最终生成一个可执行文件。
单个库文件
当我们从cargo new --lib
命令创建项目(package)后,默认的目录结构是这样:
1 | Cargo.toml |
库文件默认是.rlib
格式,是 Rust 特有的格式,第三方包就是用这种格式。也可以改为静态库.lib
或动态库.dll
。
一个可执行文件和一个库文件
1 | Cargo.toml |
这样最终会编译出一个.exe
文件和一个.rlib
文件。
多个可执行文件
Rust 规定,在src/bin
这个目录下的每个文件都是一个可编译的可执行文件。
1 | Cargo.toml |
这样在编译后会生成出:
1 | target/ |
第一个app1.exe
就是顶层main.rs
编译出的文件,默认用包名命名。
如果在src/bin
目录下用一个和包名同名的文件会如何呢?会编译失败:
1 | Caused by: |
多个库文件
在一个项目(package)中能编译多个库吗?不行,Rust 只会将lib.rs
文件作为库编译,没有像src/bin
这种特殊的约定。
workspace
上面提到,一个项目最多只能有一个库文件,但在实际中,一个项目肯定有很多库文件,那么就不能用一个package
来管理项目了,需要使用workspace
的概念。
就是新建一个根目录加一个Cargo.toml
文件即可:
1 | workspace/ |
这样就创建了两个可执行文件,两个库。根目录下创建Cargo.toml
文件,内容如下
1 | [workspace] |
现在所有项目都会在根目录下生成二进制文件,
总结
package
就是项目
的概念,可以包含多个可编译的单元(crate)。其中可执行文件可以有任意多个,入口main.rs
文件和src/bin
目录下的所有文件。但库类型的编译只允许有一个,入口文件是lib.rs
。- 项目中如果需要多个库文件时,则要引入
workspace
的概念,对应 Visual Studio 中的解决方案。
相关阅读
工作空间 Workspace
What are packages, crates and modules?
Rust包和模块系统