/tests/testsuite/plugins.rs

https://gitlab.com/frewsxcv/cargo · Rust · 439 lines · 410 code · 23 blank · 6 comment · 4 complexity · 8d3fac71804ed1c110aa084fc8a775ea MD5 · raw file

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