From 04b863edf77030d0be5f6ea4be47b5dff9c9617a Mon Sep 17 00:00:00 2001 From: rdb Date: Mon, 25 Oct 2010 19:26:02 +0000 Subject: [PATCH] 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 --- direct/src/p3d/Packager.py | 86 +++++++++++++++++++++++++++++----- direct/src/p3d/coreapi.pdef | 4 +- direct/src/p3d/panda3d.pdef | 14 +++--- direct/src/p3d/ppackage.py | 3 +- direct/src/p3d/thirdparty.pdef | 33 +++++++++---- 5 files changed, 107 insertions(+), 33 deletions(-) diff --git a/direct/src/p3d/Packager.py b/direct/src/p3d/Packager.py index 69ef0f78c8..50e29f3db6 100644 --- a/direct/src/p3d/Packager.py +++ b/direct/src/p3d/Packager.py @@ -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 diff --git a/direct/src/p3d/coreapi.pdef b/direct/src/p3d/coreapi.pdef index 461ad6eb9b..8012ac3b35 100644 --- a/direct/src/p3d/coreapi.pdef +++ b/direct/src/p3d/coreapi.pdef @@ -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) diff --git a/direct/src/p3d/panda3d.pdef b/direct/src/p3d/panda3d.pdef index ab664813d5..22d6cc4ecd 100755 --- a/direct/src/p3d/panda3d.pdef +++ b/direct/src/p3d/panda3d.pdef @@ -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): diff --git a/direct/src/p3d/ppackage.py b/direct/src/p3d/ppackage.py index 08740d3c9f..cb5bb23eb3 100755 --- a/direct/src/p3d/ppackage.py +++ b/direct/src/p3d/ppackage.py @@ -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: diff --git a/direct/src/p3d/thirdparty.pdef b/direct/src/p3d/thirdparty.pdef index 15a698f06c..1c44d464d6 100644 --- a/direct/src/p3d/thirdparty.pdef +++ b/direct/src/p3d/thirdparty.pdef @@ -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)