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:])