github.com/hwaf/hwaf@v0.0.0-20140814122253-5465f73b20f1/py-hwaftools/orch/pkgconf.py (about)

     1  #!/usr/bin/env python
     2  '''
     3  Package specific interpretation layered on deconf.
     4  '''
     5  
     6  import os
     7      
     8  from . import deconf
     9  from .util import check_output, CalledProcessError, update_if, string2list
    10  from . import features as featmod
    11  from . import ups
    12  from . import rootsys
    13  
    14  def ncpus():
    15      try:
    16          import psutil
    17          return psutil.NUM_CPUS
    18      except ImportError:
    19          pass
    20  
    21      try:
    22          import multiprocessing
    23          return multiprocessing.cpu_count()
    24      except ImportError:
    25          pass
    26      except NotImplementedError:
    27          pass
    28  
    29      return 1
    30  
    31  def host_description():
    32      '''
    33      Return a dictionary of host description variables.
    34      '''
    35      ret = {}
    36      uname_fields = ['kernelname', 'hostname', 
    37                      'kernelversion', 'vendorstring', 'machine']
    38      uname = os.uname()
    39      for k,v in zip(uname_fields, uname):
    40          ret[k] = v
    41      platform = '{kernelname}-{machine}'.format(**ret)
    42      ret['platform'] = platform
    43      ret['ups_flavor'] = ups.flavor()
    44      ret['root_config_arch'] = rootsys.arch()
    45  
    46      bits = '32'
    47      libbits = 'lib'
    48      if uname[-1] in ['x86_64']: # fixme: mac os x?
    49          bits = '64'
    50          libbits = 'lib64'
    51      ret['bits'] = bits
    52      ret['libbits'] = libbits
    53      ret['gcc_dumpversion'] = check_output(['gcc','-dumpversion']).strip()
    54      ret['gcc_dumpmachine'] = check_output(['gcc','-dumpmachine']).strip()
    55  
    56      try:
    57          ma = check_output(
    58              ['gcc','-print-multiarch'],    # debian-specific
    59              stderr=open('/dev/null', 'w')
    60              ).strip()
    61      except CalledProcessError:
    62          ma = ""
    63      ret['gcc_multiarch'] = ma
    64      if 'darwin' in ret['kernelname'].lower():
    65          libc_version = ret['kernelversion'] # FIXME: something better on Mac ?
    66          ret['ld_soname_option'] = 'install_name'
    67          ret['soext'] = 'dylib'
    68      else:
    69          libc_version = check_output(['ldd','--version']).split(b'\n')[0].split()[-1]
    70          ret['ld_soname_option'] = 'soname'
    71          ret['soext'] = 'so'
    72      ret['libc_version'] = libc_version
    73      ret['NCPUS'] = str(ncpus())
    74          
    75      return ret
    76  
    77  
    78  class PkgFormatter(object):
    79      def __init__(self, **kwds):
    80          self.vars = dict()
    81          self.vars.update(kwds)
    82  
    83      def __call__(self, string, **kwds):
    84          if not string: return string
    85          vars = dict(self.vars)
    86          vars.update(kwds)
    87          try:
    88              ret = string.format(**vars)
    89          except ValueError:
    90              print ("%s" % string)
    91              raise
    92          return ret
    93  
    94  def fold_in_feature_defaults(suite, formatter = None, **kwds):
    95      # fold in feature defaults
    96      for group in suite['groups']:
    97          new_packages = list()
    98          for package in group['packages']:
    99              featlist = string2list(package.get('features'))
   100              featcfg = featmod.defaults(featlist)
   101              package = update_if(featcfg, None, **package)            
   102              new_packages.append(package)
   103          group['packages'] = new_packages
   104  
   105      if not formatter:
   106          formatter = PkgFormatter()
   107      suite = deconf.format_any(suite, formatter=formatter, **kwds)
   108      return suite
   109  
   110  def munge_package(package):
   111      '''
   112      Put some computed values into the package's dict
   113      '''
   114      hd = host_description()
   115      for k,v in hd.items():
   116          package.setdefault(k,v)
   117  
   118      tags = package.get('tags') or ''
   119      tags = [x.strip() for x in tags.split(',')]
   120      package.setdefault('tagsdashed',  '-'.join(tags))
   121      package.setdefault('tagsunderscore', '_'.join(tags))
   122  
   123      version = package.get('version')
   124      if version:
   125          version = version.format(**package)
   126          package.setdefault('version_2digit', '.'.join(version.split('.')[:2]))
   127          package.setdefault('version_underscore', version.replace('.','_'))
   128          package.setdefault('version_dashed', version.replace('.','-'))
   129          package.setdefault('version_nodots', version.replace('.',''))
   130  
   131  
   132      for sysdir in 'control urlfile download patch source'.split():
   133          package.setdefault('%s_dir' % sysdir, sysdir + 's')
   134      package.setdefault('install_dir', '{PREFIX}')
   135      package.setdefault('build_dir', 'builds/{package}-{version}')
   136  
   137      dest_install_dir = package.get('dest_install_dir') or package.get('install_dir')
   138      package['dest_install_dir'] = dest_install_dir
   139  
   140  def fold_in_worch_values(suite, formatter, **kwds):
   141      for group in suite['groups']:
   142          for package in group['packages']:
   143              munge_package(package)
   144      if not formatter:
   145          formatter = PkgFormatter()
   146      suite = deconf.format_any(suite, formatter=formatter, **kwds)
   147      return suite
   148  
   149  def fold_in_package_vars(suite, formatter, **kwds):
   150      package_vars = dict()
   151  
   152      for group in suite['groups']:
   153          for package in group['packages']:
   154  #            munge_package(package)
   155              pkgname = package['package']
   156  
   157              # make uber dictionary with every package's variables
   158              # prefixed by the package name
   159              for k,v in package.items():
   160                  p_name = '%s_%s'%(pkgname,k)
   161                  package_vars[p_name] = v
   162  
   163      for group in suite['groups']:
   164          new_packages = list()
   165          for package in group['packages']:
   166              package = update_if(package_vars, None, **package)
   167              new_packages.append(package)
   168          group['packages'] = new_packages
   169  
   170      if not formatter:
   171          formatter = PkgFormatter()
   172      suite = deconf.format_any(suite, formatter=formatter, **kwds)
   173      return suite
   174  
   175  def load(filename, start='start', formatter = None, **kwds):
   176  
   177      # load in initial configuration but delay formatting
   178      return deconf.load(filename, start=start, formatter=formatter, **kwds)
   179  
   180  def fold_in(suite, formatter = None, **kwds):
   181  
   182      suite = fold_in_worch_values(suite, formatter, **kwds)
   183      suite = fold_in_feature_defaults(suite, formatter, **kwds)
   184      suite = fold_in_package_vars(suite, formatter, **kwds)
   185      
   186      return suite
   187  
   188  def dump_suite(suite):
   189      from pprint import PrettyPrinter
   190      pp = PrettyPrinter(indent=2)
   191      pp.pprint(suite)
   192  
   193  
   194  
   195  # testing
   196  
   197  
   198  def dump(filename, start='start', formatter=None):
   199      from pprint import PrettyPrinter
   200      pp = PrettyPrinter(indent=2)
   201  
   202      if not formatter:
   203          prefix ='/tmp/simple'
   204          formatter = PkgFormatter(prefix=prefix, PREFIX=prefix)
   205      data = load(filename, start=start, formatter=formatter)
   206  
   207      print ('Starting from "%s"' % start)
   208      pp.pprint(data)
   209  
   210  if '__main__' == __name__:
   211      import sys
   212      dump(sys.argv[1:])