diff options
author | Paul Eggleton <paul.eggleton@linux.intel.com> | 2016-01-19 00:18:31 +1300 |
---|---|---|
committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2016-01-19 16:35:38 +0000 |
commit | 40c10d998b90dd59c6d36c28f8ba11ec598bfa0f (patch) | |
tree | 0903dba27376952324619d3102b6107bae0022e5 /scripts/lib/recipetool/create.py | |
parent | bacff751c88b680fbfb07843b18c59c8bc80a9ea (diff) | |
download | openembedded-core-40c10d998b90dd59c6d36c28f8ba11ec598bfa0f.tar.gz openembedded-core-40c10d998b90dd59c6d36c28f8ba11ec598bfa0f.tar.bz2 openembedded-core-40c10d998b90dd59c6d36c28f8ba11ec598bfa0f.zip |
recipetool: create: move dependency mapping code to RecipeHandler
Some refactoring to allow access to the library/header/pkg-config
mappings and the DEPENDS / unmapped dependency output code from other
classes than AutotoolsRecipeHandler.
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
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 import glob import fnmatch import re +import json import logging import scriptutils import urlparse @@ -39,7 +40,73 @@ def tinfoil_init(instance): global tinfoil tinfoil = instance -class RecipeHandler(): +class RecipeHandler(object): + recipelibmap = {} + recipeheadermap = {} + + @staticmethod + def load_libmap(d): + '''Load library->recipe mapping''' + import oe.package + + if RecipeHandler.recipelibmap: + return + # First build up library->package mapping + shlib_providers = oe.package.read_shlib_providers(d) + libdir = d.getVar('libdir', True) + base_libdir = d.getVar('base_libdir', True) + libpaths = list(set([base_libdir, libdir])) + libname_re = re.compile('^lib(.+)\.so.*$') + pkglibmap = {} + for lib, item in shlib_providers.iteritems(): + for path, pkg in item.iteritems(): + if path in libpaths: + res = libname_re.match(lib) + if res: + libname = res.group(1) + if not libname in pkglibmap: + pkglibmap[libname] = pkg[0] + else: + logger.debug('unable to extract library name from %s' % lib) + + # Now turn it into a library->recipe mapping + pkgdata_dir = d.getVar('PKGDATA_DIR', True) + for libname, pkg in pkglibmap.iteritems(): + try: + with open(os.path.join(pkgdata_dir, 'runtime', pkg)) as f: + for line in f: + if line.startswith('PN:'): + RecipeHandler.recipelibmap[libname] = line.split(':', 1)[-1].strip() + break + except IOError as ioe: + if ioe.errno == 2: + logger.warn('unable to find a pkgdata file for package %s' % pkg) + else: + raise + + @staticmethod + def load_headermap(d): + '''Build up lib headerfile->recipe mapping''' + if RecipeHandler.recipeheadermap: + return + includedir = d.getVar('includedir', True) + for pkg in glob.glob(os.path.join(pkgdata_dir, 'runtime', '*-dev')): + with open(os.path.join(pkgdata_dir, 'runtime', pkg)) as f: + pn = None + headers = [] + for line in f: + if line.startswith('PN:'): + pn = line.split(':', 1)[-1].strip() + elif line.startswith('FILES_INFO:'): + val = line.split(':', 1)[1].strip() + dictval = json.loads(val) + for fullpth in sorted(dictval): + if fullpth.startswith(includedir) and fullpth.endswith('.h'): + headers.append(os.path.relpath(fullpth, includedir)) + if pn and headers: + for header in headers: + RecipeHandler.recipeheadermap[header] = pn + @staticmethod def checkfiles(path, speclist, recursive=False): results = [] @@ -54,6 +121,74 @@ class RecipeHandler(): results.extend(glob.glob(os.path.join(path, spec))) return results + @staticmethod + def handle_depends(libdeps, pcdeps, deps, outlines, values, d): + if pcdeps: + recipemap = read_pkgconfig_provides(d) + if libdeps: + RecipeHandler.load_libmap(d) + + ignorelibs = ['socket'] + ignoredeps = ['gcc-runtime', 'glibc', 'uclibc', 'musl', 'tar-native', 'binutils-native'] + + unmappedpc = [] + pcdeps = list(set(pcdeps)) + for pcdep in pcdeps: + if isinstance(pcdep, basestring): + recipe = recipemap.get(pcdep, None) + if recipe: + deps.append(recipe) + else: + if not pcdep.startswith('$'): + unmappedpc.append(pcdep) + else: + for item in pcdep: + recipe = recipemap.get(pcdep, None) + if recipe: + deps.append(recipe) + break + else: + unmappedpc.append('(%s)' % ' or '.join(pcdep)) + + unmappedlibs = [] + for libdep in libdeps: + if isinstance(libdep, tuple): + lib, header = libdep + else: + lib = libdep + header = None + + if lib in ignorelibs: + logger.debug('Ignoring library dependency %s' % lib) + continue + + recipe = RecipeHandler.recipelibmap.get(lib, None) + if recipe: + deps.append(recipe) + elif recipe is None: + if header: + RecipeHandler.load_headermap(d) + recipe = RecipeHandler.recipeheadermap.get(header, None) + if recipe: + deps.append(recipe) + elif recipe is None: + unmappedlibs.append(lib) + else: + unmappedlibs.append(lib) + + deps = set(deps).difference(set(ignoredeps)) + + if unmappedpc: + outlines.append('# NOTE: unable to map the following pkg-config dependencies: %s' % ' '.join(unmappedpc)) + outlines.append('# (this is based on recipes that have previously been built and packaged)') + + if unmappedlibs: + outlines.append('# NOTE: the following library dependencies are unknown, ignoring: %s' % ' '.join(list(set(unmappedlibs)))) + outlines.append('# (this is based on recipes that have previously been built and packaged)') + + if deps: + values['DEPENDS'] = ' '.join(deps) + def genfunction(self, outlines, funcname, content, python=False, forcespace=False): if python: prefix = 'python ' |