forked from rust-skia/rust-skia
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbinaries_config.rs
180 lines (149 loc) · 6.04 KB
/
binaries_config.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
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
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
use super::platform;
use crate::build_support::{cargo, features};
use std::{
collections::HashSet,
fs, io,
path::{Path, PathBuf},
};
pub const SKIA_OUTPUT_DIR: &str = "skia";
const ICUDTL_DAT: &str = "icudtl.dat";
/// The libraries to link with.
pub mod lib {
pub const SKIA: &str = "skia";
pub const SKIA_BINDINGS: &str = "skia-bindings";
pub const SK_SHAPER: &str = "skshaper";
pub const SK_PARAGRAPH: &str = "skparagraph";
pub const SVG: &str = "svg";
pub const SK_RESOURCES: &str = "skresources";
pub const SK_UNICODE_CORE: &str = "skunicode_core";
pub const SK_UNICODE_ICU: &str = "skunicode_icu";
}
/// The configuration of the resulting binaries.
#[derive(Clone, PartialEq, Eq, Debug)]
pub struct BinariesConfiguration {
/// The feature identifiers we built with.
pub feature_ids: HashSet<String>,
/// The output directory of the libraries we build and we need to inform cargo about.
pub output_directory: PathBuf,
/// The TARGET specific link libraries we need to inform cargo about.
pub link_libraries: Vec<String>,
/// The static Skia libraries built by ninja that dependent projects need to link with.
pub ninja_built_libraries: Vec<String>,
/// Static libraries that are generated in the binding process dependent projects need to link
/// with.
pub binding_libraries: Vec<String>,
/// Files that are generated in the binding process (this is `bindings.rs`).
pub binding_files: Vec<PathBuf>,
/// Additional files relative to the output_directory
/// that are needed to build dependent projects.
pub additional_files: Vec<PathBuf>,
/// `true` if the skia libraries are built with debugging information.
pub skia_debug: bool,
}
impl BinariesConfiguration {
/// Build a binaries configuration from a set of Skia features.
pub fn from_features(features: &features::Features, skia_debug: bool) -> Self {
let target = cargo::target();
let mut ninja_built_libraries = Vec::new();
let mut binding_libraries = Vec::new();
let binding_files = vec!["bindings.rs".into()];
let mut additional_files = Vec::new();
let feature_ids = features.ids();
if features.text_layout {
if target.is_windows() {
additional_files.push(ICUDTL_DAT.into());
}
ninja_built_libraries.push(lib::SK_PARAGRAPH.into());
ninja_built_libraries.push(lib::SK_SHAPER.into());
ninja_built_libraries.push(lib::SK_UNICODE_CORE.into());
ninja_built_libraries.push(lib::SK_UNICODE_ICU.into());
}
if features.svg {
ninja_built_libraries.push(lib::SVG.into());
ninja_built_libraries.push(lib::SK_RESOURCES.into());
}
let link_libraries = platform::link_libraries(features, &target);
let output_directory = cargo::output_directory()
.join(SKIA_OUTPUT_DIR)
.to_str()
.unwrap()
.into();
ninja_built_libraries.push(lib::SKIA.into());
binding_libraries.push(lib::SKIA_BINDINGS.into());
BinariesConfiguration {
feature_ids: feature_ids.into_iter().map(|f| f.to_string()).collect(),
output_directory,
link_libraries,
ninja_built_libraries,
binding_libraries,
binding_files,
additional_files,
skia_debug,
}
}
pub fn built_libraries(&self, include_bindings: bool) -> impl Iterator<Item = &str> {
self.ninja_built_libraries
.iter()
.chain(if include_bindings {
self.binding_libraries.iter()
} else {
[].iter()
})
.map(|x| x.as_str())
}
/// Inform cargo that the library files of the given configuration are available and
/// can be used as dependencies.
pub fn commit_to_cargo(&self) {
cargo::add_link_search(self.output_directory.to_str().unwrap());
// On Linux, the order is significant, first the static libraries we built, and then
// the system libraries.
let target = cargo::target();
cargo::add_static_link_libs(&target, self.built_libraries(true));
cargo::add_link_libs(&self.link_libraries);
}
/// Import library and additional files from `from_dir` to the output directory.
pub fn import(&self, from_dir: &Path, import_bindings: bool) -> io::Result<()> {
let output_directory = &self.output_directory;
self.copy_libs_and_additional_files(from_dir, output_directory, import_bindings)
}
/// Export library and additional files from the output directory to a `to_dir`.
pub fn export(&self, to_dir: &Path) -> io::Result<()> {
let output_directory = &self.output_directory;
self.copy_libs_and_additional_files(output_directory, to_dir, true)
}
fn copy_libs_and_additional_files(
&self,
from_dir: &Path,
to_dir: &Path,
copy_bindings: bool,
) -> io::Result<()> {
fs::create_dir_all(to_dir)?;
let target = cargo::target();
for lib in self.built_libraries(copy_bindings) {
let filename = &target.library_to_filename(lib);
copy(filename, from_dir, to_dir)?;
}
for filename in &self.additional_files {
copy(filename, from_dir, to_dir)?;
}
if copy_bindings {
for filename in &self.binding_files {
copy(filename, from_dir, to_dir)?;
}
}
return Ok(());
fn copy(file_name: &Path, from_dir: &Path, to_dir: &Path) -> io::Result<()> {
let from_path = from_dir.join(file_name);
let to_path = to_dir.join(file_name);
fs::copy(&from_path, &to_path).map(|_| ()).map_err(|e| {
eprintln!(
"COPY OPERATION FAILED: from '{}' to '{}': {}",
from_path.display(),
to_path.display(),
e
);
e
})
}
}
}