summaryrefslogtreecommitdiffstats
path: root/Mac/Tools/macfreeze/macgen_bin.py
diff options
context:
space:
mode:
Diffstat (limited to 'Mac/Tools/macfreeze/macgen_bin.py')
-rw-r--r--Mac/Tools/macfreeze/macgen_bin.py200
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