mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-01 09:23:03 -04:00
better support for pyc's
This commit is contained in:
parent
4456d45f62
commit
cce0129c7b
@ -23,11 +23,22 @@ Options:
|
|||||||
(this is preferable to having the module start itself immediately
|
(this is preferable to having the module start itself immediately
|
||||||
upon importing).
|
upon importing).
|
||||||
|
|
||||||
|
-c [py,pyc,pyo]
|
||||||
|
|
||||||
|
Specifies the compilation mode of python files. 'py' means to
|
||||||
|
leave them as source files, 'pyc' and 'pyo' are equivalent, and
|
||||||
|
mean to compile to byte code. pyc files will be written if the
|
||||||
|
interpreter is running in normal debug mode, while pyo files will
|
||||||
|
be written if it is running in optimize mode (-O or -OO).
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
import getopt
|
import getopt
|
||||||
|
import imp
|
||||||
|
import marshal
|
||||||
import direct
|
import direct
|
||||||
|
from direct.stdpy.file import open
|
||||||
from pandac.PandaModules import *
|
from pandac.PandaModules import *
|
||||||
|
|
||||||
vfs = VirtualFileSystem.getGlobalPtr()
|
vfs = VirtualFileSystem.getGlobalPtr()
|
||||||
@ -51,6 +62,9 @@ class AppPacker:
|
|||||||
# without compression.
|
# without compression.
|
||||||
uncompressible_extensions = [ 'mp3' ]
|
uncompressible_extensions = [ 'mp3' ]
|
||||||
|
|
||||||
|
# Specifies how or if python files are compiled.
|
||||||
|
compilation_mode = 'pyc'
|
||||||
|
|
||||||
def __init__(self, multifile_name):
|
def __init__(self, multifile_name):
|
||||||
# Make sure any pre-existing file is removed.
|
# Make sure any pre-existing file is removed.
|
||||||
Filename(multifile_name).unlink()
|
Filename(multifile_name).unlink()
|
||||||
@ -67,6 +81,12 @@ class AppPacker:
|
|||||||
self.image_extensions += type.getExtensions()
|
self.image_extensions += type.getExtensions()
|
||||||
|
|
||||||
def scan(self, root, main):
|
def scan(self, root, main):
|
||||||
|
if self.compilation_mode != 'py':
|
||||||
|
if __debug__:
|
||||||
|
self.compilation_mode = 'pyc'
|
||||||
|
else:
|
||||||
|
self.compilation_mode = 'pyo'
|
||||||
|
|
||||||
self.root = Filename(root)
|
self.root = Filename(root)
|
||||||
self.root.makeAbsolute(vfs.getCwd())
|
self.root.makeAbsolute(vfs.getCwd())
|
||||||
|
|
||||||
@ -131,14 +151,29 @@ class AppPacker:
|
|||||||
self.addUncompressibleFile(filename)
|
self.addUncompressibleFile(filename)
|
||||||
|
|
||||||
def addPyFile(self, filename):
|
def addPyFile(self, filename):
|
||||||
# For now, just add it as an ordinary file. Later we'll
|
targetFilename = self.makeRelFilename(filename)
|
||||||
# precompile these to .pyo's.
|
|
||||||
if filename == self.main:
|
if filename == self.main:
|
||||||
# This one is the "main.py"; the starter file.
|
# This one is the "main.py"; the starter file.
|
||||||
self.multifile.addSubfile('main.py', filename, self.compression_level)
|
targetFilename = Filename('main.py')
|
||||||
|
|
||||||
|
if self.compilation_mode == 'py':
|
||||||
|
# Add python files as source files.
|
||||||
|
self.multifile.addSubfile(targetFilename.cStr(), filename, self.compression_level)
|
||||||
|
elif self.compilation_mode == 'pyc' or self.compilation_mode == 'pyo':
|
||||||
|
# Compile it to bytecode.
|
||||||
|
targetFilename.setExtension(self.compilation_mode)
|
||||||
|
source = open(filename, 'r').read()
|
||||||
|
if source and source[-1] != '\n':
|
||||||
|
source = source + '\n'
|
||||||
|
code = compile(source, targetFilename.cStr(), 'exec')
|
||||||
|
data = imp.get_magic() + '\0\0\0\0' + marshal.dumps(code)
|
||||||
|
|
||||||
|
stream = StringStream(data)
|
||||||
|
self.multifile.addSubfile(targetFilename.cStr(), stream, self.compression_level)
|
||||||
|
self.multifile.flush()
|
||||||
else:
|
else:
|
||||||
# Any other Python file; add it normally.
|
raise StandardError, 'Unsupported compilation mode %s' % (self.compilation_mode)
|
||||||
self.addTextFile(filename)
|
|
||||||
|
|
||||||
def addEggFile(self, filename, outFilename):
|
def addEggFile(self, filename, outFilename):
|
||||||
# Precompile egg files to bam's.
|
# Precompile egg files to bam's.
|
||||||
@ -268,15 +303,18 @@ class AppPacker:
|
|||||||
|
|
||||||
|
|
||||||
def makePackedApp(args):
|
def makePackedApp(args):
|
||||||
opts, args = getopt.getopt(args, 'r:m:h')
|
opts, args = getopt.getopt(args, 'r:m:c:h')
|
||||||
|
|
||||||
root = '.'
|
root = '.'
|
||||||
main = None
|
main = None
|
||||||
|
compilation_mode = AppPacker.compilation_mode
|
||||||
for option, value in opts:
|
for option, value in opts:
|
||||||
if option == '-r':
|
if option == '-r':
|
||||||
root = value
|
root = value
|
||||||
elif option == '-m':
|
elif option == '-m':
|
||||||
main = value
|
main = value
|
||||||
|
elif option == '-c':
|
||||||
|
compilation_mode = value
|
||||||
elif option == '-h':
|
elif option == '-h':
|
||||||
print __doc__
|
print __doc__
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
@ -289,6 +327,7 @@ def makePackedApp(args):
|
|||||||
raise ArgumentError, "Too many arguments."
|
raise ArgumentError, "Too many arguments."
|
||||||
|
|
||||||
p = AppPacker(multifile_name)
|
p = AppPacker(multifile_name)
|
||||||
|
p.compilation_mode = compilation_mode
|
||||||
p.scan(root = root, main = main)
|
p.scan(root = root, main = main)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
@ -17,11 +17,11 @@ FTPythonSource = 0
|
|||||||
FTPythonCompiled = 1
|
FTPythonCompiled = 1
|
||||||
FTCompiledModule = 2
|
FTCompiledModule = 2
|
||||||
|
|
||||||
pycExtension = 'pyc'
|
compiledExtensions = [ 'pyc', 'pyo' ]
|
||||||
if not __debug__:
|
if not __debug__:
|
||||||
# In optimized mode, we actually operate on .pyo files, not .pyc
|
# In optimized mode, we prefer loading .pyo files over .pyc files.
|
||||||
# files.
|
# We implement that by reversing the extension names.
|
||||||
pycExtension = 'pyo'
|
compiledExtensions = [ 'pyo', 'pyc' ]
|
||||||
|
|
||||||
class VFSImporter:
|
class VFSImporter:
|
||||||
""" This class serves as a Python importer to support loading
|
""" This class serves as a Python importer to support loading
|
||||||
@ -45,8 +45,9 @@ class VFSImporter:
|
|||||||
|
|
||||||
# If there's no .py file, but there's a .pyc file, load that
|
# If there's no .py file, but there's a .pyc file, load that
|
||||||
# anyway.
|
# anyway.
|
||||||
|
for ext in compiledExtensions:
|
||||||
filename = Filename(path)
|
filename = Filename(path)
|
||||||
filename.setExtension(pycExtension)
|
filename.setExtension(ext)
|
||||||
vfile = vfs.getFile(filename, True)
|
vfile = vfs.getFile(filename, True)
|
||||||
if vfile:
|
if vfile:
|
||||||
return VFSLoader(self, vfile, filename, FTPythonCompiled)
|
return VFSLoader(self, vfile, filename, FTPythonCompiled)
|
||||||
@ -71,7 +72,8 @@ class VFSImporter:
|
|||||||
if vfile:
|
if vfile:
|
||||||
return VFSLoader(self, vfile, filename, FTPythonSource,
|
return VFSLoader(self, vfile, filename, FTPythonSource,
|
||||||
packagePath = path)
|
packagePath = path)
|
||||||
filename = Filename(path, '__init__.' + pycExtension)
|
for ext in compiledExtensions:
|
||||||
|
filename = Filename(path, '__init__.' + ext)
|
||||||
vfile = vfs.getFile(filename, True)
|
vfile = vfs.getFile(filename, True)
|
||||||
if vfile:
|
if vfile:
|
||||||
return VFSLoader(self, vfile, filename, FTPythonCompiled,
|
return VFSLoader(self, vfile, filename, FTPythonCompiled,
|
||||||
@ -192,12 +194,14 @@ class VFSLoader:
|
|||||||
# It's a .py file (or an __init__.py file; same thing). Read
|
# It's a .py file (or an __init__.py file; same thing). Read
|
||||||
# the .pyc file if it is available and current; otherwise read
|
# the .pyc file if it is available and current; otherwise read
|
||||||
# the .py file and compile it.
|
# the .py file and compile it.
|
||||||
pycFilename = Filename(self.filename)
|
|
||||||
pycFilename.setExtension(pycExtension)
|
|
||||||
pycVfile = vfs.getFile(pycFilename, False)
|
|
||||||
t_pyc = None
|
t_pyc = None
|
||||||
|
for ext in compiledExtensions:
|
||||||
|
pycFilename = Filename(self.filename)
|
||||||
|
pycFilename.setExtension(ext)
|
||||||
|
pycVfile = vfs.getFile(pycFilename, False)
|
||||||
if pycVfile:
|
if pycVfile:
|
||||||
t_pyc = pycVfile.getTimestamp()
|
t_pyc = pycVfile.getTimestamp()
|
||||||
|
break
|
||||||
|
|
||||||
code = None
|
code = None
|
||||||
if t_pyc and t_pyc >= self.timestamp:
|
if t_pyc and t_pyc >= self.timestamp:
|
||||||
@ -233,7 +237,7 @@ class VFSLoader:
|
|||||||
|
|
||||||
# try to cache the compiled code
|
# try to cache the compiled code
|
||||||
pycFilename = Filename(filename)
|
pycFilename = Filename(filename)
|
||||||
pycFilename.setExtension(pycExtension)
|
pycFilename.setExtension(compiledExtensions[0])
|
||||||
try:
|
try:
|
||||||
f = open(pycFilename, 'wb')
|
f = open(pycFilename, 'wb')
|
||||||
except IOError:
|
except IOError:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user