]> git.ipfire.org Git - people/ms/u-boot.git/blame - tools/buildman/board.py
Merge git://git.denx.de/u-boot-fsl-qoriq
[people/ms/u-boot.git] / tools / buildman / board.py
CommitLineData
fc3fe1c2
SG
1# Copyright (c) 2012 The Chromium OS Authors.
2#
1a459660 3# SPDX-License-Identifier: GPL-2.0+
fc3fe1c2
SG
4#
5
8426d8b0
SW
6import re
7
6131beab
SG
8class Expr:
9 """A single regular expression for matching boards to build"""
10
11 def __init__(self, expr):
12 """Set up a new Expr object.
13
14 Args:
15 expr: String cotaining regular expression to store
16 """
17 self._expr = expr
18 self._re = re.compile(expr)
19
20 def Matches(self, props):
21 """Check if any of the properties match the regular expression.
22
23 Args:
24 props: List of properties to check
25 Returns:
26 True if any of the properties match the regular expression
27 """
28 for prop in props:
29 if self._re.match(prop):
30 return True
31 return False
32
33 def __str__(self):
34 return self._expr
35
36class Term:
37 """A list of expressions each of which must match with properties.
38
39 This provides a list of 'AND' expressions, meaning that each must
40 match the board properties for that board to be built.
41 """
42 def __init__(self):
43 self._expr_list = []
44 self._board_count = 0
45
46 def AddExpr(self, expr):
47 """Add an Expr object to the list to check.
48
49 Args:
50 expr: New Expr object to add to the list of those that must
51 match for a board to be built.
52 """
53 self._expr_list.append(Expr(expr))
54
55 def __str__(self):
56 """Return some sort of useful string describing the term"""
57 return '&'.join([str(expr) for expr in self._expr_list])
58
59 def Matches(self, props):
60 """Check if any of the properties match this term
61
62 Each of the expressions in the term is checked. All must match.
63
64 Args:
65 props: List of properties to check
66 Returns:
67 True if all of the expressions in the Term match, else False
68 """
69 for expr in self._expr_list:
70 if not expr.Matches(props):
71 return False
72 return True
73
fc3fe1c2
SG
74class Board:
75 """A particular board that we can build"""
03c1bb24 76 def __init__(self, status, arch, cpu, soc, vendor, board_name, target, options):
fc3fe1c2
SG
77 """Create a new board type.
78
79 Args:
03c1bb24 80 status: define whether the board is 'Active' or 'Orphaned'
fc3fe1c2
SG
81 arch: Architecture name (e.g. arm)
82 cpu: Cpu name (e.g. arm1136)
fc3fe1c2 83 soc: Name of SOC, or '' if none (e.g. mx31)
03c1bb24
AB
84 vendor: Name of vendor (e.g. armltd)
85 board_name: Name of board (e.g. integrator)
73f30b9b 86 target: Target name (use make <target>_defconfig to configure)
fc3fe1c2
SG
87 options: board-specific options (e.g. integratorcp:CM1136)
88 """
89 self.target = target
90 self.arch = arch
91 self.cpu = cpu
92 self.board_name = board_name
93 self.vendor = vendor
94 self.soc = soc
fc3fe1c2 95 self.options = options
e0f2406e
TR
96 self.props = [self.target, self.arch, self.cpu, self.board_name,
97 self.vendor, self.soc, self.options]
fc3fe1c2
SG
98 self.build_it = False
99
100
101class Boards:
102 """Manage a list of boards."""
103 def __init__(self):
104 # Use a simple list here, sinc OrderedDict requires Python 2.7
105 self._boards = []
106
107 def AddBoard(self, board):
108 """Add a new board to the list.
109
110 The board's target member must not already exist in the board list.
111
112 Args:
113 board: board to add
114 """
115 self._boards.append(board)
116
117 def ReadBoards(self, fname):
118 """Read a list of boards from a board file.
119
120 Create a board object for each and add it to our _boards list.
121
122 Args:
123 fname: Filename of boards.cfg file
124 """
125 with open(fname, 'r') as fd:
126 for line in fd:
127 if line[0] == '#':
128 continue
129 fields = line.split()
130 if not fields:
131 continue
132 for upto in range(len(fields)):
133 if fields[upto] == '-':
134 fields[upto] = ''
03c1bb24 135 while len(fields) < 8:
fc3fe1c2 136 fields.append('')
03c1bb24
AB
137 if len(fields) > 8:
138 fields = fields[:8]
fc3fe1c2
SG
139
140 board = Board(*fields)
141 self.AddBoard(board)
142
143
144 def GetList(self):
145 """Return a list of available boards.
146
147 Returns:
148 List of Board objects
149 """
150 return self._boards
151
152 def GetDict(self):
153 """Build a dictionary containing all the boards.
154
155 Returns:
156 Dictionary:
157 key is board.target
158 value is board
159 """
160 board_dict = {}
161 for board in self._boards:
162 board_dict[board.target] = board
163 return board_dict
164
165 def GetSelectedDict(self):
166 """Return a dictionary containing the selected boards
167
168 Returns:
169 List of Board objects that are marked selected
170 """
171 board_dict = {}
172 for board in self._boards:
173 if board.build_it:
174 board_dict[board.target] = board
175 return board_dict
176
177 def GetSelected(self):
178 """Return a list of selected boards
179
180 Returns:
181 List of Board objects that are marked selected
182 """
183 return [board for board in self._boards if board.build_it]
184
185 def GetSelectedNames(self):
186 """Return a list of selected boards
187
188 Returns:
189 List of board names that are marked selected
190 """
191 return [board.target for board in self._boards if board.build_it]
192
6131beab
SG
193 def _BuildTerms(self, args):
194 """Convert command line arguments to a list of terms.
195
196 This deals with parsing of the arguments. It handles the '&'
197 operator, which joins several expressions into a single Term.
198
199 For example:
200 ['arm & freescale sandbox', 'tegra']
201
202 will produce 3 Terms containing expressions as follows:
203 arm, freescale
204 sandbox
205 tegra
206
207 The first Term has two expressions, both of which must match for
208 a board to be selected.
209
210 Args:
211 args: List of command line arguments
212 Returns:
213 A list of Term objects
214 """
215 syms = []
216 for arg in args:
217 for word in arg.split():
218 sym_build = []
219 for term in word.split('&'):
220 if term:
221 sym_build.append(term)
222 sym_build.append('&')
223 syms += sym_build[:-1]
224 terms = []
225 term = None
226 oper = None
227 for sym in syms:
228 if sym == '&':
229 oper = sym
230 elif oper:
231 term.AddExpr(sym)
232 oper = None
233 else:
234 if term:
235 terms.append(term)
236 term = Term()
237 term.AddExpr(sym)
238 if term:
239 terms.append(term)
240 return terms
241
3cf4ae6f 242 def SelectBoards(self, args, exclude=[]):
fc3fe1c2
SG
243 """Mark boards selected based on args
244
245 Args:
3cf4ae6f
SG
246 args: List of strings specifying boards to include, either named,
247 or by their target, architecture, cpu, vendor or soc. If
248 empty, all boards are selected.
249 exclude: List of boards to exclude, regardless of 'args'
fc3fe1c2
SG
250
251 Returns:
8d7523c5 252 Dictionary which holds the list of boards which were selected
fc3fe1c2
SG
253 due to each argument, arranged by argument.
254 """
255 result = {}
6131beab
SG
256 terms = self._BuildTerms(args)
257
8d7523c5 258 result['all'] = []
6131beab 259 for term in terms:
8d7523c5 260 result[str(term)] = []
fc3fe1c2 261
3cf4ae6f
SG
262 exclude_list = []
263 for expr in exclude:
264 exclude_list.append(Expr(expr))
265
fc3fe1c2 266 for board in self._boards:
3cf4ae6f
SG
267 matching_term = None
268 build_it = False
6131beab
SG
269 if terms:
270 match = False
271 for term in terms:
272 if term.Matches(board.props):
3cf4ae6f
SG
273 matching_term = str(term)
274 build_it = True
6131beab 275 break
fc3fe1c2 276 else:
3cf4ae6f
SG
277 build_it = True
278
279 # Check that it is not specifically excluded
280 for expr in exclude_list:
281 if expr.Matches(board.props):
282 build_it = False
283 break
284
285 if build_it:
fc3fe1c2 286 board.build_it = True
3cf4ae6f 287 if matching_term:
8d7523c5
SG
288 result[matching_term].append(board.target)
289 result['all'].append(board.target)
fc3fe1c2
SG
290
291 return result