My bmk version picking up Mac icons
BlitzMax Forums/BlitzMax Module Tweaks/My bmk version picking up Mac icons
| ||
I need to note, the tweak I did here only works on Mac, if you compile the code below in Windows or Linux you should experience no difference at all. A thing in BlitzMax that always annoyed me is the fact that BMK always placed the BlitzMax logo as the logo for my GUI apps on Mac. Now icons are very easy to replace on Mac, I'm pretty sure there ain't no OS on which this is simpler, however if I got to re-compile the same code over and over (in order to add new features or fix bugs) I get that BMax logo back requiring me to replace it once again. To make matters even worse, OS X has a very aggressive caching system, so even if I replace the icon manually I will still see the BMax Logo, so I always have to hope the right icon is there when I zip my apps for distrubution. The code below is the source code of BMK (in BlitzMax v1.51) and the only file that needed a tweak was bmk.bmx itself, so that makes stuff easier. When using this version of bmk to build a GUI app on Mac (on console apps everything works the same as with the original BMK), you can do two things to make this BMK directly place your own icon into your app bundle. Let's say we call our game "BlitzMario" and that the main build file is BlitzMario.bmx. If you place an icon with the same file name into the same folder as BlitzMario.bmx (so the icon will be named "BlitzMario.icns"), bmk will place that icon into the built app. Another method is to place a textfile named BlitzMario.bmx.macicons in the same folder as BlitzMario.bmx and that file should contain nothing more but the full filename of the desired icon (always with full path name + extention). I myself only use that option if I make a quick toolset of multiple apps all having the same icon. If in the example above neither BlitzMario.icns nor BlitzMario.bmx.macicons can be found, the bmk will ask if you want to try it again (you may have forgotten, so you can now set it right, and request bmk to start over) or you can make bmk put in the BlitzMax logo anyway. I also build in a cancel option in that case, however when bmk is called from MaxIDE this does not really seem to work the way it should. I've been doing this tweak in nearly every new BlitzMax version I installed and I must say it saved me a lot of trouble messing with the icons every time I compile a GUI app. Since Windows compiling requires just you put your icon in an .o file which you can import, no trouble arises at all in Windows, and as far as I found out Linux does not directly link icons to an executable the way Mac and Windows do (png files in the start menu, but not "inside" the app itself) so not really an issue there either I guess. :) I felt like I should have shared this "tweak" with the community before, but in Dutch we often say "beter te laat dan nooit", meaning literally "better too late than never". You can use this tweak any way you see fit (as long as it is within the BMax license), and you may credit me if you desire, but it's totally not required (as this "tweak" only took me 10 minutes or so, if not shorter). ;) ' ' Change History : ' BaH 28/09/2007 - Added custom appstub compiles using -b parameter. ' Synched with current bmk source. ' Strict Framework brl.basic Import "bmk_make.bmx" Import "bmk_zap.bmx" Import "bmk_bb2bmx.bmx" ?MacOS Incbin "macos.icns" ? If AppArgs.length<2 CmdError Local cmd$=AppArgs[1],args$[] args=ParseConfigArgs( AppArgs[2..] ) CreateDir BlitzMaxPath()+"/tmp" Select cmd.ToLower() Case "makeapp" SetConfigMung MakeApplication args,False Case "makelib" SetConfigMung MakeApplication args,True Case "makemods" ' Local ms=MilliSecs() If opt_debug Or opt_release SetConfigMung MakeModules args Else opt_debug=True opt_release=False SetConfigMung MakeModules args opt_debug=False opt_release=True SetConfigMung MakeModules args EndIf ' ms=MilliSecs()-ms ' Print "ms="+ms Case "cleanmods" CleanModules args Case "zapmod" ZapModule args Case "unzapmod" UnzapModule args Case "listmods" ListModules args Case "modstatus" ModuleStatus args Case "syncmods" SyncModules args Case "convertbb" ConvertBB args Case "ranlibdir" RanlibDir args Default CmdError End Select Function SetConfigMung() If opt_release opt_debug=False opt_configmung="release" If opt_threaded opt_configmung:+".mt" opt_configmung="."+opt_configmung+"."+cfg_platform+"."+opt_arch Else opt_debug=True opt_release=False opt_configmung="debug" If opt_threaded opt_configmung:+".mt" opt_configmung="."+opt_configmung+"."+cfg_platform+"."+opt_arch EndIf End Function Function SetModfilter( t$ ) opt_modfilter=t.ToLower() If opt_modfilter="*" opt_modfilter="" Else If opt_modfilter[opt_modfilter.length-1]<>"." opt_modfilter:+"." EndIf End Function Function MakeModules( args$[] ) If args.length>1 CmdError If args.length SetModfilter args[0] Else opt_modfilter="" Local mods:TList=EnumModules() BeginMake MakeMod "brl.blitz" For Local name$=EachIn mods MakeMod name Next End Function Function CleanModules( args$[] ) If args.length>1 CmdError If args.length SetModfilter args[0] Else opt_modfilter="" Local mods:TList=EnumModules() Local name$ For name=EachIn mods If (name+".").Find(opt_modfilter)<>0 Continue Print "Cleaning:"+name Local path$=ModulePath(name) DeleteDir path+"/.bmx",True If Not opt_kill Continue For Local f$=EachIn LoadDir( path ) Local p$=path+"/"+f Select FileType(p) Case FILETYPE_DIR If f<>"doc" DeleteDir p,True EndIf Case FILETYPE_FILE Select ExtractExt(f).tolower() Case "i","a","txt","htm","html" 'nop Default DeleteFile p End Select End Select Next Next End Function Function MakeApplication( args$[],makelib ) If opt_execute If Len(args)=0 CmdError Else If Len(args)<>1 CmdError EndIf Local Main$=RealPath( args[0] ) Select ExtractExt(Main).ToLower() Case "" Main:+".bmx" Case "c","cpp","cxx","mm","bmx" Default Throw "Unrecognized app source file type:"+ExtractExt(Main) End Select If FileType(Main)<>FILETYPE_FILE Throw "Unable to open source file '"+Main+"'" If Not opt_outfile opt_outfile=StripExt( Main ) ?Win32 If makelib If ExtractExt(opt_outfile).ToLower()<>"dll" opt_outfile:+".dll" Else If ExtractExt(opt_outfile).ToLower()<>"exe" opt_outfile:+".exe" EndIf ? ?MacOS If opt_apptype="gui" Local appId$=StripDir( opt_outfile ) Local exeDir$=opt_outfile+".app",d$,t:TStream Local IconFile$ = "incbin::macos.icns" ' Tricky's custom icon routine. Local Ok = False ' Tricky's custom icon routine. d=exeDir+"/Contents/MacOS" Select FileType( d ) Case FILETYPE_NONE CreateDir d,True If FileType( d )<>FILETYPE_DIR Throw "Unable to create application directory" EndIf Case FILETYPE_FILE Throw "Unable to create application directory" Case FILETYPE_DIR End Select d=exeDir+"/Contents/Resources" Select FileType( d ) Case FILETYPE_NONE CreateDir d If FileType( d )<>FILETYPE_DIR Throw "Unable to create resources directory" EndIf Case FILETYPE_FILE Throw "Unable to create resources directory" Case FILETYPE_DIR End Select t=WriteStream( exeDir+"/Contents/Info.plist" ) If Not t Throw "Unable to create Info.plist" t.WriteLine "<?xml version=~q1.0~q encoding=~qUTF-8~q?>" t.WriteLine "<!DOCTYPE plist PUBLIC ~q-//Apple Computer//DTD PLIST 1.0//EN~q ~qhttp://www.apple.com/DTDs/PropertyList-1.0.dtd~q>" t.WriteLine "<plist version=~q1.0~q>" t.WriteLine "<dict>" t.WriteLine "~t<key>CFBundleExecutable</key>" t.WriteLine "~t<string>"+appId+"</string>" t.WriteLine "~t<key>CFBundleIconFile</key>" t.WriteLine "~t<string>"+appId+"</string>" t.WriteLine "~t<key>CFBundlePackageType</key>" t.WriteLine "~t<string>APPL</string>" t.WriteLine "</dict>" t.WriteLine "</plist>" t.Close t=WriteStream( exeDir+"/Contents/Resources/"+appId+".icns" ) If Not t Throw "Unable to create icons" 'Local in:TStream=ReadStream( "incbin::macos.icns" ) ' Tricky's custom icon routine. Start! Repeat If FileType(StripExt(args[0])+".icns")=1 Print "Same named Icon found!" IconFile = StripExt(args[0])+".icns" ok=True ElseIf FileType(args[0]+".macicons") Print "Reading data from: "+args[0]+".macicons" iconfile = Trim(LoadString(args[0]+".macicons")) Ok=True Else Print "WARNING! No Icon Data Found! What do you want to do?" Print "0 = Try again" Print "1 = Use the BlitzMax Logo for the icon" Print "2 = Cancel this build" Local k Repeat k=Input("Please enter your choice: ").ToInt() Until K>=0 And K<=2 Select K Case 0 Ok=False Case 1 Ok=True Case 3 End End Select EndIf Until Ok Print "Using icon file: "+iconfile Local in:TStream=ReadStream( iconfile ) CopyStream in,t in.Close t.Close opt_outfile=exeDir+"/Contents/MacOS/"+appId EndIf ? BeginMake MakeApp Main,makelib If opt_execute Print "Executing:"+StripDir( opt_outfile ) Local cmd$=CQuote( opt_outfile ) For Local i=1 Until args.length cmd:+" "+CQuote( args[i] ) Next Sys cmd EndIf End Function Function ZapModule( args$[] ) If Len(args)<>2 CmdError Local modname$=args[0].ToLower() Local outfile$=RealPath( args[1] ) Local stream:TStream=WriteStream( outfile ) If Not stream Throw "Unable to open output file" ZapMod modname,stream stream.Close End Function Function UnzapModule( args$[] ) If Len(args)<>1 CmdError Local infile$=args[0] Local stream:TStream=ReadStream( infile ) If Not stream Throw "Unable to open input file" UnzapMod stream stream.Close End Function Function ListModules( args$[],modid$="" ) If Len(args)<>0 CmdError Throw "Todo!" End Function Function ModuleStatus( args$[] ) If Len(args)<>1 CmdError ListModules Null,args[0] End Function Function SyncModules( args$[] ) If args.length CmdError If Sys( BlitzMaxPath()+"/bin/syncmods" ) Throw "SyncMods error" End Function Function RanlibDir( args$[] ) If args.length<>1 CmdError Ranlib args[0] End Function |