def __init__(self, xpath=None, hookspath=None, excludes=None): self.path = [] self.warnings = {} if xpath: self.path = xpath self.path.extend(sys.path) self.modules = LogDict() # RegistryImportDirector is necessary only on Windows. if is_win: self.metapath = [ PyInstaller.depend.impdirector.BuiltinImportDirector(), PyInstaller.depend.impdirector.RegistryImportDirector(), PyInstaller.depend.impdirector.PathImportDirector(self.path) ] else: self.metapath = [ PyInstaller.depend.impdirector.BuiltinImportDirector(), PyInstaller.depend.impdirector.PathImportDirector(self.path) ] if hookspath: hooks.__path__.extend(hookspath) if excludes is None: self.excludes = set() else: self.excludes = set(excludes)
def UpdateResourcesFromDict(dstpath, res, types=None, names=None, languages=None): """ Update or add resources from resource dict in dll/exe file dstpath. types = a list of resource types to update (None = all) names = a list of resource names to update (None = all) languages = a list of resource languages to update (None = all) """ if types: types = set(types) if names: names = set(names) if langauges: languages = set(languages) for type_ in res: if not types or type_ in types: for name in res[type_]: if not names or name in names: for language in res[type_][name]: if not languages or language in languages: UpdateResources(dstpath, res[type_][name][language], [type_], [name], [language])
def _GetResources(hsrc, types=None, names=None, languages=None): """ Get resources from hsrc. types = a list of resource types to search for (None = all) names = a list of resource names to search for (None = all) languages = a list of resource languages to search for (None = all) Return a dict of the form {type_: {name: {language: data}}} which might also be empty if no matching resources were found. """ if types: types = set(types) if names: names = set(names) if languages: languages = set(languages) res = {} try: # logger.debug("Enumerating resource types") enum_types = win32api.EnumResourceTypes(hsrc) if types and not "*" in types: enum_types = filter(lambda type_: type_ in types, enum_types) for type_ in enum_types: # logger.debug("Enumerating resources of type %s", type_) enum_names = win32api.EnumResourceNames(hsrc, type_) if names and not "*" in names: enum_names = filter(lambda name: name in names, enum_names) for name in enum_names: # logger.debug("Enumerating resources of type %s name %s", type_, name) enum_languages = win32api.EnumResourceLanguages(hsrc, type_, name) if languages and not "*" in languages: enum_languages = filter(lambda language: language in languages, enum_languages) for language in enum_languages: data = win32api.LoadResource(hsrc, type_, name, language) if not type_ in res: res[type_] = {} if not name in res[type_]: res[type_][name] = {} res[type_][name][language] = data except pywintypes.error, exception: if exception.args[0] in (ERROR_RESOURCE_DATA_NOT_FOUND, ERROR_RESOURCE_TYPE_NOT_FOUND, ERROR_RESOURCE_NAME_NOT_FOUND, ERROR_RESOURCE_LANG_NOT_FOUND): # logger.info('%s: %s', exception.args[1:3]) pass else: raise exception
def _GetResources(hsrc, types=None, names=None, languages=None): """ Get resources from hsrc. types = a list of resource types to search for (None = all) names = a list of resource names to search for (None = all) languages = a list of resource languages to search for (None = all) Return a dict of the form {type_: {name: {language: data}}} which might also be empty if no matching resources were found. """ if types: types = set(types) if names: names = set(names) if languages: languages = set(languages) res = {} try: # logger.debug("Enumerating resource types") enum_types = win32api.EnumResourceTypes(hsrc) if types and not "*" in types: enum_types = filter(lambda type_: type_ in types, enum_types) for type_ in enum_types: # logger.debug("Enumerating resources of type %s", type_) enum_names = win32api.EnumResourceNames(hsrc, type_) if names and not "*" in names: enum_names = filter(lambda name: name in names, enum_names) for name in enum_names: # logger.debug("Enumerating resources of type %s name %s", type_, name) enum_languages = win32api.EnumResourceLanguages( hsrc, type_, name) if languages and not "*" in languages: enum_languages = filter( lambda language: language in languages, enum_languages) for language in enum_languages: data = win32api.LoadResource(hsrc, type_, name, language) if not type_ in res: res[type_] = {} if not name in res[type_]: res[type_][name] = {} res[type_][name][language] = data except pywintypes.error, exception: if exception.args[0] in (ERROR_RESOURCE_DATA_NOT_FOUND, ERROR_RESOURCE_TYPE_NOT_FOUND, ERROR_RESOURCE_NAME_NOT_FOUND, ERROR_RESOURCE_LANG_NOT_FOUND): # logger.info('%s: %s', exception.args[1:3]) pass else: raise exception
def _getImports_macholib(pth): """ Find the binary dependencies of PTH. This implementation is for Mac OS X and uses library macholib. """ from PyInstaller.lib.macholib.MachO import MachO from PyInstaller.lib.macholib.dyld import dyld_find rslt = [] seen = set() # Libraries read from binary headers. # Walk through mach binary headers. m = MachO(pth) for header in m.headers: for idx, name, lib in header.walkRelocatables(): # Sometimes some libraries are present multiple times. if lib not in seen: seen.add(lib) # Try to find files in file system. exec_path = os.path.abspath('.') for lib in seen: if lib.startswith('@loader_path'): # macholib can't handle @loader_path. It has to be # handled the same way as @executable_path. # It is also replaced by 'exec_path'. lib = lib.replace('@loader_path', '@executable_path') try: lib = dyld_find(lib, executable_path=exec_path) rslt.append(lib) except ValueError: logger.error('Can not find path %s (needed by %s)', lib, pth) return rslt
def selectAssemblies(pth, manifest=None): """ Return a binary's dependent assemblies files that should be included. Return a list of pairs (name, fullpath) """ rv = [] if not os.path.isfile(pth): pth = check_extract_from_egg(pth)[0][0] if manifest: _depNames = set([dep.name for dep in manifest.dependentAssemblies]) for assembly in getAssemblies(pth): if seen.get(assembly.getid().upper(), 0): continue if manifest and not assembly.name in _depNames: # Add assembly as dependency to our final output exe's manifest logger.info("Adding %s to dependent assemblies " "of final executable", assembly.name) manifest.dependentAssemblies.append(assembly) _depNames.add(assembly.name) if not dylib.include_library(assembly.name): logger.debug("Skipping assembly %s", assembly.getid()) continue if assembly.optional: logger.debug("Skipping optional assembly %s", assembly.getid()) continue files = assembly.find_files() if files: seen[assembly.getid().upper()] = 1 for fn in files: fname, fext = os.path.splitext(fn) if fext.lower() == ".manifest": nm = assembly.name + fext else: nm = os.path.basename(fn) ftocnm = nm if assembly.language not in (None, "", "*", "neutral"): ftocnm = os.path.join(assembly.getlanguage(), ftocnm) nm, ftocnm, fn = [item.encode(sys.getfilesystemencoding()) for item in (nm, ftocnm, fn)] if not seen.get(fn.upper(), 0): logger.debug("Adding %s", ftocnm) seen[nm.upper()] = 1 seen[fn.upper()] = 1 rv.append((ftocnm, fn)) else: #logger.info("skipping %s part of assembly %s dependency of %s", # ftocnm, assembly.name, pth) pass else: logger.error("Assembly %s not found", assembly.getid()) return rv
def __init__(self, xpath=None, hookspath=None, excludes=None): self.path = [] self.warnings = {} if xpath: self.path = xpath self.path.extend(sys.path) self.modules = LogDict() self.metapath = [ BuiltinImportDirector(), FrozenImportDirector(), RegistryImportDirector(), PathImportDirector(self.path) ] if hookspath: hooks.__path__.extend(hookspath) if excludes is None: self.excludes = set() else: self.excludes = set(excludes)
def selectAssemblies(pth, manifest=None): """ Return a binary's dependent assemblies files that should be included. Return a list of pairs (name, fullpath) """ rv = [] if not os.path.isfile(pth): pth = check_extract_from_egg(pth)[0][0] if manifest: _depNames = set([dep.name for dep in manifest.dependentAssemblies]) for assembly in getAssemblies(pth): if seen.get(assembly.getid().upper(), 0): continue if manifest and not assembly.name in _depNames: # Add assembly as dependency to our final output exe's manifest logger.info( "Adding %s to dependent assemblies " "of final executable", assembly.name) manifest.dependentAssemblies.append(assembly) _depNames.add(assembly.name) if not dylib.include_library(assembly.name): logger.debug("Skipping assembly %s", assembly.getid()) continue if assembly.optional: logger.debug("Skipping optional assembly %s", assembly.getid()) continue files = assembly.find_files() if files: seen[assembly.getid().upper()] = 1 for fn in files: fname, fext = os.path.splitext(fn) if fext.lower() == ".manifest": nm = assembly.name + fext else: nm = os.path.basename(fn) ftocnm = nm if assembly.language not in (None, "", "*", "neutral"): ftocnm = os.path.join(assembly.getlanguage(), ftocnm) nm, ftocnm, fn = [ item.encode(sys.getfilesystemencoding()) for item in (nm, ftocnm, fn) ] if not seen.get(fn.upper(), 0): logger.debug("Adding %s", ftocnm) seen[nm.upper()] = 1 seen[fn.upper()] = 1 rv.append((ftocnm, fn)) else: #logger.info("skipping %s part of assembly %s dependency of %s", # ftocnm, assembly.name, pth) pass else: logger.error("Assembly %s not found", assembly.getid()) return rv
def _getImports_pe(pth): """ Find the binary dependencies of PTH. This implementation walks through the PE header and uses library pefile for that and supports 32/64bit Windows """ import PyInstaller.lib.pefile as pefile pe = pefile.PE(pth) dlls = set() # Some libraries have no other binary dependencies. # e.g. C:\windows\system32\kernel32.dll on Wine for entry in getattr(pe, 'DIRECTORY_ENTRY_IMPORT', []): dlls.add(entry.dll) return dlls
def find_django_root(dir): entities = set(os.listdir(dir)) if "manage.py" in entities and "settings.py" in entities and "urls.py" in entities: return [dir] else: django_root_directories = [] for entity in entities: path_to_analyze = os.path.join(dir, entity) if os.path.isdir(path_to_analyze): try: dir_entities = os.listdir(path_to_analyze) except (IOError, OSError): # silently skip unreadable directories continue if "manage.py" in dir_entities and "settings.py" in dir_entities and "urls.py" in dir_entities: django_root_directories.append(path_to_analyze) return django_root_directories
def __init__(self, pathlist=None, importers=None): if pathlist is None: self.path = sys.path else: self.path = pathlist self.ownertypes = filter(None, [ PyInstaller.depend.owner.DirOwner, PyInstaller.depend.owner.ZipOwner, PyInstaller.depend.owner.PYZOwner, PyInstaller.depend.owner.Owner, ]) if importers: self.shadowpath = importers else: self.shadowpath = {} self.building = set()
def _getImports_pe(pth): """ Find the binary dependencies of PTH. This implementation walks through the PE header and uses library pefile for that and supports 32/64bit Windows """ import PyInstaller.lib.pefile as pefile dlls = set() # By default library pefile parses all PE information. # We are only interested in the list of dependent dlls. # Performance is improved by reading only needed information. # https://code.google.com/p/pefile/wiki/UsageExamples pe = pefile.PE(pth, fast_load=True) pe.parse_data_directories(directories=[ pefile.DIRECTORY_ENTRY['IMAGE_DIRECTORY_ENTRY_IMPORT']]) # Some libraries have no other binary dependencies. Use empty list # in that case. Otherwise pefile would return None. # e.g. C:\windows\system32\kernel32.dll on Wine for entry in getattr(pe, 'DIRECTORY_ENTRY_IMPORT', []): dlls.add(entry.dll) return dlls
def _getImports_ldd(pth): """ Find the binary dependencies of PTH. This implementation is for ldd platforms (mostly unix). """ rslt = set() if is_aix: # Match libs of the form 'archive.a(sharedobject.so)' # Will not match the fake lib '/unix' lddPattern = re.compile(r"\s+(.*?)(\(.*\))") else: lddPattern = re.compile(r"\s+(.*?)\s+=>\s+(.*?)\s+\(.*\)") for line in compat.exec_command('ldd', pth).strip().splitlines(): m = lddPattern.search(line) if m: if is_aix: lib = m.group(1) name = os.path.basename(lib) + m.group(2) else: name, lib = m.group(1), m.group(2) if name[:10] in ('linux-gate', 'linux-vdso'): # linux-gate is a fake library which does not exist and # should be ignored. See also: # http://www.trilithium.com/johan/2005/08/linux-gate/ continue if os.path.exists(lib): # Add lib if it is not already found. if lib not in rslt: rslt.add(lib) else: logger.error('Can not find %s in path %s (needed by %s)', name, lib, pth) return rslt
__all__ = ['exclude_list', 'include_list', 'include_library'] import os import re from PyInstaller import is_win, is_unix, is_aix, is_darwin from PyInstaller.compat import set import PyInstaller.log as logging logger = logging.getLogger('PyInstaller.build.dylib') _BOOTLOADER_FNAMES = set(['run', 'run_d', 'runw', 'runw_d']) # Regex excludes # Ignoring some system libraries speeds up packaging process _excludes = {} # Regex includes - overrides excludes. # Include list is used only to override specific libraries # from exclude list. _includes = {} _win_excludes = { # MS assembly excludes r'^Microsoft\.Windows\.Common-Controls$': 1, }
def _getImports_macholib(pth): """ Find the binary dependencies of PTH. This implementation is for Mac OS X and uses library macholib. """ from PyInstaller.lib.macholib.MachO import MachO from PyInstaller.lib.macholib.mach_o import LC_RPATH from PyInstaller.lib.macholib.dyld import dyld_find rslt = set() seen = set() # Libraries read from binary headers. ## Walk through mach binary headers. m = MachO(pth) for header in m.headers: for idx, name, lib in header.walkRelocatables(): # Sometimes some libraries are present multiple times. if lib not in seen: seen.add(lib) # Walk through mach binary headers and look for LC_RPATH. # macholib can't handle @rpath. LC_RPATH has to be read # from the MachO header. # TODO Do we need to remove LC_RPATH from MachO load commands? # Will it cause any harm to leave them untouched? # Removing LC_RPATH should be implemented when getting # files from the bincache if it is necessary. run_paths = set() for header in m.headers: for command in header.commands: # A command is a tupple like: # (<macholib.mach_o.load_command object at 0x>, # <macholib.mach_o.rpath_command object at 0x>, # '../lib\x00\x00') cmd_type = command[0].cmd if cmd_type == LC_RPATH: rpath = command[2] # Remove trailing '\x00' characters. # e.g. '../lib\x00\x00' rpath = rpath.rstrip('\x00') # Make rpath absolute. According to Apple doc LC_RPATH # is always relative to the binary location. rpath = os.path.normpath(os.path.join(os.path.dirname(pth), rpath)) run_paths.update([rpath]) ## Try to find files in file system. # In cases with @loader_path or @executable_path # try to look in the same directory as the checked binary is. # This seems to work in most cases. exec_path = os.path.abspath(os.path.dirname(pth)) for lib in seen: # Suppose that @rpath is not used for system libraries and # using macholib can be avoided. # macholib can't handle @rpath. if lib.startswith('@rpath'): lib = lib.replace('@rpath', '.') # Make path relative. final_lib = None # Absolute path to existing lib on disk. # Try multiple locations. for run_path in run_paths: # @rpath may contain relative value. Use exec_path as # base path. if not os.path.isabs(run_path): run_path = os.path.join(exec_path, run_path) # Stop looking for lib when found in first location. if os.path.exists(os.path.join(run_path, lib)): final_lib = os.path.abspath(os.path.join(run_path, lib)) rslt.add(final_lib) break # Log error if no existing file found. if not final_lib: logger.error('Can not find path %s (needed by %s)', lib, pth) # Macholib has to be used to get absolute path to libraries. else: # macholib can't handle @loader_path. It has to be # handled the same way as @executable_path. # It is also replaced by 'exec_path'. if lib.startswith('@loader_path'): lib = lib.replace('@loader_path', '@executable_path') try: lib = dyld_find(lib, executable_path=exec_path) rslt.add(lib) except ValueError: logger.error('Can not find path %s (needed by %s)', lib, pth) return rslt
__all__ = ["exclude_list", "include_list", "include_library"] import os import re from PyInstaller import is_win, is_unix, is_aix, is_darwin from PyInstaller.compat import set import PyInstaller.log as logging logger = logging.getLogger("PyInstaller.build.dylib") _BOOTLOADER_FNAMES = set(["run", "run_d", "runw", "runw_d"]) # Regex excludes # Ignoring some system libraries speeds up packaging process _excludes = {} # Regex includes - overrides excludes. # Include list is used only to override specific libraries # from exclude list. _includes = {} _win_excludes = { # MS assembly excludes r"^Microsoft\.Windows\.Common-Controls$": 1 }
LOAD_NAME = dis.opname.index('LOAD_NAME') EXEC_STMT = dis.opname.index('EXEC_STMT') try: SET_LINENO = dis.opname.index('SET_LINENO') except ValueError: SET_LINENO = None BUILD_LIST = dis.opname.index('BUILD_LIST') LOAD_CONST = dis.opname.index('LOAD_CONST') if is_py25: LOAD_CONST_level = LOAD_CONST else: LOAD_CONST_level = None if is_py27: COND_OPS = set([dis.opname.index('POP_JUMP_IF_TRUE'), dis.opname.index('POP_JUMP_IF_FALSE'), dis.opname.index('JUMP_IF_TRUE_OR_POP'), dis.opname.index('JUMP_IF_FALSE_OR_POP'), ]) else: COND_OPS = set([dis.opname.index('JUMP_IF_FALSE'), dis.opname.index('JUMP_IF_TRUE'), ]) JUMP_FORWARD = dis.opname.index('JUMP_FORWARD') try: STORE_DEREF = dis.opname.index('STORE_DEREF') except ValueError: STORE_DEREF = None STORE_OPS = set([STORE_NAME, STORE_FAST, STORE_GLOBAL, STORE_DEREF, STORE_MAP]) #IMPORT_STAR -> IMPORT_NAME mod ; IMPORT_STAR #JUMP_IF_FALSE / JUMP_IF_TRUE / JUMP_FORWARD HASJREL = set(dis.hasjrel)