12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063 |
- SuperStrict
- Import "bmk_config.bmx"
- Import "bmk_ng.bmx"
- Import "file_util.c"
- Import "hash.c"
- 'OS X Nasm doesn't work? Used to produce incorrect reloc offsets - haven't checked for a while
- Const USE_NASM:Int=False
- Const CC_WARNINGS:Int=False'True
- Const IOS_HAS_MERGE:Int = False
- Type TModOpt ' BaH
- Field cc_opts:String = ""
- Field ld_opts:TList = New TList
- Field cpp_opts:String = ""
- Field c_opts:String = ""
- Field asm_opts:String = ""
-
- Method addOption(qval:String, path:String)
- If qval.startswith("CC_OPTS") Then
- cc_opts:+ " " + setPath(ReQuote(qval[qval.find(":") + 1..].Trim()), path)
- ElseIf qval.startswith("CPP_OPTS") Then
- cpp_opts:+ " " + setPath(ReQuote(qval[qval.find(":") + 1..].Trim()), path)
- ElseIf qval.startswith("C_OPTS") Then
- c_opts:+ " " + setPath(ReQuote(qval[qval.find(":") + 1..].Trim()), path)
- ElseIf qval.startswith("ASM_OPTS") Then
- asm_opts:+ " " + setPath(ReQuote(qval[qval.find(":") + 1..].Trim()), path)
- ElseIf qval.startswith("LD_OPTS") Then
- Local opt:String = ReQuote(qval[qval.find(":") + 1..].Trim())
-
- If opt.startsWith("-L") Then
- opt = "-L" + CQuote(opt[2..])
- End If
- ld_opts.addLast opt
- ElseIf qval.startswith("CC_VOPT") Then
- setOption("cc_opts", qval)
- ElseIf qval.startswith("CPP_VOPT") Then
- setOption("cpp_opts", qval)
- ElseIf qval.startswith("C_VOPT") Then
- setOption("c_opts", qval)
- ElseIf qval.startswith("ASM_VOPT") Then
- setOption("asm_opts", qval)
- ElseIf qval.startswith("LD_VOPT") Then
- setOption("ld_opts", qval)
- End If
- End Method
- Function setOption(option:String, qval:String)
- Local opt:String = qval[qval.find(":") + 1..].Trim()
- Local parts:String[] = opt.Split("|")
- If parts.length = 2 Then
- globals.SetOption(option, parts[0].trim(), parts[1].Trim())
- End If
- End Function
-
- Method hasCCopt:Int(value:String)
- Return cc_opts.find(value) >= 0
- End Method
- Method hasCPPopt:Int(value:String)
- Return cpp_opts.find(value) >= 0
- End Method
- Method hasCopt:Int(value:String)
- Return c_opts.find(value) >= 0
- End Method
- Method hasASMopt:Int(value:String)
- Return asm_opts.find(value) >= 0
- End Method
- Method hasLDopt:Int(value:String)
- For Local opt:String = EachIn ld_opts
- If opt.find(value) >= 0 Then
- Return True
- End If
- Next
- Return False
- End Method
- Function setPath:String(value:String, path:String)
- If value.Contains("%PWD%") Then
- If FileType(path) = FILETYPE_FILE Then
- path = ExtractDir(path)
- End If
- Return value.Replace("%PWD%", path)
- End If
-
- ' var replace
- Local s:Int = value.Find("%")
- If s >= 0 Then
- Local e:Int = value.Find("%", s + 1)
- If e >= 0 Then
- Local v:String = value[s+1..e]
- value = value[..s] + processor.option(v, "NA") + value[e+1..]
- End If
- End If
-
- Return value
- End Function
-
- End Type
- Global mod_opts:TModOpt ' BaH
- Function Match:Int( ext$,pat$ )
- Return (";"+pat+";").Find( ";"+ext+";" )<>-1
- End Function
- Function HTTPEsc$( t$ )
- t=t.Replace( " ","%20" )
- Return t
- End Function
- Function Sys:Int( cmd$ )
- If opt_verbose
- Print cmd
- Else If opt_dumpbuild
- Local p$=cmd
- p=p.Replace( BlitzMaxPath()+"/","./" )
- WriteStdout p+"~n"
- Local t$="mkdir "
- If cmd.StartsWith( t ) And FileType( cmd[t.length..] ) Return 0
- EndIf
- Return system_( cmd )
- End Function
- Function Ranlib( dir$ )
- '
- ?MacOS
- If macos_version>=$1040 Return
- ?
- '
- For Local f$=EachIn LoadDir( dir )
- Local p$=dir+"/"+f
- Select FileType( p )
- Case FILETYPE_DIR
- Ranlib p
- Case FILETYPE_FILE
- If ExtractExt(f).ToLower()="a" Sys "ranlib "+p
- End Select
- Next
- End Function
- Function Assemble( src$,obj$ )
- processor.RunCommand("assemble", [src, obj])
- End Function
- Function AssembleNative( src$, obj$, opts:String )
- processor.RunCommand("assembleNative", [src, obj, opts])
- End Function
- Function Fasm2As( src$,obj$ )
- processor.RunCommand("fasm2as", [src, obj])
- End Function
- Function CompileC( src$,obj$,opts$ )
- processor.RunCommand("CompileC", [src, obj, opts])
- End Function
- Function CompileBMX( src$,obj$,opts$ )
-
- If processor.BCCVersion() <> "BlitzMax" Then
- opts :+ " -p " + processor.Platform()
- End If
-
- If opt_standalone opt_nolog = True
-
- processor.RunCommand("CompileBMX", [src, obj, opts])
- If opt_standalone opt_nolog = False
- End Function
- Function CreateMergeArc( path$ , arc_path:String )
- Local cmd$
- If processor.Platform() = "ios" Then
- Local proc:String = processor.CPU()
- Local opp:String
- Select proc
- Case "x86"
- proc = "i386"
- opp = "x86_64"
- Case "x64"
- proc = "x86_64"
- opp = "i386"
- Case "armv7"
- opp = "arm64"
- Case "arm64"
- opp = "armv7"
- End Select
-
- cmd = "lipo "
- If Not FileType(path) Then
- cmd :+ "-create -arch_blank " + opp + " -arch "
- Else
- cmd :+ CQuote(path)
- cmd :+ " -replace "
- End If
-
- cmd :+ proc + " " + CQuote(arc_path)
-
- cmd :+ " -output " + CQuote(path)
- End If
- If cmd And processor.MultiSys( cmd, path, Null, Null )
- DeleteFile path
- Throw "Build Error: Failed to merge archive " + path
- EndIf
- End Function
- Function LinkApp( path$,lnk_files:TList,makelib:Int,opts$ )
- If processor.Platform() = "ios" Then
- PackageIOSApp(path, lnk_files, opts)
- Return
- End If
- DeleteFile path
- Local cmd$
- Local files$
- Local tmpfile$=BlitzMaxPath()+"/tmp/ld.tmp"
-
- Local sb:TStringBuffer = New TStringBuffer
- Local fb:TStringBuffer = New TStringBuffer
-
- If opt_standalone tmpfile = String(globals.GetRawVar("EXEPATH")) + "/ld." + processor.AppDet() + ".txt.tmp"
-
- If processor.Platform() = "macos" Or processor.Platform() = "osx" Then
- sb.Append(processor.Option(processor.BuildName("gpp"), "g++"))
- Select processor.CPU()
- Case "ppc"
- sb.Append(" -arch ppc" )
- Case "x86"
- sb.Append(" -arch i386 -read_only_relocs suppress")
- Case "x64"
- sb.Append(" -arch x86_64")
- Case "arm64"
- sb.Append(" -arch arm64")
- End Select
-
- If processor.Option(processor.BuildName("sysroot"), "") Then
- sb.Append(" -isysroot ").Append(processor.Option(processor.BuildName("sysroot"), ""))
- End If
-
- sb.Append(" -o ").Append(CQuote( path ))
-
- If opt_debug Or opt_gdbdebug Then
- sb.Append(" -g")
- End If
- If processor.BCCVersion() = "BlitzMax" Then
- sb.Append(" ").Append(CQuote("-L" +CQuote( BlitzMaxPath()+"/lib" ) ))
- End If
-
- If Not opt_dumpbuild Then
- sb.Append(" -filelist ").Append(CQuote( tmpfile ))
- End If
- For Local t$=EachIn lnk_files
- If opt_dumpbuild Or (t[..1]="-") Or (t[..1]="`")
- sb.Append(" ").Append(t)
- Else
- fb.Append(t).Append(Chr(10))
- EndIf
- Next
- sb.Append(" -lSystem -framework CoreServices -framework CoreFoundation")
- If opts Then
- sb.Append(" ").Append(opts)
- End If
-
- If processor.CPU() = "ppc"
- sb.Append(" -lc -lgcc_eh")
- End If
-
- End If
-
- If processor.Platform() = "win32"
- Local ext:String = ""
- ?win32
- ext = ".exe"
- ?
- Local version:Int = Int(processor.GCCVersion(True))
- Local usingLD:Int = False
- Local options:TStringBuffer = fb
- If processor.HasClang() Then
- options = sb
- End If
- ' always use g++ instead of LD...
- ' uncomment if we want to change to only use LD for GCC's < 4.x
- 'If version < 40000 Then
- ' usingLD = True
- 'End If
- ' or we can override in the config...
- If globals.Get("link_with_ld") Or (version >= 40600 And version < 60000) Then
- usingLD = True
- End If
-
- Local blitzMaxLibDir:String = "/lib"
- If processor.CPU()="x64" Then
- blitzMaxLibDir = "/lib64"
- End If
- If usingLD Then
- sb.Append(CQuote(processor.Option("path_to_ld", processor.MinGWBinPath()+ "/ld" + ext))).Append(" -stack 4194304")
- If Not opt_debug And Not opt_gdbdebug Then
- sb.Append(processor.option("strip.debug", " -s "))
- End If
- If opt_apptype="gui" Then
- sb.Append(" -subsystem windows")
- End If
- Else
- Local prefix:String = processor.MinGWExePrefix()
- sb.Append(CQuote(processor.Option("path_to_gpp", processor.MinGWBinPath() + "/" + prefix + "g++" + ext)))
- If Not processor.HasClang() Then
- If version < 60000 Then
- sb.Append(" --stack=4194304")
- Else
- sb.Append(" -Wl,--stack,4194304")
- End If
- End If
- If Not opt_debug And Not opt_gdbdebug Then
- sb.Append(processor.option("strip.debug", " -s "))
- End If
- If opt_apptype="gui"
- If version < 60000 Then
- sb.Append(" --subsystem,windows -mwindows")
- Else
- sb.Append(" -Wl,--subsystem,windows -mwindows")
- End If
- Else
- If Not makelib
- sb.Append(" -mconsole")
- End If
- End If
-
- If opt_threaded Then
- If version < 60000 Then
- sb.Append(" -mthread")
- Else
- sb.Append(" -mthreads")
- End If
- End If
- End If
- If makelib Then
- sb.Append(" -shared")
- If processor.Platform() = "win32" Then
- sb.Append(" -static-libgcc")
- End If
- Else
- sb.Append(" -static")
-
- If opt_gprof Then
- sb.Append(" -pg")
- End If
- End If
-
- sb.Append(" -o ").Append(CQuote( path ))
- If usingLD Then
- If processor.CPU()="x86"
- sb.Append(" ").Append(processor.MinGWLinkPaths()) ' the BlitzMax lib folder
-
- ' linking for x86 when using mingw64 binaries
- If processor.HasTarget("x86_64") Then
- sb.Append(" -mi386pe")
- End If
- Else
- sb.Append(" ").Append(processor.MinGWLinkPaths()) ' the BlitzMax lib folder
- End If
- If globals.Get("path_to_mingw_lib") Then
- sb.Append(" ").Append(CQuote( "-L"+CQuote( RealPath(processor.Option("path_to_mingw_lib", BlitzMaxPath()+"/lib") ) ) ))
- End If
- If globals.Get("path_to_mingw_lib2") Then
- sb.Append(" ").Append(CQuote( "-L"+CQuote( RealPath(processor.Option("path_to_mingw_lib2", BlitzMaxPath()+"/lib") ) ) ))
- End If
- If globals.Get("path_to_mingw_lib3") Then
- sb.Append(" ").Append(CQuote( "-L"+CQuote( RealPath(processor.Option("path_to_mingw_lib3", BlitzMaxPath()+"/lib") ) ) ))
- End If
- End If
-
- If makelib
- Local def$=StripExt(path)+".def"
- Local imp$=StripExt(path)+".a"
- If FileType( def )<>FILETYPE_FILE Then
- Print "Warning: Cannot locate .def file (" + def + "). Exporting ALL symbols."
- Else
- sb.Append(" ").Append(CQuote( def ))
- End If
-
- If version < 60000 Then
- sb.Append(" --out-implib ").Append(CQuote( imp ))
- If usingLD Then
- options.Append(" ").Append(CQuote( RealPath(processor.Option("path_to_mingw_lib", processor.MinGWDLLCrtPath()) + "/dllcrt2.o" ) ))
- End If
- Else
- sb.Append(" -Wl,--out-implib,").Append(CQuote( imp ))
- End If
- Else
- If usingLD
- fb.Append(" ").Append(CQuote( RealPath(processor.Option("path_to_mingw_lib2", processor.MinGWCrtPath()) + "/crtbegin.o" ) ))
- fb.Append(" ").Append(CQuote( RealPath(processor.Option("path_to_mingw_lib", processor.MinGWDLLCrtPath()) + "/crt2.o" ) ))
- End If
- EndIf
-
- Local xpmanifest$
- For Local f$=EachIn lnk_files
- Local t$=CQuote( f )
- If processor.HasClang() Then
- If f.StartsWith("-l") Then
- f = f.Replace(" ", "~n")
- End If
- t = f.Replace("\", "/").Replace(" ", "\ ").Replace("'", "\'")
- End If
- If opt_dumpbuild Or (t[..1]="-" And t[..2]<>"-l")
- sb.Append(" ").Append(t)
- Else
- If f.EndsWith( "/win32maxguiex.mod/xpmanifest.o" )
- xpmanifest=t
- Else
- If processor.HasClang() Then
- fb.Append("~n").Append(t)
- Else
- fb.Append(" ").Append(t)
- End If
- EndIf
- EndIf
- Next
- If xpmanifest Then
- If processor.HasClang() Then
- fb.Append("~n").Append(xpmanifest)
- Else
- fb.Append(" ").Append(xpmanifest)
- End If
- End If
-
- sb.Append(" ")
- If processor.HasClang() Then
- sb.Append("@")
- End If
- sb.Append(CQuote( tmpfile ))
-
- options.Append(" -lgdi32 -lwsock32 -lwinmm -ladvapi32")
- ' add any user-defined linker options
- options.Append(" ").Append(opts)
- If usingLD
- If opts.Find("stdc++") = -1 Then
- options.Append(" -lstdc++")
- End If
- options.Append(" -lmingwex")
-
-
- ' for a native Win32 runtiime of mingw 3.4.5, this needs to appear early.
- 'If Not processor.Option("path_to_mingw", "") Then
- options.Append(" -lmingw32")
- 'End If
- If opts.Find("gcc") = -1 Then
- options.Append(" -lgcc")
- End If
- ' if using 4.8+ or mingw64, we need to link to pthreads
- If version >= 40800 Or processor.HasTarget("x86_64") Or processor.HasClang() Then
- options.Append(" -lwinpthread ")
-
- If processor.CPU()="x86" Then
- options.Append(" -lgcc")
- End If
- End If
-
- options.Append(" -lmoldname -lmsvcrt ")
- End If
- options.Append(" -luser32 -lkernel32 ")
- 'If processor.Option("path_to_mingw", "") Then
- ' for a non-native Win32 runtime, this needs to appear last.
- ' (Actually, also for native gcc 4.x, but I dunno how we'll handle that yet!)
- If usingLD
- options.Append(" -lmingw32 ")
- End If
- ' add any user-defined linker options, again - just to cover whether we missed dependencies before.
- options.Append(" ").Append(opts)
- 'End If
-
- If Not makelib
- If usingLD
- options.Append(" ").Append(CQuote( processor.Option("path_to_mingw_lib2", processor.MinGWCrtPath()) + "/crtend.o" ))
- End If
- EndIf
-
- If Not processor.HasClang() Then
- fb.Insert(0,"INPUT(").Append(")")
- End If
- End If
-
- If processor.Platform() = "linux" Or processor.Platform() = "raspberrypi" Or processor.Platform() = "haiku"
- sb.Append(processor.Option(processor.BuildName("gpp"), "g++"))
- 'cmd:+" -m32 -s -Os -pthread"
- If processor.Platform() <> "raspberrypi" And processor.Platform() <> "haiku" Then
- If processor.CPU() = "x86" Or processor.CPU() = "arm" Then
- sb.Append(" -m32")
- End If
- If processor.CPU() = "x64" Then
- sb.Append(" -m64")
- End If
- End If
- If opt_static Then
- sb.Append(" -static")
- End If
- If processor.Platform() <> "haiku" And Not opt_nopie Then
- sb.Append(" -no-pie -fpie")
- End If
- If opt_gprof Then
- sb.Append(" -pg")
- End If
-
- If processor.Platform() <> "haiku" Then
- sb.Append(" -pthread")
- Else
- sb.Append(" -lpthread")
- End If
-
- sb.Append(" -o ").Append(CQuote( path ))
- sb.Append(" ").Append(CQuote( tmpfile ))
-
- If processor.Platform() <> "haiku" Then
- If processor.CPU() = "x86" Then
- sb.Append(" -L").Append(processor.Option(processor.BuildName("lib32"), "/usr/lib32"))
- End If
- sb.Append(" -L").Append(processor.Option(processor.BuildName("x11lib"), "/usr/X11R6/lib"))
- sb.Append(" -L").Append(processor.Option(processor.BuildName("lib"), "/usr/lib"))
- Else
- sb.Append(" -L").Append(CQuote( "/boot/system/develop/lib" ))
- sb.Append(" -L").Append(CQuote( BlitzMaxPath()+"/lib" ))
- End If
-
- For Local t$=EachIn lnk_files
- t=CQuote(t)
- If opt_dumpbuild Or (t[..1]="-" And t[..2]<>"-l") Or (t[..1]="`")
- sb.Append(" ").Append(t)
- Else
- fb.Append(" ").Append(t)
- EndIf
- Next
-
- fb.Insert(0,"INPUT(").Append(")")
- End If
-
- If processor.Platform() = "android" Then
- sb.Append(processor.Option(processor.BuildName("gpp"), "g++"))
-
- Local libso:String = StripDir(path)
- sb.Append(" -fPIC -shared ")
-
- ' for stlport shared lib
- sb.Append(" -L").Append(AndroidSTLPortDir())
-
- sb.Append(" -Wl,-soname,lib").Append(libso).Append(".so ")
- sb.Append(" -Wl,--export-dynamic -rdynamic ")
- sb.Append(" -o ").Append(CQuote( ExtractDir(path) + "/lib" + libso + ".so" ))
- sb.Append(" ").Append(CQuote( tmpfile ))
- sb.Append(" ").Append(processor.Option("android.platform.sysroot", ""))
-
- For Local t$=EachIn lnk_files
- t=CQuote(t)
- If opt_dumpbuild Or (t[..1]="-" And t[..2]<>"-l")
- sb.Append(" ").Append(t)
- Else
- fb.Append(" ").Append(t)
- EndIf
- Next
-
- sb.Append(" -Wl,-Bdynamic -lGLESv2 -lGLESv1_CM ")
- ' libstlport
- sb.Append(" -lstlport_shared")
- sb.Append(" -llog -ldl -landroid ")
-
- fb.Insert(0,"INPUT(").Append(")")
- End If
- If processor.Platform() = "emscripten"
- sb.Append(processor.Option(processor.BuildName("gpp"), "em++"))
- ' cmd:+" -pthread" ' No threading support yet...
- sb.Append(" -o ").Append(CQuote( path ))
- 'cmd:+" -filelist "+CQuote( tmpfile )
-
- sb.Append(" ").Append(opts)
-
- For Local t$=EachIn lnk_files
- t=CQuote(t)
- 'If opt_dumpbuild Or (t[..1]="-" And t[..2]<>"-l")
- sb.Append(" ").Append(t)
- 'Else
- ' files:+" "+t
- 'EndIf
- Next
-
- fb.Insert(0,"INPUT(").Append(")")
- End If
-
- If processor.Platform() = "nx" Then
- sb.Append(processor.Option(processor.BuildName("gpp"), "g++"))
-
- Local libso:String = StripDir(path)
- sb.Append(" -MMD -MP -MF ")
- sb.Append(" -march=armv8-a -mtune=cortex-a57 -mtp=soft -fPIE ")
-
- sb.Append(" -specs=").Append(processor.Option("nx.devkitpro", "")).Append("/libnx/switch.specs")
- sb.Append(" -g")
- 'sb.Append(" -Wl,-Map,").Append(StripExt(path)).Append(".map")
-
- sb.Append(" -L").Append(NXLibDir())
-
- sb.Append(" -o ").Append(CQuote( path ))
- sb.Append(" ").Append(CQuote( tmpfile ))
-
- Local endLinks:TList = New TList
-
- For Local t$=EachIn lnk_files
- t=CQuote(t)
- If opt_dumpbuild Or (t[..1]="-" And t[..2]<>"-l") Or (t[..1]="`")
- sb.Append(" ").Append(t)
- Else
- If t.Contains("appstub") Or t.Contains("blitz.mod") Then
- endLinks.AddLast(t)
- Continue
- End If
- fb.Append(" ").Append(t)
- EndIf
- Next
- fb.Append(" -lnx -lm")
- For Local t:String = EachIn endLinks
- fb.Append(" ").Append(t)
- Next
- fb.Insert(0,"INPUT(").Append(")")
- End If
- Local t$=getenv_( "BMK_LD_OPTS" )
- If t
- sb.Append(" ").Append(t)
- EndIf
-
- cmd = sb.ToString()
- files = fb.ToString()
- If Not opt_standalone Then
- Local stream:TStream=WriteStream( tmpfile )
- stream.WriteBytes files.ToCString(),files.length
- stream.Close
- End If
- If processor.Sys( cmd ) Throw "Build Error: Failed to link "+path
- If opt_standalone
- Local stream:TStream=WriteStream( StripExt(tmpfile) )
- Local f:String = processor.FixPaths(files)
- stream.WriteBytes f.ToCString(),f.length
- stream.Close
- End If
- End Function
- Function MergeApp(file1:String, file2:String, outputFile:String)
- If Not opt_quiet Print "[100%] Merging:"+StripDir(file1) + " + " + StripDir(file2) + " > " + StripDir(outputFile)
- Local cmd:String = "lipo -create ~q" + file1 + "~q ~q" + file2 + "~q -output ~q" + outputFile + "~q"
-
- If processor.Sys( cmd ) Throw "Merge Error: Failed to merge " + file1 + " and " + file2 + " into " + outputFile
-
- DeleteFile file1
- DeleteFile file2
- End Function
- Function DeployAndroidProject()
- Local appId:String = StripDir(StripExt(opt_outfile))
- If opt_debug And opt_outfile.EndsWith(".debug") Then
- appId :+ ".debug"
- End If
- Local buildDir:String = ExtractDir(opt_outfile)
- ' eg. android-project-test_01
- Local projectDir:String = buildDir + "/android-project-" + appId '+ "-" + processor.CPU()
- ' check for dir
- If Not FileType(projectDir) Then
- ' doesn't exist. create it
- Local resourceProject:String = BlitzMaxPath() + "/resources/android/android-project"
- If Not FileType(resourceProject) Then
- Throw "Missing resources folder for Android build : " + resourceProject
- End If
-
- CopyDir(resourceProject, projectDir)
- End If
-
- ' check for valid dir
- If FileType(projectDir) <> FILETYPE_DIR Then
- Throw "Error creating project dir '" + projectDir + "'"
- End If
-
- ' create assets dir if missing
- Local assetsDir:String = projectDir + "/assets"
-
- If opt_all Then
- ' remove assets if we are doing a full build
- DeleteDir(assetsDir, True)
- End If
-
- If FileType(assetsDir) <> FILETYPE_DIR Then
- CreateDir(assetsDir)
- If FileType(assetsDir) <> FILETYPE_DIR Then
- Throw "Error creating assests dir '" + assetsDir + "'"
- End If
- End If
- ' create libs/abi dir if missing
- Local abiDir:String = projectDir + "/libs"
- If FileType(abiDir) <> FILETYPE_DIR Then
- CreateDir(abiDir)
- If FileType(abiDir) <> FILETYPE_DIR Then
- Throw "Error creating libs dir '" + abiDir + "'"
- End If
- End If
-
- abiDir :+ "/" + GetAndroidArch()
- If FileType(abiDir) <> FILETYPE_DIR Then
- CreateDir(abiDir)
- If FileType(abiDir) <> FILETYPE_DIR Then
- Throw "Error creating libs abi dir '" + abiDir + "'"
- End If
- End If
-
- ' copy stlport
- Local stlportDest:String = abiDir + "/libstlport_shared.so"
-
- If opt_all Or Not FileType(stlportDest) Then
- Local stlportSrc:String = AndroidSTLPortDir() + "/libstlport_shared.so"
-
- CopyFile(stlportSrc, stlportDest)
-
- If Not FileType(stlportDest) Then
- Throw "Error copying libstlport_shared.so from '" + stlportSrc + "'"
- End If
- End If
-
- Local projectSettings:TMap = ParseApplicationIniFile()
-
- Local appPackage:String = String(projectSettings.ValueForKey("app.package"))
-
- Local packagePath:String = projectDir + "/src/" + PathFromPackage(appPackage)
-
- ' create the package
- If Not FileType(packagePath) Then
- CreateDir(packagePath, True)
-
- If FileType(packagePath) <> FILETYPE_DIR Then
- Throw "Error creating package '" + packagePath + "'"
- End If
- End If
-
- ' copy/create java
- Local gameClassFile:String = packagePath+ "/BlitzMaxApp.java"
-
- If Not FileType(gameClassFile) Then
- CopyFile(projectDir + "/BlitzMaxApp.java", gameClassFile)
-
- If Not FileType(gameClassFile) Then
- Throw "Error creating class file '" + gameClassFile + "'"
- End If
- End If
-
- ' merge project data
- ' update AndroidManifest.xml
- MergeFile(projectDir, "AndroidManifest.xml", projectSettings)
-
- ' update BlitzMaxApp.java
- MergeFile(packagePath, "BlitzMaxApp.java", projectSettings)
-
- Local javaApp:String = LoadString( gameClassFile )
- ' set the package
- javaApp = ReplaceBlock( javaApp, "app.package","package " + appPackage + ";" )
- ' lib imports
- javaApp = ReplaceBlock( javaApp, "lib.imports", GetAndroidLibImports() )
- SaveString(javaApp, gameClassFile)
- ' update strings.xml
- MergeFile(projectDir + "/res/values", "strings.xml", projectSettings)
- ' update build.xml
- MergeFile(projectDir, "build.xml", projectSettings)
- ' set the sdk target
- Local projectPropertiesFile:String = projectDir + "/project.properties"
- Local projectProperties:String = LoadString( projectPropertiesFile )
- projectProperties = ReplaceBlock( projectProperties, "sdk.target","target=android-" + processor.option("android.sdk.target", ""), "~n#")
- SaveString(projectProperties, projectPropertiesFile)
- ' copy resources to assets
- CopyAndroidResources(buildDir, assetsDir)
- End Function
- Function GetAndroidLibImports:String()
- Local imports:String
-
- imports = "System.loadLibrary( ~qstlport_shared~q);~n"
-
- ' TODO : others imported via project...
-
- Return imports
- End Function
- Function GetAndroidArch:String()
- Local arch:String
- Select processor.CPU()
- Case "x86"
- arch = "x86"
- Case "x64"
- arch = "x86_64"
- Case "arm"
- arch = "armeabi-v7a"
- Case "armeabi"
- arch = "armeabi"
- Case "armeabiv7a"
- arch = "armeabi-v7a"
- Case "arm64v8a"
- arch = "arm64-v8a"
- Default
- Throw "Not a valid architecture '" + processor.CPU() + "'"
- End Select
- Return arch
- End Function
- Function AndroidSTLPortDir:String()
- Return processor.Option("android.ndk", "") + "/sources/cxx-stl/stlport/libs/" + GetAndroidArch()
- End Function
- Function CopyAndroidResources(buildDir:String, assetsDir:String)
- Local paths:String[] = SplitPaths(String(globals.GetRawVar("resource_path")))
-
- If paths Then
- For Local dir:String = EachIn paths
- Local resourceDir:String = buildDir + "/" + dir
-
- If Not FileType(resourceDir) Then
- Print "Warning : Defined resource_path '" + dir + "' not found"
- End If
-
- If FileType(resourceDir) = FILETYPE_DIR Then
-
- CopyDir assetsDir + "/" + dir, resourceDir
-
- End If
-
- Next
- End If
- End Function
- Function GetAndroidSDKTarget:String()
- Local sdkPath:String = processor.Option("android.sdk", "") + "/platforms"
- Local target:String = processor.Option("android.sdk.target", "")
-
- Local targetPath:String
-
- If target Then
- targetPath = sdkPath + "/android-" + target
-
- If FileType(targetPath) = FILETYPE_DIR Then
- Return target
- End If
-
- End If
-
- ' find highest numbered target platform dir
- Local dirs:String[] = LoadDir(sdkPath, True)
- Local high:Int
-
- For Local dir:String = EachIn dirs
-
- Local index:Int = dir.Find("android-")
-
- If index >= 0 Then
- Local value:Int = dir[index + 8..].ToInt()
- high = Max(value, high)
- End If
-
- Next
-
- If high > 0 Then
- Return high
- End If
-
- End Function
- Function NXLibDir:String()
- Return processor.Option("nx.devkitpro", "") + "/libnx/lib"
- End Function
- Function NxToolsDir:String()
- Return processor.Option("nx.devkitpro", "") + "/tools/bin"
- End Function
- Function BuildNxDependencies()
-
- BuildNxNso()
- BuildNxNacp()
- BuildNxNro()
-
- End Function
- Function BuildNxNso()
- If Not opt_quiet Print "Building:" + StripDir(StripExt(opt_outfile)) + ".nso"
- Local elf2nso:String = NxToolsDir() + "/elf2nso"
- ?win32
- elf2nso :+ ".exe"
- ?
- If Not FileType(elf2nso) Then
- Throw "elf2nso tool not present at " + elf2nso
- End If
- Local app:String = StripExt(opt_outfile)
-
- Local cmd:String = elf2nso + " " + CQuote(app + ".elf")
- cmd :+ " " + CQuote(app + ".nso")
-
- Sys(cmd)
- End Function
- Function BuildNxNacp()
- If Not opt_quiet Print "Building:" + StripDir(StripExt(opt_outfile)) + ".nacp"
- Local nacptool:String = NxToolsDir() + "/nacptool"
- ?win32
- nacptool :+ ".exe"
- ?
- If Not FileType(nacptool) Then
- Throw "nacptool tool not present at " + nacptool
- End If
- Local app:String = StripExt(opt_outfile)
-
- Local cmd:String = nacptool + " --create"
- Local name:String = processor.AppSetting("app.name")
- If Not name Then
- name = StripDir(StripExt(opt_outfile))
- End If
- cmd :+ " " + CQuote(name)
-
- Local auth:String = processor.AppSetting("app.company")
- If Not auth Then
- auth = "Unspecified Author"
- End If
- cmd :+ " " + CQuote(auth)
-
- Local ver:String = processor.AppSetting("app.version.name")
- If Not ver Then
- ver = "1.0.0"
- End If
- cmd :+ " " + CQuote(ver)
-
- cmd :+ " " + CQuote(app + ".nacp")
- Sys(cmd)
- End Function
- Function BuildNxNro()
- If Not opt_quiet Print "Building:" + StripDir(StripExt(opt_outfile)) + ".nro"
- Local elf2nro:String = NxToolsDir() + "/elf2nro"
- ?win32
- elf2nro :+ ".exe"
- ?
- If Not FileType(elf2nro) Then
- Throw "elf2nro tool not present at " + elf2nro
- End If
- ' get icon
- Local icon:String
- ' app.jpg
- ' TODO
- ' icon.jpg
- ' TODO
- ' default icon
- If Not icon Then
- icon = processor.Option("nx.devkitpro", "") + "/libnx/default_icon.jpg"
- If Not FileType(icon) Then
- Throw "Default icon not found at " + icon
- End If
- End If
-
- Local app:String = StripExt(opt_outfile)
-
- Local cmd:String = elf2nro + " " + CQuote(app + ".elf")
- cmd :+ " " + CQuote(app + ".nro")
- cmd :+ " --icon=" + CQuote(icon)
- cmd :+ " --nacp=" + CQuote(app + ".nacp")
-
- Local romfsDir:String = ExtractDir(opt_outfile) + "/romfs"
-
- If FileType(romfsDir) = FILETYPE_DIR Then
- cmd :+ " --romfsdir=" + CQuote(romfsDir)
- End If
-
- Sys(cmd)
- End Function
- Function PathFromPackage:String(package:String)
- Return package.Replace(".", "/")
- End Function
- Function MergeFile(dir:String, file:String, settings:TMap)
- Local s:String = LoadString(dir + "/" + file)
- s = ReplaceEnv(s, settings)
- SaveString(s, dir + "/" + file)
- End Function
- Function ReplaceEnv:String( str:String, settings:TMap )
- Local bits:TStringStack = New TStringStack
- Repeat
- Local i:Int = str.Find( "${" )
- If i=-1 Exit
- Local e:Int = str.Find( "}",i+2 )
- If e=-1 Exit
-
- If i>=2 And str[i-2..i] = "//" Then
- bits.AddLast str[..e+1]
- str = str[e+1..]
- Continue
- EndIf
-
- Local t:String = str[i+2..e]
- Local v:String = String(settings.ValueForKey(t))
- If Not v Then
- v = "${" + t + "}"
- End If
- bits.AddLast str[..i]
- bits.AddLast v
-
- str = str[e+1..]
- Forever
- If bits.IsEmpty() Then
- Return str
- End If
-
- bits.AddLast str
- Return bits.Join( "" )
- End Function
- Function ReplaceBlock:String( Text:String,tag:String,repText:String,mark:String="~n//" )
- 'find begin tag
- Local beginTag:String = mark+"${start."+tag+"}"
- Local i:Int = Text.Find( beginTag )
- If i=-1 Throw "Error updating target project - can't find block begin tag '"+tag+"'."
- i :+ beginTag.Length
- While i < Text.Length And Text[i-1]<>10
- i :+ 1
- Wend
-
- 'find end tag
- Local endTag:String = mark+"${end."+tag+"}"
- Local i2:Int = Text.Find( endTag,i-1 )
- If i2=-1 Throw "Error updating target project - can't find block end tag '"+tag+"'."
- If Not repText Or repText[repText.Length-1]=10 Then
- i2 :+ 1
- End If
-
- Return Text[..i]+repText+Text[i2..]
- End Function
- Function SplitPaths:String[](paths:String)
- Local split:String[] = New String[0]
-
- Local inQuote:Int
- Local token:String
- For Local i:Int = 0 Until paths.length
- Local char:Int = paths[i]
- If char = Asc("~q") Then
- inQuote = Not inQuote
- Else If char = Asc(" ") And Not inQuote Then
- token = token.Trim()
- If token Then
- split :+ [token]
- End If
- token = Null
- Else
- token :+ Chr(char)
- End If
- Next
-
- token = token.Trim()
- If token Then
- split :+ [token]
- End If
-
- Return split
- End Function
- Function PackageIOSApp( path$, lnk_files:TList, opts$ )
- Local templatePath:String = BlitzMaxPath() + "/resources/ios/template"
-
- If Not FileType(templatePath) Then
- Throw "iOS template dir is missing. Expecting it at '" + templatePath + "'"
- End If
-
- Local appId:String = StripDir(StripExt(opt_outfile))
- Local appPath:String = ExtractDir(opt_outfile)
-
- Local appProjectDir:String = appPath + "/" + appId + ".xcodeproj"
- If opt_all Then
- DeleteDir appProjectDir, True
- End If
- If Not FileType(appProjectDir) Then
- CopyDir templatePath + "/project.xcodeproj", appProjectDir
- End If
-
-
- Local projectPath:String = appProjectDir + "/project.pbxproj"
-
- Local uuid:String = "5CABB1EFACE"
- Local fileMap:TFileMap = New TFileMap
-
- For Local f:String = EachIn lnk_files
- Local kind:Int
- Select ExtractExt(f)
- Case "a"
- kind = TFileID.TYPE_ARC
- Case "o"
- kind = TFileID.TYPE_OBJ
- Case "dylib"
- kind = TFileID.TYPE_DYL
- Default
- If f.StartsWith("-l") Then
- kind = TFileID.TYPE_DYL
- End If
- If f.StartsWith("-framework") Then
- kind = TFileID.TYPE_FRM
- End If
- End Select
- fileMap.FileId(f, uuid, TFileMap.BUILD, kind)
- Next
-
- ' add project-specific resource paths?
- Local paths:String[] = SplitPaths(String(globals.GetRawVar("resource_path")))
- If paths Then
- For Local f:String = EachIn paths
- fileMap.FileId(f, uuid, TFileMap.BUILD, TFileID.TYPE_DIR)
- Next
- End If
- Local project:String = LoadString(projectPath)
- ' clean project
- project = iOSProjectClean(project, uuid)
-
- project = iOSProjectAppendFiles(project, uuid, fileMap)
- project = project.Replace("${PROJECT}", appId)
- project = project.Replace("${PROJECT_STRIPPED}", iOSFixAppId(appId))
- project = project.Replace("${COMPANY_IDENTIFIER}", processor.option("company_identifier", "com.mycompany"))
- project = project.Replace("${TEAM_ID}", processor.option("developer_team_id", "developer_team_id"))
-
- SaveString(project, projectPath)
-
- iOSCopyDefaultFiles(templatePath, appPath)
-
- End Function
- Function iOSFixAppId:String(id:String)
- id = id.Replace(" ", "") ' no spaces
- id = id.Replace("_", "") ' no underscores
- Return id
- End Function
- Function iOSCopyDefaultFiles(templatePath:String, appPath:String)
- Local iconSrc:String = templatePath + "/Icon.png"
- Local iconDest:String = appPath + "/Icon.png"
-
- Local defaultSrc:String = templatePath + "/Default.png"
- Local defaultDest:String = appPath + "/Default.png"
- Local default2Src:String = templatePath + "/[email protected]"
- Local default2Dest:String = appPath + "/[email protected]"
- Local plistSrc:String = templatePath + "/Info.plist"
- Local plistDest:String = appPath + "/Info.plist"
-
- If opt_all Or Not FileType(iconDest) Then
- CopyFile iconSrc, iconDest
- End If
- If opt_all Or Not FileType(defaultDest) Then
- CopyFile defaultSrc, defaultDest
- End If
- If opt_all Or Not FileType(default2Dest) Then
- CopyFile default2Src, default2Dest
- End If
- If opt_all Or Not FileType(plistDest) Then
- CopyFile plistSrc, plistDest
- End If
- End Function
- Function iOSProjectClean:String(Text:String, uuid:String)
-
- Local stack:TStringStack = New TStringStack
-
- For Local line:String = EachIn Text.Split("~n")
-
- If Not line.Trim().StartsWith(uuid) Then
- stack.AddLast(line)
- End If
-
- Next
- Return stack.Join("~n")
- End Function
- Function iOSProjectAppendFiles:String(Text:String, uuid:String, fileMap:TFileMap)
-
- Local offset:Int = -1
-
- offset = FindEol(Text, "/* Begin PBXBuildFile section */")
- If offset = -1 Then
- Return ""
- End If
- Text = Text[..offset] + iOSProjectBuildFiles(uuid, fileMap) + Text[offset..]
- offset = FindEol(Text,"/* Begin PBXFileReference section */")
- If offset = -1 Then
- Return ""
- End If
- Text = Text[..offset] + iOSProjectFileRefs(uuid, fileMap) + Text[offset..]
-
- offset = FindEol(Text,"/* Begin PBXFrameworksBuildPhase section */")
- If offset <> -1 Then
- offset = FindEol(Text,"/* Frameworks */ = {",offset)
- End If
- If offset <> -1 Then
- offset = FindEol(Text,"files = (",offset)
- End If
- If offset = -1 Then
- Return ""
- End If
- Text = Text[..offset] + iOSProjectFrameworksBuildPhase(uuid, fileMap) + Text[offset..]
-
- offset = FindEol(Text,"/* Begin PBXResourcesBuildPhase section */")
- If offset <> -1 Then
- offset = FindEol(Text,"/* Resources */ = {",offset)
- End If
- If offset <> -1 Then
- offset = FindEol(Text,"files = (",offset)
- End If
- If offset = -1 Then
- Return ""
- End If
- Text = Text[..offset] + iOSProjectResourcesBuildPhase(uuid, fileMap) + Text[offset..]
-
- offset = FindEol(Text,"/* Begin PBXGroup section */")
- If offset <> -1 Then
- offset = FindEol(Text,"/* Resources */ = {",offset)
- End If
- If offset <> -1 Then
- offset = FindEol(Text,"children = (",offset)
- End If
- If offset = -1 Then
- Return ""
- End If
- Text = Text[..offset] + iOSProjectResourcesGroup(uuid, fileMap) + Text[offset..]
- offset = FindEol(Text,"/* Begin PBXGroup section */")
- If offset <> -1 Then
- offset = FindEol(Text,"/* Frameworks */ = {",offset)
- End If
- If offset <> -1 Then
- offset = FindEol(Text,"children = (",offset)
- End If
- If offset = -1 Then
- Return ""
- End If
- Text = Text[..offset] + iOSProjectFrameworksGroup(uuid, fileMap) + Text[offset..]
-
- offset = FindEol(Text,"/* Begin PBXGroup section */")
- If offset <> -1 Then
- offset = FindEol(Text,"/* libs */ = {",offset)
- End If
- If offset <> -1 Then
- offset = FindEol(Text,"children = (",offset)
- End If
- If offset = -1 Then
- Return ""
- End If
- Text = Text[..offset] + iOSProjectLibsGroup(uuid, fileMap) + Text[offset..]
- offset = FindEol(Text,"/* Begin PBXGroup section */")
- If offset <> -1 Then
- offset = FindEol(Text,"/* Objects */ = {",offset)
- End If
- If offset <> -1 Then
- offset = FindEol(Text,"children = (",offset)
- End If
- If offset = -1 Then
- Return ""
- End If
- Text = Text[..offset] + iOSProjectObjectsGroup(uuid, fileMap) + Text[offset..]
- offset = FindEol(Text,"/* Begin XCBuildConfiguration section */")
- If offset <> -1 Then
- offset = FindEol(Text,"/* Debug */ = {",offset)
- End If
- If offset <> -1 Then
- offset = FindEol(Text,"LIBRARY_SEARCH_PATHS = (",offset)
- End If
- If offset = -1 Then
- Return ""
- End If
- Text = Text[..offset] + iOSProjectLibSearchPaths(uuid, fileMap) + Text[offset..]
- offset = FindEol(Text,"/* Begin XCBuildConfiguration section */")
- If offset <> -1 Then
- offset = FindEol(Text,"/* Release */ = {",offset)
- End If
- If offset <> -1 Then
- offset = FindEol(Text,"LIBRARY_SEARCH_PATHS = (",offset)
- End If
- If offset = -1 Then
- Return ""
- End If
- Text = Text[..offset] + iOSProjectLibSearchPaths(uuid, fileMap) + Text[offset..]
- Return Text
- End Function
- Function iOSProjectBuildFiles:String(uuid:String, fileMap:TFileMap)
- Local stack:TStringStack = New TStringStack
- For Local f:TFileId = EachIn fileMap.buildFiles
- Local path:String = f.path
- Local id:String = f.id
- Local fileRef:String = fileMap.FileId(path, uuid, TFileMap.REF, f.kind)
- Local dir:String = ExtractDir(path)
- Local name:String = StripDir(path)
- If path.StartsWith("-framework") Then
- name = path[11..]
- End If
-
- Select f.kind
- Case TFileId.TYPE_ARC, TFileId.TYPE_OBJ, TFileId.TYPE_DYL
- stack.AddLast "~t~t" + id + " /* " + name + " */ = {isa = PBXBuildFile; fileRef = " + fileRef + "; };"
- Case TFileId.TYPE_DIR
- stack.AddLast "~t~t" + id + " /* " + name + " in Resources */ = {isa = PBXBuildFile; fileRef = " + fileRef + "; };"
- Case TFileId.TYPE_LIB, TFileId.TYPE_FRM
- stack.AddLast "~t~t" + id + " /* " + name + " in Frameworks */ = {isa = PBXBuildFile; fileRef = " + fileRef + "; };"
- End Select
- Next
-
- If stack.Count() Then
- stack.AddLast ""
- End If
-
- Return stack.Join("~n")
- End Function
- Function iOSProjectFileRefs:String(uuid:String, fileMap:TFileMap)
- Local stack:TStringStack = New TStringStack
- For Local path:String = EachIn fileMap.refFiles.Keys()
- Local id:String = String(fileMap.refFiles.ValueForKey(path))
- Local dir:String = ExtractDir(path)
- Local name:String = StripDir(path)
-
- Local fid:TFileId = fileMap.GetBuildFileIdForPath(path)
-
- Select fid.kind
- Case TFileId.TYPE_ARC
- stack.AddLast "~t~t" + id + " /* " + name + " */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = " + name + "; path = ~q" + path + "~q; sourceTree = ~q<absolute>~q; };"
- Case TFileId.TYPE_OBJ
- stack.AddLast "~t~t" + id + " /* " + name + " */ = {isa = PBXFileReference; lastKnownFileType = ~qcompiled.mach-o.objfile~q; name = " + name + "; path = ~q" + path + "~q; sourceTree = ~q<absolute>~q; };"
- Case TFileId.TYPE_DYL
- stack.AddLast "~t~t" + id + " /* " + name + " */ = {isa = PBXFileReference; lastKnownFileType = ~qcompiled.mach-o.dylib~q; name = " + name + "; path = ~q" + path + "~q; sourceTree = ~q<absolute>~q; };"
- Case TFileId.TYPE_DIR
- stack.AddLast "~t~t" + id + " = {isa = PBXFileReference; lastKnownFileType = folder; path = ~q" + path + "~q; sourceTree = SOURCE_ROOT; };"
- Case TFileId.TYPE_LIB
- name = "lib" + path[2..] + ".a"
- Local found:Int = False
- ' path should be provided as a -L...
- For Local p:String = EachIn fileMap.refFiles.Keys()
- If p.StartsWith("-L") Then
- Local libPath:String = p[2..].Replace("~q", "") + "/" + name
- If FileType(libPath) Then
- found = True
- stack.AddLast "~t~t" + id + " /* " + name + " */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = " + name + "; path = ~q" + libPath + "~q; sourceTree = ~q<absolute>~q; };"
- Exit
- End If
- End If
- Next
- If Not found Then
- Print "WARNING : could not find file for library import '" + path + "'. Maybe LD_OPTS: -L... was not defined?"
- End If
- Case TFileId.TYPE_FRM
- name = path[11..]
- stack.AddLast "~t~t" + id + " /* " + name + " */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = " + name + ".framework; path = System/Library/Frameworks/" + name + ".framework; sourceTree = SDKROOT; };"
- End Select
- Next
-
- If stack.Count() Then
- stack.AddLast ""
- End If
-
- Return stack.Join("~n")
- End Function
- Function iOSProjectFrameworksBuildPhase:String(uuid:String, fileMap:TFileMap)
- Local stack:TStringStack = New TStringStack
- For Local f:TFileId = EachIn fileMap.buildFiles
- Local path:String = f.path
- Local id:String = f.id
- Local dir:String = ExtractDir(path)
- Local name:String = StripDir(path)
-
- Select ExtractExt(name)
- Case "a", "o"
- stack.AddLast "~t~t~t~t" + id + " /* " + name + " */"
- End Select
-
- If path.StartsWith("-l") Then
- name = "lib" + path[2..] + ".a"
- stack.AddLast "~t~t~t~t" + id + " /* " + name + " */"
- End If
- If path.StartsWith("-framework") Then
- name = path[11..]
- stack.AddLast "~t~t~t~t" + id + " /* " + name + ".framework in Frameworks */"
- End If
- Next
-
- If stack.Count() Then
- stack.AddLast ""
- End If
-
- Return stack.Join(",~n")
- End Function
- Function iOSProjectResourcesBuildPhase:String(uuid:String, fileMap:TFileMap)
- Local stack:TStringStack = New TStringStack
- For Local f:TFileId = EachIn fileMap.buildFiles
- Local path:String = f.path
- Local id:String = f.id
-
- If f.kind = TFileId.TYPE_DIR Then
- stack.AddLast "~t~t~t~t" + id + " /* " + path + " in Resources */"
- End If
- Next
-
- If stack.Count() Then
- stack.AddLast ""
- End If
-
- Return stack.Join(",~n")
- End Function
- Function iOSProjectResourcesGroup:String(uuid:String, fileMap:TFileMap)
- Local stack:TStringStack = New TStringStack
- For Local path:String = EachIn fileMap.refFiles.Keys()
- Local id:String = String(fileMap.refFiles.ValueForKey(path))
-
- Local fid:TFileId = fileMap.GetBuildFileIdForPath(path)
-
- If fid.kind = TFileId.TYPE_DIR Then
- stack.AddLast "~t~t~t~t" + id + " /* " + path + " */"
- End If
- Next
-
- If stack.Count() Then
- stack.AddLast ""
- End If
-
- Return stack.Join(",~n")
- End Function
- Function iOSProjectFrameworksGroup:String(uuid:String, fileMap:TFileMap)
- Local stack:TStringStack = New TStringStack
- For Local path:String = EachIn fileMap.refFiles.Keys()
- Local id:String = String(fileMap.refFiles.ValueForKey(path))
-
- If path.StartsWith("-framework") Then
- Local name:String = path[11..]
- stack.AddLast "~t~t~t~t" + id + " /* " + name + ".framework in Frameworks */"
- End If
- Next
-
- If stack.Count() Then
- stack.AddLast ""
- End If
-
- Return stack.Join(",~n")
- End Function
- Function iOSProjectLibsGroup:String(uuid:String, fileMap:TFileMap)
- Local stack:TStringStack = New TStringStack
- For Local path:String = EachIn fileMap.refFiles.Keys()
- Local id:String = String(fileMap.refFiles.ValueForKey(path))
- Local dir:String = ExtractDir(path)
- Local name:String = StripDir(path)
-
- Select ExtractExt(name)
- Case "a"
- stack.AddLast "~t~t~t~t" + id + " /* " + name + " */"
- End Select
- If path.StartsWith("-l") Then
- name = "lib" + path[2..] + ".a"
- stack.AddLast "~t~t~t~t" + id + " /* " + name + " */"
- End If
- Next
-
- If stack.Count() Then
- stack.AddLast ""
- End If
-
- Return stack.Join(",~n")
- End Function
- Function iOSProjectObjectsGroup:String(uuid:String, fileMap:TFileMap)
- Local stack:TStringStack = New TStringStack
- For Local path:String = EachIn fileMap.refFiles.Keys()
- Local id:String = String(fileMap.refFiles.ValueForKey(path))
- Local dir:String = ExtractDir(path)
- Local name:String = StripDir(path)
-
- Select ExtractExt(name)
- Case "o"
- stack.AddLast "~t~t~t~t" + id + " /* " + name + " */"
- End Select
- Next
-
- If stack.Count() Then
- stack.AddLast ""
- End If
-
- Return stack.Join(",~n")
- End Function
- Function iOSProjectLibSearchPaths:String(uuid:String, fileMap:TFileMap)
- Local stack:TStringStack = New TStringStack
- For Local f:TFileId = EachIn fileMap.buildFiles
- Local path:String = f.path
- Local dir:String = ExtractDir(path)
- Local name:String = StripDir(path)
- Select ExtractExt(name)
- Case "a"
- stack.AddLast "~t~t~t~t~q" + EscapeSpaces(dir) + "~q"
- End Select
-
- If path.StartsWith("-L") Then
- stack.AddLast("~t~t~t~t~q" + EscapeSpaces(path[2..]) + "~q")
- End If
-
- Next
-
- If stack.Count() Then
- stack.AddLast ""
- End If
-
- Return stack.Join(",~n")
- End Function
- Function MakeUpx()
- If processor.Platform() = "emscripten" Or processor.Platform() = "nx" Or processor.Platform() = "ios" Then
- Return
- End If
-
- Local upx:String = BlitzMaxPath() + "/bin/upx"
- ?win32
- upx :+ ".exe"
- ?
- If Not opt_quiet Then
- Print "Packing:" + StripDir(opt_outfile)
- End If
-
- If FileType(upx) <> FILETYPE_FILE Then
- If Not opt_quiet Then
- Print "WARNING: Missing UPX : " + upx
- End If
- Return
- End If
-
- Local cmd:String = upx + " -9 "
- If Not opt_verbose Then
- cmd :+ "-qqq "
- Else
- cmd :+ "-qq "
- End If
-
- cmd :+ CQuote(opt_outfile)
-
- Sys(cmd)
- End Function
- Function FindEOL:Int(Text:String, substr:String, start:Int = 0)
- Local i:Int = Text.Find(substr, start)
- If i = -1 Then
- Return -1
- End If
- i :+ substr.Length
- Local eol:Int = Text.Find("~n", i) + 1
- If eol = 0 Then
- Return Text.Length
- End If
- Return eol
- End Function
- Function ConcatString:String(a1:String, a2:String, a3:String, a4:String, a5:String = Null, a6:String = Null, a7:String = Null)
- ?bmxng
- Local s:TStringBuffer = New TStringBuffer(128)
- ?Not bmxng
- TStringBuffer.initialCapacity = 128
- Local s:TStringBuffer = New TStringBuffer
- ?
- s.Append(a1).Append(a2).Append(a3).Append(a4)
- If a5 s.Append(a5)
- If a6 s.Append(a6)
- If a7 s.Append(a7)
- Return s.ToString()
- End Function
- Type TStringStack Extends TList
- Method Join:String(s:String)
- Local arr:String[] = New String[count()]
- Local index:Int
- For Local t:String = EachIn Self
- arr[index] = t
- index :+ 1
- Next
-
- Return s.Join(arr)
- End Method
- End Type
- Type TFileId
- Const TYPE_OBJ:Int = 1
- Const TYPE_ARC:Int = 2
- Const TYPE_DYL:Int = 3
- Const TYPE_LIB:Int = 4
- Const TYPE_FRM:Int = 5
- Const TYPE_DIR:Int = 6
- Field path:String
- Field id:String
-
- Field kind:Int
- End Type
- Type TFileMap
- Const BUILD:Int = 0
- Const REF:Int = 1
- Field lastId:Int = 0
- Field refFiles:TMap = New TMap
- Field buildFiles:TList = New TList
-
- Method FileId:String(path:String, uuid:String, kind:Int = BUILD, fileKind:Int = 0)
-
- Local id:String
- If kind = BUILD Then
- Local f:TFileId = GetBuildFileIdForPath(path)
- If f Then
- id = f.id
- End If
- Else
- id = String(refFiles.ValueForKey(path))
- End If
-
- If id Then
- Return id
- End If
-
- Local file:String = "0000000000000" + lastId
-
- id = uuid + file[file.length - 13..]
-
- If kind = BUILD Then
- Local f:TFileId = New TFileId
- f.path = path
- f.id = id
- f.kind = fileKind
- buildFiles.AddLast(f)
- Else
- refFiles.Insert(path, id)
- End If
-
- lastId :+ 1
-
- Return id
- End Method
-
- Method GetBuildFileIdForPath:TFileId(path:String)
- For Local f:TFileId = EachIn buildFiles
- If f.path = path Then
- Return f
- End If
- Next
- End Method
- End Type
- Type TOrderedMap Extends TMap
- Field _keys:TList = New TList
- Method Insert( key:Object,value:Object )
- If Not Contains(key) Then
- _keys.AddLast(key)
- End If
- Super.Insert(key, value)
- End Method
-
- Method Remove:Int( key:Object )
- _keys.Remove(key)
- Return Super.Remove(key)
- End Method
- Method OrderedKeys:TList()
- Return _keys
- End Method
- End Type
- Type TBootstrapConfig
- Field assets:TBootstrapAsset[]
- Field targets:TBootstrapTarget[]
-
- Method CopyAssets(dest:String)
-
- For Local asset:TBootstrapAsset = EachIn assets
-
- Print "processing " + asset.name
-
- Local basePath:String
-
- Select asset.assetType
- Case "m"
- basePath = "mod/" + asset.name.Replace(".",".mod/")+".mod"
- Case "a"
- basePath = "src/" + asset.name
- Default
- Continue
- End Select
- Local maxBase:String = BlitzMaxPath() + "/" + basePath
-
- If Not FileType(maxBase) Throw "Expected dir missing : " + basePath
- If FileType(maxBase) <> FILETYPE_DIR Throw "Not a dir : " + basePath
-
- Local destBase:String = dest + "/" + basePath
- If Not CreateDir(destBase, True) Throw "Error creating " + basePath
-
- For Local part:String = EachIn asset.parts
-
- If part.StartsWith("*") Then
- ' copy files
- FileCopy(maxBase, destBase, part[1..])
- Else
- ' copy dir
- Local srcDir:String = maxBase + "/" + part
- Local destDir:String = destBase + "/" + part
-
- DirCopy(srcDir, destDir)
- End If
-
- Next
-
- Next
-
- End Method
-
- Method DirCopy(src:String, dest:String)
- If Not FileType(src) Throw "Source dir not found : " + src
- If Not CreateDir(dest, True) Throw "Unable to create " + dest
-
- If Not CreateDir(dest + "/.bmx") Throw "Unable to create " + dest + "/.bmx"
-
- For Local file:String = EachIn LoadDir( src )
- If file.EndsWith(".bmx") Then
- Continue
- End If
-
- Local filePath:String = src + "/" + file
-
- Select FileType( filePath )
- Case FILETYPE_DIR
- DirCopy( filePath, dest + "/" + file )
- Case FILETYPE_FILE
- CopyFile( filePath, dest + "/" + file )
- End Select
- Next
-
- If LoadDir(dest + "/.bmx").Length = 0 Then
- CreateFile(dest + "/.bmx/.gitkeep")
- End If
- End Method
-
- Method FileCopy(src:String, dest:String, suffix:String)
-
- If Not CreateDir(dest + "/.bmx") Throw "Unable to create " + dest + "/.bmx"
-
- For Local file:String = EachIn LoadDir( src )
- If Not file.EndsWith(suffix) Then
- Continue
- End If
-
- Local filePath:String = src + "/" + file
-
- If FileType(filePath) = FILETYPE_FILE Then
- CopyFile(filePath, dest + "/" + file)
- End If
- Next
- End Method
-
- Method CopySources(dest:String, sources:TList)
- Local bmxRoot:String = "$BMX_ROOT"
- If processor.Platform() = "win32" Then
- bmxRoot = "%BMX_ROOT%"
- End If
-
- For Local path:String = EachIn sources
- Local srcPath:String = path.Replace(bmxRoot, BlitzMaxPath())
- Local destPath:String = path.Replace(bmxRoot, dest)
-
- CreateDir(ExtractDir(destPath), True)
-
- If Not FileType(srcPath) Throw "Not found : " + srcPath
-
- CopyFile(srcPath, destPath)
- Next
- End Method
-
- Method CopyScripts(dest:String, app:TBootstrapAsset)
- dest = dest + "/src/" + app.name
- Local src:String = BlitzMaxPath() + "/src/" + app.name
-
- Local ld:String = "/ld." + processor.AppDet() + ".txt"
- Local build:String = "/" + processor.AppDet() + ".build"
-
- Local ldSrcPath:String = src + ld
- Local buildSrcPath:String = src + build
-
- If Not FileType(ldSrcPath) Throw "ld script missing : " + ldSrcPath
- If Not FileType(buildSrcPath) Throw "build script missing : " + buildSrcPath
-
- CopyFile(ldSrcPath, dest + ld)
- CopyFile(buildSrcPath, dest + build)
- End Method
-
- End Type
- Type TBootstrapAsset
- Field assetType:String
- Field name:String
- Field parts:String[]
- End Type
- Type TBootstrapTarget
- Field platform:String
- Field arch:String
- End Type
- Function LoadBootstrapConfig:TBootstrapConfig()
- Const CONFIG:String = "bin/bootstrap.cfg"
-
- Local file:String = BlitzMaxPath() + "/" + CONFIG
- If Not FileType(file) Then
- Throw CONFIG + " not found"
- End If
-
- Local cfg:String = LoadText(file).Trim()
- If cfg Then
- Local LINES:String[] = cfg.Split("~n")
- Local assets:String[]
-
- For Local line:String = EachIn LINES
- line = line.Trim()
- If line And Not line.StartsWith("#") Then
- assets :+ [line]
- End If
- Next
-
- Local boot:TBootstrapConfig = New TBootstrapConfig
- 'boot.assets = New TBootstrapAsset[assets.length]
-
- 'Local i:Int
- For Local assetLine:String = EachIn assets
- Local parts:String[] = assetLine.Split("~t")
- If parts And parts.length > 1 Then
- Select parts[0]
- Case "t"
- Local target:TBootstrapTarget = New TBootstrapTarget
- target.platform = parts[1]
- target.arch = parts[2]
-
- boot.targets :+ [target]
- Default
- Local asset:TBootstrapAsset = New TBootstrapAsset
- asset.assetType = parts[0]
- asset.name = parts[1]
- If parts.length > 2 Then
- asset.parts = parts[2..]
- End If
-
- boot.assets :+ [asset]
-
- 'i :+ 1
- End Select
- End If
- Next
-
- Return boot
- Else
- Throw "Could not load " + CONFIG
- End If
-
- End Function
- Extern
- Function bmx_setfiletimenow(path:String)
- Function bmx_hash_createState:Byte Ptr()
- Function bmx_hash_reset(state:Byte Ptr)
- Function bmx_hash_update(state:Byte Ptr, data:Byte Ptr, length:Int)
- Function bmx_hash_digest:String(state:Byte Ptr)
- Function bmx_hash_free(state:Byte Ptr)
- End Extern
- Function SetFileTimeNow(path:String)
- bmx_setfiletimenow(path)
- End Function
- Type TFileHash
- Field statePtr:Byte Ptr
-
- Method Create:TFileHash()
- statePtr = bmx_hash_createState()
- Return Self
- End Method
-
- Method CalculateHash:String(stream:TStream)
- Const BUFFER_SIZE:Int = 8192
-
-
- bmx_hash_reset(statePtr)
-
- Local data:Byte[BUFFER_SIZE]
-
- While True
- Local read:Int = stream.Read(data, BUFFER_SIZE)
- bmx_hash_update(statePtr, data, read)
-
- If read < BUFFER_SIZE Then
- Exit
- End If
- Wend
-
- Return bmx_hash_digest(statePtr)
-
- End Method
-
- Method Free()
- bmx_hash_free(statePtr)
- End Method
- End Type
- Function CalculateFileHash:String(path:String)
-
- If FileType(path) = FILETYPE_FILE Then
- Local fileHasher:TFileHash = New TFileHash.Create()
- Local stream:TStream = ReadStream(path)
- Local fileHash:String = fileHasher.CalculateHash(stream)
- stream.Close()
-
- fileHasher.Free()
-
- Return fileHash
- End If
-
- Return Null
- End Function
|