Mac version of freeze. Uses standard freeze modules where it can,
augmenting them here and there. For now, it works more-or-less similar to unix/windows freeze, generating a config.c file, but storing modules in PYC resources. A template project is also copied. The hooks are in place to freeze by merging shared libraries so you can freeze without a C compiler/linker, but this does not work yet.
This commit is contained in:
parent
fa68b07526
commit
144fa678d2
|
@ -0,0 +1,39 @@
|
|||
import re
|
||||
import os
|
||||
|
||||
# The regular expression for freeze directives. These are comments with the
|
||||
# word macfreeze immedeately followed by a colon, followed by a directive,
|
||||
# followed by argument(s)
|
||||
#
|
||||
# The directives supported are
|
||||
# include - Include a module or file
|
||||
# exclude - Exclude a module
|
||||
# path - Add sys.path entries. Relative paths are relative to the source file.
|
||||
#
|
||||
# See the macfreeze.py main program for a real live example.
|
||||
#
|
||||
DIRECTIVE_RE=r'^\s*#\s*macfreeze:\s*(\S*)\s*(.*)\s*$'
|
||||
REPROG=re.compile(DIRECTIVE_RE)
|
||||
|
||||
def findfreezedirectives(program):
|
||||
extra_modules = []
|
||||
exclude_modules = []
|
||||
extra_path = []
|
||||
progdir, filename = os.path.split(program)
|
||||
fp = open(program)
|
||||
for line in fp.readlines():
|
||||
match = REPROG.match(line)
|
||||
if match:
|
||||
directive = match.group(1)
|
||||
argument = match.group(2)
|
||||
if directive == 'include':
|
||||
extra_modules.append(argument)
|
||||
elif directive == 'exclude':
|
||||
exclude_modules.append(argument)
|
||||
elif directive == 'path':
|
||||
argument = os.path.join(progdir, argument)
|
||||
extra_path.append(argument)
|
||||
else:
|
||||
print '** Unknown directive', line
|
||||
return extra_modules, exclude_modules, extra_path
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
"""macfreeze - Main program and GUI
|
||||
|
||||
macfreeze allows you to turn Python scripts into fully self-contained
|
||||
Mac applications, by including all the Python and C code needed in a single
|
||||
executable. Like unix/windows freeze it can produce a config.c allowing you
|
||||
to build the application with a development environment (CodeWarrior, to be
|
||||
precise), but unlike the standard freeze it is also possible to create frozen
|
||||
applications without a development environment, by glueing all the
|
||||
shared libraries and extension modules needed together in a single
|
||||
executable, using some Code Fragment Manager tricks."""
|
||||
|
||||
import macfs
|
||||
import sys
|
||||
import EasyDialogs
|
||||
import string
|
||||
|
||||
import macfreezegui
|
||||
import macmodulefinder
|
||||
|
||||
#
|
||||
# Here are the macfreeze directives, used when freezing macfreeze itself
|
||||
# (see directives.py for an explanation)
|
||||
#
|
||||
# macfreeze: path ::::Tools:freeze
|
||||
# macfreeze: exclude win32api
|
||||
#
|
||||
|
||||
def main():
|
||||
if len(sys.argv) < 2:
|
||||
gentype, program, output, debug = macfreezegui.dialog()
|
||||
elif len(sys.argv) == 2:
|
||||
gentype, program, output, debug = macfreezegui.dialog(sys.argv[1])
|
||||
else:
|
||||
EasyDialog.Message(
|
||||
"Please pass a single script. Additional modules can be specified with directives")
|
||||
sys.exit(0)
|
||||
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)
|
||||
except macmodulefinder.Missing, arg:
|
||||
arg.sort()
|
||||
print '** Missing modules:', string.join(arg, ' ')
|
||||
sys.exit(1)
|
||||
#
|
||||
# And generate
|
||||
#
|
||||
if gentype == 'info':
|
||||
import macgen_info
|
||||
macgen_info.generate(output, module_dict)
|
||||
return 1 # So the user can inspect it
|
||||
elif gentype == 'source':
|
||||
import macgen_src
|
||||
warnings = macgen_src.generate(output, module_dict, debug)
|
||||
return warnings
|
||||
elif gentype == 'resource':
|
||||
import macgen_rsrc
|
||||
macgen_rsrc.generate(output, module_dict, debug)
|
||||
warnings = macgen_rsrc.warnings(module_dict)
|
||||
return warnings
|
||||
elif gentype == 'applet':
|
||||
import macgen_bin
|
||||
macgen_bin.generate(output, module_dict, debug)
|
||||
else:
|
||||
raise 'unknown gentype', gentype
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
(This file must be converted with BinHex 4.0)
|
||||
|
||||
:$QeKBfCbC@9kC5jbFh*M!(*cFQ058d9%!3#3"`1-AQF!N!3"!!!!!cS!!!)k!!!
|
||||
!8M4lA$"F-M!dA$)`0(YF-&`b-$4F-M!dHe``A$)`0&`b$QeKBfCbC@9kC5jbFh*
|
||||
MFfaKH@9bFR0bG(4iG#ia0f`!-(*cFQ058d9%!3!!J!#"!*!5XE4#FJ#3"J0ZA$-
|
||||
b-&`c0cGF-&`b06"F-c)`A$-h0e``A$)e-&`c-M"F-cFhA$"F-M8`A$-b-&`c0cG
|
||||
F-&`b06"F-c)`A$-h0e``A$)e-&`c-M"F-cFhA$"F-M8`A$-b-&`c0cGF-&`b06"
|
||||
F-c)`A$-h0e``A$)e-&`c-M"F-cFhA$"F-M8`A$-b-!!!!"J!2!!U!@)"m3!&!*!
|
||||
)!J!!!$!+!!!#'J!6!*!&$`!*!"m!9)J(8f0bDA"d1J#3"Ji!L`!H!@@)"R0MFQP
|
||||
`G!#3"3d"F3!K!Ed%#8*bEhGcC5iZ,R)!N!93!!N!BJ&P"L0(C@jPFQ&dC5"bCA0
|
||||
[GA*MC5"KEQ3JFfpeFQ0P)'C[FL"$9f`!N!9S!"X!H!#"L!j2GA4`GA3JCQpXC'9
|
||||
b1J#3"@J!L`"i!@@)"R0MFQP`G!#3"@F"F3"k!Ed%#8*bEhGcC5iZ,Q%!N!@%!!N
|
||||
!PJ&P"Kp(C@jPFQ&dC5"3@8-JFQ9cEh9bBf8JCQPXC5"[EQajG!#3"Cd!'`#Y!(f
|
||||
)$%peG("eG#"QD@aP1J#3"Ci!L!#Y!@@)"R0MFQP`G!#3"CX"F!#[!Ed%#8*bEhG
|
||||
cC5iZ,Q%!N!@j!!N!bJ&L"L9(C@jPFQ&dC5"KF("XD@0KG'P[EL"QFQpY)(0SBA*
|
||||
PC#"XD@*cE!#3"G%!'`$K!(b)$%peG("eG#"QD@aP1J#3"G%!L!$K!@@)"R0MFQP
|
||||
`G!#3"Fm"E`$M!Ed%#8*bEhGcC5iZ,T`!N!3""`&[!4X"[33#6dX!N!3""J!,!4S
|
||||
!8!3'3f&ZBf9X!*!&+J!*!$X!ISJ04'9LG@FJ)'aPGQ9X1XJ!N!8U!)X!1J$@%!%
|
||||
aG!#3"H`!#3$q!@-'%%PZCQpbE@&dD@pZ)'pZE(N!!!%!!!!$1J!!!MS!!!"5"cH
|
||||
I$#UD!!!!(!"'!!&%6%p(!!!!%N4*9%`!!!!H!J#3"`FhXI3#!2rr!!!!(!FhY5!
|
||||
,6@&TEL"ND@&XEfGZ5!:
|
|
@ -0,0 +1,158 @@
|
|||
"""macfreezegui - The GUI for macfreeze"""
|
||||
import Dlg
|
||||
import macfs
|
||||
import EasyDialogs
|
||||
import sys
|
||||
import os
|
||||
import string
|
||||
import Res
|
||||
|
||||
ID_MAINDIALOG=512
|
||||
|
||||
ITEM_SCRIPTNAME=2
|
||||
ITEM_SCRIPTBROWSE=3
|
||||
ITEM_GENSOURCE=4
|
||||
ITEM_GENSOURCE_ITEMS=(7,)
|
||||
ITEM_SOURCEDIRNAME=6
|
||||
ITEM_SOURCEDIRBROWSE=7
|
||||
ITEM_GENRESOURCE=8
|
||||
ITEM_GENRESOURCE_ITEMS=(11,)
|
||||
ITEM_RESOURCENAME=10
|
||||
ITEM_RESOURCEBROWSE=11
|
||||
ITEM_GENAPPLET=12
|
||||
ITEM_GENAPPLET_ITEMS=(15,)
|
||||
ITEM_APPLETNAME=14
|
||||
ITEM_APPLETBROWSE=15
|
||||
ITEM_OK=16
|
||||
ITEM_CANCEL=17
|
||||
ITEM_DEBUG=19
|
||||
ITEM_GENINFO=20
|
||||
|
||||
RADIO_GROUPING={
|
||||
ITEM_GENSOURCE: ITEM_GENSOURCE_ITEMS,
|
||||
ITEM_GENRESOURCE: ITEM_GENRESOURCE_ITEMS,
|
||||
ITEM_GENAPPLET: ITEM_GENAPPLET_ITEMS,
|
||||
ITEM_GENINFO: ()
|
||||
}
|
||||
|
||||
def dialog(script=None):
|
||||
|
||||
# Invent the various names
|
||||
if not script:
|
||||
fss, ok = macfs.PromptGetFile("Script?", "TEXT")
|
||||
if not ok:
|
||||
sys.exit(0)
|
||||
script = fss.as_pathname()
|
||||
basename, ext = os.path.splitext(script)
|
||||
if ext:
|
||||
appletname = basename
|
||||
rsrcname = basename + 'modules.rsrc'
|
||||
else:
|
||||
appletname = script + '.applet'
|
||||
rsrcname = script + 'modules.rsrc'
|
||||
dirname, basebase = os.path.split(basename)
|
||||
dirname = os.path.join(dirname, 'build.'+basebase)
|
||||
|
||||
# Get the dialog, possibly opening the resource file (if needed)
|
||||
try:
|
||||
d = Dlg.GetNewDialog(ID_MAINDIALOG, -1)
|
||||
except Dlg.Error:
|
||||
d = None
|
||||
if d == None:
|
||||
try:
|
||||
Res.OpenResFile('macfreeze.rsrc')
|
||||
except Res.Error:
|
||||
d = None
|
||||
else:
|
||||
d = Dlg.GetNewDialog(ID_MAINDIALOG, -1)
|
||||
if d == None:
|
||||
EasyDialogs.Message("Dialog resource not found or faulty")
|
||||
sys.exit(1)
|
||||
|
||||
# Fill the dialog
|
||||
d.SetDialogDefaultItem(ITEM_OK)
|
||||
d.SetDialogCancelItem(ITEM_CANCEL)
|
||||
|
||||
_dialogsetfile(d, ITEM_SCRIPTNAME, script)
|
||||
_dialogsetfile(d, ITEM_SOURCEDIRNAME, dirname)
|
||||
_dialogsetfile(d, ITEM_RESOURCENAME, rsrcname)
|
||||
_dialogsetfile(d, ITEM_APPLETNAME, appletname)
|
||||
|
||||
gentype = ITEM_GENSOURCE
|
||||
_dialogradiogroup(d, ITEM_GENSOURCE)
|
||||
|
||||
# Interact
|
||||
d.GetDialogWindow().SetWTitle("Standalone application creation options")
|
||||
d.GetDialogWindow().ShowWindow()
|
||||
d.DrawDialog()
|
||||
while 1:
|
||||
item = Dlg.ModalDialog(None)
|
||||
if item == ITEM_OK:
|
||||
break
|
||||
elif item == ITEM_CANCEL:
|
||||
sys.exit(0)
|
||||
elif item in RADIO_GROUPING.keys():
|
||||
gentype = item
|
||||
_dialogradiogroup(d, item)
|
||||
elif item == ITEM_SCRIPTBROWSE:
|
||||
fss, ok = macfs.PromptGetFile("Script?")
|
||||
if ok:
|
||||
script = fss.as_pathname()
|
||||
_dialogsetfile(d, ITEM_SCRIPTNAME, script)
|
||||
elif item == ITEM_SOURCEDIRBROWSE:
|
||||
fss, ok = macfs.StandardPutFile("Output folder name", os.path.split(dirname)[1])
|
||||
if ok:
|
||||
dirname = fss.as_pathname()
|
||||
_dialogsetfile(d, ITEM_SOURCEDIRNAME, dirname)
|
||||
elif item == ITEM_RESOURCEBROWSE:
|
||||
fss, ok = macfs.StandardPutFile("Resource output file", os.path.split(rsrcname)[1])
|
||||
if ok:
|
||||
rsrcname = fss.as_pathname()
|
||||
_dialogsetfile(d, ITEM_RESOURCENAME, rsrcname)
|
||||
elif item == ITEM_APPLETBROWSE:
|
||||
fss, ok = macfs.StandardPutFile("Applet output file", os.path.split(appletname)[1])
|
||||
if ok:
|
||||
appletname = fss.as_pathname()
|
||||
_dialogsetfile(d, ITEM_APPLETNAME, appletname)
|
||||
else:
|
||||
pass
|
||||
tp, h, rect = d.GetDialogItem(ITEM_DEBUG)
|
||||
debug = Dlg.GetDialogItemText(h)
|
||||
try:
|
||||
debug = string.atoi(string.strip(debug))
|
||||
except ValueError:
|
||||
EasyDialogs.Message("Illegal debug value %s, set to zero."%`debug`)
|
||||
debug = 0
|
||||
if gentype == ITEM_GENSOURCE:
|
||||
return 'source', script, dirname, debug
|
||||
elif gentype == ITEM_GENRESOURCE:
|
||||
return 'resource', script, rsrcname, debug
|
||||
elif gentype == ITEM_GENAPPLET:
|
||||
return 'applet', script, appletname, debug
|
||||
elif gentype == ITEM_GENINFO:
|
||||
return 'info', script, '', debug
|
||||
raise 'Error in gentype', gentype
|
||||
|
||||
def _dialogradiogroup(d, item):
|
||||
for k in RADIO_GROUPING.keys():
|
||||
subitems = RADIO_GROUPING[k]
|
||||
tp, h, rect = d.GetDialogItem(k)
|
||||
if k == item:
|
||||
h.as_Control().SetControlValue(1)
|
||||
for i2 in subitems:
|
||||
d.ShowDialogItem(i2)
|
||||
else:
|
||||
h.as_Control().SetControlValue(0)
|
||||
for i2 in subitems:
|
||||
d.HideDialogItem(i2)
|
||||
|
||||
def _dialogsetfile(d, item, file):
|
||||
if len(file) > 32:
|
||||
file = '\311:' + os.path.split(file)[1]
|
||||
tp, h, rect = d.GetDialogItem(item)
|
||||
Dlg.SetDialogItemText(h, file)
|
||||
|
||||
if __name__ == '__main__':
|
||||
type, script, file, debug = dialog()
|
||||
print type, script, file, 'debug=%d'%debug
|
||||
sys.exit(1)
|
|
@ -0,0 +1,6 @@
|
|||
"""macgen_bin - Generate application from shared libraries"""
|
||||
import EasyDialogs
|
||||
|
||||
def generate(output, module_dict):
|
||||
EasyDialogs.Message('Not yet implemented')
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
"""macgen_info - Generate informational output"""
|
||||
|
||||
def generate(output, module_dict):
|
||||
for name in module_dict.keys():
|
||||
print 'Include %-20s\t'%name,
|
||||
module = module_dict[name]
|
||||
print module.gettype(), '\t', `module`
|
||||
return 0
|
|
@ -0,0 +1,35 @@
|
|||
"""macgen_info - Generate PYC resource file only"""
|
||||
import EasyDialogs
|
||||
import py_resource
|
||||
import Res
|
||||
import sys
|
||||
|
||||
def generate(output, module_dict, debug=0, preload=1):
|
||||
fsid = py_resource.create(output)
|
||||
|
||||
for name, module in module_dict.items():
|
||||
if module.gettype() != 'module':
|
||||
continue
|
||||
location = module.__file__
|
||||
|
||||
if location[-4:] == '.pyc':
|
||||
# Attempt corresponding .py
|
||||
location = location[:-1]
|
||||
if location[-3:] != '.py':
|
||||
print '*** skipping', location
|
||||
continue
|
||||
|
||||
id, name = py_resource.frompyfile(location, name, preload=preload)
|
||||
if debug > 0:
|
||||
print 'PYC resource %5d\t%s\t%s'%(id, name, location)
|
||||
|
||||
Res.CloseResFile(fsid)
|
||||
|
||||
def warnings(module_dict):
|
||||
problems = 0
|
||||
for name, module in module_dict.items():
|
||||
if module.gettype() not in ('builtin', 'module'):
|
||||
problems = problems + 1
|
||||
print 'Warning: %s not included: %s %s'%(name, module.gettype(), module)
|
||||
return problems
|
||||
|
|
@ -0,0 +1,109 @@
|
|||
"""macgen_info - Generate CodeWarrior project, config source, resource file"""
|
||||
import EasyDialogs
|
||||
import os
|
||||
import sys
|
||||
import macfs
|
||||
import MacOS
|
||||
import macostools
|
||||
import macgen_rsrc
|
||||
# Note: this depends on being frozen, or on sys.path already being
|
||||
# modified by macmodulefinder.
|
||||
import makeconfig
|
||||
|
||||
TEMPLATEDIR=os.path.join(sys.prefix, ':Mac:mwerks:projects:build.macfreeze')
|
||||
PROJECT_TEMPLATE=os.path.join(TEMPLATEDIR, ':frozen.prj')
|
||||
CONFIG_TEMPLATE=os.path.join(TEMPLATEDIR, ':templatefrozenconfig.c')
|
||||
BUNDLE_TEMPLATE=os.path.join(TEMPLATEDIR, ':frozenbundle.rsrc')
|
||||
|
||||
def generate(output, module_dict, debug=0):
|
||||
problems = 0
|
||||
output_created=0
|
||||
if not os.path.exists(output):
|
||||
print 'Creating project folder', output
|
||||
os.mkdir(output)
|
||||
output_created = 1
|
||||
# Resolve aliases, if needed
|
||||
try:
|
||||
fss, dummy1, dummy2 = macfs.ResolveAliasFile(output)
|
||||
except macfs.error:
|
||||
pass
|
||||
else:
|
||||
newname = fss.as_pathname()
|
||||
if newname != output:
|
||||
if debug:
|
||||
print 'Alias', output
|
||||
print 'Resolved to', newname
|
||||
output = newname
|
||||
# Construct the filenames
|
||||
dummy, outfile = os.path.split(output)
|
||||
build, ext = os.path.splitext(outfile)
|
||||
if build == 'build' and ext[0] == '.':
|
||||
# This is probably a good name for the project
|
||||
projname = ext[1:]
|
||||
else:
|
||||
projname = 'frozenapplet.prj'
|
||||
config_name = os.path.join(output, ':macfrozenconfig.c')
|
||||
project_name = os.path.join(output, ':' + projname + '.prj')
|
||||
resource_name = os.path.join(output, ':frozenmodules.rsrc')
|
||||
bundle_name = os.path.join(output, ':frozenbundle.rsrc')
|
||||
|
||||
# Fill the output folder, if needed.
|
||||
if output_created:
|
||||
# Create the project, if needed
|
||||
if not os.path.exists(project_name):
|
||||
print 'Creating project', project_name
|
||||
if not os.path.exists(PROJECT_TEMPLATE):
|
||||
print '** No template CodeWarrior project found at', PROJECT_TEMPLATE
|
||||
print ' To generate standalone Python applications from source you need'
|
||||
print ' a full source distribution. Check http://www.cwi.nl/~jack/macpython.html'
|
||||
print ' for details.'
|
||||
problems = 1
|
||||
else:
|
||||
macostools.copy(PROJECT_TEMPLATE, project_name)
|
||||
print 'A template CodeWarrior project has been copied to', project_name
|
||||
print 'It is up to you to make the following changes:'
|
||||
print '- Change the output file name'
|
||||
print '- Change the search path, unless the folder is in the python home'
|
||||
print '- Add sourcefiles/libraries for any extension modules used'
|
||||
print '- Remove unused sources, to speed up the build process'
|
||||
print '- Remove unused resource files (like tcl/tk) for a smaller binary'
|
||||
problems = 1
|
||||
macostools.copy(BUNDLE_TEMPLATE, bundle_name)
|
||||
print 'A template bundle file has also been copied to', bundle_name
|
||||
print 'You may want to adapt signature, size resource, etc'
|
||||
|
||||
|
||||
# Create the resource file
|
||||
macgen_rsrc.generate(resource_name, module_dict, debug=debug)
|
||||
|
||||
# Create the config.c file
|
||||
if not os.path.exists(CONFIG_TEMPLATE):
|
||||
print '** No template config.c found at', PROJECT_TEMPLATE
|
||||
print ' To generate standalone Python applications from source you need'
|
||||
print ' a full source distribution. Check http://www.cwi.nl/~jack/macpython.html'
|
||||
print ' for details.'
|
||||
problems = 1
|
||||
else:
|
||||
# Find elegible modules (builtins and dynamically loaded modules)
|
||||
c_modules = []
|
||||
for module in module_dict.keys():
|
||||
if module_dict[module].gettype() in ('builtin', 'dynamic'):
|
||||
c_modules.append(module)
|
||||
ifp = open(CONFIG_TEMPLATE)
|
||||
ofp = open(config_name, 'w')
|
||||
makeconfig.makeconfig(ifp, ofp, c_modules)
|
||||
ifp.close()
|
||||
ofp.close()
|
||||
MacOS.SetCreatorAndType(config_name, 'CWIE', 'TEXT')
|
||||
|
||||
if warnings(module_dict):
|
||||
problems = 1
|
||||
return problems
|
||||
|
||||
def warnings(module_dict):
|
||||
problems = 0
|
||||
for name, module in module_dict.items():
|
||||
if module.gettype() not in ('builtin', 'module', 'dynamic'):
|
||||
problems = problems + 1
|
||||
print 'Warning: %s not included: %s %s'%(name, module.gettype(), module)
|
||||
return problems
|
|
@ -0,0 +1,8 @@
|
|||
"""macgenerate - Generate the out for macfreeze"""
|
||||
|
||||
def generate(program, module_dict):
|
||||
for name in module_dict.keys():
|
||||
print 'Include %-20s\t'%name,
|
||||
module = module_dict[name]
|
||||
print module.gettype(), '\t', `module`
|
||||
return 0
|
|
@ -0,0 +1,101 @@
|
|||
"""macmodulefinder - Find modules used in a script. Only slightly
|
||||
mac-specific, really."""
|
||||
|
||||
import sys
|
||||
import os
|
||||
|
||||
import directives
|
||||
|
||||
try:
|
||||
# This will work if we are frozen ourselves
|
||||
import modulefinder
|
||||
except ImportError:
|
||||
# And this will work otherwise
|
||||
_FREEZEDIR=os.path.join(sys.prefix, ':Tools:freeze')
|
||||
sys.path.insert(0, _FREEZEDIR)
|
||||
import modulefinder
|
||||
|
||||
#
|
||||
# Modules that must be included, and modules that need not be included
|
||||
# (but are if they are found)
|
||||
#
|
||||
MAC_INCLUDE_MODULES=['site', 'exceptions']
|
||||
MAC_MAYMISS_MODULES=['posix', 'os2', 'nt', 'dos', 'dospath', 'nturl2path', 'pwd', 'sitecustomize']
|
||||
|
||||
# An exception:
|
||||
Missing="macmodulefinder.Missing"
|
||||
|
||||
class Module(modulefinder.Module):
|
||||
|
||||
def gettype(self):
|
||||
"""Return type of module"""
|
||||
if self.__path__:
|
||||
return 'package'
|
||||
if self.__code__:
|
||||
return 'module'
|
||||
if self.__file__:
|
||||
return 'dynamic'
|
||||
return 'builtin'
|
||||
|
||||
class ModuleFinder(modulefinder.ModuleFinder):
|
||||
|
||||
def add_module(self, fqname):
|
||||
if self.modules.has_key(fqname):
|
||||
return self.modules[fqname]
|
||||
self.modules[fqname] = m = Module(fqname)
|
||||
return m
|
||||
|
||||
def process(program, modules=[], module_files = [], debug=0):
|
||||
error = []
|
||||
#
|
||||
# Add the standard modules needed for startup
|
||||
#
|
||||
modules = modules + MAC_INCLUDE_MODULES
|
||||
#
|
||||
# search the main source for directives
|
||||
#
|
||||
extra_modules, exclude_modules, extra_path = \
|
||||
directives.findfreezedirectives(program)
|
||||
for m in extra_modules:
|
||||
if os.sep in m:
|
||||
# It is a file
|
||||
module_files.append(m)
|
||||
else:
|
||||
modules.append(m)
|
||||
path = extra_path + sys.path[:]
|
||||
#
|
||||
# Create the module finder and let it do its work
|
||||
#
|
||||
modfinder = ModuleFinder(path,
|
||||
excludes=exclude_modules, debug=debug)
|
||||
for m in modules:
|
||||
modfinder.import_hook(m)
|
||||
for m in module_files:
|
||||
modfinder.load_file(m)
|
||||
modfinder.run_script(program)
|
||||
module_dict = modfinder.modules
|
||||
#
|
||||
# Tell the user about missing modules
|
||||
#
|
||||
maymiss = exclude_modules + MAC_MAYMISS_MODULES
|
||||
for m in modfinder.badmodules.keys():
|
||||
if not m in maymiss:
|
||||
if debug > 0:
|
||||
print 'Missing', m
|
||||
error.append(m)
|
||||
#
|
||||
# Warn the user about unused builtins
|
||||
#
|
||||
for m in sys.builtin_module_names:
|
||||
if m in ('__main__', '__builtin__'):
|
||||
pass
|
||||
elif not module_dict.has_key(m):
|
||||
if debug > 0:
|
||||
print 'Unused', m
|
||||
elif module_dict[m].gettype() != 'builtin':
|
||||
# XXXX Can this happen?
|
||||
if debug > 0:
|
||||
print 'Conflict', m
|
||||
if error:
|
||||
raise Missing, error
|
||||
return module_dict
|
Loading…
Reference in New Issue