summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Purdie <richard.purdie@linuxfoundation.org>2022-08-10 14:34:22 +0100
committerRichard Purdie <richard.purdie@linuxfoundation.org>2022-08-12 11:49:29 +0100
commit7bd328f9d24b4fb23c7d5de50bddbb60828c9ffc (patch)
tree243a5d896a1b005deb35bd5d7bb167b86d0cdd23
parente19ce4191d94646e35386a5f2179c02ef8dc1cb6 (diff)
downloadpoky-7bd328f9d24b4fb23c7d5de50bddbb60828c9ffc.tar.gz
bitbake: BBHandler/cooker: Implement recipe and global classes
We have some confusion for users since some classes are meant to work in the configuration space (or "globally") and some are meant to be selected by recipes individually. The cleanest way I could find to clarify this is to create "classes-global" and "classes-recipe" directories which contain the approproate classes and have bitbake switch scope between them at the appropriate point during parsing. The existing "classes" directory is always searched as a fallback. Once a class is moved to a specific directory, it will no longer be found in the incorrect context. A good example from OE is that INHERIT += "testimage" will no longer work but IMAGE_CLASSES += "testimage" will, which makes the global scope cleaner by only including it where it is useful and intended to be used (images). (Bitbake rev: f33ce7e742f46635658c400b82558cf822690b5e) Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
-rwxr-xr-xbitbake/bin/bitbake-worker1
-rw-r--r--bitbake/lib/bb/cooker.py1
-rw-r--r--bitbake/lib/bb/cookerdata.py1
-rw-r--r--bitbake/lib/bb/data.py2
-rw-r--r--bitbake/lib/bb/parse/parse_py/BBHandler.py29
-rw-r--r--bitbake/lib/bb/tests/parse.py1
-rw-r--r--bitbake/lib/bblayers/query.py26
7 files changed, 39 insertions, 22 deletions
diff --git a/bitbake/bin/bitbake-worker b/bitbake/bin/bitbake-worker
index 2f3e9f72f9..7be39370b3 100755
--- a/bitbake/bin/bitbake-worker
+++ b/bitbake/bin/bitbake-worker
@@ -457,6 +457,7 @@ class BitbakeWorker(object):
457 for mc in self.databuilder.mcdata: 457 for mc in self.databuilder.mcdata:
458 self.databuilder.mcdata[mc].setVar("PRSERV_HOST", self.workerdata["prhost"]) 458 self.databuilder.mcdata[mc].setVar("PRSERV_HOST", self.workerdata["prhost"])
459 self.databuilder.mcdata[mc].setVar("BB_HASHSERVE", self.workerdata["hashservaddr"]) 459 self.databuilder.mcdata[mc].setVar("BB_HASHSERVE", self.workerdata["hashservaddr"])
460 self.databuilder.mcdata[mc].setVar("__bbclasstype", "recipe")
460 461
461 def handle_newtaskhashes(self, data): 462 def handle_newtaskhashes(self, data):
462 self.workerdata["newhashes"] = pickle.loads(data) 463 self.workerdata["newhashes"] = pickle.loads(data)
diff --git a/bitbake/lib/bb/cooker.py b/bitbake/lib/bb/cooker.py
index 2adf4d297d..1b6ee3032c 100644
--- a/bitbake/lib/bb/cooker.py
+++ b/bitbake/lib/bb/cooker.py
@@ -402,6 +402,7 @@ class BBCooker:
402 for mc in self.databuilder.mcdata.values(): 402 for mc in self.databuilder.mcdata.values():
403 mc.renameVar("__depends", "__base_depends") 403 mc.renameVar("__depends", "__base_depends")
404 self.add_filewatch(mc.getVar("__base_depends", False), self.configwatcher) 404 self.add_filewatch(mc.getVar("__base_depends", False), self.configwatcher)
405 mc.setVar("__bbclasstype", "recipe")
405 406
406 self.baseconfig_valid = True 407 self.baseconfig_valid = True
407 self.parsecache_valid = False 408 self.parsecache_valid = False
diff --git a/bitbake/lib/bb/cookerdata.py b/bitbake/lib/bb/cookerdata.py
index d54ac932e5..9706948ab3 100644
--- a/bitbake/lib/bb/cookerdata.py
+++ b/bitbake/lib/bb/cookerdata.py
@@ -254,6 +254,7 @@ class CookerDataBuilder(object):
254 filtered_keys = bb.utils.approved_variables() 254 filtered_keys = bb.utils.approved_variables()
255 bb.data.inheritFromOS(self.basedata, self.savedenv, filtered_keys) 255 bb.data.inheritFromOS(self.basedata, self.savedenv, filtered_keys)
256 self.basedata.setVar("BB_ORIGENV", self.savedenv) 256 self.basedata.setVar("BB_ORIGENV", self.savedenv)
257 self.basedata.setVar("__bbclasstype", "global")
257 258
258 if worker: 259 if worker:
259 self.basedata.setVar("BB_WORKERCONTEXT", "1") 260 self.basedata.setVar("BB_WORKERCONTEXT", "1")
diff --git a/bitbake/lib/bb/data.py b/bitbake/lib/bb/data.py
index c09d9b04bb..53fe34825d 100644
--- a/bitbake/lib/bb/data.py
+++ b/bitbake/lib/bb/data.py
@@ -441,7 +441,7 @@ def generate_dependency_hash(tasklist, gendeps, lookupcache, ignored_vars, fn):
441 441
442def inherits_class(klass, d): 442def inherits_class(klass, d):
443 val = d.getVar('__inherit_cache', False) or [] 443 val = d.getVar('__inherit_cache', False) or []
444 needle = os.path.join('classes', '%s.bbclass' % klass) 444 needle = '/%s.bbclass' % klass
445 for v in val: 445 for v in val:
446 if v.endswith(needle): 446 if v.endswith(needle):
447 return True 447 return True
diff --git a/bitbake/lib/bb/parse/parse_py/BBHandler.py b/bitbake/lib/bb/parse/parse_py/BBHandler.py
index 1189114341..18e6868387 100644
--- a/bitbake/lib/bb/parse/parse_py/BBHandler.py
+++ b/bitbake/lib/bb/parse/parse_py/BBHandler.py
@@ -44,17 +44,24 @@ def inherit(files, fn, lineno, d):
44 __inherit_cache = d.getVar('__inherit_cache', False) or [] 44 __inherit_cache = d.getVar('__inherit_cache', False) or []
45 files = d.expand(files).split() 45 files = d.expand(files).split()
46 for file in files: 46 for file in files:
47 if not os.path.isabs(file) and not file.endswith(".bbclass"): 47 classtype = d.getVar("__bbclasstype", False)
48 file = os.path.join('classes', '%s.bbclass' % file) 48 origfile = file
49 49 for t in ["classes-" + classtype, "classes"]:
50 if not os.path.isabs(file): 50 file = origfile
51 bbpath = d.getVar("BBPATH") 51 if not os.path.isabs(file) and not file.endswith(".bbclass"):
52 abs_fn, attempts = bb.utils.which(bbpath, file, history=True) 52 file = os.path.join(t, '%s.bbclass' % file)
53 for af in attempts: 53
54 if af != abs_fn: 54 if not os.path.isabs(file):
55 bb.parse.mark_dependency(d, af) 55 bbpath = d.getVar("BBPATH")
56 if abs_fn: 56 abs_fn, attempts = bb.utils.which(bbpath, file, history=True)
57 file = abs_fn 57 for af in attempts:
58 if af != abs_fn:
59 bb.parse.mark_dependency(d, af)
60 if abs_fn:
61 file = abs_fn
62
63 if os.path.exists(file):
64 break
58 65
59 if not os.path.exists(file): 66 if not os.path.exists(file):
60 raise ParseError("Could not inherit file %s" % (file), fn, lineno) 67 raise ParseError("Could not inherit file %s" % (file), fn, lineno)
diff --git a/bitbake/lib/bb/tests/parse.py b/bitbake/lib/bb/tests/parse.py
index 1a3b74934d..ee7f2534f1 100644
--- a/bitbake/lib/bb/tests/parse.py
+++ b/bitbake/lib/bb/tests/parse.py
@@ -164,6 +164,7 @@ python () {
164 # become unset/disappear. 164 # become unset/disappear.
165 # 165 #
166 def test_parse_classextend_contamination(self): 166 def test_parse_classextend_contamination(self):
167 self.d.setVar("__bbclasstype", "recipe")
167 cls = self.parsehelper(self.classextend_bbclass, suffix=".bbclass") 168 cls = self.parsehelper(self.classextend_bbclass, suffix=".bbclass")
168 #clsname = os.path.basename(cls.name).replace(".bbclass", "") 169 #clsname = os.path.basename(cls.name).replace(".bbclass", "")
169 self.classextend = self.classextend.replace("###CLASS###", cls.name) 170 self.classextend = self.classextend.replace("###CLASS###", cls.name)
diff --git a/bitbake/lib/bblayers/query.py b/bitbake/lib/bblayers/query.py
index 9142ec4474..afd39518e5 100644
--- a/bitbake/lib/bblayers/query.py
+++ b/bitbake/lib/bblayers/query.py
@@ -57,11 +57,12 @@ are overlayed will also be listed, with a " (skipped)" suffix.
57 # Check for overlayed .bbclass files 57 # Check for overlayed .bbclass files
58 classes = collections.defaultdict(list) 58 classes = collections.defaultdict(list)
59 for layerdir in self.bblayers: 59 for layerdir in self.bblayers:
60 classdir = os.path.join(layerdir, 'classes') 60 for c in ["classes-global", "classes-recipe", "classes"]:
61 if os.path.exists(classdir): 61 classdir = os.path.join(layerdir, c)
62 for classfile in os.listdir(classdir): 62 if os.path.exists(classdir):
63 if os.path.splitext(classfile)[1] == '.bbclass': 63 for classfile in os.listdir(classdir):
64 classes[classfile].append(classdir) 64 if os.path.splitext(classfile)[1] == '.bbclass':
65 classes[classfile].append(classdir)
65 66
66 # Locating classes and other files is a bit more complicated than recipes - 67 # Locating classes and other files is a bit more complicated than recipes -
67 # layer priority is not a factor; instead BitBake uses the first matching 68 # layer priority is not a factor; instead BitBake uses the first matching
@@ -124,9 +125,14 @@ skipped recipes will also be listed, with a " (skipped)" suffix.
124 if inherits: 125 if inherits:
125 bbpath = str(self.tinfoil.config_data.getVar('BBPATH')) 126 bbpath = str(self.tinfoil.config_data.getVar('BBPATH'))
126 for classname in inherits: 127 for classname in inherits:
127 classfile = 'classes/%s.bbclass' % classname 128 found = False
128 if not bb.utils.which(bbpath, classfile, history=False): 129 for c in ["classes-global", "classes-recipe", "classes"]:
129 logger.error('No class named %s found in BBPATH', classfile) 130 cfile = c + '/%s.bbclass' % classname
131 if bb.utils.which(bbpath, cfile, history=False):
132 found = True
133 break
134 if not found:
135 logger.error('No class named %s found in BBPATH', classname)
130 sys.exit(1) 136 sys.exit(1)
131 137
132 pkg_pn = self.tinfoil.cooker.recipecaches[mc].pkg_pn 138 pkg_pn = self.tinfoil.cooker.recipecaches[mc].pkg_pn
@@ -174,7 +180,7 @@ skipped recipes will also be listed, with a " (skipped)" suffix.
174 logger.plain(" %s %s%s", layer.ljust(20), ver, skipped) 180 logger.plain(" %s %s%s", layer.ljust(20), ver, skipped)
175 181
176 global_inherit = (self.tinfoil.config_data.getVar('INHERIT') or "").split() 182 global_inherit = (self.tinfoil.config_data.getVar('INHERIT') or "").split()
177 cls_re = re.compile('classes/') 183 cls_re = re.compile('classes.*/')
178 184
179 preffiles = [] 185 preffiles = []
180 show_unique_pn = [] 186 show_unique_pn = []
@@ -407,7 +413,7 @@ NOTE: .bbappend files can impact the dependencies.
407 self.check_cross_depends("RRECOMMENDS", layername, f, best, args.filenames, ignore_layers) 413 self.check_cross_depends("RRECOMMENDS", layername, f, best, args.filenames, ignore_layers)
408 414
409 # The inherit class 415 # The inherit class
410 cls_re = re.compile('classes/') 416 cls_re = re.compile('classes.*/')
411 if f in self.tinfoil.cooker_data.inherits: 417 if f in self.tinfoil.cooker_data.inherits:
412 inherits = self.tinfoil.cooker_data.inherits[f] 418 inherits = self.tinfoil.cooker_data.inherits[f]
413 for cls in inherits: 419 for cls in inherits: