[U-Boot] [PATCH v3 08/10] moveconfig: Handle moving multiple configs at once

Joe Hershberger joe.hershberger at ni.com
Thu May 14 00:28:54 CEST 2015


Moving configs is a fairly slow process since each board config must
pass through a compiler to evaluate the configs. Also, many configs
are related in a way that makes sense to atomically move.

Add support to tools/moveconfig.py to read multiple lines from the
.moveconfig file and create a parser for each. After compiling the
configs, simply run all the parsers on the autoconf.mk to find the
state of each of those configs.

Signed-off-by: Joe Hershberger <joe.hershberger at ni.com>

---

Changes in v3:
-New for version 3

Changes in v2: None

 tools/moveconfig.py | 75 ++++++++++++++++++++++++++++++-----------------------
 1 file changed, 42 insertions(+), 33 deletions(-)

diff --git a/tools/moveconfig.py b/tools/moveconfig.py
index 97ff597..798f717 100755
--- a/tools/moveconfig.py
+++ b/tools/moveconfig.py
@@ -91,9 +91,9 @@ def cleanup_header(header_path, patterns):
             if not i in matched:
                 f.write(line)
 
-def cleanup_headers(config):
+def cleanup_headers(config_attrs):
     while True:
-        choice = raw_input('Clean up %s in headers? [y/n]: ' % config).lower()
+        choice = raw_input('Clean up headers? [y/n]: ').lower()
         print choice
         if choice == 'y' or choice == 'n':
             break
@@ -102,8 +102,9 @@ def cleanup_headers(config):
         return
 
     patterns = []
-    patterns.append(re.compile(r'#\s*define\s+%s\W' % config))
-    patterns.append(re.compile(r'#\s*undef\s+%s\W' % config))
+    for config_attr in config_attrs:
+        patterns.append(re.compile(r'#\s*define\s+%s\W' % config_attr['config']))
+        patterns.append(re.compile(r'#\s*undef\s+%s\W' % config_attr['config']))
 
     for (dirpath, dirnames, filenames) in os.walk('include'):
         for filename in filenames:
@@ -126,7 +127,7 @@ class KconfigParser:
     PREFIX = { '.': '+', 'spl': 'S', 'tpl': 'T' }
 
     def __init__(self, build_dir, config_attr):
-        """Create a new .config perser.
+        """Create a new .config parser.
 
         Arguments:
           build_dir: Build directory where .config is located
@@ -141,6 +142,7 @@ class KconfigParser:
         else:
             self.no_spl_support = False
         self.re = re.compile(r'%s=(.*)' % self.config)
+        self.dotconfig = os.path.join(self.build_dir, '.config')
 
     def get_cross_compile(self):
         """Parse .config file and return CROSS_COMPILE
@@ -150,7 +152,6 @@ class KconfigParser:
         """
         arch = ''
         cpu = ''
-        self.dotconfig = os.path.join(self.build_dir, '.config')
         for line in open(self.dotconfig):
             m = self.re_arch.match(line)
             if m:
@@ -204,7 +205,6 @@ class KconfigParser:
                 value = '(default)'
 
             values.append(value)
-            os.remove(autoconf)
 
             if value == '(undef)' or value == '(default)':
                 continue
@@ -220,6 +220,7 @@ class KconfigParser:
                 prefixes[output_line] = self.PREFIX[img]
 
         output = defconfig[:-len('_defconfig')].ljust(37) + ': '
+        output += self.config.replace('CONFIG_','').ljust(18) + ': '
         for value in values:
             output += value.ljust(12)
 
@@ -241,7 +242,7 @@ class Slot:
     for faster processing.
     """
 
-    def __init__(self, config_attr, devnull, make_cmd, options):
+    def __init__(self, config_attrs, devnull, make_cmd, options):
         """Create a new slot.
 
         Arguments:
@@ -251,7 +252,9 @@ class Slot:
         self.devnull = devnull
         self.make_cmd = (make_cmd, 'O=' + self.build_dir)
         self.options = options
-        self.parser = KconfigParser(self.build_dir, config_attr)
+        self.parsers = []
+        for config_attr in config_attrs:
+            self.parsers.append(KconfigParser(self.build_dir, config_attr))
         self.state = STATE_IDLE
 
     def __del__(self):
@@ -314,10 +317,11 @@ class Slot:
             return True
 
         if self.state == STATE_SILENTOLDCONFIG:
-            if self.parser.update_defconfig(self.defconfig):
-                self.defconfig_error('ERROR - autoconf.mk not found')
-                self.state = STATE_IDLE
-                return True
+            for parser in self.parsers:
+                if parser.update_defconfig(self.defconfig):
+                    self.defconfig_error('ERROR - autoconf.mk not found')
+                    self.state = STATE_IDLE
+                    return True
 
             """Save off the defconfig in a consistent way"""
             cmd = list(self.make_cmd)
@@ -336,7 +340,7 @@ class Slot:
             self.state = STATE_IDLE
             return True
 
-        self.cross_compile = self.parser.get_cross_compile()
+        self.cross_compile = self.parsers[0].get_cross_compile()
         cmd = list(self.make_cmd)
         if self.cross_compile:
             cmd.append('CROSS_COMPILE=%s' % self.cross_compile)
@@ -350,7 +354,7 @@ class Slots:
 
     """Controller of the array of subprocess slots."""
 
-    def __init__(self, config_attr, options):
+    def __init__(self, config_attrs, options):
         """Create a new slots controller.
 
         Arguments:
@@ -360,7 +364,7 @@ class Slots:
         devnull = get_devnull()
         make_cmd = get_make_cmd()
         for i in range(options.jobs):
-            self.slots.append(Slot(config_attr, devnull, make_cmd, options))
+            self.slots.append(Slot(config_attrs, devnull, make_cmd, options))
 
     def add(self, defconfig):
         """Add a new subprocess if a vacant slot is available.
@@ -400,15 +404,16 @@ class Slots:
                 ret = False
         return ret
 
-def move_config(config_attr, options):
+def move_config(config_attrs, options):
     check_top_directory()
 
-    print 'Moving %s (type: %s, default: %s, no_spl: %s) ...  (jobs: %d)' % (
-        config_attr['config'],
-        config_attr['type'],
-        config_attr['default'],
-        config_attr['no_spl_support'],
-        options.jobs)
+    for config_attr in config_attrs:
+        print 'Moving %s (type: %s, default: %s, no_spl: %s)' % (
+            config_attr['config'],
+            config_attr['type'],
+            config_attr['default'],
+            config_attr['no_spl_support'])
+    print '%d jobs...' % options.jobs
 
     if options.defconfigs:
         defconfigs = [line.strip() for line in open(options.defconfigs, 'r')]
@@ -426,7 +431,7 @@ def move_config(config_attr, options):
     if os.path.exists('moveconfig.failed'):
         os.remove('moveconfig.failed')
 
-    slots = Slots(config_attr, options)
+    slots = Slots(config_attrs, options)
 
     # Main loop to process defconfig files:
     #  Add a new subprocess into a vacant slot.
@@ -441,7 +446,7 @@ def move_config(config_attr, options):
     while not slots.empty():
         time.sleep(SLEEP_TIME)
 
-    cleanup_headers(config_attr['config'])
+    cleanup_headers(config_attrs)
 
     if os.path.exists('moveconfig.failed'):
         print '!!!  Some boards were not processed; move the config manually.'
@@ -468,31 +473,35 @@ def main():
     (options, args) = parser.parse_args()
 
     args_key = ('config', 'type', 'default', 'no_spl_support')
-    config_attr = {}
+    config_attrs = []
 
     if len(args) >= len(args_key):
         saved_attr = ''
         for i, key in enumerate(args_key):
-            config_attr[key] = args[i]
+            config_attrs.append({})
+            config_attrs[0][key] = args[i]
             saved_attr = saved_attr + ' %s' % args[i]
         with open('.moveconfig', 'w') as f:
             f.write(saved_attr)
     elif os.path.exists('.moveconfig'):
         f = open('.moveconfig')
         try:
-            saved_attr = f.readline().split()
-            for i, key in enumerate(args_key):
-                config_attr[key] = saved_attr[i]
+            for j, line in enumerate(f):
+                config_attrs.append({})
+                saved_attr = line.split()
+                for i, key in enumerate(args_key):
+                    config_attrs[j][key] = saved_attr[i]
         except:
             sys.exit('%s: broken format' % '.moveconfig')
     else:
         parser.print_usage()
         sys.exit(1)
 
-    if not config_attr['config'].startswith('CONFIG_'):
-        config_attr['config'] = 'CONFIG_' + config_attr['config']
+    for config_attr in config_attrs:
+        if not config_attr['config'].startswith('CONFIG_'):
+            config_attr['config'] = 'CONFIG_' + config_attr['config']
 
-    move_config(config_attr, options)
+    move_config(config_attrs, options)
 
 if __name__ == '__main__':
     main()
-- 
1.7.11.5



More information about the U-Boot mailing list