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