From patchwork Mon Sep 23 23:35:17 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 277328 X-Patchwork-Delegate: sjg@chromium.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from theia.denx.de (theia.denx.de [85.214.87.163]) by ozlabs.org (Postfix) with ESMTP id 8EA1C2C00BF for ; Tue, 24 Sep 2013 10:35:32 +1000 (EST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id DDD6B4A023; Tue, 24 Sep 2013 02:35:30 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id uPAU-sf3pBL6; Tue, 24 Sep 2013 02:35:30 +0200 (CEST) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 1E86C4A05F; Tue, 24 Sep 2013 02:35:28 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 784E74A05F for ; Tue, 24 Sep 2013 02:35:22 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id v76yn74Mi+fI for ; Tue, 24 Sep 2013 02:35:15 +0200 (CEST) X-policyd-weight: NOT_IN_SBL_XBL_SPAMHAUS=-1.5 NOT_IN_SPAMCOP=-1.5 NOT_IN_BL_NJABL=-1.5 (only DNSBL check requested) Received: from mail-ve0-f201.google.com (mail-ve0-f201.google.com [209.85.128.201]) by theia.denx.de (Postfix) with ESMTPS id 526104A023 for ; Tue, 24 Sep 2013 02:35:07 +0200 (CEST) Received: by mail-ve0-f201.google.com with SMTP id c14so449987vea.0 for ; Mon, 23 Sep 2013 17:35:06 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=l4eED+k/4b2vRc5oie3UmvcUF8HV61uG0Ewgd/xMO30=; b=V2yosSX9Y6mjapbaqOvhXTu7FdUt6l+zCLPSHeQeWuIUgBNJX3x04K6s8PFXzbaYu4 mGYIcEvCjs9GsH8yZxShjJ0a0HW4DR3vk54+gmd7gWHRzs94Pr1I+A6ROrdjAnlwSOYt yckC6IUOuNs20wybZzyRpvrW4gYvYoDQZuPcOlHPQq59JGm1tvPI7iFLwj/mMTA83p8C bxA/Crtx6GXiXel2PVOZpp4uDiP33CyXKUTNWyWUwX60/AVsLXPDSHFkcA3HP1LHTOVn +gB3fFk/hHtpj5sHUqlIZ7L4mOi/zUHUErGJcjQesJW0bInBBcrM1Ywg2G9W4xCIl/qD fGwg== X-Gm-Message-State: ALoCoQlI0NEJRzgDWA3WeF+7tPl+xEn7JyoedGu1Fo+NRQ6gxGwH19NNN/L8L8USkGr43jYhMEENvPoP6W9F+HVukQJ1IA8p8UnW6XKY19uGLBKvr7x5lCLeqYTalTtBxbD6k0ae3/2o32Aozox97xzYDoW8Rp6zBBfRlDA9UehXNT60lrfW6Gjv7285iE0KIgwVbQ/hWiN5 X-Received: by 10.236.145.34 with SMTP id o22mr8880467yhj.22.1379979336403; Mon, 23 Sep 2013 16:35:36 -0700 (PDT) Received: from corp2gmr1-1.hot.corp.google.com (corp2gmr1-1.hot.corp.google.com [172.24.189.92]) by gmr-mx.google.com with ESMTPS id y62si3921135yha.0.1969.12.31.16.00.00 (version=TLSv1.1 cipher=AES128-SHA bits=128/128); Mon, 23 Sep 2013 16:35:36 -0700 (PDT) Received: from kaki.bld.corp.google.com (kaki.bld.corp.google.com [172.29.216.32]) by corp2gmr1-1.hot.corp.google.com (Postfix) with ESMTP id 3852731C226; Mon, 23 Sep 2013 16:35:36 -0700 (PDT) Received: by kaki.bld.corp.google.com (Postfix, from userid 121222) id 16272220E52; Mon, 23 Sep 2013 17:35:20 -0600 (MDT) From: Simon Glass To: U-Boot Mailing List Date: Mon, 23 Sep 2013 17:35:17 -0600 Message-Id: <1379979317-24092-2-git-send-email-sjg@chromium.org> X-Mailer: git-send-email 1.8.4 In-Reply-To: <1379979317-24092-1-git-send-email-sjg@chromium.org> References: <1379979317-24092-1-git-send-email-sjg@chromium.org> Cc: Tom Rini Subject: [U-Boot] [PATCH v2 2/2] buildman: Allow make flags to be specified for each board X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.11 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: u-boot-bounces@lists.denx.de Errors-To: u-boot-bounces@lists.denx.de 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 --- Changes in v2: Correct unit test invocation tools/buildman/README | 22 ++++++++++++ tools/buildman/bsettings.py | 3 -- tools/buildman/builder.py | 1 + tools/buildman/buildman.py | 13 ++++++++ tools/buildman/toolchain.py | 81 +++++++++++++++++++++++++++++++++++++++++++-- 5 files changed, 115 insertions(+), 5 deletions(-) diff --git a/tools/buildman/README b/tools/buildman/README index 734ada6..f63f278 100644 --- a/tools/buildman/README +++ b/tools/buildman/README @@ -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 ============= diff --git a/tools/buildman/bsettings.py b/tools/buildman/bsettings.py index c801130..9164798 100644 --- a/tools/buildman/bsettings.py +++ b/tools/buildman/bsettings.py @@ -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 diff --git a/tools/buildman/builder.py b/tools/buildman/builder.py index 29da67a..4a2d753 100644 --- a/tools/buildman/builder.py +++ b/tools/buildman/builder.py @@ -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: diff --git a/tools/buildman/buildman.py b/tools/buildman/buildman.py index 6fba2f2..43895b8 100755 --- a/tools/buildman/buildman.py +++ b/tools/buildman/buildman.py @@ -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) diff --git a/tools/buildman/toolchain.py b/tools/buildman/toolchain.py index dfa1d00..a292338 100644 --- a/tools/buildman/toolchain.py +++ b/tools/buildman/toolchain.py @@ -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