mirror of
https://xff.cz/git/u-boot/
synced 2025-09-30 15:01:27 +02:00
moveconfig: Allow querying board configuration
It is useful to be able to find out which boards define a particular option, or combination of options. This is not as easy as grepping the defconfig files since many options are implied by others. Add a -f option to the moveconfig tool to permit this. Update the documentation to cover this, including a better title for the doc page. Signed-off-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
.. SPDX-License-Identifier: GPL-2.0+
|
.. SPDX-License-Identifier: GPL-2.0+
|
||||||
|
|
||||||
moveconfig
|
moveconfig - Migrating and querying CONFIG options
|
||||||
==========
|
==================================================
|
||||||
|
|
||||||
Since Kconfig was introduced to U-Boot, we have worked on moving
|
Since Kconfig was introduced to U-Boot, we have worked on moving
|
||||||
config options from headers to Kconfig (defconfig).
|
config options from headers to Kconfig (defconfig).
|
||||||
@@ -129,6 +129,24 @@ To process CONFIG_CMD_FPGAD only for a subset of configs based on path match::
|
|||||||
./tools/moveconfig.py -Cy CONFIG_CMD_FPGAD -d -
|
./tools/moveconfig.py -Cy CONFIG_CMD_FPGAD -d -
|
||||||
|
|
||||||
|
|
||||||
|
Finding boards with particular CONFIG combinations
|
||||||
|
--------------------------------------------------
|
||||||
|
|
||||||
|
You can use `moveconfig.py` to figure out which boards have a CONFIG enabled, or
|
||||||
|
which do not. To use it, first build a database::
|
||||||
|
|
||||||
|
./tools/moveconfig.py -b
|
||||||
|
|
||||||
|
Then you can run queries using the `-f` flag followed by a list of CONFIG terms.
|
||||||
|
Each term is CONFIG name, with or without a tilde (~) prefix. The tool searches
|
||||||
|
for boards which match the CONFIG name, or do not match if tilde is used. For
|
||||||
|
example, to find boards which enabled CONFIG_SCSI but not CONFIG_BLK::
|
||||||
|
|
||||||
|
tools/moveconfig.py -f SCSI ~BLK
|
||||||
|
3 matches
|
||||||
|
pg_wcom_seli8_defconfig highbank_defconfig pg_wcom_expu1_defconfig
|
||||||
|
|
||||||
|
|
||||||
Finding implied CONFIGs
|
Finding implied CONFIGs
|
||||||
-----------------------
|
-----------------------
|
||||||
|
|
||||||
@@ -235,6 +253,9 @@ Available options
|
|||||||
Specify a file containing a list of defconfigs to move. The defconfig
|
Specify a file containing a list of defconfigs to move. The defconfig
|
||||||
files can be given with shell-style wildcards. Use '-' to read from stdin.
|
files can be given with shell-style wildcards. Use '-' to read from stdin.
|
||||||
|
|
||||||
|
-f, --find
|
||||||
|
Find boards with a given config combination
|
||||||
|
|
||||||
-n, --dry-run
|
-n, --dry-run
|
||||||
Perform a trial run that does not make any changes. It is useful to
|
Perform a trial run that does not make any changes. It is useful to
|
||||||
see what is going to happen before one actually runs it.
|
see what is going to happen before one actually runs it.
|
||||||
|
@@ -1569,6 +1569,79 @@ def do_imply_config(config_list, add_imply, imply_flags, skip_added,
|
|||||||
add_imply_rule(config[CONFIG_LEN:], fname, linenum)
|
add_imply_rule(config[CONFIG_LEN:], fname, linenum)
|
||||||
|
|
||||||
|
|
||||||
|
def do_find_config(config_list):
|
||||||
|
"""Find boards with a given combination of CONFIGs
|
||||||
|
|
||||||
|
Params:
|
||||||
|
config_list: List of CONFIG options to check (each a string consisting
|
||||||
|
of a config option, with or without a CONFIG_ prefix. If an option
|
||||||
|
is preceded by a tilde (~) then it must be false, otherwise it must
|
||||||
|
be true)
|
||||||
|
"""
|
||||||
|
all_configs, all_defconfigs, config_db, defconfig_db = read_database()
|
||||||
|
|
||||||
|
# Get the whitelist
|
||||||
|
with open('scripts/config_whitelist.txt') as inf:
|
||||||
|
adhoc_configs = set(inf.read().splitlines())
|
||||||
|
|
||||||
|
# Start with all defconfigs
|
||||||
|
out = all_defconfigs
|
||||||
|
|
||||||
|
# Work through each config in turn
|
||||||
|
adhoc = []
|
||||||
|
for item in config_list:
|
||||||
|
# Get the real config name and whether we want this config or not
|
||||||
|
cfg = item
|
||||||
|
want = True
|
||||||
|
if cfg[0] == '~':
|
||||||
|
want = False
|
||||||
|
cfg = cfg[1:]
|
||||||
|
|
||||||
|
if cfg in adhoc_configs:
|
||||||
|
adhoc.append(cfg)
|
||||||
|
continue
|
||||||
|
|
||||||
|
# Search everything that is still in the running. If it has a config
|
||||||
|
# that we want, or doesn't have one that we don't, add it into the
|
||||||
|
# running for the next stage
|
||||||
|
in_list = out
|
||||||
|
out = set()
|
||||||
|
for defc in in_list:
|
||||||
|
has_cfg = cfg in config_db[defc]
|
||||||
|
if has_cfg == want:
|
||||||
|
out.add(defc)
|
||||||
|
if adhoc:
|
||||||
|
print(f"Error: Not in Kconfig: %s" % ' '.join(adhoc))
|
||||||
|
else:
|
||||||
|
print(f'{len(out)} matches')
|
||||||
|
print(' '.join(out))
|
||||||
|
|
||||||
|
|
||||||
|
def prefix_config(cfg):
|
||||||
|
"""Prefix a config with CONFIG_ if needed
|
||||||
|
|
||||||
|
This handles ~ operator, which indicates that the CONFIG should be disabled
|
||||||
|
|
||||||
|
>>> prefix_config('FRED')
|
||||||
|
'CONFIG_FRED'
|
||||||
|
>>> prefix_config('CONFIG_FRED')
|
||||||
|
'CONFIG_FRED'
|
||||||
|
>>> prefix_config('~FRED')
|
||||||
|
'~CONFIG_FRED'
|
||||||
|
>>> prefix_config('~CONFIG_FRED')
|
||||||
|
'~CONFIG_FRED'
|
||||||
|
>>> prefix_config('A123')
|
||||||
|
'CONFIG_A123'
|
||||||
|
"""
|
||||||
|
op = ''
|
||||||
|
if cfg[0] == '~':
|
||||||
|
op = cfg[0]
|
||||||
|
cfg = cfg[1:]
|
||||||
|
if not cfg.startswith('CONFIG_'):
|
||||||
|
cfg = 'CONFIG_' + cfg
|
||||||
|
return op + cfg
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
try:
|
try:
|
||||||
cpu_count = multiprocessing.cpu_count()
|
cpu_count = multiprocessing.cpu_count()
|
||||||
@@ -1596,6 +1669,8 @@ def main():
|
|||||||
parser.add_option('-e', '--exit-on-error', action='store_true',
|
parser.add_option('-e', '--exit-on-error', action='store_true',
|
||||||
default=False,
|
default=False,
|
||||||
help='exit immediately on any error')
|
help='exit immediately on any error')
|
||||||
|
parser.add_option('-f', '--find', action='store_true', default=False,
|
||||||
|
help='Find boards with a given config combination')
|
||||||
parser.add_option('-H', '--headers-only', dest='cleanup_headers_only',
|
parser.add_option('-H', '--headers-only', dest='cleanup_headers_only',
|
||||||
action='store_true', default=False,
|
action='store_true', default=False,
|
||||||
help='only cleanup the headers')
|
help='only cleanup the headers')
|
||||||
@@ -1631,13 +1706,12 @@ def main():
|
|||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
||||||
if len(configs) == 0 and not any((options.force_sync, options.build_db,
|
if len(configs) == 0 and not any((options.force_sync, options.build_db,
|
||||||
options.imply)):
|
options.imply, options.find)):
|
||||||
parser.print_usage()
|
parser.print_usage()
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
# prefix the option name with CONFIG_ if missing
|
# prefix the option name with CONFIG_ if missing
|
||||||
configs = [ config if config.startswith('CONFIG_') else 'CONFIG_' + config
|
configs = [prefix_config(cfg) for cfg in configs]
|
||||||
for config in configs ]
|
|
||||||
|
|
||||||
check_top_directory()
|
check_top_directory()
|
||||||
|
|
||||||
@@ -1663,6 +1737,10 @@ def main():
|
|||||||
options.skip_added)
|
options.skip_added)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
if options.find:
|
||||||
|
do_find_config(configs)
|
||||||
|
return
|
||||||
|
|
||||||
config_db = {}
|
config_db = {}
|
||||||
db_queue = queue.Queue()
|
db_queue = queue.Queue()
|
||||||
t = DatabaseThread(config_db, db_queue)
|
t = DatabaseThread(config_db, db_queue)
|
||||||
@@ -1705,4 +1783,4 @@ def main():
|
|||||||
fd.write('\n')
|
fd.write('\n')
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
main()
|
sys.exit(main())
|
||||||
|
Reference in New Issue
Block a user