Rust Cargo使用總結

熊皮皮發表於2018-11-25

文件列表見:Rust 移動端跨平臺複雜圖形渲染專案開發系列總結(目錄)

2018.12.23 更新cargo workspace feature編譯的命令執行路徑問題

Cargo用於組織Rust專案,比直接用rustc編譯多個原始檔更方便。本文件介紹我們開發過程中用到的Cargo功能與小技巧。完整資訊可閱讀The Cargo Book

Cargo使用依賴專案的指定git commit

rev表示要使用的commit id,可簡寫成前7個字元,因為git commit id前7個字元可算出完整的41個字元值。

[dependencies]
gfx-hal = { version = "0.1.0", git = "https://github.com/gfx-rs/gfx", rev = "bd7f058efe78d7626a1cc6fbc0c1d3702fb6d2e7" }
// 或者寫成多行
[dependencies.gfx-hal]
git = "https://github.com/gfx-rs/gfx"
version = "0.1.0" 
rev = "bd7f058efe78d7626a1cc6fbc0c1d3702fb6d2e7"
複製程式碼

git倉庫地址需要支援https訪問,如果是http需要額外配置,比較麻煩。

引用本地Rust專案

[dependencies]
hello_utils = { path = "hello_utils", version = "0.1.0" }
複製程式碼

path是相對於本專案Cargo.toml檔案的被依賴專案的Cargo.toml的位置,填錯將找不到檔案,且編譯報錯。詳細資訊參考The Cargo Book/specifying-dependencies

測試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,
    {
        use queue::QueueFamily;

        let requested_family = self
            .queue_families
            .iter()
            .filter(|family| {
                C::supported_by(family.queue_type())
                    && selector(&family)
                    && count <= family.max_queues()
            })
            .next();

        let priorities = vec![1.0; count];
        let (id, families) = match requested_family {
            Some(family) => (family.id(), [(family, priorities.as_slice())]),
            _ => return Err(DeviceCreationError::InitializationFailed),
        };

        let Gpu { device, mut queues } = self.physical_device.open(&families)?;
        Ok((device, queues.take(id).unwrap()))
    }
複製程式碼

前面Examples程式碼可以用rust-skeptic進行測試,具體做法可閱讀rust-skeptic文件。

cargo workspace feature編譯路徑問題

對於cargo workspace下有多個project的情況,如果對其中一個project進行feature編譯執行或做單元測試,一定要在此專案的Cargo.toml或src內執行,否則Cargo會忽悠cargo test或cargo build --features=your_feature所指定的feature,這是個很小卻容易踩中的坑。

相關文章