📄 __init__.py
字号:
import reimport os.pathimport datetimeimport sysfrom distutils import sysconfigfrom SCons.Builder import Builderfrom SCons.Action import Actionfrom SCons.Options import Optionsfrom SCons.Environment import Environment# Import module configuration logicfrom _module import *import pkgconfigimport Customizefrom Errors import CommandError, PkgconfigGeneratorMissing_defaultEnv=Nonedef setDefaultEnv(env): global _defaultEnv _defaultEnv=envlog_file = Nonedef logOpen(env): global log_file if env.has_key('SSLOG'): if env['SSLOG'] == '': log_file = sys.stdout elif log_file == None: log_file = open(env['SSLOG'], 'w+') elif log_file.closed: log_file = open(env['SSLOG'], 'a+')def log(s): if log_file is not None: log_file.write("%s\n" % s)def log2(s): if log_file is not None: calling_func_name = sys._getframe(1).f_code.co_name log_file.write("%s: %s\n" % (calling_func_name,s))def logDate(): log(datetime.datetime.now())def logClose(): if log_file != sys.stdout and log_file is not None: log_file.close()def runCommand(command, args, captureOutput=True): """ Run command, returning its output on the stdout and stderr streams. If the command exits with a non-zero value, CommandError is raised. @param command: The name of the command @param args: The arguments to the command, either as an explicit sequence or as a whitespace delimited string. @return: A pair of strings, containing the command's output on stdout and stderr, respectively. """ if isinstance(args, basestring): args = args.split() cl = "%s %s" % (command, " ".join(args)) from subprocess import Popen, PIPE p = Popen(cl.split(), stdout=PIPE, stderr=PIPE, bufsize=-1) r = p.wait() out, err = p.communicate() if r: raise CommandError(cl, r, err.strip()) if captureOutput: return out.strip(), err.strip()def rsplit(toSplit, sub, max=None): s = toSplit[::-1] # Reverse string if max == None: l = s.split(sub) else: l = s.split(sub, max) l.reverse() # Reverse list return [s[::-1] for s in l] # Reverse list entriesdef oldrsplit(toSplit, sub, max): """ str.rsplit seems to have been introduced in 2.4 :( """ l = [] i = 0 while i < max: idx = toSplit.rfind(sub) if idx != -1: toSplit, splitOff = toSplit[:idx], toSplit[idx + len(sub):] l.insert(0, splitOff) i = i + 1 else: break l.insert(0, toSplit) return l_SshHost = "gogmagog.simula.no"if "SUDO_USER" in os.environ: # Use real user in case PyCC is install with 'sudo scons install' _SshHost = "%s@%s" % (os.environ["SUDO_USER"], _SshHost)_SshDir = "/srl/phulius/pycc"def sshList(path): """ Recursively list contents of directory on SSH server. @return: List of file paths relative to directory. """ out, err = runCommand("ssh", [_SshHost, "ls", "-R", "%s/%s" % (_SshDir, path)]) dirs = {} curDir = None for l in out.splitlines(): l = l.strip() if not l: continue l = l.replace(_SshDir + "/data/", "") if l[-1] == ":": dname = l[:-1] if dname == _SshDir + "/data": continue if dname[0] == "/": dname = l[1:] curDir = dname dirs[curDir] = [] else: if curDir is not None: dirs[curDir].append(l) paths = [] for dname, entries in dirs.items(): for e in entries: path = os.path.join(dname, e) if not path in dirs: paths.append(path) return pathsdef _sshCopy(target, source, env): env = env.Copy() if os.environ.has_key("SSH_AGENT_PID"): env["ENV"]["SSH_AGENT_PID"] = os.environ["SSH_AGENT_PID"] if os.environ.has_key("SSH_AUTH_SOCK"): env["ENV"]["SSH_AUTH_SOCK"] = os.environ["SSH_AUTH_SOCK"] for tgt in target: tgt = str(tgt) env.Execute("scp -r %s:%s/%s %s" % (_SshHost, _SshDir, tgt, tgt))def _sshDesc(target, source, env): tgts = [str(t) for t in target] return "Copying from SSH repository: %s" % ", ".join(tgts)sshCopy = Builder(action=Action(_sshCopy, _sshDesc))class Configure(object): """ Replace the standard SCons Configure method. The standard SCons Configure method is somewhat weak, in particular with regard to cleaning up after previous builds. When cleaning you normally don't want to reconfigure, you just want to clean the targets from the previous build. You may still want to get at configuration parameters however, since they may affect which targets are built (e.g. a module is only built in the presence of an external library). This class caches configuration values between builds, even command-line options, so that the build configuration when cleaning mirrors that when building. """ def __init__(self, env, arguments, options=[], customTests={}): """ @param env: SCons environment @param arguments: SCons command-line arguments (ARGUMENTS) @param options: Command-line options. """ useCache = env.GetOption("clean") # Prefer cached values if cleaning self._conf = env.Configure(log_file=os.path.join("scons", "configure.log"), custom_tests=\ customTests) for n, f in customTests.items(): setattr(self, n, getattr(self._conf, n)) self._oldCache, self._newCache = {}, {} self._cachePath = os.path.abspath(os.path.join("scons", "configure.cache")) if useCache and os.path.exists(self._cachePath): try: f = open(self._cachePath) context = None for l in f: m = re.match(r"(.+):", l) if m: context = m.group(1) self._oldCache[context] = {} continue if context is None: continue m = re.match("(.+) = (.+)", l) try: k, v = m.groups() except: continue self._oldCache[context][k] = v finally: f.close() args = arguments.copy() optsCache = os.path.join("scons", "options.cache") # Save options between runs in this cache if useCache: # Then ignore new values for o in options: if o[0] in args: del args[o[0]] opts = Options(optsCache, args=args) opts.AddOptions(*options) opts.Update(env) # Cache options if asked to cacheOptions = env.get("cacheOptions", False) if cacheOptions: del env["cacheOptions"] # Don't store this value # Wan't to make the 'veryClean' a on-off option, so we don't store veryCleanOption = env.get("veryClean", False) if veryCleanOption: del env["veryClean"] # Don't store the veryClean option opts.Save(optsCache, env) # Restore env["cacheOptions"] = cacheOptions if veryCleanOption: env["veryClean"] = veryCleanOption env.Help(opts.GenerateHelpText(env)) def checkCxxHeader(self, header, include_quotes='""'): """ Look for C++ header. @param header: The header to look for. This may be a sequence, in which case the preceding items are headers to be included before the required header. """ ctxt = "checkCxxHeader" try: r = self._oldCache[ctxt][str(header)] except KeyError: r = self._conf.CheckCXXHeader(header, include_quotes) if not ctxt in self._newCache: self._newCache[ctxt] = {} self._newCache[ctxt][str(header)] = r return r def checkLibWithHeader(self, lib, header, language="C", call=None): ctxt = "checkLibWithHeader" try: r = self._oldCache[ctxt][str(lib)] except KeyError: kwds = {} if call is not None: kwds["call"] = call r = self._conf.CheckLibWithHeader(lib, header, language, **kwds) if not ctxt in self._newCache: self._newCache[ctxt] = {} self._newCache[ctxt][str(lib)] = r return r def finish(self): """ Update configuration cache """ f = open(self._cachePath, "w") try: for ctxt, d in self._newCache.items(): f.write("%s:\n" % ctxt) for k, v in d.items(): f.write("%s = %s\n" % (k, v)) finally: f.close()## Gruff moved over from SConstruct## should be cleaned up as well.def setConstants(_dataLevelsBeneath, _DataDirRel): def setConstants(env, target, source): """Change the constants in target (from source) to reflect the location of the installed software.""" tgt = str(target[0]) src = str(source[0]) f = open(src) txt = f.readlines() f.close() if not os.path.isdir(os.path.dirname(tgt)): os.makedirs(os.path.dirname(tgt)) f = open(tgt, "w") try: found0 = found1 = False for l in txt: if l.startswith("_levelsBeneath = "): l = "_levelsBeneath = %d\n" % _dataLevelsBeneath found0 = True elif l.startswith("_dataDir ="): l = '_dataDir = "%s"\n' % _DataDirRel found1 = True f.write("%s" % l) if not found0 or not found1: raise Exception, "Failed to modify path to data directory in pycc.common" finally: f.close() return setConstants def pathValidator(key, val, env): """ Silence SCons with regard to non-existent paths """ passdef PathOption(dir, explanation, default): """ Define PathOption that works the same across old and new (0.96.9*) SCons, i.e. new SCons adds a restrictive path validator by default. Used when setting commandline options in the Configure object. """ return (dir, "%s ( /path/to/%s )" % (explanation, dir), default, pathValidator)def defaultCxxCompiler(): """Read the CXX environment variable if set""" if os.environ.has_key("CXX"): return os.environ["CXX"] else: return Nonedef defaultPythonLib(prefix=None, plat_specific=False): python_lib = sysconfig.get_python_lib(prefix=prefix, plat_specific=plat_specific) if not prefix is None: if not python_lib.startswith(prefix): python_lib = os.path.join(prefix,"lib","python" + sysconfig.get_python_version(),"site-packages") return python_libdef defaultFortranCompiler(): """Read the FORTRAN environment variable if set""" if os.environ.has_key("FORTRAN"): return os.environ["FORTRAN"] else: return Nonedef resolvePackages(candidates, defaultPackages): """Produce a complete list of packages. If a package in candidates in the basename (in front of the version-dash) match a basename among the defaultPackages, use the version from the candidates. Candidates that does not match anything in the defaultPackages set are appended to the list of packages. """ for p in defaultPackages: base = p[:p.find('-')] delIndex = -1 for c in candidates: c_base = c[:c.find('-')] if c_base == base: defaultPackages[defaultPackages.index(p)] = c delIndex = candidates.index(c) break if delIndex != -1: del(candidates[delIndex]) defaultPackages += candidates if defaultPackages.count(''): defaultPackages.remove('') return defaultPackagesdef gen_runTests(dataHash): def _runTests(target, source, env): """Target 'runtests' installs everything and then executes runtests.py in the tests directory, with the environment set up as necessary""" ldPath, pyPath = [], [os.path.join(os.path.abspath("site-packages"), "pycc")] print pyPath for f in dataHash["shlibs"]: dpath = os.path.dirname(f.abspath) if dpath not in ldPath: ldPath.append(dpath)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -