1 """macgen_bin - Generate application from shared libraries"""
15 def generate(input, output
, module_dict
=None, architecture
='fat', debug
=0):
16 # try to remove old file
22 if module_dict
is None:
23 import macmodulefinder
24 print "Searching for modules..."
25 module_dict
, missing
= macmodulefinder
.process(input, [], [], 1)
29 answer
= EasyDialogs
.AskYesNoCancel("Some modules could not be found; continue anyway?\n(%s)"
30 % string
.join(missing
, ", "))
34 applettemplatepath
= buildtools
.findtemplate()
35 corepath
= findpythoncore()
37 dynamicmodules
, dynamicfiles
, extraresfiles
= findfragments(module_dict
, architecture
)
39 print 'Adding "__main__"'
40 buildtools
.process(applettemplatepath
, input, output
, 0)
42 outputref
= Res
.OpenResFile(output
)
44 Res
.UseResFile(outputref
)
46 print "Adding Python modules"
47 addpythonmodules(module_dict
)
49 print "Adding PythonCore resources"
50 copyres(corepath
, outputref
, ['cfrg', 'Popt', 'GU\267I'], 1)
52 print "Adding resources from shared libraries"
53 for ppcpath
, cfm68kpath
in extraresfiles
:
54 if os
.path
.exists(ppcpath
):
55 copyres(ppcpath
, outputref
, ['cfrg'], 1)
56 elif os
.path
.exists(cfm68kpath
):
57 copyres(cfm68kpath
, outputref
, ['cfrg'], 1)
59 print "Fixing sys.path prefs"
60 Res
.UseResFile(outputref
)
62 res
= Res
.Get1Resource('STR#', 228) # from PythonCore
63 except Res
.Error
: pass
66 # setting pref file name to empty string
67 res
= Res
.Get1NamedResource('STR ', "PythonPreferenceFileName")
68 res
.data
= Pstring("")
70 syspathpref
= "$(APPLICATION)"
71 res
= Res
.Resource("\000\001" + Pstring(syspathpref
))
72 res
.AddResource("STR#", 229, "sys.path preference")
74 print "Creating 'PYD ' resources"
75 for modname
, (ppcfrag
, cfm68kfrag
) in dynamicmodules
.items():
76 res
= Res
.Resource(Pstring(ppcfrag
) + Pstring(cfm68kfrag
))
79 id = Res
.Unique1ID('PYD ')
80 res
.AddResource('PYD ', id, modname
)
82 Res
.CloseResFile(outputref
)
83 print "Merging code fragments"
84 cfmfile
.mergecfmfiles([applettemplatepath
, corepath
] + dynamicfiles
.keys(),
90 def findfragments(module_dict
, architecture
):
94 for name
, module
in module_dict
.items():
95 if module
.gettype() <> 'dynamic':
97 path
= resolvealiasfile(module
.__file
__)
98 dir, filename
= os
.path
.split(path
)
99 ppcfile
, cfm68kfile
= makefilenames(filename
)
102 ppcpath
= os
.path
.join(dir, ppcfile
)
103 if architecture
<> 'm68k':
104 ppcfrag
, dynamicfiles
= getfragname(ppcpath
, dynamicfiles
)
106 ppcfrag
= "_no_fragment_"
109 cfm68kpath
= os
.path
.join(dir, cfm68kfile
)
110 if architecture
<> 'pwpc':
111 cfm68kfrag
, dynamicfiles
= getfragname(cfm68kpath
, dynamicfiles
)
113 cfm68kfrag
= "_no_fragment_"
115 dynamicmodules
[name
] = ppcfrag
, cfm68kfrag
116 if (ppcpath
, cfm68kpath
) not in extraresfiles
:
117 extraresfiles
.append((ppcpath
, cfm68kpath
))
118 return dynamicmodules
, dynamicfiles
, extraresfiles
121 def getfragname(path
, dynamicfiles
):
122 if not dynamicfiles
.has_key(path
):
123 if os
.path
.exists(path
):
124 lib
= cfmfile
.CfrgResource(path
)
125 fragname
= lib
.fragments
[0].name
127 print "shared lib not found:", path
128 fragname
= "_no_fragment_"
129 dynamicfiles
[path
] = fragname
131 fragname
= dynamicfiles
[path
]
132 return fragname
, dynamicfiles
135 def addpythonmodules(module_dict
):
136 # XXX should really use macgen_rsrc.generate(), this does the same, but skips __main__
137 items
= module_dict
.items()
139 for name
, module
in items
:
140 mtype
= module
.gettype()
141 if mtype
not in ['module', 'package'] or name
== "__main__":
143 location
= module
.__file
__
145 if location
[-4:] == '.pyc':
146 # Attempt corresponding .py
147 location
= location
[:-1]
148 if location
[-3:] != '.py':
149 print '*** skipping', location
152 print 'Adding module "%s"' % name
153 id, name
= py_resource
.frompyfile(location
, name
, preload
=0,
154 ispackage
=mtype
=='package')
158 raise TypeError, "Str255 must be at most 255 chars long"
159 return chr(len(str)) + str
161 def makefilenames(name
):
162 lname
= string
.lower(name
)
163 pos
= string
.find(lname
, ".ppc.")
165 return name
, name
[:pos
] + '.CFM68K.' + name
[pos
+5:]
166 pos
= string
.find(lname
, ".cfm68k.")
168 return name
[:pos
] + '.ppc.' + name
[pos
+8:], name
169 raise ValueError, "can't make ppc/cfm68k filenames"
171 def copyres(input, output
, *args
, **kwargs
):
172 openedin
= openedout
= 0
173 if type(input) == types
.StringType
:
174 input = Res
.OpenResFile(input)
176 if type(output
) == types
.StringType
:
177 output
= Res
.OpenResFile(output
)
180 apply(buildtools
.copyres
, (input, output
) + args
, kwargs
)
183 Res
.CloseResFile(input)
185 Res
.CloseResFile(output
)
187 def findpythoncore():
188 """find the PythonCore shared library, possibly asking the user if we can't find it"""
190 vRefNum
, dirID
= macfs
.FindFolder(kOnSystemDisk
, kExtensionFolderType
, 0)
191 extpath
= macfs
.FSSpec((vRefNum
, dirID
, "")).as_pathname()
192 version
= string
.split(sys
.version
)[0]
193 corepath
= os
.path
.join(extpath
, "PythonCore " + version
)
194 if not os
.path
.exists(corepath
):
195 fss
, ok
= macfs
.PromptGetFile("Please locate PythonCore:", "shlb")
197 raise KeyboardInterrupt, "cancelled"
198 corepath
= fss
.as_pathname()
199 return resolvealiasfile(corepath
)
201 def resolvealiasfile(path
):
203 fss
, dummy1
, dummy2
= macfs
.ResolveAliasFile(path
)
207 path
= fss
.as_pathname()