This information is available through the --message-format=json Cargo flag:
cargo b $RELEASE --example example_name -q --message-format=json
- assuming
$RELEASE either expands to '' or to '--release'
outputs:
{
"reason": "compiler-artifact",
"package_id": "crate_name 0.1.0 (path+file:///private/var/folders/m_/347zzk7j6nz08tt6z3tnd3z00000gn/T/tmp.7Cn3Cxiy)",
"target": {
"kind": [
"lib"
],
"crate_types": [
"lib"
],
"name": "crate_name",
"src_path": "/private/var/folders/m_/347zzk7j6nz08tt6z3tnd3z00000gn/T/tmp.7Cn3Cxiy/src/lib.rs",
"edition": "2018",
"doctest": true
},
"profile": {
"opt_level": "0",
"debuginfo": 2,
"debug_assertions": true,
"overflow_checks": true,
"test": false
},
"features": [],
"filenames": [
"/private/var/folders/m_/347zzk7j6nz08tt6z3tnd3z00000gn/T/tmp.7Cn3Cxiy/target/debug/deps/libcrate_name-67735c22f4f0185b.rlib",
"/private/var/folders/m_/347zzk7j6nz08tt6z3tnd3z00000gn/T/tmp.7Cn3Cxiy/target/debug/deps/libcrate_name-67735c22f4f0185b.rmeta"
],
"executable": null,
"fresh": false
}
{
"reason": "compiler-artifact",
"package_id": "crate_name 0.1.0 (path+file:///private/var/folders/m_/347zzk7j6nz08tt6z3tnd3z00000gn/T/tmp.7Cn3Cxiy)",
"target": {
"kind": [
"example"
],
"crate_types": [
"bin"
],
"name": "example_name",
"src_path": "/private/var/folders/m_/347zzk7j6nz08tt6z3tnd3z00000gn/T/tmp.7Cn3Cxiy/examples/example_name.rs",
"edition": "2018",
"doctest": false
},
"profile": {
"opt_level": "0",
"debuginfo": 2,
"debug_assertions": true,
"overflow_checks": true,
"test": false
},
"features": [],
"filenames": [
"/private/var/folders/m_/347zzk7j6nz08tt6z3tnd3z00000gn/T/tmp.7Cn3Cxiy/target/debug/examples/example_name",
"/private/var/folders/m_/347zzk7j6nz08tt6z3tnd3z00000gn/T/tmp.7Cn3Cxiy/target/debug/examples/example_name.dSYM"
],
"executable": "/private/var/folders/m_/347zzk7j6nz08tt6z3tnd3z00000gn/T/tmp.7Cn3Cxiy/target/debug/examples/example_name",
"fresh": false
}
{
"reason": "build-finished",
"success": true
}
I'll let you stare at the output, but you can notice that you can filter based on .target.kind being ["example"] (if you want to know about --example executables), and then .target.name being example_name.
Then, the field executable is the one that tells you where cargo has created the binary.
Proof-of-Concept
Hence, the following jq-based one-liner:
cargo build $RELEASE --example example_name -q --message-format=json \
| jq -r -c '
select(
(.target.kind == ["example"])
and
(.target.name == "example_name")
)
| .executable
'
which yields
/path/to/ā¦/crate/target/release/examples/example_name
which, granted, seems to be an easy to guess file name not requiring all this:
Location of executables
-
examples/example_name.rs
yields an executable at:
target/{debug,release}/examples/example_name.ext
Remarks regarding target/
-
Note that target/ is the default CARGO_TARGET_DIR, which can be overridden through env vars or .cargo/config keys, or simply be located in a parent directory if such directory is a workspace having the current crate as one of its members.
-
Note also that when cross-compiling, there will be an intermediate directory in between the CARGO_TARGET_DIR / target/ and the {debug,release} duet, named as the target triplet:
<cargo-target-dir>{,/<target-triple>}/{debug,release}/ā¦
-
src/main.rs or src/bin/crate_name/main.rs
yields an executable at:
target/{debug,release}/crate_name.ext
-
tests/test_name.rs
yields an executable at:
target/debug/deps/test_name-SOME_HASH.ext
which is the one featuring a hard-to-predict file name because of that hash.
That's where parsing the JSON output of the --message-format=json output of Cargo comes in very handy 
Again, a jq proof-of-concept
Getting the exact path of a specific integration test binary (jq PoC)
Assuming a tests/test_name.rs file layout, we do:
cargo test $RELEASE --test test_name --no-run -q --message-format=json \
| jq -r -c '
select(
(.target.kind == ["test"])
and
(.target.name == "test_name")
)
| .executable
'
to obtain
/abs/path/to/ā¦/target/ā¦/{debug,release}/deps/test_name-<hash>{,.ext}
Getting the paths of all the integration tests under tests/
cargo test $RELEASE --no-run -q --message-format=json \
| jq -r -c 'select(.target.kind == ["test"]) | .executable'
to obtain one path per line 
- if you are worried about weird whitespace shenanigans, you can remove the
-r from jq to get json-stringified versions of these paths, allowing to disambiguate the paths at the cost of having to perform the json-unstringification ourselves afterwards.