buildman: Add a --boards option to specify particular boards to build
At present 'buildman sandbox' will build all 5 boards for the sandbox
architecture rather than the single board 'sandbox'. The only current way
to exclude sandbox_spl, sandbox_noblk, etc. is to use -x which is a bit
clumbsy.
Add a --boards option to allow individual build targets to be specified.
Signed-off-by: Simon Glass <sjg@chromium.org>
diff --git a/tools/buildman/README b/tools/buildman/README
index 7660190..5a709c6 100644
--- a/tools/buildman/README
+++ b/tools/buildman/README
@@ -114,6 +114,10 @@
plan to use your machine for anything else, you can use -T to increase the
number of threads beyond the default.
+
+Selecting which boards to build
+===============================
+
Buildman lets you build all boards, or a subset. Specify the subset by passing
command-line arguments that list the desired board name, architecture name,
SOC name, or anything else in the boards.cfg file. Multiple arguments are
@@ -138,11 +142,17 @@
means to build all arm boards except nvidia, freescale and anything ending
with 'ball'.
+For building specific boards you can use the --boards option, which takes a
+comma-separated list of board target names and be used multiple times on
+the command line:
+
+ buidman --boards sandbox,snow --boards
+
It is convenient to use the -n option to see what will be built based on
the subset given. Use -v as well to get an actual list of boards.
Buildman does not store intermediate object files. It optionally copies
-the binary output into a directory when a build is successful. Size
+the binary output into a directory when a build is successful (-k). Size
information is always recorded. It needs a fair bit of disk space to work,
typically 250MB per thread.
diff --git a/tools/buildman/board.py b/tools/buildman/board.py
index 272bac0..2a1d021 100644
--- a/tools/buildman/board.py
+++ b/tools/buildman/board.py
@@ -237,20 +237,30 @@
terms.append(term)
return terms
- def SelectBoards(self, args, exclude=[]):
+ def SelectBoards(self, args, exclude=[], boards=None):
"""Mark boards selected based on args
+ Normally either boards (an explicit list of boards) or args (a list of
+ terms to match against) is used. It is possible to specify both, in
+ which case they are additive.
+
+ If boards and args are both empty, all boards are selected.
+
Args:
args: List of strings specifying boards to include, either named,
or by their target, architecture, cpu, vendor or soc. If
empty, all boards are selected.
exclude: List of boards to exclude, regardless of 'args'
+ boards: List of boards to build
Returns:
- Dictionary which holds the list of boards which were selected
- due to each argument, arranged by argument.
+ Tuple
+ Dictionary which holds the list of boards which were selected
+ due to each argument, arranged by argument.
+ List of errors found
"""
result = {}
+ warnings = []
terms = self._BuildTerms(args)
result['all'] = []
@@ -261,6 +271,7 @@
for expr in exclude:
exclude_list.append(Expr(expr))
+ found = []
for board in self._boards:
matching_term = None
build_it = False
@@ -271,6 +282,10 @@
matching_term = str(term)
build_it = True
break
+ elif boards:
+ if board.target in boards:
+ build_it = True
+ found.append(board.target)
else:
build_it = True
@@ -286,4 +301,9 @@
result[matching_term].append(board.target)
result['all'].append(board.target)
- return result
+ if boards:
+ remaining = set(boards) - set(found)
+ if remaining:
+ warnings.append('Boards not found: %s\n' % ', '.join(remaining))
+
+ return result, warnings
diff --git a/tools/buildman/cmdline.py b/tools/buildman/cmdline.py
index e493b1a..49a8a13 100644
--- a/tools/buildman/cmdline.py
+++ b/tools/buildman/cmdline.py
@@ -18,6 +18,8 @@
parser.add_option('-B', '--bloat', dest='show_bloat',
action='store_true', default=False,
help='Show changes in function code size for each board')
+ parser.add_option('--boards', type='string', action='append',
+ help='List of board names to build separated by comma')
parser.add_option('-c', '--count', dest='count', type='int',
default=-1, help='Run build on the top n commits')
parser.add_option('-C', '--force-reconfig', dest='force_reconfig',
@@ -102,7 +104,7 @@
type='string', action='append',
help='Specify a list of boards to exclude, separated by comma')
- parser.usage += """
+ parser.usage += """ [list of target/arch/cpu/board/vendor/soc to build]
Build U-Boot for all commits in a branch. Use -n to do a dry run"""
diff --git a/tools/buildman/control.py b/tools/buildman/control.py
index bc08197..96f8ccf 100644
--- a/tools/buildman/control.py
+++ b/tools/buildman/control.py
@@ -41,7 +41,8 @@
GetPlural(options.threads), options.jobs, GetPlural(options.jobs))
return str
-def ShowActions(series, why_selected, boards_selected, builder, options):
+def ShowActions(series, why_selected, boards_selected, builder, options,
+ board_warnings):
"""Display a list of actions that we would take, if not a dry run.
Args:
@@ -55,6 +56,7 @@
value is Board object
builder: The builder that will be used to build the commits
options: Command line options object
+ board_warnings: List of warnings obtained from board selected
"""
col = terminal.Color()
print 'Dry run, so not doing much. But I would do this:'
@@ -79,6 +81,9 @@
print ' %s' % ' '.join(why_selected[arg])
print ('Total boards to build for each commit: %d\n' %
len(why_selected['all']))
+ if board_warnings:
+ for warning in board_warnings:
+ print col.Color(col.YELLOW, warning)
def CheckOutputDir(output_dir):
"""Make sure that the output directory is not within the current directory
@@ -210,7 +215,15 @@
for arg in options.exclude:
exclude += arg.split(',')
- why_selected = boards.SelectBoards(args, exclude)
+
+ if options.boards:
+ requested_boards = []
+ for b in options.boards:
+ requested_boards += b.split(',')
+ else:
+ requested_boards = None
+ why_selected, board_warnings = boards.SelectBoards(args, exclude,
+ requested_boards)
selected = boards.GetSelected()
if not len(selected):
sys.exit(col.Color(col.RED, 'No matching boards found'))
@@ -292,7 +305,8 @@
# For a dry run, just show our actions as a sanity check
if options.dry_run:
- ShowActions(series, why_selected, selected, builder, options)
+ ShowActions(series, why_selected, selected, builder, options,
+ board_warnings)
else:
builder.force_build = options.force_build
builder.force_build_failures = options.force_build_failures
diff --git a/tools/buildman/test.py b/tools/buildman/test.py
index e0c9d6d..61a4626 100644
--- a/tools/buildman/test.py
+++ b/tools/buildman/test.py
@@ -313,60 +313,63 @@
def testBoardSingle(self):
"""Test single board selection"""
self.assertEqual(self.boards.SelectBoards(['sandbox']),
- {'all': ['board4'], 'sandbox': ['board4']})
+ ({'all': ['board4'], 'sandbox': ['board4']}, []))
def testBoardArch(self):
"""Test single board selection"""
self.assertEqual(self.boards.SelectBoards(['arm']),
- {'all': ['board0', 'board1'],
- 'arm': ['board0', 'board1']})
+ ({'all': ['board0', 'board1'],
+ 'arm': ['board0', 'board1']}, []))
def testBoardArchSingle(self):
"""Test single board selection"""
self.assertEqual(self.boards.SelectBoards(['arm sandbox']),
- {'sandbox': ['board4'],
+ ({'sandbox': ['board4'],
'all': ['board0', 'board1', 'board4'],
- 'arm': ['board0', 'board1']})
+ 'arm': ['board0', 'board1']}, []))
def testBoardArchSingleMultiWord(self):
"""Test single board selection"""
self.assertEqual(self.boards.SelectBoards(['arm', 'sandbox']),
- {'sandbox': ['board4'], 'all': ['board0', 'board1', 'board4'], 'arm': ['board0', 'board1']})
+ ({'sandbox': ['board4'],
+ 'all': ['board0', 'board1', 'board4'],
+ 'arm': ['board0', 'board1']}, []))
def testBoardSingleAnd(self):
"""Test single board selection"""
self.assertEqual(self.boards.SelectBoards(['Tester & arm']),
- {'Tester&arm': ['board0', 'board1'], 'all': ['board0', 'board1']})
+ ({'Tester&arm': ['board0', 'board1'],
+ 'all': ['board0', 'board1']}, []))
def testBoardTwoAnd(self):
"""Test single board selection"""
self.assertEqual(self.boards.SelectBoards(['Tester', '&', 'arm',
'Tester' '&', 'powerpc',
'sandbox']),
- {'sandbox': ['board4'],
+ ({'sandbox': ['board4'],
'all': ['board0', 'board1', 'board2', 'board3',
'board4'],
'Tester&powerpc': ['board2', 'board3'],
- 'Tester&arm': ['board0', 'board1']})
+ 'Tester&arm': ['board0', 'board1']}, []))
def testBoardAll(self):
"""Test single board selection"""
self.assertEqual(self.boards.SelectBoards([]),
- {'all': ['board0', 'board1', 'board2', 'board3',
- 'board4']})
+ ({'all': ['board0', 'board1', 'board2', 'board3',
+ 'board4']}, []))
def testBoardRegularExpression(self):
"""Test single board selection"""
self.assertEqual(self.boards.SelectBoards(['T.*r&^Po']),
- {'all': ['board2', 'board3'],
- 'T.*r&^Po': ['board2', 'board3']})
+ ({'all': ['board2', 'board3'],
+ 'T.*r&^Po': ['board2', 'board3']}, []))
def testBoardDuplicate(self):
"""Test single board selection"""
self.assertEqual(self.boards.SelectBoards(['sandbox sandbox',
'sandbox']),
- {'all': ['board4'], 'sandbox': ['board4']})
+ ({'all': ['board4'], 'sandbox': ['board4']}, []))
def CheckDirs(self, build, dirname):
self.assertEqual('base%s' % dirname, build._GetOutputDir(1))
self.assertEqual('base%s/fred' % dirname,