⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pkgconfig.py

📁 利用C
💻 PY
字号:
## Various functionality for handling pkg-config in a scons based build.## The "public interface" here is the 'generate' method and the 'PkgConfig' # class. The 'generate' method can be used to generate a pkg-config file # based on a template. Within pycc this is used to generate a suiteable# pkg-config file for the version of pycc currently build. # The 'PkgConfig' class is used to read pkg-config files using the pkg-config# command, and output the result suitable for inclusion in scons build # environments.import os, os.path, re, sys# imports from the global 'SCons'from SCons import Builder, Action# import the local 'scons'import simula_scons as sconsfrom simula_scons.Errors import CommandError, PkgconfigError, PkgconfigMissing, PkgconfigGeneratorsMissing, PkgconfigGeneratorMissingdef generate_pcFunc(replaceDict):  def _pcFunc(target, source, env):    """ Fill in .pc template. """    f = file(str(source[0]))    try: lines = f.readlines()    finally: f.close()    includeDir = env["includeDir"]    libDir = env["libDir"]    prefix = env["prefix"]    f = file(str(target[0]), "w")    # compiler:    # if env["CXX"] is set (are we sure we always use C++ - probably not...)    if env.has_key("CXX") and env["CXX"] != None:      compiler=env["CXX"]    else:      compiler=""    try:      includeDir = includeDir.replace("$prefix", "${prefix}")      libDir = libDir.replace("$prefix", "${exec_prefix}")      header = ["prefix=%s\n" % prefix, "exec_prefix=${prefix}\n", "includedir=%s\n" % includeDir, \              "libdir=%s\n" % libDir, "compiler=%s\n" % compiler]      for i in range(len(lines)):          if not lines[i].strip():              break      body = lines[i:]      # Might need to susbstitute things in the body, e.g. dependencies.      if replaceDict is not None:        for item in replaceDict:          # find line(s) in body that match the substitution key:          replLines = [ l for l in body if "@"+item+"@" in l ]          # replace the key with the replaceDict item, and feed into the body          # We support multiple occurences of a string, although that should be           # rare:          for l in replLines:            body[body.index(l)] = l.replace("@"+item+"@", replaceDict[item])      f.writelines(header + body)    finally:      f.close()  return _pcFuncdef _strFunc(target, source, env):    return "Building %s from %s" % (target[0], ", ".join([str(s) for s in source]))  def generate(env, replace=None):    """Place a template-based generator for pkg-config files in the BUILDERS."""    # we might need to pass in things to replace in the pkg-config, we    # can use the replace as a dict for that. The keys will be things to    # replace in the template and the values will be the replacements.    #     # We need to access the replace-dict inside _pcFunc, hence we must turn the     # _pcFunc into a closure.    _pcFunc = generate_pcFunc(replace)    env["BUILDERS"]["PkgConfigGenerator"] = Builder.Builder(action={".in": Action.Action(_pcFunc, \            strfunction=_strFunc)}, suffix="")def get_packgen(package):  # Try to import and run the right pkgconfig generator:  try:    packgen = __import__("simula_scons.pkgconfiggenerators",globals(),locals())  except:    raise PkgconfigGeneratorsMissing()  # Generate the pkgconfig file:  # There should probably be a second try/except around the import of the   # pkgconfig generator for the specific module.  ns = {}  try:    exec "from simula_scons.pkgconfiggenerators import %s" % (package.split('-',1)[0]) in ns  except:    raise PkgconfigGeneratorMissing(package)  packgen = ns.get("%s" % (package.split('-',1)[0]))  return packgenclass PkgConfig(object):    """Handling of pkg-config files.       Whenever pkg-config file must be read to handle a dependency, an        instance of this class will be created.    """    def __init__(self, package, env):            # If the PKG_CONFIG_PATH variable is empty, we are probably on       # deep water here.      # I'll create a suiteable directory and set as PKG_CONFIG_PATH       # right away.      # Set up a temporary place for pkgconfig files.       pkgconfdir = os.path.join(env.Dir("#scons").abspath,"pkgconfig")      # set this is SCONS_PKG_CONFIG_DIR, which should be the place the       # pkgconfiggenerators put pc-files during build      os.environ["SCONS_PKG_CONFIG_DIR"] = pkgconfdir      # Make sure that the directory exist:      if not os.path.isdir(pkgconfdir):        os.makedirs(pkgconfdir)            if not os.environ.has_key("PKG_CONFIG_PATH") or os.environ["PKG_CONFIG_PATH"] == "":        os.environ["PKG_CONFIG_PATH"]=pkgconfdir        #print "\n** Warning: Added %s \n    as PKG_CONFIG_PATH **" % (pkgconfdir)      elif os.environ.has_key("PKG_CONFIG_PATH") and pkgconfdir not in os.environ["PKG_CONFIG_PATH"]:        pkgConfPath = os.environ["PKG_CONFIG_PATH"].split(os.path.pathsep)        pkgConfPath.append(pkgconfdir)        os.environ["PKG_CONFIG_PATH"] = os.path.pathsep.join(pkgConfPath)        #print "\n** Warning: Added %s \n    in PKG_CONFIG_PATH **" % (pkgconfdir)            self.package = package      self.env = env      try:         scons.runCommand("pkg-config", ["--exists", self.package])        print "yes"      except CommandError:        print "no (pkg-config file not found)"        print " Trying to generate pkg-config file for %s..." % (self.package),        # Construct pkgconfig-file        packgen = get_packgen(package)#        # Try to import and run the right pkgconfig generator:#        try:#          packgen = __import__("simula_scons.pkgconfiggenerators",globals(),locals())#        except:#          raise PkgconfigGeneratorsMissing()#        # Generate the pkgconfig file:#        # There should probably be a second try/except around the import of the #        # pkgconfig generator for the specific module.#        ns = {}#        exec "from simula_scons.pkgconfiggenerators import %s" % (package.split('-',1)[0]) in ns#        packgen = ns.get("%s" % (package.split('-',1)[0]))        packgen.generatePkgConf(sconsEnv=env)    def _pkgconfig(self, param):        #os.environ["PKG_CONFIG_ALLOW_SYSTEM_CFLAGS"] = "1"        #os.environ["PKG_CONFIG_ALLOW_SYSTEM_LIBS"] = "1"        try: out, err = scons.runCommand("pkg-config", [param, self.package])        except CommandError, err:            raise PkgconfigError(self.package, "Error reported by pkg-config: `%s'" % err.stderr)        return out    def version(self):        """Find out what version the package think it is"""        return self._pkgconfig("--modversion")    def includeDirs(self):        out = self._pkgconfig("--cflags-only-I")        dirs = []        opts = out.split()        for o in opts:            dirs.append(o[2:])        return dirs    def libDirs(self):        out = self._pkgconfig("--libs-only-L")        dirs = []        opts = out.split()        for o in opts:            dirs.append(o[2:])        return dirs    def linkOpts(self):      link_opts = self._pkgconfig("--libs-only-other").split()      return link_opts    def compiler(self):      # If the compiler, and maybe the compilertype variable is set, read and       # return as a tuple. If I can't figure out the compilertype, I use None      # to denote 'unknown'      compiler = self._pkgconfig("--variable=compiler")      if compiler == "":        return None      else:        return compiler    def frameworks(self):        out = self._pkgconfig("--libs")        fw = re.findall(r"-framework (\S+)",out)        return fw    def libs(self):        """return a set of libraries for lib.            On Darwin (MacOSX) a tuple with libraries and frameworks is returned        """        out = self._pkgconfig("--libs-only-l")        libs = []        opts = out.split()        for o in opts:            libs.append(o[2:])        if self.env["PLATFORM"] == "darwin":            return (libs, self.frameworks())        return libs, []    def cflags(self):      return self._pkgconfig("--cflags")    def ldflags(self):      return self._pkgconfig("--libs")

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -