genconfig.py 5.2 KB

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