gen_edt: use workspace dir as base for relative paths in comments

This commit allows comments to reference files with paths that are relative
to the Zephyr workspace root. This is done by adding a new argument
'--workspace-dir' to the 'gen_edt.py' script, which is passed to the
'EDT' and 'DT' classes and used instead of the current working directory.

The workspace directory is set to WEST_TOPDIR if West is in use,
otherwise it is set to the parent directory of ZEPHYR_BASE so that
Zephyr files have a 'zephyr/' prefix.

Signed-off-by: Luca Burelli <l.burelli@arduino.cc>
This commit is contained in:
Luca Burelli 2025-05-02 14:25:08 +02:00 committed by Benjamin Cabé
commit c1603b3163
4 changed files with 29 additions and 4 deletions

View file

@ -290,11 +290,21 @@ set_property(DIRECTORY APPEND PROPERTY
# Run GEN_EDT_SCRIPT. # Run GEN_EDT_SCRIPT.
# #
if(WEST_TOPDIR)
set(GEN_EDT_WORKSPACE_DIR ${WEST_TOPDIR})
else()
# If West is not available, define the parent directory of ZEPHYR_BASE as
# the workspace. This will create comments that reference the files in the
# Zephyr tree with a 'zephyr/' prefix.
set(GEN_EDT_WORKSPACE_DIR ${ZEPHYR_BASE}/..)
endif()
string(REPLACE ";" " " EXTRA_DTC_FLAGS_RAW "${EXTRA_DTC_FLAGS}") string(REPLACE ";" " " EXTRA_DTC_FLAGS_RAW "${EXTRA_DTC_FLAGS}")
set(CMD_GEN_EDT ${PYTHON_EXECUTABLE} ${GEN_EDT_SCRIPT} set(CMD_GEN_EDT ${PYTHON_EXECUTABLE} ${GEN_EDT_SCRIPT}
--dts ${DTS_POST_CPP} --dts ${DTS_POST_CPP}
--dtc-flags '${EXTRA_DTC_FLAGS_RAW}' --dtc-flags '${EXTRA_DTC_FLAGS_RAW}'
--bindings-dirs ${DTS_ROOT_BINDINGS} --bindings-dirs ${DTS_ROOT_BINDINGS}
--workspace-dir ${GEN_EDT_WORKSPACE_DIR}
--dts-out ${ZEPHYR_DTS}.new # for debugging and dtc --dts-out ${ZEPHYR_DTS}.new # for debugging and dtc
--edt-pickle-out ${EDT_PICKLE}.new --edt-pickle-out ${EDT_PICKLE}.new
${EXTRA_GEN_EDT_ARGS} ${EXTRA_GEN_EDT_ARGS}

View file

@ -43,6 +43,7 @@ def main():
try: try:
edt = edtlib.EDT(args.dts, args.bindings_dirs, edt = edtlib.EDT(args.dts, args.bindings_dirs,
workspace_dir=args.workspace_dir,
# Suppress this warning if it's suppressed in dtc # Suppress this warning if it's suppressed in dtc
warn_reg_unit_address_mismatch= warn_reg_unit_address_mismatch=
"-Wno-simple_bus_reg" not in args.dtc_flags, "-Wno-simple_bus_reg" not in args.dtc_flags,
@ -71,6 +72,9 @@ def parse_args() -> argparse.Namespace:
parser.add_argument("--bindings-dirs", nargs='+', required=True, parser.add_argument("--bindings-dirs", nargs='+', required=True,
help="directory with bindings in YAML format, " help="directory with bindings in YAML format, "
"we allow multiple") "we allow multiple")
parser.add_argument("--workspace-dir", default=os.getcwd(),
help="directory to be used as reference for generated "
"relative paths (e.g. WEST_TOPDIR)")
parser.add_argument("--dts-out", required=True, parser.add_argument("--dts-out", required=True,
help="path to write merged DTS source code to (e.g. " help="path to write merged DTS source code to (e.g. "
"as a debugging aid)") "as a debugging aid)")

View file

@ -207,7 +207,7 @@ class Node:
# a relative path cannot be established (on Windows with files # a relative path cannot be established (on Windows with files
# in different drives, for example). # in different drives, for example).
try: try:
return os.path.relpath(filename, start=os.getcwd()) return os.path.relpath(filename, start=self.dt._base_dir)
except ValueError: except ValueError:
return filename return filename
@ -787,7 +787,7 @@ class DT:
# #
def __init__(self, filename: Optional[str], include_path: Iterable[str] = (), def __init__(self, filename: Optional[str], include_path: Iterable[str] = (),
force: bool = False): force: bool = False, base_dir: Optional[str] = None):
""" """
Parses a DTS file to create a DT instance. Raises OSError if 'filename' Parses a DTS file to create a DT instance. Raises OSError if 'filename'
can't be opened, and DTError for any parse errors. can't be opened, and DTError for any parse errors.
@ -804,6 +804,11 @@ class DT:
force: force:
Try not to raise DTError even if the input tree has errors. Try not to raise DTError even if the input tree has errors.
For experimental use; results not guaranteed. For experimental use; results not guaranteed.
base_dir:
Path to the directory that is to be used as the reference for
the generated relative paths in comments. When not provided, the
current working directory is used.
""" """
# Remember to update __deepcopy__() if you change this. # Remember to update __deepcopy__() if you change this.
@ -817,6 +822,7 @@ class DT:
self.filename = filename self.filename = filename
self._force = force self._force = force
self._base_dir = base_dir or os.getcwd()
if filename is not None: if filename is not None:
self._parse_file(filename, include_path) self._parse_file(filename, include_path)
@ -974,7 +980,7 @@ class DT:
""" """
# We need a new DT, obviously. Make a new, empty one. # We need a new DT, obviously. Make a new, empty one.
ret = DT(None, (), self._force) ret = DT(None, (), self._force, self._base_dir)
# Now allocate new Node objects for every node in self, to use # Now allocate new Node objects for every node in self, to use
# in the new DT. Set their parents to None for now and leave # in the new DT. Set their parents to None for now and leave

View file

@ -1993,6 +1993,7 @@ class EDT:
def __init__(self, def __init__(self,
dts: Optional[str], dts: Optional[str],
bindings_dirs: list[str], bindings_dirs: list[str],
workspace_dir: Optional[str] = None,
warn_reg_unit_address_mismatch: bool = True, warn_reg_unit_address_mismatch: bool = True,
default_prop_types: bool = True, default_prop_types: bool = True,
support_fixed_partitions_on_any_bus: bool = True, support_fixed_partitions_on_any_bus: bool = True,
@ -2009,6 +2010,10 @@ class EDT:
List of paths to directories containing bindings, in YAML format. List of paths to directories containing bindings, in YAML format.
These directories are recursively searched for .yaml files. These directories are recursively searched for .yaml files.
workspace_dir:
Path to the root of the Zephyr workspace. This is used as a base
directory for relative paths in the generated devicetree comments.
warn_reg_unit_address_mismatch (default: True): warn_reg_unit_address_mismatch (default: True):
If True, a warning is logged if a node has a 'reg' property where If True, a warning is logged if a node has a 'reg' property where
the address of the first entry does not match the unit address of the the address of the first entry does not match the unit address of the
@ -2077,7 +2082,7 @@ class EDT:
if dts is not None: if dts is not None:
try: try:
self._dt = DT(dts) self._dt = DT(dts, base_dir=workspace_dir)
except DTError as e: except DTError as e:
raise EDTError(e) from e raise EDTError(e) from e
self._finish_init() self._finish_init()