From: Alexander Kanavin Date: Wed, 17 Jul 2024 18:22:14 +0000 (+0200) Subject: lib/recipeutils: add a function to determine recipes with shared include files X-Git-Tag: uninative-4.6~7 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2400920f8b84cca9d6c1f6a2e850630554fe00fa;p=thirdparty%2Fopenembedded%2Fopenembedded-core.git lib/recipeutils: add a function to determine recipes with shared include files This functionality is needed for 'lockstep version upgrades' where several recipes need to be upgraded at the same time to produce a buildable outcome. The function itself obtains BBINCLUDED for each recipe and then massages the data until it takes the form of a list of sets: [{'cmake','cmake-native'}, {'qemu','qemu-native','qemu-system-native'}, ... ] There's also a selftest that checks for the above. Unfortunately this won't detect mutually exclusive recipes like mesa and mesa-gl as they're chosen with PREFERRED_PROVIDER and can't be enabled in the same build at the same time. ('devtool upgrade' will also accept just one of them but not the other) Signed-off-by: Alexander Kanavin Signed-off-by: Richard Purdie --- diff --git a/meta/lib/oe/recipeutils.py b/meta/lib/oe/recipeutils.py index f9d7dfe253a..7586332fe0c 100644 --- a/meta/lib/oe/recipeutils.py +++ b/meta/lib/oe/recipeutils.py @@ -1183,3 +1183,40 @@ def get_recipe_upgrade_status(recipes=None): pkgs_list = executor.map(_get_recipe_upgrade_status, data_copy_list) return pkgs_list + +def get_common_include_recipes(): + with bb.tinfoil.Tinfoil() as tinfoil: + tinfoil.prepare(config_only=False) + + recipes = tinfoil.all_recipe_files(variants=False) + + recipeincludes = {} + for fn in recipes: + data = tinfoil.parse_recipe_file(fn) + recipeincludes[fn] = {'bbincluded':data.getVar('BBINCLUDED').split(),'pn':data.getVar('PN')} + return _get_common_include_recipes(recipeincludes) + +def _get_common_include_recipes(recipeincludes_all): + recipeincludes = {} + for fn,data in recipeincludes_all.items(): + bbincluded_filtered = [i for i in data['bbincluded'] if os.path.dirname(i) == os.path.dirname(fn) and i != fn] + if bbincluded_filtered: + recipeincludes[data['pn']] = bbincluded_filtered + + recipeincludes_inverted = {} + for k,v in recipeincludes.items(): + for i in v: + recipeincludes_inverted.setdefault(i,set()).add(k) + + recipeincludes_inverted_filtered = {k:v for k,v in recipeincludes_inverted.items() if len(v) > 1} + + recipes_with_shared_includes = list() + for v in recipeincludes_inverted_filtered.values(): + recipeset = v + for v1 in recipeincludes_inverted_filtered.values(): + if recipeset.intersection(v1): + recipeset.update(v1) + if recipeset not in recipes_with_shared_includes: + recipes_with_shared_includes.append(recipeset) + + return recipes_with_shared_includes diff --git a/meta/lib/oeqa/selftest/cases/distrodata.py b/meta/lib/oeqa/selftest/cases/distrodata.py index b60913dbca4..bc561605220 100644 --- a/meta/lib/oeqa/selftest/cases/distrodata.py +++ b/meta/lib/oeqa/selftest/cases/distrodata.py @@ -115,3 +115,15 @@ The list of oe-core recipes with maintainers is empty. This may indicate that th self.fail(""" Unable to find recipes for the following entries in maintainers.inc: """ + "\n".join(['%s' % i for i in missing_recipes])) + + def test_common_include_recipes(self): + """ + Summary: Test that obtaining recipes that share includes between them returns a sane result + Expected: At least cmake and qemu entries are present in the output + Product: oe-core + Author: Alexander Kanavin + """ + recipes = oe.recipeutils.get_common_include_recipes() + + self.assertIn({'qemu-system-native', 'qemu', 'qemu-native'}, recipes) + self.assertIn({'cmake-native', 'cmake'}, recipes)