buildman: Add options to get the arch and toolchain info
authorSimon Glass <sjg@chromium.org>
Thu, 5 Dec 2019 22:59:14 +0000 (15:59 -0700)
committerSimon Glass <sjg@chromium.org>
Wed, 11 Dec 2019 04:11:31 +0000 (21:11 -0700)
Sometimes it is useful for external tools to use buildman to provide the
toolchain information. Add an -a option which shows the value to use for
the ARCH environment variable, and -A which does the same for
CROSS_COMPILE

Signed-off-by: Simon Glass <sjg@chromium.org>
tools/buildman/README
tools/buildman/cmdline.py
tools/buildman/control.py
tools/buildman/test.py
tools/buildman/toolchain.py

index e366192..c1ac0d0 100644 (file)
@@ -1061,6 +1061,9 @@ Other options
 
 Buildman has various other command line options. Try --help to see them.
 
+To find out what architecture or toolchain prefix buildman will use for a build,
+see the -a and -A options.
+
 When doing builds, Buildman's return code will reflect the overall result:
 
     0 (success)     No errors or warnings found
index 832a514..b412093 100644 (file)
@@ -13,6 +13,10 @@ def ParseArgs():
             args: command lin arguments
     """
     parser = OptionParser()
+    parser.add_option('-a', '--print-arch', action='store_true',
+          help='Print the architecture for a board (ARCH=)')
+    parser.add_option('-A', '--print-prefix', action='store_true',
+          help='Print the tool-chain prefix for a board (CROSS_COMPILE=)')
     parser.add_option('-b', '--branch', type='string',
           help='Branch name to build, or range of commits to build')
     parser.add_option('-B', '--bloat', dest='show_bloat',
index a9c5022..969d866 100644 (file)
@@ -107,6 +107,34 @@ def CheckOutputDir(output_dir):
             break
         path = parent
 
+def ShowToolchainInfo(boards, toolchains, print_arch, print_prefix):
+    """Show information about a the tool chain used by one or more boards
+
+    The function checks that all boards use the same toolchain.
+
+    Args:
+        boards: Boards object containing selected boards
+        toolchains: Toolchains object containing available toolchains
+        print_arch: True to print ARCH value
+        print_prefix: True to print CROSS_COMPILE value
+
+    Return:
+        None on success, string error message otherwise
+    """
+    boards = boards.GetSelectedDict()
+    tc_set = set()
+    for brd in boards.values():
+        tc_set.add(toolchains.Select(brd.arch))
+    if len(tc_set) != 1:
+        return 'Supplied boards must share one toolchain'
+        return False
+    tc = tc_set.pop()
+    if print_arch:
+        print(tc.GetEnvArgs(toolchain.VAR_ARCH))
+    if print_prefix:
+        print(tc.GetEnvArgs(toolchain.VAR_CROSS_COMPILE))
+    return None
+
 def DoBuildman(options, args, toolchains=None, make_func=None, boards=None,
                clean_dir=False):
     """The main control code for buildman
@@ -200,6 +228,13 @@ def DoBuildman(options, args, toolchains=None, make_func=None, boards=None,
     if not len(selected):
         sys.exit(col.Color(col.RED, 'No matching boards found'))
 
+    if options.print_arch or options.print_prefix:
+        err = ShowToolchainInfo(boards, toolchains, options.print_arch,
+                                options.print_prefix)
+        if err:
+            sys.exit(col.Color(col.RED, err))
+        return 0
+
     # Work out how many commits to build. We want to build everything on the
     # branch. We also build the upstream commit as a control so we can see
     # problems introduced by the first commit on the branch.
index b4e28d6..acd862b 100644 (file)
@@ -451,6 +451,24 @@ class TestBuild(unittest.TestCase):
                     'crosstool/files/bin/x86_64/.*/'
                     'x86_64-gcc-.*-nolibc_arm-.*linux-gnueabi.tar.xz')
 
+    def testGetEnvArgs(self):
+        """Test the GetEnvArgs() function"""
+        tc = self.toolchains.Select('arm')
+        self.assertEqual('arm-linux-',
+                         tc.GetEnvArgs(toolchain.VAR_CROSS_COMPILE))
+        self.assertEqual('', tc.GetEnvArgs(toolchain.VAR_PATH))
+        self.assertEqual('arm',
+                         tc.GetEnvArgs(toolchain.VAR_ARCH))
+        self.assertEqual('', tc.GetEnvArgs(toolchain.VAR_MAKE_ARGS))
+
+        self.toolchains.Add('/path/to/x86_64-linux-gcc', test=False)
+        tc = self.toolchains.Select('x86')
+        self.assertEqual('/path/to',
+                         tc.GetEnvArgs(toolchain.VAR_PATH))
+        tc.override_toolchain = 'clang'
+        self.assertEqual('HOSTCC=clang CC=clang',
+                         tc.GetEnvArgs(toolchain.VAR_MAKE_ARGS))
+
 
 if __name__ == "__main__":
     unittest.main()
index 086a4d4..4f39bfd 100644 (file)
@@ -18,6 +18,8 @@ import tools
 (PRIORITY_FULL_PREFIX, PRIORITY_PREFIX_GCC, PRIORITY_PREFIX_GCC_PATH,
     PRIORITY_CALC) = list(range(4))
 
+(VAR_CROSS_COMPILE, VAR_PATH, VAR_ARCH, VAR_MAKE_ARGS) = range(4)
+
 # Simple class to collect links from a page
 class MyHTMLParser(HTMLParser):
     def __init__(self, arch):
@@ -145,6 +147,30 @@ class Toolchain:
 
         return value
 
+    def GetEnvArgs(self, which):
+        """Get an environment variable/args value based on the the toolchain
+
+        Args:
+            which: VAR_... value to get
+
+        Returns:
+            Value of that environment variable or arguments
+        """
+        wrapper = self.GetWrapper()
+        if which == VAR_CROSS_COMPILE:
+            return wrapper + os.path.join(self.path, self.cross)
+        elif which == VAR_PATH:
+            return self.path
+        elif which == VAR_ARCH:
+            return self.arch
+        elif which == VAR_MAKE_ARGS:
+            args = self.MakeArgs()
+            if args:
+                return ' '.join(args)
+            return ''
+        else:
+            raise ValueError('Unknown arg to GetEnvArgs (%d)' % which)
+
     def MakeEnvironment(self, full_path):
         """Returns an environment for using the toolchain.