1*c689edbbSJens Wiklander#!/usr/bin/env python3 2*c689edbbSJens Wiklander 3*c689edbbSJens Wiklander# Copyright (c) 2018-2019, Ulf Magnusson 4*c689edbbSJens Wiklander# SPDX-License-Identifier: ISC 5*c689edbbSJens Wiklander 6*c689edbbSJens Wiklander""" 7*c689edbbSJens WiklanderGenerates a header file with #defines from the configuration, matching the 8*c689edbbSJens Wiklanderformat of include/generated/autoconf.h in the Linux kernel. 9*c689edbbSJens Wiklander 10*c689edbbSJens WiklanderOptionally, also writes the configuration output as a .config file. See 11*c689edbbSJens Wiklander--config-out. 12*c689edbbSJens Wiklander 13*c689edbbSJens WiklanderThe --sync-deps, --file-list, and --env-list options generate information that 14*c689edbbSJens Wiklandercan be used to avoid needless rebuilds/reconfigurations. 15*c689edbbSJens Wiklander 16*c689edbbSJens WiklanderBefore writing a header or configuration file, Kconfiglib compares the old 17*c689edbbSJens Wiklandercontents of the file against the new contents. If there's no change, the write 18*c689edbbSJens Wiklanderis skipped. This avoids updating file metadata like the modification time, and 19*c689edbbSJens Wiklandermight save work depending on your build setup. 20*c689edbbSJens Wiklander 21*c689edbbSJens WiklanderBy default, the configuration is generated from '.config'. A different 22*c689edbbSJens Wiklanderconfiguration file can be passed in the KCONFIG_CONFIG environment variable. 23*c689edbbSJens Wiklander 24*c689edbbSJens WiklanderA custom header string can be inserted at the beginning of generated 25*c689edbbSJens Wiklanderconfiguration and header files by setting the KCONFIG_CONFIG_HEADER and 26*c689edbbSJens WiklanderKCONFIG_AUTOHEADER_HEADER environment variables, respectively (this also works 27*c689edbbSJens Wiklanderfor other scripts). The string is not automatically made a comment (this is by 28*c689edbbSJens Wiklanderdesign, to allow anything to be added), and no trailing newline is added, so 29*c689edbbSJens Wiklanderadd '/* */', '#', and newlines as appropriate. 30*c689edbbSJens Wiklander 31*c689edbbSJens WiklanderSee https://www.gnu.org/software/make/manual/make.html#Multi_002dLine for a 32*c689edbbSJens Wiklanderhandy way to define multi-line variables in makefiles, for use with custom 33*c689edbbSJens Wiklanderheaders. Remember to export the variable to the environment. 34*c689edbbSJens Wiklander""" 35*c689edbbSJens Wiklanderimport argparse 36*c689edbbSJens Wiklanderimport os 37*c689edbbSJens Wiklanderimport sys 38*c689edbbSJens Wiklander 39*c689edbbSJens Wiklanderimport kconfiglib 40*c689edbbSJens Wiklander 41*c689edbbSJens Wiklander 42*c689edbbSJens WiklanderDEFAULT_SYNC_DEPS_PATH = "deps/" 43*c689edbbSJens Wiklander 44*c689edbbSJens Wiklander 45*c689edbbSJens Wiklanderdef main(): 46*c689edbbSJens Wiklander parser = argparse.ArgumentParser( 47*c689edbbSJens Wiklander formatter_class=argparse.RawDescriptionHelpFormatter, 48*c689edbbSJens Wiklander description=__doc__) 49*c689edbbSJens Wiklander 50*c689edbbSJens Wiklander parser.add_argument( 51*c689edbbSJens Wiklander "--header-path", 52*c689edbbSJens Wiklander metavar="HEADER_FILE", 53*c689edbbSJens Wiklander help=""" 54*c689edbbSJens WiklanderPath to write the generated header file to. If not specified, the path in the 55*c689edbbSJens Wiklanderenvironment variable KCONFIG_AUTOHEADER is used if it is set, and 'config.h' 56*c689edbbSJens Wiklanderotherwise. 57*c689edbbSJens Wiklander""") 58*c689edbbSJens Wiklander 59*c689edbbSJens Wiklander parser.add_argument( 60*c689edbbSJens Wiklander "--config-out", 61*c689edbbSJens Wiklander metavar="CONFIG_FILE", 62*c689edbbSJens Wiklander help=""" 63*c689edbbSJens WiklanderWrite the configuration to CONFIG_FILE. This is useful if you include .config 64*c689edbbSJens Wiklanderfiles in Makefiles, as the generated configuration file will be a full .config 65*c689edbbSJens Wiklanderfile even if .config is outdated. The generated configuration matches what 66*c689edbbSJens Wiklanderolddefconfig would produce. If you use sync-deps, you can include 67*c689edbbSJens Wiklanderdeps/auto.conf instead. --config-out is meant for cases where incremental build 68*c689edbbSJens Wiklanderinformation isn't needed. 69*c689edbbSJens Wiklander""") 70*c689edbbSJens Wiklander 71*c689edbbSJens Wiklander parser.add_argument( 72*c689edbbSJens Wiklander "--sync-deps", 73*c689edbbSJens Wiklander metavar="OUTPUT_DIR", 74*c689edbbSJens Wiklander nargs="?", 75*c689edbbSJens Wiklander const=DEFAULT_SYNC_DEPS_PATH, 76*c689edbbSJens Wiklander help=""" 77*c689edbbSJens WiklanderEnable generation of symbol dependency information for incremental builds, 78*c689edbbSJens Wiklanderoptionally specifying the output directory (default: {}). See the docstring of 79*c689edbbSJens WiklanderKconfig.sync_deps() in Kconfiglib for more information. 80*c689edbbSJens Wiklander""".format(DEFAULT_SYNC_DEPS_PATH)) 81*c689edbbSJens Wiklander 82*c689edbbSJens Wiklander parser.add_argument( 83*c689edbbSJens Wiklander "--file-list", 84*c689edbbSJens Wiklander metavar="OUTPUT_FILE", 85*c689edbbSJens Wiklander help=""" 86*c689edbbSJens WiklanderWrite a list of all Kconfig files to OUTPUT_FILE, with one file per line. The 87*c689edbbSJens Wiklanderpaths are relative to $srctree (or to the current directory if $srctree is 88*c689edbbSJens Wiklanderunset). Files appear in the order they're 'source'd. 89*c689edbbSJens Wiklander""") 90*c689edbbSJens Wiklander 91*c689edbbSJens Wiklander parser.add_argument( 92*c689edbbSJens Wiklander "--env-list", 93*c689edbbSJens Wiklander metavar="OUTPUT_FILE", 94*c689edbbSJens Wiklander help=""" 95*c689edbbSJens WiklanderWrite a list of all environment variables referenced in Kconfig files to 96*c689edbbSJens WiklanderOUTPUT_FILE, with one variable per line. Each line has the format NAME=VALUE. 97*c689edbbSJens WiklanderOnly environment variables referenced with the preprocessor $(VAR) syntax are 98*c689edbbSJens Wiklanderincluded, and not variables referenced with the older $VAR syntax (which is 99*c689edbbSJens Wiklanderonly supported for backwards compatibility). 100*c689edbbSJens Wiklander""") 101*c689edbbSJens Wiklander 102*c689edbbSJens Wiklander parser.add_argument( 103*c689edbbSJens Wiklander "kconfig", 104*c689edbbSJens Wiklander metavar="KCONFIG", 105*c689edbbSJens Wiklander nargs="?", 106*c689edbbSJens Wiklander default="Kconfig", 107*c689edbbSJens Wiklander help="Top-level Kconfig file (default: Kconfig)") 108*c689edbbSJens Wiklander 109*c689edbbSJens Wiklander args = parser.parse_args() 110*c689edbbSJens Wiklander 111*c689edbbSJens Wiklander 112*c689edbbSJens Wiklander kconf = kconfiglib.Kconfig(args.kconfig, suppress_traceback=True) 113*c689edbbSJens Wiklander kconf.load_config() 114*c689edbbSJens Wiklander 115*c689edbbSJens Wiklander if args.header_path is None: 116*c689edbbSJens Wiklander if "KCONFIG_AUTOHEADER" in os.environ: 117*c689edbbSJens Wiklander kconf.write_autoconf() 118*c689edbbSJens Wiklander else: 119*c689edbbSJens Wiklander # Kconfiglib defaults to include/generated/autoconf.h to be 120*c689edbbSJens Wiklander # compatible with the C tools. 'config.h' is used here instead for 121*c689edbbSJens Wiklander # backwards compatibility. It's probably a saner default for tools 122*c689edbbSJens Wiklander # as well. 123*c689edbbSJens Wiklander kconf.write_autoconf("config.h") 124*c689edbbSJens Wiklander else: 125*c689edbbSJens Wiklander kconf.write_autoconf(args.header_path) 126*c689edbbSJens Wiklander 127*c689edbbSJens Wiklander if args.config_out is not None: 128*c689edbbSJens Wiklander kconf.write_config(args.config_out, save_old=False) 129*c689edbbSJens Wiklander 130*c689edbbSJens Wiklander if args.sync_deps is not None: 131*c689edbbSJens Wiklander kconf.sync_deps(args.sync_deps) 132*c689edbbSJens Wiklander 133*c689edbbSJens Wiklander if args.file_list is not None: 134*c689edbbSJens Wiklander with _open_write(args.file_list) as f: 135*c689edbbSJens Wiklander for path in kconf.kconfig_filenames: 136*c689edbbSJens Wiklander f.write(path + "\n") 137*c689edbbSJens Wiklander 138*c689edbbSJens Wiklander if args.env_list is not None: 139*c689edbbSJens Wiklander with _open_write(args.env_list) as f: 140*c689edbbSJens Wiklander for env_var in kconf.env_vars: 141*c689edbbSJens Wiklander f.write("{}={}\n".format(env_var, os.environ[env_var])) 142*c689edbbSJens Wiklander 143*c689edbbSJens Wiklander 144*c689edbbSJens Wiklanderdef _open_write(path): 145*c689edbbSJens Wiklander # Python 2/3 compatibility. io.open() is available on both, but makes 146*c689edbbSJens Wiklander # write() expect 'unicode' strings on Python 2. 147*c689edbbSJens Wiklander 148*c689edbbSJens Wiklander if sys.version_info[0] < 3: 149*c689edbbSJens Wiklander return open(path, "w") 150*c689edbbSJens Wiklander return open(path, "w", encoding="utf-8") 151*c689edbbSJens Wiklander 152*c689edbbSJens Wiklander 153*c689edbbSJens Wiklanderif __name__ == "__main__": 154*c689edbbSJens Wiklander main() 155