20
20
SCRIPT_DIR = Path (os .path .dirname (os .path .realpath (__file__ )))
21
21
22
22
opt_flags_pattern = re .compile (r"@DECOMP_OPT_FLAGS\s*=\s*(.*)\s*" )
23
+ ido_version_pattern = re .compile (r"@DECOMP_IDO_VERSION\s*=\s*(.*)\s*" )
24
+
25
+ IDO_VAR_MAP = {
26
+ "5.3" : "$IDO_53" ,
27
+ "7.1" : "$IDO_71"
28
+ }
29
+
30
+ class BuildFileConfig :
31
+ def __init__ (self , opt : "str | None" , ido_version : "str | None" ):
32
+ self .opt = opt
33
+ self .ido_version = ido_version
23
34
24
35
class BuildFileType (Enum ):
25
36
C = 1
26
37
ASM = 2
27
38
BIN = 3
28
39
29
40
class BuildFile :
30
- def __init__ (self , src_path : str , obj_path : str , type : BuildFileType , opt : "str | None" = None ):
41
+ def __init__ (self , src_path : str , obj_path : str , type : BuildFileType , config : BuildFileConfig | None = None ):
31
42
self .src_path = src_path
32
43
self .obj_path = obj_path
33
44
self .type = type
34
- self .opt = opt
45
+ self .config = config
35
46
36
47
class DLL :
37
48
def __init__ (self , number : str , dir : str , files : "list[BuildFile]" ):
@@ -178,19 +189,17 @@ def __write_prelude(self):
178
189
# Write tools
179
190
cross = self .__detect_cross ()
180
191
exe_suffix = ".exe" if sys .platform == "win32" else ""
192
+ ido_recomp_platform = "windows" if sys .platform == "win32" else "linux"
181
193
182
194
self .writer .comment ("Tools" )
183
195
self .writer .variable ("AS" , f"{ cross } as{ exe_suffix } " )
184
196
self .writer .variable ("LD" , f"{ cross } ld{ exe_suffix } " )
185
197
self .writer .variable ("OBJCOPY" , f"{ cross } objcopy{ exe_suffix } " )
186
- if sys .platform == "win32" :
187
- self .writer .variable ("CC" , "tools/ido_recomp/windows/5.3/cc.exe" )
188
- else :
189
- self .writer .variable ("CC" , "tools/ido_recomp/linux/5.3/cc" )
198
+ self .writer .variable ("IDO_53" , f"tools/ido_recomp/{ ido_recomp_platform } /5.3/cc{ exe_suffix } " )
199
+ self .writer .variable ("IDO_71" , f"tools/ido_recomp/{ ido_recomp_platform } /7.1/cc{ exe_suffix } " )
200
+ self .writer .variable ("CC" , "$IDO_53" )
190
201
self .writer .variable ("ASM_PROCESSOR" , "python3 tools/asm_processor/build.py" )
191
202
self .writer .variable ("HEADER_DEPS" , "python3 tools/header_deps.py" )
192
- self .writer .variable ("CC_PREPROCESSED" , "$ASM_PROCESSOR $CC -- $AS $AS_FLAGS --" )
193
- self .writer .variable ("CC_PREPROCESSED_DLL" , "$ASM_PROCESSOR $CC -- $AS $AS_FLAGS_DLL --" )
194
203
self .writer .variable ("ELF2DLL" , "python3 tools/elf2dll.py" )
195
204
self .writer .variable ("DINODLL" , "python3 tools/dino_dll.py" )
196
205
@@ -199,11 +208,11 @@ def __write_prelude(self):
199
208
# Write rules
200
209
self .writer .comment ("Rules" )
201
210
self .writer .rule ("cc" ,
202
- "$HEADER_DEPS $CC_PREPROCESSED -c $CC_FLAGS $OPT_FLAGS -o $out $in" ,
211
+ "$HEADER_DEPS $ASM_PROCESSOR $CC -- $AS $AS_FLAGS -- -c $CC_FLAGS $OPT_FLAGS -o $out $in" ,
203
212
"Compiling $in..." ,
204
213
depfile = "$out.d" )
205
214
self .writer .rule ("cc_dll" ,
206
- "$HEADER_DEPS $CC_PREPROCESSED_DLL -c $CC_FLAGS_DLL $OPT_FLAGS -o $out $in" ,
215
+ "$HEADER_DEPS $ASM_PROCESSOR $CC -- $AS $AS_FLAGS_DLL -- -c $CC_FLAGS_DLL $OPT_FLAGS -o $out $in" ,
207
216
"Compiling $in..." ,
208
217
depfile = "$out.d" )
209
218
self .writer .rule ("as" , "$AS $AS_FLAGS -o $out $in" , "Assembling $in..." )
@@ -231,10 +240,7 @@ def __write_file_builds(self):
231
240
232
241
for file in self .input .files :
233
242
# Determine variables
234
- variables : dict [str , str ] = {}
235
- opt = file .opt
236
- if opt is not None and opt != self .config .default_opt_flags :
237
- variables ["OPT_FLAGS" ] = opt
243
+ variables : dict [str , str ] = self .__file_config_to_variables (file .config )
238
244
239
245
# Determine command
240
246
command : str
@@ -267,10 +273,7 @@ def __write_dll_builds(self):
267
273
dll_link_deps : "list[str]" = []
268
274
for file in dll .files :
269
275
# Determine variables
270
- variables : dict [str , str ] = {}
271
- opt = file .opt
272
- if opt is not None and opt != self .config .default_opt_flags :
273
- variables ["OPT_FLAGS" ] = opt
276
+ variables : dict [str , str ] = self .__file_config_to_variables (file .config )
274
277
275
278
# Determine command
276
279
command : str
@@ -392,6 +395,17 @@ def __detect_cross(self) -> str:
392
395
else :
393
396
return "mips-linux-gnu-"
394
397
398
+ def __file_config_to_variables (self , file_config : BuildFileConfig | None ):
399
+ variables : dict [str , str ] = {}
400
+
401
+ if file_config != None :
402
+ if file_config .opt != None :
403
+ variables ["OPT_FLAGS" ] = file_config .opt
404
+ if file_config .ido_version != None :
405
+ variables ["CC" ] = IDO_VAR_MAP [file_config .ido_version ]
406
+
407
+ return variables
408
+
395
409
class ObjDiffConfigWriter :
396
410
def __init__ (self , output_file : TextIO , input : BuildFiles , config : BuildConfig ):
397
411
self .output_file = output_file
@@ -462,8 +476,8 @@ def __scan_c_files(self):
462
476
paths = [Path (path ) for path in glob .glob ("src/**/*.c" , recursive = True ) if not Path (path ).is_relative_to (Path ("src/dlls" ))]
463
477
for src_path in paths :
464
478
obj_path = self .__make_obj_path (src_path )
465
- opt = self .__get_optimization_level (src_path )
466
- self .files .append (BuildFile (str (src_path ), str (obj_path ), BuildFileType .C , opt ))
479
+ file_config = self .__get_file_config (src_path )
480
+ self .files .append (BuildFile (str (src_path ), str (obj_path ), BuildFileType .C , file_config ))
467
481
468
482
def __scan_asm_files (self ):
469
483
# Exclude splat nonmatchings, those are compiled in with their respective C file
@@ -510,8 +524,8 @@ def __scan_dlls(self):
510
524
511
525
for src_path in c_paths :
512
526
obj_path = self .__make_obj_path (src_path )
513
- opt = self .__get_optimization_level (src_path )
514
- files .append (BuildFile (str (src_path ), str (obj_path ), BuildFileType .C , opt ))
527
+ file_config = self .__get_file_config (src_path )
528
+ files .append (BuildFile (str (src_path ), str (obj_path ), BuildFileType .C , file_config ))
515
529
516
530
for src_path in asm_paths :
517
531
obj_path = self .__make_obj_path (src_path )
@@ -533,18 +547,35 @@ def __scan_dlls(self):
533
547
def __make_obj_path (self , path : Path ) -> str :
534
548
return path .with_suffix ('.o' )
535
549
536
- def __get_optimization_level (self , path : Path ) -> str :
550
+ def __get_file_config (self , path : Path ) -> BuildFileConfig :
551
+ opt_flags : "str | None" = None
552
+ ido_version : "str | None" = None
553
+
537
554
with open (path , "r" , encoding = "utf-8" ) as file :
555
+ found_comments = False
538
556
while True :
539
557
line = file .readline ().strip ()
540
- if len (line ) == 0 :
558
+ if len (line ) == 0 and found_comments :
559
+ # End on empty line after comment block
541
560
break
542
561
if line .startswith ("//" ):
562
+ found_comments = True
563
+
543
564
opt_match = opt_flags_pattern .search (line )
544
565
if opt_match != None :
545
- return opt_match .group (1 )
566
+ opt_flags = opt_match .group (1 )
567
+ continue
568
+ ido_match = ido_version_pattern .search (line )
569
+ if ido_match != None :
570
+ ido_version = ido_match .group (1 )
571
+ continue
572
+ else :
573
+ # End on non-empty non-comment line
574
+ break
546
575
547
- return self .config .default_opt_flags
576
+ return BuildFileConfig (
577
+ opt = opt_flags ,
578
+ ido_version = ido_version )
548
579
549
580
def __get_dll_config (self , dll_dir : Path , number : int ) -> DLLBuildConfig | None :
550
581
yaml_path = dll_dir .joinpath ("dll.yaml" )
0 commit comments