forked from bmx-ng/bmk
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbmk_make.bmx
517 lines (412 loc) · 13.1 KB
/
bmk_make.bmx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
Strict
Import "bmk_modutil.bmx"
Rem
Experimental speedup hack by Mark!
Should allow you to modify non-interface affecting code without triggering lots of recompiles.
Works by determining whether blah.bmx's .i file physically changes after blah.bmx is compiled.
If not, then anything importing blah.bmx may not need to be recompiled.
Uses a new '.i2' file which is updated only when actual .i file content changes.
End Rem
Global EXPERIMENTAL_SPEEDUP
Local t$=getenv_( "BMK_SPEEDUP" )
If t EXPERIMENTAL_SPEEDUP=True
Type TFile
Field path$,time
Field itime 'Tommo:added timestamp for included file
Function Create:TFile( path$,files:TList, time:Int = 0 )
Local f:TFile=New TFile
f.path=path
If time Then
f.time = time
Else
f.time=FileTime(path)
End If
If files files.AddFirst f
Return f
End Function
End Type
Global make:TMake = New TMake
Type TMake
Method New()
LuaRegisterObject Self,"make"
End Method
'Method CC(src_path:String)
' MakeSrc(RealPath(src_path), True)
'End Method
Method Make(src_path:String)
MakeSrc(RealPath(src_path), True)
End Method
End Type
Global cc_opts$
Global bcc_opts$
Global app_main$
Global app_type$
Global src_files:TList
Global obj_files:TList
Global lnk_files:TList
Global tmp_stack:TList
Global ext_files:TList
Function Push( o:Object )
tmp_stack.AddLast o
End Function
Function Pop:Object()
Return tmp_stack.RemoveLast()
End Function
Function FindFile:TFile( path$,files:TList )
path=path.ToLower()
Local f:TFile
For f=EachIn files
If f.path.ToLower()=path Return f
Next
End Function
Function MaxTime( files:TList )
Local f:TFile,t
For f=EachIn files
If f.time>t t=f.time
Next
Return t
End Function
Function FilePaths:TList( files:TList )
Local f:TFile,p:TList=New TList
For f=EachIn files
p.AddLast f.path
Next
Return p
End Function
Function AddList( src:TList,dst:TList )
Local t:Object
For t=EachIn src
dst.AddLast t
Next
End Function
Function BeginMake()
cc_opts=Null
bcc_opts=Null
app_main=Null
src_files=New TList
obj_files=New TList
lnk_files=New TList
tmp_stack=New TList
ext_files=New TList
opt_framework=""
End Function
'returns mod interface file
Function MakeMod:TFile( mod_name$, isRequired:Int = False )
Local path$=ModulePath(mod_name)
Local id$=ModuleIdent(mod_name)
Local src_path$=path+"/"+id+".bmx"
Local arc_path$=path+"/"+id+opt_configmung+processor.CPU()+".a"
Local iface_path$=path+"/"+id+opt_configmung+processor.CPU()+".i"
Local skip:String = globals.Get("skip_mod")
If skip Then
skip :+ " "
Local name:String = mod_name + " "
If skip.tolower().find(name.tolower()) >= 0 Then
If opt_debug Then
Print "Skipping " + mod_name + " (d)"
Else
Print "Skipping " + mod_name + " (r)"
End If
Return
End If
End If
mod_opts = New TModOpt ' BaH
Local iface:TFile=FindFile( iface_path,src_files )
If iface Return iface
' commented out, because it throws asserts all the time in debug mode. So,
' either it shouldn't be checking it here, or something else isn't right. I vote the former.
' Assert Not FindFile( arc_path,lnk_files )
Local arc:TFile=TFile.Create( arc_path,Null )
If ((mod_name+".").Find(opt_modfilter)=0 Or (isRequired And opt_modbuild)) And FileType(src_path)=FILETYPE_FILE
globals.PushAll()
Push cc_opts
Push bcc_opts
Push obj_files
globals.SetVar("universal", String(opt_universal))
cc_opts=""
'cc_opts:+" -I"+CQuote(path)
globals.AddOption("cc_opts", "filepath", "-I"+CQuote(path))
'cc_opts:+" -I"+CQuote(ModulePath(""))
globals.AddOption("cc_opts", "modulepath", "-I"+CQuote(ModulePath("")))
If opt_release Then
'cc_opts:+" -DNDEBUG"
globals.AddOption("cc_opts", "nodebug", "-DNDEBUG")
End If
If opt_threaded Then
'cc_opts:+" -DTHREADED"
globals.AddOption("cc_opts", "threaded", "-DTHREADED")
End If
bcc_opts=" -g "+processor.CPU()
bcc_opts:+" -m "+mod_name$
If opt_quiet bcc_opts:+" -q"
If opt_verbose bcc_opts:+" -v"
If opt_release bcc_opts:+" -r"
If opt_threaded bcc_opts:+" -h"
obj_files=New TList
Local force_build:Int = False
If Not FileType(iface_path) Then
' if the interface file is missing... we *really* want to force a recompile
force_build = True
End If
MakeSrc src_path,True, force_build, isRequired
?threaded
processManager.WaitForThreads()
?
If MaxTime( obj_files )>arc.time Or (Not isRequired And opt_all)
If Not opt_quiet Print "Archiving:"+StripDir(arc_path)
CreateArc arc_path,FilePaths( obj_files )
arc.time=FileTime(arc_path)
EndIf
obj_files=TList(Pop())
bcc_opts=String(Pop())
cc_opts=String(Pop())
globals.PopAll()
EndIf
Local src:TFile=MakeSrc( iface_path,False )
lnk_files.AddFirst arc
Return src
End Function
'adds to obj_files
'returns input src file
Function MakeSrc:TFile( src_path$,buildit, force_build:Int = False, isRequired:Int = False )
'Print "MakeSrc : " + src_path
Local src:TFile=FindFile( src_path,src_files )
If src Return src
If FileType(src_path)<>FILETYPE_FILE Return
src=TFile.Create( src_path,src_files )
Local src_file:TSourceFile=ParseSourceFile( src_path )
If Not src_file Return
Local main_file=(src_path=app_main)
Local keep_opts:TModOpt = mod_opts ' BaH
If mod_opts Then
globals.SetVar("mod_ccopts", String(mod_opts.cc_opts))
End If
If main_file
If src_file.framewk
If opt_framework Throw "Framework already specified on commandline"
opt_framework=src_file.framewk
bcc_opts:+" -f "+opt_framework
MakeMod opt_framework
Else
If app_type="bmx"
For Local t$=EachIn EnumModules()
If t.Find("brl.")=0 Or t.Find("pub.")=0
If t<>"brl.blitz" And t<>opt_appstub MakeMod t
EndIf
Next
EndIf
EndIf
Else If src_file.framewk
Throw "Framework must appear in main source file"
EndIf
mod_opts = keep_opts ' BaH
If mod_opts Then
globals.SetVar("mod_ccopts", String(mod_opts.cc_opts))
End If
globals.PushAll(["LD_OPTS"])
push cc_opts
Push CurrentDir()
ChangeDir ExtractDir( src_path )
Local src_ext$=ExtractExt( src_path ).ToLower()
Local src_type:Int = String(RunCommand("source_type", [src_ext])).ToInt()
If src_type & (SOURCE_BMX | SOURCE_IFACE)
'incbins
For Local inc$=EachIn src_file.incbins
Local time=FileTime( inc )
'Tommo:
If time > src.time Then
src.time = time
src.itime = time 'update inc timestamp
End If
'Tommo: End of mod
Next
'includes
For Local inc$=EachIn src_file.includes
Local inc_ext$=ExtractExt(inc).ToLower()
If Match(inc_ext,"bmx")
Local dep:TFile=MakeSrc(RealPath(inc),False)
If Not dep Continue
'Tommo:
If dep.time > src.time 'update inc timestamp
src.time = dep.time
src.itime = dep.time
EndIf
'Tommo:End of mod
Else
Throw "Unrecognized Include file type: "+inc
EndIf
Next
'module imports
For Local imp$=EachIn src_file.modimports
Local dep:TFile=MakeMod(imp, True)
If Not dep Continue
'cc_opts:+" -I"+CQuote(ExtractDir(dep.path))
globals.AddOption("cc_opts", "include_"+imp, "-I"+CQuote(ExtractDir(dep.path)))
If dep.time>src.time src.time=dep.time
Next
mod_opts = keep_opts ' BaH
If mod_opts Then
globals.SetVar("mod_ccopts", String(mod_opts.cc_opts))
End If
For Local imp$=EachIn mod_opts.ld_opts ' BaH
ext_files.AddLast TModOpt.setPath(imp, ExtractDir(src_path))
Next
'quoted imports
For Local imp$=EachIn src_file.imports
If imp[0]=Asc("-")
ext_files.AddLast imp
Continue
EndIf
Local imp_ext$=ExtractExt(imp).ToLower()
If Match( imp_ext,"h;hpp;hxx" )
'cc_opts:+" -I"+CQuote(RealPath(ExtractDir(imp)))
globals.AddOption("cc_opts", "include_" + imp, "-I"+CQuote(RealPath(ExtractDir(imp))))
Else If Match( imp_ext,"o;a;lib" )
ext_files.AddLast RealPath(imp)
Else If Match( imp_ext,ALL_SRC_EXTS )
Local dep:TFile=MakeSrc(RealPath(imp),True,,isRequired)
If Not dep Or Not Match( imp_ext,"bmx;i" ) Continue
If EXPERIMENTAL_SPEEDUP And Match( imp_ext,"bmx" )
Local p$=ExtractDir( dep.path )+"/.bmx"
Local i_path$=p+"/"+StripDir( dep.path )+opt_configmung+processor.CPU()+".i2"
If FileType( i_path )=FILETYPE_FILE
Local i_time=FileTime( i_path )
If i_time>src.time src.time=i_time
Else
If dep.time>src.time src.time=dep.time
EndIf
Else
If dep.time>src.time src.time=dep.time
EndIf
Else
Throw "Unrecognized Import file type: "+imp
EndIf
Next
Else If src_type & (SOURCE_C | SOURCE_HEADER) 'If Match( src_ext,"c;m;cpp;cxx;mm;h;hpp;hxx" )
For Local inc$=EachIn src_file.includes
Local inc_ext$=ExtractExt(inc).ToLower()
Local inc_type:Int = String(RunCommand("source_type", [inc_ext])).ToInt()
If Not inc_type & SOURCE_HEADER 'Match(inc_ext,"h;hpp;hxx")
Continue
EndIf
Local path$=RealPath(inc)
Local dep:TFile=MakeSrc(path,False)
If dep And dep.time>src.time src.time=dep.time
If Not opt_traceheaders Continue
Local src$=StripExt(path)+".cpp"
If FileType(src)<>FILETYPE_FILE
src=""
EndIf
If Not src Continue
MakeSrc src,True
Next
EndIf
If buildit And src_type & (SOURCE_BMX | SOURCE_C | SOURCE_ASM) 'Match( src_ext,"bmx;c;m;cpp;cxx;mm;s;asm;cc" )
Local p$=ExtractDir( src_path )+"/.bmx"
If opt_dumpbuild Or FileType( p )=FILETYPE_NONE
CreateDir p
'Sys "mkdir "+p 'Windows no likey...
EndIf
If FileType( p )<>FILETYPE_DIR Throw "Unable to create temporary directory"
Local obj_path$=p+"/"+StripDir( src_path )
If main_file obj_path:+"."+opt_apptype
obj_path:+opt_configmung+processor.CPU()+".o"
Local obj:TFile
Local time:Int
' Has the source been changed since we last compiled?
If src.time>FileTime( obj_path ) Or (Not isRequired And opt_all) Or force_build
' pragmas
Local pragma_inDefine:Int, pragma_text:String, pragma_name:String
For Local pragma:String = EachIn src_file.pragmas
processor.ProcessPragma(pragma, pragma_inDefine, pragma_text, pragma_name)
Next
If Not opt_quiet Print "Compiling:"+StripDir(src_path)
Select src_type
Case SOURCE_BMX
Local opts$=bcc_opts
If main_file opts=" -t "+opt_apptype+opts
CompileBMX src_path,obj_path,opts
If EXPERIMENTAL_SPEEDUP
Local i_path$=StripExt( obj_path )+".i"
If FileType( i_path )=FILETYPE_FILE
Local i_path2$=i_path+"2",update=True
'Tommo:
If Not opt_all And FileType(i_path2) = FILETYPE_FILE ..
And (src.time = FileTime(src.path) Or src.time = src.itime) ' added checking for Included file timestamp
'Tommo: end of mod
If FileSize( i_path )=FileSize( i_path2 )
Local i_bytes:Byte[]=LoadByteArray( i_path )
Local i_bytes2:Byte[]=LoadByteArray( i_path2 )
If i_bytes.length=i_bytes2.length And memcmp_( i_bytes,i_bytes2,i_bytes.length )=0
update=False
EndIf
EndIf
EndIf
If update CopyFile i_path,i_path2
EndIf
EndIf
If processor.BCCVersion() <> "BlitzMax" Then
Local csrc_path:String = StripExt(obj_path) + ".c"
Local cobj_path:String = StripExt(obj_path) + ".o"
CompileC csrc_path,cobj_path,cc_opts
End If
Case SOURCE_C '"c","m","cpp","cxx","mm"
CompileC src_path,obj_path,cc_opts
?threaded
time_(Varptr time)
?
Case SOURCE_ASM '"s","asm"
Assemble src_path,obj_path
End Select
EndIf
obj = TFile.Create( obj_path,obj_files, time )
lnk_files.AddFirst obj
EndIf
ChangeDir String(Pop())
cc_opts=String(Pop())
globals.PopAll()
Return src
End Function
Function MakeApp:TFile( Main$,makelib )
app_main=Main
cc_opts=""
globals.AddOption("cc_opts", "modulepath", "-I"+CQuote(ModulePath("")))
If opt_release Then
globals.AddOption("cc_opts", "nodebug", "-DNDEBUG")
End If
globals.SetVar("universal", String(opt_universal))
bcc_opts=" -g "+processor.CPU()
If opt_quiet bcc_opts:+" -q"
If opt_verbose bcc_opts:+" -v"
If opt_release bcc_opts:+" -r"
If opt_threaded bcc_opts:+" -h"
If opt_framework bcc_opts:+" -f "+opt_framework
Local app_ext$=ExtractExt( app_main ).ToLower()
Local _type:Int = String(RunCommand("source_type", [app_ext])).ToInt()
Select _type
Case SOURCE_BMX
app_type="bmx"
MakeMod "brl.blitz"
MakeSrc Main,True
MakeMod opt_appstub
Case SOURCE_C '"c","cpp","cxx","mm"
app_type="c/c++"
If opt_framework MakeMod opt_framework
MakeSrc Main,True
Default
Throw "Unrecognized app source file extension:"+app_ext
End Select
?threaded
processManager.WaitForThreads()
?
If MaxTime( lnk_files )>FileTime( opt_outfile ) Or opt_all
If Not opt_quiet Print "Linking:"+StripDir( opt_outfile )
lnk_files=FilePaths( lnk_files )
AddList ext_files,lnk_files
'globals.Dump()
LinkApp opt_outfile,lnk_files,makelib, globals.Get("ld_opts")
EndIf
' post process
LoadBMK(ExtractDir(Main) + "/post.bmk")
app_main=""
End Function