]> granicus.if.org Git - python/commitdiff
Implementation of freezing from shared libraries, without source. (Just)
authorJack Jansen <jack.jansen@cwi.nl>
Fri, 31 Jul 1998 09:43:36 +0000 (09:43 +0000)
committerJack Jansen <jack.jansen@cwi.nl>
Fri, 31 Jul 1998 09:43:36 +0000 (09:43 +0000)
Mac/Tools/macfreeze/macfreeze.py
Mac/Tools/macfreeze/macgen_bin.py

index 60962eec0a1c28130fd0609f5ed1383a59d8d09e..2f43e204d17999a4dd2935e265043998c89f4cbf 100644 (file)
@@ -37,7 +37,7 @@ def main():
        mustwait = process(gentype, program, output, debug=debug)
        if mustwait:
                sys.exit(1)
-               
+
 def process(gentype, program, output, modules=[], module_files=[], debug=0):
        try:
                module_dict = macmodulefinder.process(program, modules, module_files, debug)
@@ -63,10 +63,10 @@ def process(gentype, program, output, modules=[], module_files=[], debug=0):
                return warnings
        elif gentype == 'applet':
                import macgen_bin
-               macgen_bin.generate(output, module_dict, debug)
+               architecture = 'fat' # user should choose
+               macgen_bin.generate(program, output, module_dict, architecture, debug)
        else:
                raise 'unknown gentype', gentype
-                       
+
 if __name__ == '__main__':
        main()
-               
index d524e9bb9d1e7d6221e82d0e5b0dcc2fc38b5055..a4ee828915311e987646d0d373b9f107dc18b155 100644 (file)
@@ -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\85I'], 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