summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Purdie <richard.purdie@linuxfoundation.org>2022-11-27 17:08:04 +0000
committerRichard Purdie <richard.purdie@linuxfoundation.org>2022-12-08 11:15:47 +0000
commit42e8b2682f56f450c1258956213198052d6bcb96 (patch)
tree6e1e223a179f5df5651fe3742b0e8afa55339597
parentf4ffba353eb7877060c25d264fa10cd60f797f0b (diff)
downloadpoky-42e8b2682f56f450c1258956213198052d6bcb96.tar.gz
bitbake: parse: Add support for addpylib conf file directive and BB_GLOBAL_PYMODULES
For many years OE-Core has injected it's own python modules into the python namespace using an immediate expansion of a variable in base.bbclass. It also added all entries from BBPATH to sys.path. We really need this to become a first class citizen of the langauge, this new addpylib directive allows that. Usage is of the form: addpylib <directory> <namespace> The namespace is imported and if there is an attribute BBIMPORT, that list of names is iterated and imported too. This mirrors what OE-Core has done for a long time with one difference in implmentation, sys.path is only appended to. This means later imported namespaces can't overwrite an earlier one and can't overwrite the main python module space. In practice we've never done that and it isn't something we should encourage or support. The new directive is only applied for .conf files and not other filetypes as it only makes sense in that context. It is also only allowed in the "base configuration" context of cookerdata since adding it at the recipe level wouldn't work properly due to the way it changes the global namespace. At the same time, move the list of modules to place in the global namespace into a BB_GLOBAL_PYMODULES variable. It is intended that only the core layer should touch this and it is meant to be a very small list, usually os and sys. BB_GLOBAL_PYMODULES is expected to be set before the first addpylib directive. Layers adding a lib directory will now need to use this directive as BBPATH is not going to be added automatically by OE-Core in future. The directives are immediate operations so it does make modules available sooner than the current OE-Core approach. The new code appends to sys.path rather than prepends as core did, as overwriting python standard library modules would be a bad idea and naturally encouraging people to collaborate around our own core modules is desireable. (Bitbake rev: afb8478d3853f6edf3669b93588314627d617d6b) Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
-rw-r--r--bitbake/lib/bb/cookerdata.py2
-rw-r--r--bitbake/lib/bb/parse/__init__.py4
-rw-r--r--bitbake/lib/bb/parse/ast.py27
-rw-r--r--bitbake/lib/bb/parse/parse_py/BBHandler.py4
-rw-r--r--bitbake/lib/bb/parse/parse_py/ConfHandler.py14
5 files changed, 43 insertions, 8 deletions
diff --git a/bitbake/lib/bb/cookerdata.py b/bitbake/lib/bb/cookerdata.py
index c322ab2ffb..28cb59d83a 100644
--- a/bitbake/lib/bb/cookerdata.py
+++ b/bitbake/lib/bb/cookerdata.py
@@ -184,7 +184,7 @@ def catch_parse_error(func):
184 184
185@catch_parse_error 185@catch_parse_error
186def parse_config_file(fn, data, include=True): 186def parse_config_file(fn, data, include=True):
187 return bb.parse.handle(fn, data, include) 187 return bb.parse.handle(fn, data, include, baseconfig=True)
188 188
189@catch_parse_error 189@catch_parse_error
190def _inherit(bbclass, data): 190def _inherit(bbclass, data):
diff --git a/bitbake/lib/bb/parse/__init__.py b/bitbake/lib/bb/parse/__init__.py
index 347609513b..4cd82f115b 100644
--- a/bitbake/lib/bb/parse/__init__.py
+++ b/bitbake/lib/bb/parse/__init__.py
@@ -99,12 +99,12 @@ def supports(fn, data):
99 return 1 99 return 1
100 return 0 100 return 0
101 101
102def handle(fn, data, include = 0): 102def handle(fn, data, include=0, baseconfig=False):
103 """Call the handler that is appropriate for this file""" 103 """Call the handler that is appropriate for this file"""
104 for h in handlers: 104 for h in handlers:
105 if h['supports'](fn, data): 105 if h['supports'](fn, data):
106 with data.inchistory.include(fn): 106 with data.inchistory.include(fn):
107 return h['handle'](fn, data, include) 107 return h['handle'](fn, data, include, baseconfig)
108 raise ParseError("not a BitBake file", fn) 108 raise ParseError("not a BitBake file", fn)
109 109
110def init(fn, data): 110def init(fn, data):
diff --git a/bitbake/lib/bb/parse/ast.py b/bitbake/lib/bb/parse/ast.py
index 9e0a0f5c98..862087c77d 100644
--- a/bitbake/lib/bb/parse/ast.py
+++ b/bitbake/lib/bb/parse/ast.py
@@ -9,6 +9,7 @@
9# SPDX-License-Identifier: GPL-2.0-only 9# SPDX-License-Identifier: GPL-2.0-only
10# 10#
11 11
12import sys
12import bb 13import bb
13from bb import methodpool 14from bb import methodpool
14from bb.parse import logger 15from bb.parse import logger
@@ -269,6 +270,29 @@ class BBHandlerNode(AstNode):
269 data.setVarFlag(h, "handler", 1) 270 data.setVarFlag(h, "handler", 1)
270 data.setVar('__BBHANDLERS', bbhands) 271 data.setVar('__BBHANDLERS', bbhands)
271 272
273class PyLibNode(AstNode):
274 def __init__(self, filename, lineno, libdir, namespace):
275 AstNode.__init__(self, filename, lineno)
276 self.libdir = libdir
277 self.namespace = namespace
278
279 def eval(self, data):
280 global_mods = (data.getVar("BB_GLOBAL_PYMODULES") or "").split()
281 for m in global_mods:
282 if m not in bb.utils._context:
283 bb.utils._context[m] = __import__(m)
284
285 libdir = data.expand(self.libdir)
286 if libdir not in sys.path:
287 sys.path.append(libdir)
288 try:
289 bb.utils._context[self.namespace] = __import__(self.namespace)
290 toimport = getattr(bb.utils._context[self.namespace], "BBIMPORTS", [])
291 for i in toimport:
292 bb.utils._context[self.namespace] = __import__(self.namespace + "." + i)
293 except AttributeError as e:
294 bb.error("Error importing OE modules: %s" % str(e))
295
272class InheritNode(AstNode): 296class InheritNode(AstNode):
273 def __init__(self, filename, lineno, classes): 297 def __init__(self, filename, lineno, classes):
274 AstNode.__init__(self, filename, lineno) 298 AstNode.__init__(self, filename, lineno)
@@ -320,6 +344,9 @@ def handleDelTask(statements, filename, lineno, m):
320def handleBBHandlers(statements, filename, lineno, m): 344def handleBBHandlers(statements, filename, lineno, m):
321 statements.append(BBHandlerNode(filename, lineno, m.group(1))) 345 statements.append(BBHandlerNode(filename, lineno, m.group(1)))
322 346
347def handlePyLib(statements, filename, lineno, m):
348 statements.append(PyLibNode(filename, lineno, m.group(1), m.group(2)))
349
323def handleInherit(statements, filename, lineno, m): 350def handleInherit(statements, filename, lineno, m):
324 classes = m.group(1) 351 classes = m.group(1)
325 statements.append(InheritNode(filename, lineno, classes)) 352 statements.append(InheritNode(filename, lineno, classes))
diff --git a/bitbake/lib/bb/parse/parse_py/BBHandler.py b/bitbake/lib/bb/parse/parse_py/BBHandler.py
index 584966fea1..4d5b45e1ef 100644
--- a/bitbake/lib/bb/parse/parse_py/BBHandler.py
+++ b/bitbake/lib/bb/parse/parse_py/BBHandler.py
@@ -101,7 +101,7 @@ def get_statements(filename, absolute_filename, base_name):
101 cached_statements[absolute_filename] = statements 101 cached_statements[absolute_filename] = statements
102 return statements 102 return statements
103 103
104def handle(fn, d, include): 104def handle(fn, d, include, baseconfig=False):
105 global __infunc__, __body__, __residue__, __classname__ 105 global __infunc__, __body__, __residue__, __classname__
106 __body__ = [] 106 __body__ = []
107 __infunc__ = [] 107 __infunc__ = []
@@ -265,7 +265,7 @@ def feeder(lineno, s, fn, root, statements, eof=False):
265 ast.handleInherit(statements, fn, lineno, m) 265 ast.handleInherit(statements, fn, lineno, m)
266 return 266 return
267 267
268 return ConfHandler.feeder(lineno, s, fn, statements) 268 return ConfHandler.feeder(lineno, s, fn, statements, conffile=False)
269 269
270# Add us to the handlers list 270# Add us to the handlers list
271from .. import handlers 271from .. import handlers
diff --git a/bitbake/lib/bb/parse/parse_py/ConfHandler.py b/bitbake/lib/bb/parse/parse_py/ConfHandler.py
index 451e68dd66..3076067287 100644
--- a/bitbake/lib/bb/parse/parse_py/ConfHandler.py
+++ b/bitbake/lib/bb/parse/parse_py/ConfHandler.py
@@ -46,6 +46,7 @@ __require_regexp__ = re.compile( r"require\s+(.+)" )
46__export_regexp__ = re.compile( r"export\s+([a-zA-Z0-9\-_+.${}/~]+)$" ) 46__export_regexp__ = re.compile( r"export\s+([a-zA-Z0-9\-_+.${}/~]+)$" )
47__unset_regexp__ = re.compile( r"unset\s+([a-zA-Z0-9\-_+.${}/~]+)$" ) 47__unset_regexp__ = re.compile( r"unset\s+([a-zA-Z0-9\-_+.${}/~]+)$" )
48__unset_flag_regexp__ = re.compile( r"unset\s+([a-zA-Z0-9\-_+.${}/~]+)\[([a-zA-Z0-9\-_+.]+)\]$" ) 48__unset_flag_regexp__ = re.compile( r"unset\s+([a-zA-Z0-9\-_+.${}/~]+)\[([a-zA-Z0-9\-_+.]+)\]$" )
49__addpylib_regexp__ = re.compile(r"addpylib\s+(.+)\s+(.+)" )
49 50
50def init(data): 51def init(data):
51 return 52 return
@@ -107,7 +108,7 @@ def include_single_file(parentfn, fn, lineno, data, error_out):
107# parsing. This turns out to be a hard problem to solve any other way. 108# parsing. This turns out to be a hard problem to solve any other way.
108confFilters = [] 109confFilters = []
109 110
110def handle(fn, data, include): 111def handle(fn, data, include, baseconfig=False):
111 init(data) 112 init(data)
112 113
113 if include == 0: 114 if include == 0:
@@ -144,7 +145,7 @@ def handle(fn, data, include):
144 # skip comments 145 # skip comments
145 if s[0] == '#': 146 if s[0] == '#':
146 continue 147 continue
147 feeder(lineno, s, abs_fn, statements) 148 feeder(lineno, s, abs_fn, statements, baseconfig=baseconfig)
148 149
149 # DONE WITH PARSING... time to evaluate 150 # DONE WITH PARSING... time to evaluate
150 data.setVar('FILE', abs_fn) 151 data.setVar('FILE', abs_fn)
@@ -157,7 +158,9 @@ def handle(fn, data, include):
157 158
158 return data 159 return data
159 160
160def feeder(lineno, s, fn, statements): 161# baseconfig is set for the bblayers/layer.conf cookerdata config parsing
162# The function is also used by BBHandler, conffile would be False
163def feeder(lineno, s, fn, statements, baseconfig=False, conffile=True):
161 m = __config_regexp__.match(s) 164 m = __config_regexp__.match(s)
162 if m: 165 if m:
163 groupd = m.groupdict() 166 groupd = m.groupdict()
@@ -189,6 +192,11 @@ def feeder(lineno, s, fn, statements):
189 ast.handleUnsetFlag(statements, fn, lineno, m) 192 ast.handleUnsetFlag(statements, fn, lineno, m)
190 return 193 return
191 194
195 m = __addpylib_regexp__.match(s)
196 if baseconfig and conffile and m:
197 ast.handlePyLib(statements, fn, lineno, m)
198 return
199
192 raise ParseError("unparsed line: '%s'" % s, fn, lineno); 200 raise ParseError("unparsed line: '%s'" % s, fn, lineno);
193 201
194# Add us to the handlers list 202# Add us to the handlers list