Skip to contentSkip to conversation

Improve recipetool metadata extraction

PATCH New Paul Eggleton 1 participant 11 messages Jan 18, 2016

lore
Share & tools
lore
#0 lore raw

cover Improve recipetool metadata extraction

Improve the ability for recipetool create (or devtool add, which uses the former) to extract dependencies from source trees, as well as a couple of other related fixes.

The following changes since commit a42229df424552955c0ac62da1063461f97f5938:

openssh: CVE-2016-1907 (2016-01-17 11:32:21 +0000)

are available in the git repository at:

git://git.openembedded.org/openembedded-core-contrib paule/recipetool-fixes
http://cgit.openembedded.org/cgit.cgi/openembedded-core-contrib/log/?h=paule/recipetool-fixes

Paul Eggleton (10):
recipetool: create: improve extraction of pkg-config / lib deps
recipetool: create: pick up boost macros in configure.ac
recipetool: create: detect flex/bison dependency
recipetool: create: support additional autoconf macros from autoconf-archive
recipetool: create: fix overzealous mapping of git URLs
recipetool: create: move dependency mapping code to RecipeHandler
recipetool: create: force GL libraries to virtual/*
recipetool: create: add basic support for extracting dependencies from cmake
recipetool: create: add a couple more license checksums
oe-selftest: devtool: fix test_devtool_add_library if python was built first

 meta/lib/oeqa/selftest/devtool.py         |  12 +-
 meta/lib/oeqa/selftest/recipetool.py      |  21 +-
 scripts/lib/recipetool/create.py          | 149 ++++++++++++-
 scripts/lib/recipetool/create_buildsys.py | 340 +++++++++++++++++++++++-------
 4 files changed, 432 insertions(+), 90 deletions(-)
Signature · 1 line
2.5.0
#1 lore raw

PATCH 1/10 recipetool: create: improve extraction of pkg-config / lib deps

* The regexes for PKG_CHECK_MODULES / AC_CHECK_LIB were a bit too strict and thus we were skipping some macros.
* Add support for PKG_CHECK_EXISTS
* Avoid duplicates in warning on missing pkg-config dependencies
* Ignore dependency on musl (since this may come up if it's the selected C library)

---
 meta/lib/oeqa/selftest/recipetool.py      |  4 ++--
 scripts/lib/recipetool/create_buildsys.py | 18 ++++++++++++++----
 2 files changed, 16 insertions(+), 6 deletions(-)
meta/lib/oeqa/selftest/recipetool.py +2 -2
index 4103a88..927da73 100644
@@ -383,7 +383,7 @@ class RecipetoolTests(RecipetoolBase):
     @testcase(1194)
     def test_recipetool_create_git(self):
         # Ensure we have the right data in shlibs/pkgdata
-        bitbake('libpng pango libx11 libxext jpeg')
+        bitbake('libpng pango libx11 libxext jpeg libxsettings-client libcheck')
         # Try adding a recipe
         tempsrc = os.path.join(self.tempdir, 'srctree')
         os.makedirs(tempsrc)
@@ -397,7 +397,7 @@ class RecipetoolTests(RecipetoolBase):
         checkvars['S'] = '${WORKDIR}/git'
         checkvars['PV'] = '1.11+git${SRCPV}'
         checkvars['SRC_URI'] = srcuri
-        checkvars['DEPENDS'] = set(['libjpeg-turbo', 'libpng', 'libx11', 'libxext', 'pango'])
+        checkvars['DEPENDS'] = set(['libcheck', 'libjpeg-turbo', 'libpng', 'libx11', 'libxsettings-client', 'libxext', 'pango'])
         inherits = ['autotools', 'pkgconfig']
         self._test_recipe_contents(recipefile, checkvars, inherits)
 
scripts/lib/recipetool/create_buildsys.py +14 -4
index 1674aba..7fedb2a 100644
@@ -157,12 +157,13 @@ class AutotoolsRecipeHandler(RecipeHandler):
         progclassmap = {'gconftool-2': 'gconf',
                 'pkg-config': 'pkgconfig'}
 
-        ignoredeps = ['gcc-runtime', 'glibc', 'uclibc', 'tar-native', 'binutils-native']
+        ignoredeps = ['gcc-runtime', 'glibc', 'uclibc', 'musl', 'tar-native', 'binutils-native']
         ignorelibs = ['socket']
 
-        pkg_re = re.compile('PKG_CHECK_MODULES\(\[?[a-zA-Z0-9]*\]?, \[?([^,\]]*)[),].*')
-        lib_re = re.compile('AC_CHECK_LIB\(\[?([a-zA-Z0-9]*)\]?, .*')
-        progs_re = re.compile('_PROGS?\(\[?[a-zA-Z0-9]*\]?, \[?([^,\]]*)\]?[),].*')
+        pkg_re = re.compile('PKG_CHECK_MODULES\(\[?[a-zA-Z0-9_]*\]?, *\[?([^,\]]*)\]?[),].*')
+        pkgce_re = re.compile('PKG_CHECK_EXISTS\(\[?([^,\]]*)\]?[),].*')
+        lib_re = re.compile('AC_CHECK_LIB\(\[?([^,\]]*)\]?,.*')
+        progs_re = re.compile('_PROGS?\(\[?[a-zA-Z0-9_]*\]?, \[?([^,\]]*)\]?[),].*')
         dep_re = re.compile('([^ ><=]+)( [<>=]+ [^ ><=]+)?')
         ac_init_re = re.compile('AC_INIT\(([^,]+), *([^,]+)[,)].*')
         am_init_re = re.compile('AM_INIT_AUTOMAKE\(([^,]+), *([^,]+)[,)].*')
@@ -249,6 +250,13 @@ class AutotoolsRecipeHandler(RecipeHandler):
                     if res:
                         pcdeps.extend([x[0] for x in res])
                 inherits.append('pkgconfig')
+            elif keyword == 'PKG_CHECK_EXISTS':
+                res = pkgce_re.search(value)
+                if res:
+                    res = dep_re.findall(res.group(1))
+                    if res:
+                        pcdeps.extend([x[0] for x in res])
+                inherits.append('pkgconfig')
             elif keyword in ('AM_GNU_GETTEXT', 'AM_GLIB_GNU_GETTEXT', 'GETTEXT_PACKAGE'):
                 inherits.append('gettext')
             elif keyword in ('AC_PROG_INTLTOOL', 'IT_PROG_INTLTOOL'):
@@ -313,6 +321,7 @@ class AutotoolsRecipeHandler(RecipeHandler):
                         defines[key] = value
 
         keywords = ['PKG_CHECK_MODULES',
+                    'PKG_CHECK_EXISTS',
                     'AM_GNU_GETTEXT',
                     'AM_GLIB_GNU_GETTEXT',
                     'GETTEXT_PACKAGE',
@@ -375,6 +384,7 @@ class AutotoolsRecipeHandler(RecipeHandler):
 
         recipemap = read_pkgconfig_provides(tinfoil.config_data)
         unmapped = []
+        pcdeps = list(set(pcdeps))
         for pcdep in pcdeps:
             recipe = recipemap.get(pcdep, None)
             if recipe:
Signature · 1 line
2.5.0
#2 lore raw

PATCH 2/10 recipetool: create: pick up boost macros in configure.ac

In reply to Paul Eggleton

The presence of BOOST_REQUIRE or AX_BOOST.* indicates that boost is a dependency.

---
 scripts/lib/recipetool/create_buildsys.py | 4 ++++
 1 file changed, 4 insertions(+)
scripts/lib/recipetool/create_buildsys.py +4 -0
index 7fedb2a..544dae3 100644
@@ -294,6 +294,8 @@ class AutotoolsRecipeHandler(RecipeHandler):
                                     unmappedlibs.append(lib)
             elif keyword == 'AC_PATH_X':
                 deps.append('libx11')
+            elif keyword in ('AX_BOOST', 'BOOST_REQUIRE'):
+                deps.append('boost')
             elif keyword == 'AC_INIT':
                 if extravalues is not None:
                     res = ac_init_re.match(value)
@@ -332,6 +334,8 @@ class AutotoolsRecipeHandler(RecipeHandler):
                     'AC_PATH_PROG',
                     'AC_CHECK_LIB',
                     'AC_PATH_X',
+                    'AX_BOOST',
+                    'BOOST_REQUIRE',
                     'AC_INIT',
                     'AM_INIT_AUTOMAKE',
                     'define(',
Signature · 1 line
2.5.0
#3 lore raw

PATCH 3/10 recipetool: create: detect flex/bison dependency

In reply to Paul Eggleton

There are a few different macros that can be used to pick up these tools, add support for them all.

---
 scripts/lib/recipetool/create_buildsys.py | 9 +++++++++
 1 file changed, 9 insertions(+)
scripts/lib/recipetool/create_buildsys.py +9 -0
index 544dae3..c6d9bbe 100644
@@ -296,6 +296,10 @@ class AutotoolsRecipeHandler(RecipeHandler):
                 deps.append('libx11')
             elif keyword in ('AX_BOOST', 'BOOST_REQUIRE'):
                 deps.append('boost')
+            elif keyword in ('AC_PROG_LEX', 'AM_PROG_LEX', 'AX_PROG_FLEX'):
+                deps.append('flex-native')
+            elif keyword in ('AC_PROG_YACC', 'AX_PROG_BISON'):
+                deps.append('bison-native')
             elif keyword == 'AC_INIT':
                 if extravalues is not None:
                     res = ac_init_re.match(value)
@@ -336,6 +340,11 @@ class AutotoolsRecipeHandler(RecipeHandler):
                     'AC_PATH_X',
                     'AX_BOOST',
                     'BOOST_REQUIRE',
+                    'AC_PROG_LEX',
+                    'AM_PROG_LEX',
+                    'AX_PROG_FLEX',
+                    'AC_PROG_YACC',
+                    'AX_PROG_BISON',
                     'AC_INIT',
                     'AM_INIT_AUTOMAKE',
                     'define(',
Signature · 1 line
2.5.0
#4 lore raw

PATCH 4/10 recipetool: create: support additional autoconf macros from autoconf-archive

In reply to Paul Eggleton

Support a number of macros from autoconf-archive when reading configure.ac to extract dependencies.

---
 scripts/lib/recipetool/create_buildsys.py | 95 ++++++++++++++++++++++++++++++-
 1 file changed, 94 insertions(+), 1 deletion(-)
scripts/lib/recipetool/create_buildsys.py +94 -1
index c6d9bbe..127e133 100644
@@ -144,6 +144,8 @@ class AutotoolsRecipeHandler(RecipeHandler):
     def extract_autotools_deps(outlines, srctree, extravalues=None, acfile=None):
         import shlex
         import oe.package
+        import json
+        import glob
 
         values = {}
         inherits = []
@@ -163,6 +165,7 @@ class AutotoolsRecipeHandler(RecipeHandler):
         pkg_re = re.compile('PKG_CHECK_MODULES\(\[?[a-zA-Z0-9_]*\]?, *\[?([^,\]]*)\]?[),].*')
         pkgce_re = re.compile('PKG_CHECK_EXISTS\(\[?([^,\]]*)\]?[),].*')
         lib_re = re.compile('AC_CHECK_LIB\(\[?([^,\]]*)\]?,.*')
+        libx_re = re.compile('AX_CHECK_LIBRARY\(\[?[^,\]]*\]?, *\[?([^,\]]*)\]?, *\[?([a-zA-Z0-9-]*)\]?,.*')
         progs_re = re.compile('_PROGS?\(\[?[a-zA-Z0-9_]*\]?, \[?([^,\]]*)\]?[),].*')
         dep_re = re.compile('([^ ><=]+)( [<>=]+ [^ ><=]+)?')
         ac_init_re = re.compile('AC_INIT\(([^,]+), *([^,]+)[,)].*')
@@ -189,6 +192,7 @@ class AutotoolsRecipeHandler(RecipeHandler):
 
         # Now turn it into a library->recipe mapping
         recipelibmap = {}
+        recipeheadermap = {}
         pkgdata_dir = tinfoil.config_data.getVar('PKGDATA_DIR', True)
         for libname, pkg in pkglibmap.iteritems():
             try:
@@ -203,6 +207,27 @@ class AutotoolsRecipeHandler(RecipeHandler):
                 else:
                     raise
 
+        def load_headermap():
+            if recipeheadermap:
+                return
+            includedir = tinfoil.config_data.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:
+                            recipeheadermap[header] = pn
+
         defines = {}
         def subst_defines(value):
             newvalue = value
@@ -263,7 +288,7 @@ class AutotoolsRecipeHandler(RecipeHandler):
                 deps.append('intltool-native')
             elif keyword == 'AM_PATH_GLIB_2_0':
                 deps.append('glib-2.0')
-            elif keyword == 'AC_CHECK_PROG' or keyword == 'AC_PATH_PROG':
+            elif keyword in ('AC_CHECK_PROG', 'AC_PATH_PROG', 'AX_WITH_PROG'):
                 res = progs_re.search(value)
                 if res:
                     for prog in shlex.split(res.group(1)):
@@ -292,6 +317,26 @@ class AutotoolsRecipeHandler(RecipeHandler):
                             if libdep is None:
                                 if not lib.startswith('$'):
                                     unmappedlibs.append(lib)
+            elif keyword == 'AX_CHECK_LIBRARY':
+                res = libx_re.search(value)
+                if res:
+                    lib = res.group(2)
+                    if lib in ignorelibs:
+                        logger.debug('Ignoring library dependency %s' % lib)
+                    else:
+                        libdep = recipelibmap.get(lib, None)
+                        if libdep:
+                            deps.append(libdep)
+                        else:
+                            if libdep is None:
+                                if not lib.startswith('$'):
+                                    header = res.group(1)
+                                    load_headermap()
+                                    libdep = recipeheadermap.get(header, None)
+                                    if libdep:
+                                        deps.append(libdep)
+                                    else:
+                                        unmappedlibs.append(lib)
             elif keyword == 'AC_PATH_X':
                 deps.append('libx11')
             elif keyword in ('AX_BOOST', 'BOOST_REQUIRE'):
@@ -300,6 +345,36 @@ class AutotoolsRecipeHandler(RecipeHandler):
                 deps.append('flex-native')
             elif keyword in ('AC_PROG_YACC', 'AX_PROG_BISON'):
                 deps.append('bison-native')
+            elif keyword == 'AX_CHECK_ZLIB':
+                deps.append('zlib')
+            elif keyword in ('AX_CHECK_OPENSSL', 'AX_LIB_CRYPTO'):
+                deps.append('openssl')
+            elif keyword == 'AX_LIB_CURL':
+                deps.append('curl')
+            elif keyword == 'AX_LIB_BEECRYPT':
+                deps.append('beecrypt')
+            elif keyword == 'AX_LIB_EXPAT':
+                deps.append('expat')
+            elif keyword == 'AX_LIB_GCRYPT':
+                deps.append('libgcrypt')
+            elif keyword == 'AX_LIB_NETTLE':
+                deps.append('nettle')
+            elif keyword == 'AX_LIB_READLINE':
+                deps.append('readline')
+            elif keyword == 'AX_LIB_SQLITE3':
+                deps.append('sqlite3')
+            elif keyword == 'AX_LIB_TAGLIB':
+                deps.append('taglib')
+            elif keyword == 'AX_PKG_SWIG':
+                deps.append('swig')
+            elif keyword == 'AX_PROG_XSLTPROC':
+                deps.append('libxslt-native')
+            elif keyword == 'AX_WITH_CURSES':
+                deps.append('ncurses')
+            elif keyword == 'AX_PATH_BDB':
+                deps.append('db')
+            elif keyword == 'AX_PATH_LIB_PCRE':
+                deps.append('libpcre')
             elif keyword == 'AC_INIT':
                 if extravalues is not None:
                     res = ac_init_re.match(value)
@@ -336,7 +411,9 @@ class AutotoolsRecipeHandler(RecipeHandler):
                     'AM_PATH_GLIB_2_0',
                     'AC_CHECK_PROG',
                     'AC_PATH_PROG',
+                    'AX_WITH_PROG',
                     'AC_CHECK_LIB',
+                    'AX_CHECK_LIBRARY',
                     'AC_PATH_X',
                     'AX_BOOST',
                     'BOOST_REQUIRE',
@@ -345,6 +422,22 @@ class AutotoolsRecipeHandler(RecipeHandler):
                     'AX_PROG_FLEX',
                     'AC_PROG_YACC',
                     'AX_PROG_BISON',
+                    'AX_CHECK_ZLIB',
+                    'AX_CHECK_OPENSSL',
+                    'AX_LIB_CRYPTO',
+                    'AX_LIB_CURL',
+                    'AX_LIB_BEECRYPT',
+                    'AX_LIB_EXPAT',
+                    'AX_LIB_GCRYPT',
+                    'AX_LIB_NETTLE',
+                    'AX_LIB_READLINE'
+                    'AX_LIB_SQLITE3',
+                    'AX_LIB_TAGLIB',
+                    'AX_PKG_SWIG',
+                    'AX_PROG_XSLTPROC',
+                    'AX_WITH_CURSES',
+                    'AX_PATH_BDB',
+                    'AX_PATH_LIB_PCRE',
                     'AC_INIT',
                     'AM_INIT_AUTOMAKE',
                     'define(',
Signature · 1 line
2.5.0
#5 lore raw

PATCH 5/10 recipetool: create: fix overzealous mapping of git URLs

In reply to Paul Eggleton

The regex for detecting git URLs was unanchored, leading to it matching where it shouldn't have. An example of where this went wrong was
http://taglib.github.io/releases/taglib-1.9.1.tar.gz.

---
 scripts/lib/recipetool/create.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
scripts/lib/recipetool/create.py +1 -1
index 4f95d7e..1218a7d 100644
@@ -140,7 +140,7 @@ def create_recipe(args):
             # Assume the archive contains the directory structure verbatim
             # so we need to extract to a subdirectory
             fetchuri += ';subdir=%s' % os.path.splitext(os.path.basename(urlparse.urlsplit(fetchuri).path))[0]
-        git_re = re.compile('(https?)://([^;]+\.git)(;.*)?')
+        git_re = re.compile('(https?)://([^;]+\.git)(;.*)?$')
         res = git_re.match(fetchuri)
         if res:
             # Need to switch the URI around so that the git fetcher is used
Signature · 1 line
2.5.0
#6 lore raw

PATCH 6/10 recipetool: create: move dependency mapping code to RecipeHandler

In reply to Paul Eggleton

Some refactoring to allow access to the library/header/pkg-config mappings and the DEPENDS / unmapped dependency output code from other classes than AutotoolsRecipeHandler.

---
 scripts/lib/recipetool/create.py          | 137 +++++++++++++++++++++++++++++-
 scripts/lib/recipetool/create_buildsys.py | 121 ++------------------------
 2 files changed, 144 insertions(+), 114 deletions(-)
scripts/lib/recipetool/create.py +136 -1
index 1218a7d..dab917f 100644
@@ -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 '
scripts/lib/recipetool/create_buildsys.py +8 -113

169 lines not on this page · raw message

Signature · 1 line
2.5.0
#7 lore raw

PATCH 7/10 recipetool: create: force GL libraries to virtual/*

In reply to Paul Eggleton

We want to specify dependencies on virtual/* rather than whatever library is selected in the current configuration.

---
 scripts/lib/recipetool/create.py | 5 +++++
 1 file changed, 5 insertions(+)
scripts/lib/recipetool/create.py +5 -0
index dab917f..1601a7f 100644
@@ -84,6 +84,11 @@ class RecipeHandler(object):
                 else:
                     raise
 
+        # Some overrides - these should be mapped to the virtual
+        RecipeHandler.recipelibmap['GL'] = 'virtual/libgl'
+        RecipeHandler.recipelibmap['EGL'] = 'virtual/egl'
+        RecipeHandler.recipelibmap['GLESv2'] = 'virtual/libgles2'
+
     @staticmethod
     def load_headermap(d):
         '''Build up lib headerfile->recipe mapping'''
Signature · 1 line
2.5.0
#8 lore raw

PATCH 8/10 recipetool: create: add basic support for extracting dependencies from cmake

In reply to Paul Eggleton

Add support for extracting dependencies from CMakeLists.txt. There's still a bunch of things missing that are outside the scope of OE-Core and we still lack a proper extension mechanism, but this is a good start.

This also adds an oe-selftest test to exercise the new code a bit.

Implements [YOCTO #7635].

---
 meta/lib/oeqa/selftest/recipetool.py      |  17 +++
 scripts/lib/recipetool/create.py          |   3 +
 scripts/lib/recipetool/create_buildsys.py | 177 +++++++++++++++++++++++++++++-
 3 files changed, 191 insertions(+), 6 deletions(-)
meta/lib/oeqa/selftest/recipetool.py +17 -0
index 927da73..b4d33bc 100644
@@ -422,6 +422,23 @@ class RecipetoolTests(RecipetoolBase):
         inherits = ['autotools']
         self._test_recipe_contents(os.path.join(temprecipe, dirlist[0]), checkvars, inherits)
 
+    def test_recipetool_create_cmake(self):
+        # Try adding a recipe
+        temprecipe = os.path.join(self.tempdir, 'recipe')
+        os.makedirs(temprecipe)
+        recipefile = os.path.join(temprecipe, 'navit_0.5.0.bb')
+        srcuri = 'http://downloads.sourceforge.net/project/navit/v0.5.0/navit-0.5.0.tar.gz'
+        result = runCmd('recipetool create -o %s %s' % (temprecipe, srcuri))
+        self.assertTrue(os.path.isfile(recipefile))
+        checkvars = {}
+        checkvars['LICENSE'] = set(['Unknown', 'GPLv2', 'LGPLv2'])
+        checkvars['SRC_URI'] = 'http://downloads.sourceforge.net/project/navit/v${PV}/navit-${PV}.tar.gz'
+        checkvars['SRC_URI[md5sum]'] = '242f398e979a6b8c0f3c802b63435b68'
+        checkvars['SRC_URI[sha256sum]'] = '13353481d7fc01a4f64e385dda460b51496366bba0fd2cc85a89a0747910e94d'
+        checkvars['DEPENDS'] = set(['freetype', 'zlib', 'openssl', 'glib-2.0', 'virtual/libgl', 'virtual/egl', 'gtk+', 'libpng', 'libsdl', 'freeglut', 'dbus-glib'])
+        inherits = ['cmake', 'python-dir', 'gettext', 'pkgconfig']
+        self._test_recipe_contents(recipefile, checkvars, inherits)
+
 class RecipetoolAppendsrcBase(RecipetoolBase):
     def _try_recipetool_appendsrcfile(self, testrecipe, newfile, destfile, options, expectedlines, expectedfiles):
         cmd = 'recipetool appendsrcfile %s %s %s %s %s' % (options, self.templayerdir, testrecipe, newfile, destfile)
scripts/lib/recipetool/create.py +3 -0
index 1601a7f..ad6bf7b 100644
@@ -558,6 +558,8 @@ def create_recipe(args):
     outlines = []
     outlines.extend(lines_before)
     if classes:
+        if outlines[-1] and not outlines[-1].startswith('#'):
+            outlines.append('')
         outlines.append('inherit %s' % ' '.join(classes))
         outlines.append('')
     outlines.extend(lines_after)
@@ -627,6 +629,7 @@ def get_license_md5sums(d, static_only=False):
     md5sums['5f30f0716dfdd0d91eb439ebec522ec2'] = 'LGPLv2'
     md5sums['55ca817ccb7d5b5b66355690e9abc605'] = 'LGPLv2'
     md5sums['252890d9eee26aab7b432e8b8a616475'] = 'LGPLv2'
+    md5sums['3214f080875748938ba060314b4f727d'] = 'LGPLv2'
     md5sums['d32239bcb673463ab874e80d47fae504'] = 'GPLv3'
     md5sums['f27defe1e96c2e1ecd4e0c9be8967949'] = 'GPLv3'
     md5sums['6a6a8e020838b23406c81b19c1d46df6'] = 'LGPLv3'
scripts/lib/recipetool/create_buildsys.py +171 -6

195 lines not on this page · raw message

Signature · 1 line
2.5.0
#9 lore raw

PATCH 9/10 recipetool: create: add a couple more license checksums

In reply to Paul Eggleton

I found these when I was looking at libftdi and they seem to be generic enough to show up in at least a couple of other packages so I figure I'll add them.

---
 scripts/lib/recipetool/create.py | 2 ++
 1 file changed, 2 insertions(+)
scripts/lib/recipetool/create.py +2 -0
index ad6bf7b..43861ee 100644
@@ -630,11 +630,13 @@ def get_license_md5sums(d, static_only=False):
     md5sums['55ca817ccb7d5b5b66355690e9abc605'] = 'LGPLv2'
     md5sums['252890d9eee26aab7b432e8b8a616475'] = 'LGPLv2'
     md5sums['3214f080875748938ba060314b4f727d'] = 'LGPLv2'
+    md5sums['db979804f025cf55aabec7129cb671ed'] = 'LGPLv2'
     md5sums['d32239bcb673463ab874e80d47fae504'] = 'GPLv3'
     md5sums['f27defe1e96c2e1ecd4e0c9be8967949'] = 'GPLv3'
     md5sums['6a6a8e020838b23406c81b19c1d46df6'] = 'LGPLv3'
     md5sums['3b83ef96387f14655fc854ddc3c6bd57'] = 'Apache-2.0'
     md5sums['385c55653886acac3821999a3ccd17b3'] = 'Artistic-1.0 | GPL-2.0' # some perl modules
+    md5sums['54c7042be62e169199200bc6477f04d1'] = 'BSD-3-Clause'
     return md5sums
 
 def guess_license(srctree):
Signature · 1 line
2.5.0
#10 lore raw

PATCH 10/10 oe-selftest: devtool: fix test_devtool_add_library if python was built first

In reply to Paul Eggleton

If Python is in the sysroot then this test can fail due to some brokenness in libftdi's CMakeLists.txt file for its python bindings. Just disable it in order to have the test work more reliably.

---
 meta/lib/oeqa/selftest/devtool.py | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)
meta/lib/oeqa/selftest/devtool.py +8 -4
index f6471bd..43c7cda 100644
@@ -208,15 +208,16 @@ class DevtoolTests(DevtoolBase):
         # Fetch source
         tempdir = tempfile.mkdtemp(prefix='devtoolqa')
         self.track_for_cleanup(tempdir)
-        url = 'http://www.intra2net.com/en/developer/libftdi/download/libftdi1-1.1.tar.bz2'
+        version = '1.1'
+        url = 'https://www.intra2net.com/en/developer/libftdi/download/libftdi1-%s.tar.bz2' % version
         result = runCmd('wget %s' % url, cwd=tempdir)
-        result = runCmd('tar xfv libftdi1-1.1.tar.bz2', cwd=tempdir)
-        srcdir = os.path.join(tempdir, 'libftdi1-1.1')
+        result = runCmd('tar xfv libftdi1-%s.tar.bz2' % version, cwd=tempdir)
+        srcdir = os.path.join(tempdir, 'libftdi1-%s' % version)
         self.assertTrue(os.path.isfile(os.path.join(srcdir, 'CMakeLists.txt')), 'Unable to find CMakeLists.txt in source directory')
         # Test devtool add (and use -V so we test that too)
         self.track_for_cleanup(self.workspacedir)
         self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
-        result = runCmd('devtool add libftdi %s -V 1.1' % srcdir)
+        result = runCmd('devtool add libftdi %s -V %s' % (srcdir, version))
         self.assertTrue(os.path.exists(os.path.join(self.workspacedir, 'conf', 'layer.conf')), 'Workspace directory not created')
         # Test devtool status
         result = runCmd('devtool status')
@@ -224,6 +225,9 @@ class DevtoolTests(DevtoolBase):
         self.assertIn(srcdir, result.output)
         # Clean up anything in the workdir/sysroot/sstate cache (have to do this *after* devtool add since the recipe only exists then)
         bitbake('libftdi -c cleansstate')
+        # libftdi's python/CMakeLists.txt is a bit broken, so let's just disable it
+        recipefile = '%s/recipes/libftdi/libftdi_%s.bb' % (self.workspacedir, version)
+        result = runCmd('recipetool setvar %s EXTRA_OECMAKE -- "-DPYTHON_BINDINGS=OFF"' % recipefile)
         # Test devtool build
         result = runCmd('devtool build libftdi')
         staging_libdir = get_bb_var('STAGING_LIBDIR', 'libftdi')
Signature · 1 line
2.5.0