-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbuild.rs
113 lines (99 loc) · 3.58 KB
/
build.rs
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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
use std::env;
use std::path::PathBuf;
use std::process::Command;
#[cfg(all(windows, target_env = "msvc"))]
pub fn is_msvc() -> bool {
true
}
#[cfg(not(all(windows, target_env = "msvc")))]
pub fn is_msvc() -> bool {
false
}
/// Runs a command, checks that it is successful, and
/// returns its output if requested
pub fn run_command(command: &mut Command, fetch_stdout: bool, pipe_output: bool) -> Result<String,String> {
if pipe_output {
command.stdout(std::process::Stdio::piped());
command.stderr(std::process::Stdio::piped());
}
println!("Executing command: {:?}", command);
// command.output() must be called before command.status()
// to avoid freezes on Windows
let output = if pipe_output || fetch_stdout {
Some(try!(command.output().or(Err(format!("command execution failed: {:?}", command)))))
} else {
None
};
let status = try!(command.status().or(Err(format!("command execution failed: {:?}", command))));
if status.success() {
Ok(if let Some(output) = output {
if fetch_stdout {
try!(String::from_utf8(output.stdout).or(Err("comand output is not valid unicode")))
} else {
String::new()
}
} else {
String::new()
})
} else {
if let Some(output) = output {
use std::io::Write;
println!("Stdout:");
try!(std::io::stderr().write_all(&output.stdout).or(Err("output failed")));
println!("Stderr:");
try!(std::io::stderr().write_all(&output.stderr).or(Err("output failed")));
}
Err(format!("command failed with status {:?}: {:?}", status, command).into())
}
}
fn main() {
let manifest_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
let mut c_lib_path = PathBuf::from(manifest_dir.clone());
c_lib_path.push("c_lib");
c_lib_path.push("install");
c_lib_path.push("lib");
println!("cargo:rustc-link-search={}", c_lib_path.to_str().unwrap());
let mut build_path = PathBuf::from(manifest_dir.clone());
build_path.push("c_lib");
build_path.push("build");
let mut source_path = PathBuf::from(manifest_dir.clone());
source_path.push("c_lib");
source_path.push("source");
let mut install_path = PathBuf::from(manifest_dir);
install_path.push("c_lib");
install_path.push("install");
//create directories
::std::fs::create_dir_all(build_path.to_str().unwrap()).unwrap();
::std::fs::create_dir_all(install_path.to_str().unwrap()).unwrap();
//STEP1: run cmake
let mut cmake_command = Command::new("cmake");
cmake_command.arg(source_path.to_str().unwrap())
.arg(format!("-DCMAKE_INSTALL_PREFIX={}",install_path.to_str().unwrap()))
.current_dir(build_path.to_str().unwrap());
if is_msvc() {
cmake_command.arg("-G").arg("NMake Makefiles");
// Rust always links to release version of MSVC runtime, so
// link will fail if C library is built in debug mode
cmake_command.arg("-DCMAKE_BUILD_TYPE=Release");
}
run_command(&mut cmake_command, false, true).unwrap();
//STEP2: make
let make_command_name = if is_msvc() { "nmake" } else { "make" }.to_string();
let mut make_args = Vec::new();
if !is_msvc() {
make_args.push(format!("-j{}", 4));
}
make_args.push("install".to_string());
let mut make_command = Command::new(make_command_name);
make_command.args(&make_args)
.current_dir(build_path.to_str().unwrap());
/*if let Some(linker_env_library_dirs) = self.linker_env_library_dirs {
if !linker_env_library_dirs.is_empty() {
for name in &["LIBRARY_PATH", "LD_LIBRARY_PATH", "LIB"] {
let value = try!(add_env_path_item(name, (*linker_env_library_dirs).clone()));
make_command.env(name, value);
}
}
}*/
run_command(&mut make_command, false, true).unwrap();
}