mirror of
https://git.yoctoproject.org/poky
synced 2026-05-31 00:39:46 +00:00
recipetool: create: add basic support for extracting dependencies from cmake
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]. (From OE-Core rev: 77e73e6930381fdbd6e78d3913d6467572e16568) Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
This commit is contained in:
committed by
Richard Purdie
parent
3eb397fab6
commit
2c8c9fe3b4
@@ -422,6 +422,23 @@ class RecipetoolTests(RecipetoolBase):
|
|||||||
inherits = ['autotools']
|
inherits = ['autotools']
|
||||||
self._test_recipe_contents(os.path.join(temprecipe, dirlist[0]), checkvars, inherits)
|
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):
|
class RecipetoolAppendsrcBase(RecipetoolBase):
|
||||||
def _try_recipetool_appendsrcfile(self, testrecipe, newfile, destfile, options, expectedlines, expectedfiles):
|
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)
|
cmd = 'recipetool appendsrcfile %s %s %s %s %s' % (options, self.templayerdir, testrecipe, newfile, destfile)
|
||||||
|
|||||||
@@ -558,6 +558,8 @@ def create_recipe(args):
|
|||||||
outlines = []
|
outlines = []
|
||||||
outlines.extend(lines_before)
|
outlines.extend(lines_before)
|
||||||
if classes:
|
if classes:
|
||||||
|
if outlines[-1] and not outlines[-1].startswith('#'):
|
||||||
|
outlines.append('')
|
||||||
outlines.append('inherit %s' % ' '.join(classes))
|
outlines.append('inherit %s' % ' '.join(classes))
|
||||||
outlines.append('')
|
outlines.append('')
|
||||||
outlines.extend(lines_after)
|
outlines.extend(lines_after)
|
||||||
@@ -627,6 +629,7 @@ def get_license_md5sums(d, static_only=False):
|
|||||||
md5sums['5f30f0716dfdd0d91eb439ebec522ec2'] = 'LGPLv2'
|
md5sums['5f30f0716dfdd0d91eb439ebec522ec2'] = 'LGPLv2'
|
||||||
md5sums['55ca817ccb7d5b5b66355690e9abc605'] = 'LGPLv2'
|
md5sums['55ca817ccb7d5b5b66355690e9abc605'] = 'LGPLv2'
|
||||||
md5sums['252890d9eee26aab7b432e8b8a616475'] = 'LGPLv2'
|
md5sums['252890d9eee26aab7b432e8b8a616475'] = 'LGPLv2'
|
||||||
|
md5sums['3214f080875748938ba060314b4f727d'] = 'LGPLv2'
|
||||||
md5sums['d32239bcb673463ab874e80d47fae504'] = 'GPLv3'
|
md5sums['d32239bcb673463ab874e80d47fae504'] = 'GPLv3'
|
||||||
md5sums['f27defe1e96c2e1ecd4e0c9be8967949'] = 'GPLv3'
|
md5sums['f27defe1e96c2e1ecd4e0c9be8967949'] = 'GPLv3'
|
||||||
md5sums['6a6a8e020838b23406c81b19c1d46df6'] = 'LGPLv3'
|
md5sums['6a6a8e020838b23406c81b19c1d46df6'] = 'LGPLv3'
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ class CmakeRecipeHandler(RecipeHandler):
|
|||||||
if RecipeHandler.checkfiles(srctree, ['CMakeLists.txt']):
|
if RecipeHandler.checkfiles(srctree, ['CMakeLists.txt']):
|
||||||
classes.append('cmake')
|
classes.append('cmake')
|
||||||
values = CmakeRecipeHandler.extract_cmake_deps(lines_before, srctree, extravalues)
|
values = CmakeRecipeHandler.extract_cmake_deps(lines_before, srctree, extravalues)
|
||||||
|
classes.extend(values.pop('inherit', '').split())
|
||||||
for var, value in values.iteritems():
|
for var, value in values.iteritems():
|
||||||
lines_before.append('%s = "%s"' % (var, value))
|
lines_before.append('%s = "%s"' % (var, value))
|
||||||
lines_after.append('# Specify any options you want to pass to cmake using EXTRA_OECMAKE:')
|
lines_after.append('# Specify any options you want to pass to cmake using EXTRA_OECMAKE:')
|
||||||
@@ -48,18 +49,182 @@ class CmakeRecipeHandler(RecipeHandler):
|
|||||||
@staticmethod
|
@staticmethod
|
||||||
def extract_cmake_deps(outlines, srctree, extravalues, cmakelistsfile=None):
|
def extract_cmake_deps(outlines, srctree, extravalues, cmakelistsfile=None):
|
||||||
values = {}
|
values = {}
|
||||||
|
inherits = []
|
||||||
|
|
||||||
if cmakelistsfile:
|
if cmakelistsfile:
|
||||||
srcfiles = [cmakelistsfile]
|
srcfiles = [cmakelistsfile]
|
||||||
else:
|
else:
|
||||||
srcfiles = RecipeHandler.checkfiles(srctree, ['CMakeLists.txt'])
|
srcfiles = RecipeHandler.checkfiles(srctree, ['CMakeLists.txt'])
|
||||||
|
|
||||||
proj_re = re.compile('project\(([^)]*)\)', re.IGNORECASE)
|
# Note that some of these are non-standard, but probably better to
|
||||||
with open(srcfiles[0], 'r') as f:
|
# be able to map them anyway if we see them
|
||||||
for line in f:
|
cmake_pkgmap = {'alsa': 'alsa-lib',
|
||||||
res = proj_re.match(line.strip())
|
'aspell': 'aspell',
|
||||||
if res:
|
'atk': 'atk',
|
||||||
extravalues['PN'] = res.group(1).split()[0]
|
'bison': 'bison-native',
|
||||||
|
'boost': 'boost',
|
||||||
|
'bzip2': 'bzip2',
|
||||||
|
'cairo': 'cairo',
|
||||||
|
'cups': 'cups',
|
||||||
|
'curl': 'curl',
|
||||||
|
'curses': 'ncurses',
|
||||||
|
'cvs': 'cvs',
|
||||||
|
'drm': 'libdrm',
|
||||||
|
'dbus': 'dbus',
|
||||||
|
'dbusglib': 'dbus-glib',
|
||||||
|
'egl': 'virtual/egl',
|
||||||
|
'expat': 'expat',
|
||||||
|
'flex': 'flex-native',
|
||||||
|
'fontconfig': 'fontconfig',
|
||||||
|
'freetype': 'freetype',
|
||||||
|
'gettext': '',
|
||||||
|
'git': '',
|
||||||
|
'gio': 'glib-2.0',
|
||||||
|
'giounix': 'glib-2.0',
|
||||||
|
'glew': 'glew',
|
||||||
|
'glib': 'glib-2.0',
|
||||||
|
'glib2': 'glib-2.0',
|
||||||
|
'glu': 'libglu',
|
||||||
|
'glut': 'freeglut',
|
||||||
|
'gobject': 'glib-2.0',
|
||||||
|
'gperf': 'gperf-native',
|
||||||
|
'gnutls': 'gnutls',
|
||||||
|
'gtk2': 'gtk+',
|
||||||
|
'gtk3': 'gtk+3',
|
||||||
|
'gtk': 'gtk+3',
|
||||||
|
'harfbuzz': 'harfbuzz',
|
||||||
|
'icu': 'icu',
|
||||||
|
'intl': 'virtual/libintl',
|
||||||
|
'jpeg': 'jpeg',
|
||||||
|
'libarchive': 'libarchive',
|
||||||
|
'libiconv': 'virtual/libiconv',
|
||||||
|
'liblzma': 'xz',
|
||||||
|
'libxml2': 'libxml2',
|
||||||
|
'libxslt': 'libxslt',
|
||||||
|
'opengl': 'virtual/libgl',
|
||||||
|
'openmp': '',
|
||||||
|
'openssl': 'openssl',
|
||||||
|
'pango': 'pango',
|
||||||
|
'perl': '',
|
||||||
|
'perllibs': '',
|
||||||
|
'pkgconfig': '',
|
||||||
|
'png': 'libpng',
|
||||||
|
'pthread': '',
|
||||||
|
'pythoninterp': '',
|
||||||
|
'pythonlibs': '',
|
||||||
|
'ruby': 'ruby-native',
|
||||||
|
'sdl': 'libsdl',
|
||||||
|
'sdl2': 'libsdl2',
|
||||||
|
'subversion': 'subversion-native',
|
||||||
|
'swig': 'swig-native',
|
||||||
|
'tcl': 'tcl-native',
|
||||||
|
'threads': '',
|
||||||
|
'tiff': 'tiff',
|
||||||
|
'wget': 'wget',
|
||||||
|
'x11': 'libx11',
|
||||||
|
'xcb': 'libxcb',
|
||||||
|
'xext': 'libxext',
|
||||||
|
'xfixes': 'libxfixes',
|
||||||
|
'zlib': 'zlib',
|
||||||
|
}
|
||||||
|
|
||||||
|
pcdeps = []
|
||||||
|
libdeps = []
|
||||||
|
deps = []
|
||||||
|
unmappedpkgs = []
|
||||||
|
|
||||||
|
proj_re = re.compile('project\s*\(([^)]*)\)', re.IGNORECASE)
|
||||||
|
pkgcm_re = re.compile('pkg_check_modules\s*\(\s*[a-zA-Z0-9-_]+\s*(REQUIRED)?\s+([^)\s]+)\s*\)', re.IGNORECASE)
|
||||||
|
pkgsm_re = re.compile('pkg_search_module\s*\(\s*[a-zA-Z0-9-_]+\s*(REQUIRED)?((\s+[^)\s]+)+)\s*\)', re.IGNORECASE)
|
||||||
|
findpackage_re = re.compile('find_package\s*\(\s*([a-zA-Z0-9-_]+)\s*.*', re.IGNORECASE)
|
||||||
|
checklib_re = re.compile('check_library_exists\s*\(\s*([^\s)]+)\s*.*', re.IGNORECASE)
|
||||||
|
include_re = re.compile('include\s*\(\s*([^)\s]*)\s*\)', re.IGNORECASE)
|
||||||
|
subdir_re = re.compile('add_subdirectory\s*\(\s*([^)\s]*)\s*([^)\s]*)\s*\)', re.IGNORECASE)
|
||||||
|
dep_re = re.compile('([^ ><=]+)( *[<>=]+ *[^ ><=]+)?')
|
||||||
|
|
||||||
|
def parse_cmake_file(fn, paths=None):
|
||||||
|
searchpaths = (paths or []) + [os.path.dirname(fn)]
|
||||||
|
logger.debug('Parsing file %s' % fn)
|
||||||
|
with open(fn, 'r') as f:
|
||||||
|
for line in f:
|
||||||
|
line = line.strip()
|
||||||
|
res = include_re.match(line)
|
||||||
|
if res:
|
||||||
|
includefn = bb.utils.which(':'.join(searchpaths), res.group(1))
|
||||||
|
if includefn:
|
||||||
|
parse_cmake_file(includefn, searchpaths)
|
||||||
|
else:
|
||||||
|
logger.debug('Unable to recurse into include file %s' % res.group(1))
|
||||||
|
continue
|
||||||
|
res = subdir_re.match(line)
|
||||||
|
if res:
|
||||||
|
subdirfn = os.path.join(os.path.dirname(fn), res.group(1), 'CMakeLists.txt')
|
||||||
|
if os.path.exists(subdirfn):
|
||||||
|
parse_cmake_file(subdirfn, searchpaths)
|
||||||
|
else:
|
||||||
|
logger.debug('Unable to recurse into subdirectory file %s' % subdirfn)
|
||||||
|
continue
|
||||||
|
res = proj_re.match(line)
|
||||||
|
if res:
|
||||||
|
extravalues['PN'] = res.group(1).split()[0]
|
||||||
|
continue
|
||||||
|
res = pkgcm_re.match(line)
|
||||||
|
if res:
|
||||||
|
res = dep_re.findall(res.group(2))
|
||||||
|
if res:
|
||||||
|
pcdeps.extend([x[0] for x in res])
|
||||||
|
inherits.append('pkgconfig')
|
||||||
|
continue
|
||||||
|
res = pkgsm_re.match(line)
|
||||||
|
if res:
|
||||||
|
res = dep_re.findall(res.group(2))
|
||||||
|
if res:
|
||||||
|
# Note: appending a tuple here!
|
||||||
|
item = tuple((x[0] for x in res))
|
||||||
|
if len(item) == 1:
|
||||||
|
item = item[0]
|
||||||
|
pcdeps.append(item)
|
||||||
|
inherits.append('pkgconfig')
|
||||||
|
continue
|
||||||
|
res = findpackage_re.match(line)
|
||||||
|
if res:
|
||||||
|
origpkg = res.group(1)
|
||||||
|
pkg = origpkg.lower()
|
||||||
|
if pkg == 'gettext':
|
||||||
|
inherits.append('gettext')
|
||||||
|
elif pkg == 'perl':
|
||||||
|
inherits.append('perlnative')
|
||||||
|
elif pkg == 'pkgconfig':
|
||||||
|
inherits.append('pkgconfig')
|
||||||
|
elif pkg == 'pythoninterp':
|
||||||
|
inherits.append('pythonnative')
|
||||||
|
elif pkg == 'pythonlibs':
|
||||||
|
inherits.append('python-dir')
|
||||||
|
else:
|
||||||
|
dep = cmake_pkgmap.get(pkg, None)
|
||||||
|
if dep:
|
||||||
|
deps.append(dep)
|
||||||
|
elif dep is None:
|
||||||
|
unmappedpkgs.append(origpkg)
|
||||||
|
continue
|
||||||
|
res = checklib_re.match(line)
|
||||||
|
if res:
|
||||||
|
lib = res.group(1)
|
||||||
|
if not lib.startswith('$'):
|
||||||
|
libdeps.append(lib)
|
||||||
|
if line.lower().startswith('useswig'):
|
||||||
|
deps.append('swig-native')
|
||||||
|
continue
|
||||||
|
|
||||||
|
parse_cmake_file(srcfiles[0])
|
||||||
|
|
||||||
|
if unmappedpkgs:
|
||||||
|
outlines.append('# NOTE: unable to map the following CMake package dependencies: %s' % ' '.join(unmappedpkgs))
|
||||||
|
|
||||||
|
RecipeHandler.handle_depends(libdeps, pcdeps, deps, outlines, values, tinfoil.config_data)
|
||||||
|
|
||||||
|
if inherits:
|
||||||
|
values['inherit'] = ' '.join(list(set(inherits)))
|
||||||
|
|
||||||
return values
|
return values
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user