STATE_AUTOCONF = 2
STATE_SAVEDEFCONFIG = 3
-ACTION_MOVE = 0
-ACTION_NO_ENTRY = 1
-ACTION_NO_ENTRY_WARN = 2
-ACTION_NO_CHANGE = 3
-
COLOR_BLACK = '0;30'
COLOR_RED = '0;31'
COLOR_GREEN = '0;32'
re_arch = re.compile(r'CONFIG_SYS_ARCH="(.*)"')
re_cpu = re.compile(r'CONFIG_SYS_CPU="(.*)"')
- def __init__(self, configs, args, build_dir):
+ def __init__(self, args, build_dir):
"""Create a new parser.
Args:
- configs: A list of CONFIGs to move.
args (Namespace): program arguments
build_dir: Build directory.
"""
- self.configs = configs
self.args = args
self.dotconfig = os.path.join(build_dir, '.config')
self.autoconf = os.path.join(build_dir, 'include', 'autoconf.mk')
return arch
- def parse_one_config(self, config, dotconfig_lines, autoconf_lines):
- """Parse .config, defconfig, include/autoconf.mk for one config.
-
- This function looks for the config options in the lines from
- defconfig, .config, and include/autoconf.mk in order to decide
- which action should be taken for this defconfig.
-
- Args:
- config: CONFIG name to parse.
- dotconfig_lines: lines from the .config file.
- autoconf_lines: lines from the include/autoconf.mk file.
-
- Returns:
- A tupple of the action for this defconfig and the line
- matched for the config.
- """
- not_set = '# %s is not set' % config
-
- for line in autoconf_lines:
- line = line.rstrip()
- if line.startswith(config + '='):
- new_val = line
- break
- else:
- new_val = not_set
-
- new_val = try_expand(new_val)
-
- for line in dotconfig_lines:
- line = line.rstrip()
- if line.startswith(config + '=') or line == not_set:
- old_val = line
- break
- else:
- if new_val == not_set:
- return (ACTION_NO_ENTRY, config)
- else:
- return (ACTION_NO_ENTRY_WARN, config)
-
- # If this CONFIG is neither bool nor trisate
- if old_val[-2:] != '=y' and old_val[-2:] != '=m' and old_val != not_set:
- # tools/scripts/define2mk.sed changes '1' to 'y'.
- # This is a problem if the CONFIG is int type.
- # Check the type in Kconfig and handle it correctly.
- if new_val[-2:] == '=y':
- new_val = new_val[:-1] + '1'
-
- return (ACTION_NO_CHANGE if old_val == new_val else ACTION_MOVE,
- new_val)
-
def update_dotconfig(self):
"""Parse files for the config options and update the .config.
The "updated flag" is True if the .config was updated, False
otherwise. The "log string" shows what happend to the .config.
"""
-
- results = []
updated = False
suspicious = False
- rm_files = [self.config_autoconf, self.autoconf]
- if self.args.spl:
- if os.path.exists(self.spl_autoconf):
- autoconf_path = self.spl_autoconf
- rm_files.append(self.spl_autoconf)
- else:
- for f in rm_files:
- os.remove(f)
- return (updated, suspicious,
- color_text(self.args.color, COLOR_BROWN,
- "SPL is not enabled. Skipped.") + '\n')
- else:
- autoconf_path = self.autoconf
+ autoconf_path = self.autoconf
dotconfig_lines = read_file(self.dotconfig)
autoconf_lines = read_file(autoconf_path)
- for config in self.configs:
- result = self.parse_one_config(config, dotconfig_lines,
- autoconf_lines)
- results.append(result)
-
log = ''
- for (action, value) in results:
- if action == ACTION_MOVE:
- actlog = "Move '%s'" % value
- log_color = COLOR_LIGHT_GREEN
- elif action == ACTION_NO_ENTRY:
- actlog = '%s is not defined in Kconfig. Do nothing.' % value
- log_color = COLOR_LIGHT_BLUE
- elif action == ACTION_NO_ENTRY_WARN:
- actlog = '%s is not defined in Kconfig (suspicious). Do nothing.' % value
- log_color = COLOR_YELLOW
- suspicious = True
- elif action == ACTION_NO_CHANGE:
- actlog = "'%s' is the same as the define in Kconfig. Do nothing." \
- % value
- log_color = COLOR_LIGHT_PURPLE
- else:
- sys.exit('Internal Error. This should not happen.')
-
- log += color_text(self.args.color, log_color, actlog) + '\n'
-
- with open(self.dotconfig, 'a', encoding='utf-8') as out:
- for (action, value) in results:
- if action == ACTION_MOVE:
- out.write(value + '\n')
- updated = True
-
- self.results = results
- for f in rm_files:
- os.remove(f)
-
return (updated, suspicious, log)
def check_defconfig(self):
defconfig_lines = read_file(self.defconfig)
- for (action, value) in self.results:
- if action != ACTION_MOVE:
- continue
- if not value in defconfig_lines:
- log += color_text(self.args.color, COLOR_YELLOW,
- "'%s' was removed by savedefconfig.\n" %
- value)
-
return log
for faster processing.
"""
- def __init__(self, toolchains, configs, args, progress, devnull,
+ def __init__(self, toolchains, args, progress, devnull,
make_cmd, reference_src_dir, db_queue):
"""Create a new process slot.
Args:
toolchains: Toolchains object containing toolchains.
- configs: A list of CONFIGs to move.
args: Program arguments
progress: A progress indicator.
devnull: A file object of '/dev/null'.
self.make_cmd = (make_cmd, 'O=' + self.build_dir)
self.reference_src_dir = reference_src_dir
self.db_queue = db_queue
- self.parser = KconfigParser(configs, args, self.build_dir)
+ self.parser = KconfigParser(args, self.build_dir)
self.state = STATE_IDLE
self.failed_boards = set()
self.suspicious_boards = set()
"""Controller of the array of subprocess slots."""
- def __init__(self, toolchains, configs, args, progress,
- reference_src_dir, db_queue):
+ def __init__(self, toolchains, args, progress, reference_src_dir, db_queue):
"""Create a new slots controller.
Args:
toolchains: Toolchains object containing toolchains.
- configs: A list of CONFIGs to move.
args: Program arguments
progress: A progress indicator.
reference_src_dir: Determine the true starting config state from this
devnull = subprocess.DEVNULL
make_cmd = get_make_cmd()
for i in range(args.jobs):
- self.slots.append(Slot(toolchains, configs, args, progress,
- devnull, make_cmd, reference_src_dir,
- db_queue))
+ self.slots.append(Slot(toolchains, args, progress, devnull,
+ make_cmd, reference_src_dir, db_queue))
def add(self, defconfig):
"""Add a new subprocess if a vacant slot is found.
return self.src_dir
-def move_config(toolchains, configs, args, db_queue):
- """Move config options to defconfig files.
+def move_config(toolchains, args, db_queue):
+ """Build database or sync config options to defconfig files.
Args:
- configs: A list of CONFIGs to move.
+ toolchains: Toolchains to use
args: Program arguments
+ db_queue: Queue for database updates
"""
- if len(configs) == 0:
- if args.force_sync:
- print('No CONFIG is specified. You are probably syncing defconfigs.', end=' ')
- elif args.build_db:
- print('Building %s database' % CONFIG_DATABASE)
- else:
- print('Neither CONFIG nor --force-sync is specified. Nothing will happen.', end=' ')
- else:
- print('Move ' + ', '.join(configs), end=' ')
+ if args.force_sync:
+ print('Syncing defconfigs', end=' ')
+ elif args.build_db:
+ print('Building %s database' % CONFIG_DATABASE)
print('(jobs: %d)\n' % args.jobs)
if args.git_ref:
defconfigs = get_all_defconfigs()
progress = Progress(len(defconfigs))
- slots = Slots(toolchains, configs, args, progress, reference_src_dir,
- db_queue)
+ slots = Slots(toolchains, args, progress, reference_src_dir, db_queue)
# Main loop to process defconfig files:
# Add a new subprocess into a vacant slot.
parser.add_argument('configs', nargs='*')
args = parser.parse_args()
- configs = args.configs
if args.test:
sys.argv = [sys.argv[0]]
do_scan_source(os.getcwd(), args.update)
return
- if not any((len(configs), args.force_sync, args.build_db, args.imply,
- args.find)):
+ if not any((args.force_sync, args.build_db, args.imply, args.find)):
parser.print_usage()
sys.exit(1)
# prefix the option name with CONFIG_ if missing
- configs = [prefix_config(cfg) for cfg in configs]
+ configs = [prefix_config(cfg) for cfg in args.configs]
check_top_directory()
toolchains = toolchain.Toolchains()
toolchains.GetSettings()
toolchains.Scan(verbose=False)
- move_config(toolchains, [], args, db_queue)
+ move_config(toolchains, args, db_queue)
db_queue.join()
if args.commit: