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
|