esp-idf/docs/idf_extensions/gen_defines.py
Marius Vikhammer fbb54184ef doc: add generation of tags from sdkconfig and x_caps.h headers
Also updates the way we handle exclude_patterns to use the new tags

Closes IDF-1484
2020-05-13 07:09:01 +00:00

73 lines
2.6 KiB
Python

# Sphinx extension to integrate defines into the Sphinx Build
#
# Runs after the IDF dummy project has been built
#
# Then emits the new 'idf-defines-generated' event which has a dictionary of raw text define values
# that other extensions can use to generate relevant data.
import glob
import os
import subprocess
import re
def generate_defines(app, project_description):
sdk_config_path = os.path.join(project_description["build_dir"], "config")
# Parse kconfig macros to pass into doxygen
#
# TODO: this should use the set of "config which can't be changed" eventually,
# not the header
defines = get_defines(os.path.join(project_description["build_dir"],
"config", "sdkconfig.h"), sdk_config_path)
# Add all SOC _caps.h headers and kconfig macros to the defines
#
# kind of a hack, be nicer to add a component info dict in project_description.json
soc_path = [p for p in project_description["build_component_paths"] if p.endswith("/soc")][0]
soc_headers = glob.glob(os.path.join(soc_path, "soc", project_description["target"],
"include", "soc", "*_caps.h"))
assert len(soc_headers) > 0
for soc_header in soc_headers:
defines.update(get_defines(soc_header, sdk_config_path))
add_tags(app, defines)
app.emit('idf-defines-generated', defines)
def get_defines(header_path, sdk_config_path):
defines = {}
# Note: we run C preprocessor here without any -I arguments (except "sdkconfig.h"), so assumption is
# that these headers are all self-contained and don't include any other headers
# not in the same directory
print("Reading macros from %s..." % (header_path))
processed_output = subprocess.check_output(["xtensa-esp32-elf-gcc", "-I", sdk_config_path,
"-dM", "-E", header_path]).decode()
for line in processed_output.split("\n"):
line = line.strip()
m = re.search("#define ([^ ]+) ?(.*)", line)
if m and not m.group(1).startswith("_"):
defines[m.group(1)] = m.group(2)
return defines
def add_tags(app, defines):
# try to parse define values as ints and add to tags
for name, value in defines.items():
try:
define_value = int(value.strip("()"))
if define_value > 0:
app.tags.add(name)
except ValueError:
continue
def setup(app):
app.connect('idf-info', generate_defines)
app.add_event('idf-defines-generated')
return {'parallel_read_safe': True, 'parallel_write_safe': True, 'version': '0.1'}