bmk.bmx 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602
  1. '
  2. ' Change History :
  3. ' 3.06 31/08/2015 - Added universal ios builds (x86+x64, armv7+arm64).
  4. ' Added ?ptr32 and ?ptr64 compiler definitions.
  5. ' Copy android resources to apk.
  6. ' 3.05 04/08/2015 - Added support for ios target.
  7. ' 3.04 03/07/2015 - Added -quick app build option - skips building/checking required module if .a and .i present.
  8. ' 3.03 20/06/2015 - Legacy bcc installations can now use local MinGW32 dir.
  9. ' 3.02 10/06/2015 - Added standalone app build generation. Generates source and build script for bmk/bcc-less compile.
  10. ' 3.01 28/05/2015 - Reworked android stuff to work with standard setup.
  11. ' Fixed OS X sysroot issue, and enhanced OS X configuration.
  12. ' Improved support for mixed builds (compiling between legacy and ng)
  13. ' 3.00 05/05/2015 - "Chirpy Chipmunk"
  14. ' - Redesign of dependency processing - parallel build!
  15. ' - Added progress information.
  16. ' - Now uses thread pool.
  17. ' 2.25 15/02/2015 - Fix for preprocessor bmxng version check.
  18. ' Fixed Win32 pthread link order issue.
  19. ' Use Win32 pthread link for GCC 4.8+
  20. ' 2.24 22/01/2015 - Added support for emscripten target.
  21. ' Added platform/arch validation.
  22. ' Auto suffix .html for emscripten apps.
  23. ' Added opengles target platform preprocessor option.
  24. ' Added project-specific pre-processing - "<app file>.bmk".
  25. ' Added gdb debug generation option.
  26. ' 2.23 01/12/2014 - Added direct support for android and raspberrypi targets.
  27. ' - Added android configuration settings and project template.
  28. ' 2.22 02/10/2014 - Win32 NG will now prefer MINGW-located files (bin/lib), instead of BlitzMax bin/lib.
  29. ' - Use .exe suffixes for binaries on Windows.
  30. ' - Add MinGW/bin to PATH on Windows.
  31. ' - Handle quotes in Import strings.
  32. ' - Minimum OS-X version 10.5 (circa 2007).
  33. ' - Release builds are stripped by default. Can be overridden with 'stripsymbols' option.
  34. ' 2.21 28/08/2014 - Added support for 64-bit Win32 build options.
  35. ' 2.20 17/07/2014 - Improved target (cross-compile) options.
  36. ' - Fixed issue with Linux popen signature and old bcc.
  37. ' 2.19 05/06/2014 - Linux compilation fix for new bcc.
  38. ' - Architecture tweaks and documentation update.
  39. ' - Removed bb2bmx/convertbb option.
  40. ' 2.18 13/04/2014 - Added suport for 64-bit OS X build options.
  41. ' - Added new bcc c/c++ compiler definition : BMX_NG
  42. ' 2.17 25/02/2014 - Support multiple build systems.
  43. ' - Added Linux custom tool locations.
  44. ' 2.16 07/12/2013 - Support for pre-build scripts.
  45. ' Changes for OS X sandbox/codesign support.
  46. ' Return correct version when using clang as gcc compiler.
  47. ' Added configurable ld_opts settings.
  48. ' Enhanced inline pragma support.
  49. ' Fixed module hierarchical build issue.
  50. ' 2.15 04/12/2012 - Update to latest official changes.
  51. ' 2.14 05/10/2011 - Added recent official changes.
  52. ' Fixed mingw gcc 4.6+ build problems.
  53. ' 2.13 21/08/2011 - ModuleInfo quotes support.
  54. ' 2.12 30/07/2011 - OSX 10.7 (Lion) tweaks.
  55. ' 2.11 27/02/2011 - Use g++ instead of ld for linking on win32.
  56. ' 2.10 24/02/2011 - Added option for skipping module builds.
  57. ' 2.09 30/04/2010 - Fixed loadBMK to work for local app folder.
  58. ' 2.08 05/04/2010 - Added Tommo's include speedup fix.
  59. ' Fixed PPC universal link issue.
  60. ' 2.07 28/01/2010 - Fixed win32 linking to include libmingw32 both at the start and end of the list. (should cover 3.9.5 and 4.x gcc's)
  61. ' 2.06 30/12/2009 - Added APPID variable for scripts on Mac (useful for custom plists).
  62. ' 2.05 10/12/2009 - Added .cc file support.
  63. ' Fixed Linux optimization flag -Os always being set.
  64. ' 2.04 28/06/2009 - Tweaked thread error reporting.
  65. ' Small speedup with threading.
  66. ' 2.03 28/06/2009 - Improved custom options support for Universal builds.
  67. ' Fixed import ordering.
  68. ' 2.02 08/06/2009 - Fixed multiple defines problem.
  69. ' 2.01 07/06/2009 - Fixed dependency compilation issue - or lack of it!
  70. ' BaH 26/05/2009 - Added multi-process (threading) support.
  71. ' Improved custom variable overriding.
  72. ' BaH 18/05/2009 - Added Universal support (Mac) with -i parameter.
  73. ' Added cross-compile support with -l win32.
  74. ' BaH 28/09/2007 - Added custom appstub compiles using -b parameter.
  75. ' Synched with current bmk source.
  76. '
  77. Strict
  78. Framework brl.filesystem
  79. Import "bmk_make.bmx"
  80. Import "bmk_zap.bmx"
  81. ?MacOS
  82. Import BRL.RamStream
  83. Incbin "macos.icns"
  84. ?
  85. If AppArgs.length<2 CmdError "Not enough parameters", True
  86. Local cmd$=AppArgs[1],args$[]
  87. args=ParseConfigArgs( AppArgs[2..] )
  88. ' validate the platform configuration
  89. ValidatePlatformArchitecture()
  90. ' preload the default options
  91. processor.RunCommand("default_cc_opts", Null)
  92. ' load any global custom options (in BlitzMax/bin)
  93. LoadOptions
  94. CreateDir BlitzMaxPath()+"/tmp"
  95. Select cmd.ToLower()
  96. Case "makeapp"
  97. SetConfigMung
  98. MakeApplication args,False
  99. Case "makelib"
  100. SetConfigMung
  101. MakeApplication args,True
  102. Case "makemods"
  103. opt_quickscan = False
  104. If opt_debug Or opt_release
  105. SetConfigMung
  106. MakeModules args
  107. If opt_universal
  108. SetConfigMung
  109. processor.ToggleCPU()
  110. LoadOptions(True) ' reload options for PPC
  111. MakeModules args
  112. processor.ToggleCPU()
  113. LoadOptions(True)
  114. End If
  115. Else
  116. opt_debug=True
  117. opt_release=False
  118. SetConfigMung
  119. MakeModules args
  120. If opt_universal
  121. SetConfigMung
  122. processor.ToggleCPU()
  123. LoadOptions(True) ' reload options for PPC
  124. MakeModules args
  125. processor.ToggleCPU()
  126. LoadOptions(True)
  127. End If
  128. opt_debug=False
  129. opt_release=True
  130. SetConfigMung
  131. MakeModules args
  132. If opt_universal
  133. SetConfigMung
  134. processor.ToggleCPU()
  135. LoadOptions(True) ' reload options for PPC
  136. MakeModules args
  137. processor.ToggleCPU()
  138. LoadOptions(True)
  139. End If
  140. EndIf
  141. Case "cleanmods"
  142. CleanModules args
  143. Case "zapmod"
  144. ZapModule args
  145. Case "unzapmod"
  146. UnzapModule args
  147. Case "listmods"
  148. ListModules args
  149. Case "modstatus"
  150. ModuleStatus args
  151. Case "syncmods"
  152. SyncModules args
  153. Case "ranlibdir"
  154. RanlibDir args
  155. Case "-v"
  156. VersionInfo(processor.GCCVersion(), GetCoreCount())
  157. Default
  158. CmdError "Unknown operation '" + cmd.ToLower() + "'"
  159. End Select
  160. Function SetConfigMung()
  161. If opt_release
  162. opt_debug=False
  163. opt_configmung="release"
  164. If opt_threaded opt_configmung:+".mt"
  165. opt_configmung="."+opt_configmung+"."+processor.Platform()+"."'+opt_arch
  166. Else
  167. opt_debug=True
  168. opt_release=False
  169. opt_configmung="debug"
  170. If opt_threaded opt_configmung:+".mt"
  171. opt_configmung="."+opt_configmung+"."+processor.Platform()+"."'+opt_arch
  172. EndIf
  173. End Function
  174. Function SetModfilter( t$ )
  175. opt_modfilter=t.ToLower()
  176. If opt_modfilter="*"
  177. opt_modfilter=""
  178. Else If opt_modfilter[opt_modfilter.length-1]<>"." And opt_modfilter.Find(".") < 0 Then
  179. opt_modfilter:+"."
  180. EndIf
  181. End Function
  182. Function MakeModules( args$[] )
  183. If opt_standalone CmdError "Standalone build not available for makemods"
  184. If args.length>1 CmdError "Expecting only 1 argument for makemods"
  185. Local mods:TList
  186. If args.length Then
  187. Local m:String = args[0]
  188. If m.find(".") > 0 And m[m.length-1]<>"." Then
  189. ' full module name?
  190. mods = New TList
  191. mods.AddLast(m)
  192. SetModfilter m
  193. Else
  194. SetModfilter m
  195. mods = EnumModules()
  196. End If
  197. Else
  198. opt_modfilter=""
  199. mods = EnumModules()
  200. End If
  201. BeginMake
  202. Local buildManager:TBuildManager = New TBuildManager
  203. buildManager.MakeMods(mods, opt_all)
  204. buildManager.DoBuild()
  205. End Function
  206. Function CleanModules( args$[] )
  207. If args.length>1 CmdError "Expecting only 1 argument for cleanmods"
  208. If args.length SetModfilter args[0] Else opt_modfilter=""
  209. Local mods:TList=EnumModules()
  210. Local name$
  211. For name=EachIn mods
  212. If (name+".").Find(opt_modfilter)<>0 Continue
  213. Print "Cleaning:"+name
  214. Local path$=ModulePath(name)
  215. DeleteDir path+"/.bmx",True
  216. If Not opt_kill Continue
  217. For Local f$=EachIn LoadDir( path )
  218. Local p$=path+"/"+f
  219. Select FileType(p)
  220. Case FILETYPE_DIR
  221. If f<>"doc"
  222. DeleteDir p,True
  223. EndIf
  224. Case FILETYPE_FILE
  225. Select ExtractExt(f).tolower()
  226. Case "i","a","txt","htm","html"
  227. 'nop
  228. Default
  229. DeleteFile p
  230. End Select
  231. End Select
  232. Next
  233. Next
  234. End Function
  235. Function MakeApplication( args$[],makelib )
  236. If opt_execute
  237. If Len(args)=0 CmdError "Execute requires at least 1 argument"
  238. Else
  239. If Len(args)<>1 CmdError "Expecting only 1 argument for makeapp"
  240. EndIf
  241. Local Main$=RealPath( args[0] )
  242. Select ExtractExt(Main).ToLower()
  243. Case ""
  244. Main:+".bmx"
  245. Case "c","cpp","cxx","mm","bmx"
  246. Default
  247. Throw "Unrecognized app source file type:"+ExtractExt(Main)
  248. End Select
  249. If FileType(Main)<>FILETYPE_FILE Throw "Unable to open source file '"+Main+"'"
  250. If Not opt_outfile Then
  251. opt_outfile = StripExt( Main )
  252. Else
  253. opt_outfile = RealPath(opt_outfile)
  254. End If
  255. ' set some useful global variables
  256. globals.SetVar("BUILDPATH", ExtractDir(opt_outfile))
  257. globals.SetVar("EXEPATH", ExtractDir(opt_outfile))
  258. globals.SetVar("OUTFILE", StripDir(StripExt(opt_outfile)))
  259. ' some more useful globals
  260. If processor.Platform() = "macos" And opt_apptype="gui" Then
  261. Local appId$=StripDir( opt_outfile )
  262. globals.SetVar("APPID", appId)
  263. ' modify for bundle
  264. globals.SetVar("EXEPATH", ExtractDir(opt_outfile+".app/Contents/MacOS/"+appId))
  265. ' make bundle dirs
  266. Local exeDir$=opt_outfile+".app",d$
  267. d=exeDir+"/Contents/MacOS"
  268. Select FileType( d )
  269. Case FILETYPE_NONE
  270. CreateDir d,True
  271. If FileType( d )<>FILETYPE_DIR
  272. Throw "Unable to create application directory"
  273. EndIf
  274. Case FILETYPE_FILE
  275. Throw "Unable to create application directory"
  276. Case FILETYPE_DIR
  277. End Select
  278. d=exeDir+"/Contents/Resources"
  279. Select FileType( d )
  280. Case FILETYPE_NONE
  281. CreateDir d
  282. If FileType( d )<>FILETYPE_DIR
  283. Throw "Unable to create resources directory"
  284. EndIf
  285. Case FILETYPE_FILE
  286. Throw "Unable to create resources directory"
  287. Case FILETYPE_DIR
  288. End Select
  289. End If
  290. ' generic pre process
  291. LoadBMK(ExtractDir(Main) + "/pre.bmk")
  292. ' project-specific pre process
  293. LoadBMK(ExtractDir(Main) + "/" + StripDir( opt_outfile ) + ".bmk")
  294. If processor.Platform() = "win32" Then
  295. If makelib
  296. If ExtractExt(opt_outfile).ToLower()<>"dll" opt_outfile:+".dll"
  297. Else
  298. If ExtractExt(opt_outfile).ToLower()<>"exe" opt_outfile:+".exe"
  299. EndIf
  300. EndIf
  301. If processor.Platform() = "macos" Or processor.Platform() = "osx" Then
  302. If opt_apptype="gui"
  303. 'Local appId$=StripDir( opt_outfile )
  304. Local appId$ = globals.Get("APPID")
  305. Local exeDir$=opt_outfile+".app",d$,t:TStream
  306. Rem
  307. d=exeDir+"/Contents/MacOS"
  308. Select FileType( d )
  309. Case FILETYPE_NONE
  310. CreateDir d,True
  311. If FileType( d )<>FILETYPE_DIR
  312. Throw "Unable to create application directory"
  313. EndIf
  314. Case FILETYPE_FILE
  315. Throw "Unable to create application directory"
  316. Case FILETYPE_DIR
  317. End Select
  318. d=exeDir+"/Contents/Resources"
  319. Select FileType( d )
  320. Case FILETYPE_NONE
  321. CreateDir d
  322. If FileType( d )<>FILETYPE_DIR
  323. Throw "Unable to create resources directory"
  324. EndIf
  325. Case FILETYPE_FILE
  326. Throw "Unable to create resources directory"
  327. Case FILETYPE_DIR
  328. End Select
  329. End Rem
  330. t=WriteStream( exeDir+"/Contents/Info.plist" )
  331. If Not t Throw "Unable to create Info.plist"
  332. t.WriteLine "<?xml version=~q1.0~q encoding=~qUTF-8~q?>"
  333. t.WriteLine "<!DOCTYPE plist PUBLIC ~q-//Apple Computer//DTD PLIST 1.0//EN~q ~qhttp://www.apple.com/DTDs/PropertyList-1.0.dtd~q>"
  334. t.WriteLine "<plist version=~q1.0~q>"
  335. t.WriteLine "<dict>"
  336. t.WriteLine "~t<key>CFBundleExecutable</key>"
  337. t.WriteLine "~t<string>"+appId+"</string>"
  338. t.WriteLine "~t<key>CFBundleIconFile</key>"
  339. t.WriteLine "~t<string>"+appId+"</string>"
  340. t.WriteLine "~t<key>CFBundlePackageType</key>"
  341. t.WriteLine "~t<string>APPL</string>"
  342. If globals.Get("custom_plist") Then
  343. t.WriteLine "~t" + globals.Get("custom_plist")
  344. End If
  345. t.WriteLine "</dict>"
  346. t.WriteLine "</plist>"
  347. t.Close
  348. t=WriteStream( exeDir+"/Contents/Resources/"+appId+".icns" )
  349. If Not t Throw "Unable to create icons"
  350. Local in:TStream=ReadStream( "incbin::macos.icns" )
  351. CopyStream in,t
  352. in.Close
  353. t.Close
  354. opt_outfile=exeDir+"/Contents/MacOS/"+appId
  355. ' Mac GUI exepath is in the bundle...
  356. 'globals.SetVar("EXEPATH", ExtractDir(opt_outfile))
  357. 'globals.SetVar("APPID", appId)
  358. EndIf
  359. End If
  360. If processor.Platform() = "emscripten" Then
  361. If ExtractExt(opt_outfile).ToLower()<>"html" opt_outfile:+".html"
  362. End If
  363. BeginMake
  364. 'MakeApp Main,makelib
  365. Local buildManager:TBuildManager = New TBuildManager
  366. ' "android-project" check and copy
  367. If processor.Platform() = "android" Then
  368. DeployAndroidProject()
  369. End If
  370. buildManager.MakeApp(Main, makelib)
  371. buildManager.DoBuild(True)
  372. If opt_universal And processor.Platform() = "ios" Then
  373. processor.ToggleCPU()
  374. LoadOptions(True) ' reload options for PPC
  375. BeginMake
  376. Local buildManager:TBuildManager = New TBuildManager
  377. buildManager.MakeApp(Main, makelib)
  378. buildManager.DoBuild(True)
  379. processor.ToggleCPU()
  380. LoadOptions(True)
  381. End If
  382. Rem
  383. If opt_universal
  384. Local previousOutfile:String = opt_outfile
  385. processor.ToggleCPU()
  386. LoadOptions(True) ' reload options for PPC
  387. opt_outfile :+ "." + processor.CPU()
  388. BeginMake
  389. MakeApp Main,makelib
  390. processor.ToggleCPU()
  391. LoadOptions(True)
  392. MergeApp opt_outfile, previousOutfile
  393. opt_outfile = previousOutfile
  394. End If
  395. End Rem
  396. If opt_standalone
  397. Local buildScript:String = String(globals.GetRawVar("EXEPATH")) + "/" + StripExt(StripDir( app_main )) + "." + opt_apptype + opt_configmung + processor.CPU() + ".build"
  398. Local ldScript:String = "$APP_ROOT/ld." + processor.AppDet() + ".txt"
  399. Local stream:TStream = WriteStream(buildScript)
  400. stream.WriteString("echo ~qBuilding " + String(globals.GetRawVar("OUTFILE")) + "...~q~n~n")
  401. stream.WriteString("if [ -z ~q${APP_ROOT}~q ]; then~n")
  402. stream.WriteString("~tAPP_ROOT=" + String(globals.GetRawVar("EXEPATH")) + "~n")
  403. stream.WriteString("fi~n~n")
  404. stream.WriteString("if [ -z ~q${BMX_ROOT}~q ]; then~n")
  405. stream.WriteString("~tBMX_ROOT=" + BlitzMaxPath() + "~n")
  406. stream.WriteString("fi~n")
  407. stream.WriteString("~n~n")
  408. stream.WriteString("cp " + ldScript + " " + ldScript + ".tmp~n")
  409. stream.WriteString("sed -i -- 's=\$BMX_ROOT='$BMX_ROOT'=g' " + ldScript + ".tmp~n")
  410. stream.WriteString("sed -i -- 's=\$APP_ROOT='$APP_ROOT'=g' " + ldScript + ".tmp~n")
  411. stream.WriteString("~n~n")
  412. If processor.buildLog Then
  413. For Local s:String = EachIn processor.buildLog
  414. stream.WriteString(s + "~n")
  415. Next
  416. End If
  417. stream.WriteString("~n")
  418. stream.WriteString("echo ~qFinished.~q~n")
  419. stream.Close()
  420. End If
  421. If opt_execute
  422. ?Not android
  423. Print "Executing:"+StripDir( opt_outfile )
  424. Local cmd$=CQuote( opt_outfile )
  425. For Local i=1 Until args.length
  426. cmd:+" "+CQuote( args[i] )
  427. Next
  428. Sys cmd
  429. ?android
  430. ' on android we'll deploy the apk
  431. ?
  432. EndIf
  433. End Function
  434. Function ZapModule( args$[] )
  435. If Len(args)<>2 CmdError "Both module name and outfile required"
  436. Local modname$=args[0].ToLower()
  437. Local outfile$=RealPath( args[1] )
  438. Local stream:TStream=WriteStream( outfile )
  439. If Not stream Throw "Unable to open output file"
  440. ZapMod modname,stream
  441. stream.Close
  442. End Function
  443. Function UnzapModule( args$[] )
  444. If Len(args)<>1 CmdError "Expecting 1 argument for unzapmod"
  445. Local infile$=args[0]
  446. Local stream:TStream=ReadStream( infile )
  447. If Not stream Throw "Unable to open input file"
  448. UnzapMod stream
  449. stream.Close
  450. End Function
  451. Function ListModules( args$[],modid$="" )
  452. If Len(args)<>0 CmdError
  453. Throw "Todo!"
  454. End Function
  455. Function ModuleStatus( args$[] )
  456. If Len(args)<>1 CmdError
  457. ListModules Null,args[0]
  458. End Function
  459. Function SyncModules( args$[] )
  460. If args.length CmdError
  461. If Sys( BlitzMaxPath()+"/bin/syncmods" ) Throw "SyncMods error"
  462. End Function
  463. Function RanlibDir( args$[] )
  464. If args.length<>1 CmdError "Expecting 1 argument for ranlibdir"
  465. Ranlib args[0]
  466. End Function
  467. Function LoadOptions(reload:Int = False)
  468. If reload Then
  469. ' reset the options to default
  470. processor.RunCommand("default_cc_opts", Null)
  471. End If
  472. LoadBMK(AppDir + "/custom.bmk")
  473. End Function