summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--tools/buildman/README9
-rw-r--r--tools/buildman/board.py144
-rw-r--r--tools/buildman/test.py48
3 files changed, 184 insertions, 17 deletions
diff --git a/tools/buildman/README b/tools/buildman/README
index aaf0a10..d4e8404 100644
--- a/tools/buildman/README
+++ b/tools/buildman/README
@@ -108,6 +108,15 @@ behaviour is a superset of exact or substring matching. Examples are:
* '^tegra[23]0$' All boards with either Tegra20 or Tegra30 SoC
* 'powerpc' All PowerPC boards
+While the default is to OR the terms together, you can also make use of
+the '&' operator to limit the selection:
+
+* 'freescale & arm sandbox' All Freescale boards with ARM architecture,
+ plus sandbox
+
+It is convenient to use the -n option to see whaat will be built based on
+the subset given.
+
Buildman does not store intermediate object files. It optionally copies
the binary output into a directory when a build is successful. Size
information is always recorded. It needs a fair bit of disk space to work,
diff --git a/tools/buildman/board.py b/tools/buildman/board.py
index 7bcc932..a333287 100644
--- a/tools/buildman/board.py
+++ b/tools/buildman/board.py
@@ -5,6 +5,72 @@
import re
+class Expr:
+ """A single regular expression for matching boards to build"""
+
+ def __init__(self, expr):
+ """Set up a new Expr object.
+
+ Args:
+ expr: String cotaining regular expression to store
+ """
+ self._expr = expr
+ self._re = re.compile(expr)
+
+ def Matches(self, props):
+ """Check if any of the properties match the regular expression.
+
+ Args:
+ props: List of properties to check
+ Returns:
+ True if any of the properties match the regular expression
+ """
+ for prop in props:
+ if self._re.match(prop):
+ return True
+ return False
+
+ def __str__(self):
+ return self._expr
+
+class Term:
+ """A list of expressions each of which must match with properties.
+
+ This provides a list of 'AND' expressions, meaning that each must
+ match the board properties for that board to be built.
+ """
+ def __init__(self):
+ self._expr_list = []
+ self._board_count = 0
+
+ def AddExpr(self, expr):
+ """Add an Expr object to the list to check.
+
+ Args:
+ expr: New Expr object to add to the list of those that must
+ match for a board to be built.
+ """
+ self._expr_list.append(Expr(expr))
+
+ def __str__(self):
+ """Return some sort of useful string describing the term"""
+ return '&'.join([str(expr) for expr in self._expr_list])
+
+ def Matches(self, props):
+ """Check if any of the properties match this term
+
+ Each of the expressions in the term is checked. All must match.
+
+ Args:
+ props: List of properties to check
+ Returns:
+ True if all of the expressions in the Term match, else False
+ """
+ for expr in self._expr_list:
+ if not expr.Matches(props):
+ return False
+ return True
+
class Board:
"""A particular board that we can build"""
def __init__(self, status, arch, cpu, soc, vendor, board_name, target, options):
@@ -124,6 +190,55 @@ class Boards:
"""
return [board.target for board in self._boards if board.build_it]
+ def _BuildTerms(self, args):
+ """Convert command line arguments to a list of terms.
+
+ This deals with parsing of the arguments. It handles the '&'
+ operator, which joins several expressions into a single Term.
+
+ For example:
+ ['arm & freescale sandbox', 'tegra']
+
+ will produce 3 Terms containing expressions as follows:
+ arm, freescale
+ sandbox
+ tegra
+
+ The first Term has two expressions, both of which must match for
+ a board to be selected.
+
+ Args:
+ args: List of command line arguments
+ Returns:
+ A list of Term objects
+ """
+ syms = []
+ for arg in args:
+ for word in arg.split():
+ sym_build = []
+ for term in word.split('&'):
+ if term:
+ sym_build.append(term)
+ sym_build.append('&')
+ syms += sym_build[:-1]
+ terms = []
+ term = None
+ oper = None
+ for sym in syms:
+ if sym == '&':
+ oper = sym
+ elif oper:
+ term.AddExpr(sym)
+ oper = None
+ else:
+ if term:
+ terms.append(term)
+ term = Term()
+ term.AddExpr(sym)
+ if term:
+ terms.append(term)
+ return terms
+
def SelectBoards(self, args):
"""Mark boards selected based on args
@@ -137,26 +252,21 @@ class Boards:
due to each argument, arranged by argument.
"""
result = {}
- argres = {}
- for arg in args:
- result[arg] = 0
- argres[arg] = re.compile(arg)
+ terms = self._BuildTerms(args)
+
result['all'] = 0
+ for term in terms:
+ result[str(term)] = 0
for board in self._boards:
- if args:
- for arg in args:
- argre = argres[arg]
- match = False
- for prop in board.props:
- match = argre.match(prop)
- if match:
- break
- if match:
- if not board.build_it:
- board.build_it = True
- result[arg] += 1
- result['all'] += 1
+ if terms:
+ match = False
+ for term in terms:
+ if term.Matches(board.props):
+ board.build_it = True
+ result[str(term)] += 1
+ result['all'] += 1
+ break
else:
board.build_it = True
result['all'] += 1
diff --git a/tools/buildman/test.py b/tools/buildman/test.py
index 502c9b4..a51c942 100644
--- a/tools/buildman/test.py
+++ b/tools/buildman/test.py
@@ -165,5 +165,53 @@ class TestBuild(unittest.TestCase):
args = ['tegra20']
control.DoBuildman(options, args)
+ def testBoardSingle(self):
+ """Test single board selection"""
+ self.assertEqual(self.boards.SelectBoards(['sandbox']),
+ {'all': 1, 'sandbox': 1})
+
+ def testBoardArch(self):
+ """Test single board selection"""
+ self.assertEqual(self.boards.SelectBoards(['arm']),
+ {'all': 2, 'arm': 2})
+
+ def testBoardArchSingle(self):
+ """Test single board selection"""
+ self.assertEqual(self.boards.SelectBoards(['arm sandbox']),
+ {'all': 3, 'arm': 2, 'sandbox' : 1})
+
+ def testBoardArchSingleMultiWord(self):
+ """Test single board selection"""
+ self.assertEqual(self.boards.SelectBoards(['arm', 'sandbox']),
+ {'all': 3, 'arm': 2, 'sandbox' : 1})
+
+ def testBoardSingleAnd(self):
+ """Test single board selection"""
+ self.assertEqual(self.boards.SelectBoards(['Tester & arm']),
+ {'all': 2, 'Tester&arm': 2})
+
+ def testBoardTwoAnd(self):
+ """Test single board selection"""
+ self.assertEqual(self.boards.SelectBoards(['Tester', '&', 'arm',
+ 'Tester' '&', 'powerpc',
+ 'sandbox']),
+ {'all': 5, 'Tester&powerpc': 2, 'Tester&arm': 2,
+ 'sandbox' : 1})
+
+ def testBoardAll(self):
+ """Test single board selection"""
+ self.assertEqual(self.boards.SelectBoards([]), {'all': 5})
+
+ def testBoardRegularExpression(self):
+ """Test single board selection"""
+ self.assertEqual(self.boards.SelectBoards(['T.*r&^Po']),
+ {'T.*r&^Po': 2, 'all': 2})
+
+ def testBoardDuplicate(self):
+ """Test single board selection"""
+ self.assertEqual(self.boards.SelectBoards(['sandbox sandbox',
+ 'sandbox']),
+ {'all': 1, 'sandbox': 1})
+
if __name__ == "__main__":
unittest.main()