Pre-RFC: Add cargo target name environment variable


#1

EDIT: Currently investigating if module_path! is sufficient.

Summary

Add CARGO_TARGET_NAME to the environment of targets: [[bin]], [[bench]], [[test]], and [[example]]

Motivation

Currently it is not straightforward for external benchmark harnesses (eg. criterion) to know which benchmark target is being executed.

For instance given the following directory structure:

benches/
├── bencha.rs
└── benchb.rs

and cargo.toml

[[bench]]
name = "bencha"
harness = false

[[bench]]
name = "benchb"
harness = false

Criterion doesn’t know what target is being benchmarked during benchmarking

It would be nice for a harness to be able to output structured data (csv / json) of the benchmark data (I’ve been championing it for criterion) to enable richer graphics and interpretation of benchmarks. With CARGO_TARGET_NAME, criterion could output the results into bencha.csv and benchb.csv instead of clobbering each other.

I recently came across the evmap project where the owner eschewed any harness and wrote their own benchmark executable, which outputs space delimited data as input to create detailed charts. Ideally, the rust community will converge on a single benchmark harness that allows an output of structured data, but we’re kinda blocked on missing CARGO_TARGET_NAME from Cargo to truly enable that.

Detailed Design

When cargo fills in the environment with other variables like CARGO_PKG_NAME, add CARGO_TARGET_NAME with the result of Target::name.

Drawbacks

Adding another environment variable is another feature to maintain and document. Alex has stated he’s wary of adding additional environment variables to cargo. Also this would be another step away from Cargo binaries are not run in pristine environment.

Questions

  • CARGO_TARGET_NAME may not be the best name. What’s a better name?
  • I’m not aware of external harnesses for bin, test, or example targets, so is this best geared for only benchmarks?

Alternatives

  • Dissect argv[0] (eg: bencha-afa3414ds -> bencha). Relying on this seems a bit dirty for an external harness as there is nothing guaranteeing an executable name format.
  • There may be a feasible alternative using cargo metadata, but brief testing didn’t reveal anything.

Aside: First [pre-]RFC and no idea if new environment variables are appropriate for an RFC, but I figured I’d post and test the water :smile:


#2

Can you just use module_path! for this? You can split at the first :: if you just want the crate name.


#3

Very nice! Inside benchmarks:

println!("{}", module_path!());

yields:

bencha
benchb

respectively. I did not know this! Thank you, I’ll chew on this and see if this solves everything. I’ll edit the post.