diff mbox

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

Message ID 1431556137-8426-8-git-send-email-joe.hershberger@ni.com
State Superseded
Delegated to: Masahiro Yamada
Headers show

Commit Message

Joe Hershberger May 13, 2015, 10:28 p.m. UTC
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@ni.com>

---

Changes in v3:
-New for version 3

Changes in v2: None

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

Comments

Masahiro Yamada May 14, 2015, 2:37 p.m. UTC | #1
Hi Joe,

2015-05-14 7:28 GMT+09:00 Joe Hershberger <joe.hershberger@ni.com>:
> 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@ni.com>
>

Sorry for leaving this scripts for such a long time.
(I have been busy in the Linux side lately.)
causing two people to develope a similar feature.

I thought the same thing.
My idea was to stop giving config attributes from the command arguments.
Instead, the name of the input file is given as the argument.
Joe Hershberger May 14, 2015, 6:05 p.m. UTC | #2
Hi Masahiro-san,

On Thu, May 14, 2015 at 9:37 AM, Masahiro Yamada
<yamada.masahiro@socionext.com> wrote:
> Hi Joe,
>
> 2015-05-14 7:28 GMT+09:00 Joe Hershberger <joe.hershberger@ni.com>:
>> 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@ni.com>
>>
>
> Sorry for leaving this scripts for such a long time.
> (I have been busy in the Linux side lately.)
> causing two people to develope a similar feature.

Not too big a deal. Hopefully this will be in the tree soon so we can
stop managing this in every branch.

> I thought the same thing.
> My idea was to stop giving config attributes from the command arguments.
> Instead, the name of the input file is given as the argument.

That's fine. I was just trying to maintain your original features.

Cheers,
-Joe
diff mbox

Patch

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()