12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241 |
- Strict
- Import "bmk_modutil.bmx"
- Rem
- Experimental speedup hack by Mark!
- Should allow you to modify non-interface affecting code without triggering lots of recompiles.
- Works by determining whether blah.bmx's .i file physically changes after blah.bmx is compiled.
- If not, then anything importing blah.bmx may not need to be recompiled.
- Uses a new '.i2' file which is updated only when actual .i file content changes.
- End Rem
- Global EXPERIMENTAL_SPEEDUP
- Local t$=getenv_( "BMK_SPEEDUP" )
- If t EXPERIMENTAL_SPEEDUP=True
- Global cc_opts$
- Global bcc_opts$
- Function BeginMake()
- cc_opts=Null
- bcc_opts=Null
- app_main=Null
- opt_framework=""
- End Function
- Function ConfigureAndroidPaths()
- CheckAndroidPaths()
-
- Local toolchain:String
- Local arch:String
- Local abi:String
-
- Select processor.CPU()
- Case "x86"
- toolchain = "x86-"
- arch = "arch-x86"
- abi = "x86"
- Case "x64"
- toolchain = "x86_64-"
- arch = "arch-x86_64"
- abi = "x86_64"
- Case "arm", "armeabi", "armeabiv7a"
- toolchain = "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-"
- 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/" + toolchain + "gcc" + exe
- Local gppPath:String = toolchainDir + "/bin/" + toolchain + "g++" + exe
- Local arPath:String = toolchainDir + "/bin/" + toolchain + "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 = getenv_("ANDROID_HOME")
- If Not androidHome Then
- androidHome = processor.Option("android.home", "")
- If Not androidHome Then
- Throw "ANDROID_HOME or 'android.home' config option not set"
- End If
-
- putenv_("ANDROID_HOME=" + androidHome.Trim())
- Else
- globals.SetVar("android.home", androidHome)
- End If
-
- Local androidSDK:String = getenv_("ANDROID_SDK")
- If Not androidSDK Then
- androidSDK = processor.Option("android.sdk", "")
- If Not androidSDK Then
- Throw "ANDROID_SDK or 'android.sdk' config option not set"
- End If
-
- putenv_("ANDROID_SDK=" + androidSDK.Trim())
- Else
- globals.SetVar("android.sdk", androidSDK)
- End If
- Local androidNDK:String = getenv_("ANDROID_NDK")
- If Not androidNDK Then
- androidNDK = processor.Option("android.ndk", "")
- If Not androidNDK Then
- Throw "ANDROID_NDK or 'android.ndk' config option not set"
- End If
-
- putenv_("ANDROID_NDK=" + androidNDK.Trim())
- Else
- globals.SetVar("android.ndk", androidNDK)
- End If
- Local androidToolchainVersion:String = getenv_("ANDROID_TOOLCHAIN_VERSION")
- If Not androidToolchainVersion Then
- androidToolchainVersion = processor.Option("android.toolchain.version", "")
- If Not androidToolchainVersion Then
- Throw "ANDROID_TOOLCHAIN_VERSION or 'android.toolchain.version' config option not set"
- End If
-
- putenv_("ANDROID_TOOLCHAIN_VERSION=" + androidToolchainVersion.Trim())
- Else
- globals.SetVar("android.toolchain.version", androidToolchainVersion)
- End If
- Local androidPlatform:String = getenv_("ANDROID_PLATFORM")
- If Not androidPlatform Then
- androidPlatform = processor.Option("android.platform", "")
- If Not androidPlatform Then
- Throw "ANDROID_PLATFORM or 'android.platform' config option not set"
- End If
-
- putenv_("ANDROID_PLATFORM=" + androidPlatform.Trim())
- Else
- globals.SetVar("android.platform", androidPlatform)
- End If
- Local androidSDKTarget:String = getenv_("ANDROID_SDK_TARGET")
- If Not androidSDKTarget Then
- androidSDKTarget = processor.Option("android.sdk.target", "")
-
- If androidSDKTarget Then
- putenv_("ANDROID_SDK_TARGET=" + androidSDKTarget.Trim())
- End If
-
- ' NOTE : if not set, we'll try to determine the actual target later, and fail if required then.
- Else
- globals.SetVar("android.sdk.target", androidSDKTarget)
- End If
- Local antHome:String = getenv_("ANT_HOME")
- If Not antHome Then
- antHome = processor.Option("ant.home", "")
- 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.Trim())
- Else
- globals.SetVar("ant.home", antHome)
- End If
- ?Not win32
- Local pathSeparator:String = ":"
- Local dirSeparator:String = "/"
- ?win32
- Local pathSeparator:String = ";"
- Local dirSeparator:String = "\"
- ?
- Local path:String = getenv_("PATH")
- path = androidSDK.Trim() + dirSeparator + "platform-tools" + pathSeparator + path
- path = androidSDK.Trim() + dirSeparator + "tools" + pathSeparator + path
- path = androidNDK.Trim() + pathSeparator + path
- path = antHome.Trim() + 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.sysroot", path)
- globals.SetVar("ios.syslibroot", path)
- Case "armv7", "arm64"
- Local path:String = "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk"
- globals.SetVar("ios.sysroot", path)
- globals.SetVar("ios.syslibroot", path)
- End Select
- End Function
- Type TBuildManager
- Field sources:TMap = New TMap
-
- Field buildAll:Int
-
- Field framework_mods:TList
-
- Method New()
- ' pre build checks
- If processor.Platform() = "android" Then
- ConfigureAndroidPaths()
- Else If processor.Platform() = "ios" Then
- ConfigureIOSPaths()
- End If
- 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)
- 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"
- source.obj_path = build_path + "/" + StripDir( main_path ) + "." + opt_apptype + opt_configmung + processor.CPU() + ".o"
- source.obj_time = FileTime(source.obj_path)
- source.iface_path = StripExt(source.obj_path) + ".o"
- source.iface_time = FileTime(source.iface_path)
-
- Local cc_opts:String = " -I" + CQuote(ModulePath(""))
- If opt_release Then
- cc_opts :+ " -DNDEBUG"
- End If
-
- Local bcc_opts:String = " -g " + processor.CPU()
- If opt_quiet bcc_opts:+" -q"
- If opt_verbose bcc_opts:+" -v"
- If opt_release bcc_opts:+" -r"
- If opt_threaded bcc_opts:+" -h"
- If opt_framework bcc_opts:+" -f " + opt_framework
- If opt_gdbdebug And processor.BCCVersion() <> "BlitzMax" Then
- bcc_opts:+" -d"
- End If
- source.cc_opts :+ cc_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
- bcc_opts :+" -f " + 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 = bcc_opts
- source.requiresBuild = 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
- Local link:TSourceFile = CreateLinkStage(gen)
- End Method
-
- Method DoBuild(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 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 = ExtractDir(m.path) + "/.bmx"
-
- If Not FileType(build_path) Then
- CreateDir build_path
- End If
-
- If FileType(build_path) <> FILETYPE_DIR Then
- Throw "Unable to create temporary directory"
- 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.obj_time Or m.iface_time < m.MaxIfaceTime()) Then
-
- m.requiresBuild = True
- 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
-
- m.iface_time = time_(Null)
-
- End If
- Case STAGE_FASM2AS
- For Local s:TSourceFile = EachIn m.depsList
- If s.requiresBuild Then
- m.requiresBuild = True
- Exit
- End If
- Next
- If m.requiresBuild Or (m.time > m.obj_time Or m.iface_time < m.MaxIfaceTime()) Then
-
- m.requiresBuild = 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.requiresBuild = 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
- Print ShowPct(m.pct) + "Compiling:" + StripDir(csrc_path)
- End If
- CompileC csrc_path,cobj_path, m.cc_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
- ' a module?
- If m.modid Then
- 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
- Print ShowPct(m.pct) + "Archiving:" + StripDir(m.arc_path)
- End If
- CreateArc m.arc_path, objs
- m.arc_time = time_(Null)
- m.obj_time = time_(Null)
-
- End If
- Else
- ' 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()
-
- If max_lnk_time > FileTime(opt_outfile) Or opt_all Then
- If Not opt_quiet Then
- Print ShowPct(m.pct) + "Linking:" + StripDir(opt_outfile)
- 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, False, globals.Get("ld_opts")
- m.obj_time = time_(Null)
- End If
- End If
- Case STAGE_MERGE
- ' 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 Select
- Else If Match(m.ext, "s") Then
- If m.time > m.obj_time Then ' object is older or doesn't exist
- m.requiresBuild = True
- End If
- If m.requiresBuild Then
- If Not opt_quiet Then
- Print ShowPct(m.pct) + "Compiling:" + StripDir(m.path)
- End If
-
- If processor.BCCVersion() = "BlitzMax" Then
- Assemble m.path, m.obj_path
- Else
- CompileC m.path, m.obj_path, m.cc_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.requiresBuild = True
- End If
-
- If m.requiresBuild Then
-
- If Not opt_quiet Then
- Print ShowPct(m.pct) + "Compiling:" + StripDir(m.path)
- End If
-
- CompileC m.path, m.obj_path, m.cc_opts
-
- m.obj_time = time_(Null)
- End If
- End If
- End If
-
- Next
- ?threaded
- processManager.WaitForTasks()
- ?
- Next
-
- If app_build Then
- ' post process
- LoadBMK(ExtractDir(app_main) + "/post.bmk")
- If processor.Platform() = "android"
- ' create the apk
-
- ' copy shared object
- Local androidABI:String = processor.Option("android.abi", "")
-
- Local appId:String = StripDir(StripExt(opt_outfile))
- Local buildDir:String = ExtractDir(opt_outfile)
- Local projectDir:String = buildDir + "/android-project-" + appId
-
- Local abiPath:String = projectDir + "/libs/" + androidABI
-
- Local sharedObject:String = "lib" + appId + ".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
-
- Else If processor.Platform() = "ios" Then
-
- Local iosSimulator:Int = (processor.CPU() = "x86")
-
- ' TODO - other stuff ?
-
- 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.cc_opts :+ " -I" + CQuote(ExtractDir(s.path))
- End If
- End If
- Next
- 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)
- If s Then
-
- If rebuildImports Then
- s.requiresBuild = 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
-
- 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.requiresBuild = True
- End If
- Else
- If Not FileType(StripExt(s.obj_path) + ".c") Then
- s.requiresBuild = 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
-
- 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.cc_opts :+ " -I" + CQuote(ExtractDir(path))
-
- Else If Match(ext, "o") Then ' object?
-
- 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
- ' 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)
- Local time:Int = FileTime(path)
-
- ' update our time to the latest incbin time
- If time > source.time Then
- source.time = time
- End If
-
- Next
- If source.depsList Then
- For Local s:TSourceFile = EachIn source.depsList
- If Not Match(s.ext, "bmx") Then
- s.cc_opts = source.cc_opts
- End If
- Next
- End If
-
- End If
- End Method
-
- Method GetSourceFile:TSourceFile(source_path:String, isMod:Int = False, rebuild:Int = False, isInclude:Int = False)
- Local source:TSourceFile = TSourceFile(sources.ValueForKey(source_path))
- If Not source 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)
-
- source.obj_path = ExtractDir(source_path) + "/.bmx/" + StripDir(source_path) + opt_configmung + processor.CPU() + ".o"
- source.obj_time = FileTime(source.obj_path)
-
- If Match(ext, "bmx") Then
- source.iface_path = ExtractDir(source_path) + "/.bmx/" + StripDir(source_path) + opt_configmung + processor.CPU() + ".i"
- source.iface_time = FileTime(source.iface_path)
- End If
- End If
- End If
- End If
- End If
-
- Return source
- 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 processor.Platform() = "ios" Then
- source = TSourceFile(sources.ValueForKey(merge_path))
- Else
- source = TSourceFile(sources.ValueForKey(arc_path))
- End If
- If Not source Then
- source = ParseISourceFile(iface_path)
-
- If source Then
- source.arc_path = arc_path
- source.arc_time = arc_time
- source.iface_path = iface_path
- source.iface_time = iface_time
- source.merge_time = merge_time
- If 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)
- ' get the module interface and lib details
- Local arc_path:String = path + "/" + id + opt_configmung + processor.CPU() + ".a"
- Local arc_time:Int = FileTime(arc_path)
- Local iface_path:String = path + "/" + id + opt_configmung + processor.CPU() + ".i"
- Local iface_time:Int = FileTime(iface_path)
- Local merge_path:String
- Local merge_time:Int
-
- If processor.Platform() = "ios" Then
- If processor.CPU() = "x86" Or processor.CPU() = "x64" Then
- merge_path = path + "/" + id + opt_configmung + "sim.a"
- Else
- merge_path = path + "/" + id + opt_configmung + "dev.a"
- End If
- merge_time = FileTime(merge_path)
- End If
- Local source:TSourceFile
- Local link:TSourceFile
- If arc_time And iface_time And opt_quickscan 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_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 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 = 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_time = iface_time
- source.merge_path = merge_path
- source.merge_time = merge_time
-
- Local cc_opts:String = " -I" + CQuote(path)
- cc_opts :+ " -I" + CQuote(ModulePath(""))
- If opt_release Then
- cc_opts :+ " -DNDEBUG"
- End If
- If opt_threaded Then
- cc_opts :+ " -DTHREADED"
- End If
-
- source.cc_opts = ""
- If source.mod_opts Then
- source.cc_opts :+ source.mod_opts.cc_opts
- End If
- source.cc_opts :+ cc_opts
-
- ' Module BCC opts
- Local bcc_opts:String = " -g "+processor.CPU()
- bcc_opts :+ " -m " + m
- If opt_quiet bcc_opts:+" -q"
- If opt_verbose bcc_opts:+" -v"
- If opt_release bcc_opts:+" -r"
- If opt_threaded bcc_opts:+" -h"
- If opt_gdbdebug And processor.BCCVersion() <> "BlitzMax" Then
- bcc_opts:+" -d"
- End If
-
- source.bcc_opts = bcc_opts
-
- source.requiresBuild = rebuild
- ' interface is REQUIRED for compilation
- If Not iface_time Then
- source.requiresBuild = 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
- Local realLink:TSourceFile = CreateLinkStage(gen)
-
- ' create a fat archive
- link = CreateMergeStage(realLink)
- End If
- Else
- If 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 CreateLinkStage:TSourceFile(source:TSourceFile)
- Local link:TSourceFile = New TSourceFile
-
- source.CopyInfo(link)
-
- link.deps.Insert(StripExt(link.obj_path) + ".c", source)
- link.stage = STAGE_LINK
- link.processed = True
- link.depsList = New TList
- link.depsList.AddLast(source)
- If 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)
- total :+ pct
- num :+ 1
- If num = count Then
- m.pct = 100
- Else
- m.pct = total
- End If
- Next
- batches.AddLast(list)
-
- Wend
-
- 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 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
-
- End Type
|