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>
This commit is contained in:
parent
bd8b74551b
commit
0689036a35
@ -114,6 +114,10 @@ a few commits or boards, it will be pretty slow. As a tip, if you don't
|
|||||||
plan to use your machine for anything else, you can use -T to increase the
|
plan to use your machine for anything else, you can use -T to increase the
|
||||||
number of threads beyond the default.
|
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
|
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,
|
command-line arguments that list the desired board name, architecture name,
|
||||||
SOC name, or anything else in the boards.cfg file. Multiple arguments are
|
SOC name, or anything else in the boards.cfg file. Multiple arguments are
|
||||||
@ -138,11 +142,17 @@ You can also use -x to specifically exclude some boards. For example:
|
|||||||
means to build all arm boards except nvidia, freescale and anything ending
|
means to build all arm boards except nvidia, freescale and anything ending
|
||||||
with 'ball'.
|
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
|
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.
|
the subset given. Use -v as well to get an actual list of boards.
|
||||||
|
|
||||||
Buildman does not store intermediate object files. It optionally copies
|
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,
|
information is always recorded. It needs a fair bit of disk space to work,
|
||||||
typically 250MB per thread.
|
typically 250MB per thread.
|
||||||
|
|
||||||
|
@ -237,20 +237,30 @@ class Boards:
|
|||||||
terms.append(term)
|
terms.append(term)
|
||||||
return terms
|
return terms
|
||||||
|
|
||||||
def SelectBoards(self, args, exclude=[]):
|
def SelectBoards(self, args, exclude=[], boards=None):
|
||||||
"""Mark boards selected based on args
|
"""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:
|
||||||
args: List of strings specifying boards to include, either named,
|
args: List of strings specifying boards to include, either named,
|
||||||
or by their target, architecture, cpu, vendor or soc. If
|
or by their target, architecture, cpu, vendor or soc. If
|
||||||
empty, all boards are selected.
|
empty, all boards are selected.
|
||||||
exclude: List of boards to exclude, regardless of 'args'
|
exclude: List of boards to exclude, regardless of 'args'
|
||||||
|
boards: List of boards to build
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Dictionary which holds the list of boards which were selected
|
Tuple
|
||||||
due to each argument, arranged by argument.
|
Dictionary which holds the list of boards which were selected
|
||||||
|
due to each argument, arranged by argument.
|
||||||
|
List of errors found
|
||||||
"""
|
"""
|
||||||
result = {}
|
result = {}
|
||||||
|
warnings = []
|
||||||
terms = self._BuildTerms(args)
|
terms = self._BuildTerms(args)
|
||||||
|
|
||||||
result['all'] = []
|
result['all'] = []
|
||||||
@ -261,6 +271,7 @@ class Boards:
|
|||||||
for expr in exclude:
|
for expr in exclude:
|
||||||
exclude_list.append(Expr(expr))
|
exclude_list.append(Expr(expr))
|
||||||
|
|
||||||
|
found = []
|
||||||
for board in self._boards:
|
for board in self._boards:
|
||||||
matching_term = None
|
matching_term = None
|
||||||
build_it = False
|
build_it = False
|
||||||
@ -271,6 +282,10 @@ class Boards:
|
|||||||
matching_term = str(term)
|
matching_term = str(term)
|
||||||
build_it = True
|
build_it = True
|
||||||
break
|
break
|
||||||
|
elif boards:
|
||||||
|
if board.target in boards:
|
||||||
|
build_it = True
|
||||||
|
found.append(board.target)
|
||||||
else:
|
else:
|
||||||
build_it = True
|
build_it = True
|
||||||
|
|
||||||
@ -286,4 +301,9 @@ class Boards:
|
|||||||
result[matching_term].append(board.target)
|
result[matching_term].append(board.target)
|
||||||
result['all'].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
|
||||||
|
@ -18,6 +18,8 @@ def ParseArgs():
|
|||||||
parser.add_option('-B', '--bloat', dest='show_bloat',
|
parser.add_option('-B', '--bloat', dest='show_bloat',
|
||||||
action='store_true', default=False,
|
action='store_true', default=False,
|
||||||
help='Show changes in function code size for each board')
|
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',
|
parser.add_option('-c', '--count', dest='count', type='int',
|
||||||
default=-1, help='Run build on the top n commits')
|
default=-1, help='Run build on the top n commits')
|
||||||
parser.add_option('-C', '--force-reconfig', dest='force_reconfig',
|
parser.add_option('-C', '--force-reconfig', dest='force_reconfig',
|
||||||
@ -102,7 +104,7 @@ def ParseArgs():
|
|||||||
type='string', action='append',
|
type='string', action='append',
|
||||||
help='Specify a list of boards to exclude, separated by comma')
|
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"""
|
Build U-Boot for all commits in a branch. Use -n to do a dry run"""
|
||||||
|
|
||||||
|
@ -41,7 +41,8 @@ def GetActionSummary(is_summary, commits, selected, options):
|
|||||||
GetPlural(options.threads), options.jobs, GetPlural(options.jobs))
|
GetPlural(options.threads), options.jobs, GetPlural(options.jobs))
|
||||||
return str
|
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.
|
"""Display a list of actions that we would take, if not a dry run.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -55,6 +56,7 @@ def ShowActions(series, why_selected, boards_selected, builder, options):
|
|||||||
value is Board object
|
value is Board object
|
||||||
builder: The builder that will be used to build the commits
|
builder: The builder that will be used to build the commits
|
||||||
options: Command line options object
|
options: Command line options object
|
||||||
|
board_warnings: List of warnings obtained from board selected
|
||||||
"""
|
"""
|
||||||
col = terminal.Color()
|
col = terminal.Color()
|
||||||
print 'Dry run, so not doing much. But I would do this:'
|
print 'Dry run, so not doing much. But I would do this:'
|
||||||
@ -79,6 +81,9 @@ def ShowActions(series, why_selected, boards_selected, builder, options):
|
|||||||
print ' %s' % ' '.join(why_selected[arg])
|
print ' %s' % ' '.join(why_selected[arg])
|
||||||
print ('Total boards to build for each commit: %d\n' %
|
print ('Total boards to build for each commit: %d\n' %
|
||||||
len(why_selected['all']))
|
len(why_selected['all']))
|
||||||
|
if board_warnings:
|
||||||
|
for warning in board_warnings:
|
||||||
|
print col.Color(col.YELLOW, warning)
|
||||||
|
|
||||||
def CheckOutputDir(output_dir):
|
def CheckOutputDir(output_dir):
|
||||||
"""Make sure that the output directory is not within the current directory
|
"""Make sure that the output directory is not within the current directory
|
||||||
@ -210,7 +215,15 @@ def DoBuildman(options, args, toolchains=None, make_func=None, boards=None,
|
|||||||
for arg in options.exclude:
|
for arg in options.exclude:
|
||||||
exclude += arg.split(',')
|
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()
|
selected = boards.GetSelected()
|
||||||
if not len(selected):
|
if not len(selected):
|
||||||
sys.exit(col.Color(col.RED, 'No matching boards found'))
|
sys.exit(col.Color(col.RED, 'No matching boards found'))
|
||||||
@ -292,7 +305,8 @@ def DoBuildman(options, args, toolchains=None, make_func=None, boards=None,
|
|||||||
|
|
||||||
# For a dry run, just show our actions as a sanity check
|
# For a dry run, just show our actions as a sanity check
|
||||||
if options.dry_run:
|
if options.dry_run:
|
||||||
ShowActions(series, why_selected, selected, builder, options)
|
ShowActions(series, why_selected, selected, builder, options,
|
||||||
|
board_warnings)
|
||||||
else:
|
else:
|
||||||
builder.force_build = options.force_build
|
builder.force_build = options.force_build
|
||||||
builder.force_build_failures = options.force_build_failures
|
builder.force_build_failures = options.force_build_failures
|
||||||
|
@ -313,60 +313,63 @@ class TestBuild(unittest.TestCase):
|
|||||||
def testBoardSingle(self):
|
def testBoardSingle(self):
|
||||||
"""Test single board selection"""
|
"""Test single board selection"""
|
||||||
self.assertEqual(self.boards.SelectBoards(['sandbox']),
|
self.assertEqual(self.boards.SelectBoards(['sandbox']),
|
||||||
{'all': ['board4'], 'sandbox': ['board4']})
|
({'all': ['board4'], 'sandbox': ['board4']}, []))
|
||||||
|
|
||||||
def testBoardArch(self):
|
def testBoardArch(self):
|
||||||
"""Test single board selection"""
|
"""Test single board selection"""
|
||||||
self.assertEqual(self.boards.SelectBoards(['arm']),
|
self.assertEqual(self.boards.SelectBoards(['arm']),
|
||||||
{'all': ['board0', 'board1'],
|
({'all': ['board0', 'board1'],
|
||||||
'arm': ['board0', 'board1']})
|
'arm': ['board0', 'board1']}, []))
|
||||||
|
|
||||||
def testBoardArchSingle(self):
|
def testBoardArchSingle(self):
|
||||||
"""Test single board selection"""
|
"""Test single board selection"""
|
||||||
self.assertEqual(self.boards.SelectBoards(['arm sandbox']),
|
self.assertEqual(self.boards.SelectBoards(['arm sandbox']),
|
||||||
{'sandbox': ['board4'],
|
({'sandbox': ['board4'],
|
||||||
'all': ['board0', 'board1', 'board4'],
|
'all': ['board0', 'board1', 'board4'],
|
||||||
'arm': ['board0', 'board1']})
|
'arm': ['board0', 'board1']}, []))
|
||||||
|
|
||||||
|
|
||||||
def testBoardArchSingleMultiWord(self):
|
def testBoardArchSingleMultiWord(self):
|
||||||
"""Test single board selection"""
|
"""Test single board selection"""
|
||||||
self.assertEqual(self.boards.SelectBoards(['arm', 'sandbox']),
|
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):
|
def testBoardSingleAnd(self):
|
||||||
"""Test single board selection"""
|
"""Test single board selection"""
|
||||||
self.assertEqual(self.boards.SelectBoards(['Tester & arm']),
|
self.assertEqual(self.boards.SelectBoards(['Tester & arm']),
|
||||||
{'Tester&arm': ['board0', 'board1'], 'all': ['board0', 'board1']})
|
({'Tester&arm': ['board0', 'board1'],
|
||||||
|
'all': ['board0', 'board1']}, []))
|
||||||
|
|
||||||
def testBoardTwoAnd(self):
|
def testBoardTwoAnd(self):
|
||||||
"""Test single board selection"""
|
"""Test single board selection"""
|
||||||
self.assertEqual(self.boards.SelectBoards(['Tester', '&', 'arm',
|
self.assertEqual(self.boards.SelectBoards(['Tester', '&', 'arm',
|
||||||
'Tester' '&', 'powerpc',
|
'Tester' '&', 'powerpc',
|
||||||
'sandbox']),
|
'sandbox']),
|
||||||
{'sandbox': ['board4'],
|
({'sandbox': ['board4'],
|
||||||
'all': ['board0', 'board1', 'board2', 'board3',
|
'all': ['board0', 'board1', 'board2', 'board3',
|
||||||
'board4'],
|
'board4'],
|
||||||
'Tester&powerpc': ['board2', 'board3'],
|
'Tester&powerpc': ['board2', 'board3'],
|
||||||
'Tester&arm': ['board0', 'board1']})
|
'Tester&arm': ['board0', 'board1']}, []))
|
||||||
|
|
||||||
def testBoardAll(self):
|
def testBoardAll(self):
|
||||||
"""Test single board selection"""
|
"""Test single board selection"""
|
||||||
self.assertEqual(self.boards.SelectBoards([]),
|
self.assertEqual(self.boards.SelectBoards([]),
|
||||||
{'all': ['board0', 'board1', 'board2', 'board3',
|
({'all': ['board0', 'board1', 'board2', 'board3',
|
||||||
'board4']})
|
'board4']}, []))
|
||||||
|
|
||||||
def testBoardRegularExpression(self):
|
def testBoardRegularExpression(self):
|
||||||
"""Test single board selection"""
|
"""Test single board selection"""
|
||||||
self.assertEqual(self.boards.SelectBoards(['T.*r&^Po']),
|
self.assertEqual(self.boards.SelectBoards(['T.*r&^Po']),
|
||||||
{'all': ['board2', 'board3'],
|
({'all': ['board2', 'board3'],
|
||||||
'T.*r&^Po': ['board2', 'board3']})
|
'T.*r&^Po': ['board2', 'board3']}, []))
|
||||||
|
|
||||||
def testBoardDuplicate(self):
|
def testBoardDuplicate(self):
|
||||||
"""Test single board selection"""
|
"""Test single board selection"""
|
||||||
self.assertEqual(self.boards.SelectBoards(['sandbox sandbox',
|
self.assertEqual(self.boards.SelectBoards(['sandbox sandbox',
|
||||||
'sandbox']),
|
'sandbox']),
|
||||||
{'all': ['board4'], 'sandbox': ['board4']})
|
({'all': ['board4'], 'sandbox': ['board4']}, []))
|
||||||
def CheckDirs(self, build, dirname):
|
def CheckDirs(self, build, dirname):
|
||||||
self.assertEqual('base%s' % dirname, build._GetOutputDir(1))
|
self.assertEqual('base%s' % dirname, build._GetOutputDir(1))
|
||||||
self.assertEqual('base%s/fred' % dirname,
|
self.assertEqual('base%s/fred' % dirname,
|
||||||
|
Loading…
Reference in New Issue
Block a user