Rust Cargo 使用总结

文档列表见:Rust 移动端跨平台复杂图形渲染项目开发系列总结(目录)html

2019.4.24 更新:多条件(feature)编译前端

Cargo用于组织Rust项目,比直接用rustc编译多个源文件更方便。本文档介绍咱们开发过程当中用到的Cargo功能与小技巧,更多信息可参考 The Cargo Bookgit

使用依赖项目的指定git commit

rev表示要用的git commit id,可简写成前7个字符,由于git commit id前7个字符可算出完整的41个SHA字符值。github

[dependencies]
gfx-hal = { version = "0.1.0", git = "https://github.com/gfx-rs/gfx", rev = "bd7f058" }
# 或者写成多行
[dependencies.gfx-hal]
git = "https://github.com/gfx-rs/gfx"
version = "0.1.0" 
rev = "bd7f058"
复制代码

git仓库地址须要支持https访问,若是是http须要额外配置,比较麻烦。api

引用本地Rust项目

[dependencies]
hello_utils = { path = "hello_utils", version = "0.1.0" }
复制代码

path是相对于本项目Cargo.toml文件的被依赖项目的Cargo.toml的位置,填错将找不到文件,且编译报错。详细信息参考The Cargo Book/specifying-dependencies缓存

workspace feature 条件编译的执行路径问题

当cargo workspace中存在多个project时,若是对某一project进行feature条件编译或单元测试,必定要在此项目的Cargo.toml或src路径中执行,不然Cargo会忽悠cargo testcargo build --features=your_feature所指定的feature,这是个容易遇的坑。性能优化

default feature 条件编译

[features]
default = ["gfx-backend-metal"]
复制代码

写在Cargo.toml的default = ["a", "b", "c"]cargo build是默认启用的,即不用加上--features条件。bash

多条件(feature)编译

语法:--features "条件1 条件2 条件3",每一个feature(条件)中间留出空格,示例:ide

cargo build --features "metal gl" --bin quad 表示启用metalgl两个条件编译去编译quad可执行程序。工具

cargo c 减小编译耗时

  • 使用cargo check,命令可缩写为cargo c若是只是想验证语法、类型检查等,那么能够直接使用这个命令,它只会调用编译器前端。比cargo build快2倍,比cargo build -—release快6倍。
  • 使用sccache,该工具是Mozilla出品的Rust兼容的编译缓存服务,通常能够得到2倍速度提高。使用cargo install sccache安装sccache,而且在.bashrc中添加环境变量export RUSTC_WRAPPER=sccache
  • 避免LTO。 LTO是连接时优化的缩写。LTO将付出更高的编译时间代价。
  • 控制crate依赖。

如何缓解Rust编译时间长的痛苦

编译优化级别说明

opt level 3和z,哪一个性能优化更高?答案:3。 z无论性能,z和s差很少,O2的优化,减小size。

另外一种说法:在不一样平台上会获得不一样结果,-z为size优化,对于cpu code cache小的机器优点比较大,大概就是优化等级开高了代码尺寸变大会致使在某些cache小的机器上性能降低的很厉害。z在inline的优化确定要少一些。优化这东西是个神坑,不要跳。建议在你的手机上进行profiling。

opt level 参数完整说明见 Properly document and explain opt-levels s and z

[profile.release] debug=true 的讨论

这样改会影响release的性能吗? 好像只是留下符号信息。编译出来大点吧。性能应该不会有啥影响。你能够试试 提及来release带符号 会不会致使行号不许啊

To get the best data from a profiler, you need both optimizations (usually enabled only in release builds) and debug symbols (usually enabled only in debug builds). To enable both, add this to your Cargo.toml: Programming Rust

尝试:

debug = false --release image-20190225103810132

debug = true --release image-20190225104833677

hal api基本没改善,多是由于多数被inline或zero cost abstraction?

workspace 与其子 project 同时指定 [profile] 配置会引发冲突

package: /Users/michael/Documents/my_project/gles/Cargo.toml workspace: /Users/michael/Documents/my_project/Cargo.toml 同时指定

# The release profile, used for `cargo build --release`
[profile.release]
panic = "abort"
debug = true # `true` for better profiler readability with debug symbols, `false` for sdk client
lto = true
opt-level = 3
overflow-checks = false
复制代码

warning: profiles for the non root package will be ignored, specify profiles at the workspace root:

测试Rust代码中的Markdown代码段

/// Open the physical device with `count` queues from some active queue family. The family is
/// the first that both provides the capability `C`, supports at least `count` queues, and for
/// which `selector` returns true.
///
/// # Examples
///
/// ```no_run
/// # extern crate gfx_backend_empty as empty;
/// # extern crate gfx_hal as hal;
/// use hal::General;
/// # fn main() {
///
/// # let mut adapter: hal::Adapter<empty::Backend> = return;
/// let (device, queues) = adapter.open_with::<_, General>(1, |_| true).unwrap();
/// # }
/// ```
///
/// # Return
///
/// Returns the same errors as `open` and `InitializationFailed` if no suitable
/// queue family could be found.
pub fn open_with<F, C>(
    &self,
    count: usize,
    selector: F,
) -> Result<(B::Device, QueueGroup<B, C>), DeviceCreationError>
where
    F: Fn(&B::QueueFamily) -> bool,
    C: Capability,
{
    // ...
}
复制代码

注释中的Examples代码能够用rust-skeptic进行测试,具体作法可阅读rust-skeptic文档。

相关文章
相关标签/搜索