firmware-base/vendor/sming/Sming/Tools/cfgtool.py
2026-01-28 16:42:43 +01:00

111 lines
3.6 KiB
Python

#!/usr/bin/env python3
#
# Sming configuration management tool
#
# Used by build system to enable compatibility with Kconfig
#
#
import argparse, configparser, os, sys, platform, kconfiglib
def load_config_vars(filename):
parser = configparser.ConfigParser()
parser.optionxform = str # preserve case
with open(filename) as f:
data = "[config]\n" + f.read()
data = data.replace(' := ', ' = ')
parser.read_string(data)
return parser['config']
def set_kconfig_value(symbol, v):
"""Convert values from Sming format to Kconfig format.
Hidden variables are used to store choice selections and cannot be set directly.
Instead, locate the corresponding choice variable and set that.
"""
if symbol.visibility == 2:
if symbol.type is kconfiglib.BOOL:
v = 'y' if v == '1' else 'n'
elif symbol.type == kconfiglib._T_INT:
v = 0 if v == '' else v
symbol.set_value(v)
else:
for sym, cond in symbol.defaults:
if isinstance(cond, tuple):
cond = cond[1]
if not isinstance(cond, kconfiglib.Symbol):
continue
if v == sym.name and cond.type is kconfiglib.BOOL:
cond.set_value('y')
break
def fixpath(path):
"""Paths in Windows can get a little weird"""
if len(path) > 2 and path[1] != ':' and platform.system() == 'Windows' and path[2] == '/':
return path[1] + ':' + path[2:]
return path
def createComponentsFile():
fileList = os.environ['KCONFIG_FILES'].split()
compFile = os.environ['KCONFIG_COMPONENTS']
with open(compFile, "w") as f:
for s in fileList:
f.write('source "%s"\n' % fixpath(s))
def main():
parser = argparse.ArgumentParser(description='Sming configuration management tool')
parser.add_argument('--to-kconfig', help="Convert Sming configuration to Kconfig format", action='store_true')
parser.add_argument('--from-kconfig', help="Convert Kconfig configuration to Sming format", action='store_true')
parser.add_argument('config_file', help='Source configuration file')
args = parser.parse_args()
if args.to_kconfig:
createComponentsFile()
conf = kconfiglib.Kconfig(os.environ['KCONFIG'])
src = load_config_vars(args.config_file)
for k, v in src.items():
c = conf.syms.get(k)
if c:
set_kconfig_value(c, v)
conf.write_config(os.environ['KCONFIG_CONFIG'])
elif args.from_kconfig:
conf = kconfiglib.Kconfig(os.environ['KCONFIG'])
conf.load_config(os.environ['KCONFIG_CONFIG'])
dst = load_config_vars(args.config_file)
varnames = set(dst.pop('CACHED_VAR_NAMES').split())
for k, sym in conf.syms.items():
if sym.type is kconfiglib.UNKNOWN:
continue
if sym.env_var is not None:
continue
v = str(sym.user_value) if sym.user_value else ""
if sym.type is kconfiglib.BOOL:
v = "1" if v in ['y', '2'] else "0"
dst[sym.name] = v
varnames.add(sym.name)
with open(args.config_file, "w") as f:
for k, v in dst.items():
f.write("%s=%s\n" % (k, v))
f.write("\n")
varnames = list(varnames)
varnames.sort()
f.write("CACHED_VAR_NAMES := " + " ".join(varnames))
else:
raise RuntimeError("No command specified")
if __name__ == '__main__':
try:
main()
except Exception as e:
print("** ERROR! %s" % e, file=sys.stderr)
sys.exit(2)