1 # SPDX-License-Identifier: GPL-2.0+
2 # Copyright (c) 2012 The Chromium OS Authors.
4 from collections import OrderedDict
8 """A single regular expression for matching boards to build"""
10 def __init__(self, expr):
11 """Set up a new Expr object.
14 expr: String cotaining regular expression to store
17 self._re = re.compile(expr)
19 def Matches(self, props):
20 """Check if any of the properties match the regular expression.
23 props: List of properties to check
25 True if any of the properties match the regular expression
28 if self._re.match(prop):
36 """A list of expressions each of which must match with properties.
38 This provides a list of 'AND' expressions, meaning that each must
39 match the board properties for that board to be built.
45 def AddExpr(self, expr):
46 """Add an Expr object to the list to check.
49 expr: New Expr object to add to the list of those that must
50 match for a board to be built.
52 self._expr_list.append(Expr(expr))
55 """Return some sort of useful string describing the term"""
56 return '&'.join([str(expr) for expr in self._expr_list])
58 def Matches(self, props):
59 """Check if any of the properties match this term
61 Each of the expressions in the term is checked. All must match.
64 props: List of properties to check
66 True if all of the expressions in the Term match, else False
68 for expr in self._expr_list:
69 if not expr.Matches(props):
74 """A particular board that we can build"""
75 def __init__(self, status, arch, cpu, soc, vendor, board_name, target, options):
76 """Create a new board type.
79 status: define whether the board is 'Active' or 'Orphaned'
80 arch: Architecture name (e.g. arm)
81 cpu: Cpu name (e.g. arm1136)
82 soc: Name of SOC, or '' if none (e.g. mx31)
83 vendor: Name of vendor (e.g. armltd)
84 board_name: Name of board (e.g. integrator)
85 target: Target name (use make <target>_defconfig to configure)
86 options: board-specific options (e.g. integratorcp:CM1136)
91 self.board_name = board_name
94 self.options = options
95 self.props = [self.target, self.arch, self.cpu, self.board_name,
96 self.vendor, self.soc, self.options]
101 """Manage a list of boards."""
103 # Use a simple list here, sinc OrderedDict requires Python 2.7
106 def AddBoard(self, brd):
107 """Add a new board to the list.
109 The board's target member must not already exist in the board list.
114 self._boards.append(brd)
116 def ReadBoards(self, fname):
117 """Read a list of boards from a board file.
119 Create a Board object for each and add it to our _boards list.
122 fname: Filename of boards.cfg file
124 with open(fname, 'r', encoding='utf-8') as fd:
128 fields = line.split()
131 for upto in range(len(fields)):
132 if fields[upto] == '-':
134 while len(fields) < 8:
144 """Return a list of available boards.
147 List of Board objects
152 """Build a dictionary containing all the boards.
159 board_dict = OrderedDict()
160 for brd in self._boards:
161 board_dict[brd.target] = brd
164 def GetSelectedDict(self):
165 """Return a dictionary containing the selected boards
168 List of Board objects that are marked selected
170 board_dict = OrderedDict()
171 for brd in self._boards:
173 board_dict[brd.target] = brd
176 def GetSelected(self):
177 """Return a list of selected boards
180 List of Board objects that are marked selected
182 return [brd for brd in self._boards if brd.build_it]
184 def GetSelectedNames(self):
185 """Return a list of selected boards
188 List of board names that are marked selected
190 return [brd.target for brd in self._boards if brd.build_it]
192 def _BuildTerms(self, args):
193 """Convert command line arguments to a list of terms.
195 This deals with parsing of the arguments. It handles the '&'
196 operator, which joins several expressions into a single Term.
199 ['arm & freescale sandbox', 'tegra']
201 will produce 3 Terms containing expressions as follows:
206 The first Term has two expressions, both of which must match for
207 a board to be selected.
210 args: List of command line arguments
212 A list of Term objects
216 for word in arg.split():
218 for term in word.split('&'):
220 sym_build.append(term)
221 sym_build.append('&')
222 syms += sym_build[:-1]
241 def SelectBoards(self, args, exclude=[], brds=None):
242 """Mark boards selected based on args
244 Normally either boards (an explicit list of boards) or args (a list of
245 terms to match against) is used. It is possible to specify both, in
246 which case they are additive.
248 If brds and args are both empty, all boards are selected.
251 args: List of strings specifying boards to include, either named,
252 or by their target, architecture, cpu, vendor or soc. If
253 empty, all boards are selected.
254 exclude: List of boards to exclude, regardless of 'args'
255 brds: List of boards to build
259 Dictionary which holds the list of boards which were selected
260 due to each argument, arranged by argument.
263 result = OrderedDict()
265 terms = self._BuildTerms(args)
269 result[str(term)] = []
273 exclude_list.append(Expr(expr))
276 for brd in self._boards:
282 if term.Matches(brd.props):
283 matching_term = str(term)
287 if brd.target in brds:
289 found.append(brd.target)
293 # Check that it is not specifically excluded
294 for expr in exclude_list:
295 if expr.Matches(brd.props):
302 result[matching_term].append(brd.target)
303 result['all'].append(brd.target)
306 remaining = set(brds) - set(found)
308 warnings.append('Boards not found: %s\n' % ', '.join(remaining))
310 return result, warnings