1#[cfg(feature = "pkg-config")]
2pub use pkg_config;
3
4#[cfg(feature = "bindgen")]
5pub use bindgen;
6
7#[cfg(feature = "cc")]
8pub use cc;
9
10use std::{iter::Chain, path::Path};
11
12#[cfg(feature = "pkg-config")]
13use std::path::PathBuf;
14
15pub mod iter;
16
17pub trait CcArgs<'a, P1, P2, P3, S1, S2, S3, S4, S5, I1>
18where
19 P1: AsRef<Path> + 'a,
20 P2: AsRef<Path> + 'a,
21 P3: AsRef<Path> + 'a,
22 S1: AsRef<str> + 'a,
23 S2: AsRef<str> + 'a,
24 S3: AsRef<str> + 'a,
25 S4: AsRef<str> + 'a,
26 S5: AsRef<str> + 'a,
27 I1: Iterator<Item = S3> + 'a,
28{
29 type LinkPathsIter: Iterator<Item = P1>;
30
31 fn link_paths(&'a self) -> Self::LinkPathsIter;
32
33 #[inline]
34 fn link_paths_args(&'a self) -> iter::LinkPathsArgsIter<P1, Self::LinkPathsIter> {
35 self.link_paths().into()
36 }
37
38 type IncludePathsIter: Iterator<Item = P2>;
39
40 fn include_paths(&'a self) -> Self::IncludePathsIter;
41
42 #[inline]
43 fn include_paths_args(&'a self) -> iter::IncludePathsArgsIter<P2, Self::IncludePathsIter> {
44 self.include_paths().into()
45 }
46
47 type FrameworkPathsIter: Iterator<Item = P3>;
48
49 fn framework_paths(&'a self) -> Self::FrameworkPathsIter;
50
51 #[inline]
52 fn framework_paths_args(
53 &'a self,
54 ) -> iter::FrameworkPathsArgsIter<P3, Self::FrameworkPathsIter> {
55 self.framework_paths().into()
56 }
57
58 type FrameworksIter: Iterator<Item = S1>;
59
60 fn frameworks(&'a self) -> Self::FrameworksIter;
61
62 #[inline]
63 fn frameworks_args(&'a self) -> iter::FrameworksArgsIter<S1, Self::FrameworksIter> {
64 self.frameworks().into()
65 }
66
67 type LibsIter: Iterator<Item = S2>;
68
69 fn libs(&'a self) -> Self::LibsIter;
70
71 #[inline]
72 fn libs_args(&'a self) -> iter::LibsArgsIter<S2, Self::LibsIter> {
73 self.libs().into()
74 }
75
76 type LdArgsIter: Iterator<Item = I1>;
77
78 fn ld_args(&'a self) -> Self::LdArgsIter;
79
80 #[inline]
81 fn ld_args_args(&'a self) -> iter::LdArgsArgsIter<S3, I1, Self::LdArgsIter> {
82 self.ld_args().into()
83 }
84
85 type DefinesIter: Iterator<Item = (S4, &'a Option<S5>)>;
86
87 fn defines(&'a self) -> Self::DefinesIter;
88
89 #[inline]
90 fn defines_args(&'a self) -> iter::DefinesArgsIter<'a, S4, S5, Self::DefinesIter> {
91 self.defines().into()
92 }
93
94 fn cc_args(
95 &'a self,
96 ) -> Chain<
97 Chain<
98 Chain<
99 Chain<
100 Chain<
101 Chain<
102 iter::LinkPathsArgsIter<P1, Self::LinkPathsIter>,
103 iter::IncludePathsArgsIter<P2, Self::IncludePathsIter>,
104 >,
105 iter::FrameworkPathsArgsIter<P3, Self::FrameworkPathsIter>,
106 >,
107 iter::FrameworksArgsIter<S1, Self::FrameworksIter>,
108 >,
109 iter::LibsArgsIter<S2, Self::LibsIter>,
110 >,
111 iter::LdArgsArgsIter<S3, I1, Self::LdArgsIter>,
112 >,
113 iter::DefinesArgsIter<'a, S4, S5, Self::DefinesIter>,
114 > {
115 self.link_paths_args()
116 .chain(self.include_paths_args())
117 .chain(self.framework_paths_args())
118 .chain(self.frameworks_args())
119 .chain(self.libs_args())
120 .chain(self.ld_args_args())
121 .chain(self.defines_args())
122 }
123}
124
125pub trait MergeCcArgs {
126 fn merge_cc_args<'a, P1, P2, P3, S1, S2, S3, S4, S5, I1, A>(self, lib: &'a A) -> Self
127 where
128 P1: AsRef<Path> + 'a,
129 P2: AsRef<Path> + 'a,
130 P3: AsRef<Path> + 'a,
131 S1: AsRef<str> + 'a,
132 S2: AsRef<str> + 'a,
133 S3: AsRef<str> + 'a,
134 S4: AsRef<str> + 'a,
135 S5: AsRef<str> + 'a,
136 I1: Iterator<Item = S3> + 'a,
137 A: CcArgs<'a, P1, P2, P3, S1, S2, S3, S4, S5, I1>;
138}
139
140#[cfg(feature = "bindgen")]
141impl MergeCcArgs for bindgen::Builder {
142 fn merge_cc_args<'a, P1, P2, P3, S1, S2, S3, S4, S5, I1, A>(self, lib: &'a A) -> Self
143 where
144 P1: AsRef<Path> + 'a,
145 P2: AsRef<Path> + 'a,
146 P3: AsRef<Path> + 'a,
147 S1: AsRef<str> + 'a,
148 S2: AsRef<str> + 'a,
149 S3: AsRef<str> + 'a,
150 S4: AsRef<str> + 'a,
151 S5: AsRef<str> + 'a,
152 I1: Iterator<Item = S3> + 'a,
153 A: CcArgs<'a, P1, P2, P3, S1, S2, S3, S4, S5, I1>,
154 {
155 self.clang_args(lib.cc_args())
156 }
157}
158
159#[cfg(feature = "pkg-config")]
160#[inline]
161pub(crate) fn vec_iter<'a, T>(v: &'a Vec<T>) -> std::slice::Iter<'a, T> {
162 v.iter()
163}
164
165#[cfg(feature = "pkg-config")]
166impl<'a>
167 CcArgs<
168 'a,
169 &'a PathBuf,
170 &'a PathBuf,
171 &'a PathBuf,
172 &'a String,
173 &'a String,
174 &'a String,
175 &'a String,
176 String,
177 std::slice::Iter<'a, String>,
178 > for pkg_config::Library
179{
180 type LinkPathsIter = std::slice::Iter<'a, PathBuf>;
181
182 fn link_paths(&'a self) -> Self::LinkPathsIter {
183 self.link_paths.iter()
184 }
185
186 type IncludePathsIter = std::slice::Iter<'a, PathBuf>;
187
188 fn include_paths(&'a self) -> Self::IncludePathsIter {
189 self.include_paths.iter()
190 }
191
192 type FrameworkPathsIter = std::slice::Iter<'a, PathBuf>;
193
194 fn framework_paths(&'a self) -> Self::FrameworkPathsIter {
195 self.framework_paths.iter()
196 }
197
198 type FrameworksIter = std::slice::Iter<'a, String>;
199
200 fn frameworks(&'a self) -> Self::FrameworksIter {
201 self.frameworks.iter()
202 }
203
204 type LibsIter = std::slice::Iter<'a, String>;
205
206 fn libs(&'a self) -> Self::LibsIter {
207 self.libs.iter()
208 }
209
210 type LdArgsIter = std::iter::Map<
211 std::slice::Iter<'a, Vec<String>>,
212 fn(&'a Vec<String>) -> std::slice::Iter<'a, String>,
213 >;
214
215 fn ld_args(&'a self) -> Self::LdArgsIter {
216 self.ld_args.iter().map(vec_iter)
217 }
218
219 type DefinesIter = std::collections::hash_map::Iter<'a, String, Option<String>>;
220
221 fn defines(&'a self) -> Self::DefinesIter {
222 self.defines.iter()
223 }
224}
225
226#[cfg(feature = "cc")]
227impl MergeCcArgs for cc::Build {
228 fn merge_cc_args<'a, P1, P2, P3, S1, S2, S3, S4, S5, I1, A>(mut self, lib: &'a A) -> Self
229 where
230 P1: AsRef<Path> + 'a,
231 P2: AsRef<Path> + 'a,
232 P3: AsRef<Path> + 'a,
233 S1: AsRef<str> + 'a,
234 S2: AsRef<str> + 'a,
235 S3: AsRef<str> + 'a,
236 S4: AsRef<str> + 'a,
237 S5: AsRef<str> + 'a,
238 I1: Iterator<Item = S3> + 'a,
239 A: CcArgs<'a, P1, P2, P3, S1, S2, S3, S4, S5, I1>,
240 {
241 for (name, value) in lib.defines() {
242 let value = value.as_ref();
243 self.define(name.as_ref(), value.map(|x| x.as_ref()));
244 }
245
246 for path in lib.include_paths() {
247 self.include(path);
248 }
249
250 for arg in lib
251 .link_paths_args()
252 .chain(lib.framework_paths_args())
253 .chain(lib.libs_args())
254 .chain(lib.frameworks_args())
255 .chain(lib.ld_args_args())
256 {
257 self.flag(&arg);
258 }
259
260 self
261 }
262}