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
77
78
79
80
#![deny(missing_docs)]
#![deny(rustdoc::broken_intra_doc_links)]
use std::env;
use std::fmt;
use std::path::Path;
use std::path::PathBuf;
#[derive(Debug)]
pub struct Error {
os: &'static str,
arch: &'static str,
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"protoc binary cannot be found for platform {}-{}",
self.os, self.arch
)
}
}
impl std::error::Error for Error {}
pub fn protoc_bin_path() -> Result<PathBuf, Error> {
let protoc_bin_name = match (env::consts::OS, env::consts::ARCH) {
("linux", "x86") => "protoc-linux-x86_32",
("linux", "x86_64") => "protoc-linux-x86_64",
("linux", "aarch64") => "protoc-linux-aarch_64",
("linux", "powerpc64") => "protoc-linux-ppcle_64",
("macos", "x86_64") => "protoc-osx-x86_64",
("macos", "aarch64") => "protoc-osx-x86_64",
("windows", _) => "protoc-win32.exe",
(os, arch) => return Err(Error { os, arch }),
};
let protoc_bin_path = Path::new(env!("CARGO_MANIFEST_DIR"))
.join("bin")
.join(protoc_bin_name);
assert!(
protoc_bin_path.exists(),
"internal: protoc not found {}",
protoc_bin_name
);
Ok(protoc_bin_path)
}
#[cfg(test)]
mod test {
use std::io::Read;
use std::process;
#[test]
fn smoke() {
let process = process::Command::new(super::protoc_bin_path().unwrap())
.arg("--version")
.stdin(process::Stdio::null())
.stdout(process::Stdio::piped())
.spawn()
.unwrap();
let mut stdout = String::new();
process.stdout.unwrap().read_to_string(&mut stdout).unwrap();
assert!(stdout.contains("libprotoc"), "stdout is: {:?}", stdout)
}
}