@@ -50,6 +50,11 @@ use std::path::{Path, PathBuf};
50
50
use std:: str:: { self , FromStr } ;
51
51
use std:: sync:: { Arc , Mutex } ;
52
52
53
+ /// A build script instruction that tells Cargo to display an error after the
54
+ /// build script has finished running. Read [the doc] for more.
55
+ ///
56
+ /// [the doc]: https://doc.rust-lang.org/nightly/cargo/reference/build-scripts.html#cargo-error
57
+ const CARGO_ERROR_SYNTAX : & str = "cargo::error=" ;
53
58
/// Deprecated: A build script instruction that tells Cargo to display a warning after the
54
59
/// build script has finished running. Read [the doc] for more.
55
60
///
@@ -60,6 +65,15 @@ const OLD_CARGO_WARNING_SYNTAX: &str = "cargo:warning=";
60
65
///
61
66
/// [the doc]: https://doc.rust-lang.org/nightly/cargo/reference/build-scripts.html#cargo-warning
62
67
const NEW_CARGO_WARNING_SYNTAX : & str = "cargo::warning=" ;
68
+
69
+ #[ derive( Clone , Debug , Hash , PartialEq , Eq , PartialOrd , Ord ) ]
70
+ pub enum Severity {
71
+ Error ,
72
+ Warning ,
73
+ }
74
+
75
+ pub type LogMessage = ( Severity , String ) ;
76
+
63
77
/// Contains the parsed output of a custom build script.
64
78
#[ derive( Clone , Debug , Hash , Default , PartialEq , Eq , PartialOrd , Ord ) ]
65
79
pub struct BuildOutput {
@@ -82,11 +96,13 @@ pub struct BuildOutput {
82
96
pub rerun_if_changed : Vec < PathBuf > ,
83
97
/// Environment variables which, when changed, will cause a rebuild.
84
98
pub rerun_if_env_changed : Vec < String > ,
85
- /// Warnings generated by this build.
99
+ /// Errors and warnings generated by this build.
86
100
///
87
- /// These are only displayed if this is a "local" package, `-vv` is used,
88
- /// or there is a build error for any target in this package.
89
- pub warnings : Vec < String > ,
101
+ /// These are only displayed if this is a "local" package, `-vv` is used, or
102
+ /// there is a build error for any target in this package. Note that any log
103
+ /// message of severity `Error` will by itself cause a build error, and will
104
+ /// cause all log messages to be displayed.
105
+ pub log_messages : Vec < LogMessage > ,
90
106
}
91
107
92
108
/// Map of packages to build script output.
@@ -473,15 +489,18 @@ fn build_work(build_runner: &mut BuildRunner<'_, '_>, unit: &Unit) -> CargoResul
473
489
state. running ( & cmd) ;
474
490
let timestamp = paths:: set_invocation_time ( & script_run_dir) ?;
475
491
let prefix = format ! ( "[{} {}] " , id. name( ) , id. version( ) ) ;
476
- let mut warnings_in_case_of_panic = Vec :: new ( ) ;
492
+ let mut log_messages_in_case_of_panic = Vec :: new ( ) ;
477
493
let output = cmd
478
494
. exec_with_streaming (
479
495
& mut |stdout| {
496
+ if let Some ( error) = stdout. strip_prefix ( CARGO_ERROR_SYNTAX ) {
497
+ log_messages_in_case_of_panic. push ( ( Severity :: Error , error. to_owned ( ) ) ) ;
498
+ }
480
499
if let Some ( warning) = stdout
481
500
. strip_prefix ( OLD_CARGO_WARNING_SYNTAX )
482
501
. or ( stdout. strip_prefix ( NEW_CARGO_WARNING_SYNTAX ) )
483
502
{
484
- warnings_in_case_of_panic . push ( warning. to_owned ( ) ) ;
503
+ log_messages_in_case_of_panic . push ( ( Severity :: Warning , warning. to_owned ( ) ) ) ;
485
504
}
486
505
if extra_verbose {
487
506
state. stdout ( format ! ( "{}{}" , prefix, stdout) ) ?;
@@ -521,15 +540,29 @@ fn build_work(build_runner: &mut BuildRunner<'_, '_>, unit: &Unit) -> CargoResul
521
540
build_error_context
522
541
} ) ;
523
542
543
+ // If the build failed
524
544
if let Err ( error) = output {
525
- insert_warnings_in_build_outputs (
545
+ insert_log_messages_in_build_outputs (
526
546
build_script_outputs,
527
547
id,
528
548
metadata_hash,
529
- warnings_in_case_of_panic ,
549
+ log_messages_in_case_of_panic ,
530
550
) ;
531
551
return Err ( error) ;
532
552
}
553
+ // ... or it logged any errors
554
+ else if log_messages_in_case_of_panic
555
+ . iter ( )
556
+ . any ( |( severity, _) | * severity == Severity :: Error )
557
+ {
558
+ insert_log_messages_in_build_outputs (
559
+ build_script_outputs,
560
+ id,
561
+ metadata_hash,
562
+ log_messages_in_case_of_panic,
563
+ ) ;
564
+ anyhow:: bail!( "build script logged errors" ) ;
565
+ }
533
566
534
567
let output = output. unwrap ( ) ;
535
568
@@ -610,22 +643,23 @@ fn build_work(build_runner: &mut BuildRunner<'_, '_>, unit: &Unit) -> CargoResul
610
643
Ok ( job)
611
644
}
612
645
613
- /// When a build script run fails, store only warnings and nuke other outputs,
614
- /// as they are likely broken.
615
- fn insert_warnings_in_build_outputs (
646
+ /// When a build script run fails, store only log messages, and nuke other
647
+ /// outputs, as they are likely broken.
648
+ fn insert_log_messages_in_build_outputs (
616
649
build_script_outputs : Arc < Mutex < BuildScriptOutputs > > ,
617
650
id : PackageId ,
618
651
metadata_hash : Metadata ,
619
- warnings : Vec < String > ,
652
+ log_messages : Vec < LogMessage > ,
620
653
) {
621
- let build_output_with_only_warnings = BuildOutput {
622
- warnings ,
654
+ let build_output_with_only_log_messages = BuildOutput {
655
+ log_messages ,
623
656
..BuildOutput :: default ( )
624
657
} ;
625
- build_script_outputs
626
- . lock ( )
627
- . unwrap ( )
628
- . insert ( id, metadata_hash, build_output_with_only_warnings) ;
658
+ build_script_outputs. lock ( ) . unwrap ( ) . insert (
659
+ id,
660
+ metadata_hash,
661
+ build_output_with_only_log_messages,
662
+ ) ;
629
663
}
630
664
631
665
impl BuildOutput {
@@ -677,7 +711,7 @@ impl BuildOutput {
677
711
let mut metadata = Vec :: new ( ) ;
678
712
let mut rerun_if_changed = Vec :: new ( ) ;
679
713
let mut rerun_if_env_changed = Vec :: new ( ) ;
680
- let mut warnings = Vec :: new ( ) ;
714
+ let mut log_messages = Vec :: new ( ) ;
681
715
let whence = format ! ( "build script of `{}`" , pkg_descr) ;
682
716
// Old syntax:
683
717
// cargo:rustc-flags=VALUE
@@ -849,15 +883,18 @@ impl BuildOutput {
849
883
"rustc-link-search" => library_paths. push ( PathBuf :: from ( value) ) ,
850
884
"rustc-link-arg-cdylib" | "rustc-cdylib-link-arg" => {
851
885
if !targets. iter ( ) . any ( |target| target. is_cdylib ( ) ) {
852
- warnings. push ( format ! (
853
- "{}{} was specified in the build script of {}, \
886
+ log_messages. push ( (
887
+ Severity :: Warning ,
888
+ format ! (
889
+ "{}{} was specified in the build script of {}, \
854
890
but that package does not contain a cdylib target\n \
855
891
\n \
856
892
Allowing this was an unintended change in the 1.50 \
857
893
release, and may become an error in the future. \
858
894
For more information, see \
859
895
<https://github.com/rust-lang/cargo/issues/9562>.",
860
- syntax_prefix, key, pkg_descr
896
+ syntax_prefix, key, pkg_descr
897
+ ) ,
861
898
) ) ;
862
899
}
863
900
linker_args. push ( ( LinkArgTarget :: Cdylib , value) )
@@ -943,10 +980,10 @@ impl BuildOutput {
943
980
if nightly_features_allowed
944
981
|| rustc_bootstrap_allows ( library_name. as_deref ( ) )
945
982
{
946
- warnings . push ( format ! ( "Cannot set `RUSTC_BOOTSTRAP={}` from {}.\n \
983
+ log_messages . push ( ( Severity :: Warning , format ! ( "Cannot set `RUSTC_BOOTSTRAP={}` from {}.\n \
947
984
note: Crates cannot set `RUSTC_BOOTSTRAP` themselves, as doing so would subvert the stability guarantees of Rust for your project.",
948
985
val, whence
949
- ) ) ;
986
+ ) ) ) ;
950
987
} else {
951
988
// Setting RUSTC_BOOTSTRAP would change the behavior of the crate.
952
989
// Abort with an error.
@@ -962,7 +999,8 @@ impl BuildOutput {
962
999
env. push ( ( key, val) ) ;
963
1000
}
964
1001
}
965
- "warning" => warnings. push ( value. to_string ( ) ) ,
1002
+ "error" => log_messages. push ( ( Severity :: Error , value. to_string ( ) ) ) ,
1003
+ "warning" => log_messages. push ( ( Severity :: Warning , value. to_string ( ) ) ) ,
966
1004
"rerun-if-changed" => rerun_if_changed. push ( PathBuf :: from ( value) ) ,
967
1005
"rerun-if-env-changed" => rerun_if_env_changed. push ( value. to_string ( ) ) ,
968
1006
"metadata" => {
@@ -987,7 +1025,7 @@ impl BuildOutput {
987
1025
metadata,
988
1026
rerun_if_changed,
989
1027
rerun_if_env_changed,
990
- warnings ,
1028
+ log_messages ,
991
1029
} )
992
1030
}
993
1031
0 commit comments