Re: [PATCH v2 01/34] kbuild: Add support for DT binding schema checks
From: Rob Herring
Date: Mon Dec 10 2018 - 10:55:24 EST
On Fri, Dec 7, 2018 at 10:47 PM Masahiro Yamada
<yamada.masahiro@xxxxxxxxxxxxx> wrote:
>
> Hi Rob,
>
>
> On Tue, Dec 4, 2018 at 6:32 AM Rob Herring <robh@xxxxxxxxxx> wrote:
> >
> > This adds the build infrastructure for checking DT binding schema
> > documents and validating dts files using the binding schema.
> >
> > Check DT binding schema documents:
> > make dt_binding_check
> >
> > Build dts files and check using DT binding schema:
> > make dtbs_check
> >
> > Optionally, DT_SCHEMA_FILES can passed in with a schema file(s) to use
> > for validation. This makes it easier to find and fix errors generated by
> > a specific schema.
> >
> > Currently, the validation targets are separate from a normal build to
> > avoid a hard dependency on the external DT schema project and because
> > there are lots of warnings generated.
> >
> > Cc: Jonathan Corbet <corbet@xxxxxxx>
> > Cc: Mark Rutland <mark.rutland@xxxxxxx>
> > Cc: Masahiro Yamada <yamada.masahiro@xxxxxxxxxxxxx>
> > Cc: Michal Marek <michal.lkml@xxxxxxxxxxx>
> > Cc: linux-doc@xxxxxxxxxxxxxxx
> > Cc: devicetree@xxxxxxxxxxxxxxx
> > Cc: linux-kbuild@xxxxxxxxxxxxxxx
> > Signed-off-by: Rob Herring <robh@xxxxxxxxxx>
> > ---
> > .gitignore | 1 +
> > Documentation/Makefile | 2 +-
> > Documentation/devicetree/bindings/.gitignore | 1 +
> > Documentation/devicetree/bindings/Makefile | 33 ++++++++++++++++++++
> > Makefile | 11 +++++--
> > scripts/Makefile.lib | 24 ++++++++++++--
> > 6 files changed, 67 insertions(+), 5 deletions(-)
> > create mode 100644 Documentation/devicetree/bindings/.gitignore
> > create mode 100644 Documentation/devicetree/bindings/Makefile
> >
> > diff --git a/.gitignore b/.gitignore
> > index 97ba6b79834c..a20ac26aa2f5 100644
> > --- a/.gitignore
> > +++ b/.gitignore
> > @@ -15,6 +15,7 @@
> > *.bin
> > *.bz2
> > *.c.[012]*.*
> > +*.dt.yaml
> > *.dtb
> > *.dtb.S
> > *.dwo
> > diff --git a/Documentation/Makefile b/Documentation/Makefile
> > index 2ca77ad0f238..9786957c6a35 100644
> > --- a/Documentation/Makefile
> > +++ b/Documentation/Makefile
> > @@ -2,7 +2,7 @@
> > # Makefile for Sphinx documentation
> > #
> >
> > -subdir-y :=
> > +subdir-y := devicetree/bindings/
> >
> > # You can set these variables from the command line.
> > SPHINXBUILD = sphinx-build
> > diff --git a/Documentation/devicetree/bindings/.gitignore b/Documentation/devicetree/bindings/.gitignore
> > new file mode 100644
> > index 000000000000..d9194c02dd08
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/.gitignore
> > @@ -0,0 +1 @@
> > +*.example.dts
> > diff --git a/Documentation/devicetree/bindings/Makefile b/Documentation/devicetree/bindings/Makefile
> > new file mode 100644
> > index 000000000000..ee0110dd8131
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/Makefile
> > @@ -0,0 +1,33 @@
> > +# SPDX-License-Identifier: GPL-2.0
> > +DT_DOC_CHECKER ?= dt-doc-validate
> > +DT_EXTRACT_EX ?= dt-extract-example
> > +DT_MK_SCHEMA ?= dt-mk-schema
> > +DT_MK_SCHEMA_FLAGS := $(if $(DT_SCHEMA_FILES), -u)
> > +
> > +quiet_cmd_chk_binding = CHKDT $<
> > + cmd_chk_binding = (set -e; \
> > + $(DT_DOC_CHECKER) $< ; \
> > + mkdir -p $(dir $@) ; \
> > + $(DT_EXTRACT_EX) $< > $@ )
> > +
> > +$(obj)/%.example.dts: $(src)/%.yaml FORCE
> > + $(call if_changed,chk_binding)
> > +
> > +DT_TMP_SCHEMA := .schema.yaml.tmp
> > +extra-y += $(DT_TMP_SCHEMA)
> > +
> > +quiet_cmd_mk_schema = SCHEMA $@
> > + cmd_mk_schema = mkdir -p $(obj); \
> > + rm -f $@; \
> > + $(DT_MK_SCHEMA) $(DT_MK_SCHEMA_FLAGS) -o $@ $<
>
>
> I think '$<' is wrong.
>
> '$<' is replaced with the first prerequisite.
Indeed.
> You can easily check what is happening here.
>
> $ cat Documentation/devicetree/bindings/..schema.yaml.tmp.cmd
> cmd_Documentation/devicetree/bindings/.schema.yaml.tmp := mkdir -p
> Documentation/devicetree/bindings; rm -f
> Documentation/devicetree/bindings/.schema.yaml.tmp; dt-mk-schema -o
> Documentation/devicetree/bindings/.schema.yaml.tmp
> Documentation/devicetree/bindings/arm/ti/ti,davinci.yaml
>
>
> So, the dt-validater will check only binding from ti,davinci.yaml,
> which is almost useless.
>
>
>
> If I understand it correctly,
> .schema.yaml.tmp should contain all binding yaml.
>
>
> I fixed it up like follows:
>
> diff --git a/Documentation/devicetree/bindings/Makefile
> b/Documentation/devicetree/bindings/Makefile
> index ee0110d..267458f 100644
> --- a/Documentation/devicetree/bindings/Makefile
> +++ b/Documentation/devicetree/bindings/Makefile
> @@ -19,7 +19,7 @@ extra-y += $(DT_TMP_SCHEMA)
> quiet_cmd_mk_schema = SCHEMA $@
> cmd_mk_schema = mkdir -p $(obj); \
> rm -f $@; \
> - $(DT_MK_SCHEMA) $(DT_MK_SCHEMA_FLAGS) -o $@ $<
> + $(DT_MK_SCHEMA) $(DT_MK_SCHEMA_FLAGS) -o $@
> $(filter-out FORCE, $^)
Thanks, I incorporated this fix.
>
> DT_DOCS = $(shell cd $(srctree)/$(src) && find * -name '*.yaml')
> DT_SCHEMA_FILES ?= $(addprefix $(src)/,$(DT_DOCS))
>
>
>
> Then, I see another error.
I fixed this with this change:
@@ -27,7 +27,7 @@ DT_SCHEMA_FILES ?= $(addprefix $(src)/,$(DT_DOCS))
extra-y += $(patsubst $(src)/%.yaml,%.example.dts, $(DT_SCHEMA_FILES))
extra-y += $(patsubst $(src)/%.yaml,%.example.dtb, $(DT_SCHEMA_FILES))
-$(obj)/$(DT_TMP_SCHEMA): $(addprefix $(obj)/,$(patsubst
$(src)/%.yaml,%.example.dtb, $(DT_SCHEMA_FILES)))
+$(obj)/$(DT_TMP_SCHEMA): | $(addprefix $(obj)/,$(patsubst
$(src)/%.yaml,%.example.dtb, $(DT_SCHEMA_FILES)))
$(obj)/$(DT_TMP_SCHEMA): $(addprefix $(srctree)/, $(DT_SCHEMA_FILES)) FORCE
$(call if_changed,mk_schema)
>
>
> SCHEMA Documentation/devicetree/bindings/.schema.yaml.tmp
> Traceback (most recent call last):
> File "/home/masahiro/ref/yaml-bindings/tools/dt-mk-schema", line 32,
> in <module>
> schemas = dtschema.process_schemas(args.schemas, core_schema=(not
> args.useronly))
> File "/usr/local/lib/python3.5/dist-packages/dtschema-0.0.1-py3.5.egg/dtschema/lib.py",
> line 359, in process_schemas
> sch = process_schema(os.path.abspath(filename))
> File "/usr/local/lib/python3.5/dist-packages/dtschema-0.0.1-py3.5.egg/dtschema/lib.py",
> line 314, in process_schema
> schema = load_schema(filename)
> File "/usr/local/lib/python3.5/dist-packages/dtschema-0.0.1-py3.5.egg/dtschema/lib.py",
> line 80, in load_schema
> return yaml.load(f.read())
> File "/usr/lib/python3.5/codecs.py", line 321, in decode
> (result, consumed) = self._buffer_decode(data, self.errors, final)
> UnicodeDecodeError: 'utf-8' codec can't decode byte 0xd0 in position
> 0: invalid continuation byte
> Documentation/devicetree/bindings/Makefile:33: recipe for target
> 'Documentation/devicetree/bindings/.schema.yaml.tmp' failed
> make[1]: *** [Documentation/devicetree/bindings/.schema.yaml.tmp] Error 1
> Makefile:1278: recipe for target 'dt_binding_check' failed
> make: *** [dt_binding_check] Error 2
>
>
>
>
>
>
>
> BTW, I cannot build *.dt.yaml
>
>
>
> DTC arch/arm/boot/dts/alpine-db.dt.yaml
> FATAL ERROR: Unknown output format "yaml"
> scripts/Makefile.lib:313: recipe for target
> 'arch/arm/boot/dts/alpine-db.dt.yaml' failed
> make[1]: *** [arch/arm/boot/dts/alpine-db.dt.yaml] Error 1
> make[1]: *** Deleting file 'arch/arm/boot/dts/alpine-db.dt.yaml'
> Makefile:1262: recipe for target 'dtbs_check' failed
>
>
>
>
> I use linux-next.
>
>
> script/dtc/dtc does not understand '-O yaml'
>
>
> I also tried the upstream DTC project with no success.
>
>
> Where can I get dtc with yaml support?
You need libyaml and its headers. I'll try to make this a better error
message. For now, libyaml is optional so we don't break everyone just
building dtbs.
Rob