buildman: Allow make flags to be specified for each board

There are a few make options such as BUILD_TAG which can be provided when
building U-Boot. Provide a way for buildman to pass these flags to make
also.

The flags should be in a [make-flags] section and arranged by target name
(the 'target' column in boards.cfg. See the README for more details.

Signed-off-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
Simon Glass 2013-09-23 17:35:17 -06:00
parent e19d5781ec
commit 4281ad8e7f
5 changed files with 115 additions and 5 deletions

View File

@ -629,6 +629,28 @@ It is common when refactoring code for the rodata to decrease as the text size
increases, and vice versa.
Providing 'make' flags
======================
U-Boot's build system supports a few flags (such as BUILD_TAG) which affect
the build product. These flags can be specified in the buildman settings
file. They can also be useful when building U-Boot against other open source
software.
[make-flags]
at91-boards=ENABLE_AT91_TEST=1
snapper9260=${at91-boards} BUILD_TAG=442
snapper9g45=${at91-boards} BUILD_TAG=443
This will use 'make ENABLE_AT91_TEST=1 BUILD_TAG=442' for snapper9260
and 'make ENABLE_AT91_TEST=1 BUILD_TAG=442' for snapper9g45. A special
variable ${target} is available to access the target name (snapper9260 and
snapper9g20 in this case). Variables are resolved recursively.
It is expected that any variables added are dealt with in U-Boot's
config.mk file and documented in the README.
Other options
=============

View File

@ -36,9 +36,6 @@ def GetItems(section):
return settings.items(section)
except ConfigParser.NoSectionError as e:
print e
print ("Warning: No tool chains - please add a [toolchain] section "
"to your buildman config file %s. See README for details" %
config_fname)
return []
except:
raise

View File

@ -253,6 +253,7 @@ class BuilderThread(threading.Thread):
args.extend(['-j', str(self.builder.num_jobs)])
config_args = ['%s_config' % brd.target]
config_out = ''
args.extend(self.builder.toolchains.GetMakeArguments(brd))
# If we need to reconfigure, do that now
if do_config:

View File

@ -32,6 +32,19 @@ import toolchain
def RunTests():
import test
import doctest
result = unittest.TestResult()
for module in ['toolchain']:
suite = doctest.DocTestSuite(module)
suite.run(result)
# TODO: Surely we can just 'print' result?
print result
for test, err in result.errors:
print err
for test, err in result.failures:
print err
sys.argv = [sys.argv[0]]
suite = unittest.TestLoader().loadTestsFromTestCase(test.TestBuild)

View File

@ -3,6 +3,7 @@
# SPDX-License-Identifier: GPL-2.0+
#
import re
import glob
import os
@ -97,12 +98,18 @@ class Toolchains:
def __init__(self):
self.toolchains = {}
self.paths = []
for name, value in bsettings.GetItems('toolchain'):
toolchains = bsettings.GetItems('toolchain')
if not toolchains:
print ("Warning: No tool chains - please add a [toolchain] section"
" to your buildman config file %s. See README for details" %
config_fname)
for name, value in toolchains:
if '*' in value:
self.paths += glob.glob(value)
else:
self.paths.append(value)
self._make_flags = dict(bsettings.GetItems('make-flags'))
def Add(self, fname, test=True, verbose=False):
"""Add a toolchain to our list
@ -167,3 +174,73 @@ class Toolchains:
if not arch in self.toolchains:
raise ValueError, ("No tool chain found for arch '%s'" % arch)
return self.toolchains[arch]
def ResolveReferences(self, var_dict, args):
"""Resolve variable references in a string
This converts ${blah} within the string to the value of blah.
This function works recursively.
Args:
var_dict: Dictionary containing variables and their values
args: String containing make arguments
Returns:
Resolved string
>>> bsettings.Setup()
>>> tcs = Toolchains()
>>> tcs.Add('fred', False)
>>> var_dict = {'oblique' : 'OBLIQUE', 'first' : 'fi${second}rst', \
'second' : '2nd'}
>>> tcs.ResolveReferences(var_dict, 'this=${oblique}_set')
'this=OBLIQUE_set'
>>> tcs.ResolveReferences(var_dict, 'this=${oblique}_set${first}nd')
'this=OBLIQUE_setfi2ndrstnd'
"""
re_var = re.compile('(\$\{[a-z0-9A-Z]{1,}\})')
while True:
m = re_var.search(args)
if not m:
break
lookup = m.group(0)[2:-1]
value = var_dict.get(lookup, '')
args = args[:m.start(0)] + value + args[m.end(0):]
return args
def GetMakeArguments(self, board):
"""Returns 'make' arguments for a given board
The flags are in a section called 'make-flags'. Flags are named
after the target they represent, for example snapper9260=TESTING=1
will pass TESTING=1 to make when building the snapper9260 board.
References to other boards can be added in the string also. For
example:
[make-flags]
at91-boards=ENABLE_AT91_TEST=1
snapper9260=${at91-boards} BUILD_TAG=442
snapper9g45=${at91-boards} BUILD_TAG=443
This will return 'ENABLE_AT91_TEST=1 BUILD_TAG=442' for snapper9260
and 'ENABLE_AT91_TEST=1 BUILD_TAG=443' for snapper9g45.
A special 'target' variable is set to the board target.
Args:
board: Board object for the board to check.
Returns:
'make' flags for that board, or '' if none
"""
self._make_flags['target'] = board.target
arg_str = self.ResolveReferences(self._make_flags,
self._make_flags.get(board.target, ''))
args = arg_str.split(' ')
i = 0
while i < len(args):
if not args[i]:
del args[i]
else:
i += 1
return args