@@ -52,7 +52,8 @@ use std::sync::{Arc, Mutex};
52
52
/// build script has finished running. Read [the doc] for more.
53
53
///
54
54
/// [the doc]: https://doc.rust-lang.org/nightly/cargo/reference/build-scripts.html#cargo-warning
55
- const CARGO_WARNING : & str = "cargo:warning=" ;
55
+ const OLD_CARGO_WARNING_SYNTAX : & str = "cargo:warning=" ;
56
+ const NEW_CARGO_WARNING_SYNTAX : & str = "cargo::warning=" ;
56
57
57
58
/// Contains the parsed output of a custom build script.
58
59
#[ derive( Clone , Debug , Hash , Default ) ]
@@ -435,7 +436,10 @@ fn build_work(cx: &mut Context<'_, '_>, unit: &Unit) -> CargoResult<Job> {
435
436
let output = cmd
436
437
. exec_with_streaming (
437
438
& mut |stdout| {
438
- if let Some ( warning) = stdout. strip_prefix ( CARGO_WARNING ) {
439
+ if let Some ( warning) = stdout
440
+ . strip_prefix ( OLD_CARGO_WARNING_SYNTAX )
441
+ . or ( stdout. strip_prefix ( NEW_CARGO_WARNING_SYNTAX ) )
442
+ {
439
443
warnings_in_case_of_panic. push ( warning. to_owned ( ) ) ;
440
444
}
441
445
if extra_verbose {
@@ -643,28 +647,93 @@ impl BuildOutput {
643
647
Ok ( line) => line. trim ( ) ,
644
648
Err ( ..) => continue ,
645
649
} ;
646
- let mut iter = line. splitn ( 2 , ':' ) ;
650
+ let mut new_syntax = true ;
651
+ let mut iter = line. splitn ( 2 , "::" ) ;
647
652
if iter. next ( ) != Some ( "cargo" ) {
648
- // skip this line since it doesn't start with "cargo:"
649
- continue ;
653
+ // For backwards compatibility, we also accept lines that start with "cargo:".
654
+ new_syntax = false ;
655
+ iter = line. splitn ( 2 , ":" ) ;
656
+ if iter. next ( ) != Some ( "cargo" ) {
657
+ // skip this line since it doesn't start with "cargo:" or "cargo::".
658
+ continue ;
659
+ }
650
660
}
651
661
let data = match iter. next ( ) {
652
662
Some ( val) => val,
653
663
None => continue ,
654
664
} ;
655
665
656
- // getting the `key=value` part of the line
657
- let mut iter = data. splitn ( 2 , '=' ) ;
658
- let key = iter. next ( ) ;
659
- let value = iter. next ( ) ;
660
- let ( key, value) = match ( key, value) {
661
- ( Some ( a) , Some ( b) ) => ( a, b. trim_end ( ) ) ,
662
- // Line started with `cargo:` but didn't match `key=value`.
663
- _ => bail ! ( "invalid output in {}: `{}`\n \
664
- Expected a line with `cargo:key=value` with an `=` character, \
665
- but none was found.\n \
666
- See https://doc.rust-lang.org/cargo/reference/build-scripts.html#outputs-of-the-build-script \
667
- for more information about build script outputs.", whence, line) ,
666
+ // Old syntax:
667
+ // cargo:rustc-flags=VALUE
668
+ // cargo:KEY=VALUE (for other unreserved keys)
669
+ // New syntax:
670
+ // cargo::rustc-flags=VALUE
671
+ // cargo::metadata=KEY=VALUE (for other unreserved keys)
672
+ const RESERVED_KEYS : & [ & str ] = & [
673
+ "rustc-flags" ,
674
+ "rustc-link-lib" ,
675
+ "rustc-link-search" ,
676
+ "rustc-link-arg-cdylib" ,
677
+ "rustc-link-arg-bins" ,
678
+ "rustc-link-arg-bin" ,
679
+ "rustc-link-arg-tests" ,
680
+ "rustc-link-arg-benches" ,
681
+ "rustc-link-arg-examples" ,
682
+ "rustc-link-arg" ,
683
+ "rustc-cfg" ,
684
+ "rustc-check-cfg" ,
685
+ "rustc-env" ,
686
+ "warning" ,
687
+ "rerun-if-changed" ,
688
+ "rerun-if-env-changed" ,
689
+ ] ;
690
+ const DOCS_LINK_SUGGESTION : & str = "See https://doc.rust-lang.org/cargo/reference/build-scripts.html#outputs-of-the-build-script \
691
+ for more information about build script outputs.";
692
+ let mut iter = data. splitn ( 3 , '=' ) ;
693
+ let part1 = iter. next ( ) ;
694
+ let part2 = iter. next ( ) ;
695
+ let part3 = iter. next ( ) ;
696
+ let ( key, value) = match ( part1, part2, part3) {
697
+ // For instance, `cargo::metadata=foo=bar`.
698
+ ( Some ( "metadata" ) , Some ( a) , Some ( b) ) => {
699
+ // `cargo::metadata=` should only be used with the new syntax.
700
+ if !new_syntax {
701
+ bail ! ( "invalid output in {}: `{}`\n \
702
+ Expected a line with `cargo::KEY=VALUE`, but found `cargo:metadata=KEY=VALUE`.\n \
703
+ {}", whence, line, DOCS_LINK_SUGGESTION
704
+ )
705
+ }
706
+ // Reserved keys should not be used with the `cargo::metadata` syntax.
707
+ if new_syntax && RESERVED_KEYS . contains ( & a) {
708
+ bail ! ( "invalid output in {}: `{}`\n \
709
+ The reserved key `{}` cannot be used in a `cargo::metadata` line. Please use `cargo::{}=VAlUE` instead.\n \
710
+ {}", whence, line, a, a, DOCS_LINK_SUGGESTION
711
+ )
712
+ }
713
+ ( a, b. trim_end ( ) . to_owned ( ) )
714
+ }
715
+ // For instance, `cargo::warning=foo` or `cargo:warning=foo`.
716
+ ( Some ( a) , Some ( b) , None ) => {
717
+ // Only reserved keys should be used with the `cargo::` syntax.
718
+ // Otherwise, it should be `cargo::metadata=KEY=VALUE`.
719
+ if new_syntax && !RESERVED_KEYS . contains ( & a) {
720
+ bail ! ( "invalid output in {}: `{}`\n \
721
+ Expected a line with `cargo::metadata=KEY=VALUE` but it did not have the `metadata=` part.\n \
722
+ {}", whence, line, DOCS_LINK_SUGGESTION
723
+ )
724
+ }
725
+ ( a, b. trim_end ( ) . to_owned ( ) )
726
+ }
727
+ // For instance, `cargo:rustc-link-search=[KIND=]PATH` or `cargo::rustc-link-search=[KIND=]PATH`.
728
+ ( Some ( a) , Some ( b) , Some ( c) ) => ( a, format ! ( "{}={}" , b, c) . trim_end ( ) . to_owned ( ) ) ,
729
+ // Line started with `cargo:` or `cargo::` but didn't match any of the above.
730
+ _ => bail ! (
731
+ "invalid output in {}: `{}`\n \
732
+ {}",
733
+ whence,
734
+ line,
735
+ DOCS_LINK_SUGGESTION
736
+ ) ,
668
737
} ;
669
738
670
739
// This will rewrite paths if the target directory has been moved.
0 commit comments