]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - tools/buildman/board.py
Merge branch 'master' of git://git.denx.de/u-boot-arm
[karo-tx-uboot.git] / tools / buildman / board.py
1 # Copyright (c) 2012 The Chromium OS Authors.
2 #
3 # SPDX-License-Identifier:      GPL-2.0+
4 #
5
6 import re
7
8 class 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
36 class 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
74 class Board:
75     """A particular board that we can build"""
76     def __init__(self, status, arch, cpu, soc, vendor, board_name, target, options):
77         """Create a new board type.
78
79         Args:
80             status: define whether the board is 'Active' or 'Orphaned'
81             arch: Architecture name (e.g. arm)
82             cpu: Cpu name (e.g. arm1136)
83             soc: Name of SOC, or '' if none (e.g. mx31)
84             vendor: Name of vendor (e.g. armltd)
85             board_name: Name of board (e.g. integrator)
86             target: Target name (use make <target>_defconfig to configure)
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
95         self.props = [self.target, self.arch, self.cpu, self.board_name,
96                       self.vendor, self.soc]
97         self.options = options
98         self.build_it = False
99
100
101 class 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] = ''
135                 while len(fields) < 8:
136                     fields.append('')
137                 if len(fields) > 8:
138                     fields = fields[:8]
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
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
242     def SelectBoards(self, args, exclude=[]):
243         """Mark boards selected based on args
244
245         Args:
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'
250
251         Returns:
252             Dictionary which holds the number of boards which were selected
253             due to each argument, arranged by argument.
254         """
255         result = {}
256         terms = self._BuildTerms(args)
257
258         result['all'] = 0
259         for term in terms:
260             result[str(term)] = 0
261
262         exclude_list = []
263         for expr in exclude:
264             exclude_list.append(Expr(expr))
265
266         for board in self._boards:
267             matching_term = None
268             build_it = False
269             if terms:
270                 match = False
271                 for term in terms:
272                     if term.Matches(board.props):
273                         matching_term = str(term)
274                         build_it = True
275                         break
276             else:
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:
286                 board.build_it = True
287                 if matching_term:
288                     result[matching_term] += 1
289                 result['all'] += 1
290
291         return result