X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=tools%2Fmoveconfig.py;h=496c90a9dc81dc70ff705bea9c1a727d8175ed16;hb=1c94578e7a3ce9d2e864b9243d213392d324205a;hp=87ced5cd8959a3c3eceb3a5983c102ac94e98c65;hpb=7740f653e6b3634383603e31ad2f3decac8becf1;p=u-boot diff --git a/tools/moveconfig.py b/tools/moveconfig.py index 87ced5cd89..496c90a9dc 100755 --- a/tools/moveconfig.py +++ b/tools/moveconfig.py @@ -135,6 +135,9 @@ Available options Surround each portion of the log with escape sequences to display it in color on the terminal. + -d, --defconfigs + Specify a file containing a list of defconfigs to move + -n, --dry-run Peform a trial run that does not make any changes. It is useful to see what is going to happen before one actually runs it. @@ -143,10 +146,16 @@ Available options Exit immediately if Make exits with a non-zero status while processing a defconfig file. + -H, --headers-only + Only cleanup the headers; skip the defconfig processing + -j, --jobs Specify the number of threads to run simultaneously. If not specified, the number of threads is the same as the number of CPU cores. + -v, --verbose + Show any build errors as boards are built + To see the complete list of supported options, run $ tools/moveconfig.py -h @@ -342,11 +351,12 @@ def cleanup_headers(config_attrs, dry_run): patterns.append(re.compile(r'#\s*define\s+%s\W' % config)) patterns.append(re.compile(r'#\s*undef\s+%s\W' % config)) - for (dirpath, dirnames, filenames) in os.walk('include'): - for filename in filenames: - if not fnmatch.fnmatch(filename, '*~'): - cleanup_one_header(os.path.join(dirpath, filename), patterns, - dry_run) + for dir in 'include', 'arch', 'board': + for (dirpath, dirnames, filenames) in os.walk(dir): + for filename in filenames: + if not fnmatch.fnmatch(filename, '*~'): + cleanup_one_header(os.path.join(dirpath, filename), + patterns, dry_run) ### classes ### class KconfigParser: @@ -549,7 +559,7 @@ class Slot: pass shutil.rmtree(self.build_dir) - def add(self, defconfig): + def add(self, defconfig, num, total): """Assign a new subprocess for defconfig and add it to the slot. If the slot is vacant, create a new subprocess for processing the @@ -566,9 +576,12 @@ class Slot: return False cmd = list(self.make_cmd) cmd.append(defconfig) - self.ps = subprocess.Popen(cmd, stdout=self.devnull) + self.ps = subprocess.Popen(cmd, stdout=self.devnull, + stderr=subprocess.PIPE) self.defconfig = defconfig self.state = STATE_DEFCONFIG + self.num = num + self.total = total return True def poll(self): @@ -591,11 +604,21 @@ class Slot: return False if self.ps.poll() != 0: - + errmsg = 'Failed to process.' + errout = self.ps.stderr.read() + if errout.find('gcc: command not found') != -1: + errmsg = 'Compiler not found (' + errmsg += color_text(self.options.color, COLOR_YELLOW, + self.cross_compile) + errmsg += color_text(self.options.color, COLOR_LIGHT_RED, + ')') print >> sys.stderr, log_msg(self.options.color, COLOR_LIGHT_RED, self.defconfig, - "failed to process.") + errmsg), + if self.options.verbose: + print >> sys.stderr, color_text(self.options.color, + COLOR_LIGHT_CYAN, errout) if self.options.exit_on_error: sys.exit("Exit on error.") else: @@ -609,11 +632,14 @@ class Slot: if self.state == STATE_AUTOCONF: self.parser.update_defconfig(self.defconfig) + print ' %d defconfigs out of %d\r' % (self.num + 1, self.total), + sys.stdout.flush() + """Save off the defconfig in a consistent way""" cmd = list(self.make_cmd) cmd.append('savedefconfig') self.ps = subprocess.Popen(cmd, stdout=self.devnull, - stderr=self.devnull) + stderr=subprocess.PIPE) self.state = STATE_SAVEDEFCONFIG return False @@ -624,13 +650,17 @@ class Slot: self.state = STATE_IDLE return True - cross_compile = self.parser.get_cross_compile() + self.cross_compile = self.parser.get_cross_compile() cmd = list(self.make_cmd) - if cross_compile: - cmd.append('CROSS_COMPILE=%s' % cross_compile) + if self.cross_compile: + cmd.append('CROSS_COMPILE=%s' % self.cross_compile) cmd.append('KCONFIG_IGNORE_DUPLICATES=1') cmd.append('include/config/auto.conf') - self.ps = subprocess.Popen(cmd, stdout=self.devnull) + """This will be screen-scraped, so be sure the expected text will be + returned consistently on every machine by setting LANG=C""" + self.ps = subprocess.Popen(cmd, stdout=self.devnull, + env=dict(os.environ, LANG='C'), + stderr=subprocess.PIPE) self.state = STATE_AUTOCONF return False @@ -658,7 +688,7 @@ class Slots: for i in range(options.jobs): self.slots.append(Slot(config_attrs, options, devnull, make_cmd)) - def add(self, defconfig): + def add(self, defconfig, num, total): """Add a new subprocess if a vacant slot is found. Arguments: @@ -668,7 +698,7 @@ class Slots: Return True on success or False on failure """ for slot in self.slots: - if slot.add(defconfig): + if slot.add(defconfig, num, total): return True return False @@ -709,6 +739,10 @@ class Slots: print >> sys.stderr, color_text(self.options.color, COLOR_LIGHT_RED, line) + with open('moveconfig.failed', 'w') as f: + for board in failed_boards: + f.write(board + '\n') + def move_config(config_attrs, options): """Move config options to defconfig files. @@ -717,8 +751,6 @@ def move_config(config_attrs, options): the type, and the default value of the target config. options: option flags """ - check_top_directory() - if len(config_attrs) == 0: print 'Nothing to do. exit.' sys.exit(0) @@ -729,20 +761,29 @@ def move_config(config_attrs, options): config_attr['type'], config_attr['default']) - # All the defconfig files to be processed - defconfigs = [] - for (dirpath, dirnames, filenames) in os.walk('configs'): - dirpath = dirpath[len('configs') + 1:] - for filename in fnmatch.filter(filenames, '*_defconfig'): - defconfigs.append(os.path.join(dirpath, filename)) + if options.defconfigs: + defconfigs = [line.strip() for line in open(options.defconfigs)] + for i, defconfig in enumerate(defconfigs): + if not defconfig.endswith('_defconfig'): + defconfigs[i] = defconfig + '_defconfig' + if not os.path.exists(os.path.join('configs', defconfigs[i])): + sys.exit('%s - defconfig does not exist. Stopping.' % + defconfigs[i]) + else: + # All the defconfig files to be processed + defconfigs = [] + for (dirpath, dirnames, filenames) in os.walk('configs'): + dirpath = dirpath[len('configs') + 1:] + for filename in fnmatch.filter(filenames, '*_defconfig'): + defconfigs.append(os.path.join(dirpath, filename)) slots = Slots(config_attrs, options) # Main loop to process defconfig files: # Add a new subprocess into a vacant slot. # Sleep if there is no available slot. - for defconfig in defconfigs: - while not slots.add(defconfig): + for i, defconfig in enumerate(defconfigs): + while not slots.add(defconfig, i, len(defconfigs)): while not slots.available(): # No available slot: sleep for a while time.sleep(SLEEP_TIME) @@ -751,10 +792,9 @@ def move_config(config_attrs, options): while not slots.empty(): time.sleep(SLEEP_TIME) + print '' slots.show_failed_boards() - cleanup_headers(config_attrs, options.dry_run) - def bad_recipe(filename, linenum, msg): """Print error message with the file name and the line number and exit.""" sys.exit("%s: line %d: error : " % (filename, linenum) + msg) @@ -835,13 +875,20 @@ def main(): # Add options here parser.add_option('-c', '--color', action='store_true', default=False, help='display the log in color') + parser.add_option('-d', '--defconfigs', type='string', + help='a file containing a list of defconfigs to move') parser.add_option('-n', '--dry-run', action='store_true', default=False, help='perform a trial run (show log with no changes)') parser.add_option('-e', '--exit-on-error', action='store_true', default=False, help='exit immediately on any error') + parser.add_option('-H', '--headers-only', dest='cleanup_headers_only', + action='store_true', default=False, + help='only cleanup the headers') parser.add_option('-j', '--jobs', type='int', default=cpu_count, help='the number of jobs to run simultaneously') + parser.add_option('-v', '--verbose', action='store_true', default=False, + help='show any build errors as boards are built') parser.usage += ' recipe_file\n\n' + \ 'The recipe_file should describe config options you want to move.\n' + \ 'Each line should contain config_name, type, default_value\n\n' + \ @@ -860,7 +907,12 @@ def main(): update_cross_compile() - move_config(config_attrs, options) + check_top_directory() + + if not options.cleanup_headers_only: + move_config(config_attrs, options) + + cleanup_headers(config_attrs, options.dry_run) if __name__ == '__main__': main()