Как получить метаданные Cargo пакета (версию, имя, описание) в программе на Rust?
Использование встроенных макросов env!() и option_env!()
Самый простой и рекомендуемый способ — использовать макросы env!("CARGO_PKG_VERSION") и option_env!("CARGO_PKG_NAME"). Cargo автоматически устанавливает эти переменные окружения во время компиляции. Вот как это работает:
fn main() {
// Обязательные поля (паника, если переменная не установлена)
let version = env!("CARGO_PKG_VERSION");
let name = env!("CARGO_PKG_NAME");
// Необязательные поля (возвращают Option<&str>)
let description = option_env!("CARGO_PKG_DESCRIPTION").unwrap_or("No description");
let authors = option_env!("CARGO_PKG_AUTHORS").unwrap_or("Unknown");
println!("{} v{}", name, version);
println!("Description: {}", description);
println!("Authors: {}", authors);
}
Полный список доступных переменных окружения Cargo:
CARGO_PKG_NAME— имя пакетаCARGO_PKG_VERSION— полная версия (например, "0.2.1")CARGO_PKG_VERSION_MAJOR— мажорная версия ("0")CARGO_PKG_VERSION_MINOR— минорная версия ("2")CARGO_PKG_VERSION_PATCH— патч-версия ("1")CARGO_PKG_VERSION_PRE— pre-release тег (если есть)CARGO_PKG_AUTHORS— авторы через запятуюCARGO_PKG_DESCRIPTION— описание из Cargo.tomlCARGO_PKG_HOMEPAGE— URL домашней страницыCARGO_PKG_REPOSITORY— URL репозиторияCARGO_PKG_LICENSE— лицензияCARGO_PKG_LICENSE_FILE— путь к файлу лицензииCARGO_PKG_RUST_VERSION— минимальная версия RustCARGO_PKG_README— путь к README файлуCARGO_CRATE_NAME— имя крейта (может отличаться от имени пакета)CARGO_MANIFEST_DIR— путь к директории с Cargo.toml
Получение хэша коммита Git
Для получения хэша коммита Git нужно использовать build.rs скрипт сборки. Создайте файл build.rs в корне вашего проекта:
use std::process::Command;
use std::env;
fn main() {
// Получаем хэш текущего коммита
let output = Command::new("git")
.args(&["rev-parse", "--short", "HEAD"])
.output();
if let Ok(output) = output {
let git_hash = String::from_utf8_lossy(&output.stdout);
let git_hash = git_hash.trim();
println!("cargo:rustc-env=GIT_HASH={}", git_hash);
}
// Также можно получить дату коммита
let output = Command::new("git")
.args(&["log", "-1", "--format=%cd", "--date=short"])
.output();
if let Ok(output) = output {
let git_date = String::from_utf8_lossy(&output.stdout);
let git_date = git_date.trim();
println!("cargo:rustc-env=GIT_DATE={}", git_date);
}
}
Теперь в основном коде:
fn main() {
let version = env!("CARGO_PKG_VERSION");
let git_hash = option_env!("GIT_HASH").unwrap_or("unknown");
let git_date = option_env!("GIT_DATE").unwrap_or("unknown");
println!("MyApp v{} ({} {})", version, git_hash, git_date);
}
Использование крейта built
Если вам нужно больше метаданных (например, время сборки, флаги компилятора, зависимости), рекомендую крейт built. Добавьте в Cargo.toml:
[build-dependencies]
built = "0.7"
В build.rs:
fn main() {
built::write_built_file().expect("Failed to acquire build-time information");
}
В основном коде:
include!(concat!(env!("OUT_DIR"), "/built.rs"));
fn main() {
println!("Version: {}", built::PKG_VERSION);
println!("Git commit: {}", built::GIT_COMMIT_HASH.unwrap_or("unknown"));
println!("Build time: {}", built::BUILT_TIME_UTC);
println!("Rustc version: {}", built::RUSTC_VERSION);
}
<<Использование крейта vergen для расширенной генерации метаданных
Альтернативный подход — крейт vergen, который генерирует ещё больше информации, включая информацию о Git, CI/CD, версии Rust и т.д. Вот как его использовать:
Добавьте в Cargo.toml:
[build-dependencies]
vergen = { version = "8", features = ["build", "git", "rustc"] }
В build.rs:
use vergen::EmitBuilder;
fn main() {
EmitBuilder::builder()
.all_build()
.all_git()
.all_rustc()
.emit()
.unwrap();
}
В основном коде:
fn main() {
println!("Version: {}", env!("VERGEN_BUILD_SEMVER"));
println!("Git SHA: {}", env!("VERGEN_GIT_SHA"));
println!("Git branch: {}", env!("VERGEN_GIT_BRANCH"));
println!("Build timestamp: {}", env!("VERGEN_BUILD_TIMESTAMP"));
println!("Rustc: {}", env!("VERGEN_RUSTC_SEMVER"));
}
Преимущества перед built:
- Больше готовых переменных окружения (включая информацию о CI)
- Автоматическое определение, является ли сборка "грязной" (есть незакоммиченные изменения)
- Поддержка Git-тегов
Недостаток: крейт тяжелее и может замедлить сборку, если не настроить выборочную генерацию.
Выбирайте подход в зависимости от ваших потребностей: для простого вывода версии достаточно встроенных макросов, для продвинутой информации используйте built или vergen.
Ответов пока нет.
Войдите чтобы оставить ответ