1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
use std::env;
use std::path::PathBuf;
use std::process::Command;
use serde::Deserialize;
#[derive(Deserialize)]
struct MetaData {
target_directory: PathBuf,
}
fn primary_target_dir() -> PathBuf {
if let Some(target_dir) = env::var_os("CARGO_TARGET_DIR") {
let target_dir = PathBuf::from(target_dir);
if target_dir.is_dir() {
println!("first out");
return target_dir;
};
}
env::current_exe()
.ok()
.map(|mut path| {
path.pop();
if path.ends_with("deps") || path.ends_with("examples") {
path.pop();
}
path
})
.unwrap()
}
fn cargo_inferred_target_dir() -> PathBuf {
let metadata = Command::new(env::var("CARGO").ok().unwrap_or_else(|| "cargo".into()))
.arg("metadata")
.output()
.unwrap();
let meta: MetaData = serde_json::from_slice(&metadata.stdout).unwrap();
let mut rv = meta.target_directory;
if cfg!(debug_assertions) {
rv.push("debug");
} else {
rv.push("release");
}
rv
}
fn find_exe(name: &str) -> PathBuf {
let mut first = primary_target_dir();
first.push(name);
if first.is_file() {
return first;
}
let mut alt = cargo_inferred_target_dir();
alt.push(name);
if alt.is_file() {
return alt;
}
panic!("Cannot determine path to executable '{}'", name);
}
pub fn get_cargo_bin(name: &str) -> PathBuf {
let env_var = format!("CARGO_BIN_EXE_{}", name);
env::var_os(&env_var)
.map(|p| p.into())
.unwrap_or_else(|| find_exe(&format!("{}{}", name, env::consts::EXE_SUFFIX)))
}
pub fn get_cargo_example(name: &str) -> PathBuf {
find_exe(&format!("examples/{}{}", name, env::consts::EXE_SUFFIX))
}