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