Several improvements:

* Don't try to include linux kernel vdso's
 * Ability to mark modules or files as required
 * Fix some issues with several thirdparty packages in the pdef
This commit is contained in:
rdb 2010-10-25 19:26:02 +00:00
parent 09f6436745
commit 04b863edf7
5 changed files with 107 additions and 33 deletions

View File

@ -40,7 +40,7 @@ class Packager:
explicit = False, compress = None, extract = None,
text = None, unprocessed = None,
executable = None, dependencyDir = None,
platformSpecific = None):
platformSpecific = None, required = False):
assert isinstance(filename, Filename)
self.filename = Filename(filename)
self.newName = newName
@ -53,6 +53,7 @@ class Packager:
self.executable = executable
self.dependencyDir = dependencyDir
self.platformSpecific = platformSpecific
self.required = required
if not self.newName:
self.newName = self.filename.cStr()
@ -350,12 +351,19 @@ class Packager:
self.sourceFilenames = {}
self.targetFilenames = {}
# This is the set of files and modules that are
# required and may not be excluded from the package.
self.requiredFilenames = []
self.requiredModules = []
# This records the current list of modules we have added so
# far.
self.freezer = FreezeTool.Freezer(platform = self.packager.platform)
def close(self):
""" Writes out the contents of the current package. """
""" Writes out the contents of the current package. Returns True
if the package was constructed successfully, False if one or more
required files or modules are missing. """
if not self.p3dApplication and not self.packager.allowPackages:
message = 'Cannot generate packages without an installDir; use -i'
@ -420,14 +428,16 @@ class Packager:
break
if self.solo:
self.installSolo()
result = self.installSolo()
else:
self.installMultifile()
result = self.installMultifile()
if self.p3dApplication:
allowPythonDev = self.configs.get('allow_python_dev', 0)
if int(allowPythonDev):
print "\n*** Generating %s.p3d with allow_python_dev enabled ***\n" % (self.packageName)
return result
def considerPlatform(self):
@ -472,6 +482,16 @@ class Packager:
# would make patching less efficient.
self.multifile.setRecordTimestamp(False)
# Make sure that all required files are present.
missing = []
for file in self.requiredFilenames:
if file not in self.files or file.isExcluded(self):
missing.append(file.filename.getBasename())
if len(missing) > 0:
self.notify.warning("Cannot build package %s, missing required files: %r" % (self.packageName, missing))
self.cleanup()
return False
self.extracts = []
self.components = []
@ -513,6 +533,19 @@ class Packager:
# Pick up any unfrozen Python files.
self.freezer.done()
# But first, make sure that all required modules are present.
missing = []
for module in self.requiredModules:
if module not in self.freezer.modules.keys() or \
self.freezer.modules[module].exclude:
missing.append(module)
if len(missing) > 0:
self.notify.warning("Cannot build package %s, missing required modules: %r" % (self.packageName, missing))
self.cleanup()
return False
# OK, we can add it.
self.freezer.addToMultifile(self.multifile, self.compressionLevel)
self.addExtensionModules()
@ -698,6 +731,7 @@ class Packager:
self.packager.contentsChanged = True
self.cleanup()
return True
def installSolo(self):
""" Installs the package as a "solo", which means we
@ -765,6 +799,7 @@ class Packager:
self.packager.contentsChanged = True
self.cleanup()
return True
def cleanup(self):
# Now that all the files have been packed, we can delete
@ -791,6 +826,8 @@ class Packager:
return None
self.sourceFilenames[file.filename] = file
if file.required:
self.requiredFilenames.append(file)
if file.text is None and not file.filename.exists():
if not file.isExcluded(self):
@ -799,6 +836,7 @@ class Packager:
self.files.append(file)
self.targetFilenames[lowerName] = file
return file
def excludeFile(self, filename):
@ -1176,6 +1214,11 @@ class Packager:
path = DSearchPath(Filename(file.filename.getDirname()))
for filename in filenames:
# These vDSO's provided by Linux aren't
# supposed to be anywhere on the system.
if filename in ["linux-gate.so.1", "linux-vdso.so.1"]:
continue
filename = Filename.fromOsSpecific(filename)
filename.resolveFilename(path)
@ -2370,12 +2413,17 @@ class Packager:
statements = classDef.__dict__.get('__statements', [])
if not statements:
self.notify.info("No files added to %s" % (name))
for (lineno, stype, name, args, kw) in statements:
for (lineno, stype, sname, args, kw) in statements:
if stype == 'class':
raise PackagerError, 'Nested classes not allowed'
self.__evalFunc(name, args, kw)
self.__evalFunc(sname, args, kw)
package = self.endPackage()
packages.append(package)
if package is not None:
packages.append(package)
elif packageNames is not None:
# If the name is explicitly specified, this means
# we should abort if the package faild to construct.
raise PackagerError, 'Failed to construct %s' % name
else:
self.__evalFunc(name, args, kw)
except PackagerError:
@ -2478,14 +2526,18 @@ class Packager:
def endPackage(self):
""" Closes the current package specification. This actually
generates the package file. Returns the finished package."""
generates the package file. Returns the finished package,
or None if the package failed to close (e.g. missing files). """
if not self.currentPackage:
raise PackagerError, 'unmatched endPackage'
package = self.currentPackage
package.signParams += self.signParams[:]
package.close()
self.currentPackage = None
if not package.close():
return None
self.packageList.append(package)
self.packages[(package.packageName, package.platform, package.version)] = package
@ -2844,13 +2896,16 @@ class Packager:
""" Adds the indicated Python module(s) to the current package. """
self.addModule(args, **kw)
def addModule(self, moduleNames, newName = None, filename = None):
def addModule(self, moduleNames, newName = None, filename = None, required = False):
if not self.currentPackage:
raise OutsideOfPackageError
if (newName or filename) and len(moduleNames) != 1:
raise PackagerError, 'Cannot specify newName with multiple modules'
if required:
self.currentPackage.requiredModules += moduleNames
for moduleName in moduleNames:
self.currentPackage.freezer.addModule(moduleName, newName = newName, filename = filename)
@ -2883,7 +2938,7 @@ class Packager:
newFilename.setExtension(filename.getExtension())
self.currentPackage.addFile(
filename, newName = newFilename.cStr(),
explicit = True, extract = True)
explicit = True, extract = True, required = True)
self.currentPackage.mainModule = (moduleName, newName)
@ -3054,7 +3109,8 @@ class Packager:
def addFiles(self, filenames, text = None, newName = None,
newDir = None, extract = None, executable = None,
deleteTemp = False, literal = False, dependencyDir = None):
deleteTemp = False, literal = False,
dependencyDir = None, required = False):
""" Adds the indicated arbitrary files to the current package.
@ -3098,6 +3154,10 @@ class Packager:
renamed to .dylib and no extension on OSX (or .so on Linux);
and glob characters will be expanded.
If required is true, then the file is marked a vital part of
the package. The package will not be built if this file
somehow cannot be added to the package.
"""
if not self.currentPackage:
@ -3178,7 +3238,7 @@ class Packager:
filename, newName = name, extract = extract,
explicit = explicit, executable = executable,
text = text, deleteTemp = deleteTemp,
dependencyDir = dependencyDir)
dependencyDir = dependencyDir, required = required)
def do_exclude(self, filename):
""" Marks the indicated filename as not to be included. The

View File

@ -110,7 +110,7 @@ class p3dcert(package):
else:
# Anywhere else, we just ship the executable file p3dcert.exe.
file('p3dcert.exe')
file('p3dcert.exe', required = True)
class p3dembed(package):
@ -118,4 +118,4 @@ class p3dembed(package):
# pdeploy to generate a self-extracting .p3d executable.
config(platform_specific = True)
file('p3dembed.exe')
file('p3dembed.exe', required = True)

View File

@ -203,7 +203,7 @@ class fmod(package):
config(display_name = "FMod audio library")
require('panda3d')
file('libp3fmod_audio.dll')
file('libp3fmod_audio.dll', required = True)
file('fmod.prc', extract = True, text = """
plugin-path $FMOD_ROOT
@ -218,7 +218,7 @@ class openal(package):
config(display_name = "OpenAL audio library")
require('panda3d')
file('libp3openal_audio.dll')
file('libp3openal_audio.dll', required = True)
file('openal.prc', extract = True, text = """
plugin-path $OPENAL_ROOT
@ -243,7 +243,7 @@ class egg(package):
config(display_name = "Panda3D egg loader")
require('panda3d')
file('libpandaegg.dll')
file('libpandaegg.dll', required = True)
file('egg.prc', extract = True, text = """
plugin-path $EGG_ROOT
@ -258,7 +258,7 @@ class ode(package):
config(display_name = "Panda3D Open Dynamics Engine integration")
require('panda3d')
file('libpandaode.dll')
file('libpandaode.dll', required = True)
class physx(package):
# This package contains the code for the NVIDIA PhysX integration.
@ -268,7 +268,7 @@ class physx(package):
config(display_name = "Panda3D PhysX integration")
require('panda3d')
file('libpandaphysx.dll')
file('libpandaphysx.dll', required = True)
file('physxcudart_20.dll')
file('PhysXDevice.dll')
@ -281,7 +281,7 @@ class ai(package):
config(display_name = "Panda3D AI modules")
require('panda3d')
file('libpandaai.dll')
file('libpandaai.dll', required = True)
class vision(package):
# This package contains the code for webcam support, augmented
@ -292,7 +292,7 @@ class vision(package):
config(display_name = "Panda3D vision modules")
require('panda3d')
file('libp3vision.dll')
file('libp3vision.dll', required = True)
class packp3d(p3d):

View File

@ -31,7 +31,8 @@ Parameters:
Specify the names of the package(s) you wish to build out of the
package.pdef file. This allows you to build only a subset of the
packages defined in this file. If you omit these parameters, all
packages are built.
packages are built, and packages that cannot be built are silently
ignored.
Options:

View File

@ -22,15 +22,16 @@ class wx(package):
module('direct.wxwidgets')
module('direct.wxwidgets.WxAppShell')
module('direct.wxwidgets.WxSlider')
module('wx', 'wx.*')
module('wx', required = True)
module('wx.*')
class tk(package):
config(display_name = "Tk GUI Toolkit")
#config(gui_app = True)
require('panda3d')
module('Tkinter',
'direct.showbase.TkGlobal',
module('Tkinter', required = True)
module('direct.showbase.TkGlobal',
'direct.tkpanels',
'direct.tkwidgets')
@ -44,25 +45,36 @@ class numpy(package):
config(display_name = "NumPy")
require('panda3d')
module('numpy')
module('numpy', required = True)
class pygame(package):
config(display_name = "PyGame")
require('panda3d', 'numpy')
module('pygame')
module('pygame', required = True)
class twisted(package):
config(display_name = "Twisted")
require('panda3d')
module('twisted', 'twisted.*', 'twisted.*.*')
module('twisted', 'twisted._version', required = True)
module('twisted.application', 'twisted.conch', 'twisted.cred',
'twisted.enterprise', 'twisted.internet', 'twisted.lore',
'twisted.mail', 'twisted.manhole', 'twisted.names',
'twisted.news', 'twisted.pair', 'twisted.persisted',
'twisted.plugin', 'twisted.plugins', 'twisted.python',
'twisted.runner', 'twisted.scripts', 'twisted.spread',
'twisted.tap', 'twisted.trial', 'twisted.vfs',
'twisted.web', 'twisted.web2', 'twisted.words')
module('twisted.*', 'twisted.*.*')
class pil(package):
config(display_name = "Python Imaging Library")
require('panda3d')
module('PIL', 'PIL.*', 'ArgImagePlugin', 'BdfFontFile',
module('PIL', required = True)
module('ArgImagePlugin', 'BdfFontFile',
'BmpImagePlugin', 'BufrStubImagePlugin', 'ContainerIO',
'CurImagePlugin', 'DcxImagePlugin', 'EpsImagePlugin',
'ExifTags', 'FitsStubImagePlugin', 'FliImagePlugin',
@ -92,16 +104,17 @@ class pyopengl(package):
config(display_name = "PyOpenGL")
require('panda3d', 'numpy')
module('OpenGL', 'OpenGL.*')
module('OpenGL', 'OpenGL.GL', required = True)
module('OpenGL.GLU', 'OpenGL.GLUT', 'OpenGL.GLE', 'OpenGL.GLX')
class httplib2(package):
config(display_name = "httplib2")
require('panda3d')
module('httplib2')
module('httplib2', required = True)
class pycurl(package):
config(display_name = "PyCURL")
require('panda3d')
module('pycurl')
module('pycurl', required = True)