tools: moveconfig: Add a new --git-ref option

This option allows the 'make autoconf.mk' step to run against a former
repo state, while the savedefconfig step runs against the current repo
state. This is convenient for the case where something in the Kconfig
has changed such that the defconfig is no longer complete with the new
Kconfigs. This feature allows the .config to be built assuming those old
Kconfigs, but then savedefconfig based on the new state of the Kconfigs.

If in doubt, always specify this switch. It will always do the right
thing even if not required, but if it was required and you don't use it,
the moved configs will be incorrect. When not using this switch, you
must very carefully evaluate that all moved configs are correct.

Signed-off-by: Joe Hershberger <joe.hershberger@ni.com>
Reviewed-by: Masahiro Yamada <yamada.masahiro@socionext.com>
This commit is contained in:
Joe Hershberger 2016-06-10 14:53:32 -05:00 committed by Masahiro Yamada
parent 06cc1d36d0
commit 6b96c1a1ca

View File

@ -143,6 +143,14 @@ Available options
Specify the number of threads to run simultaneously. If not specified,
the number of threads is the same as the number of CPU cores.
-r, --git-ref
Specify the git ref to clone for building the autoconf.mk. If unspecified
use the CWD. This is useful for when changes to the Kconfig affect the
default values and you want to capture the state of the defconfig from
before that change was in effect. If in doubt, specify a ref pre-Kconfig
changes (use HEAD if Kconfig changes are not committed). Worst case it will
take a bit longer to run, but will always do the right thing.
-v, --verbose
Show any build errors as boards are built
@ -584,7 +592,7 @@ class Slot:
for faster processing.
"""
def __init__(self, configs, options, progress, devnull, make_cmd):
def __init__(self, configs, options, progress, devnull, make_cmd, reference_src_dir):
"""Create a new process slot.
Arguments:
@ -593,12 +601,15 @@ class Slot:
progress: A progress indicator.
devnull: A file object of '/dev/null'.
make_cmd: command name of GNU Make.
reference_src_dir: Determine the true starting config state from this
source tree.
"""
self.options = options
self.progress = progress
self.build_dir = tempfile.mkdtemp()
self.devnull = devnull
self.make_cmd = (make_cmd, 'O=' + self.build_dir)
self.reference_src_dir = reference_src_dir
self.parser = KconfigParser(configs, options, self.build_dir)
self.state = STATE_IDLE
self.failed_boards = []
@ -636,6 +647,7 @@ class Slot:
self.defconfig = defconfig
self.log = ''
self.use_git_ref = True if self.options.git_ref else False
self.do_defconfig()
return True
@ -664,9 +676,16 @@ class Slot:
if self.ps.poll() != 0:
self.handle_error()
elif self.state == STATE_DEFCONFIG:
self.do_autoconf()
if self.options.git_ref and not self.use_git_ref:
self.do_savedefconfig()
else:
self.do_autoconf()
elif self.state == STATE_AUTOCONF:
self.do_savedefconfig()
if self.use_git_ref:
self.use_git_ref = False
self.do_defconfig()
else:
self.do_savedefconfig()
elif self.state == STATE_SAVEDEFCONFIG:
self.update_defconfig()
else:
@ -689,6 +708,9 @@ class Slot:
cmd = list(self.make_cmd)
cmd.append(self.defconfig)
if self.use_git_ref:
cmd.append('-C')
cmd.append(self.reference_src_dir)
self.ps = subprocess.Popen(cmd, stdout=self.devnull,
stderr=subprocess.PIPE)
self.state = STATE_DEFCONFIG
@ -708,6 +730,9 @@ class Slot:
cmd.append('CROSS_COMPILE=%s' % self.cross_compile)
cmd.append('KCONFIG_IGNORE_DUPLICATES=1')
cmd.append('include/config/auto.conf')
if self.use_git_ref:
cmd.append('-C')
cmd.append(self.reference_src_dir)
self.ps = subprocess.Popen(cmd, stdout=self.devnull,
stderr=subprocess.PIPE)
self.state = STATE_AUTOCONF
@ -784,13 +809,15 @@ class Slots:
"""Controller of the array of subprocess slots."""
def __init__(self, configs, options, progress):
def __init__(self, configs, options, progress, reference_src_dir):
"""Create a new slots controller.
Arguments:
configs: A list of CONFIGs to move.
options: option flags.
progress: A progress indicator.
reference_src_dir: Determine the true starting config state from this
source tree.
"""
self.options = options
self.slots = []
@ -798,7 +825,7 @@ class Slots:
make_cmd = get_make_cmd()
for i in range(options.jobs):
self.slots.append(Slot(configs, options, progress, devnull,
make_cmd))
make_cmd, reference_src_dir))
def add(self, defconfig):
"""Add a new subprocess if a vacant slot is found.
@ -855,6 +882,24 @@ class Slots:
for board in failed_boards:
f.write(board + '\n')
class WorkDir:
def __init__(self):
"""Create a new working directory."""
self.work_dir = tempfile.mkdtemp()
def __del__(self):
"""Delete the working directory
This function makes sure the temporary directory is cleaned away
even if Python suddenly dies due to error. It should be done in here
because it is guaranteed the destructor is always invoked when the
instance of the class gets unreferenced.
"""
shutil.rmtree(self.work_dir)
def get(self):
return self.work_dir
def move_config(configs, options):
"""Move config options to defconfig files.
@ -871,6 +916,21 @@ def move_config(configs, options):
print 'Move ' + ', '.join(configs),
print '(jobs: %d)\n' % options.jobs
reference_src_dir = ''
if options.git_ref:
work_dir = WorkDir()
reference_src_dir = work_dir.get()
print "Cloning git repo to a separate work directory..."
subprocess.check_output(['git', 'clone', os.getcwd(), '.'],
cwd=reference_src_dir)
print "Checkout '%s' to build the original autoconf.mk." % \
subprocess.check_output(['git', 'rev-parse', '--short',
options.git_ref]).strip()
subprocess.check_output(['git', 'checkout', options.git_ref],
stderr=subprocess.STDOUT,
cwd=reference_src_dir)
if options.defconfigs:
defconfigs = [line.strip() for line in open(options.defconfigs)]
for i, defconfig in enumerate(defconfigs):
@ -888,7 +948,7 @@ def move_config(configs, options):
defconfigs.append(os.path.join(dirpath, filename))
progress = Progress(len(defconfigs))
slots = Slots(configs, options, progress)
slots = Slots(configs, options, progress, reference_src_dir)
# Main loop to process defconfig files:
# Add a new subprocess into a vacant slot.
@ -930,6 +990,8 @@ def main():
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('-r', '--git-ref', type='string',
help='the git ref to clone for building the autoconf.mk')
parser.add_option('-v', '--verbose', action='store_true', default=False,
help='show any build errors as boards are built')
parser.usage += ' CONFIG ...'