• 基于语义化版本的项目版本声明与管理
  • cargo的toml描述文件配置字段详细参考

基于语义化版本的项目版本声明与管理

我们在使用toml描述文件对项目进行配置时,经常会遇到项目版本声明及管理的问题,比如:

这里package段落中的version字段的值,以及dependencies段落中的libc字段的值,这些值的写法,都涉及到语义化版本控制的问题。语义化版本控制是用一组简单的规则及条件来约束版本号的配置和增长。这些规则是根据(但不局限于)已经被各种封闭、开放源码软件所广泛使用的惯例所设计。简单来说,语义化版本控制遵循下面这些规则:

  • 版本格式:主版本号.次版本号.修订号,版本号递增规则如下:
  1. 主版本号:当你做了不兼容的 API 修改,
  2. 次版本号:当你做了向下兼容的功能性新增,
  3. 修订号:当你做了向下兼容的问题修正。
  • 先行版本号及版本编译信息可以加到“主版本号.次版本号.修订号”的后面,作为延伸。

关于语义化版本控制的具体细节问题,大家可以参考这里,我不再赘述。

cargo的toml描述文件配置字段详细参考

啥也不多说了,直接上例子,大家注意我在例子中的中文解释,个人觉得这样比较一目了然:

  1. # 软件包名称,如果需要在别的地方引用此软件包,请用此名称。
  2. name = "hello_world"
  3. # 当前版本号,这里遵循semver标准,也就是语义化版本控制标准。
  4. version = "0.1.0" # the current version, obeying semver
  5. # 软件所有作者列表
  6. authors = ["you@example.com"]
  7. # 非常有用的一个字段,如果要自定义自己的构建工作流,
  8. # 尤其是要调用外部工具来构建其他本地语言(C、C++、D等)开发的软件包时。
  9. # 这时,自定义的构建流程可以使用rust语言,写在"build.rs"文件中。
  10. build = "build.rs"
  11. # 显式声明软件包文件夹内哪些文件被排除在项目的构建流程之外,
  12. # 哪些文件包含在项目的构建流程中
  13. exclude = ["build/**/*.o", "doc/**/*.html"]
  14. include = ["src/**/*", "Cargo.toml"]
  15. # 当软件包在向公共仓库发布时出现错误时,使能此字段可以阻止此错误。
  16. publish = false
  17. # 关于软件包的一个简短介绍。
  18. description = "..."
  19. # 下面这些字段标明了软件包仓库的更多信息
  20. documentation = "..."
  21. homepage = "..."
  22. repository = "..."
  23. # 顾名思义,此字段指向的文件就是传说中的ReadMe,
  24. # 并且,此文件的内容最终会保存在注册表数据库中。
  25. readme = "..."
  26. # 用于分类和检索的关键词。
  27. keywords = ["...", "..."]
  28. # 软件包的许可证,必须是cargo仓库已列出的已知的标准许可证。
  29. license = "..."
  30. # 软件包的非标许可证书对应的文件路径。
  31. license-file = "..."

依赖的详细配置

  1. hammer = "0.5.0"
  2. color = "> 0.6.0, < 0.8.0"

与平台相关的依赖定义格式不变,不同的是需要定义在[target]字段下。例如:

cargo内置五种编译器调用模板,分别为dev、release、test、bench、doc,分别用于定义不同类型生成目标时的编译器参数,如果我们自己想改变这些编译模板,可以自己定义相应字段的值,例如(注意:下述例子中列出的值均为此模板字段对应的系统默认值):

  1. # 开发模板, 对应`cargo build`命令
  2. [profile.dev]
  3. opt-level = 0 # 控制编译器的 --opt-level 参数,也就是优化参数
  4. debug = true # 控制编译器是否开启 `-g` 参数
  5. lto = false # 控制`-C lto` 参数,此参数影响可执行文件和静态库的生成,
  6. debug-assertions = true # 控制调试断言是否开启
  7. codegen-units = 1 # 控制编译器的 `-C codegen-units` 参数。注意,当`lto = true`时,此字段值被忽略
  8. # 发布模板, 对应`cargo build --release`命令
  9. [profile.release]
  10. opt-level = 3
  11. debug = false
  12. rpath = false
  13. lto = false
  14. debug-assertions = false
  15. codegen-units = 1
  16. # 测试模板,对应`cargo test`命令
  17. [profile.test]
  18. opt-level = 0
  19. debug = true
  20. rpath = false
  21. lto = false
  22. debug-assertions = true
  23. codegen-units = 1
  24. # 性能评估模板,对应`cargo bench`命令
  25. [profile.bench]
  26. opt-level = 3
  27. debug = false
  28. rpath = false
  29. lto = false
  30. debug-assertions = false
  31. codegen-units = 1
  32. # 文档模板,对应`cargo doc`命令
  33. [profile.doc]
  34. opt-level = 0
  35. debug = true
  36. rpath = false
  37. lto = false
  38. debug-assertions = true
  39. codegen-units = 1

需要注意的是,当调用编译器时,只有位于调用最顶层的软件包的模板文件有效,其他的子软件包或者依赖软件包的模板定义将被顶层软件包的模板覆盖。

[features]段落

[features]段落中的字段被用于条件编译选项或者是可选依赖。例如:

  1. [package]
  2. name = "awesome"
  3. [features]
  4. # 此字段设置了可选依赖的默认选择列表,
  5. # 注意这里的"session"并非一个软件包名称,
  6. # 而是另一个featrue字段session
  7. default = ["jquery", "uglifier", "session"]
  8. # 类似这样的值为空的feature一般用于条件编译,
  9. # 此feature依赖于bcrypt软件包,
  10. # 这样封装的好处是未来可以对secure-password此feature增加可选项目。
  11. secure-password = ["bcrypt"]
  12. # 此处的session字段导入了cookie软件包中的feature段落中的session字段
  13. session = ["cookie/session"]
  14. [dependencies]
  15. # 必要的依赖
  16. cookie = "1.2.0"
  17. oauth = "1.1.0"
  18. route-recognizer = "=2.1.0"
  19. # 可选依赖
  20. jquery = { version = "1.0.2", optional = true }
  21. uglifier = { version = "1.5.3", optional = true }
  22. bcrypt = { version = "*", optional = true }
  23. civet = { version = "*", optional = true }

使用features时需要遵循以下规则:

  • feature名称在本描述文件中不能与出现的软件包名称冲突
  • 除了default feature,其他所有的features均是可选的
  • features不能相互循环包含
  • 开发依赖包不能包含在内
  • features组只能依赖于可选软件包

features的一个重要用途就是,当开发者需要对软件包进行最终的发布时,在进行构建时可以声明暴露给终端用户的features,这可以通过下述命令实现:

  1. $ cargo build --release --features "shumway pdf"

当运行cargo test命令时,cargo将会按做以下事情:

  • 编译并运行软件包源代码中被#[cfg(test)] 所标志的单元测试
  • 编译并运行文档测试
  • 编译并运行集成测试
  • 编译examples

配置构建目标

所有的诸如[[bin]], [lib], [[bench]], [[test]]以及 [[example]]等字段,均提供了类似的配置,以说明构建目标应该怎样被构建。例如(下述例子中[lib]段落中各字段值均为默认值):

  1. [lib]
  2. # 库名称,默认与项目名称相同
  3. name = "foo"
  4. # 此选项仅用于[lib]段落,其决定构建目标的构建方式,
  5. # 可以取dylib, rlib, staticlib 三种值之一,表示生成动态库、r库或者静态库。
  6. crate-type = ["dylib"]
  7. # path字段声明了此构建目标相对于cargo.toml文件的相对路径
  8. path = "src/lib.rs"
  9. # 单元测试开关选项
  10. test = true
  11. # 文档测试开关选项
  12. doctest = true
  13. # 性能评估开关选项
  14. bench = true
  15. # 文档生成开关选项
  16. doc = true
  17. # 是否构建为编译器插件的开关选项
  18. plugin = false
  19. # 如果设置为false,`cargo test`将会忽略传递给rustc的--test参数。
  20. harness = true