forked from Mirrors/opensbi
scripts: Add Kconfiglib v14.1.0 under scripts directory
We adopt Kconfiglib v14.1.0 sources under scripts directory so that top-level OpenSBI makefile can directly use Kconfiglib scripts without expecting users to install a particular version of Kconfiglib on their build system. Signed-off-by: Anup Patel <apatel@ventanamicro.com> Tested-by: Andrew Jones <ajones@ventanamicro.com> Acked-by: Atish Patra <atishp@rivosinc.com> Tested-by: Atish Patra <atishp@rivosinc.com>
This commit is contained in:
5
scripts/Kconfiglib/LICENSE.txt
Normal file
5
scripts/Kconfiglib/LICENSE.txt
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
Copyright (c) 2011-2019, Ulf Magnusson <ulfalizer@gmail.com>
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
45
scripts/Kconfiglib/allnoconfig.py
Executable file
45
scripts/Kconfiglib/allnoconfig.py
Executable file
@@ -0,0 +1,45 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
# Copyright (c) 2018-2019, Ulf Magnusson
|
||||||
|
# SPDX-License-Identifier: ISC
|
||||||
|
|
||||||
|
"""
|
||||||
|
Writes a configuration file where as many symbols as possible are set to 'n'.
|
||||||
|
|
||||||
|
The default output filename is '.config'. A different filename can be passed
|
||||||
|
in the KCONFIG_CONFIG environment variable.
|
||||||
|
|
||||||
|
Usage for the Linux kernel:
|
||||||
|
|
||||||
|
$ make [ARCH=<arch>] scriptconfig SCRIPT=Kconfiglib/allnoconfig.py
|
||||||
|
"""
|
||||||
|
|
||||||
|
# See examples/allnoconfig_walk.py for another way to implement this script
|
||||||
|
|
||||||
|
import kconfiglib
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
kconf = kconfiglib.standard_kconfig(__doc__)
|
||||||
|
|
||||||
|
# Avoid warnings that would otherwise get printed by Kconfiglib for the
|
||||||
|
# following:
|
||||||
|
#
|
||||||
|
# 1. Assigning a value to a symbol without a prompt, which never has any
|
||||||
|
# effect
|
||||||
|
#
|
||||||
|
# 2. Assigning values invalid for the type (only bool/tristate symbols
|
||||||
|
# accept 0/1/2, for n/m/y). The assignments will be ignored for other
|
||||||
|
# symbol types, which is what we want.
|
||||||
|
kconf.warn = False
|
||||||
|
for sym in kconf.unique_defined_syms:
|
||||||
|
sym.set_value(2 if sym.is_allnoconfig_y else 0)
|
||||||
|
kconf.warn = True
|
||||||
|
|
||||||
|
kconf.load_allconfig("allno.config")
|
||||||
|
|
||||||
|
print(kconf.write_config())
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
56
scripts/Kconfiglib/allyesconfig.py
Executable file
56
scripts/Kconfiglib/allyesconfig.py
Executable file
@@ -0,0 +1,56 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
# Copyright (c) 2018-2019, Ulf Magnusson
|
||||||
|
# SPDX-License-Identifier: ISC
|
||||||
|
|
||||||
|
"""
|
||||||
|
Writes a configuration file where as many symbols as possible are set to 'y'.
|
||||||
|
|
||||||
|
The default output filename is '.config'. A different filename can be passed
|
||||||
|
in the KCONFIG_CONFIG environment variable.
|
||||||
|
|
||||||
|
Usage for the Linux kernel:
|
||||||
|
|
||||||
|
$ make [ARCH=<arch>] scriptconfig SCRIPT=Kconfiglib/allyesconfig.py
|
||||||
|
"""
|
||||||
|
import kconfiglib
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
kconf = kconfiglib.standard_kconfig(__doc__)
|
||||||
|
|
||||||
|
# See allnoconfig.py
|
||||||
|
kconf.warn = False
|
||||||
|
|
||||||
|
# Try to set all symbols to 'y'. Dependencies might truncate the value down
|
||||||
|
# later, but this will at least give the highest possible value.
|
||||||
|
#
|
||||||
|
# Assigning 0/1/2 to non-bool/tristate symbols has no effect (int/hex
|
||||||
|
# symbols still take a string, because they preserve formatting).
|
||||||
|
for sym in kconf.unique_defined_syms:
|
||||||
|
# Set choice symbols to 'm'. This value will be ignored for choices in
|
||||||
|
# 'y' mode (the "normal" mode), which will instead just get their
|
||||||
|
# default selection, but will set all symbols in m-mode choices to 'm',
|
||||||
|
# which is as high as they can go.
|
||||||
|
#
|
||||||
|
# Here's a convoluted example of how you might get an m-mode choice
|
||||||
|
# even during allyesconfig:
|
||||||
|
#
|
||||||
|
# choice
|
||||||
|
# tristate "weird choice"
|
||||||
|
# depends on m
|
||||||
|
sym.set_value(1 if sym.choice else 2)
|
||||||
|
|
||||||
|
# Set all choices to the highest possible mode
|
||||||
|
for choice in kconf.unique_choices:
|
||||||
|
choice.set_value(2)
|
||||||
|
|
||||||
|
kconf.warn = True
|
||||||
|
|
||||||
|
kconf.load_allconfig("allyes.config")
|
||||||
|
|
||||||
|
print(kconf.write_config())
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
43
scripts/Kconfiglib/defconfig.py
Executable file
43
scripts/Kconfiglib/defconfig.py
Executable file
@@ -0,0 +1,43 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
# Copyright (c) 2019, Ulf Magnusson
|
||||||
|
# SPDX-License-Identifier: ISC
|
||||||
|
|
||||||
|
"""
|
||||||
|
Reads a specified configuration file, then writes a new configuration file.
|
||||||
|
This can be used to initialize the configuration from e.g. an arch-specific
|
||||||
|
configuration file. This input configuration file would usually be a minimal
|
||||||
|
configuration file, as generated by e.g. savedefconfig.
|
||||||
|
|
||||||
|
The default output filename is '.config'. A different filename can be passed in
|
||||||
|
the KCONFIG_CONFIG environment variable.
|
||||||
|
"""
|
||||||
|
import argparse
|
||||||
|
|
||||||
|
import kconfiglib
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
parser = argparse.ArgumentParser(
|
||||||
|
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||||
|
description=__doc__)
|
||||||
|
|
||||||
|
parser.add_argument(
|
||||||
|
"--kconfig",
|
||||||
|
default="Kconfig",
|
||||||
|
help="Top-level Kconfig file (default: Kconfig)")
|
||||||
|
|
||||||
|
parser.add_argument(
|
||||||
|
"config",
|
||||||
|
metavar="CONFIGURATION",
|
||||||
|
help="Input configuration file")
|
||||||
|
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
kconf = kconfiglib.Kconfig(args.kconfig, suppress_traceback=True)
|
||||||
|
print(kconf.load_config(args.config))
|
||||||
|
print(kconf.write_config())
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
154
scripts/Kconfiglib/genconfig.py
Executable file
154
scripts/Kconfiglib/genconfig.py
Executable file
@@ -0,0 +1,154 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
# Copyright (c) 2018-2019, Ulf Magnusson
|
||||||
|
# SPDX-License-Identifier: ISC
|
||||||
|
|
||||||
|
"""
|
||||||
|
Generates a header file with #defines from the configuration, matching the
|
||||||
|
format of include/generated/autoconf.h in the Linux kernel.
|
||||||
|
|
||||||
|
Optionally, also writes the configuration output as a .config file. See
|
||||||
|
--config-out.
|
||||||
|
|
||||||
|
The --sync-deps, --file-list, and --env-list options generate information that
|
||||||
|
can be used to avoid needless rebuilds/reconfigurations.
|
||||||
|
|
||||||
|
Before writing a header or configuration file, Kconfiglib compares the old
|
||||||
|
contents of the file against the new contents. If there's no change, the write
|
||||||
|
is skipped. This avoids updating file metadata like the modification time, and
|
||||||
|
might save work depending on your build setup.
|
||||||
|
|
||||||
|
By default, the configuration is generated from '.config'. A different
|
||||||
|
configuration file can be passed in the KCONFIG_CONFIG environment variable.
|
||||||
|
|
||||||
|
A custom header string can be inserted at the beginning of generated
|
||||||
|
configuration and header files by setting the KCONFIG_CONFIG_HEADER and
|
||||||
|
KCONFIG_AUTOHEADER_HEADER environment variables, respectively (this also works
|
||||||
|
for other scripts). The string is not automatically made a comment (this is by
|
||||||
|
design, to allow anything to be added), and no trailing newline is added, so
|
||||||
|
add '/* */', '#', and newlines as appropriate.
|
||||||
|
|
||||||
|
See https://www.gnu.org/software/make/manual/make.html#Multi_002dLine for a
|
||||||
|
handy way to define multi-line variables in makefiles, for use with custom
|
||||||
|
headers. Remember to export the variable to the environment.
|
||||||
|
"""
|
||||||
|
import argparse
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
|
import kconfiglib
|
||||||
|
|
||||||
|
|
||||||
|
DEFAULT_SYNC_DEPS_PATH = "deps/"
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
parser = argparse.ArgumentParser(
|
||||||
|
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||||
|
description=__doc__)
|
||||||
|
|
||||||
|
parser.add_argument(
|
||||||
|
"--header-path",
|
||||||
|
metavar="HEADER_FILE",
|
||||||
|
help="""
|
||||||
|
Path to write the generated header file to. If not specified, the path in the
|
||||||
|
environment variable KCONFIG_AUTOHEADER is used if it is set, and 'config.h'
|
||||||
|
otherwise.
|
||||||
|
""")
|
||||||
|
|
||||||
|
parser.add_argument(
|
||||||
|
"--config-out",
|
||||||
|
metavar="CONFIG_FILE",
|
||||||
|
help="""
|
||||||
|
Write the configuration to CONFIG_FILE. This is useful if you include .config
|
||||||
|
files in Makefiles, as the generated configuration file will be a full .config
|
||||||
|
file even if .config is outdated. The generated configuration matches what
|
||||||
|
olddefconfig would produce. If you use sync-deps, you can include
|
||||||
|
deps/auto.conf instead. --config-out is meant for cases where incremental build
|
||||||
|
information isn't needed.
|
||||||
|
""")
|
||||||
|
|
||||||
|
parser.add_argument(
|
||||||
|
"--sync-deps",
|
||||||
|
metavar="OUTPUT_DIR",
|
||||||
|
nargs="?",
|
||||||
|
const=DEFAULT_SYNC_DEPS_PATH,
|
||||||
|
help="""
|
||||||
|
Enable generation of symbol dependency information for incremental builds,
|
||||||
|
optionally specifying the output directory (default: {}). See the docstring of
|
||||||
|
Kconfig.sync_deps() in Kconfiglib for more information.
|
||||||
|
""".format(DEFAULT_SYNC_DEPS_PATH))
|
||||||
|
|
||||||
|
parser.add_argument(
|
||||||
|
"--file-list",
|
||||||
|
metavar="OUTPUT_FILE",
|
||||||
|
help="""
|
||||||
|
Write a list of all Kconfig files to OUTPUT_FILE, with one file per line. The
|
||||||
|
paths are relative to $srctree (or to the current directory if $srctree is
|
||||||
|
unset). Files appear in the order they're 'source'd.
|
||||||
|
""")
|
||||||
|
|
||||||
|
parser.add_argument(
|
||||||
|
"--env-list",
|
||||||
|
metavar="OUTPUT_FILE",
|
||||||
|
help="""
|
||||||
|
Write a list of all environment variables referenced in Kconfig files to
|
||||||
|
OUTPUT_FILE, with one variable per line. Each line has the format NAME=VALUE.
|
||||||
|
Only environment variables referenced with the preprocessor $(VAR) syntax are
|
||||||
|
included, and not variables referenced with the older $VAR syntax (which is
|
||||||
|
only supported for backwards compatibility).
|
||||||
|
""")
|
||||||
|
|
||||||
|
parser.add_argument(
|
||||||
|
"kconfig",
|
||||||
|
metavar="KCONFIG",
|
||||||
|
nargs="?",
|
||||||
|
default="Kconfig",
|
||||||
|
help="Top-level Kconfig file (default: Kconfig)")
|
||||||
|
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
|
||||||
|
kconf = kconfiglib.Kconfig(args.kconfig, suppress_traceback=True)
|
||||||
|
kconf.load_config()
|
||||||
|
|
||||||
|
if args.header_path is None:
|
||||||
|
if "KCONFIG_AUTOHEADER" in os.environ:
|
||||||
|
kconf.write_autoconf()
|
||||||
|
else:
|
||||||
|
# Kconfiglib defaults to include/generated/autoconf.h to be
|
||||||
|
# compatible with the C tools. 'config.h' is used here instead for
|
||||||
|
# backwards compatibility. It's probably a saner default for tools
|
||||||
|
# as well.
|
||||||
|
kconf.write_autoconf("config.h")
|
||||||
|
else:
|
||||||
|
kconf.write_autoconf(args.header_path)
|
||||||
|
|
||||||
|
if args.config_out is not None:
|
||||||
|
kconf.write_config(args.config_out, save_old=False)
|
||||||
|
|
||||||
|
if args.sync_deps is not None:
|
||||||
|
kconf.sync_deps(args.sync_deps)
|
||||||
|
|
||||||
|
if args.file_list is not None:
|
||||||
|
with _open_write(args.file_list) as f:
|
||||||
|
for path in kconf.kconfig_filenames:
|
||||||
|
f.write(path + "\n")
|
||||||
|
|
||||||
|
if args.env_list is not None:
|
||||||
|
with _open_write(args.env_list) as f:
|
||||||
|
for env_var in kconf.env_vars:
|
||||||
|
f.write("{}={}\n".format(env_var, os.environ[env_var]))
|
||||||
|
|
||||||
|
|
||||||
|
def _open_write(path):
|
||||||
|
# Python 2/3 compatibility. io.open() is available on both, but makes
|
||||||
|
# write() expect 'unicode' strings on Python 2.
|
||||||
|
|
||||||
|
if sys.version_info[0] < 3:
|
||||||
|
return open(path, "w")
|
||||||
|
return open(path, "w", encoding="utf-8")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
7160
scripts/Kconfiglib/kconfiglib.py
Normal file
7160
scripts/Kconfiglib/kconfiglib.py
Normal file
File diff suppressed because it is too large
Load Diff
3278
scripts/Kconfiglib/menuconfig.py
Executable file
3278
scripts/Kconfiglib/menuconfig.py
Executable file
File diff suppressed because it is too large
Load Diff
246
scripts/Kconfiglib/oldconfig.py
Executable file
246
scripts/Kconfiglib/oldconfig.py
Executable file
@@ -0,0 +1,246 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
# Copyright (c) 2018-2019, Ulf Magnusson
|
||||||
|
# SPDX-License-Identifier: ISC
|
||||||
|
|
||||||
|
"""
|
||||||
|
Implements oldconfig functionality.
|
||||||
|
|
||||||
|
1. Loads existing .config
|
||||||
|
2. Prompts for the value of all modifiable symbols/choices that
|
||||||
|
aren't already set in the .config
|
||||||
|
3. Writes an updated .config
|
||||||
|
|
||||||
|
The default input/output filename is '.config'. A different filename can be
|
||||||
|
passed in the KCONFIG_CONFIG environment variable.
|
||||||
|
|
||||||
|
When overwriting a configuration file, the old version is saved to
|
||||||
|
<filename>.old (e.g. .config.old).
|
||||||
|
|
||||||
|
Entering '?' displays the help text of the symbol/choice, if any.
|
||||||
|
|
||||||
|
Unlike 'make oldconfig', this script doesn't print menu titles and comments,
|
||||||
|
but gives Kconfig definition locations. Printing menus and comments would be
|
||||||
|
pretty easy to add: Look at the parents of each item, and print all menu
|
||||||
|
prompts and comments unless they have already been printed (assuming you want
|
||||||
|
to skip "irrelevant" menus).
|
||||||
|
"""
|
||||||
|
from __future__ import print_function
|
||||||
|
|
||||||
|
import sys
|
||||||
|
|
||||||
|
from kconfiglib import Symbol, Choice, BOOL, TRISTATE, HEX, standard_kconfig
|
||||||
|
|
||||||
|
|
||||||
|
# Python 2/3 compatibility hack
|
||||||
|
if sys.version_info[0] < 3:
|
||||||
|
input = raw_input
|
||||||
|
|
||||||
|
|
||||||
|
def _main():
|
||||||
|
# Earlier symbols in Kconfig files might depend on later symbols and become
|
||||||
|
# visible if their values change. This flag is set to True if the value of
|
||||||
|
# any symbol changes, in which case we rerun the oldconfig to check for new
|
||||||
|
# visible symbols.
|
||||||
|
global conf_changed
|
||||||
|
|
||||||
|
kconf = standard_kconfig(__doc__)
|
||||||
|
print(kconf.load_config())
|
||||||
|
|
||||||
|
while True:
|
||||||
|
conf_changed = False
|
||||||
|
|
||||||
|
for node in kconf.node_iter():
|
||||||
|
oldconfig(node)
|
||||||
|
|
||||||
|
if not conf_changed:
|
||||||
|
break
|
||||||
|
|
||||||
|
print(kconf.write_config())
|
||||||
|
|
||||||
|
|
||||||
|
def oldconfig(node):
|
||||||
|
"""
|
||||||
|
Prompts the user for a value if node.item is a visible symbol/choice with
|
||||||
|
no user value.
|
||||||
|
"""
|
||||||
|
# See main()
|
||||||
|
global conf_changed
|
||||||
|
|
||||||
|
# Only symbols and choices can be configured
|
||||||
|
if not isinstance(node.item, (Symbol, Choice)):
|
||||||
|
return
|
||||||
|
|
||||||
|
# Skip symbols and choices that aren't visible
|
||||||
|
if not node.item.visibility:
|
||||||
|
return
|
||||||
|
|
||||||
|
# Skip symbols and choices that don't have a prompt (at this location)
|
||||||
|
if not node.prompt:
|
||||||
|
return
|
||||||
|
|
||||||
|
if isinstance(node.item, Symbol):
|
||||||
|
sym = node.item
|
||||||
|
|
||||||
|
# Skip symbols that already have a user value
|
||||||
|
if sym.user_value is not None:
|
||||||
|
return
|
||||||
|
|
||||||
|
# Skip symbols that can only have a single value, due to selects
|
||||||
|
if len(sym.assignable) == 1:
|
||||||
|
return
|
||||||
|
|
||||||
|
# Skip symbols in choices in y mode. We ask once for the entire choice
|
||||||
|
# instead.
|
||||||
|
if sym.choice and sym.choice.tri_value == 2:
|
||||||
|
return
|
||||||
|
|
||||||
|
# Loop until the user enters a valid value or enters a blank string
|
||||||
|
# (for the default value)
|
||||||
|
while True:
|
||||||
|
val = input("{} ({}) [{}] ".format(
|
||||||
|
node.prompt[0], _name_and_loc_str(sym),
|
||||||
|
_default_value_str(sym)))
|
||||||
|
|
||||||
|
if val == "?":
|
||||||
|
_print_help(node)
|
||||||
|
continue
|
||||||
|
|
||||||
|
# Substitute a blank string with the default value the symbol
|
||||||
|
# would get
|
||||||
|
if not val:
|
||||||
|
val = sym.str_value
|
||||||
|
|
||||||
|
# Automatically add a "0x" prefix for hex symbols, like the
|
||||||
|
# menuconfig interface does. This isn't done when loading .config
|
||||||
|
# files, hence why set_value() doesn't do it automatically.
|
||||||
|
if sym.type == HEX and not val.startswith(("0x", "0X")):
|
||||||
|
val = "0x" + val
|
||||||
|
|
||||||
|
old_str_val = sym.str_value
|
||||||
|
|
||||||
|
# Kconfiglib itself will print a warning here if the value
|
||||||
|
# is invalid, so we don't need to bother
|
||||||
|
if sym.set_value(val):
|
||||||
|
# Valid value input. We're done with this node.
|
||||||
|
|
||||||
|
if sym.str_value != old_str_val:
|
||||||
|
conf_changed = True
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
else:
|
||||||
|
choice = node.item
|
||||||
|
|
||||||
|
# Skip choices that already have a visible user selection...
|
||||||
|
if choice.user_selection and choice.user_selection.visibility == 2:
|
||||||
|
# ...unless there are new visible symbols in the choice. (We know
|
||||||
|
# they have y (2) visibility in that case, because m-visible
|
||||||
|
# symbols get demoted to n-visibility in y-mode choices, and the
|
||||||
|
# user-selected symbol had visibility y.)
|
||||||
|
for sym in choice.syms:
|
||||||
|
if sym is not choice.user_selection and sym.visibility and \
|
||||||
|
sym.user_value is None:
|
||||||
|
# New visible symbols in the choice
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
# No new visible symbols in the choice
|
||||||
|
return
|
||||||
|
|
||||||
|
# Get a list of available selections. The mode of the choice limits
|
||||||
|
# the visibility of the choice value symbols, so this will indirectly
|
||||||
|
# skip choices in n and m mode.
|
||||||
|
options = [sym for sym in choice.syms if sym.visibility == 2]
|
||||||
|
|
||||||
|
if not options:
|
||||||
|
# No y-visible choice value symbols
|
||||||
|
return
|
||||||
|
|
||||||
|
# Loop until the user enters a valid selection or a blank string (for
|
||||||
|
# the default selection)
|
||||||
|
while True:
|
||||||
|
print("{} ({})".format(node.prompt[0], _name_and_loc_str(choice)))
|
||||||
|
|
||||||
|
for i, sym in enumerate(options, 1):
|
||||||
|
print("{} {}. {} ({})".format(
|
||||||
|
">" if sym is choice.selection else " ",
|
||||||
|
i,
|
||||||
|
# Assume people don't define choice symbols with multiple
|
||||||
|
# prompts. That generates a warning anyway.
|
||||||
|
sym.nodes[0].prompt[0],
|
||||||
|
sym.name))
|
||||||
|
|
||||||
|
sel_index = input("choice[1-{}]: ".format(len(options)))
|
||||||
|
|
||||||
|
if sel_index == "?":
|
||||||
|
_print_help(node)
|
||||||
|
continue
|
||||||
|
|
||||||
|
# Pick the default selection if the string is blank
|
||||||
|
if not sel_index:
|
||||||
|
choice.selection.set_value(2)
|
||||||
|
break
|
||||||
|
|
||||||
|
try:
|
||||||
|
sel_index = int(sel_index)
|
||||||
|
except ValueError:
|
||||||
|
print("Bad index", file=sys.stderr)
|
||||||
|
continue
|
||||||
|
|
||||||
|
if not 1 <= sel_index <= len(options):
|
||||||
|
print("Bad index", file=sys.stderr)
|
||||||
|
continue
|
||||||
|
|
||||||
|
# Valid selection
|
||||||
|
|
||||||
|
if options[sel_index - 1].tri_value != 2:
|
||||||
|
conf_changed = True
|
||||||
|
|
||||||
|
options[sel_index - 1].set_value(2)
|
||||||
|
break
|
||||||
|
|
||||||
|
# Give all of the non-selected visible choice symbols the user value n.
|
||||||
|
# This makes it so that the choice is no longer considered new once we
|
||||||
|
# do additional passes, if the reason that it was considered new was
|
||||||
|
# that it had new visible choice symbols.
|
||||||
|
#
|
||||||
|
# Only giving visible choice symbols the user value n means we will
|
||||||
|
# prompt for the choice again if later user selections make more new
|
||||||
|
# choice symbols visible, which is correct.
|
||||||
|
for sym in choice.syms:
|
||||||
|
if sym is not choice.user_selection and sym.visibility:
|
||||||
|
sym.set_value(0)
|
||||||
|
|
||||||
|
|
||||||
|
def _name_and_loc_str(sc):
|
||||||
|
# Helper for printing the name of the symbol/choice 'sc' along with the
|
||||||
|
# location(s) in the Kconfig files where it is defined. Unnamed choices
|
||||||
|
# return "choice" instead of the name.
|
||||||
|
|
||||||
|
return "{}, defined at {}".format(
|
||||||
|
sc.name or "choice",
|
||||||
|
", ".join("{}:{}".format(node.filename, node.linenr)
|
||||||
|
for node in sc.nodes))
|
||||||
|
|
||||||
|
|
||||||
|
def _print_help(node):
|
||||||
|
print("\n" + (node.help or "No help text\n"))
|
||||||
|
|
||||||
|
|
||||||
|
def _default_value_str(sym):
|
||||||
|
# Returns the "m/M/y" string in e.g.
|
||||||
|
#
|
||||||
|
# TRISTATE_SYM prompt (TRISTATE_SYM, defined at Kconfig:9) [n/M/y]:
|
||||||
|
#
|
||||||
|
# For string/int/hex, returns the default value as-is.
|
||||||
|
|
||||||
|
if sym.type in (BOOL, TRISTATE):
|
||||||
|
return "/".join(("NMY" if sym.tri_value == tri else "nmy")[tri]
|
||||||
|
for tri in sym.assignable)
|
||||||
|
|
||||||
|
# string/int/hex
|
||||||
|
return sym.str_value
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
_main()
|
28
scripts/Kconfiglib/olddefconfig.py
Executable file
28
scripts/Kconfiglib/olddefconfig.py
Executable file
@@ -0,0 +1,28 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
# Copyright (c) 2018-2019, Ulf Magnusson
|
||||||
|
# SPDX-License-Identifier: ISC
|
||||||
|
|
||||||
|
"""
|
||||||
|
Updates an old .config file or creates a new one, by filling in default values
|
||||||
|
for all new symbols. This is the same as picking the default selection for all
|
||||||
|
symbols in oldconfig, or entering the menuconfig interface and immediately
|
||||||
|
saving.
|
||||||
|
|
||||||
|
The default input/output filename is '.config'. A different filename can be
|
||||||
|
passed in the KCONFIG_CONFIG environment variable.
|
||||||
|
|
||||||
|
When overwriting a configuration file, the old version is saved to
|
||||||
|
<filename>.old (e.g. .config.old).
|
||||||
|
"""
|
||||||
|
import kconfiglib
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
kconf = kconfiglib.standard_kconfig(__doc__)
|
||||||
|
print(kconf.load_config())
|
||||||
|
print(kconf.write_config())
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
49
scripts/Kconfiglib/savedefconfig.py
Executable file
49
scripts/Kconfiglib/savedefconfig.py
Executable file
@@ -0,0 +1,49 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
# Copyright (c) 2019, Ulf Magnusson
|
||||||
|
# SPDX-License-Identifier: ISC
|
||||||
|
|
||||||
|
"""
|
||||||
|
Saves a minimal configuration file that only lists symbols that differ in value
|
||||||
|
from their defaults. Loading such a configuration file is equivalent to loading
|
||||||
|
the "full" configuration file.
|
||||||
|
|
||||||
|
Minimal configuration files are handy to start from when editing configuration
|
||||||
|
files by hand.
|
||||||
|
|
||||||
|
The default input configuration file is '.config'. A different input filename
|
||||||
|
can be passed in the KCONFIG_CONFIG environment variable.
|
||||||
|
|
||||||
|
Note: Minimal configurations can also be generated from within the menuconfig
|
||||||
|
interface.
|
||||||
|
"""
|
||||||
|
import argparse
|
||||||
|
|
||||||
|
import kconfiglib
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
parser = argparse.ArgumentParser(
|
||||||
|
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||||
|
description=__doc__)
|
||||||
|
|
||||||
|
parser.add_argument(
|
||||||
|
"--kconfig",
|
||||||
|
default="Kconfig",
|
||||||
|
help="Top-level Kconfig file (default: Kconfig)")
|
||||||
|
|
||||||
|
parser.add_argument(
|
||||||
|
"--out",
|
||||||
|
metavar="MINIMAL_CONFIGURATION",
|
||||||
|
default="defconfig",
|
||||||
|
help="Output filename for minimal configuration (default: defconfig)")
|
||||||
|
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
kconf = kconfiglib.Kconfig(args.kconfig, suppress_traceback=True)
|
||||||
|
print(kconf.load_config())
|
||||||
|
print(kconf.write_min_config(args.out))
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
92
scripts/Kconfiglib/setconfig.py
Executable file
92
scripts/Kconfiglib/setconfig.py
Executable file
@@ -0,0 +1,92 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
# Copyright (c) 2019, Ulf Magnusson
|
||||||
|
# SPDX-License-Identifier: ISC
|
||||||
|
|
||||||
|
"""
|
||||||
|
Simple utility for setting configuration values from the command line.
|
||||||
|
|
||||||
|
Sample usage:
|
||||||
|
|
||||||
|
$ setconfig FOO_SUPPORT=y BAR_BITS=8
|
||||||
|
|
||||||
|
Note: Symbol names should not be prefixed with 'CONFIG_'.
|
||||||
|
|
||||||
|
The exit status on errors is 1.
|
||||||
|
|
||||||
|
The default input/output configuration file is '.config'. A different filename
|
||||||
|
can be passed in the KCONFIG_CONFIG environment variable.
|
||||||
|
|
||||||
|
When overwriting a configuration file, the old version is saved to
|
||||||
|
<filename>.old (e.g. .config.old).
|
||||||
|
"""
|
||||||
|
import argparse
|
||||||
|
import sys
|
||||||
|
|
||||||
|
import kconfiglib
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
parser = argparse.ArgumentParser(
|
||||||
|
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||||
|
description=__doc__)
|
||||||
|
|
||||||
|
parser.add_argument(
|
||||||
|
"--kconfig",
|
||||||
|
default="Kconfig",
|
||||||
|
help="Top-level Kconfig file (default: Kconfig)")
|
||||||
|
|
||||||
|
parser.add_argument(
|
||||||
|
"--no-check-exists",
|
||||||
|
dest="check_exists",
|
||||||
|
action="store_false",
|
||||||
|
help="Ignore assignments to non-existent symbols instead of erroring "
|
||||||
|
"out")
|
||||||
|
|
||||||
|
parser.add_argument(
|
||||||
|
"--no-check-value",
|
||||||
|
dest="check_value",
|
||||||
|
action="store_false",
|
||||||
|
help="Ignore assignments that didn't \"take\" (where the symbol got a "
|
||||||
|
"different value, e.g. due to unsatisfied dependencies) instead "
|
||||||
|
"of erroring out")
|
||||||
|
|
||||||
|
parser.add_argument(
|
||||||
|
"assignments",
|
||||||
|
metavar="ASSIGNMENT",
|
||||||
|
nargs="*",
|
||||||
|
help="A 'NAME=value' assignment")
|
||||||
|
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
kconf = kconfiglib.Kconfig(args.kconfig, suppress_traceback=True)
|
||||||
|
print(kconf.load_config())
|
||||||
|
|
||||||
|
for arg in args.assignments:
|
||||||
|
if "=" not in arg:
|
||||||
|
sys.exit("error: no '=' in assignment: '{}'".format(arg))
|
||||||
|
name, value = arg.split("=", 1)
|
||||||
|
|
||||||
|
if name not in kconf.syms:
|
||||||
|
if not args.check_exists:
|
||||||
|
continue
|
||||||
|
sys.exit("error: no symbol '{}' in configuration".format(name))
|
||||||
|
|
||||||
|
sym = kconf.syms[name]
|
||||||
|
|
||||||
|
if not sym.set_value(value):
|
||||||
|
sys.exit("error: '{}' is an invalid value for the {} symbol {}"
|
||||||
|
.format(value, kconfiglib.TYPE_TO_STR[sym.orig_type],
|
||||||
|
name))
|
||||||
|
|
||||||
|
if args.check_value and sym.str_value != value:
|
||||||
|
sys.exit("error: {} was assigned the value '{}', but got the "
|
||||||
|
"value '{}'. Check the symbol's dependencies, and make "
|
||||||
|
"sure that it has a prompt."
|
||||||
|
.format(name, value, sym.str_value))
|
||||||
|
|
||||||
|
print(kconf.write_config())
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
Reference in New Issue
Block a user