Merge branch 'next'
[oweals/u-boot.git] / tools / buildman / board.py
index a3332876240ea673e02c51db3d0bcab0e181e387..447aaabea86a6be89444b7842b8ffd52d5c54705 100644 (file)
@@ -1,8 +1,7 @@
+# SPDX-License-Identifier: GPL-2.0+
 # Copyright (c) 2012 The Chromium OS Authors.
-#
-# SPDX-License-Identifier:     GPL-2.0+
-#
 
+from collections import OrderedDict
 import re
 
 class Expr:
@@ -92,9 +91,9 @@ class Board:
         self.board_name = board_name
         self.vendor = vendor
         self.soc = soc
-        self.props = [self.target, self.arch, self.cpu, self.board_name,
-                      self.vendor, self.soc]
         self.options = options
+        self.props = [self.target, self.arch, self.cpu, self.board_name,
+                      self.vendor, self.soc, self.options]
         self.build_it = False
 
 
@@ -122,7 +121,7 @@ class Boards:
         Args:
             fname: Filename of boards.cfg file
         """
-        with open(fname, 'r') as fd:
+        with open(fname, 'r', encoding='utf-8') as fd:
             for line in fd:
                 if line[0] == '#':
                     continue
@@ -157,7 +156,7 @@ class Boards:
                 key is board.target
                 value is board
         """
-        board_dict = {}
+        board_dict = OrderedDict()
         for board in self._boards:
             board_dict[board.target] = board
         return board_dict
@@ -168,7 +167,7 @@ class Boards:
         Returns:
             List of Board objects that are marked selected
         """
-        board_dict = {}
+        board_dict = OrderedDict()
         for board in self._boards:
             if board.build_it:
                 board_dict[board.target] = board
@@ -239,36 +238,73 @@ class Boards:
             terms.append(term)
         return terms
 
-    def SelectBoards(self, args):
+    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:
-            List of strings specifying boards to include, either named, or
-            by their target, architecture, cpu, vendor or soc. If empty, all
-            boards are selected.
+            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 number 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 = {}
+        result = OrderedDict()
+        warnings = []
         terms = self._BuildTerms(args)
 
-        result['all'] = 0
+        result['all'] = []
         for term in terms:
-            result[str(term)] = 0
+            result[str(term)] = []
 
+        exclude_list = []
+        for expr in exclude:
+            exclude_list.append(Expr(expr))
+
+        found = []
         for board in self._boards:
+            matching_term = None
+            build_it = False
             if terms:
                 match = False
                 for term in terms:
                     if term.Matches(board.props):
-                        board.build_it = True
-                        result[str(term)] += 1
-                        result['all'] += 1
+                        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
+
+            # Check that it is not specifically excluded
+            for expr in exclude_list:
+                if expr.Matches(board.props):
+                    build_it = False
+                    break
+
+            if build_it:
                 board.build_it = True
-                result['all'] += 1
+                if matching_term:
+                    result[matching_term].append(board.target)
+                result['all'].append(board.target)
+
+        if boards:
+            remaining = set(boards) - set(found)
+            if remaining:
+                warnings.append('Boards not found: %s\n' % ', '.join(remaining))
 
-        return result
+        return result, warnings