1+ use crate :: toolchain:: LocalToolchain ;
12use benchlib:: benchmark:: passes_filter;
23use cargo_metadata:: Message ;
34use core:: option:: Option ;
45use core:: option:: Option :: Some ;
56use core:: result:: Result :: Ok ;
7+ use std:: io:: BufReader ;
68use std:: path:: { Path , PathBuf } ;
7- use std:: process:: Command ;
9+ use std:: process:: { Child , Command , Stdio } ;
810
911/// A binary that defines several benchmarks using the `run_benchmark_group` function from
1012/// `benchlib`.
@@ -65,10 +67,17 @@ impl BenchmarkFilter {
6567/// We assume that each binary defines a benchmark suite using `benchlib`.
6668/// We then execute each benchmark suite with the `list-benchmarks` command to find out its
6769/// benchmark names.
68- pub fn discover_benchmarks ( cargo_stdout : & [ u8 ] ) -> anyhow:: Result < BenchmarkSuite > {
70+ pub fn discover_benchmarks (
71+ toolchain : & LocalToolchain ,
72+ dir : & Path ,
73+ ) -> anyhow:: Result < BenchmarkSuite > {
74+ log:: info!( "Compiling runtime benchmarks" ) ;
75+ let mut child = start_runtime_benchmarks_compilation ( toolchain, dir) ?;
76+
6977 let mut groups = vec ! [ ] ;
7078
71- for message in Message :: parse_stream ( cargo_stdout) {
79+ let stream = BufReader :: new ( child. stdout . take ( ) . unwrap ( ) ) ;
80+ for message in Message :: parse_stream ( stream) {
7281 let message = message?;
7382 match message {
7483 Message :: CompilerArtifact ( artifact) => {
@@ -81,23 +90,57 @@ pub fn discover_benchmarks(cargo_stdout: &[u8]) -> anyhow::Result<BenchmarkSuite
8190 path. display( )
8291 )
8392 } ) ?;
93+ log:: info!( "Compiled {}" , path. display( ) ) ;
8494 groups. push ( BenchmarkGroup {
8595 binary : path,
8696 benchmark_names : benchmarks,
8797 } ) ;
8898 }
8999 }
90100 }
91- _ => { }
101+ Message :: TextLine ( line) => println ! ( "{}" , line) ,
102+ Message :: CompilerMessage ( msg) => {
103+ print ! ( "{}" , msg. message. rendered. unwrap_or( msg. message. message) )
104+ }
105+ _ => {
106+ log:: debug!( "Cargo metadata output: {:?}" , message) ;
107+ }
92108 }
93109 }
94110
111+ let output = child. wait ( ) ?;
112+ if output. success ( ) {
113+ log:: info!( "Successfully compiled runtime benchmarks" ) ;
114+ } else {
115+ return Err ( anyhow:: anyhow!( "Failed to compile runtime benchmarks" ) ) ;
116+ }
117+
95118 groups. sort_unstable_by ( |a, b| a. binary . cmp ( & b. binary ) ) ;
96119 log:: debug!( "Found binaries: {:?}" , groups) ;
97120
98121 Ok ( BenchmarkSuite { groups } )
99122}
100123
124+ /// Compiles all runtime benchmark binaries (groups) and returns the stdout output stream of Cargo.
125+ fn start_runtime_benchmarks_compilation (
126+ toolchain : & LocalToolchain ,
127+ dir : & Path ,
128+ ) -> anyhow:: Result < Child > {
129+ let child = Command :: new ( & toolchain. cargo )
130+ . env ( "RUSTC" , & toolchain. rustc )
131+ . arg ( "build" )
132+ . arg ( "--release" )
133+ . arg ( "--message-format" )
134+ . arg ( "json-diagnostic-rendered-ansi" )
135+ . current_dir ( dir)
136+ . stdin ( Stdio :: null ( ) )
137+ . stdout ( Stdio :: piped ( ) )
138+ . stderr ( Stdio :: null ( ) )
139+ . spawn ( )
140+ . map_err ( |error| anyhow:: anyhow!( "Failed to start cargo: {:?}" , error) ) ?;
141+ Ok ( child)
142+ }
143+
101144/// Uses a command from `benchlib` to find the benchmark names from the given
102145/// benchmark binary.
103146fn gather_benchmarks ( binary : & Path ) -> anyhow:: Result < Vec < String > > {
0 commit comments