ctranslate2_src_build_support/
lib.rs1use std::{
2 env,
3 fs::File,
4 path::{Path, PathBuf},
5};
6
7use flate2::Compression;
8use tar::Builder;
9use walkdir::WalkDir;
10
11pub mod dnnl;
12pub mod download;
13pub mod file_changes;
14pub mod link;
15pub mod native;
16pub mod submodules;
17pub mod windows_crt_patch;
18
19#[derive(Debug, Eq, PartialEq, Copy, Clone)]
20pub enum Os {
21 Win,
22 Mac,
23 Linux,
24 Unknown,
25}
26
27pub fn export(lib_path: &Path, modules: &[PathBuf], modules2: &[PathBuf]) {
28 let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap());
29 let out_dir = out_dir
30 .parent()
31 .unwrap()
32 .parent()
33 .unwrap()
34 .parent()
35 .unwrap();
36
37 let tar_gz = File::create(out_dir.join("vendored.tar.gz")).unwrap();
38 let enc = flate2::write::GzEncoder::new(tar_gz, Compression::default());
39 let mut tar = Builder::new(enc);
40
41 tar.append_dir_all("include", lib_path.join("../include"))
42 .unwrap();
43
44 for module in modules {
45 let mut file = File::open(&module).unwrap();
46 let name = module.file_name().unwrap().to_str().unwrap();
47 tar.append_file(format!("lib/{}", name), &mut file).unwrap();
48 }
49 for module in modules2 {
50 let mut file = File::open(&module).unwrap();
51 let name = module.file_name().unwrap().to_str().unwrap();
52 tar.append_file(format!("dyn/{}", name), &mut file).unwrap();
53 }
54
55 tar.finish().unwrap();
56}
57
58pub fn link_libraries<T: AsRef<Path>>(root: T) -> Vec<PathBuf> {
59 let mut current_dir = None;
60 let mut libs = Vec::new();
61 for entry in WalkDir::new(root).into_iter().filter_map(Result::ok) {
62 let path = entry.path();
63 if path.is_file() {
64 if let Some(file_name) = path
65 .file_name()
66 .and_then(|name| name.to_str())
67 .filter(|name| is_library(name))
68 {
69 let parent = path.parent().unwrap();
70 if Some(parent) != current_dir.as_deref() {
71 println!("cargo:rustc-link-search={}", parent.display());
72 current_dir = Some(parent.to_path_buf());
73 }
74 libs.push(path.to_path_buf());
75
76 let lib_name = library_name(file_name);
77 println!("cargo:rustc-link-lib=static={}", lib_name);
78 }
79 }
80 }
81 libs
82}
83
84#[cfg(not(target_os = "windows"))]
85fn is_library(name: &&str) -> bool {
86 name.starts_with("lib") && name.ends_with(".a")
87}
88
89#[cfg(not(target_os = "windows"))]
90fn library_name(name: &str) -> &str {
91 &name[3..name.len() - 2]
92}
93
94#[cfg(target_os = "windows")]
95fn is_library(name: &&str) -> bool {
96 name.ends_with(".lib") && !name.starts_with(".")
97}
98
99#[cfg(target_os = "windows")]
100fn library_name(name: &str) -> &str {
101 &name[0..name.len() - 4]
102}
103
104pub fn link_dynamic_libraries<T: AsRef<Path>>(root: T) -> Vec<PathBuf> {
105 let mut current_dir = None;
106 let mut libs = Vec::new();
107
108 for entry in WalkDir::new(root).into_iter().filter_map(Result::ok) {
109 let path = entry.path();
110 if path.is_file() {
111 if let Some(file_name) = path
112 .file_name()
113 .and_then(|name| name.to_str())
114 .filter(|name| is_dynamic_library(name))
115 {
116 let parent = path.parent().unwrap();
117 if Some(parent) != current_dir.as_deref() {
118 println!("cargo:rustc-link-search={}", parent.display());
119 current_dir = Some(parent.to_path_buf());
120 }
121 libs.push(path.to_path_buf());
122
123 let lib_name = dynamic_library_name(file_name);
124 println!("cargo:rustc-link-lib=dylib={}", lib_name);
125 }
126 }
127 }
128
129 libs
130}
131
132#[cfg(target_os = "linux")]
133fn is_dynamic_library(name: &str) -> bool {
134 name.starts_with("lib") && name.ends_with(".so")
135}
136
137#[cfg(target_os = "linux")]
138fn dynamic_library_name(name: &str) -> &str {
139 &name[3..name.len() - 3] }
141
142#[cfg(target_os = "macos")]
143fn is_dynamic_library(name: &str) -> bool {
144 name.starts_with("lib") && name.ends_with(".dylib")
145}
146
147#[cfg(target_os = "macos")]
148fn dynamic_library_name(name: &str) -> &str {
149 &name[3..name.len() - 6] }
151
152#[cfg(target_os = "windows")]
153fn is_dynamic_library(name: &str) -> bool {
154 name.ends_with(".lib") && !name.starts_with(".")
156}
157
158#[cfg(target_os = "windows")]
159fn dynamic_library_name(name: &str) -> &str {
160 &name[0..name.len() - 4] }