xref: /optee_os/scripts/kconfig/kconfiglib/genconfig.py (revision c689edbb2550c76ae81dcecab717d82a564b2d7b)
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