]> git.proxmox.com Git - cargo.git/blame - tests/testsuite/profile_overrides.rs
Fix BuildScriptOutput when a build script is run multiple times.
[cargo.git] / tests / testsuite / profile_overrides.rs
CommitLineData
83571aee
EH
1//! Tests for profile overrides (build-override and per-package overrides).
2
9115b2c3
AC
3use cargo_test_support::registry::Package;
4use cargo_test_support::{basic_lib_manifest, basic_manifest, project};
9ca36de4 5
0e0d9688 6#[cargo_test]
9ca36de4 7fn profile_override_basic() {
7fe2fbc8 8 let p = project()
9ca36de4
EH
9 .file(
10 "Cargo.toml",
11 r#"
9ca36de4
EH
12 [package]
13 name = "foo"
14 version = "0.0.1"
15 authors = []
16
17 [dependencies]
18 bar = {path = "bar"}
19
20 [profile.dev]
21 opt-level = 1
22
fcfe0b89 23 [profile.dev.package.bar]
9ca36de4
EH
24 opt-level = 3
25 "#,
fecb7246
AC
26 )
27 .file("src/lib.rs", "")
9ca36de4
EH
28 .file("bar/Cargo.toml", &basic_lib_manifest("bar"))
29 .file("bar/src/lib.rs", "")
30 .build();
31
85984a87 32 p.cargo("build -v")
85984a87 33 .with_stderr(
9ca36de4
EH
34 "[COMPILING] bar [..]
35[RUNNING] `rustc --crate-name bar [..] -C opt-level=3 [..]`
36[COMPILING] foo [..]
37[RUNNING] `rustc --crate-name foo [..] -C opt-level=1 [..]`
38[FINISHED] dev [optimized + debuginfo] target(s) in [..]",
fecb7246
AC
39 )
40 .run();
9ca36de4
EH
41}
42
0e0d9688 43#[cargo_test]
5415a341 44fn profile_override_warnings() {
7fe2fbc8 45 let p = project()
9ca36de4
EH
46 .file(
47 "Cargo.toml",
48 r#"
9ca36de4
EH
49 [package]
50 name = "foo"
51 version = "0.0.1"
52
53 [dependencies]
54 bar = {path = "bar"}
55
fcfe0b89 56 [profile.dev.package.bart]
9ca36de4
EH
57 opt-level = 3
58
fcfe0b89 59 [profile.dev.package.no-suggestion]
9ca36de4 60 opt-level = 3
5415a341 61
fcfe0b89 62 [profile.dev.package."bar:1.2.3"]
5415a341 63 opt-level = 3
9ca36de4 64 "#,
fecb7246
AC
65 )
66 .file("src/lib.rs", "")
9ca36de4
EH
67 .file("bar/Cargo.toml", &basic_lib_manifest("bar"))
68 .file("bar/src/lib.rs", "")
69 .build();
70
77ee608d
EH
71 p.cargo("build")
72 .with_stderr_contains(
9ca36de4 73 "\
77ee608d
EH
74[WARNING] profile package spec `bar:1.2.3` in profile `dev` \
75 has a version or URL that does not match any of the packages: \
76 bar v0.5.0 ([..]/foo/bar)
77[WARNING] profile package spec `bart` in profile `dev` did not match any packages
9ca36de4 78
7d7fe679 79<tab>Did you mean `bar`?
77ee608d 80[WARNING] profile package spec `no-suggestion` in profile `dev` did not match any packages
9ca36de4
EH
81[COMPILING] [..]
82",
85984a87
DW
83 )
84 .run();
9ca36de4
EH
85}
86
0e0d9688 87#[cargo_test]
9ca36de4
EH
88fn profile_override_bad_settings() {
89 let bad_values = [
90 (
91 "panic = \"abort\"",
fcfe0b89 92 "`panic` may not be specified in a `package` profile",
9ca36de4
EH
93 ),
94 (
95 "lto = true",
fcfe0b89 96 "`lto` may not be specified in a `package` profile",
9ca36de4
EH
97 ),
98 (
99 "rpath = true",
fcfe0b89
EH
100 "`rpath` may not be specified in a `package` profile",
101 ),
77ee608d 102 ("package = {}", "package-specific profiles cannot be nested"),
9ca36de4 103 ];
ef0b4776 104 for &(snippet, expected) in bad_values.iter() {
7fe2fbc8 105 let p = project()
9ca36de4
EH
106 .file(
107 "Cargo.toml",
108 &format!(
109 r#"
9ca36de4
EH
110 [package]
111 name = "foo"
112 version = "0.0.1"
113
114 [dependencies]
115 bar = {{path = "bar"}}
116
fcfe0b89 117 [profile.dev.package.bar]
9ca36de4
EH
118 {}
119 "#,
120 snippet
121 ),
fecb7246
AC
122 )
123 .file("src/lib.rs", "")
9ca36de4
EH
124 .file("bar/Cargo.toml", &basic_lib_manifest("bar"))
125 .file("bar/src/lib.rs", "")
126 .build();
127
85984a87 128 p.cargo("build")
85984a87
DW
129 .with_status(101)
130 .with_stderr_contains(format!("Caused by:\n {}", expected))
131 .run();
9ca36de4
EH
132 }
133}
b9181ef3 134
0e0d9688 135#[cargo_test]
b9181ef3
EH
136fn profile_override_hierarchy() {
137 // Test that the precedence rules are correct for different types.
7fe2fbc8 138 let p = project()
b9181ef3
EH
139 .file(
140 "Cargo.toml",
141 r#"
b9181ef3
EH
142 [workspace]
143 members = ["m1", "m2", "m3"]
144
145 [profile.dev]
146 codegen-units = 1
147
fcfe0b89 148 [profile.dev.package.m2]
b9181ef3
EH
149 codegen-units = 2
150
fcfe0b89 151 [profile.dev.package."*"]
b9181ef3
EH
152 codegen-units = 3
153
154 [profile.dev.build-override]
155 codegen-units = 4
fecb7246
AC
156 "#,
157 )
b9181ef3 158 // m1
fecb7246
AC
159 .file(
160 "m1/Cargo.toml",
b9181ef3
EH
161 r#"
162 [package]
163 name = "m1"
164 version = "0.0.1"
165
166 [dependencies]
167 m2 = { path = "../m2" }
168 dep = { path = "../../dep" }
fecb7246
AC
169 "#,
170 )
ca7d9ee2
DW
171 .file("m1/src/lib.rs", "extern crate m2; extern crate dep;")
172 .file("m1/build.rs", "fn main() {}")
b9181ef3 173 // m2
fecb7246
AC
174 .file(
175 "m2/Cargo.toml",
b9181ef3
EH
176 r#"
177 [package]
178 name = "m2"
179 version = "0.0.1"
180
181 [dependencies]
182 m3 = { path = "../m3" }
183
184 [build-dependencies]
185 m3 = { path = "../m3" }
186 dep = { path = "../../dep" }
fecb7246
AC
187 "#,
188 )
ca7d9ee2 189 .file("m2/src/lib.rs", "extern crate m3;")
fecb7246
AC
190 .file(
191 "m2/build.rs",
192 "extern crate m3; extern crate dep; fn main() {}",
193 )
b9181ef3
EH
194 // m3
195 .file("m3/Cargo.toml", &basic_lib_manifest("m3"))
196 .file("m3/src/lib.rs", "")
197 .build();
198
199 // dep (outside of workspace)
85984a87
DW
200 let _dep = project()
201 .at("dep")
b9181ef3
EH
202 .file("Cargo.toml", &basic_lib_manifest("dep"))
203 .file("src/lib.rs", "")
204 .build();
205
206 // Profiles should be:
207 // m3: 4 (as build.rs dependency)
208 // m3: 1 (as [profile.dev] as workspace member)
fcfe0b89 209 // dep: 3 (as [profile.dev.package."*"] as non-workspace member)
b9181ef3 210 // m1 build.rs: 4 (as [profile.dev.build-override])
fcfe0b89
EH
211 // m2 build.rs: 2 (as [profile.dev.package.m2])
212 // m2: 2 (as [profile.dev.package.m2])
b9181ef3
EH
213 // m1: 1 (as [profile.dev])
214
dda81d31 215 p.cargo("build -v").with_stderr_unordered("\
b9181ef3
EH
216[COMPILING] m3 [..]
217[COMPILING] dep [..]
daa1bce2
AC
218[RUNNING] `rustc --crate-name m3 m3/src/lib.rs [..] --crate-type lib --emit=[..]link -C codegen-units=4 [..]
219[RUNNING] `rustc --crate-name dep [..]dep/src/lib.rs [..] --crate-type lib --emit=[..]link -C codegen-units=3 [..]
220[RUNNING] `rustc --crate-name m3 m3/src/lib.rs [..] --crate-type lib --emit=[..]link -C codegen-units=1 [..]
221[RUNNING] `rustc --crate-name build_script_build m1/build.rs [..] --crate-type bin --emit=[..]link -C codegen-units=4 [..]
b9181ef3 222[COMPILING] m2 [..]
daa1bce2 223[RUNNING] `rustc --crate-name build_script_build m2/build.rs [..] --crate-type bin --emit=[..]link -C codegen-units=2 [..]
05400b80
DW
224[RUNNING] `[..]/m1-[..]/build-script-build`
225[RUNNING] `[..]/m2-[..]/build-script-build`
daa1bce2 226[RUNNING] `rustc --crate-name m2 m2/src/lib.rs [..] --crate-type lib --emit=[..]link -C codegen-units=2 [..]
b9181ef3 227[COMPILING] m1 [..]
daa1bce2 228[RUNNING] `rustc --crate-name m1 m1/src/lib.rs [..] --crate-type lib --emit=[..]link -C codegen-units=1 [..]
b9181ef3
EH
229[FINISHED] dev [unoptimized + debuginfo] [..]
230",
85984a87
DW
231 )
232 .run();
b9181ef3 233}
5415a341 234
0e0d9688 235#[cargo_test]
5415a341 236fn profile_override_spec_multiple() {
7fe2fbc8 237 let p = project()
5415a341
EH
238 .file(
239 "Cargo.toml",
240 r#"
5415a341
EH
241 [package]
242 name = "foo"
243 version = "0.0.1"
244
245 [dependencies]
246 bar = { path = "bar" }
247
fcfe0b89 248 [profile.dev.package.bar]
5415a341
EH
249 opt-level = 3
250
fcfe0b89 251 [profile.dev.package."bar:0.5.0"]
5415a341
EH
252 opt-level = 3
253 "#,
fecb7246
AC
254 )
255 .file("src/lib.rs", "")
5415a341
EH
256 .file("bar/Cargo.toml", &basic_lib_manifest("bar"))
257 .file("bar/src/lib.rs", "")
258 .build();
259
85984a87 260 p.cargo("build -v")
85984a87
DW
261 .with_status(101)
262 .with_stderr_contains(
5415a341 263 "\
fcfe0b89
EH
264[ERROR] multiple package overrides in profile `dev` match package `bar v0.5.0 ([..])`
265found package specs: bar, bar:0.5.0",
fecb7246
AC
266 )
267 .run();
5415a341
EH
268}
269
0e0d9688 270#[cargo_test]
5415a341 271fn profile_override_spec() {
7fe2fbc8 272 let p = project()
5415a341
EH
273 .file(
274 "Cargo.toml",
275 r#"
5415a341
EH
276 [workspace]
277 members = ["m1", "m2"]
278
fcfe0b89 279 [profile.dev.package."dep:1.0.0"]
5415a341
EH
280 codegen-units = 1
281
fcfe0b89 282 [profile.dev.package."dep:2.0.0"]
5415a341 283 codegen-units = 2
fecb7246
AC
284 "#,
285 )
5415a341 286 // m1
fecb7246
AC
287 .file(
288 "m1/Cargo.toml",
5415a341
EH
289 r#"
290 [package]
291 name = "m1"
292 version = "0.0.1"
293
294 [dependencies]
295 dep = { path = "../../dep1" }
fecb7246
AC
296 "#,
297 )
ca7d9ee2 298 .file("m1/src/lib.rs", "extern crate dep;")
5415a341 299 // m2
fecb7246
AC
300 .file(
301 "m2/Cargo.toml",
5415a341
EH
302 r#"
303 [package]
304 name = "m2"
305 version = "0.0.1"
306
307 [dependencies]
308 dep = {path = "../../dep2" }
fecb7246
AC
309 "#,
310 )
ca7d9ee2 311 .file("m2/src/lib.rs", "extern crate dep;")
5415a341
EH
312 .build();
313
85984a87
DW
314 project()
315 .at("dep1")
ab19c483 316 .file("Cargo.toml", &basic_manifest("dep", "1.0.0"))
5415a341
EH
317 .file("src/lib.rs", "")
318 .build();
319
85984a87
DW
320 project()
321 .at("dep2")
ab19c483 322 .file("Cargo.toml", &basic_manifest("dep", "2.0.0"))
5415a341
EH
323 .file("src/lib.rs", "")
324 .build();
325
85984a87 326 p.cargo("build -v")
85984a87
DW
327 .with_stderr_contains("[RUNNING] `rustc [..]dep1/src/lib.rs [..] -C codegen-units=1 [..]")
328 .with_stderr_contains("[RUNNING] `rustc [..]dep2/src/lib.rs [..] -C codegen-units=2 [..]")
329 .run();
5415a341 330}
3cf913ef 331
0e0d9688 332#[cargo_test]
3cf913ef
EH
333fn override_proc_macro() {
334 Package::new("shared", "1.0.0").publish();
335 let p = project()
336 .file(
337 "Cargo.toml",
338 r#"
3cf913ef
EH
339 [package]
340 name = "foo"
341 version = "0.1.0"
342 edition = "2018"
343
344 [dependencies]
345 shared = "1.0"
346 pm = {path = "pm"}
347
348 [profile.dev.build-override]
349 codegen-units = 4
350 "#,
351 )
352 .file("src/lib.rs", r#"pm::eat!{}"#)
353 .file(
354 "pm/Cargo.toml",
355 r#"
356 [package]
357 name = "pm"
358 version = "0.1.0"
359
360 [lib]
361 proc-macro = true
362
363 [dependencies]
364 shared = "1.0"
365 "#,
366 )
367 .file(
368 "pm/src/lib.rs",
369 r#"
370 extern crate proc_macro;
371 use proc_macro::TokenStream;
372
373 #[proc_macro]
374 pub fn eat(_item: TokenStream) -> TokenStream {
375 "".parse().unwrap()
376 }
377 "#,
378 )
379 .build();
380
381 p.cargo("build -v")
3cf913ef
EH
382 // Shared built for the proc-macro.
383 .with_stderr_contains("[RUNNING] `rustc [..]--crate-name shared [..]-C codegen-units=4[..]")
384 // Shared built for the library.
385 .with_stderr_line_without(
386 &["[RUNNING] `rustc --crate-name shared"],
387 &["-C codegen-units"],
388 )
389 .with_stderr_contains("[RUNNING] `rustc [..]--crate-name pm [..]-C codegen-units=4[..]")
390 .with_stderr_line_without(
391 &["[RUNNING] `rustc [..]--crate-name foo"],
392 &["-C codegen-units"],
393 )
394 .run();
395}
fcfe0b89 396
12392f6d
EH
397#[cargo_test]
398fn no_warning_ws() {
399 // https://github.com/rust-lang/cargo/issues/7378, avoid warnings in a workspace.
400 let p = project()
401 .file(
402 "Cargo.toml",
403 r#"
12392f6d
EH
404 [workspace]
405 members = ["a", "b"]
406
407 [profile.dev.package.a]
408 codegen-units = 3
409 "#,
410 )
411 .file("a/Cargo.toml", &basic_manifest("a", "0.1.0"))
412 .file("a/src/lib.rs", "")
413 .file("b/Cargo.toml", &basic_manifest("b", "0.1.0"))
414 .file("b/src/lib.rs", "")
415 .build();
416
417 p.cargo("build -p b")
12392f6d
EH
418 .with_stderr(
419 "\
420[COMPILING] b [..]
421[FINISHED] [..]
422",
423 )
424 .run();
425}
2296af27
EH
426
427#[cargo_test]
428fn build_override_shared() {
429 // A dependency with a build script that is shared with a build
430 // dependency, using different profile settings. That is:
431 //
432 // foo DEBUG=2
433 // ├── common DEBUG=2
434 // │ └── common Run build.rs DEBUG=2
435 // │ └── common build.rs DEBUG=0 (build_override)
436 // └── foo Run build.rs DEBUG=2
437 // └── foo build.rs DEBUG=0 (build_override)
438 // └── common DEBUG=0 (build_override)
439 // └── common Run build.rs DEBUG=0 (build_override)
440 // └── common build.rs DEBUG=0 (build_override)
441 //
442 // The key part here is that `common` RunCustomBuild is run twice, once
443 // with DEBUG=2 (as a dependency of foo) and once with DEBUG=0 (as a
444 // build-dependency of foo's build script).
445 Package::new("common", "1.0.0")
446 .file(
447 "build.rs",
448 r#"
449 fn main() {
450 if std::env::var("DEBUG").unwrap() != "false" {
451 println!("cargo:rustc-cfg=foo_debug");
452 } else {
453 println!("cargo:rustc-cfg=foo_release");
454 }
455 }
456 "#,
457 )
458 .file(
459 "src/lib.rs",
460 r#"
461 pub fn foo() -> u32 {
462 if cfg!(foo_debug) {
463 assert!(cfg!(debug_assertions));
464 1
465 } else if cfg!(foo_release) {
466 assert!(!cfg!(debug_assertions));
467 2
468 } else {
469 panic!("not set");
470 }
471 }
472 "#,
473 )
474 .publish();
475
476 let p = project()
477 .file(
478 "Cargo.toml",
479 r#"
480 [package]
481 name = "foo"
482 version = "0.1.0"
483 edition = "2018"
484
485 [build-dependencies]
486 common = "1.0"
487
488 [dependencies]
489 common = "1.0"
490
491 [profile.dev.build-override]
492 debug = 0
493 debug-assertions = false
494 "#,
495 )
496 .file(
497 "build.rs",
498 r#"
499 fn main() {
500 assert_eq!(common::foo(), 2);
501 }
502 "#,
503 )
504 .file(
505 "src/main.rs",
506 r#"
507 fn main() {
508 assert_eq!(common::foo(), 1);
509 }
510 "#,
511 )
512 .build();
513
514 p.cargo("run").run();
515}