panda3d/direct/src/showutil/FreezeTool.py
2009-07-27 08:07:41 +00:00

876 lines
30 KiB
Python

""" This module contains code to freeze a number of Python modules
into a single (mostly) standalone DLL or EXE. """
import modulefinder
import sys
import os
import marshal
import imp
import platform
from distutils.sysconfig import PREFIX, get_python_inc, get_python_version
import direct
from pandac.PandaModules import *
# These are modules that Python always tries to import up-front. They
# must be frozen in any main.exe.
startupModules = [
'site', 'sitecustomize', 'os', 'encodings.cp1252',
'org',
]
# Our own Python source trees to watch out for.
sourceTrees = ['direct']
# The command to compile a c to an object file. Replace %(basename)s
# with the basename of the source file, and an implicit .c extension.
compileObj = 'error'
# The command to link a single object file into an executable. As
# above, replace $(basename)s with the basename of the original source
# file, and of the target executable.
linkExe = 'error'
# The command to link a single object file into a shared library.
linkDll = 'error'
# Paths to Python stuff.
Python = None
PythonIPath = get_python_inc()
PythonVersion = get_python_version()
# The VC directory of Microsoft Visual Studio (if relevant)
MSVC = None
# Directory to Windows Platform SDK (if relevant)
PSDK = None
if sys.platform == 'win32':
Python = PREFIX
if ('VCINSTALLDIR' in os.environ):
MSVC = os.environ['VCINSTALLDIR']
elif (Filename('/c/Program Files/Microsoft Visual Studio 9.0/VC').exists()):
MSVC = Filename('/c/Program Files/Microsoft Visual Studio 9.0/VC').toOsSpecific()
elif (Filename('/c/Program Files/Microsoft Visual Studio .NET 2003/Vc7').exists()):
MSVC = Filename('/c/Program Files/Microsoft Visual Studio .NET 2003/Vc7').toOsSpecific()
else:
print 'Could not locate Microsoft Visual C++ Compiler! Try running from the Visual Studio Command Prompt.'
exit(1)
if ('WindowsSdkDir' in os.environ):
PSDK = os.environ['WindowsSdkDir']
elif (platform.architecture()[0] == '32bit' and Filename('/c/Program Files/Microsoft Platform SDK for Windows Server 2003 R2').exists()):
PSDK = Filename('/c/Program Files/Microsoft Platform SDK for Windows Server 2003 R2').toOsSpecific()
elif (os.path.exists(os.path.join(MSVC, 'PlatformSDK'))):
PSDK = os.path.join(MSVC, 'PlatformSDK')
else:
print 'Could not locate the Microsoft Windows Platform SDK! Try running from the Visual Studio Command Prompt.'
exit(1)
# If it is run by makepanda, it handles the MSVC and PlatformSDK paths itself.
if ('MAKEPANDA' in os.environ):
compileObj = 'cl /wd4996 /Fo%(basename)s.obj /nologo /c /MD /Zi /O2 /Ob2 /EHsc /Zm300 /W3 /I"%(pythonIPath)s" %(filename)s'
linkExe = 'link /nologo /MAP:NUL /FIXED:NO /OPT:REF /STACK:4194304 /INCREMENTAL:NO /LIBPATH:"%(python)s\libs" /out:%(basename)s.exe %(basename)s.obj'
linkDll = 'link /nologo /DLL /MAP:NUL /FIXED:NO /OPT:REF /INCREMENTAL:NO /LIBPATH:"%(python)s\libs" /out:%(basename)s.pyd %(basename)s.obj'
else:
os.environ['PATH'] += ';' + MSVC + '\\bin;' + MSVC + '\\Common7\\IDE;' + PSDK + '\\bin'
compileObj = 'cl /wd4996 /Fo%(basename)s.obj /nologo /c /MD /Zi /O2 /Ob2 /EHsc /Zm300 /W3 /I"%(pythonIPath)s" /I"%(PSDK)s\include" /I"%(MSVC)s\include" %(filename)s'
linkExe = 'link /nologo /MAP:NUL /FIXED:NO /OPT:REF /STACK:4194304 /INCREMENTAL:NO /LIBPATH:"%(PSDK)s\lib" /LIBPATH:"%(MSVC)s\lib" /LIBPATH:"%(python)s\libs" /out:%(basename)s.exe %(basename)s.obj'
linkDll = 'link /nologo /DLL /MAP:NUL /FIXED:NO /OPT:REF /INCREMENTAL:NO /LIBPATH:"%(PSDK)s\lib" /LIBPATH:"%(MSVC)s\lib" /LIBPATH:"%(python)s\libs" /out:%(basename)s.pyd %(basename)s.obj'
elif sys.platform == 'darwin':
# OSX
compileObj = "gcc -fPIC -c -o %(basename)s.o -O2 -I%(pythonIPath)s %(filename)s"
linkExe = "gcc -o %(basename)s %(basename)s.o -framework Python"
linkDll = "gcc -undefined dynamic_lookup -bundle -o %(basename)s.so %(basename)s.o"
else:
# Linux
compileObj = "gcc -fPIC -c -o %(basename)s.o -O2 %(filename)s -I %(pythonIPath)s"
linkExe = "gcc -o %(basename)s %(basename)s.o -lpython%(pythonVersion)s"
linkDll = "gcc -shared -o %(basename)s.so %(basename)s.o -lpython%(pythonVersion)s"
# The code from frozenmain.c in the Python source repository.
frozenMainCode = """
/* Python interpreter main program for frozen scripts */
#include "Python.h"
#ifdef MS_WINDOWS
extern void PyWinFreeze_ExeInit(void);
extern void PyWinFreeze_ExeTerm(void);
extern int PyInitFrozenExtensions(void);
#endif
/* Main program */
int
Py_FrozenMain(int argc, char **argv)
{
char *p;
int n, sts;
int inspect = 0;
int unbuffered = 0;
Py_FrozenFlag = 1; /* Suppress errors from getpath.c */
if ((p = Py_GETENV("PYTHONINSPECT")) && *p != '\\0')
inspect = 1;
if ((p = Py_GETENV("PYTHONUNBUFFERED")) && *p != '\\0')
unbuffered = 1;
if (unbuffered) {
setbuf(stdin, (char *)NULL);
setbuf(stdout, (char *)NULL);
setbuf(stderr, (char *)NULL);
}
#ifdef MS_WINDOWS
PyInitFrozenExtensions();
#endif /* MS_WINDOWS */
Py_SetProgramName(argv[0]);
Py_Initialize();
#ifdef MS_WINDOWS
PyWinFreeze_ExeInit();
#endif
if (Py_VerboseFlag)
fprintf(stderr, "Python %s\\n%s\\n",
Py_GetVersion(), Py_GetCopyright());
PySys_SetArgv(argc, argv);
n = PyImport_ImportFrozenModule("__main__");
if (n == 0)
Py_FatalError("__main__ not frozen");
if (n < 0) {
PyErr_Print();
sts = 1;
}
else
sts = 0;
if (inspect && isatty((int)fileno(stdin)))
sts = PyRun_AnyFile(stdin, "<stdin>") != 0;
#ifdef MS_WINDOWS
PyWinFreeze_ExeTerm();
#endif
Py_Finalize();
return sts;
}
"""
# The code from frozen_dllmain.c in the Python source repository.
# Windows only.
frozenDllMainCode = """
#include "windows.h"
static char *possibleModules[] = {
"pywintypes",
"pythoncom",
"win32ui",
NULL,
};
BOOL CallModuleDllMain(char *modName, DWORD dwReason);
/*
Called by a frozen .EXE only, so that built-in extension
modules are initialized correctly
*/
void PyWinFreeze_ExeInit(void)
{
char **modName;
for (modName = possibleModules;*modName;*modName++) {
/* printf("Initialising '%s'\\n", *modName); */
CallModuleDllMain(*modName, DLL_PROCESS_ATTACH);
}
}
/*
Called by a frozen .EXE only, so that built-in extension
modules are cleaned up
*/
void PyWinFreeze_ExeTerm(void)
{
// Must go backwards
char **modName;
for (modName = possibleModules+(sizeof(possibleModules) / sizeof(char *))-2;
modName >= possibleModules;
*modName--) {
/* printf("Terminating '%s'\\n", *modName);*/
CallModuleDllMain(*modName, DLL_PROCESS_DETACH);
}
}
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
{
BOOL ret = TRUE;
switch (dwReason) {
case DLL_PROCESS_ATTACH:
{
char **modName;
for (modName = possibleModules;*modName;*modName++) {
BOOL ok = CallModuleDllMain(*modName, dwReason);
if (!ok)
ret = FALSE;
}
break;
}
case DLL_PROCESS_DETACH:
{
// Must go backwards
char **modName;
for (modName = possibleModules+(sizeof(possibleModules) / sizeof(char *))-2;
modName >= possibleModules;
*modName--)
CallModuleDllMain(*modName, DLL_PROCESS_DETACH);
break;
}
}
return ret;
}
BOOL CallModuleDllMain(char *modName, DWORD dwReason)
{
BOOL (WINAPI * pfndllmain)(HINSTANCE, DWORD, LPVOID);
char funcName[255];
HMODULE hmod = GetModuleHandle(NULL);
strcpy(funcName, "_DllMain");
strcat(funcName, modName);
strcat(funcName, "@12"); // stdcall convention.
pfndllmain = (BOOL (WINAPI *)(HINSTANCE, DWORD, LPVOID))GetProcAddress(hmod, funcName);
if (pfndllmain==NULL) {
/* No function by that name exported - then that module does
not appear in our frozen program - return OK
*/
return TRUE;
}
return (*pfndllmain)(hmod, dwReason, NULL);
}
"""
# Our own glue code to start up a Python executable.
mainInitCode = """
%(frozenMainCode)s
int
main(int argc, char *argv[]) {
PyImport_FrozenModules = _PyImport_FrozenModules;
return Py_FrozenMain(argc, argv);
}
"""
# Our own glue code to start up a Python shared library.
dllInitCode = """
static PyMethodDef nullMethods[] = {
{NULL, NULL}
};
%(dllexport)svoid init%(moduleName)s() {
int count;
struct _frozen *new_FrozenModules;
count = 0;
while (PyImport_FrozenModules[count].name != NULL) {
++count;
}
new_FrozenModules = (struct _frozen *)malloc((count + %(newcount)s + 1) * sizeof(struct _frozen));
memcpy(new_FrozenModules, _PyImport_FrozenModules, %(newcount)s * sizeof(struct _frozen));
memcpy(new_FrozenModules + %(newcount)s, PyImport_FrozenModules, count * sizeof(struct _frozen));
memset(new_FrozenModules + count + %(newcount)s, 0, sizeof(struct _frozen));
PyImport_FrozenModules = new_FrozenModules;
Py_InitModule("%(moduleName)s", nullMethods);
}
"""
programFile = """
#include "Python.h"
%(moduleDefs)s
static struct _frozen _PyImport_FrozenModules[] = {
%(moduleList)s
{NULL, NULL, 0}
};
%(initCode)s
"""
# Windows needs this bit.
frozenExtensions = """
static struct _inittab extensions[] = {
/* Sentinel */
{0, 0}
};
extern DL_IMPORT(int) PyImport_ExtendInittab(struct _inittab *newtab);
int PyInitFrozenExtensions()
{
return PyImport_ExtendInittab(extensions);
}
"""
okMissing = [
'Carbon.Folder', 'Carbon.Folders', 'HouseGlobals', 'Carbon.File',
'MacOS', '_emx_link', 'ce', 'mac', 'org.python.core', 'os.path',
'os2', 'posix', 'pwd', 'readline', 'riscos', 'riscosenviron',
'riscospath', 'dbm', 'fcntl', 'win32api',
'_winreg', 'ctypes', 'ctypes.wintypes', 'nt','msvcrt',
'EasyDialogs', 'SOCKS', 'ic', 'rourl2path', 'termios',
'OverrideFrom23._Res', 'email', 'email.Utils', 'email.Generator',
'email.Iterators', '_subprocess', 'gestalt',
'direct.extensions_native.extensions_darwin',
]
class Freezer:
# Module tokens:
MTAuto = 0
MTInclude = 1
MTExclude = 2
MTForbid = 3
def __init__(self, previous = None, debugLevel = 0):
# Normally, we are freezing for our own platform. Change this
# if untrue.
self.platform = sys.platform
# You will also need to change these for a cross-compiler
# situation.
self.compileObj = compileObj
self.linkExe = linkExe
self.linkDll = linkDll
# The filename extension to append to the source file before
# compiling.
self.sourceExtension = '.c'
# The filename extension to append to the object file.
self.objectExtension = '.o'
if self.platform == 'win32':
self.objectExtension = '.obj'
# True to compile to an executable, false to compile to a dll. If
# setMain() is called, this is automatically set to True.
self.compileToExe = False
# Change any of these to change the generated startup and glue
# code.
self.frozenMainCode = frozenMainCode
self.frozenDllMainCode = frozenDllMainCode
self.mainInitCode = mainInitCode
self.frozenExtensions = frozenExtensions
# End of public interface. These remaining members should not
# be directly manipulated by callers.
self.previousModules = {}
self.modules = {}
if previous:
self.previousModules = dict(previous.modules)
self.modules = dict(previous.modules)
self.mainModule = None
self.mf = None
# Make sure we know how to find "direct".
if direct.__path__:
modulefinder.AddPackagePath('direct', direct.__path__[0])
def excludeModule(self, moduleName, forbid = False):
""" Adds a module to the list of modules not to be exported by
this tool. If forbid is true, the module is furthermore
forbidden to be imported, even if it exists on disk. """
if forbid:
self.modules[moduleName] = self.MTForbid
else:
self.modules[moduleName] = self.MTExclude
def handleCustomPath(self, moduleName):
""" Indicates a module that may perform runtime manipulation
of its __path__ variable, and which must therefore be actually
imported at runtime in order to determine the true value of
__path__. """
str = 'import %s' % (moduleName)
exec str
module = sys.modules[moduleName]
for path in module.__path__:
modulefinder.AddPackagePath(moduleName, path)
def getModulePath(self, moduleName):
""" Looks for the indicated directory module and returns its
__path__ member: the list of directories in which its python
files can be found. If the module is a .py file and not a
directory, returns None. """
# First, try to import the module directly. That's the most
# reliable answer, if it works.
try:
module = __import__(moduleName)
except:
module = None
if module != None:
for symbol in moduleName.split('.')[1:]:
module = getattr(module, symbol)
return module.__path__
# If it didn't work--maybe the module is unimportable because
# it makes certain assumptions about the builtins, or
# whatever--then just look for file on disk. That's usually
# good enough.
path = None
baseName = moduleName
if '.' in baseName:
parentName, baseName = moduleName.rsplit('.', 1)
path = self.getModulePath(parentName)
if path == None:
return None
file, pathname, description = imp.find_module(baseName, path)
if os.path.isdir(pathname):
return [pathname]
else:
return None
def addModule(self, moduleName, implicit = False):
""" Adds a module to the list of modules to be exported by
this tool. If implicit is true, it is OK if the module does
not actually exist.
The module name may end in ".*", which means to add all of the
.py files (other than __init__.py) in a particular directory.
It may also end in ".*.*", which means to cycle through all
directories within a particular directory.
"""
moduleName = moduleName.replace("/", ".").replace("direct.src", "direct")
if implicit:
token = self.MTAuto
else:
token = self.MTInclude
if moduleName.endswith('.*'):
# Find the parent module, so we can get its directory.
parentName = moduleName[:-2]
parentNames = [parentName]
if parentName.endswith('.*'):
# Another special case. The parent name "*" means to
# return all possible directories within a particular
# directory.
topName = parentName[:-2]
parentNames = []
for dirname in self.getModulePath(topName):
for filename in os.listdir(dirname):
if os.path.exists(os.path.join(dirname, filename, '__init__.py')):
parentName = '%s.%s' % (topName, filename)
if self.getModulePath(parentName):
parentNames.append(parentName)
for parentName in parentNames:
path = self.getModulePath(parentName)
if path == None:
# It's actually a regular module.
self.modules[parentName] = token
else:
# Now get all the py files in the parent directory.
for dirname in path:
for filename in os.listdir(dirname):
if '-' in filename:
continue
if filename.endswith('.py') and filename != '__init__.py':
moduleName = '%s.%s' % (parentName, filename[:-3])
self.modules[moduleName] = token
else:
# A normal, explicit module name.
self.modules[moduleName] = token
def setMain(self, moduleName):
moduleName = moduleName.replace("/", ".").replace("direct.src", "direct")
self.addModule(moduleName)
self.mainModule = moduleName
self.compileToExe = True
def done(self):
assert self.mf == None
if self.compileToExe:
# Ensure that each of our required startup modules is
# on the list.
for moduleName in startupModules:
if moduleName not in self.modules:
self.modules[moduleName] = self.MTAuto
# Excluding a parent module also excludes all its children.
# Walk through the list in sorted order, so we reach children
# before parents.
names = self.modules.items()
names.sort()
excludes = []
excludeDict = {}
includes = []
autoIncludes = []
for moduleName, token in names:
if '.' in moduleName:
parentName, baseName = moduleName.rsplit('.', 1)
if parentName in excludeDict:
token = excludeDict[parentName]
if token == self.MTInclude:
includes.append(moduleName)
elif token == self.MTAuto:
autoIncludes.append(moduleName)
elif token == self.MTExclude or token == self.MTForbid:
excludes.append(moduleName)
excludeDict[moduleName] = token
self.mf = modulefinder.ModuleFinder(excludes = excludes)
# Attempt to import the explicit modules into the modulefinder.
for moduleName in includes:
self.mf.import_hook(moduleName)
# Also attempt to import any implicit modules. If any of
# these fail to import, we don't care.
for moduleName in autoIncludes:
try:
self.mf.import_hook(moduleName)
except ImportError:
pass
# Now, any new modules we found get added to the export list.
for moduleName in self.mf.modules.keys():
if moduleName not in self.modules:
self.modules[moduleName] = self.MTAuto
missing = []
for moduleName in self.mf.any_missing():
if moduleName in startupModules:
continue
if moduleName in self.previousModules:
continue
# This module is missing. Let it be missing in the
# runtime also.
self.modules[moduleName] = self.MTExclude
if moduleName in okMissing:
# If it's listed in okMissing, don't even report it.
continue
prefix = moduleName.split('.')[0]
if prefix not in sourceTrees:
# If it's in not one of our standard source trees, assume
# it's some wacky system file we don't need.
continue
missing.append(moduleName)
if missing:
error = "There are some missing modules: %r" % missing
print error
raise StandardError, error
def mangleName(self, moduleName):
return 'M_' + moduleName.replace('.', '__')
def __getModuleNames(self):
# Collect a list of all of the modules we will be explicitly
# referencing.
moduleNames = []
for moduleName, token in self.modules.items():
prevToken = self.previousModules.get(moduleName, None)
if token == self.MTInclude or token == self.MTAuto:
# Include this module (even if a previous pass
# excluded it). But don't bother if we exported it
# previously.
if prevToken != self.MTInclude and prevToken != self.MTAuto:
if moduleName in self.mf.modules or \
moduleName in startupModules:
moduleNames.append(moduleName)
elif token == self.MTForbid:
if prevToken != self.MTForbid:
moduleNames.append(moduleName)
moduleNames.sort()
return moduleNames
def __replacePaths(self):
# Build up the replacement pathname table, so we can eliminate
# the personal information in the frozen pathnames. The
# actual filename we put in there is meaningful only for stack
# traces, so we'll just use the module name.
replace_paths = []
for moduleName, module in self.mf.modules.items():
if module.__code__:
origPathname = module.__code__.co_filename
replace_paths.append((origPathname, moduleName))
self.mf.replace_paths = replace_paths
# Now that we have built up the replacement mapping, go back
# through and actually replace the paths.
for moduleName, module in self.mf.modules.items():
if module.__code__:
co = self.mf.replace_paths_in_code(module.__code__)
module.__code__ = co;
def __addPyc(self, multifile, filename, code):
if code:
data = imp.get_magic() + '\0\0\0\0' + \
marshal.dumps(code)
stream = StringStream(data)
multifile.addSubfile(filename, stream, 0)
multifile.flush()
def __addPythonDirs(self, multifile, moduleDirs, dirnames):
""" Adds all of the names on dirnames as a module directory. """
if not dirnames:
return
str = '.'.join(dirnames)
if str not in moduleDirs:
# Add an implicit __init__.py file.
moduleName = '.'.join(dirnames)
filename = '/'.join(dirnames) + '/__init__.py'
stream = StringStream('')
multifile.addSubfile(filename, stream, 0)
multifile.flush()
moduleDirs[str] = True
self.__addPythonDirs(multifile, moduleDirs, dirnames[:-1])
def __addPythonFile(self, multifile, moduleDirs, moduleName):
""" Adds the named module to the multifile as a .pyc file. """
module = self.mf.modules.get(moduleName, None)
if getattr(module, '__path__', None) is not None:
# It's actually a package. In this case, we really write
# the file moduleName/__init__.py.
moduleName += '.__init__'
# First, split the module into its subdirectory names.
dirnames = moduleName.split('.')
self.__addPythonDirs(multifile, moduleDirs, dirnames[:-1])
# Attempt to add the original source file if we can.
if getattr(module, '__file__', None):
sourceFilename = Filename.fromOsSpecific(module.__file__)
sourceFilename.setExtension("py")
if sourceFilename.exists():
filename = '/'.join(dirnames) + '.py'
multifile.addSubfile(filename, sourceFilename, 0)
return
# If we can't find the source file, add the compiled pyc instead.
filename = '/'.join(dirnames) + '.pyc'
code = getattr(module, "__code__", None)
self.__addPyc(multifile, filename, code)
def writeMultifile(self, mfname):
"""Instead of generating a frozen file, put all of the Python
code in a multifile. """
self.__replacePaths()
Filename(mfname).unlink()
multifile = Multifile()
if not multifile.openReadWrite(mfname):
raise StandardError
moduleDirs = {}
for moduleName in self.__getModuleNames():
token = self.modules[moduleName]
if token != self.MTForbid:
self.__addPythonFile(multifile, moduleDirs, moduleName)
multifile.flush()
multifile.repack()
def generateCode(self, basename):
self.__replacePaths()
# Now generate the actual export table.
moduleDefs = []
moduleList = []
for moduleName in self.__getModuleNames():
token = self.modules[moduleName]
if token == self.MTForbid:
# Explicitly disallow importing this module.
moduleList.append(self.makeForbiddenModuleListEntry(moduleName))
else:
assert token != self.MTExclude
# Allow importing this module.
module = self.mf.modules.get(moduleName, None)
code = getattr(module, "__code__", None)
if not code and moduleName in startupModules:
# Forbid the loading of this startup module.
moduleList.append(self.makeForbiddenModuleListEntry(moduleName))
else:
if moduleName in sourceTrees:
# This is one of our Python source trees.
# These are a special case: we don't compile
# the __init__.py files within them, since
# their only purpose is to munge the __path__
# variable anyway. Instead, we pretend the
# __init__.py files are empty.
code = compile('', moduleName, 'exec')
if code:
code = marshal.dumps(code)
mangledName = self.mangleName(moduleName)
moduleDefs.append(self.makeModuleDef(mangledName, code))
moduleList.append(self.makeModuleListEntry(mangledName, code, moduleName, module))
if moduleName == self.mainModule:
# Add a special entry for __main__.
moduleList.append(self.makeModuleListEntry(mangledName, code, '__main__', module))
filename = basename + self.sourceExtension
if self.compileToExe:
code = self.frozenMainCode
if self.platform == 'win32':
code += self.frozenDllMainCode
initCode = self.mainInitCode % {
'frozenMainCode' : code,
'programName' : os.path.basename(basename),
}
if self.platform == 'win32':
initCode += self.frozenExtensions
target = basename + '.exe'
else:
target = basename
compileFunc = self.compileExe
else:
dllexport = ''
if self.platform == 'win32':
dllexport = '__declspec(dllexport) '
target = basename + '.pyd'
else:
target = basename + '.so'
initCode = dllInitCode % {
'dllexport' : dllexport,
'moduleName' : os.path.basename(basename),
'newcount' : len(moduleList),
}
compileFunc = self.compileDll
text = programFile % {
'moduleDefs' : '\n'.join(moduleDefs),
'moduleList' : '\n'.join(moduleList),
'initCode' : initCode,
}
file = open(filename, 'w')
file.write(text)
file.close()
try:
compileFunc(filename, basename)
finally:
if (os.path.exists(filename)):
os.unlink(filename)
if (os.path.exists(basename + self.objectExtension)):
os.unlink(basename + self.objectExtension)
return target
def compileExe(self, filename, basename):
compile = self.compileObj % {
'python' : Python,
'MSVC' : MSVC,
'PSDK' : PSDK,
'pythonIPath' : PythonIPath,
'pythonVersion' : PythonVersion,
'filename' : filename,
'basename' : basename,
}
print >> sys.stderr, compile
if os.system(compile) != 0:
raise StandardError
link = self.linkExe % {
'python' : Python,
'MSVC' : MSVC,
'PSDK' : PSDK,
'pythonIPath' : PythonIPath,
'pythonVersion' : PythonVersion,
'filename' : filename,
'basename' : basename,
}
print >> sys.stderr, link
if os.system(link) != 0:
raise StandardError
def compileDll(self, filename, basename):
compile = self.compileObj % {
'python' : Python,
'MSVC' : MSVC,
'PSDK' : PSDK,
'pythonIPath' : PythonIPath,
'pythonVersion' : PythonVersion,
'filename' : filename,
'basename' : basename,
}
print >> sys.stderr, compile
if os.system(compile) != 0:
raise StandardError
link = self.linkDll % {
'python' : Python,
'MSVC' : MSVC,
'PSDK' : PSDK,
'pythonIPath' : PythonIPath,
'pythonVersion' : PythonVersion,
'filename' : filename,
'basename' : basename,
}
print >> sys.stderr, link
if os.system(link) != 0:
raise StandardError
def makeModuleDef(self, mangledName, code):
result = ''
result += 'static unsigned char %s[] = {' % (mangledName)
for i in range(0, len(code), 16):
result += '\n '
for c in code[i:i+16]:
result += ('%d,' % ord(c))
result += '\n};\n'
return result
def makeModuleListEntry(self, mangledName, code, moduleName, module):
size = len(code)
if getattr(module, "__path__", None):
# Indicate package by negative size
size = -size
return ' {"%s", %s, %s},' % (moduleName, mangledName, size)
def makeForbiddenModuleListEntry(self, moduleName):
return ' {"%s", NULL, 0},' % (moduleName)