# Best way to implement \`--version\` option?

**URL:** <https://users.rust-lang.org/t/best-way-to-implement-version-option/116227>\
**Category:** help\
**Created:** [August 19, 2024, 8:12pm UTC](https://users.rust-lang.org/t/best-way-to-implement-version-option/116227 "2024-08-19T20:12:23Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![ike](https://avatars.discourse-cdn.com/v4/letter/i/df705f/32.png) [@ike](https://users.rust-lang.org/u/ike)\
**Post date:** [August 19, 2024, 8:12pm UTC](https://users.rust-lang.org/t/best-way-to-implement-version-option/116227/1 "2024-08-19T20:12:23Z")

</div>

What is the best way to gather contents for a `--version` string command line option in a Rust app that:

- Always updates whenever _anything needs_ rebuilding
- Includes build timestamp
- Includes some kind of version information, such as git commit hash, Cargo version string, etc.
- Does not require any runtime dependencies (does not add to runtime footprint).

I have found various crates that might help with this, such as `build_details`, `compile_time`, `shadow_rs`, and even `compile_time_run`. But I don't know how to determine how often these run and what their runtime dependencies are.

---

<div class="post-metadata">

**Author:** ![jwodder](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/jwodder/32/27866_2.png) [@jwodder](https://users.rust-lang.org/u/jwodder)\
**Post date:** [August 19, 2024, 9:27pm UTC](https://users.rust-lang.org/t/best-way-to-implement-version-option/116227/2 "2024-08-19T21:27:15Z")

</div>

The general approach is to use a [build script](https://doc.rust-lang.org/cargo/reference/build-scripts.html) (`build.rs`) that determines the timestamp, Git info, etc. and provides that information to your actual binary crate by either (a) emitting `cargo::rustc-env` instructions to set environment variables when the crate is compiled, at which point the envvars can be accessed with `env!()` or (b) writing Rust code or other structured data to a file in `OUT_DIR`, which can then be incorporated into the crate with `include!()` or similar. By default, `build.rs` is rerun if any files in your package changed, but [this can be modified](https://doc.rust-lang.org/cargo/reference/build-scripts.html#change-detection).

This is the approach taken by two of the packages you mentioned — `build_details` and `shadow_rs` — and so "how often these run" becomes just "how often is `build.rs` (re)run." As for runtime dependencies, you need to see whether each package's documentation tells you to add anything to `[dependencies]` (not to be confused with `[build-dependencies]`, which is only for `build.rs` dependencies). `build_details`' README states that it requires a runtime dependency on `phf`, and `shadow-rs` requires both a runtime and build-time dependency on `shadow-rs`.

The `compile_time` and `compile_time_run` packages, in contrast, use proc macros that run arbitrary Rust code when the invoking code is compiled. I don't feel qualified to answer your questions when it comes to this approach, though the use of proc macros for this strikes me as a bit of an anti-pattern.

---

<div class="post-metadata">

**Author:** ![kornel](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/kornel/32/4823_2.png) [@kornel](https://users.rust-lang.org/u/kornel)\
**Post date:** [August 19, 2024, 10:07pm UTC](https://users.rust-lang.org/t/best-way-to-implement-version-option/116227/3 "2024-08-19T22:07:19Z")

</div>

Use [vergen](https://lib.rs/crates/vergen). It's designed to collect and update build-time information.

Most importantly it's a de-facto standard, so for example when package maintainers need to make builds reproducible, they only need to configure vergen, and not patch crates individually.

> **[GitHub - rustyhorde/vergen: Generate cargo instructions at compile time in...](https://github.com/rustyhorde/vergen)**
>
> Generate cargo instructions at compile time in build scripts for use with the env! or option\_env! macros

---

<div class="post-metadata">

**Author:** ![ike](https://avatars.discourse-cdn.com/v4/letter/i/df705f/32.png) [@ike](https://users.rust-lang.org/u/ike)\
**Post date:** [August 20, 2024, 12:34am UTC](https://users.rust-lang.org/t/best-way-to-implement-version-option/116227/4 "2024-08-20T00:34:30Z")

</div>

`vergen_gitcl` looks like exactly what I want in terms of output and lack of runtime footprint! Thanks for pointing it out!

I added `CARGO_PKG_VERSION` to the `option_env!`'s, which Cargo sets itself.

And I have `build.rs` emit `cargo::rerun-if-changed=src` to get it to update on every build.

---

<div class="post-metadata">

**Author:** ![system](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/system/32/51372_2.png) [@system](https://users.rust-lang.org/u/system)\
**Post date:** [November 18, 2024, 12:35am UTC](https://users.rust-lang.org/t/best-way-to-implement-version-option/116227/5 "2024-11-18T00:35:01Z")

</div>

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.
