]> git.proxmox.com Git - cargo.git/blob - tests/testsuite/plugins.rs
Auto merge of #6335 - Metaswitch:cli-in-library, r=dwijnand
[cargo.git] / tests / testsuite / plugins.rs
1 use support::{basic_manifest, project};
2 use support::{is_nightly, rustc_host};
3
4 #[test]
5 fn plugin_to_the_max() {
6 if !is_nightly() {
7 return;
8 }
9
10 let foo = project()
11 .file(
12 "Cargo.toml",
13 r#"
14 [package]
15 name = "foo"
16 version = "0.0.1"
17 authors = []
18
19 [lib]
20 name = "foo_lib"
21
22 [dependencies.bar]
23 path = "../bar"
24 "#,
25 ).file(
26 "src/main.rs",
27 r#"
28 #![feature(plugin)]
29 #![plugin(bar)]
30 extern crate foo_lib;
31
32 fn main() { foo_lib::foo(); }
33 "#,
34 ).file(
35 "src/foo_lib.rs",
36 r#"
37 #![feature(plugin)]
38 #![plugin(bar)]
39
40 pub fn foo() {}
41 "#,
42 ).build();
43 let _bar = project()
44 .at("bar")
45 .file(
46 "Cargo.toml",
47 r#"
48 [package]
49 name = "bar"
50 version = "0.0.1"
51 authors = []
52
53 [lib]
54 name = "bar"
55 plugin = true
56
57 [dependencies.baz]
58 path = "../baz"
59 "#,
60 ).file(
61 "src/lib.rs",
62 r#"
63 #![feature(plugin_registrar, rustc_private)]
64
65 extern crate rustc_plugin;
66 extern crate baz;
67
68 use rustc_plugin::Registry;
69
70 #[plugin_registrar]
71 pub fn foo(_reg: &mut Registry) {
72 println!("{}", baz::baz());
73 }
74 "#,
75 ).build();
76 let _baz = project()
77 .at("baz")
78 .file(
79 "Cargo.toml",
80 r#"
81 [package]
82 name = "baz"
83 version = "0.0.1"
84 authors = []
85
86 [lib]
87 name = "baz"
88 crate_type = ["dylib"]
89 "#,
90 ).file("src/lib.rs", "pub fn baz() -> i32 { 1 }")
91 .build();
92
93 foo.cargo("build").run();
94 foo.cargo("doc").run();
95 }
96
97 #[test]
98 fn plugin_with_dynamic_native_dependency() {
99 if !is_nightly() {
100 return;
101 }
102
103 let build = project()
104 .at("builder")
105 .file(
106 "Cargo.toml",
107 r#"
108 [package]
109 name = "builder"
110 version = "0.0.1"
111 authors = []
112
113 [lib]
114 name = "builder"
115 crate-type = ["dylib"]
116 "#,
117 ).file("src/lib.rs", "#[no_mangle] pub extern fn foo() {}")
118 .build();
119
120 let foo = project()
121 .file(
122 "Cargo.toml",
123 r#"
124 [package]
125 name = "foo"
126 version = "0.0.1"
127 authors = []
128
129 [dependencies.bar]
130 path = "bar"
131 "#,
132 ).file(
133 "src/main.rs",
134 r#"
135 #![feature(plugin)]
136 #![plugin(bar)]
137
138 fn main() {}
139 "#,
140 ).file(
141 "bar/Cargo.toml",
142 r#"
143 [package]
144 name = "bar"
145 version = "0.0.1"
146 authors = []
147 build = 'build.rs'
148
149 [lib]
150 name = "bar"
151 plugin = true
152 "#,
153 ).file(
154 "bar/build.rs",
155 r#"
156 use std::env;
157 use std::fs;
158 use std::path::PathBuf;
159
160 fn main() {
161 let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap());
162 let root = PathBuf::from(env::var("BUILDER_ROOT").unwrap());
163 let file = format!("{}builder{}",
164 env::consts::DLL_PREFIX,
165 env::consts::DLL_SUFFIX);
166 let src = root.join(&file);
167 let dst = out_dir.join(&file);
168 fs::copy(src, dst).unwrap();
169 if cfg!(windows) {
170 fs::copy(root.join("builder.dll.lib"),
171 out_dir.join("builder.dll.lib")).unwrap();
172 }
173 println!("cargo:rustc-flags=-L {}", out_dir.display());
174 }
175 "#,
176 ).file(
177 "bar/src/lib.rs",
178 r#"
179 #![feature(plugin_registrar, rustc_private)]
180 extern crate rustc_plugin;
181
182 use rustc_plugin::Registry;
183
184 #[cfg_attr(not(target_env = "msvc"), link(name = "builder"))]
185 #[cfg_attr(target_env = "msvc", link(name = "builder.dll"))]
186 extern { fn foo(); }
187
188 #[plugin_registrar]
189 pub fn bar(_reg: &mut Registry) {
190 unsafe { foo() }
191 }
192 "#,
193 ).build();
194
195 build.cargo("build").run();
196
197 let root = build.root().join("target").join("debug");
198 foo.cargo("build -v").env("BUILDER_ROOT", root).run();
199 }
200
201 #[test]
202 fn plugin_integration() {
203 let p = project()
204 .file(
205 "Cargo.toml",
206 r#"
207 [package]
208 name = "foo"
209 version = "0.0.1"
210 authors = []
211 build = "build.rs"
212
213 [lib]
214 name = "foo"
215 plugin = true
216 doctest = false
217 "#,
218 ).file("build.rs", "fn main() {}")
219 .file("src/lib.rs", "")
220 .file("tests/it_works.rs", "")
221 .build();
222
223 p.cargo("test -v").run();
224 }
225
226 #[test]
227 fn doctest_a_plugin() {
228 let p = project()
229 .file(
230 "Cargo.toml",
231 r#"
232 [package]
233 name = "foo"
234 version = "0.0.1"
235 authors = []
236
237 [dependencies]
238 bar = { path = "bar" }
239 "#,
240 ).file("src/lib.rs", "#[macro_use] extern crate bar;")
241 .file(
242 "bar/Cargo.toml",
243 r#"
244 [package]
245 name = "bar"
246 version = "0.0.1"
247 authors = []
248
249 [lib]
250 name = "bar"
251 plugin = true
252 "#,
253 ).file("bar/src/lib.rs", "pub fn bar() {}")
254 .build();
255
256 p.cargo("test -v").run();
257 }
258
259 // See #1515
260 #[test]
261 fn native_plugin_dependency_with_custom_ar_linker() {
262 let target = rustc_host();
263
264 let _foo = project()
265 .file(
266 "Cargo.toml",
267 r#"
268 [package]
269 name = "foo"
270 version = "0.0.1"
271 authors = []
272
273 [lib]
274 plugin = true
275 "#,
276 ).file("src/lib.rs", "")
277 .build();
278
279 let bar = project()
280 .at("bar")
281 .file(
282 "Cargo.toml",
283 r#"
284 [package]
285 name = "bar"
286 version = "0.0.1"
287 authors = []
288
289 [dependencies.foo]
290 path = "../foo"
291 "#,
292 ).file("src/lib.rs", "")
293 .file(
294 ".cargo/config",
295 &format!(
296 r#"
297 [target.{}]
298 ar = "nonexistent-ar"
299 linker = "nonexistent-linker"
300 "#,
301 target
302 ),
303 ).build();
304
305 bar.cargo("build --verbose")
306 .with_status(101)
307 .with_stderr_contains(
308 "\
309 [COMPILING] foo v0.0.1 ([..])
310 [RUNNING] `rustc [..] -C ar=nonexistent-ar -C linker=nonexistent-linker [..]`
311 [ERROR] [..]linker[..]
312 ",
313 ).run();
314 }
315
316 #[test]
317 fn panic_abort_plugins() {
318 if !is_nightly() {
319 return;
320 }
321
322 let p = project()
323 .file(
324 "Cargo.toml",
325 r#"
326 [package]
327 name = "foo"
328 version = "0.0.1"
329 authors = []
330
331 [profile.dev]
332 panic = 'abort'
333
334 [dependencies]
335 bar = { path = "bar" }
336 "#,
337 ).file("src/lib.rs", "")
338 .file(
339 "bar/Cargo.toml",
340 r#"
341 [package]
342 name = "bar"
343 version = "0.0.1"
344 authors = []
345
346 [lib]
347 plugin = true
348 "#,
349 ).file(
350 "bar/src/lib.rs",
351 r#"
352 #![feature(rustc_private)]
353 extern crate syntax;
354 "#,
355 ).build();
356
357 p.cargo("build").run();
358 }
359
360 #[test]
361 fn shared_panic_abort_plugins() {
362 if !is_nightly() {
363 return;
364 }
365
366 let p = project()
367 .file(
368 "Cargo.toml",
369 r#"
370 [package]
371 name = "foo"
372 version = "0.0.1"
373 authors = []
374
375 [profile.dev]
376 panic = 'abort'
377
378 [dependencies]
379 bar = { path = "bar" }
380 baz = { path = "baz" }
381 "#,
382 ).file("src/lib.rs", "extern crate baz;")
383 .file(
384 "bar/Cargo.toml",
385 r#"
386 [package]
387 name = "bar"
388 version = "0.0.1"
389 authors = []
390
391 [lib]
392 plugin = true
393
394 [dependencies]
395 baz = { path = "../baz" }
396 "#,
397 ).file(
398 "bar/src/lib.rs",
399 r#"
400 #![feature(rustc_private)]
401 extern crate syntax;
402 extern crate baz;
403 "#,
404 ).file("baz/Cargo.toml", &basic_manifest("baz", "0.0.1"))
405 .file("baz/src/lib.rs", "")
406 .build();
407
408 p.cargo("build").run();
409 }