diff options
Diffstat (limited to 'scripts/lib/recipetool/create.py')
| -rw-r--r-- | scripts/lib/recipetool/create.py | 137 |
1 files changed, 136 insertions, 1 deletions
diff --git a/scripts/lib/recipetool/create.py b/scripts/lib/recipetool/create.py index 1218a7d284..dab917faac 100644 --- a/scripts/lib/recipetool/create.py +++ b/scripts/lib/recipetool/create.py | |||
| @@ -21,6 +21,7 @@ import argparse | |||
| 21 | import glob | 21 | import glob |
| 22 | import fnmatch | 22 | import fnmatch |
| 23 | import re | 23 | import re |
| 24 | import json | ||
| 24 | import logging | 25 | import logging |
| 25 | import scriptutils | 26 | import scriptutils |
| 26 | import urlparse | 27 | import urlparse |
| @@ -39,7 +40,73 @@ def tinfoil_init(instance): | |||
| 39 | global tinfoil | 40 | global tinfoil |
| 40 | tinfoil = instance | 41 | tinfoil = instance |
| 41 | 42 | ||
| 42 | class RecipeHandler(): | 43 | class RecipeHandler(object): |
| 44 | recipelibmap = {} | ||
| 45 | recipeheadermap = {} | ||
| 46 | |||
| 47 | @staticmethod | ||
| 48 | def load_libmap(d): | ||
| 49 | '''Load library->recipe mapping''' | ||
| 50 | import oe.package | ||
| 51 | |||
| 52 | if RecipeHandler.recipelibmap: | ||
| 53 | return | ||
| 54 | # First build up library->package mapping | ||
| 55 | shlib_providers = oe.package.read_shlib_providers(d) | ||
| 56 | libdir = d.getVar('libdir', True) | ||
| 57 | base_libdir = d.getVar('base_libdir', True) | ||
| 58 | libpaths = list(set([base_libdir, libdir])) | ||
| 59 | libname_re = re.compile('^lib(.+)\.so.*$') | ||
| 60 | pkglibmap = {} | ||
| 61 | for lib, item in shlib_providers.iteritems(): | ||
| 62 | for path, pkg in item.iteritems(): | ||
| 63 | if path in libpaths: | ||
| 64 | res = libname_re.match(lib) | ||
| 65 | if res: | ||
| 66 | libname = res.group(1) | ||
| 67 | if not libname in pkglibmap: | ||
| 68 | pkglibmap[libname] = pkg[0] | ||
| 69 | else: | ||
| 70 | logger.debug('unable to extract library name from %s' % lib) | ||
| 71 | |||
| 72 | # Now turn it into a library->recipe mapping | ||
| 73 | pkgdata_dir = d.getVar('PKGDATA_DIR', True) | ||
| 74 | for libname, pkg in pkglibmap.iteritems(): | ||
| 75 | try: | ||
| 76 | with open(os.path.join(pkgdata_dir, 'runtime', pkg)) as f: | ||
| 77 | for line in f: | ||
| 78 | if line.startswith('PN:'): | ||
| 79 | RecipeHandler.recipelibmap[libname] = line.split(':', 1)[-1].strip() | ||
| 80 | break | ||
| 81 | except IOError as ioe: | ||
| 82 | if ioe.errno == 2: | ||
| 83 | logger.warn('unable to find a pkgdata file for package %s' % pkg) | ||
| 84 | else: | ||
| 85 | raise | ||
| 86 | |||
| 87 | @staticmethod | ||
| 88 | def load_headermap(d): | ||
| 89 | '''Build up lib headerfile->recipe mapping''' | ||
| 90 | if RecipeHandler.recipeheadermap: | ||
| 91 | return | ||
| 92 | includedir = d.getVar('includedir', True) | ||
| 93 | for pkg in glob.glob(os.path.join(pkgdata_dir, 'runtime', '*-dev')): | ||
| 94 | with open(os.path.join(pkgdata_dir, 'runtime', pkg)) as f: | ||
| 95 | pn = None | ||
| 96 | headers = [] | ||
| 97 | for line in f: | ||
| 98 | if line.startswith('PN:'): | ||
| 99 | pn = line.split(':', 1)[-1].strip() | ||
| 100 | elif line.startswith('FILES_INFO:'): | ||
| 101 | val = line.split(':', 1)[1].strip() | ||
| 102 | dictval = json.loads(val) | ||
| 103 | for fullpth in sorted(dictval): | ||
| 104 | if fullpth.startswith(includedir) and fullpth.endswith('.h'): | ||
| 105 | headers.append(os.path.relpath(fullpth, includedir)) | ||
| 106 | if pn and headers: | ||
| 107 | for header in headers: | ||
| 108 | RecipeHandler.recipeheadermap[header] = pn | ||
| 109 | |||
| 43 | @staticmethod | 110 | @staticmethod |
| 44 | def checkfiles(path, speclist, recursive=False): | 111 | def checkfiles(path, speclist, recursive=False): |
| 45 | results = [] | 112 | results = [] |
| @@ -54,6 +121,74 @@ class RecipeHandler(): | |||
| 54 | results.extend(glob.glob(os.path.join(path, spec))) | 121 | results.extend(glob.glob(os.path.join(path, spec))) |
| 55 | return results | 122 | return results |
| 56 | 123 | ||
| 124 | @staticmethod | ||
| 125 | def handle_depends(libdeps, pcdeps, deps, outlines, values, d): | ||
| 126 | if pcdeps: | ||
| 127 | recipemap = read_pkgconfig_provides(d) | ||
| 128 | if libdeps: | ||
| 129 | RecipeHandler.load_libmap(d) | ||
| 130 | |||
| 131 | ignorelibs = ['socket'] | ||
| 132 | ignoredeps = ['gcc-runtime', 'glibc', 'uclibc', 'musl', 'tar-native', 'binutils-native'] | ||
| 133 | |||
| 134 | unmappedpc = [] | ||
| 135 | pcdeps = list(set(pcdeps)) | ||
| 136 | for pcdep in pcdeps: | ||
| 137 | if isinstance(pcdep, basestring): | ||
| 138 | recipe = recipemap.get(pcdep, None) | ||
| 139 | if recipe: | ||
| 140 | deps.append(recipe) | ||
| 141 | else: | ||
| 142 | if not pcdep.startswith('$'): | ||
| 143 | unmappedpc.append(pcdep) | ||
| 144 | else: | ||
| 145 | for item in pcdep: | ||
| 146 | recipe = recipemap.get(pcdep, None) | ||
| 147 | if recipe: | ||
| 148 | deps.append(recipe) | ||
| 149 | break | ||
| 150 | else: | ||
| 151 | unmappedpc.append('(%s)' % ' or '.join(pcdep)) | ||
| 152 | |||
| 153 | unmappedlibs = [] | ||
| 154 | for libdep in libdeps: | ||
| 155 | if isinstance(libdep, tuple): | ||
| 156 | lib, header = libdep | ||
| 157 | else: | ||
| 158 | lib = libdep | ||
| 159 | header = None | ||
| 160 | |||
| 161 | if lib in ignorelibs: | ||
| 162 | logger.debug('Ignoring library dependency %s' % lib) | ||
| 163 | continue | ||
| 164 | |||
| 165 | recipe = RecipeHandler.recipelibmap.get(lib, None) | ||
| 166 | if recipe: | ||
| 167 | deps.append(recipe) | ||
| 168 | elif recipe is None: | ||
| 169 | if header: | ||
| 170 | RecipeHandler.load_headermap(d) | ||
| 171 | recipe = RecipeHandler.recipeheadermap.get(header, None) | ||
| 172 | if recipe: | ||
| 173 | deps.append(recipe) | ||
| 174 | elif recipe is None: | ||
| 175 | unmappedlibs.append(lib) | ||
| 176 | else: | ||
| 177 | unmappedlibs.append(lib) | ||
| 178 | |||
| 179 | deps = set(deps).difference(set(ignoredeps)) | ||
| 180 | |||
| 181 | if unmappedpc: | ||
| 182 | outlines.append('# NOTE: unable to map the following pkg-config dependencies: %s' % ' '.join(unmappedpc)) | ||
| 183 | outlines.append('# (this is based on recipes that have previously been built and packaged)') | ||
| 184 | |||
| 185 | if unmappedlibs: | ||
| 186 | outlines.append('# NOTE: the following library dependencies are unknown, ignoring: %s' % ' '.join(list(set(unmappedlibs)))) | ||
| 187 | outlines.append('# (this is based on recipes that have previously been built and packaged)') | ||
| 188 | |||
| 189 | if deps: | ||
| 190 | values['DEPENDS'] = ' '.join(deps) | ||
| 191 | |||
| 57 | def genfunction(self, outlines, funcname, content, python=False, forcespace=False): | 192 | def genfunction(self, outlines, funcname, content, python=False, forcespace=False): |
| 58 | if python: | 193 | if python: |
| 59 | prefix = 'python ' | 194 | prefix = 'python ' |
