11//! Provides functions to build the kernel and the bootloader.
22
3+ use cargo_metadata:: Metadata ;
34use error:: { BootloaderError , BuildKernelError , BuilderError , CreateBootimageError } ;
45use std:: {
56 path:: { Path , PathBuf } ,
@@ -16,6 +17,7 @@ pub mod error;
1617/// Allows building the kernel and creating a bootable disk image with it.
1718pub struct Builder {
1819 manifest_path : PathBuf ,
20+ project_metadata : Option < Metadata > ,
1921}
2022
2123impl Builder {
@@ -24,7 +26,10 @@ impl Builder {
2426 /// If None is passed for `manifest_path`, it is automatically searched.
2527 pub fn new ( manifest_path : Option < PathBuf > ) -> Result < Self , BuilderError > {
2628 let manifest_path = manifest_path. unwrap_or ( locate_cargo_manifest:: locate_manifest ( ) ?) ;
27- Ok ( Builder { manifest_path } )
29+ Ok ( Builder {
30+ manifest_path,
31+ project_metadata : None ,
32+ } )
2833 }
2934
3035 /// Returns the path to the Cargo.toml file of the project.
@@ -111,17 +116,17 @@ impl Builder {
111116 ///
112117 /// If the quiet argument is set to true, all output to stdout is suppressed.
113118 pub fn create_bootimage (
114- & self ,
119+ & mut self ,
115120 bin_name : & str ,
116121 bin_path : & Path ,
117122 output_bin_path : & Path ,
118123 quiet : bool ,
119124 ) -> Result < ( ) , CreateBootimageError > {
120- let project_metadata = cargo_metadata :: MetadataCommand :: new ( )
121- . manifest_path ( & self . manifest_path )
122- . exec ( ) ? ;
123- let bootloader_build_config =
124- bootloader :: BuildConfig :: from_metadata ( & project_metadata , bin_name , bin_path ) ?;
125+ let bootloader_build_config = bootloader :: BuildConfig :: from_metadata (
126+ self . project_metadata ( ) ? ,
127+ kernel_manifest_path ,
128+ bin_path ,
129+ ) ?;
125130
126131 // build bootloader
127132 if !quiet {
@@ -181,4 +186,14 @@ impl Builder {
181186
182187 Ok ( ( ) )
183188 }
189+
190+ fn project_metadata ( & mut self ) -> Result < & Metadata , cargo_metadata:: Error > {
191+ if let Some ( ref metadata) = self . project_metadata {
192+ return Ok ( metadata) ;
193+ }
194+ let metadata = cargo_metadata:: MetadataCommand :: new ( )
195+ . manifest_path ( & self . manifest_path )
196+ . exec ( ) ?;
197+ Ok ( self . project_metadata . get_or_insert ( metadata) )
198+ }
184199}
0 commit comments