@@ -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.
@@ -474,15 +490,18 @@ fn build_work(build_runner: &mut BuildRunner<'_, '_>, unit: &Unit) -> CargoResul
474
490
state. running ( & cmd) ;
475
491
let timestamp = paths:: set_invocation_time ( & script_run_dir) ?;
476
492
let prefix = format ! ( "[{} {}] " , id. name( ) , id. version( ) ) ;
477
- let mut warnings_in_case_of_panic = Vec :: new ( ) ;
493
+ let mut log_messages_in_case_of_panic = Vec :: new ( ) ;
478
494
let output = cmd
479
495
. exec_with_streaming (
480
496
& mut |stdout| {
497
+ if let Some ( error) = stdout. strip_prefix ( CARGO_ERROR_SYNTAX ) {
498
+ log_messages_in_case_of_panic. push ( ( Severity :: Error , error. to_owned ( ) ) ) ;
499
+ }
481
500
if let Some ( warning) = stdout
482
501
. strip_prefix ( OLD_CARGO_WARNING_SYNTAX )
483
502
. or ( stdout. strip_prefix ( NEW_CARGO_WARNING_SYNTAX ) )
484
503
{
485
- warnings_in_case_of_panic . push ( warning. to_owned ( ) ) ;
504
+ log_messages_in_case_of_panic . push ( ( Severity :: Warning , warning. to_owned ( ) ) ) ;
486
505
}
487
506
if extra_verbose {
488
507
state. stdout ( format ! ( "{}{}" , prefix, stdout) ) ?;
@@ -522,15 +541,29 @@ fn build_work(build_runner: &mut BuildRunner<'_, '_>, unit: &Unit) -> CargoResul
522
541
build_error_context
523
542
} ) ;
524
543
544
+ // If the build failed
525
545
if let Err ( error) = output {
526
- insert_warnings_in_build_outputs (
546
+ insert_log_messages_in_build_outputs (
527
547
build_script_outputs,
528
548
id,
529
549
metadata_hash,
530
- warnings_in_case_of_panic ,
550
+ log_messages_in_case_of_panic ,
531
551
) ;
532
552
return Err ( error) ;
533
553
}
554
+ // ... or it logged any errors
555
+ else if log_messages_in_case_of_panic
556
+ . iter ( )
557
+ . any ( |( severity, _) | * severity == Severity :: Error )
558
+ {
559
+ insert_log_messages_in_build_outputs (
560
+ build_script_outputs,
561
+ id,
562
+ metadata_hash,
563
+ log_messages_in_case_of_panic,
564
+ ) ;
565
+ anyhow:: bail!( "build script logged errors" ) ;
566
+ }
534
567
535
568
let output = output. unwrap ( ) ;
536
569
@@ -611,22 +644,23 @@ fn build_work(build_runner: &mut BuildRunner<'_, '_>, unit: &Unit) -> CargoResul
611
644
Ok ( job)
612
645
}
613
646
614
- /// When a build script run fails, store only warnings and nuke other outputs,
615
- /// as they are likely broken.
616
- fn insert_warnings_in_build_outputs (
647
+ /// When a build script run fails, store only log messages, and nuke other
648
+ /// outputs, as they are likely broken.
649
+ fn insert_log_messages_in_build_outputs (
617
650
build_script_outputs : Arc < Mutex < BuildScriptOutputs > > ,
618
651
id : PackageId ,
619
652
metadata_hash : Metadata ,
620
- warnings : Vec < String > ,
653
+ log_messages : Vec < LogMessage > ,
621
654
) {
622
- let build_output_with_only_warnings = BuildOutput {
623
- warnings ,
655
+ let build_output_with_only_log_messages = BuildOutput {
656
+ log_messages ,
624
657
..BuildOutput :: default ( )
625
658
} ;
626
- build_script_outputs
627
- . lock ( )
628
- . unwrap ( )
629
- . insert ( id, metadata_hash, build_output_with_only_warnings) ;
659
+ build_script_outputs. lock ( ) . unwrap ( ) . insert (
660
+ id,
661
+ metadata_hash,
662
+ build_output_with_only_log_messages,
663
+ ) ;
630
664
}
631
665
632
666
impl BuildOutput {
@@ -678,7 +712,7 @@ impl BuildOutput {
678
712
let mut metadata = Vec :: new ( ) ;
679
713
let mut rerun_if_changed = Vec :: new ( ) ;
680
714
let mut rerun_if_env_changed = Vec :: new ( ) ;
681
- let mut warnings = Vec :: new ( ) ;
715
+ let mut log_messages = Vec :: new ( ) ;
682
716
let whence = format ! ( "build script of `{}`" , pkg_descr) ;
683
717
// Old syntax:
684
718
// cargo:rustc-flags=VALUE
@@ -850,15 +884,18 @@ impl BuildOutput {
850
884
"rustc-link-search" => library_paths. push ( PathBuf :: from ( value) ) ,
851
885
"rustc-link-arg-cdylib" | "rustc-cdylib-link-arg" => {
852
886
if !targets. iter ( ) . any ( |target| target. is_cdylib ( ) ) {
853
- warnings. push ( format ! (
854
- "{}{} was specified in the build script of {}, \
887
+ log_messages. push ( (
888
+ Severity :: Warning ,
889
+ format ! (
890
+ "{}{} was specified in the build script of {}, \
855
891
but that package does not contain a cdylib target\n \
856
892
\n \
857
893
Allowing this was an unintended change in the 1.50 \
858
894
release, and may become an error in the future. \
859
895
For more information, see \
860
896
<https://github.com/rust-lang/cargo/issues/9562>.",
861
- syntax_prefix, key, pkg_descr
897
+ syntax_prefix, key, pkg_descr
898
+ ) ,
862
899
) ) ;
863
900
}
864
901
linker_args. push ( ( LinkArgTarget :: Cdylib , value) )
@@ -944,10 +981,10 @@ impl BuildOutput {
944
981
if nightly_features_allowed
945
982
|| rustc_bootstrap_allows ( library_name. as_deref ( ) )
946
983
{
947
- warnings . push ( format ! ( "Cannot set `RUSTC_BOOTSTRAP={}` from {}.\n \
984
+ log_messages . push ( ( Severity :: Warning , format ! ( "Cannot set `RUSTC_BOOTSTRAP={}` from {}.\n \
948
985
note: Crates cannot set `RUSTC_BOOTSTRAP` themselves, as doing so would subvert the stability guarantees of Rust for your project.",
949
986
val, whence
950
- ) ) ;
987
+ ) ) ) ;
951
988
} else {
952
989
// Setting RUSTC_BOOTSTRAP would change the behavior of the crate.
953
990
// Abort with an error.
@@ -963,7 +1000,8 @@ impl BuildOutput {
963
1000
env. push ( ( key, val) ) ;
964
1001
}
965
1002
}
966
- "warning" => warnings. push ( value. to_string ( ) ) ,
1003
+ "error" => log_messages. push ( ( Severity :: Error , value. to_string ( ) ) ) ,
1004
+ "warning" => log_messages. push ( ( Severity :: Warning , value. to_string ( ) ) ) ,
967
1005
"rerun-if-changed" => rerun_if_changed. push ( PathBuf :: from ( value) ) ,
968
1006
"rerun-if-env-changed" => rerun_if_env_changed. push ( value. to_string ( ) ) ,
969
1007
"metadata" => {
@@ -988,7 +1026,7 @@ impl BuildOutput {
988
1026
metadata,
989
1027
rerun_if_changed,
990
1028
rerun_if_env_changed,
991
- warnings ,
1029
+ log_messages ,
992
1030
} )
993
1031
}
994
1032
0 commit comments