diff options
Diffstat (limited to 'Mac/Tools/macfreeze/macgen_bin.py')
-rw-r--r-- | Mac/Tools/macfreeze/macgen_bin.py | 200 |
1 files changed, 197 insertions, 3 deletions
diff --git a/Mac/Tools/macfreeze/macgen_bin.py b/Mac/Tools/macfreeze/macgen_bin.py index d524e9b..a4ee828 100644 --- a/Mac/Tools/macfreeze/macgen_bin.py +++ b/Mac/Tools/macfreeze/macgen_bin.py @@ -1,6 +1,200 @@ """macgen_bin - Generate application from shared libraries""" -import EasyDialogs -def generate(output, module_dict): - EasyDialogs.Message('Not yet implemented') +import os +import sys +import string +import types +import macfs +from MACFS import * +import Res +import py_resource +import cfmfile +import buildtools + + +def generate(input, output, module_dict = None, architecture = 'fat', debug=0): + # try to remove old file + try: + os.remove(output) + except: + pass + + if module_dict is None: + import macmodulefinder + print "Searching for modules..." + module_dict = macmodulefinder.process(input, [], [], 1) + + applettemplatepath = buildtools.findtemplate() + corepath = findpythoncore() + + dynamicmodules, dynamicfiles, extraresfiles = findfragments(module_dict, architecture) + print "Adding ³__main__²" + buildtools.process(applettemplatepath, input, output, 0) + + outputref = Res.OpenResFile(output) + try: + Res.UseResFile(outputref) + + print "Adding Python modules" + addpythonmodules(module_dict) + + print "Adding PythonCore resources" + copyres(corepath, outputref, ['cfrg', 'Popt', 'GU…I'], 1) + + print "Adding resources from shared libraries" + for ppcpath, cfm68kpath in extraresfiles: + if os.path.exists(ppcpath): + copyres(ppcpath, outputref, ['cfrg'], 1) + elif os.path.exists(cfm68kpath): + copyres(cfm68kpath, outputref, ['cfrg'], 1) + + print "Fixing sys.path prefs" + Res.UseResFile(outputref) + try: + res = Res.Get1Resource('STR#', 228) # from PythonCore + except Res.Error: pass + else: + res.RemoveResource() + # setting pref file name to empty string + res = Res.Get1NamedResource('STR ', "PythonPreferenceFileName") + res.data = Pstring("") + res.ChangedResource() + syspathpref = "$(APPLICATION)" + res = Res.Resource("\000\001" + Pstring(syspathpref)) + res.AddResource("STR#", 229, "sys.path preference") + + print "Creating 'PYD ' resources" + for modname, (ppcfrag, cfm68kfrag) in dynamicmodules.items(): + res = Res.Resource(Pstring(ppcfrag) + Pstring(cfm68kfrag)) + id = 0 + while id < 128: + id = Res.Unique1ID('PYD ') + res.AddResource('PYD ', id, modname) + finally: + Res.CloseResFile(outputref) + print "Merging code fragments" + cfmfile.mergecfmfiles([applettemplatepath, corepath] + dynamicfiles.keys(), + output, architecture) + + fss = macfs.FSSpec(output) + fss.SetCreatorType('Pyta', 'APPL') + print "done!" + + +def findfragments(module_dict, architecture): + dynamicmodules = {} + dynamicfiles = {} + extraresfiles = [] + for name, module in module_dict.items(): + if module.gettype() <> 'dynamic': + continue + path = resolvealiasfile(module.__file__) + dir, filename = os.path.split(path) + ppcfile, cfm68kfile = makefilenames(filename) + + # ppc stuff + ppcpath = os.path.join(dir, ppcfile) + if architecture <> 'm68k': + ppcfrag, dynamicfiles = getfragname(ppcpath, dynamicfiles) + else: + ppcfrag = "_no_fragment_" + + # 68k stuff + cfm68kpath = os.path.join(dir, cfm68kfile) + if architecture <> 'pwpc': + cfm68kfrag, dynamicfiles = getfragname(cfm68kpath, dynamicfiles) + else: + cfm68kfrag = "_no_fragment_" + + dynamicmodules[name] = ppcfrag, cfm68kfrag + if (ppcpath, cfm68kpath) not in extraresfiles: + extraresfiles.append((ppcpath, cfm68kpath)) + return dynamicmodules, dynamicfiles, extraresfiles + + +def getfragname(path, dynamicfiles): + if not dynamicfiles.has_key(path): + if os.path.exists(path): + lib = cfmfile.CfrgResource(path) + fragname = lib.fragments[0].name + else: + print "shared lib not found:", path + fragname = "_no_fragment_" + dynamicfiles[path] = fragname + else: + fragname = dynamicfiles[path] + return fragname, dynamicfiles + + +def addpythonmodules(module_dict): + items = module_dict.items() + items.sort() + for name, module in items: + if module.gettype() != 'module' or name == "__main__": + continue + location = module.__file__ + + if location[-4:] == '.pyc': + # Attempt corresponding .py + location = location[:-1] + if location[-3:] != '.py': + print '*** skipping', location + continue + + print 'Adding module ³%s²' % name + id, name = py_resource.frompyfile(location, name, preload=0) + +def Pstring(str): + if len(str) > 255: + raise TypeError, "Str255 must be at most 255 chars long" + return chr(len(str)) + str + +def makefilenames(name): + lname = string.lower(name) + pos = string.find(lname, ".ppc.") + if pos > 0: + return name, name[:pos] + '.CFM68K.' + name[pos+5:] + pos = string.find(lname, ".cfm68k.") + if pos > 0: + return name[:pos] + '.ppc.' + name[pos+8:], name + raise ValueError, "can't make ppc/cfm68k filenames" + +def copyres(input, output, *args, **kwargs): + openedin = openedout = 0 + if type(input) == types.StringType: + input = Res.OpenResFile(input) + openedin = 1 + if type(output) == types.StringType: + output = Res.OpenResFile(output) + openedout = 1 + try: + apply(buildtools.copyres, (input, output) + args, kwargs) + finally: + if openedin: + Res.CloseResFile(input) + if openedout: + Res.CloseResFile(output) + +def findpythoncore(): + """find the PythonCore shared library, possibly asking the user if we can't find it""" + + vRefNum, dirID = macfs.FindFolder(kOnSystemDisk, kExtensionFolderType, 0) + extpath = macfs.FSSpec((vRefNum, dirID, "")).as_pathname() + version = string.split(sys.version)[0] + corepath = os.path.join(extpath, "PythonCore " + version) + if not os.path.exists(corepath): + fss, ok = macfs.PromptGetFile("Please locate PythonCore:", "shlb") + if not ok: + raise KeyboardInterrupt, "cancelled" + corepath = fss.as_pathname() + return resolvealiasfile(corepath) + +def resolvealiasfile(path): + try: + fss, dummy1, dummy2 = macfs.ResolveAliasFile(path) + except macfs.error: + pass + else: + path = fss.as_pathname() + return path |