12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928 |
- SuperStrict
- Import "bmk_modutil.bmx"
- Global cc_opts$
- Global bcc_opts$
- Global cpp_opts$
- Global c_opts$
- Global asm_opts:String
- Function BeginMake()
- cc_opts=Null
- cpp_opts=Null
- c_opts=Null
- bcc_opts=Null
- asm_opts=Null
- app_main=Null
- opt_framework=""
- End Function
- Function ConfigureAndroidPaths()
- CheckAndroidPaths()
-
- Local toolchain:String
- Local toolchainBin:String
- Local arch:String
- Local abi:String
-
- Select processor.CPU()
- Case "x86"
- toolchain = "x86-"
- toolchainBin = "i686-linux-android-"
- arch = "arch-x86"
- abi = "x86"
- Case "x64"
- toolchain = "x86_64-"
- toolchainBin = "x86_64-linux-android-"
- arch = "arch-x86_64"
- abi = "x86_64"
- Case "arm", "armeabi", "armeabiv7a"
- toolchain = "arm-linux-androideabi-"
- toolchainBin = "arm-linux-androideabi-"
- arch = "arch-arm"
- If processor.CPU() = "armeabi" Then
- abi = "armeabi"
- Else
- abi = "armeabi-v7a"
- End If
- Case "arm64v8a"
- toolchain = "aarch64-linux-android-"
- toolchainBin = "aarch64-linux-android-"
- arch = "arch-arm64"
- abi = "arm64-v8a"
- End Select
-
- Local native:String
- ?macos
- native = "darwin"
- ?linux
- native = "linux"
- ?win32
- native = "windows"
- ?
- Local toolchainDir:String = processor.Option("android.ndk", "") + "/toolchains/" + ..
- toolchain + processor.Option("android.toolchain.version", "") + "/prebuilt/" + native
-
- ' look for 64 bit build first, then x86, then fallback to no architecture (generally on 32-bit dists)
- If FileType(toolchainDir + "-x86_64") = FILETYPE_DIR Then
- toolchainDir :+ "-x86_64"
- Else If FileType(toolchainDir + "-x86") = FILETYPE_DIR Then
- toolchainDir :+ "-x86"
- Else If FileType(toolchainDir) <> FILETYPE_DIR Then
- Throw "Cannot determine toolchain dir for '" + native + "', at '" + toolchainDir + "'"
- End If
- Local exe:String
- ?win32
- exe = ".exe"
- ?
-
- Local gccPath:String = toolchainDir + "/bin/" + toolchainBin + "gcc" + exe
- Local gppPath:String = toolchainDir + "/bin/" + toolchainBin + "g++" + exe
- Local arPath:String = toolchainDir + "/bin/" + toolchainBin + "ar" + exe
- Local libPath:String = toolchainDir + "/lib"
- ' check paths
- If Not FileType(RealPath(gccPath)) Then
- Throw "gcc not found at '" + gccPath + "'"
- End If
- If Not FileType(RealPath(gppPath)) Then
- Throw "g++ not found at '" + gppPath + "'"
- End If
- If Not FileType(RealPath(gccPath)) Then
- Throw "ar not found at '" + arPath + "'"
- End If
-
- globals.SetVar("android." + processor.CPU() + ".gcc", gccPath)
- globals.SetVar("android." + processor.CPU() + ".gpp", gppPath)
- globals.SetVar("android." + processor.CPU() + ".ar", arPath)
- globals.SetVar("android." + processor.CPU() + ".lib", "-L" + libPath)
- ' platform
- Local platformDir:String = processor.Option("android.ndk", "") + "/platforms/android-" + ..
- processor.Option("android.platform", "") + "/" + arch
- If Not FileType(platformDir) Then
- Throw "Cannot determine platform dir for '" + arch + "' at '" + platformDir + "'"
- End If
-
- ' platform sysroot
- globals.SetVar("android.platform.sysroot", "--sysroot " + platformDir)
- globals.AddOption("cc_opts", "android.platform.sysroot", "--sysroot " + platformDir)
-
- ' abi
- globals.SetVar("android.abi", abi)
-
- ' sdk target
- Local target:String = GetAndroidSDKTarget()
- If Not target Or Not FileType(processor.Option("android.sdk", "") + "/platforms/android-" + target) Then
- Local sdkPath:String = processor.Option("android.sdk.target", "")
- If sdkPath Then
- Throw "Cannot determine SDK target for '" + sdkPath + "'"
- Else
- Throw "Cannot determine SDK target dir. ANDROID_SDK_TARGET or android.sdk.target option is not set, and auto-lookup failed."
- End If
- End If
- globals.SetVar("android.sdk.target", target)
- End Function
- Function CheckAndroidPaths()
- ' check envs and paths
- Local androidHome:String = processor.Option("android.home", getenv_("ANDROID_HOME")).Trim()
- If Not androidHome Then
- Throw "ANDROID_HOME or 'android.home' config option not set"
- End If
-
- putenv_("ANDROID_HOME=" + androidHome)
- globals.SetVar("android.home", androidHome)
-
- Local androidSDK:String = processor.Option("android.sdk", getenv_("ANDROID_SDK")).Trim()
- If Not androidSDK Then
- Throw "ANDROID_SDK or 'android.sdk' config option not set"
- End If
-
- putenv_("ANDROID_SDK=" + androidSDK)
- globals.SetVar("android.sdk", androidSDK)
- Local androidNDK:String = processor.Option("android.ndk", getenv_("ANDROID_NDK")).Trim()
- If Not androidNDK Then
- Throw "ANDROID_NDK or 'android.ndk' config option not set"
- End If
-
- putenv_("ANDROID_NDK=" + androidNDK)
- globals.SetVar("android.ndk", androidNDK)
- Local androidToolchainVersion:String = processor.Option("android.toolchain.version", getenv_("ANDROID_TOOLCHAIN_VERSION")).Trim()
- If Not androidToolchainVersion Then
- Throw "ANDROID_TOOLCHAIN_VERSION or 'android.toolchain.version' config option not set"
- End If
-
- putenv_("ANDROID_TOOLCHAIN_VERSION=" + androidToolchainVersion)
- globals.SetVar("android.toolchain.version", androidToolchainVersion)
- Local androidPlatform:String = processor.Option("android.platform", getenv_("ANDROID_PLATFORM")).Trim()
- If Not androidPlatform Then
- Throw "ANDROID_PLATFORM or 'android.platform' config option not set"
- End If
-
- putenv_("ANDROID_PLATFORM=" + androidPlatform.Trim())
- globals.SetVar("android.platform", androidPlatform)
- Local androidSDKTarget:String = processor.Option("android.sdk.target", getenv_("ANDROID_SDK_TARGET")).Trim()
- ' NOTE : if not set, we'll try to determine the actual target later, and fail if required then.
- If androidSDKTarget Then
- putenv_("ANDROID_SDK_TARGET=" + androidSDKTarget)
- globals.SetVar("android.sdk.target", androidSDKTarget)
- End If
-
- Local antHome:String = processor.Option("ant.home", getenv_("ANT_HOME")).Trim()
- If Not antHome Then
- ' as a further fallback, we can use the one from resources folder if it exists.
- Local antDir:String = RealPath(BlitzMaxPath() + "/resources/android/apache-ant")
-
- If FileType(antDir) <> FILETYPE_DIR Then
- Throw "ANT_HOME or 'ant.home' config option not set, and resources missing apache-ant."
- Else
- antHome = antDir
- globals.SetVar("ant.home", antHome)
- End If
- End If
-
- putenv_("ANT_HOME=" + antHome)
- globals.SetVar("ant.home", antHome)
- ?Not win32
- Local pathSeparator:String = ":"
- Local dirSeparator:String = "/"
- ?win32
- Local pathSeparator:String = ";"
- Local dirSeparator:String = "\"
- ?
- Local path:String = getenv_("PATH")
- path = androidSDK + dirSeparator + "platform-tools" + pathSeparator + path
- path = androidSDK + dirSeparator + "tools" + pathSeparator + path
- path = androidNDK + pathSeparator + path
- path = antHome + dirSeparator + "bin" + pathSeparator + path
- putenv_("PATH=" + path)
- End Function
- Function ConfigureIOSPaths()
- Select processor.CPU()
- Case "x86", "x64"
- Local path:String = "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk"
- globals.SetVar("ios." + processor.CPU() + ".sysroot", path)
- globals.SetVar("ios." + processor.CPU() + ".syslibroot", path)
- Case "armv7", "arm64"
- Local path:String = "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk"
- globals.SetVar("ios." + processor.CPU() + ".sysroot", path)
- globals.SetVar("ios." + processor.CPU() + ".syslibroot", path)
- End Select
- End Function
- Function ConfigureNXPaths()
- CheckNXPaths()
-
- Local toolchainBin:String
-
- Select processor.CPU()
- Case "arm64"
- toolchainBin = "aarch64-none-elf-"
- End Select
- Local toolchainDir:String = processor.Option("nx.devkitpro", "") + "/devkitA64/"
-
- If FileType(RealPath(toolchainDir)) <> FILETYPE_DIR Then
- Throw "Cannot determine toolchain dir for NX, at '" + toolchainDir + "'"
- End If
- Local exe:String
- ?win32
- exe = ".exe"
- ?
- Local gccPath:String = toolchainDir + "/bin/" + toolchainBin + "gcc" + exe
- Local gppPath:String = toolchainDir + "/bin/" + toolchainBin + "g++" + exe
- Local arPath:String = toolchainDir + "/bin/" + toolchainBin + "ar" + exe
- Local libPath:String = toolchainDir + "/lib"
- ' check paths
- If Not FileType(RealPath(gccPath)) Then
- Throw "gcc not found at '" + gccPath + "'"
- End If
- If Not FileType(RealPath(gppPath)) Then
- Throw "g++ not found at '" + gppPath + "'"
- End If
- If Not FileType(RealPath(gccPath)) Then
- Throw "ar not found at '" + arPath + "'"
- End If
-
- globals.SetVar("nx." + processor.CPU() + ".gcc", gccPath)
- globals.SetVar("nx." + processor.CPU() + ".gpp", gppPath)
- globals.SetVar("nx." + processor.CPU() + ".ar", arPath)
- globals.SetVar("nx." + processor.CPU() + ".lib", "-L" + libPath)
- ?Not win32
- Local pathSeparator:String = ":"
- Local dirSeparator:String = "/"
- ?win32
- Local pathSeparator:String = ";"
- Local dirSeparator:String = "\"
- ?
- Local path:String = getenv_("PATH")
- path = toolchainDir + dirSeparator + "bin" + pathSeparator + path
- putenv_("PATH=" + path)
- End Function
- Function CheckNXPaths()
- ' check envs and paths
- Local devkitpro:String = processor.Option("nx.devkitpro", getenv_("DEVKITPRO")).Trim()
- If Not devkitpro Then
- Throw "DEVKITPRO or 'nx.devkitpro' config option not set"
- End If
-
- putenv_("DEVKITPRO=" + devkitpro)
- globals.SetVar("nx.devkitpro", devkitpro)
-
- End Function
- Type TBuildManager Extends TCallback
- Field sources:TMap = New TMap
-
- Field buildAll:Int
-
- Field framework_mods:TList
- Field app_iface:String
-
- Method New()
- ' pre build checks
- If processor.Platform() = "android" Then
- ConfigureAndroidPaths()
- Else If processor.Platform() = "ios" Then
- ConfigureIOSPaths()
- Else If processor.Platform() = "nx" Then
- ConfigureNXPaths()
- End If
-
- If processor.Platform() = "linux" Or processor.Platform() = "raspberrypi" Then
- If opt_nopie Then
- globals.SetVar("nopie", "true")
- End If
- End If
-
- processor.callback = Self
- End Method
- Method MakeMods(mods:TList, rebuild:Int = False)
- For Local m:String = EachIn mods
- If (opt_modfilter And ((m).Find(opt_modfilter) = 0)) Or (Not opt_modfilter) Then
- GetMod(m, rebuild Or buildAll)
- End If
- Next
- End Method
- Method MakeApp(main_path:String, makelib:Int, compileOnly:Int = False)
- app_main = main_path
- Local source:TSourceFile = GetSourceFile(app_main, False, opt_all)
- If Not source Then
- Return
- End If
- Local build_path:String = ExtractDir(main_path) + "/.bmx"
- Local appType:String
- If Not compileOnly Or source.framewk Then
- appType = "." + opt_apptype
- End If
-
- source.obj_path = build_path + "/" + StripDir( main_path ) + appType + opt_configmung + processor.CPU() + ".o"
- source.obj_time = FileTime(source.obj_path)
- source.iface_path = StripExt(source.obj_path) + ".i"
- source.iface_time = FileTime(source.iface_path)
-
- app_iface = source.iface_path
-
- Local cc_opts:String
- source.AddIncludePath(" -I" + CQuote(ModulePath("")))
- If opt_release And Not opt_gdbdebug Then
- cc_opts :+ " -DNDEBUG"
- End If
- If processor.BCCVersion() <> "BlitzMax" Then
- If opt_gdbdebug Then
- cc_opts :+ " -g"
- End If
- If opt_gprof Then
- cc_opts :+ " -pg"
- End If
- If opt_coverage Then
- cc_opts :+ " -DBMX_COVERAGE"
- End If
- End If
-
- Local sb:TStringBuffer = New TStringBuffer
- sb.Append(" -g ").Append(processor.CPU())
- If opt_quiet sb.Append(" -q")
- If opt_verbose sb.Append(" -v")
- If opt_release sb.Append(" -r")
- If opt_threaded sb.Append(" -h")
- If opt_framework sb.Append(" -f ").Append(opt_framework)
- If processor.BCCVersion() <> "BlitzMax" Then
- If opt_gdbdebug Then
- sb.Append(" -d")
- End If
- If Not opt_nostrictupgrade Then
- sb.Append(" -s")
- End If
- If opt_warnover Then
- sb.Append(" -w")
- End If
- If opt_musl Then
- sb.Append(" -musl")
- End If
- If makelib Then
- sb.Append(" -makelib")
- If opt_nodef Then
- sb.append(" -nodef")
- End If
- If opt_nohead Then
- sb.append(" -nohead")
- End If
- End If
- If opt_require_override Then
- sb.Append(" -override")
- If opt_override_error Then
- sb.Append(" -overerr")
- End If
- End If
- Local defs:String = opt_userdefs
- If globals.Get("user_defs") Then
- If defs Then
- defs :+ ","
- End If
- defs :+ globals.Get("user_defs")
- End If
- If defs Then
- sb.Append(" -ud ").Append(defs)
- End If
- If opt_standalone Then
- sb.Append(" -ib")
- End If
- If opt_coverage Then
- sb.Append(" -cov")
- End If
- If opt_no_auto_superstrict Then
- sb.Append(" -nas")
- End If
- End If
- source.cc_opts :+ cc_opts
- source.cpp_opts :+ cpp_opts
- source.c_opts :+ c_opts
- source.modimports.AddLast("brl.blitz")
- source.modimports.AddLast(opt_appstub)
- If source.framewk
- If opt_framework Then
- Throw "Framework already specified on commandline"
- End If
- opt_framework = source.framewk
- sb.Append(" -f ").Append(opt_framework)
- source.modimports.AddLast(opt_framework)
- Else
- framework_mods = New TList
- For Local t:String = EachIn EnumModules()
- If t.Find("brl.") = 0 Or t.Find("pub.") = 0 Then
- If t <> "brl.blitz" And t <> opt_appstub Then
- source.modimports.AddLast(t)
- framework_mods.AddLast(t)
- End If
- End If
- Next
- End If
-
- source.bcc_opts = sb.ToString()
- source.SetRequiresBuild(opt_all)
- CalculateDependencies(source, False, opt_all)
- source.bcc_opts :+ " -t " + opt_apptype
-
- ' create bmx stages :
- Local gen:TSourceFile
- ' for osx x86 on legacy, we need to convert asm
- If processor.BCCVersion() = "BlitzMax" And processor.CPU() = "x86" And processor.Platform() = "macos" Then
- Local fasm2as:TSourceFile = CreateFasm2AsStage(source)
- gen = CreateGenStage(fasm2as)
- Else
- gen = CreateGenStage(source)
- End If
- If Not compileOnly Then
- Local link:TSourceFile = CreateLinkStage(gen, STAGE_APP_LINK)
- End If
- End Method
-
- Method DoBuild(makelib:Int, app_build:Int = False)
- Local arc_order:TList = New TList
-
- Local files:TList = New TList
- For Local file:TSourceFile = EachIn sources.Values()
- files.AddLast(file)
- Next
- ' get the list of parallelizable batches
- ' each list of batches has no outstanding dependencies, and therefore
- ' can be compiled in parallel.
- ' the last list of batches requires all previous lists to have
- ' been compiled.
- Local batches:TList = CalculateBatches(files)
-
- For Local batch:TList = EachIn batches
- Local s:String
- For Local m:TSourceFile = EachIn batch
- ' sort archives for app linkage
- If m.modid Then
- Local path:String = m.arc_path
- If IOS_HAS_MERGE And processor.Platform() = "ios" Then
- path = m.merge_path
- End If
-
- If Not arc_order.Contains(path) Then
- arc_order.AddFirst(path)
- End If
- End If
- Local build_path:String
- If m.obj_path Then
- build_path = ExtractDir(m.obj_path)
- Else
- build_path = ExtractDir(m.path) + "/.bmx"
- End If
-
- If Not FileType(build_path) Then
- CreateDir build_path
- End If
-
- If FileType(build_path) <> FILETYPE_DIR Then
- Throw "Unable to create temporary directory : " + build_path
- End If
- ' change dir, so relative commands work as expected
- ' (eg. file processing in BMK-scripts called via pragma)
- ChangeDir ExtractDir( m.path )
- ' bmx file
- If Match(m.ext, "bmx") Then
-
- Select m.stage
- Case STAGE_GENERATE
- If m.requiresBuild Or (m.time > m.gen_time Or m.iface_time < m.MaxIfaceTime() Or Not m.MaxIfaceTime()) Then
- If Not opt_quiet Then
- Print ShowPct(m.pct) + "Processing:" + StripDir(m.path)
- End If
- ' process pragmas
- Local pragma_inDefine:Int, pragma_text:String, pragma_name:String
- For Local pragma:String = EachIn m.pragmas
- processor.ProcessPragma(pragma, pragma_inDefine, pragma_text, pragma_name)
- Next
-
- CompileBMX m.path, m.obj_path, m.bcc_opts
- End If
- Case STAGE_FASM2AS
- For Local s:TSourceFile = EachIn m.depsList
- If s.requiresBuild Then
- m.SetRequiresBuild(True)
- Exit
- End If
- Next
- If m.requiresBuild Or (m.time > m.obj_time Or m.iface_time < m.MaxIfaceTime()) Then
-
- m.SetRequiresBuild(True)
- If Not opt_quiet Then
- Print ShowPct(m.pct) + "Converting:" + StripDir(StripExt(m.obj_path) + ".s")
- End If
-
- Fasm2As m.path, m.obj_path
-
- m.asm_time = time_(Null)
-
- End If
-
- Case STAGE_OBJECT
- If m.requiresBuild Or (m.time > m.obj_time Or m.iface_time < m.MaxIfaceTime()) Then
-
- m.SetRequiresBuild(True)
-
- If processor.BCCVersion() <> "BlitzMax" Then
- Local csrc_path:String = StripExt(m.obj_path) + ".c"
- Local cobj_path:String = StripExt(m.obj_path) + ".o"
- If Not opt_quiet Then
- Local s:String = ShowPct(m.pct) + "Compiling:" + StripDir(csrc_path)
- If opt_standalone And Not opt_nolog processor.PushEcho(FixPct(s))
- Print s
- End If
-
- If opt_standalone And opt_boot Then
- processor.PushSource(csrc_path)
- processor.PushSource(StripExt(m.obj_path) + ".h")
- End If
- CompileC csrc_path,cobj_path, m.GetIncludePaths() + " " + m.cc_opts + " " + m.c_opts
- Else
- ' asm compilation
- Local src_path:String = StripExt(m.obj_path) + ".s"
- Local obj_path:String = StripExt(m.obj_path) + ".o"
- If Not opt_quiet Then
- Print ShowPct(m.pct) + "Compiling:" + StripDir(src_path)
- End If
- Assemble src_path, obj_path
- End If
-
- m.obj_time = time_(Null)
- End If
- Case STAGE_LINK
- Local max_obj_time:Int = m.MaxObjTime()
- If max_obj_time > m.arc_time And Not m.dontbuild Then
- Local objs:TList = New TList
- m.GetObjs(objs)
-
- If Not opt_quiet Then
- Local s:String = ShowPct(m.pct) + "Archiving:" + StripDir(m.arc_path)
- If opt_standalone And Not opt_nolog processor.PushEcho(FixPct(s))
- Print s
- End If
- Local at:TArcTask = New TArcTask.Create(m, m.arc_path, objs)
-
- ?threaded
- If opt_single Then
- at.CreateArc()
- Else
- processManager.AddTask(TArcTask._CreateArc, at)
- End If
- ?Not threaded
- at.CreateArc()
- ?
-
- End If
-
- Case STAGE_APP_LINK
- ' this probably should never happen.
- ' may be a bad module?
- If Not opt_outfile Then
- Throw "Build Error: Did not expect to link against " + m.path
- End If
- ' an app!
- Local max_lnk_time:Int = m.MaxLinkTime()
-
- ' include settings and icon times in calculation
- If opt_manifest And processor.Platform() = "win32" And opt_apptype="gui" Then
- Local settings:String = ExtractDir(opt_infile) + "/" + StripDir(StripExt(opt_outfile)) + ".settings"
- If Not FileType(settings) Then
- settings = ExtractDir(opt_infile) + "/" + StripDir(StripExt(opt_infile)) + ".settings"
- End If
- max_lnk_time = Max(FileTime(settings), max_lnk_time)
-
- Local icon:String = ExtractDir(opt_infile) + "/" + StripDir(StripExt(opt_outfile)) + ".ico"
- If Not FileType(icon) Then
- icon = ExtractDir(opt_infile) + "/" + StripDir(StripExt(opt_infile)) + ".ico"
- End If
- max_lnk_time = Max(FileTime(icon), max_lnk_time)
- End If
-
- If max_lnk_time > FileTime(opt_outfile) Or opt_all Then
- ' generate manifest for app
- If opt_manifest And processor.Platform() = "win32" And opt_apptype="gui" Then
- processor.RunCommand("make_win32_resource", Null)
- Local res:String = ExtractDir(opt_infile) + "/.bmx/" + StripDir(StripExt(opt_outfile)) + "." + processor.CPU() + ".res.o"
- If Not FileType(res) Then
- res = ExtractDir(opt_infile) + "/.bmx/" + StripDir(StripExt(opt_infile)) + "." + processor.CPU() + ".res.o"
- End If
- If FileType(res) = FILETYPE_FILE Then
- Local s:TSourceFile = New TSourceFile
- s.obj_path = res
- s.stage = STAGE_LINK
- s.exti = SOURCE_RES
- m.depslist.AddLast(s)
- End If
- End If
- If Not opt_quiet Then
- Local s:String = ShowPct(m.pct) + "Linking:" + StripDir(opt_outfile)
- If opt_standalone And Not opt_nolog processor.PushEcho(FixPct(s))
- Print s
- End If
- Local links:TList = New TList
- Local opts:TList = New TList
- m.GetLinks(links, opts)
- For Local arc:String = EachIn arc_order
- links.AddLast(arc)
- Next
-
- For Local o:String = EachIn opts
- links.AddLast(o)
- Next
- LinkApp opt_outfile, links, makelib, globals.Get("ld_opts")
- m.obj_time = time_(Null)
- End If
- Case STAGE_MERGE
- If IOS_HAS_MERGE Then
- ' a module?
- If m.modid Then
- Local max_obj_time:Int = m.MaxObjTime()
-
- If max_obj_time > m.merge_time And Not m.dontbuild Then
-
- If Not opt_quiet Then
- Print ShowPct(m.pct) + "Merging:" + StripDir(m.merge_path)
- End If
-
- CreateMergeArc m.merge_path, m.arc_path
-
- m.merge_time = time_(Null)
-
- End If
- End If
- End If
- End Select
- Else If Match(m.ext, "s") Then
- If m.time > m.obj_time Then ' object is older or doesn't exist
- m.SetRequiresBuild(True)
- End If
- If m.requiresBuild Then
- If Not opt_quiet Then
- Local s:String = ShowPct(m.pct) + "Compiling:" + StripDir(m.path)
- If opt_standalone And Not opt_nolog processor.PushEcho(FixPct(s))
- Print s
- End If
-
- If processor.BCCVersion() = "BlitzMax" Then
- Assemble m.path, m.obj_path
- Else
- CompileC m.path, m.obj_path, m.GetIncludePaths() + " " + m.cc_opts + " " + m.c_opts
- End If
-
- End If
-
- Else
-
- If Not m.dontbuild Then
- ' c/c++ source
- If m.time > m.obj_time Then ' object is older or doesn't exist
- m.SetRequiresBuild(True)
- End If
-
- If m.requiresBuild Then
-
- If Not opt_quiet Then
- Local s:String = ShowPct(m.pct) + "Compiling:" + StripDir(m.path)
- If opt_standalone And Not opt_nolog processor.PushEcho(FixPct(s))
- Print s
- End If
- If m.path.EndsWith(".cpp") Or m.path.EndsWith(".cc") Or m.path.EndsWith(".mm") Or m.path.EndsWith(".cxx") Then
- CompileC m.path, m.obj_path, m.GetIncludePaths() + " " + m.cc_opts + " " + m.cpp_opts
- ElseIf m.path.EndsWith(".S") Or m.path.EndsWith("asm") Then
- AssembleNative m.path, m.obj_path, m.asm_opts
- Else
- CompileC m.path, m.obj_path, m.GetIncludePaths() + " " + m.cc_opts + " " + m.c_opts
- End If
-
- m.obj_time = time_(Null)
- End If
- End If
- End If
-
- Next
- ?threaded
- If Not opt_single Then
- processManager.WaitForTasks()
- End If
- ?
- Next
-
- If app_build Then
- ' global post process
- LoadBMK("post.bmk")
- ' generic post process
- LoadBMK(ExtractDir(app_main) + "/post.bmk")
- ' project-specific post process
- LoadBMK(ExtractDir(app_main) + "/" + StripDir( opt_outfile ) + ".post.bmk")
- Select processor.Platform()
- Case "android"
- ' create the apk
-
- ' copy shared object
- Local androidABI:String = processor.Option("android.abi", "")
-
- 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)
- Local projectDir:String = buildDir + "/android-project-" + appId
-
- Local abiPath:String = projectDir + "/libs/" + androidABI
-
- Local sharedObject:String = "lib" + appId
- sharedObject :+ ".so"
-
- CopyFile(buildDir + "/" + sharedObject, abiPath + "/" + sharedObject)
-
- ' build the apk :
- Local antHome:String = processor.Option("ant.home", "").Trim()
- Local cmd:String = "~q" + antHome + "/bin/ant"
- ?win32
- cmd :+ ".bat"
- ?
- cmd :+ "~q debug"
-
- Local dir:String = CurrentDir()
-
- ChangeDir(projectDir)
-
- If opt_dumpbuild Then
- Print cmd
- End If
-
- If Sys( cmd ) Then
- Throw "Error creating apk"
- End If
-
- ChangeDir(dir)
-
- 'End If
-
- Case "ios"
-
- Local iosSimulator:Int = (processor.CPU() = "x86")
-
- ' TODO - other stuff ?
- Case "nx"
-
- ' TODO - build nro, nso, psf0 and nacp
-
- End Select
- End If
- End Method
-
- Method CalculateDependencies(source:TSourceFile, isMod:Int = False, rebuildImports:Int = False, isInclude:Int = False)
- If source And Not source.processed Then
- source.processed = True
- For Local m:String = EachIn source.modimports
- Local s:TSourceFile = GetMod(m)
- If s Then
- If Not source.moddeps Then
- source.moddeps = New TMap
- End If
-
- If Not source.moddeps.ValueForKey(m) Then
- source.moddeps.Insert(m, s)
- source.deps.Insert(s.GetSourcePath(), s)
-
- source.AddIncludePath(" -I" + CQuote(ExtractDir(s.path)))
- End If
- End If
- Next
- Local ib:TSourceFile
- If processor.BCCVersion() <> "BlitzMax" And Not source.incbins.IsEmpty() Then
- If source.owner_path Then
- ib = CreateIncBin(source, source.owner_path)
- Else
- ib = CreateIncBin(source, source.path)
- End If
- End If
- For Local f:String = EachIn source.imports
- If f[0] <> Asc("-") Then
- Local path:String = CheckPath(ExtractDir(source.path), f)
- Local s:TSourceFile = GetSourceFile(path, isMod)
-
- ' imported sourcefile not there? Maybe it's relative to the owner path instead?
- ' For example, an incbin as part of an included source file.
- If Not s Then
- Local p:String = CheckPath(ExtractDir(source.owner_path), f)
- s = GetSourceFile(p, isMod)
- If s Then
- path = p
- End If
- End If
-
- If s Then
-
- If rebuildImports Then
- s.SetRequiresBuild(rebuildImports)
- End If
-
- If Match(s.ext, "bmx") Then
- s.modimports.AddLast("brl.blitz")
-
- ' app source files need framework/mod dependencies applied
- If Not isMod Then
- If opt_framework Then
- ' add framework as dependency
- s.modimports.AddLast(opt_framework)
- Else
- ' add all pub/brl mods as dependency
- If framework_mods Then
- For Local m:String = EachIn framework_mods
- s.modimports.AddLast(m)
- Next
- End If
- End If
- End If
-
- s.bcc_opts = source.bcc_opts
- s.cc_opts :+ source.cc_opts
- s.cpp_opts :+ source.cpp_opts
- s.c_opts :+ source.c_opts
- s.asm_opts :+ source.asm_opts
- s.CopyIncludePaths(source.includePaths)
-
- CalculateDependencies(s, isMod, rebuildImports)
-
- ' if file that we generate is missing, we need to rebuild
- If processor.BCCVersion() = "BlitzMax" Then
- If Not FileType(StripExt(s.obj_path) + ".s") Then
- s.SetRequiresBuild(True)
- End If
- Else
- If Not FileType(StripExt(s.obj_path) + ".c") Then
- s.SetRequiresBuild(True)
- End If
- End If
-
- Local gen:TSourceFile
-
- ' for osx x86 on legacy, we need to convert asm
- If processor.BCCVersion() = "BlitzMax" And processor.CPU() = "x86" And processor.Platform() = "macos" Then
- Local fasm2as:TSourceFile = CreateFasm2AsStage(s)
- gen = CreateGenStage(fasm2as)
- Else
- gen = CreateGenStage(s)
- End If
- source.deps.Insert(gen.GetSourcePath(), gen)
-
- If Not source.depsList Then
- source.depsList = New TList
- End If
- source.depsList.AddLast(gen)
- Else
- s.cc_opts = source.cc_opts
- s.cpp_opts = source.cpp_opts
- s.c_opts = source.c_opts
- s.asm_opts = source.asm_opts
- s.CopyIncludePaths(source.includePaths)
-
- source.deps.Insert(s.GetSourcePath(), s)
- If Not source.depsList Then
- source.depsList = New TList
- End If
- source.depsList.AddLast(s)
- End If
-
-
- Else
- Local ext:String = ExtractExt(path)
-
- If Match(ext, "h;hpp;hxx") Then ' header?
-
- source.AddIncludePath(" -I" + CQuote(ExtractDir(path)))
-
- Else If Match(ext, "o;a;lib") Then ' object or archive?
-
- Local s:TSourceFile = New TSourceFile
- s.time = FileTime(path)
- s.obj_time = s.time
- s.path = path
- s.obj_path = path
- s.modid = source.modid
- If s.time > source.time Then
- source.time = s.time
- End If
-
- If Not source.depsList Then
- source.depsList = New TList
- End If
- source.depsList.AddLast(s)
- End If
-
- End If
- Else
- If Not source.ext_files Then
- source.ext_files = New TList
- End If
-
- source.ext_files.AddLast(f)
-
- End If
- Next
-
- For Local f:String = EachIn source.includes
- Local path:String = CheckPath(ExtractDir(source.path), f)
- Local s:TSourceFile = GetSourceFile(path, isMod, rebuildImports, True)
- If s Then
- s.owner_path = source.path
-
- If s.includePaths.IsEmpty() Then
- s.CopyIncludePaths(source.includePaths)
- End If
-
- ' calculate included file dependencies
- CalculateDependencies(s, isMod, rebuildImports)
- ' update our time to latest included time
- If s.time > source.time Then
- source.time = s.time
- End If
-
- If Not source.depsList Then
- source.depsList = New TList
- End If
- source.depsList.AddLast(s)
- End If
- Next
- For Local f:String = EachIn source.incbins
- Local path:String = CheckPath(ExtractDir(source.path), f)
- If FileType(path) = FILETYPE_FILE Then
- source.hashes.Insert(f, CalculateFileHash(path))
- End If
- Local time:Int = FileTime(path)
-
- ' update our time to the latest incbin time
- If time > source.time Then
- source.time = time
- End If
-
- ' update ib time to the latest incbin time
- If ib And ib.time And ib.time < time Then
- ib.time = time
- End If
- Next
-
- ' incbin file
- If ib Then
- Local requiresBuild:Int = False
- ' missing source.. generate and compile
- If Not ib.time Then
- requiresBuild = True
- Else If IncbinsDifference(source.incbins, ib.incbins) Then
- requiresBuild = True
- Else If IncbinsHashDifference(source, ib) Then
- requiresBuild = True
- End If
-
- If requiresBuild Then
- ib.SetRequiresBuild(True)
- source.SetRequiresBuild(True)
- End If
- ' sync timestamps
- If ib.time > source.time Then
- source.time = ib.time
- End If
- End If
-
- If source.depsList Then
- For Local s:TSourceFile = EachIn source.depsList
- If Not Match(s.ext, "bmx") Then
- s.cc_opts = source.cc_opts
- s.cpp_opts = source.cpp_opts
- s.c_opts = source.c_opts
- s.asm_opts = source.asm_opts
- s.CopyIncludePaths(source.includePaths)
- End If
- Next
- End If
-
- End If
- End Method
-
- Method GetSourceFile:TSourceFile(source_path:String, isMod:Int = False, rebuild:Int = False, isInclude:Int = False, doCreate:Int = True)
- Local source:TSourceFile = TSourceFile(sources.ValueForKey(source_path))
- If Not source And doCreate Then
- source = ParseSourceFile(source_path)
-
- If source Then
- Local ext:String = ExtractExt(source_path)
- If Match(ext, ALL_SRC_EXTS) Then
- If Not isInclude Then
- sources.Insert(source_path, source)
- Local sp:String
- If app_main = source_path Then
- sp = ConcatString(ExtractDir(source_path), "/.bmx/", StripDir(source_path), "." + opt_apptype, opt_configmung, processor.CPU())
- Else
- sp = ConcatString(ExtractDir(source_path), "/.bmx/", StripDir(source_path), opt_configmung, processor.CPU())
- End If
-
-
- If Match(ext, "bmx") Then
- source.obj_path = sp + ".o"
- source.obj_time = FileTime(source.obj_path)
- source.iface_path = sp + ".i"
- source.iface_path2 = source.iface_path + "2"
- source.iface_time = FileTime(source.iface_path2)
-
- ' gen file times
- If processor.BCCVersion() <> "BlitzMax" Then
- Local p:String = sp + ".c"
- source.gen_time = FileTime(p)
- If source.gen_time Then
- p = sp + ".h"
- source.gen_time = Min(source.gen_time, FileTime(p))
- End If
- Else
- Local p:String = sp + ".s"
- source.gen_time = FileTime(p)
- End If
- Else
- source.obj_path = PPFix(sp) + ".o"
- source.obj_time = FileTime(source.obj_path)
- End If
- Else
- source.isInclude = True
- End If
- End If
- End If
- End If
-
- Return source
- End Method
-
- Method PPFix:String(path:String)
- Local dir:String = ExtractDir(ExtractDir(path))
- Local s:String
- For Local i:Int = 0 Until 3
- Local t:String = StripDir(dir)
- If Not t Then
- t = "x"
- End If
- s = t[..1] + s
-
- dir = ExtractDir(dir)
- Next
- Return ExtractDir(path) + "/" + s + "_" + StripDir(path)
- End Method
- Method GetISourceFile:TSourceFile(arc_path:String, arc_time:Int, iface_path:String, iface_time:Int, merge_path:String, merge_time:Int)
- Local source:TSourceFile
-
- If IOS_HAS_MERGE And processor.Platform() = "ios" Then
- source = TSourceFile(sources.ValueForKey(merge_path))
- Else
- source = TSourceFile(sources.ValueForKey(arc_path))
- End If
- If Not source Then
- Local iface_path2:String = iface_path + 2
-
- source = ParseISourceFile(iface_path2)
-
- If source Then
- source.arc_path = arc_path
- source.arc_time = arc_time
- source.iface_path = iface_path
- source.iface_path2 = iface_path2
- source.iface_time = iface_time
- source.merge_time = merge_time
- If IOS_HAS_MERGE And processor.Platform() = "ios" Then
- sources.Insert(merge_path, source)
- Else
- sources.Insert(arc_path, source)
- End If
- End If
- End If
-
- Return source
- End Method
-
- Method GetMod:TSourceFile(m:String, rebuild:Int = False)
- If (opt_all And ((opt_modfilter And ((m).Find(opt_modfilter) = 0)) Or (Not opt_modfilter)) And Not app_main) Or (app_main And opt_standalone) Then
- rebuild = True
- End If
-
- Local path:String = ModulePath(m)
- Local id:String = ModuleIdent(m)
-
- Local mp:String = ConcatString(path, "/", id, opt_configmung, processor.CPU())
- ' get the module interface and lib details
- Local arc_path:String = mp + ".a"
- Local arc_time:Int = FileTime(arc_path)
- Local iface_path:String = mp + ".i"
- Local iface_path2:String = iface_path + "2"
- Local iface_time:Int = FileTime(iface_path2)
- Local merge_path:String
- Local merge_time:Int
-
- If IOS_HAS_MERGE And processor.Platform() = "ios" Then
- If processor.CPU() = "x86" Or processor.CPU() = "x64" Then
- merge_path = ConcatString(path, "/", id, opt_configmung, "sim.a")
- Else
- merge_path = ConcatString(path, "/", id, opt_configmung, "dev.a")
- End If
- merge_time = FileTime(merge_path)
- End If
- Local source:TSourceFile
- Local link:TSourceFile
- ' do a quick scan only when building apps. For module builds we want to check required modules.
- If arc_time And iface_time And opt_quickscan And app_main Then
- source = GetISourceFile(arc_path, arc_time, iface_path, iface_time, merge_path, merge_time)
-
- If Not source Then
- Return Null
- End If
-
- If Not source.processed Then
- source.modid = m
- source.arc_path = arc_path
- source.arc_time = arc_time
- source.iface_path = iface_path
- source.iface_path2 = iface_path2
- source.iface_time = iface_time
- source.obj_path = arc_path
- source.merge_path = merge_path
- source.merge_time = merge_time
-
- CalculateDependencies(source, True, rebuild)
- source.dontbuild = True
- If IOS_HAS_MERGE And processor.Platform() = "ios" Then
- source.stage = STAGE_MERGE
- sources.Insert(source.merge_path, source)
- Else
- source.stage = STAGE_LINK
- sources.Insert(source.arc_path, source)
- End If
- End If
-
- link = source
- Else
- Local src_path:String = ConcatString(path, "/", id, ".bmx")
- source = GetSourceFile(src_path, True, rebuild)
-
- If Not source Then
- Return Null
- End If
-
- ' main module file without "Module" line?
- If Not source.modid Then
- Return Null
- End If
- End If
-
- If Not source.processed Then
- source.arc_path = arc_path
- source.arc_time = arc_time
- source.iface_path = iface_path
- source.iface_path2 = iface_path2
- source.iface_time = iface_time
- source.merge_path = merge_path
- source.merge_time = merge_time
-
- Local cc_opts:String
- source.AddIncludePath(" -I" + CQuote(path))
- source.AddIncludePath(" -I" + CQuote(ModulePath("")))
- If opt_release And Not opt_gdbdebug Then
- cc_opts :+ " -DNDEBUG"
- End If
- If opt_threaded Then
- cc_opts :+ " -DTHREADED"
- End If
- If processor.BCCVersion() <> "BlitzMax" Then
- If opt_gdbdebug Then
- cc_opts :+ " -g"
- End If
- If opt_gprof Then
- cc_opts :+ " -pg"
- End If
- If opt_coverage Then
- cc_opts :+ " -DBMX_COVERAGE"
- End If
- End If
- source.cc_opts = ""
- If source.mod_opts Then
- source.cc_opts :+ source.mod_opts.cc_opts
- source.cpp_opts :+ source.mod_opts.cpp_opts
- source.c_opts :+ source.mod_opts.c_opts
- source.asm_opts :+ source.mod_opts.asm_opts
- End If
- source.cc_opts :+ cc_opts
- source.cpp_opts :+ cpp_opts
- source.c_opts :+ c_opts
- source.asm_opts :+ asm_opts
-
- ' Module BCC opts
- Local sb:TStringBuffer = New TStringBuffer
- sb.Append(" -g ").Append(processor.CPU())
- sb.Append(" -m ").Append(m)
- If opt_quiet sb.Append(" -q")
- If opt_verbose sb.Append(" -v")
- If opt_release sb.Append(" -r")
- If opt_threaded sb.Append(" -h")
- If processor.BCCVersion() <> "BlitzMax" Then
- If opt_gdbdebug Then
- sb.Append(" -d")
- End If
- If Not opt_nostrictupgrade Then
- sb.Append(" -s")
- End If
- If opt_warnover Then
- sb.Append(" -w")
- End If
- If opt_musl Then
- sb.Append(" -musl")
- End If
- If opt_require_override Then
- sb.Append(" -override")
- If opt_override_error Then
- sb.Append(" -overerr")
- End If
- End If
- Local defs:String = opt_userdefs
- If globals.Get("user_defs") Then
- If defs Then
- defs :+ ","
- End If
- defs :+ globals.Get("user_defs")
- End If
- If defs Then
- sb.Append(" -ud ").Append(defs)
- End If
- If opt_standalone Then
- sb.Append(" -ib")
- End If
- If opt_coverage Then
- sb.Append(" -cov")
- End If
- If opt_no_auto_superstrict Then
- sb.Append(" -nas")
- End If
- End If
-
- source.bcc_opts = sb.ToString()
-
- source.SetRequiresBuild(rebuild)
- ' interface is REQUIRED for compilation
- If Not iface_time Then
- source.SetRequiresBuild(True)
- End If
- If m <> "brl.blitz" Then
- source.modimports.AddLast("brl.blitz")
- End If
-
-
- CalculateDependencies(source, True, rebuild)
-
- ' create bmx stages :
- Local gen:TSourceFile
-
- ' for osx x86 on legacy, we need to convert asm
- If processor.BCCVersion() = "BlitzMax" And processor.CPU() = "x86" And processor.Platform() = "macos" Then
- Local fasm2as:TSourceFile = CreateFasm2AsStage(source)
- gen = CreateGenStage(fasm2as)
- Else
- gen = CreateGenStage(source)
- End If
-
- If processor.Platform() <> "ios" Then
- link = CreateLinkStage(gen)
- Else
- If IOS_HAS_MERGE Then
- Local realLink:TSourceFile = CreateLinkStage(gen)
-
- ' create a fat archive
- link = CreateMergeStage(realLink)
- Else
- link = CreateLinkStage(gen)
- End If
- End If
- Else
- If IOS_HAS_MERGE And processor.Platform() = "ios" Then
- link = TSourceFile(sources.ValueForKey(source.merge_path))
- Else
- link = TSourceFile(sources.ValueForKey(source.arc_path))
- End If
- If Not link Then
- Throw "Can't find link for : " + source.path
- End If
- End If
-
- Return link
- End Method
- Method CreateFasm2AsStage:TSourceFile(source:TSourceFile)
- Local fasm:TSourceFile = New TSourceFile
-
- source.CopyInfo(fasm)
-
- fasm.deps.Insert(source.path, source)
- fasm.stage = STAGE_FASM2AS
- fasm.processed = True
- fasm.depsList = New TList
- fasm.depsList.AddLast(source)
- sources.Insert(StripExt(fasm.obj_path) + ".s", fasm)
- Return fasm
- End Method
-
- Method CreateGenStage:TSourceFile(source:TSourceFile)
- Local gen:TSourceFile = New TSourceFile
-
- source.CopyInfo(gen)
-
- If processor.BCCVersion() = "BlitzMax" And processor.CPU() = "x86" And processor.Platform() = "macos" Then
- gen.deps.Insert(StripExt(source.obj_path) + ".s", source)
- Else
- gen.deps.Insert(source.path, source)
- End If
-
- gen.stage = STAGE_OBJECT
- gen.processed = True
- gen.depsList = New TList
- gen.depsList.AddLast(source)
- sources.Insert(StripExt(gen.obj_path) + ".c", gen)
- Return gen
- End Method
- Method CreateIncBin:TSourceFile(source:TSourceFile, sourcePath:String)
-
- Local path:String = StripDir(sourcePath) + opt_configmung + processor.CPU()
- If opt_standalone Or (processor.CPU() = "x86" And processor.Platform() = "win32") Then
- path :+ ".incbin.c"
- Else
- path :+ ".incbin2.c"
- End If
- Local ibPath:String = ExtractDir(sourcePath) + "/.bmx/" + path
- Local ib:TSourceFile = GetSourceFile(ibPath,,,,False)
-
- If Not ib Then
- ib = New TSourceFile
-
- ib.path = ibPath
- ib.obj_path = StripExt(ib.path) + ".o"
- ib.ext = "c"
- ib.exti = String(processor.RunCommand("source_type", [ib.ext])).ToInt()
- source.imports.AddLast(".bmx/" + StripDir(path) )
- End If
-
- If ib.includePaths.IsEmpty() Then
- ib.CopyIncludePaths(source.includePaths)
- End If
- GetIncBinFileList(ib)
-
- ib.time = FileTime(ib.path)
- ib.obj_time = FileTime(ib.obj_path)
- sources.Insert(ib.path, ib)
- If opt_standalone And opt_boot Then
- processor.PushSource(ib.path)
- End If
- Return ib
- End Method
-
- Method GetIncBinFileList(source:TSourceFile)
- Local stream:TStream = ReadStream(source.path)
- If stream Then
- While Not stream.Eof()
- Local line:String = stream.ReadLine()
- If line.StartsWith("// FILE : ") Then
- Local parts:String[] = line[10..].Split("~t")
- Local ib:String = parts[0].Replace("~q", "")
- If ib Then
- source.incbins.AddLast(ib)
- If parts.length = 2 Then
- source.hashes.Insert(ib, parts[1])
- End If
- End If
- Else If line.StartsWith("// ----") Then
- Exit
- EndIf
- Wend
-
- stream.Close()
- End If
- End Method
-
- Method IncbinsDifference:Int(ib1:TList, ib2:TList)
- If ib1.Count() <> ib2.Count() Then
- Return True
- End If
- For Local ib:String = EachIn ib1
- If Not ib2.Contains(ib) Then
- Return True
- End If
- Next
- For Local ib:String = EachIn ib2
- If Not ib1.Contains(ib) Then
- Return True
- End If
- Next
-
- Return False
- End Method
-
- Method IncbinsHashDifference:Int(source:TSourceFile, ib:TSourceFile)
- If source.hashes.IsEmpty() Then
- Return True
- End If
-
- For Local file:String = EachIn source.hashes.Keys()
- Local sourceHash:String = String(source.hashes.ValueForKey(file))
- If sourceHash <> String(ib.hashes.ValueForKey(file)) Then
- Return True
- End If
- Next
- For Local file:String = EachIn ib.hashes.Keys()
- Local ibHash:String = String(ib.hashes.ValueForKey(file))
- If ibHash <> String(source.hashes.ValueForKey(file)) Then
- Return True
- End If
- Next
- End Method
-
- Method CreateLinkStage:TSourceFile(source:TSourceFile, stage:Int = STAGE_LINK)
- Local link:TSourceFile = New TSourceFile
-
- source.CopyInfo(link)
-
- link.deps.Insert(StripExt(link.obj_path) + ".c", source)
- link.stage = stage
- link.processed = True
- link.depsList = New TList
- link.depsList.AddLast(source)
- If IOS_HAS_MERGE And processor.Platform() = "ios" Then
- sources.Insert(link.obj_path, link)
- Else
- sources.Insert(link.arc_path, link)
- End If
- Return link
- End Method
-
- Method CreateMergeStage:TSourceFile(source:TSourceFile)
- Local merge:TSourceFile = New TSourceFile
-
- source.CopyInfo(merge)
-
- merge.deps.Insert(merge.obj_path, source)
- merge.stage = STAGE_MERGE
- merge.processed = True
- merge.depsList = New TList
- merge.depsList.AddLast(source)
- sources.Insert(merge.merge_path, merge)
- Return merge
- End Method
-
- Method CalculateBatches:TList(files:TList)
- Local batches:TList = New TList
-
- Local count:Int
- Local instances:TMap = New TMap
- For Local m:TSourceFile = EachIn files
- instances.Insert(m.GetSourcePath(), m)
- count :+ 1
- Next
-
-
- Local dependencies:TMap = New TMap
- For Local m:TSourceFile = EachIn files
- dependencies.Insert(m.GetSourcePath(), m.deps)
- Next
-
- Local pct:Float = 100.0 / count
- Local total:Float
- Local num:Int
-
- While Not dependencies.IsEmpty()
-
- Local noDeps:TList = New TList
- For Local depName:String = EachIn dependencies.Keys()
- Local dep:TMap = TMap(dependencies.ValueForKey(depName))
- If dep.IsEmpty() Then
- noDeps.AddLast(depName)
- End If
- Next
-
- If noDeps.IsEmpty() Then
- ' circular dependency!
- ' TODO : dump current list for user to work out?
- Print "REMAINING :"
- For Local depName:String = EachIn dependencies.Keys()
- Print " " + depName
- Next
- Throw "circular dependency!"
- End If
-
- ' remove from dependencies
- For Local name:String = EachIn noDeps
- dependencies.Remove(name)
- Next
-
- For Local dep:TMap = EachIn dependencies.Values()
- For Local name:String = EachIn noDeps
- dep.Remove(name)
- Next
- Next
- Local list:TList = New TList
- For Local name:String = EachIn noDeps
- Local m:TSourceFile = TSourceFile(instances.ValueForKey(name))
- list.AddLast(m)
- Next
- batches.AddLast(list)
-
- Wend
- ' post process batches
- Local suffix:String[]
- Local stage:Int
- For Local i:Int = 0 Until 3
- Select i
- Case 0
- suffix = ["c", "cpp", "cc", "cxx", "m", "mm"]
- Case 1
- suffix = ["o"]
- stage = STAGE_LINK
- Case 2
- suffix = ["o"]
- stage = STAGE_APP_LINK
- End Select
-
- Local newList:TList = New TList
-
- For Local list:TList = EachIn batches
-
- For Local f:TSourceFile = EachIn list
-
- Local p:String = f.GetSourcePath()
-
- If Not p.EndsWith("bmx") Then
- For Local s:String = EachIn suffix
- If p.EndsWith(s) Then
- If app_iface And stage Then
- If (stage = STAGE_LINK And app_iface = f.iface_path) Or (stage = STAGE_APP_LINK And app_iface <> f.iface_path) Then
- Continue
- End If
- End If
- newList.AddLast(f)
- list.Remove(f)
- If list.IsEmpty() Then
- batches.Remove(list)
- End If
- ' found, no need to loop further
- Exit
- End If
- Next
- End If
- Next
- Next
-
- If Not newList.IsEmpty() Then
- batches.AddLast(newList)
- End If
- Next
-
- For Local list:TList = EachIn batches
- For Local m:TSourceFile = EachIn list
- total :+ pct
- num :+ 1
- If num = count Then
- m.pct = 100
- Else
- m.pct = total
- End If
- Next
- Next
- Return batches
-
- End Method
-
- Method ShowPct:String(pct:Int)
- Local s:String = "["
- Local p:String = String.FromInt(pct)
- Select p.length
- Case 1
- s :+ " "
- Case 2
- s :+ " "
- End Select
- Return s + p + "%] "
- End Method
-
- Method FixPct:String(pct:String)
- If processor.Platform() = "win32" Then
- Return pct.Replace("%", "%%")
- Else
- Return pct
- End If
- End Method
- Method CheckPath:String(basePath:String, path:String)
- Local p:String = RealPath(basePath + "/" + path)
- If Not FileType(p) Then
- ' maybe path is a full path already?
- p = RealPath(path)
- If Not FileType(p) Then
- ' meh... fallback to original
- p = RealPath(basePath + "/" + path)
- End If
- End If
- Return p
- End Method
-
- Method DoCallback(src:String)
- Local update:Int = True
- Local m:TSourceFile = TSourceFile(sources.ValueForKey(src))
-
- If m Then
- If FileType(m.iface_path) = FILETYPE_FILE Then
- ' has the interface/api changed since the last build?
- If FileType(m.iface_path2) = FILETYPE_FILE And m.time = FileTime( m.path ) Then
- If FileSize(m.iface_path) = FileSize(m.iface_path2) Then
- Local i_bytes:Byte[] = LoadByteArray(m.iface_path)
- Local i_bytes2:Byte[] = LoadByteArray(m.iface_path2)
- ?bmxng
- If i_bytes.length = i_bytes2.length And memcmp_( i_bytes, i_bytes2, Size_T(i_bytes.length) )=0 Then
- ?Not bmxng
- If i_bytes.length = i_bytes2.length And memcmp_( i_bytes, i_bytes2, i_bytes.length )=0 Then
- ?
- update = False
- End If
- End If
- End If
- If update Then
- CopyFile m.iface_path, m.iface_path2
- Else If m.iface_time < m.MaxIfaceTime() Then
- SetFileTimeNow(m.iface_path2)
- m.iface_time = time_(Null)
- m.maxIfaceTimeCache = -1
- End If
- End If
-
- If update Then
- m.SetRequiresBuild(True)
- m.iface_time = time_(Null)
- m.maxIfaceTimeCache = -1
- m.gen_time = time_(Null)
- End If
-
- End If
- End Method
-
- End Type
- Type TArcTask
- Field m:TSourceFile
- Field path:String
- Field oobjs:TList
- Method Create:TArcTask(m:TSourceFile, path$ , oobjs:TList )
- Self.m = m
- Self.path = path
- Self.oobjs = oobjs
- Return Self
- End Method
- Function _CreateArc:Object(data:Object)
- Return TArcTask(data).CreateArc()
- End Function
-
- Method CreateArc:Object()
- DeleteFile path
- Local cmd$,t$
-
- If processor.Platform() = "win32"
- For t$=EachIn oobjs
- If Len(cmd)+Len(t)>1000
- If opt_standalone And Not opt_nolog processor.PushLog(cmd)
- If processor.Sys( cmd )
- DeleteFile path
- Throw "Build Error: Failed to create archive "+path
- EndIf
- cmd=""
- EndIf
- If Not cmd Then
- Local prefix:String = processor.MinGWExePrefix()
- Local ext:String = ""
- If processor.OSPlatform() = "win32" Then
- ext = ".exe"
- End If
- cmd= processor.Option("path_to_ar", processor.MinGWBinPath() + "/" + prefix + "ar" + ext) + " -rc "+CQuote(path)
- End If
- cmd:+" "+CQuote(t)
- Next
- End If
-
- If processor.Platform() = "macos" Or processor.Platform() = "osx" Then
- cmd=processor.Option(processor.BuildName("libtool"), "libtool") + " -o "+CQuote(path)
- For Local t$=EachIn oobjs
- cmd:+" "+CQuote(t)
- Next
- End If
-
- If processor.Platform() = "ios" Then
- Local proc:String = processor.CPU()
- Select proc
- Case "x86"
- proc = "i386"
- Case "x64"
- proc = "x86_64"
- End Select
-
- cmd= processor.Option(processor.BuildName("libtool"), "libtool") + " -static -arch_only " + proc + " -o "+CQuote(path)
- For Local t$=EachIn oobjs
- cmd:+" "+CQuote(t)
- Next
- End If
-
- If processor.Platform() = "linux" Or processor.Platform() = "raspberrypi" Or processor.Platform() = "android" Or processor.Platform() = "emscripten" Or processor.Platform() = "nx" Or processor.Platform() = "haiku"
- For Local t$=EachIn oobjs
- If Len(cmd)+Len(t)>1000
-
- If opt_standalone And Not opt_nolog processor.PushLog(cmd)
- If processor.Sys( cmd )
- DeleteFile path
- Throw "Build Error: Failed to create archive "+path
- EndIf
- cmd=""
- EndIf
- If processor.Platform() = "emscripten" Then
- If Not cmd cmd=processor.Option(processor.BuildName("ar"), "emar") + " r "+CQuote(path)
- Else
- If Not cmd cmd=processor.Option(processor.BuildName("ar"), "ar") + " -r "+CQuote(path)
- End If
- cmd:+" "+CQuote(t)
- Next
- End If
-
- If cmd
- If opt_standalone And Not opt_nolog processor.PushLog(cmd)
- If processor.Sys( cmd )
- DeleteFile path
- Throw "Build Error: Failed to create archive "+path
- End If
- EndIf
-
- m.arc_time = time_(Null)
- m.obj_time = time_(Null)
- End Method
-
- End Type
|