-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbuild.rs
More file actions
162 lines (128 loc) · 5.02 KB
/
build.rs
File metadata and controls
162 lines (128 loc) · 5.02 KB
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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
fn main() {
#[cfg(feature = "oidn")]
oidn::setup_oidn_environment();
}
#[cfg(feature = "oidn")]
mod oidn {
use std::{
env, fs, io,
path::{Path, PathBuf},
};
fn manifest_dir() -> PathBuf {
PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap())
}
pub fn get_oidn_dir() -> PathBuf {
manifest_dir().join(
env::var("OIDN_DIR")
.expect("OIDN_DIR env var not set (set it to path like ./oidn/oidn)"),
)
}
pub fn get_oidn_version() -> String {
env::var("OIDN_VER").expect("OIDN_VER env var not set (ex: v2.3.3)")
}
pub fn setup_oidn_environment() {
let oidn_dir = get_oidn_dir();
// extraction ALWAYS re-runs; good for dev, deterministic
extract_oidn(&oidn_dir).expect("Failed to extract OIDN binaries");
copy_oidn_binaries(&oidn_dir.join("bin"));
}
pub fn extract_oidn(oidn_dir: &Path) -> io::Result<()> {
let target = env::var("TARGET").expect("TARGET environment variable not set");
let archive_path = construct_archive_path(&target);
if !archive_path.exists() {
panic!(
"OIDN archive not found: {}\nExpected archive inside: {}",
archive_path.display(),
manifest_dir().display()
);
}
let ext = archive_path.extension().and_then(|x| x.to_str());
match ext {
Some("zip") => extract_zip(&archive_path, oidn_dir),
Some("gz") => extract_tar_gz(&archive_path, oidn_dir),
_ => panic!("Unknown OIDN archive format: {:?}", ext),
}
}
pub fn construct_archive_path(target: &str) -> PathBuf {
let ver = get_oidn_version().trim_start_matches('v').to_string();
let file = if target.contains("windows") {
format!("oidn-{ver}.x64.windows.zip")
} else if target.contains("linux") {
format!("oidn-{ver}.x86_64.linux.tar.gz")
} else if target.contains("darwin") && target.contains("aarch64") {
format!("oidn-{ver}.arm64.macos.tar.gz")
} else if target.contains("darwin") {
format!("oidn-{ver}.x86_64.macos.tar.gz")
} else {
panic!("Unsupported target triple for OIDN: {target}");
};
manifest_dir().join("oidn").join(file)
}
pub fn extract_zip(archive_path: &Path, oidn_dir: &Path) -> io::Result<()> {
let file = fs::File::open(archive_path)?;
let mut archive = zip::ZipArchive::new(file)?;
if oidn_dir.exists() {
fs::remove_dir_all(oidn_dir)?;
}
fs::create_dir_all(oidn_dir)?;
for i in 0..archive.len() {
let mut file = archive.by_index(i)?;
let name = file.mangled_name();
let name = name.to_string_lossy();
let relative = name.split('\\').skip(1).collect::<Vec<_>>().join("/");
let outpath = oidn_dir.join(relative);
if file.name().ends_with('/') {
fs::create_dir_all(&outpath)?;
} else {
if let Some(parent) = outpath.parent() {
fs::create_dir_all(parent)?;
}
let mut out = fs::File::create(&outpath)?;
io::copy(&mut file, &mut out)?;
}
}
Ok(())
}
pub fn extract_tar_gz(archive_path: &Path, oidn_dir: &Path) -> io::Result<()> {
let tar_gz = fs::File::open(archive_path)?;
let tar = flate2::read::GzDecoder::new(tar_gz);
let mut archive = tar::Archive::new(tar);
let parent_dir = oidn_dir.parent().unwrap();
if oidn_dir.exists() {
fs::remove_dir_all(oidn_dir)?;
}
archive.unpack(parent_dir)?;
let extracted_dir = fs::read_dir(parent_dir)?
.filter_map(|e| e.ok())
.map(|e| e.path())
.find(|p| p.is_dir() && p.file_name().unwrap().to_string_lossy().contains("oidn"))
.expect("Could not locate extracted OIDN directory");
fs::rename(extracted_dir, oidn_dir)?;
Ok(())
}
pub fn copy_oidn_binaries(bin_dir: &Path) {
if !bin_dir.exists() {
panic!(
"OIDN bin directory missing after extraction: {}",
bin_dir.display()
);
}
let entries = fs::read_dir(bin_dir).expect("Error reading OIDN bin directory");
for entry in entries {
let entry = entry.expect("Bad fs entry");
let path = entry.path();
let file = path.file_name().unwrap();
let mut out = get_output_path();
out.push(file);
fs::create_dir_all(out.parent().unwrap()).unwrap();
fs::copy(&path, &out).unwrap_or_else(|_| {
panic!("Failed to copy OIDN binary {}", file.to_string_lossy())
});
}
}
pub fn get_output_path() -> PathBuf {
let manifest = manifest_dir();
let profile = env::var("PROFILE").unwrap();
manifest.join("target").join(profile)
}
}