def _get_pyinst_cache_dir(): old_cache_dir = None if compat.getenv('PYINSTALLER_CONFIG_DIR'): cache_dir = compat.getenv('PYINSTALLER_CONFIG_DIR') elif is_win: cache_dir = compat.getenv('LOCALAPPDATA') if not cache_dir: cache_dir = os.path.expanduser('~\\Application Data') elif is_darwin: cache_dir = os.path.expanduser('~/Library/Application Support') else: # According to XDG specification # http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html old_cache_dir = compat.getenv('XDG_DATA_HOME') if not old_cache_dir: old_cache_dir = os.path.expanduser('~/.local/share') cache_dir = compat.getenv('XDG_CACHE_HOME') if not cache_dir: cache_dir = os.path.expanduser('~/.cache') cache_dir = os.path.join(cache_dir, 'pyinstaller') # Move old cache-dir, if any, to now location if old_cache_dir and not os.path.exists(cache_dir): old_cache_dir = os.path.join(old_cache_dir, 'pyinstaller') if os.path.exists(old_cache_dir): parent_dir = os.path.dirname(cache_dir) if not os.path.exists(parent_dir): os.makedirs(parent_dir) os.rename(old_cache_dir, cache_dir) return cache_dir
def get_windows_dir(): """Return the Windows directory e.g. C:\\Windows""" try: import win32api except ImportError: windir = compat.getenv('SystemRoot', compat.getenv('WINDIR')) else: windir = win32api.GetWindowsDirectory() if not windir: raise SystemExit("Error: Can not determine your Windows directory") return windir
def findLibrary(name): """ Look for a library in the system. Emulate the algorithm used by dlopen. `name`must include the prefix, e.g. ``libpython2.4.so`` """ assert is_unix, "Current implementation for Unix only (Linux, Solaris, AIX)" lib = None # Look in the LD_LIBRARY_PATH according to platform. if is_aix: lp = compat.getenv('LIBPATH', '') elif is_darwin: lp = compat.getenv('DYLD_LIBRARY_PATH', '') else: lp = compat.getenv('LD_LIBRARY_PATH', '') for path in lp.split(os.pathsep): libs = glob(os.path.join(path, name + '*')) if libs: lib = libs[0] break # Look in /etc/ld.so.cache # TODO Look for ldconfig in /usr/sbin/ldconfig. /sbin is deprecated # in recent linux distributions. # Solaris does not have /sbin/ldconfig. Just check if this file exists. if lib is None and os.path.exists('/sbin/ldconfig'): expr = r'/[^\(\)\s]*%s\.[^\(\)\s]*' % re.escape(name) m = re.search(expr, compat.exec_command('/sbin/ldconfig', '-p')) if m: lib = m.group(0) # Look in the known safe paths if lib is None: paths = ['/lib', '/usr/lib'] if is_aix: paths.append('/opt/freeware/lib') for path in paths: libs = glob(os.path.join(path, name + '*')) if libs: lib = libs[0] break # give up :( if lib is None: return None # Resolve the file name into the soname dir = os.path.dirname(lib) return os.path.join(dir, getSoname(lib))
def _setPaths(): path = os.pathsep.join(CONF['pathex']) old = compat.getenv(envvar) if old is not None: path = os.pathsep.join((path, old)) compat.setenv(envvar, path) return old
def _setPaths(): path = os.pathsep.join(PyInstaller.__pathex__) old = compat.getenv(envvar) if old is not None: path = os.pathsep.join((path, old)) compat.setenv(envvar, path) return old
def _run_created_exe(self, test, testdir=None): """ Run executable created by PyInstaller. """ self._msg('EXECUTING TEST ' + self.test_name) # Run the test in a clean environment to make sure they're # really self-contained path = compat.getenv('PATH') compat.unsetenv('PATH') prog = self._find_exepath(test, 'dist') if prog is None: self._plain_msg('ERROR: no file generated by PyInstaller found!') compat.setenv("PATH", path) return 1 else: self._plain_msg("RUNNING: " + prog) old_wd = os.getcwd() os.chdir(os.path.dirname(prog)) prog = os.path.join(os.curdir, os.path.basename(prog)) retcode, out, err = compat.exec_command_all(prog) os.chdir(old_wd) self._msg('STDOUT %s' % self.test_name) self._plain_msg(out) self._msg('STDERR %s' % self.test_name) self._plain_msg(err) compat.setenv("PATH", path) return retcode
def getfullnameof(mod, xtrapath=None): """ Return the full path name of MOD. MOD is the basename of a dll or pyd. XTRAPATH is a path or list of paths to search first. Return the full path name of MOD. Will search the full Windows search path, as well as sys.path """ pywin32_paths = [] if compat.is_win: pywin32_paths = [os.path.join(get_python_lib(), 'pywin32_system32')] if compat.is_venv: pywin32_paths.append( os.path.join(compat.base_prefix, 'Lib', 'site-packages', 'pywin32_system32')) epath = ( sys.path + # Search sys.path first! pywin32_paths + winutils.get_system_path() + compat.getenv('PATH', '').split(os.pathsep)) if xtrapath is not None: if type(xtrapath) == type(''): epath.insert(0, xtrapath) else: epath = xtrapath + epath for p in epath: npth = os.path.join(p, mod) if os.path.exists(npth) and matchDLLArch(npth): return npth return ''
def sign_source_distribution(data): """ Sign the tgz or zip archive that will be uploaded to PYPI. :param data: """ print() # zest.releaser does a clean checkout where it generates tgz/zip in 'dist' directory and those files will be then # uploaded to pypi. dist_dir = os.path.join(data['tagdir'], 'dist') cmd = ['gpg', '--detach-sign', '--armor'] if getenv("PYINSTALLER_CODESIGNING_ID"): print("Using gpg identity", getenv("PYINSTALLER_CODESIGNING_ID"), "for signing.") cmd.extend(['--local-user', getenv("PYINSTALLER_CODESIGNING_ID")]) # Sign all files in 'dist' directory. for f in os.listdir(dist_dir): f = os.path.join(dist_dir, f) print('Signing file %s' % f) exec_command(*cmd + [f])
def setupUPXFlags(): f = compat.getenv("UPX", "") if is_win: # Binaries built with Visual Studio 7.1 require --strip-loadconf or they will not compress. Configure.py makes # sure that UPX is new enough to support --strip-loadconf. f = "--strip-loadconf " + f # Do not compress any icon, so that additional icons in the executable can still be externally bound. f = "--compress-icons=0 " + f f = "--best " + f compat.setenv("UPX", f)
def extend_system_path(paths): """ Add new paths at the beginning of environment variable PATH. Some hooks might extend PATH where PyInstaller should look for dlls. """ old_PATH = compat.getenv('PATH', '') paths.append(old_PATH) new_PATH = os.pathsep.join(paths) compat.setenv('PATH', new_PATH)
def get_policy_dir(cls): winsxs = os.path.join(compat.getenv("SystemRoot"), "WinSxS") if sys.getwindowsversion() < (6, ): # Windows XP pcfiles = os.path.join(winsxs, "Policies") if not os.path.isdir(pcfiles): logger.warning("No such dir %s", pcfiles) else: # Vista or later pcfiles = cls.get_manifest_dir() return pcfiles
def get_policy_dir(cls): winsxs = os.path.join(compat.getenv("SystemRoot"), "WinSxS") if sys.getwindowsversion() < (6, ): # Windows XP pcfiles = os.path.join(winsxs, "Policies") if not os.path.isdir(pcfiles): logger.warn("No such dir %s", pcfiles) else: # Vista or later pcfiles = cls.get_manifest_dir() return pcfiles
def pkg_resouces_get_default_cache(): """ Determine the default cache location This returns the ``PYTHON_EGG_CACHE`` environment variable, if set. Otherwise, on Windows, it returns a 'Python-Eggs' subdirectory of the 'Application Data' directory. On all other systems, it's '~/.python-eggs'. """ # This function borrowed from setuptools/pkg_resources egg_cache = compat.getenv('PYTHON_EGG_CACHE') if egg_cache is not None: return egg_cache if os.name != 'nt': return os.path.expanduser('~/.python-eggs') app_data = 'Application Data' # XXX this may be locale-specific! app_homes = [ (('APPDATA',), None), # best option, should be locale-safe (('USERPROFILE',), app_data), (('HOMEDRIVE', 'HOMEPATH'), app_data), (('HOMEPATH',), app_data), (('HOME',), None), (('WINDIR',), app_data), # 95/98/ME ] for keys, subdir in app_homes: dirname = '' for key in keys: if key in os.environ: dirname = os.path.join(dirname, compat.getenv(key)) else: break else: if subdir: dirname = os.path.join(dirname, subdir) return os.path.join(dirname, 'Python-Eggs') else: raise RuntimeError( "Please set the PYTHON_EGG_CACHE enviroment variable" )
def extend_system_path(paths): """ Add new paths at the beginning of environment variable PATH. Some hooks might extend PATH where PyInstaller should look for dlls. """ # imported here to avoid circular import from PyInstaller import compat old_path = compat.getenv('PATH', '') paths.append(old_path) new_path = os.pathsep.join(paths) compat.setenv('PATH', new_path)
def wrapper(*args, **kwargs): if is_win: old_path = getenv('PATH', '') new_path = os.pathsep.join([ x for x in os.environ['PATH'].split(os.pathsep) if path_to_clean not in x ]) setenv('PATH', new_path) try: return f(*args, **kwargs) finally: if is_win: setenv('PATH', old_path)
def test_exe(test, testdir=None): _msg("EXECUTING TEST", testdir + '/' + test) # Run the test in a clean environment to make sure they're # really self-contained path = compat.getenv("PATH") compat.unsetenv("PATH") prog = find_exepath(test, 'dist') if prog is None: print "ERROR: no file generated by PyInstaller found!" compat.setenv("PATH", path) return 1 else: print "RUNNING:", prog tmp = compat.exec_command_rc(prog) compat.setenv("PATH", path) return tmp
def _run_created_exe(self, test, testdir=None): """ Run executable created by PyInstaller. """ self._msg('EXECUTING TEST ' + self.test_name) # Run the test in a clean environment to make sure they're # really self-contained path = compat.getenv('PATH') compat.unsetenv('PATH') # For Windows we need to keep minimal PATH for sucessful running of some tests. if is_win: # Minimum Windows PATH is in most cases: C:\Windows\system32;C:\Windows compat.setenv('PATH', os.pathsep.join(winutils.get_system_path())) prog = self._find_exepath(test, 'dist') if prog is None: self._plain_msg('ERROR: no file generated by PyInstaller found!') compat.setenv("PATH", path) return 1 else: self._plain_msg("RUNNING: " + prog) old_wd = os.getcwd() os.chdir(os.path.dirname(prog)) # Run executable. prog = os.path.join(os.curdir, os.path.basename(prog)) proc = subprocess.Popen([prog], stdout=subprocess.PIPE, stderr=subprocess.PIPE) # Prints stdout of subprocess continuously. self._msg('STDOUT %s' % self.test_name) while proc.poll() is None: #line = proc.stdout.readline().strip() line = proc.stdout.read(1) self._plain_msg(line, newline=False) # Print any stdout that wasn't read before the process terminated. # See the conversation in https://github.com/pyinstaller/pyinstaller/pull/1092 # for examples of why this is necessary. self._plain_msg(proc.stdout.read(), newline=False) # Print possible stderr at the end. self._msg('STDERR %s' % self.test_name) self._plain_msg(proc.stderr.read()) compat.setenv("PATH", path) # Restore current working directory os.chdir(old_wd) return proc.returncode
def get_system_path(): """Return the path that Windows will search for dlls.""" _bpath = [] if is_win: try: import win32api except ImportError: logger.warn("Cannot determine your Windows or System directories") logger.warn("Please add them to your PATH if .dlls are not found") logger.warn("or install http://sourceforge.net/projects/pywin32/") else: sysdir = win32api.GetSystemDirectory() sysdir2 = os.path.normpath(os.path.join(sysdir, '..', 'SYSTEM')) windir = win32api.GetWindowsDirectory() _bpath = [sysdir, sysdir2, windir] _bpath.extend(compat.getenv('PATH', '').split(os.pathsep)) return _bpath
def get_system_path(): """ Return the path that Windows will search for dlls. """ _bpath = [] try: import win32api sys_dir = win32api.GetSystemDirectory() except ImportError: sys_dir = os.path.normpath(os.path.join(get_windows_dir(), 'system32')) # Ensure C:\Windows\system32 and C:\Windows directories are # always present in PATH variable. # C:\Windows\system32 is valid even for 64bit Windows. Access do DLLs are # transparently redirected to C:\Windows\syswow64 for 64bit applactions. # http://msdn.microsoft.com/en-us/library/aa384187(v=vs.85).aspx _bpath = [sys_dir, get_windows_dir()] _bpath.extend(compat.getenv('PATH', '').split(os.pathsep)) return _bpath
def findLibrary(name): """ Look for a library in the system. Emulate the algorithm used by dlopen. `name`must include the prefix, e.g. ``libpython2.4.so`` """ assert is_unix, "Current implementation for Unix only (Linux, Solaris, AIX)" lib = None # Look in the LD_LIBRARY_PATH lp = compat.getenv('LD_LIBRARY_PATH', '') for path in lp.split(os.pathsep): libs = glob(os.path.join(path, name + '*')) if libs: lib = libs[0] break # Look in /etc/ld.so.cache if lib is None: expr = r'/[^\(\)\s]*%s\.[^\(\)\s]*' % re.escape(name) m = re.search(expr, compat.exec_command('/sbin/ldconfig', '-p')) if m: lib = m.group(0) # Look in the known safe paths if lib is None: paths = ['/lib', '/usr/lib'] if is_aix: paths.append('/opt/freeware/lib') for path in paths: libs = glob(os.path.join(path, name + '*')) if libs: lib = libs[0] break # give up :( if lib is None: return None # Resolve the file name into the soname dir = os.path.dirname(lib) return os.path.join(dir, getSoname(lib))
def __init__(self, test_name, verbose=False, report=False, with_crypto=False): # Use path separator '/' even on windows for test_name name. self.test_name = test_name.replace('\\', '/') self.verbose = verbose self.test_dir, self.test_file = os.path.split(self.test_name) runtests_basedir = compat.getenv('PYINSTALLER_RUNTESTS_WORKDIR') if runtests_basedir: runtests_basedir = os.path.join(runtests_basedir, self.test_dir) if not os.path.exists(runtests_basedir): os.makedirs(runtests_basedir) else: runtests_basedir = compat.getcwd() self._specdir = runtests_basedir self._distdir = os.path.join(runtests_basedir, 'dist') self._builddir = os.path.join(runtests_basedir, 'build') # For junit xml report some behavior is changed. # Especially redirecting sys.stdout. self.report = report # Build the test executable with bytecode encryption enabled. self.with_crypto = with_crypto
def __exec_python_cmd(cmd): """ Executes an externally spawned Python interpreter and returns anything that was emitted in the standard output as a single string. """ # Prepend PYTHONPATH with pathex pp = os.pathsep.join(PyInstaller.__pathex__) old_pp = compat.getenv('PYTHONPATH') if old_pp: pp = os.pathsep.join([old_pp, pp]) compat.setenv("PYTHONPATH", pp) try: try: txt = compat.exec_python(*cmd) except OSError, e: raise SystemExit("Execution failed: %s" % e) finally: if old_pp is not None: compat.setenv("PYTHONPATH", old_pp) else: compat.unsetenv("PYTHONPATH") return txt.strip()
# Note: Keep this variable as plain string so it could be updated automatically # when doing a release. __version__ = '4.5' # Absolute path of this package's directory. Save this early so all # submodules can use the absolute path. This is required e.g. if the # current directory changes prior to loading the hooks. PACKAGEPATH = os.path.abspath(os.path.dirname(__file__)) HOMEPATH = os.path.dirname(PACKAGEPATH) # Update __version__ as necessary. if os.path.exists(os.path.join(HOMEPATH, 'setup.py')): # PyInstaller is run directly from source without installation or # __version__ is called from 'setup.py' ... if compat.getenv('PYINSTALLER_DO_RELEASE') == '1': # Suppress the git revision when doing a release. pass elif 'sdist' not in sys.argv: # and 'setup.py' was not called with 'sdist' argument. # For creating source tarball we do not want git revision # in the filename. try: __version__ += get_repo_revision() except Exception: # Write to stderr because stdout is used for eval() statement # in some subprocesses. sys.stderr.write('WARN: failed to parse git revision') else: # PyInstaller was installed by `python setup.py install'. import pkg_resources
def findLibrary(name): """ Look for a library in the system. Emulate the algorithm used by dlopen. `name`must include the prefix, e.g. ``libpython2.4.so`` """ assert is_unix, ("Current implementation for Unix only (Linux, Solaris, " "AIX, FreeBSD)") lib = None # Look in the LD_LIBRARY_PATH according to platform. if is_aix: lp = compat.getenv('LIBPATH', '') elif is_darwin: lp = compat.getenv('DYLD_LIBRARY_PATH', '') else: lp = compat.getenv('LD_LIBRARY_PATH', '') for path in lp.split(os.pathsep): libs = glob(os.path.join(path, name + '*')) if libs: lib = libs[0] break # Look in /etc/ld.so.cache # TODO Look for ldconfig in /usr/sbin/ldconfig. /sbin is deprecated # in recent linux distributions. # Solaris does not have /sbin/ldconfig. Just check if this file exists. if lib is None and os.path.exists('/sbin/ldconfig'): expr = r'/[^\(\)\s]*%s\.[^\(\)\s]*' % re.escape(name) if is_freebsd: # This has a slightly different format than on linux, but the # regex still works. m = re.search(expr, compat.exec_command('/sbin/ldconfig', '-r')) else: m = re.search(expr, compat.exec_command('/sbin/ldconfig', '-p')) if m: lib = m.group(0) # Look in the known safe paths if lib is None: paths = [ '/lib', '/lib32', '/lib64', '/usr/lib', '/usr/lib32', '/usr/lib64' ] # On Debian/Ubuntu /usr/bin/python is linked statically with libpython. # Newer Debian/Ubuntu with multiarch support putsh the libpythonX.Y.so # To paths like /usr/lib/i386-linux-gnu/. try: import sysconfig # Module available only in Python 2.7. arch_subdir = sysconfig.get_config_var('multiarchsubdir') # Ignore if None is returned. if arch_subdir: arch_subdir = os.path.basename(arch_subdir) paths.extend([ os.path.join('/usr/lib', arch_subdir), os.path.join('/usr/lib32', arch_subdir), os.path.join('/usr/lib64', arch_subdir), ]) except ImportError: pass if is_aix: paths.append('/opt/freeware/lib') elif is_freebsd: paths.append('/usr/local/lib') for path in paths: libs = glob(os.path.join(path, name + '*')) if libs: lib = libs[0] break # give up :( if lib is None: return None # Resolve the file name into the soname if is_freebsd: # On FreeBSD objdump doesn't show SONAME, so we just return the lib # we've found return lib else: dir = os.path.dirname(lib) return os.path.join(dir, getSoname(lib))
def _resolveCtypesImports(cbinaries): """Completes ctypes BINARY entries for modules with their full path. """ from ctypes.util import find_library if is_unix: envvar = "LD_LIBRARY_PATH" elif is_darwin: envvar = "DYLD_LIBRARY_PATH" else: envvar = "PATH" def _setPaths(): path = os.pathsep.join(PyInstaller.__pathex__) old = compat.getenv(envvar) if old is not None: path = os.pathsep.join((path, old)) compat.setenv(envvar, path) return old def _restorePaths(old): if old is None: compat.unsetenv(envvar) else: compat.setenv(envvar, old) ret = [] # Try to locate the shared library on disk. This is done by # executing ctypes.utile.find_library prepending ImportTracker's # local paths to library search paths, then replaces original values. old = _setPaths() for cbin in cbinaries: # Ignore annoying warnings like: # 'W: library kernel32.dll required via ctypes not found' # 'W: library coredll.dll required via ctypes not found' if cbin in ['coredll.dll', 'kernel32.dll']: continue ext = os.path.splitext(cbin)[1] # On Windows, only .dll files can be loaded. if os.name == "nt" and ext.lower() in [".so", ".dylib"]: continue cpath = find_library(os.path.splitext(cbin)[0]) if is_unix: # CAVEAT: find_library() is not the correct function. Ctype's # documentation says that it is meant to resolve only the filename # (as a *compiler* does) not the full path. Anyway, it works well # enough on Windows and Mac. On Linux, we need to implement # more code to find out the full path. if cpath is None: cpath = cbin # "man ld.so" says that we should first search LD_LIBRARY_PATH # and then the ldcache for d in compat.getenv(envvar, '').split(os.pathsep): if os.path.isfile(os.path.join(d, cpath)): cpath = os.path.join(d, cpath) break else: text = compat.exec_command("/sbin/ldconfig", "-p") for L in text.strip().splitlines(): if cpath in L: cpath = L.split("=>", 1)[1].strip() assert os.path.isfile(cpath) break else: cpath = None if cpath is None: logger.warn("library %s required via ctypes not found", cbin) else: ret.append((cbin, cpath, "BINARY")) _restorePaths(old) return ret
is_py27 = compat.is_py27 is_win = compat.is_win is_cygwin = compat.is_cygwin is_darwin = compat.is_darwin is_linux = compat.is_linux is_solar = compat.is_solar is_aix = compat.is_aix is_unix = compat.is_unix HOMEPATH = os.path.abspath(os.path.dirname(os.path.dirname(__file__))) if is_win: CONFIGDIR = compat.getenv('APPDATA') if not CONFIGDIR: CONFIGDIR = os.path.expanduser('~\\Application Data') elif is_darwin: CONFIGDIR = os.path.expanduser('~/Library/Application Support') else: # According to XDG specification # http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html CONFIGDIR = compat.getenv('XDG_DATA_HOME') if not CONFIGDIR: CONFIGDIR = os.path.expanduser('~/.local/share') CONFIGDIR = os.path.join(CONFIGDIR, 'pyinstaller') DEFAULT_CONFIGFILE = os.path.join(CONFIGDIR, 'config.dat') PLATFORM = compat.system() + '-' + compat.architecture()
hid_list = [] else: urlpatterns = urls_module.urlpatterns hid_list = [urls_module.__name__] for pattern in urlpatterns: if isinstance(pattern, RegexURLPattern): hid_list.append(pattern.callback.__module__) elif isinstance(pattern, RegexURLResolver): hid_list += find_url_callbacks(pattern.urlconf_module) return hid_list from django.core.urlresolvers import RegexURLPattern, RegexURLResolver base_module_name = ".".join(compat.getenv("DJANGO_SETTINGS_MODULE", "settings").split(".")[:-1]) if base_module_name: base_module = __import__(base_module_name, {}, {}, ["urls"]) urls = base_module.urls else: import urls hiddenimports += find_url_callbacks(urls) # This print statement is then parsed and evaluated as Python code. print(hiddenimports) logger.debug('%r', sorted(set(hiddenimports)))
from PyInstaller.utils import icon, versioninfo except ImportError, detail: logger.info('... resource update unavailable - %s', detail) return test_exe = os.path.join(HOMEPATH, 'support', 'loader', PLATFORM, 'runw.exe') if not os.path.exists(test_exe): config['hasRsrcUpdate'] = 0 logger.error('... resource update unavailable - %s not found', test_exe) return # The test_exe may be read-only # make a writable copy and test using that rw_test_exe = os.path.join(compat.getenv('TEMP'), 'me_test_exe.tmp') shutil.copyfile(test_exe, rw_test_exe) try: hexe = win32api.BeginUpdateResource(rw_test_exe, 0) except: logger.info( '... resource update unavailable - win32api.BeginUpdateResource failed' ) else: win32api.EndUpdateResource(hexe, 1) config['hasRsrcUpdate'] = 1 logger.info('... resource update available') os.remove(rw_test_exe) def test_UPX(config, upx_dir):
def find_files(self, ignore_policies=True): """ Search shared and private assemblies and return a list of files. If any files are not found, return an empty list. IMPORTANT NOTE: For the purpose of getting the dependent assembly files of an executable, the publisher configuration (aka policy) should be ignored (which is the default). Setting ignore_policies=False is only useful to find out which files are actually loaded at runtime. """ # Shared Assemblies: # http://msdn.microsoft.com/en-us/library/aa375996%28VS.85%29.aspx # # Private Assemblies: # http://msdn.microsoft.com/en-us/library/aa375674%28VS.85%29.aspx # # Assembly Searching Sequence: # http://msdn.microsoft.com/en-us/library/aa374224%28VS.85%29.aspx # # NOTE: # Multilanguage User Interface (MUI) support not yet implemented files = [] languages = [] if self.language not in (None, "", "*", "neutral"): languages.append(self.getlanguage()) if "-" in self.language: # language-culture syntax, e.g. en-us # Add only the language part languages.append(self.language.split("-")[0]) if self.language not in ("en-us", "en"): languages.append("en-us") if self.language != "en": languages.append("en") languages.append(self.getlanguage("*")) winsxs = os.path.join(compat.getenv("SystemRoot"), "WinSxS") if not os.path.isdir(winsxs): logger.warn("No such dir %s", winsxs) manifests = os.path.join(winsxs, "Manifests") if not os.path.isdir(manifests): logger.warn("No such dir %s", manifests) if not ignore_policies and self.version: if sys.getwindowsversion() < (6, ): # Windows XP pcfiles = os.path.join(winsxs, "Policies") if not os.path.isdir(pcfiles): logger.warn("No such dir %s", pcfiles) else: # Vista or later pcfiles = manifests for language in languages: version = self.version # Search for publisher configuration if not ignore_policies and version: # Publisher Configuration (aka policy) # A publisher configuration file globally redirects # applications and assemblies having a dependence on one # version of a side-by-side assembly to use another version of # the same assembly. This enables applications and assemblies # to use the updated assembly without having to rebuild all of # the affected applications. # http://msdn.microsoft.com/en-us/library/aa375680%28VS.85%29.aspx # # Under Windows XP and 2003, policies are stored as # <version>.policy files inside # %SystemRoot%\WinSxS\Policies\<name> # Under Vista and later, policies are stored as # <name>.manifest files inside %SystemRoot%\winsxs\Manifests redirected = False if os.path.isdir(pcfiles): logger.info("Searching for publisher configuration %s ...", self.getpolicyid(True, language=language)) if sys.getwindowsversion() < (6, ): # Windows XP policies = os.path.join( pcfiles, self.getpolicyid(True, language=language) + ".policy") else: # Vista or later policies = os.path.join( pcfiles, self.getpolicyid(True, language=language) + ".manifest") for manifestpth in glob(policies): if not os.path.isfile(manifestpth): logger.warn("Not a file %s", manifestpth) continue logger.info("Found %s", manifestpth) try: policy = ManifestFromXMLFile(manifestpth) except Exception, exc: logger.error("Could not parse file %s", manifestpth) logger.exception(exc) else: logger.info("Checking publisher policy for " "binding redirects") for assembly in policy.dependentAssemblies: if (not assembly.same_id(self, True) or assembly.optional): continue for redirect in assembly.bindingRedirects: if logger.isEnabledFor(logging.INFO): old = "-".join([ ".".join([str(i) for i in part]) for part in redirect[0] ]) new = ".".join( [str(i) for i in redirect[1]]) logger.info( "Found redirect for " "version(s) %s -> %n", old, new) if (version >= redirect[0][0] and version <= redirect[0][-1] and version != redirect[1]): logger.info( "Applying redirect " "%s -> %s", ".".join([str(i) for i in version]), new) version = redirect[1] redirected = True if not redirected: logger.info("Publisher configuration not used") # Search for assemblies according to assembly searching sequence paths = [] if os.path.isdir(manifests): # Add winsxs search paths paths.extend( glob( os.path.join( manifests, self.getid(language=language, version=version) + "_*.manifest"))) if self.filename: # Add private assembly search paths dirnm = os.path.dirname(self.filename) if language in (LANGUAGE_NEUTRAL_NT5, LANGUAGE_NEUTRAL_NT6): for ext in (".dll", ".manifest"): paths.extend(glob(os.path.join(dirnm, self.name + ext))) paths.extend( glob( os.path.join(dirnm, self.name, self.name + ext))) else: for ext in (".dll", ".manifest"): paths.extend( glob(os.path.join(dirnm, language, self.name + ext))) for ext in (".dll", ".manifest"): paths.extend( glob( os.path.join(dirnm, language, self.name, self.name + ext))) logger.info("Searching for assembly %s ...", self.getid(language=language, version=version)) for manifestpth in paths: if not os.path.isfile(manifestpth): logger.warn("Not a file %s", manifestpth) continue assemblynm = os.path.basename(os.path.splitext(manifestpth)[0]) try: if manifestpth.endswith(".dll"): logger.info("Found manifest in %s", manifestpth) manifest = ManifestFromResFile(manifestpth, [1]) else: logger.info("Found manifest %s", manifestpth) manifest = ManifestFromXMLFile(manifestpth) except Exception, exc: logger.error("Could not parse manifest %s", manifestpth) logger.exception(exc) else: if manifestpth.startswith(winsxs): assemblydir = os.path.join(winsxs, assemblynm) if not os.path.isdir(assemblydir): logger.warn("No such dir %s", assemblydir) logger.warn("Assembly incomplete") return [] else: assemblydir = os.path.dirname(manifestpth) files.append(manifestpth) for file_ in self.files or manifest.files: fn = file_.find(assemblydir) if fn: files.append(fn) else: # If any of our files does not exist, # the assembly is incomplete logger.warn("Assembly incomplete") return [] return files
def get_winsxs_dir(cls): return os.path.join(compat.getenv("SystemRoot"), "WinSxS")
def findLibrary(name): """ Look for a library in the system. Emulate the algorithm used by dlopen. `name`must include the prefix, e.g. ``libpython2.4.so`` """ assert compat.is_unix, \ "Current implementation for Unix only (Linux, Solaris, AIX, FreeBSD)" lib = None # Look in the LD_LIBRARY_PATH according to platform. if compat.is_aix: lp = compat.getenv('LIBPATH', '') elif compat.is_darwin: lp = compat.getenv('DYLD_LIBRARY_PATH', '') else: lp = compat.getenv('LD_LIBRARY_PATH', '') for path in lp.split(os.pathsep): libs = glob(os.path.join(path, name + '*')) if libs: lib = libs[0] break # Look in /etc/ld.so.cache # Solaris does not have /sbin/ldconfig. Just check if this file exists. if lib is None: utils.load_ldconfig_cache() lib = utils.LDCONFIG_CACHE.get(name) if lib: assert os.path.isfile(lib) # Look in the known safe paths. if lib is None: # Architecture independent locations. paths = ['/lib', '/usr/lib'] # Architecture dependent locations. if compat.architecture == '32bit': paths.extend(['/lib32', '/usr/lib32', '/usr/lib/i386-linux-gnu']) else: paths.extend(['/lib64', '/usr/lib64', '/usr/lib/x86_64-linux-gnu']) # On Debian/Ubuntu /usr/bin/python is linked statically with libpython. # Newer Debian/Ubuntu with multiarch support putsh the libpythonX.Y.so # To paths like /usr/lib/i386-linux-gnu/. try: # Module available only in Python 2.7+ import sysconfig # 'multiarchsubdir' works on Debian/Ubuntu only in Python 2.7 and 3.3+. arch_subdir = sysconfig.get_config_var('multiarchsubdir') # Ignore if None is returned. if arch_subdir: arch_subdir = os.path.basename(arch_subdir) paths.append(os.path.join('/usr/lib', arch_subdir)) else: logger.debug('Multiarch directory not detected.') except ImportError: logger.debug('Multiarch directory not detected.') if compat.is_aix: paths.append('/opt/freeware/lib') elif compat.is_hpux: if compat.architecture == '32bit': paths.append('/usr/local/lib/hpux32') else: paths.append('/usr/local/lib/hpux64') elif compat.is_freebsd or compat.is_openbsd: paths.append('/usr/local/lib') for path in paths: libs = glob(os.path.join(path, name + '*')) if libs: lib = libs[0] break # give up :( if lib is None: return None # Resolve the file name into the soname if compat.is_freebsd or compat.is_aix or compat.is_openbsd: # On FreeBSD objdump doesn't show SONAME, # and on AIX objdump does not exist, # so we just return the lib we've found return lib else: dir = os.path.dirname(lib) return os.path.join(dir, _get_so_name(lib))