mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-14 00:47:26 +00:00
moveconfig: Support building a simple config database
Add a -b option which scans all the defconfigs and builds a database of all the CONFIG options used by each. This is useful for querying later. At present this only works with the separate -b option, which does not move any configs. It would be possible to adjust the script to build the database automatically when moving configs, but this might not be useful as the database does not change that often. Signed-off-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
parent
f3b8e6470c
commit
d73fcb12e2
1 changed files with 74 additions and 7 deletions
|
@ -203,11 +203,13 @@ import glob
|
||||||
import multiprocessing
|
import multiprocessing
|
||||||
import optparse
|
import optparse
|
||||||
import os
|
import os
|
||||||
|
import Queue
|
||||||
import re
|
import re
|
||||||
import shutil
|
import shutil
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
import tempfile
|
import tempfile
|
||||||
|
import threading
|
||||||
import time
|
import time
|
||||||
|
|
||||||
SHOW_GNU_MAKE = 'scripts/show-gnu-make'
|
SHOW_GNU_MAKE = 'scripts/show-gnu-make'
|
||||||
|
@ -263,6 +265,7 @@ COLOR_LIGHT_CYAN = '1;36'
|
||||||
COLOR_WHITE = '1;37'
|
COLOR_WHITE = '1;37'
|
||||||
|
|
||||||
AUTO_CONF_PATH = 'include/config/auto.conf'
|
AUTO_CONF_PATH = 'include/config/auto.conf'
|
||||||
|
CONFIG_DATABASE = 'moveconfig.db'
|
||||||
|
|
||||||
|
|
||||||
### helper functions ###
|
### helper functions ###
|
||||||
|
@ -940,6 +943,34 @@ class KconfigParser:
|
||||||
|
|
||||||
return log
|
return log
|
||||||
|
|
||||||
|
|
||||||
|
class DatabaseThread(threading.Thread):
|
||||||
|
"""This thread processes results from Slot threads.
|
||||||
|
|
||||||
|
It collects the data in the master config directary. There is only one
|
||||||
|
result thread, and this helps to serialise the build output.
|
||||||
|
"""
|
||||||
|
def __init__(self, config_db, db_queue):
|
||||||
|
"""Set up a new result thread
|
||||||
|
|
||||||
|
Args:
|
||||||
|
builder: Builder which will be sent each result
|
||||||
|
"""
|
||||||
|
threading.Thread.__init__(self)
|
||||||
|
self.config_db = config_db
|
||||||
|
self.db_queue= db_queue
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
"""Called to start up the result thread.
|
||||||
|
|
||||||
|
We collect the next result job and pass it on to the build.
|
||||||
|
"""
|
||||||
|
while True:
|
||||||
|
defconfig, configs = self.db_queue.get()
|
||||||
|
self.config_db[defconfig] = configs
|
||||||
|
self.db_queue.task_done()
|
||||||
|
|
||||||
|
|
||||||
class Slot:
|
class Slot:
|
||||||
|
|
||||||
"""A slot to store a subprocess.
|
"""A slot to store a subprocess.
|
||||||
|
@ -949,7 +980,8 @@ class Slot:
|
||||||
for faster processing.
|
for faster processing.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, configs, options, progress, devnull, make_cmd, reference_src_dir):
|
def __init__(self, configs, options, progress, devnull, make_cmd,
|
||||||
|
reference_src_dir, db_queue):
|
||||||
"""Create a new process slot.
|
"""Create a new process slot.
|
||||||
|
|
||||||
Arguments:
|
Arguments:
|
||||||
|
@ -960,6 +992,7 @@ class Slot:
|
||||||
make_cmd: command name of GNU Make.
|
make_cmd: command name of GNU Make.
|
||||||
reference_src_dir: Determine the true starting config state from this
|
reference_src_dir: Determine the true starting config state from this
|
||||||
source tree.
|
source tree.
|
||||||
|
db_queue: output queue to write config info for the database
|
||||||
"""
|
"""
|
||||||
self.options = options
|
self.options = options
|
||||||
self.progress = progress
|
self.progress = progress
|
||||||
|
@ -967,6 +1000,7 @@ class Slot:
|
||||||
self.devnull = devnull
|
self.devnull = devnull
|
||||||
self.make_cmd = (make_cmd, 'O=' + self.build_dir)
|
self.make_cmd = (make_cmd, 'O=' + self.build_dir)
|
||||||
self.reference_src_dir = reference_src_dir
|
self.reference_src_dir = reference_src_dir
|
||||||
|
self.db_queue = db_queue
|
||||||
self.parser = KconfigParser(configs, options, self.build_dir)
|
self.parser = KconfigParser(configs, options, self.build_dir)
|
||||||
self.state = STATE_IDLE
|
self.state = STATE_IDLE
|
||||||
self.failed_boards = set()
|
self.failed_boards = set()
|
||||||
|
@ -1042,6 +1076,8 @@ class Slot:
|
||||||
if self.current_src_dir:
|
if self.current_src_dir:
|
||||||
self.current_src_dir = None
|
self.current_src_dir = None
|
||||||
self.do_defconfig()
|
self.do_defconfig()
|
||||||
|
elif self.options.build_db:
|
||||||
|
self.do_build_db()
|
||||||
else:
|
else:
|
||||||
self.do_savedefconfig()
|
self.do_savedefconfig()
|
||||||
elif self.state == STATE_SAVEDEFCONFIG:
|
elif self.state == STATE_SAVEDEFCONFIG:
|
||||||
|
@ -1091,6 +1127,17 @@ class Slot:
|
||||||
cwd=self.current_src_dir)
|
cwd=self.current_src_dir)
|
||||||
self.state = STATE_AUTOCONF
|
self.state = STATE_AUTOCONF
|
||||||
|
|
||||||
|
def do_build_db(self):
|
||||||
|
"""Add the board to the database"""
|
||||||
|
configs = {}
|
||||||
|
with open(os.path.join(self.build_dir, AUTO_CONF_PATH)) as fd:
|
||||||
|
for line in fd.readlines():
|
||||||
|
if line.startswith('CONFIG'):
|
||||||
|
config, value = line.split('=', 1)
|
||||||
|
configs[config] = value.rstrip()
|
||||||
|
self.db_queue.put([self.defconfig, configs])
|
||||||
|
self.finish(True)
|
||||||
|
|
||||||
def do_savedefconfig(self):
|
def do_savedefconfig(self):
|
||||||
"""Update the .config and run 'make savedefconfig'."""
|
"""Update the .config and run 'make savedefconfig'."""
|
||||||
|
|
||||||
|
@ -1173,7 +1220,7 @@ class Slots:
|
||||||
|
|
||||||
"""Controller of the array of subprocess slots."""
|
"""Controller of the array of subprocess slots."""
|
||||||
|
|
||||||
def __init__(self, configs, options, progress, reference_src_dir):
|
def __init__(self, configs, options, progress, reference_src_dir, db_queue):
|
||||||
"""Create a new slots controller.
|
"""Create a new slots controller.
|
||||||
|
|
||||||
Arguments:
|
Arguments:
|
||||||
|
@ -1182,6 +1229,7 @@ class Slots:
|
||||||
progress: A progress indicator.
|
progress: A progress indicator.
|
||||||
reference_src_dir: Determine the true starting config state from this
|
reference_src_dir: Determine the true starting config state from this
|
||||||
source tree.
|
source tree.
|
||||||
|
db_queue: output queue to write config info for the database
|
||||||
"""
|
"""
|
||||||
self.options = options
|
self.options = options
|
||||||
self.slots = []
|
self.slots = []
|
||||||
|
@ -1189,7 +1237,7 @@ class Slots:
|
||||||
make_cmd = get_make_cmd()
|
make_cmd = get_make_cmd()
|
||||||
for i in range(options.jobs):
|
for i in range(options.jobs):
|
||||||
self.slots.append(Slot(configs, options, progress, devnull,
|
self.slots.append(Slot(configs, options, progress, devnull,
|
||||||
make_cmd, reference_src_dir))
|
make_cmd, reference_src_dir, db_queue))
|
||||||
|
|
||||||
def add(self, defconfig):
|
def add(self, defconfig):
|
||||||
"""Add a new subprocess if a vacant slot is found.
|
"""Add a new subprocess if a vacant slot is found.
|
||||||
|
@ -1301,7 +1349,7 @@ class ReferenceSource:
|
||||||
|
|
||||||
return self.src_dir
|
return self.src_dir
|
||||||
|
|
||||||
def move_config(configs, options):
|
def move_config(configs, options, db_queue):
|
||||||
"""Move config options to defconfig files.
|
"""Move config options to defconfig files.
|
||||||
|
|
||||||
Arguments:
|
Arguments:
|
||||||
|
@ -1311,6 +1359,8 @@ def move_config(configs, options):
|
||||||
if len(configs) == 0:
|
if len(configs) == 0:
|
||||||
if options.force_sync:
|
if options.force_sync:
|
||||||
print 'No CONFIG is specified. You are probably syncing defconfigs.',
|
print 'No CONFIG is specified. You are probably syncing defconfigs.',
|
||||||
|
elif options.build_db:
|
||||||
|
print 'Building %s database' % CONFIG_DATABASE
|
||||||
else:
|
else:
|
||||||
print 'Neither CONFIG nor --force-sync is specified. Nothing will happen.',
|
print 'Neither CONFIG nor --force-sync is specified. Nothing will happen.',
|
||||||
else:
|
else:
|
||||||
|
@ -1329,7 +1379,7 @@ def move_config(configs, options):
|
||||||
defconfigs = get_all_defconfigs()
|
defconfigs = get_all_defconfigs()
|
||||||
|
|
||||||
progress = Progress(len(defconfigs))
|
progress = Progress(len(defconfigs))
|
||||||
slots = Slots(configs, options, progress, reference_src_dir)
|
slots = Slots(configs, options, progress, reference_src_dir, db_queue)
|
||||||
|
|
||||||
# Main loop to process defconfig files:
|
# Main loop to process defconfig files:
|
||||||
# Add a new subprocess into a vacant slot.
|
# Add a new subprocess into a vacant slot.
|
||||||
|
@ -1356,6 +1406,8 @@ def main():
|
||||||
|
|
||||||
parser = optparse.OptionParser()
|
parser = optparse.OptionParser()
|
||||||
# Add options here
|
# Add options here
|
||||||
|
parser.add_option('-b', '--build-db', action='store_true', default=False,
|
||||||
|
help='build a CONFIG database')
|
||||||
parser.add_option('-c', '--color', action='store_true', default=False,
|
parser.add_option('-c', '--color', action='store_true', default=False,
|
||||||
help='display the log in color')
|
help='display the log in color')
|
||||||
parser.add_option('-C', '--commit', action='store_true', default=False,
|
parser.add_option('-C', '--commit', action='store_true', default=False,
|
||||||
|
@ -1388,7 +1440,7 @@ def main():
|
||||||
|
|
||||||
(options, configs) = parser.parse_args()
|
(options, configs) = parser.parse_args()
|
||||||
|
|
||||||
if len(configs) == 0 and not options.force_sync:
|
if len(configs) == 0 and not any((options.force_sync, options.build_db)):
|
||||||
parser.print_usage()
|
parser.print_usage()
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
|
@ -1398,10 +1450,17 @@ def main():
|
||||||
|
|
||||||
check_top_directory()
|
check_top_directory()
|
||||||
|
|
||||||
|
config_db = {}
|
||||||
|
db_queue = Queue.Queue()
|
||||||
|
t = DatabaseThread(config_db, db_queue)
|
||||||
|
t.setDaemon(True)
|
||||||
|
t.start()
|
||||||
|
|
||||||
if not options.cleanup_headers_only:
|
if not options.cleanup_headers_only:
|
||||||
check_clean_directory()
|
check_clean_directory()
|
||||||
update_cross_compile(options.color)
|
update_cross_compile(options.color)
|
||||||
move_config(configs, options)
|
move_config(configs, options, db_queue)
|
||||||
|
db_queue.join()
|
||||||
|
|
||||||
if configs:
|
if configs:
|
||||||
cleanup_headers(configs, options)
|
cleanup_headers(configs, options)
|
||||||
|
@ -1421,5 +1480,13 @@ def main():
|
||||||
msg += '\n\nRsync all defconfig files using moveconfig.py'
|
msg += '\n\nRsync all defconfig files using moveconfig.py'
|
||||||
subprocess.call(['git', 'commit', '-s', '-m', msg])
|
subprocess.call(['git', 'commit', '-s', '-m', msg])
|
||||||
|
|
||||||
|
if options.build_db:
|
||||||
|
with open(CONFIG_DATABASE, 'w') as fd:
|
||||||
|
for defconfig, configs in config_db.iteritems():
|
||||||
|
print >>fd, '%s' % defconfig
|
||||||
|
for config in sorted(configs.keys()):
|
||||||
|
print >>fd, ' %s=%s' % (config, configs[config])
|
||||||
|
print >>fd
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
main()
|
main()
|
||||||
|
|
Loading…
Reference in a new issue