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, explicit = False, compress = None, extract = None,
text = None, unprocessed = None, text = None, unprocessed = None,
executable = None, dependencyDir = None, executable = None, dependencyDir = None,
platformSpecific = None): platformSpecific = None, required = False):
assert isinstance(filename, Filename) assert isinstance(filename, Filename)
self.filename = Filename(filename) self.filename = Filename(filename)
self.newName = newName self.newName = newName
@ -53,6 +53,7 @@ class Packager:
self.executable = executable self.executable = executable
self.dependencyDir = dependencyDir self.dependencyDir = dependencyDir
self.platformSpecific = platformSpecific self.platformSpecific = platformSpecific
self.required = required
if not self.newName: if not self.newName:
self.newName = self.filename.cStr() self.newName = self.filename.cStr()
@ -350,12 +351,19 @@ class Packager:
self.sourceFilenames = {} self.sourceFilenames = {}
self.targetFilenames = {} 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 # This records the current list of modules we have added so
# far. # far.
self.freezer = FreezeTool.Freezer(platform = self.packager.platform) self.freezer = FreezeTool.Freezer(platform = self.packager.platform)
def close(self): 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: if not self.p3dApplication and not self.packager.allowPackages:
message = 'Cannot generate packages without an installDir; use -i' message = 'Cannot generate packages without an installDir; use -i'
@ -420,14 +428,16 @@ class Packager:
break break
if self.solo: if self.solo:
self.installSolo() result = self.installSolo()
else: else:
self.installMultifile() result = self.installMultifile()
if self.p3dApplication: if self.p3dApplication:
allowPythonDev = self.configs.get('allow_python_dev', 0) allowPythonDev = self.configs.get('allow_python_dev', 0)
if int(allowPythonDev): if int(allowPythonDev):
print "\n*** Generating %s.p3d with allow_python_dev enabled ***\n" % (self.packageName) print "\n*** Generating %s.p3d with allow_python_dev enabled ***\n" % (self.packageName)
return result
def considerPlatform(self): def considerPlatform(self):
@ -472,6 +482,16 @@ class Packager:
# would make patching less efficient. # would make patching less efficient.
self.multifile.setRecordTimestamp(False) 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.extracts = []
self.components = [] self.components = []
@ -513,6 +533,19 @@ class Packager:
# Pick up any unfrozen Python files. # Pick up any unfrozen Python files.
self.freezer.done() 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.freezer.addToMultifile(self.multifile, self.compressionLevel)
self.addExtensionModules() self.addExtensionModules()
@ -698,6 +731,7 @@ class Packager:
self.packager.contentsChanged = True self.packager.contentsChanged = True
self.cleanup() self.cleanup()
return True
def installSolo(self): def installSolo(self):
""" Installs the package as a "solo", which means we """ Installs the package as a "solo", which means we
@ -765,6 +799,7 @@ class Packager:
self.packager.contentsChanged = True self.packager.contentsChanged = True
self.cleanup() self.cleanup()
return True
def cleanup(self): def cleanup(self):
# Now that all the files have been packed, we can delete # Now that all the files have been packed, we can delete
@ -791,6 +826,8 @@ class Packager:
return None return None
self.sourceFilenames[file.filename] = file self.sourceFilenames[file.filename] = file
if file.required:
self.requiredFilenames.append(file)
if file.text is None and not file.filename.exists(): if file.text is None and not file.filename.exists():
if not file.isExcluded(self): if not file.isExcluded(self):
@ -799,6 +836,7 @@ class Packager:
self.files.append(file) self.files.append(file)
self.targetFilenames[lowerName] = file self.targetFilenames[lowerName] = file
return file return file
def excludeFile(self, filename): def excludeFile(self, filename):
@ -1176,6 +1214,11 @@ class Packager:
path = DSearchPath(Filename(file.filename.getDirname())) path = DSearchPath(Filename(file.filename.getDirname()))
for filename in filenames: 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 = Filename.fromOsSpecific(filename)
filename.resolveFilename(path) filename.resolveFilename(path)
@ -2370,12 +2413,17 @@ class Packager:
statements = classDef.__dict__.get('__statements', []) statements = classDef.__dict__.get('__statements', [])
if not statements: if not statements:
self.notify.info("No files added to %s" % (name)) 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': if stype == 'class':
raise PackagerError, 'Nested classes not allowed' raise PackagerError, 'Nested classes not allowed'
self.__evalFunc(name, args, kw) self.__evalFunc(sname, args, kw)
package = self.endPackage() 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: else:
self.__evalFunc(name, args, kw) self.__evalFunc(name, args, kw)
except PackagerError: except PackagerError:
@ -2478,14 +2526,18 @@ class Packager:
def endPackage(self): def endPackage(self):
""" Closes the current package specification. This actually """ 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: if not self.currentPackage:
raise PackagerError, 'unmatched endPackage' raise PackagerError, 'unmatched endPackage'
package = self.currentPackage package = self.currentPackage
package.signParams += self.signParams[:] package.signParams += self.signParams[:]
package.close()
self.currentPackage = None
if not package.close():
return None
self.packageList.append(package) self.packageList.append(package)
self.packages[(package.packageName, package.platform, package.version)] = 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. """ """ Adds the indicated Python module(s) to the current package. """
self.addModule(args, **kw) 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: if not self.currentPackage:
raise OutsideOfPackageError raise OutsideOfPackageError
if (newName or filename) and len(moduleNames) != 1: if (newName or filename) and len(moduleNames) != 1:
raise PackagerError, 'Cannot specify newName with multiple modules' raise PackagerError, 'Cannot specify newName with multiple modules'
if required:
self.currentPackage.requiredModules += moduleNames
for moduleName in moduleNames: for moduleName in moduleNames:
self.currentPackage.freezer.addModule(moduleName, newName = newName, filename = filename) self.currentPackage.freezer.addModule(moduleName, newName = newName, filename = filename)
@ -2883,7 +2938,7 @@ class Packager:
newFilename.setExtension(filename.getExtension()) newFilename.setExtension(filename.getExtension())
self.currentPackage.addFile( self.currentPackage.addFile(
filename, newName = newFilename.cStr(), filename, newName = newFilename.cStr(),
explicit = True, extract = True) explicit = True, extract = True, required = True)
self.currentPackage.mainModule = (moduleName, newName) self.currentPackage.mainModule = (moduleName, newName)
@ -3054,7 +3109,8 @@ class Packager:
def addFiles(self, filenames, text = None, newName = None, def addFiles(self, filenames, text = None, newName = None,
newDir = None, extract = None, executable = 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. """ 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); renamed to .dylib and no extension on OSX (or .so on Linux);
and glob characters will be expanded. 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: if not self.currentPackage:
@ -3178,7 +3238,7 @@ class Packager:
filename, newName = name, extract = extract, filename, newName = name, extract = extract,
explicit = explicit, executable = executable, explicit = explicit, executable = executable,
text = text, deleteTemp = deleteTemp, text = text, deleteTemp = deleteTemp,
dependencyDir = dependencyDir) dependencyDir = dependencyDir, required = required)
def do_exclude(self, filename): def do_exclude(self, filename):
""" Marks the indicated filename as not to be included. The """ Marks the indicated filename as not to be included. The

View File

@ -110,7 +110,7 @@ class p3dcert(package):
else: else:
# Anywhere else, we just ship the executable file p3dcert.exe. # Anywhere else, we just ship the executable file p3dcert.exe.
file('p3dcert.exe') file('p3dcert.exe', required = True)
class p3dembed(package): class p3dembed(package):
@ -118,4 +118,4 @@ class p3dembed(package):
# pdeploy to generate a self-extracting .p3d executable. # pdeploy to generate a self-extracting .p3d executable.
config(platform_specific = True) 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") config(display_name = "FMod audio library")
require('panda3d') require('panda3d')
file('libp3fmod_audio.dll') file('libp3fmod_audio.dll', required = True)
file('fmod.prc', extract = True, text = """ file('fmod.prc', extract = True, text = """
plugin-path $FMOD_ROOT plugin-path $FMOD_ROOT
@ -218,7 +218,7 @@ class openal(package):
config(display_name = "OpenAL audio library") config(display_name = "OpenAL audio library")
require('panda3d') require('panda3d')
file('libp3openal_audio.dll') file('libp3openal_audio.dll', required = True)
file('openal.prc', extract = True, text = """ file('openal.prc', extract = True, text = """
plugin-path $OPENAL_ROOT plugin-path $OPENAL_ROOT
@ -243,7 +243,7 @@ class egg(package):
config(display_name = "Panda3D egg loader") config(display_name = "Panda3D egg loader")
require('panda3d') require('panda3d')
file('libpandaegg.dll') file('libpandaegg.dll', required = True)
file('egg.prc', extract = True, text = """ file('egg.prc', extract = True, text = """
plugin-path $EGG_ROOT plugin-path $EGG_ROOT
@ -258,7 +258,7 @@ class ode(package):
config(display_name = "Panda3D Open Dynamics Engine integration") config(display_name = "Panda3D Open Dynamics Engine integration")
require('panda3d') require('panda3d')
file('libpandaode.dll') file('libpandaode.dll', required = True)
class physx(package): class physx(package):
# This package contains the code for the NVIDIA PhysX integration. # This package contains the code for the NVIDIA PhysX integration.
@ -268,7 +268,7 @@ class physx(package):
config(display_name = "Panda3D PhysX integration") config(display_name = "Panda3D PhysX integration")
require('panda3d') require('panda3d')
file('libpandaphysx.dll') file('libpandaphysx.dll', required = True)
file('physxcudart_20.dll') file('physxcudart_20.dll')
file('PhysXDevice.dll') file('PhysXDevice.dll')
@ -281,7 +281,7 @@ class ai(package):
config(display_name = "Panda3D AI modules") config(display_name = "Panda3D AI modules")
require('panda3d') require('panda3d')
file('libpandaai.dll') file('libpandaai.dll', required = True)
class vision(package): class vision(package):
# This package contains the code for webcam support, augmented # This package contains the code for webcam support, augmented
@ -292,7 +292,7 @@ class vision(package):
config(display_name = "Panda3D vision modules") config(display_name = "Panda3D vision modules")
require('panda3d') require('panda3d')
file('libp3vision.dll') file('libp3vision.dll', required = True)
class packp3d(p3d): class packp3d(p3d):

View File

@ -31,7 +31,8 @@ Parameters:
Specify the names of the package(s) you wish to build out of the 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 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 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: Options:

View File

@ -22,15 +22,16 @@ class wx(package):
module('direct.wxwidgets') module('direct.wxwidgets')
module('direct.wxwidgets.WxAppShell') module('direct.wxwidgets.WxAppShell')
module('direct.wxwidgets.WxSlider') module('direct.wxwidgets.WxSlider')
module('wx', 'wx.*') module('wx', required = True)
module('wx.*')
class tk(package): class tk(package):
config(display_name = "Tk GUI Toolkit") config(display_name = "Tk GUI Toolkit")
#config(gui_app = True) #config(gui_app = True)
require('panda3d') require('panda3d')
module('Tkinter', module('Tkinter', required = True)
'direct.showbase.TkGlobal', module('direct.showbase.TkGlobal',
'direct.tkpanels', 'direct.tkpanels',
'direct.tkwidgets') 'direct.tkwidgets')
@ -44,25 +45,36 @@ class numpy(package):
config(display_name = "NumPy") config(display_name = "NumPy")
require('panda3d') require('panda3d')
module('numpy') module('numpy', required = True)
class pygame(package): class pygame(package):
config(display_name = "PyGame") config(display_name = "PyGame")
require('panda3d', 'numpy') require('panda3d', 'numpy')
module('pygame') module('pygame', required = True)
class twisted(package): class twisted(package):
config(display_name = "Twisted") config(display_name = "Twisted")
require('panda3d') 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): class pil(package):
config(display_name = "Python Imaging Library") config(display_name = "Python Imaging Library")
require('panda3d') require('panda3d')
module('PIL', 'PIL.*', 'ArgImagePlugin', 'BdfFontFile', module('PIL', required = True)
module('ArgImagePlugin', 'BdfFontFile',
'BmpImagePlugin', 'BufrStubImagePlugin', 'ContainerIO', 'BmpImagePlugin', 'BufrStubImagePlugin', 'ContainerIO',
'CurImagePlugin', 'DcxImagePlugin', 'EpsImagePlugin', 'CurImagePlugin', 'DcxImagePlugin', 'EpsImagePlugin',
'ExifTags', 'FitsStubImagePlugin', 'FliImagePlugin', 'ExifTags', 'FitsStubImagePlugin', 'FliImagePlugin',
@ -92,16 +104,17 @@ class pyopengl(package):
config(display_name = "PyOpenGL") config(display_name = "PyOpenGL")
require('panda3d', 'numpy') require('panda3d', 'numpy')
module('OpenGL', 'OpenGL.*') module('OpenGL', 'OpenGL.GL', required = True)
module('OpenGL.GLU', 'OpenGL.GLUT', 'OpenGL.GLE', 'OpenGL.GLX')
class httplib2(package): class httplib2(package):
config(display_name = "httplib2") config(display_name = "httplib2")
require('panda3d') require('panda3d')
module('httplib2') module('httplib2', required = True)
class pycurl(package): class pycurl(package):
config(display_name = "PyCURL") config(display_name = "PyCURL")
require('panda3d') require('panda3d')
module('pycurl') module('pycurl', required = True)