我們?cè)谑褂胻oml描述文件對(duì)項(xiàng)目進(jìn)行配置時(shí),經(jīng)常會(huì)遇到項(xiàng)目版本聲明及管理的問(wèn)題,比如:
[package]
name = "libevent_sys"
version = "0.1.0"
[dependencies]
libc = "0.2"
這里package段落中的version字段的值,以及dependencies段落中的libc字段的值,這些值的寫(xiě)法,都涉及到語(yǔ)義化版本控制的問(wèn)題。語(yǔ)義化版本控制是用一組簡(jiǎn)單的規(guī)則及條件來(lái)約束版本號(hào)的配置和增長(zhǎng)。這些規(guī)則是根據(jù)(但不局限于)已經(jīng)被各種封閉、開(kāi)放源碼軟件所廣泛使用的慣例所設(shè)計(jì)。簡(jiǎn)單來(lái)說(shuō),語(yǔ)義化版本控制遵循下面這些規(guī)則:
關(guān)于語(yǔ)義化版本控制的具體細(xì)節(jié)問(wèn)題,大家可以參考這里,我不再贅述。
啥也不多說(shuō)了,直接上例子,大家注意我在例子中的中文解釋,個(gè)人覺(jué)得這樣比較一目了然:
[package]
# 軟件包名稱,如果需要在別的地方引用此軟件包,請(qǐng)用此名稱。
name = "hello_world"
# 當(dāng)前版本號(hào),這里遵循semver標(biāo)準(zhǔn),也就是語(yǔ)義化版本控制標(biāo)準(zhǔn)。
version = "0.1.0" # the current version, obeying semver
# 軟件所有作者列表
authors = ["you@example.com"]
# 非常有用的一個(gè)字段,如果要自定義自己的構(gòu)建工作流,
# 尤其是要調(diào)用外部工具來(lái)構(gòu)建其他本地語(yǔ)言(C、C++、D等)開(kāi)發(fā)的軟件包時(shí)。
# 這時(shí),自定義的構(gòu)建流程可以使用rust語(yǔ)言,寫(xiě)在"build.rs"文件中。
build = "build.rs"
# 顯式聲明軟件包文件夾內(nèi)哪些文件被排除在項(xiàng)目的構(gòu)建流程之外,
# 哪些文件包含在項(xiàng)目的構(gòu)建流程中
exclude = ["build/**/*.o", "doc/**/*.html"]
include = ["src/**/*", "Cargo.toml"]
# 當(dāng)軟件包在向公共倉(cāng)庫(kù)發(fā)布時(shí)出現(xiàn)錯(cuò)誤時(shí),使能此字段可以阻止此錯(cuò)誤。
publish = false
# 關(guān)于軟件包的一個(gè)簡(jiǎn)短介紹。
description = "..."
# 下面這些字段標(biāo)明了軟件包倉(cāng)庫(kù)的更多信息
documentation = "..."
homepage = "..."
repository = "..."
# 顧名思義,此字段指向的文件就是傳說(shuō)中的ReadMe,
# 并且,此文件的內(nèi)容最終會(huì)保存在注冊(cè)表數(shù)據(jù)庫(kù)中。
readme = "..."
# 用于分類(lèi)和檢索的關(guān)鍵詞。
keywords = ["...", "..."]
# 軟件包的許可證,必須是cargo倉(cāng)庫(kù)已列出的已知的標(biāo)準(zhǔn)許可證。
license = "..."
# 軟件包的非標(biāo)許可證書(shū)對(duì)應(yīng)的文件路徑。
license-file = "..."
最直接的方式在之前第五章探討過(guò),這里不在贅述,例如這樣:
[dependencies]
hammer = "0.5.0"
color = "> 0.6.0, < 0.8.0"
與平臺(tái)相關(guān)的依賴定義格式不變,不同的是需要定義在[target]字段下。例如:
# 注意,此處的cfg可以使用not、any、all等操作符任意組合鍵值對(duì)。
# 并且此用法僅支持cargo 0.9.0(rust 1.8.0)以上版本。
# 如果是windows平臺(tái),則需要此依賴。
[target.'cfg(windows)'.dependencies]
winhttp = "0.4.0"
[target.'cfg(unix)'.dependencies]
openssl = "1.0.1"
#如果是32位平臺(tái),則需要此依賴。
[target.'cfg(target_pointer_width = "32")'.dependencies]
native = { path = "native/i686" }
[target.'cfg(target_pointer_width = "64")'.dependencies]
native = { path = "native/i686" }
# 另一種寫(xiě)法就是列出平臺(tái)的全稱描述
[target.x86_64-pc-windows-gnu.dependencies]
winhttp = "0.4.0"
[target.i686-unknown-linux-gnu.dependencies]
openssl = "1.0.1"
# 如果使用自定義平臺(tái),請(qǐng)將自定義平臺(tái)文件的完整路徑用雙引號(hào)包含
[target."x86_64/windows.json".dependencies]
winhttp = "0.4.0"
[target."i686/linux.json".dependencies]
openssl = "1.0.1"
native = { path = "native/i686" }
openssl = "1.0.1"
native = { path = "native/x86_64" }
# [dev-dependencies]段落的格式等同于[dependencies]段落,
# 不同之處在于,[dependencies]段落聲明的依賴用于構(gòu)建軟件包,
# 而[dev-dependencies]段落聲明的依賴僅用于構(gòu)建測(cè)試和性能評(píng)估。
# 此外,[dev-dependencies]段落聲明的依賴不會(huì)傳遞給其他依賴本軟件包的項(xiàng)目
[dev-dependencies]
iron = "0.2"
cargo內(nèi)置五種編譯器調(diào)用模板,分別為dev、release、test、bench、doc,分別用于定義不同類(lèi)型生成目標(biāo)時(shí)的編譯器參數(shù),如果我們自己想改變這些編譯模板,可以自己定義相應(yīng)字段的值,例如(注意:下述例子中列出的值均為此模板字段對(duì)應(yīng)的系統(tǒng)默認(rèn)值):
# 開(kāi)發(fā)模板, 對(duì)應(yīng)`cargo build`命令
[profile.dev]
opt-level = 0 # 控制編譯器的 --opt-level 參數(shù),也就是優(yōu)化參數(shù)
debug = true # 控制編譯器是否開(kāi)啟 `-g` 參數(shù)
rpath = false # 控制編譯器的 `-C rpath` 參數(shù)
lto = false # 控制`-C lto` 參數(shù),此參數(shù)影響可執(zhí)行文件和靜態(tài)庫(kù)的生成,
debug-assertions = true # 控制調(diào)試斷言是否開(kāi)啟
codegen-units = 1 # 控制編譯器的 `-C codegen-units` 參數(shù)。注意,當(dāng)`lto = true`時(shí),此字段值被忽略
# 發(fā)布模板, 對(duì)應(yīng)`cargo build --release`命令
[profile.release]
opt-level = 3
debug = false
rpath = false
lto = false
debug-assertions = false
codegen-units = 1
# 測(cè)試模板,對(duì)應(yīng)`cargo test`命令
[profile.test]
opt-level = 0
debug = true
rpath = false
lto = false
debug-assertions = true
codegen-units = 1
# 性能評(píng)估模板,對(duì)應(yīng)`cargo bench`命令
[profile.bench]
opt-level = 3
debug = false
rpath = false
lto = false
debug-assertions = false
codegen-units = 1
# 文檔模板,對(duì)應(yīng)`cargo doc`命令
[profile.doc]
opt-level = 0
debug = true
rpath = false
lto = false
debug-assertions = true
codegen-units = 1
需要注意的是,當(dāng)調(diào)用編譯器時(shí),只有位于調(diào)用最頂層的軟件包的模板文件有效,其他的子軟件包或者依賴軟件包的模板定義將被頂層軟件包的模板覆蓋。
[features]段落中的字段被用于條件編譯選項(xiàng)或者是可選依賴。例如:
[package]
name = "awesome"
[features]
# 此字段設(shè)置了可選依賴的默認(rèn)選擇列表,
# 注意這里的"session"并非一個(gè)軟件包名稱,
# 而是另一個(gè)featrue字段session
default = ["jquery", "uglifier", "session"]
# 類(lèi)似這樣的值為空的feature一般用于條件編譯,
# 類(lèi)似于`#[cfg(feature = "go-faster")]`。
go-faster = []
# 此feature依賴于bcrypt軟件包,
# 這樣封裝的好處是未來(lái)可以對(duì)secure-password此feature增加可選項(xiàng)目。
secure-password = ["bcrypt"]
# 此處的session字段導(dǎo)入了cookie軟件包中的feature段落中的session字段
session = ["cookie/session"]
[dependencies]
# 必要的依賴
cookie = "1.2.0"
oauth = "1.1.0"
route-recognizer = "=2.1.0"
# 可選依賴
jquery = { version = "1.0.2", optional = true }
uglifier = { version = "1.5.3", optional = true }
bcrypt = { version = "*", optional = true }
civet = { version = "*", optional = true }
如果其他軟件包要依賴使用上述awesome軟件包,可以在其描述文件中這樣寫(xiě):
[dependencies.awesome]
version = "1.3.5"
default-features = false # 禁用awesome 的默認(rèn)features
features = ["secure-password", "civet"] # 使用此處列舉的各項(xiàng)features
使用features時(shí)需要遵循以下規(guī)則:
features的一個(gè)重要用途就是,當(dāng)開(kāi)發(fā)者需要對(duì)軟件包進(jìn)行最終的發(fā)布時(shí),在進(jìn)行構(gòu)建時(shí)可以聲明暴露給終端用戶的features,這可以通過(guò)下述命令實(shí)現(xiàn):
$ cargo build --release --features "shumway pdf"
當(dāng)運(yùn)行cargo test命令時(shí),cargo將會(huì)按做以下事情:
所有的諸如[[bin]], [lib], [[bench]], [[test]]以及 [[example]]等字段,均提供了類(lèi)似的配置,以說(shuō)明構(gòu)建目標(biāo)應(yīng)該怎樣被構(gòu)建。例如(下述例子中[lib]段落中各字段值均為默認(rèn)值):
[lib]
# 庫(kù)名稱,默認(rèn)與項(xiàng)目名稱相同
name = "foo"
# 此選項(xiàng)僅用于[lib]段落,其決定構(gòu)建目標(biāo)的構(gòu)建方式,
# 可以取dylib, rlib, staticlib 三種值之一,表示生成動(dòng)態(tài)庫(kù)、r庫(kù)或者靜態(tài)庫(kù)。
crate-type = ["dylib"]
# path字段聲明了此構(gòu)建目標(biāo)相對(duì)于cargo.toml文件的相對(duì)路徑
path = "src/lib.rs"
# 單元測(cè)試開(kāi)關(guān)選項(xiàng)
test = true
# 文檔測(cè)試開(kāi)關(guān)選項(xiàng)
doctest = true
# 性能評(píng)估開(kāi)關(guān)選項(xiàng)
bench = true
# 文檔生成開(kāi)關(guān)選項(xiàng)
doc = true
# 是否構(gòu)建為編譯器插件的開(kāi)關(guān)選項(xiàng)
plugin = false
# 如果設(shè)置為false,`cargo test`將會(huì)忽略傳遞給rustc的--test參數(shù)。
harness = true