11use std:: ffi:: OsString ;
2+ use std:: fs;
23use std:: path:: { Path , PathBuf } ;
34
4- use crate :: { execute_command, test_nasm_command} ;
5+ use crate :: { execute_command, test_nasm_command, use_prebuilt_nasm } ;
56
67#[ derive( Debug ) ]
78pub ( crate ) struct NasmBuilder {
@@ -10,16 +11,18 @@ pub(crate) struct NasmBuilder {
1011 defines : Vec < ( String , Option < String > ) > ,
1112 flags : Vec < String > ,
1213 out_dir : PathBuf ,
14+ manifest_dir : PathBuf ,
1315}
1416
1517impl NasmBuilder {
16- pub ( crate ) fn new ( out_dir : PathBuf ) -> Self {
18+ pub ( crate ) fn new ( manifest_dir : PathBuf , out_dir : PathBuf ) -> Self {
1719 Self {
1820 files : Vec :: new ( ) ,
1921 includes : Vec :: new ( ) ,
2022 defines : Vec :: new ( ) ,
2123 flags : Vec :: new ( ) ,
2224 out_dir,
25+ manifest_dir,
2326 }
2427 }
2528
@@ -45,61 +48,86 @@ impl NasmBuilder {
4548 }
4649
4750 pub ( crate ) fn compile_intermediates ( & self ) -> Vec < PathBuf > {
48- if !test_nasm_command ( ) {
49- panic ! ( "NASM command not found! Build cannot continue." ) ;
50- }
51-
5251 let mut objects = Vec :: new ( ) ;
5352
54- for src in & self . files {
55- let obj_ext = "obj" ;
56- let obj_name = src
57- . file_name ( )
58- . unwrap ( )
59- . to_str ( )
60- . unwrap ( )
61- . replace ( ".asm" , & format ! ( ".{}" , obj_ext) ) ;
62- let obj_path = self . out_dir . join ( obj_name) ;
63-
64- let mut args: Vec < OsString > = vec ! [
65- "-f" . into( ) ,
66- "win64" . into( ) ,
67- "-o" . into( ) ,
68- obj_path. as_os_str( ) . into( ) ,
69- ] ;
70-
71- for inc in & self . includes {
72- args. push ( "-I" . into ( ) ) ;
73- args. push ( inc. as_os_str ( ) . into ( ) ) ;
74- }
53+ if self . files . is_empty ( ) {
54+ return vec ! [ ] ;
55+ }
7556
76- for ( key, val) in & self . defines {
77- let def = if let Some ( v) = val {
78- format ! ( "-D{}={}" , key, v)
79- } else {
80- format ! ( "-D{}" , key)
81- } ;
82- args. push ( def. into ( ) ) ;
57+ if !test_nasm_command ( ) {
58+ if use_prebuilt_nasm ( ) {
59+ let prebuilt_dir = self . manifest_dir . join ( "builder" ) . join ( "prebuilt-nasm" ) ;
60+ for src in & self . files {
61+ let obj_name = src
62+ . file_name ( )
63+ . unwrap ( )
64+ . to_str ( )
65+ . unwrap ( )
66+ . replace ( ".asm" , ".obj" ) ;
67+ let obj_path = self . out_dir . join ( & obj_name) ;
68+ let base_name = obj_name. strip_suffix ( ".obj" ) . unwrap_or ( & obj_name) ;
69+ let prebuilt_src = prebuilt_dir. join ( format ! ( "{}.obj" , base_name) ) ;
70+ if prebuilt_src. exists ( ) {
71+ fs:: copy ( & prebuilt_src, & obj_path)
72+ . expect ( "Failed to copy prebuilt NASM object" ) ;
73+ } else {
74+ panic ! ( "Prebuilt NASM object not found: {}" , prebuilt_src. display( ) ) ;
75+ }
76+ objects. push ( obj_path) ;
77+ }
78+ } else {
79+ panic ! ( "NASM command not found! Build cannot continue." ) ;
8380 }
84-
85- args. extend ( self . flags . iter ( ) . map ( |s| s. into ( ) ) ) ;
86-
87- args. push ( src. as_os_str ( ) . into ( ) ) ;
88-
89- let result = execute_command (
90- "nasm" . as_ref ( ) ,
91- & args. iter ( ) . map ( |s| s. as_os_str ( ) ) . collect :: < Vec < _ > > ( ) ,
92- ) ;
93- if !result. status {
94- panic ! (
95- "NASM failed for {}:\n -----\n {}\n -----\n {}\n -----\n " ,
96- src. display( ) ,
97- result. stdout,
98- result. stderr
81+ } else {
82+ for src in & self . files {
83+ let obj_name = src
84+ . file_name ( )
85+ . unwrap ( )
86+ . to_str ( )
87+ . unwrap ( )
88+ . replace ( ".asm" , ".obj" ) ;
89+ let obj_path = self . out_dir . join ( obj_name) ;
90+
91+ let mut args: Vec < OsString > = vec ! [
92+ "-f" . into( ) ,
93+ "win64" . into( ) ,
94+ "-o" . into( ) ,
95+ obj_path. as_os_str( ) . into( ) ,
96+ ] ;
97+
98+ for inc in & self . includes {
99+ args. push ( "-I" . into ( ) ) ;
100+ args. push ( inc. as_os_str ( ) . into ( ) ) ;
101+ }
102+
103+ for ( key, val) in & self . defines {
104+ let def = if let Some ( v) = val {
105+ format ! ( "-D{}={}" , key, v)
106+ } else {
107+ format ! ( "-D{}" , key)
108+ } ;
109+ args. push ( def. into ( ) ) ;
110+ }
111+
112+ args. extend ( self . flags . iter ( ) . map ( |s| s. into ( ) ) ) ;
113+
114+ args. push ( src. as_os_str ( ) . into ( ) ) ;
115+
116+ let result = execute_command (
117+ "nasm" . as_ref ( ) ,
118+ & args. iter ( ) . map ( |s| s. as_os_str ( ) ) . collect :: < Vec < _ > > ( ) ,
99119 ) ;
120+ if !result. status {
121+ panic ! (
122+ "NASM failed for {}:\n -----\n {}\n -----\n {}\n -----\n " ,
123+ src. display( ) ,
124+ result. stdout,
125+ result. stderr
126+ ) ;
127+ }
128+
129+ objects. push ( obj_path) ;
100130 }
101-
102- objects. push ( obj_path) ;
103131 }
104132
105133 objects
0 commit comments