@@ -171,6 +171,28 @@ impl Tool {
171171 } )
172172 }
173173
174+ pub ( crate ) fn resolve_package_manifest_dir ( & self , package : & str ) -> anyhow:: Result < PathBuf > {
175+ let metadata = self . metadata ( ) ?;
176+ let Some ( pkg) = metadata. packages . iter ( ) . find ( |pkg| pkg. name == package) else {
177+ bail ! (
178+ "package '{}' not found in cargo metadata under {}" ,
179+ package,
180+ self . manifest_dir( ) . display( )
181+ ) ;
182+ } ;
183+
184+ pkg. manifest_path
185+ . parent ( )
186+ . map ( |path| path. as_std_path ( ) . to_path_buf ( ) )
187+ . ok_or_else ( || {
188+ anyhow ! (
189+ "package '{}' manifest has no parent: {}" ,
190+ package,
191+ pkg. manifest_path
192+ )
193+ } )
194+ }
195+
174196 /// Sets the ELF artifact path and synchronizes derived runtime metadata.
175197 pub async fn set_elf_artifact_path ( & mut self , path : PathBuf ) -> anyhow:: Result < ( ) > {
176198 let path = path
@@ -485,6 +507,8 @@ fn resolve_manifest_path(input: Option<PathBuf>) -> anyhow::Result<PathBuf> {
485507#[ cfg( test) ]
486508mod tests {
487509 use super :: { Tool , ToolConfig , resolve_manifest_context} ;
510+ use crate :: run:: qemu:: resolve_qemu_config_path_in_dir;
511+ use object:: Architecture ;
488512
489513 #[ tokio:: test]
490514 async fn set_elf_artifact_path_updates_dirs_and_arch ( ) {
@@ -548,4 +572,87 @@ mod tests {
548572 assert_eq ! ( manifest. manifest_dir, app_dir) ;
549573 assert_eq ! ( manifest. workspace_dir, temp. path( ) ) ;
550574 }
575+
576+ #[ test]
577+ fn resolve_package_manifest_dir_uses_selected_package ( ) {
578+ let temp = tempfile:: tempdir ( ) . unwrap ( ) ;
579+ std:: fs:: write (
580+ temp. path ( ) . join ( "Cargo.toml" ) ,
581+ "[workspace]\n members = [\" app\" , \" kernel\" ]\n resolver = \" 3\" \n " ,
582+ )
583+ . unwrap ( ) ;
584+
585+ let app_dir = temp. path ( ) . join ( "app" ) ;
586+ std:: fs:: create_dir_all ( app_dir. join ( "src" ) ) . unwrap ( ) ;
587+ std:: fs:: write (
588+ app_dir. join ( "Cargo.toml" ) ,
589+ "[package]\n name = \" app\" \n version = \" 0.1.0\" \n edition = \" 2024\" \n " ,
590+ )
591+ . unwrap ( ) ;
592+ std:: fs:: write ( app_dir. join ( "src/main.rs" ) , "fn main() {}\n " ) . unwrap ( ) ;
593+
594+ let kernel_dir = temp. path ( ) . join ( "kernel" ) ;
595+ std:: fs:: create_dir_all ( kernel_dir. join ( "src" ) ) . unwrap ( ) ;
596+ std:: fs:: write (
597+ kernel_dir. join ( "Cargo.toml" ) ,
598+ "[package]\n name = \" kernel\" \n version = \" 0.1.0\" \n edition = \" 2024\" \n " ,
599+ )
600+ . unwrap ( ) ;
601+ std:: fs:: write ( kernel_dir. join ( "src/main.rs" ) , "fn main() {}\n " ) . unwrap ( ) ;
602+
603+ let tool = Tool :: new ( ToolConfig {
604+ manifest : Some ( app_dir. clone ( ) ) ,
605+ ..Default :: default ( )
606+ } )
607+ . unwrap ( ) ;
608+
609+ let resolved = tool. resolve_package_manifest_dir ( "kernel" ) . unwrap ( ) ;
610+ assert_eq ! ( resolved, kernel_dir) ;
611+ }
612+
613+ #[ test]
614+ fn cargo_qemu_config_resolution_prefers_package_dir_over_workspace_root ( ) {
615+ let temp = tempfile:: tempdir ( ) . unwrap ( ) ;
616+ std:: fs:: write (
617+ temp. path ( ) . join ( "Cargo.toml" ) ,
618+ "[workspace]\n members = [\" app\" , \" kernel\" ]\n resolver = \" 3\" \n " ,
619+ )
620+ . unwrap ( ) ;
621+ std:: fs:: write ( temp. path ( ) . join ( "qemu-aarch64.toml" ) , "" ) . unwrap ( ) ;
622+
623+ let app_dir = temp. path ( ) . join ( "app" ) ;
624+ std:: fs:: create_dir_all ( app_dir. join ( "src" ) ) . unwrap ( ) ;
625+ std:: fs:: write (
626+ app_dir. join ( "Cargo.toml" ) ,
627+ "[package]\n name = \" app\" \n version = \" 0.1.0\" \n edition = \" 2024\" \n " ,
628+ )
629+ . unwrap ( ) ;
630+ std:: fs:: write ( app_dir. join ( "src/main.rs" ) , "fn main() {}\n " ) . unwrap ( ) ;
631+
632+ let kernel_dir = temp. path ( ) . join ( "kernel" ) ;
633+ std:: fs:: create_dir_all ( kernel_dir. join ( "src" ) ) . unwrap ( ) ;
634+ std:: fs:: write (
635+ kernel_dir. join ( "Cargo.toml" ) ,
636+ "[package]\n name = \" kernel\" \n version = \" 0.1.0\" \n edition = \" 2024\" \n " ,
637+ )
638+ . unwrap ( ) ;
639+ std:: fs:: write ( kernel_dir. join ( "src/main.rs" ) , "fn main() {}\n " ) . unwrap ( ) ;
640+ std:: fs:: write ( kernel_dir. join ( ".qemu-aarch64.toml" ) , "" ) . unwrap ( ) ;
641+
642+ let tool = Tool :: new ( ToolConfig {
643+ manifest : Some ( app_dir) ,
644+ ..Default :: default ( )
645+ } )
646+ . unwrap ( ) ;
647+
648+ let package_dir = tool. resolve_package_manifest_dir ( "kernel" ) . unwrap ( ) ;
649+ let resolved = resolve_qemu_config_path_in_dir (
650+ & package_dir,
651+ Some ( Architecture :: Aarch64 ) ,
652+ None ,
653+ )
654+ . unwrap ( ) ;
655+
656+ assert_eq ! ( resolved, kernel_dir. join( ".qemu-aarch64.toml" ) ) ;
657+ }
551658}
0 commit comments