Re: [Qemu-devel] [PATCH RFC 17/21] qapi/types qapi/visit: Generate built-in stuff into separate files
On 02/02/2018 07:03 AM, Markus Armbruster wrote: Linking code from multiple separate QAPI schemata into the same program is possible, but involves some weirdness around built-in types: * We generate code for built-in types into .c only with option --builtins. The user is responsible to generate code for exactly one QAPI schema per program with --builtins. * We generate code for them it into .h regardless of --builtins, s/them it/them/ guarded by #ifndef QAPI_VISIT_BUILTIN. Because the code for built-in types is exactly the same in all of them, including any combination of these headers works. Replace this contraption by something more conventional: generate code for built-in types into their very own files: qapi-builtin-types.c, qapi-builtin-visit.c, qapi-builtin-types.h, qapi-builtin-visit.h, but only with --builtins. Obey --output-dir, but ignore --prefix for them. Make qapi-types.h include qapi-builtin-types.h. With multiple schemata you now have multiple qapi-types.[ch], but only one qapi-builtin-types.[ch]. Same for qapi-visit.[ch] and qapi-builtin-visit.[ch]. Bonus: if all you need is built-in stuff, you can include a much smaller header. To be exploited shortly. Signed-off-by: Markus Armbruster --- -- Eric Blake, Principal Software Engineer Red Hat, Inc. +1-919-301-3266 Virtualization: qemu.org | libvirt.org
Re: [Qemu-devel] [PATCH RFC 17/21] qapi/types qapi/visit: Generate built-in stuff into separate files
On Fri, Feb 2, 2018 at 2:03 PM, Markus Armbruster wrote: > Linking code from multiple separate QAPI schemata into the same > program is possible, but involves some weirdness around built-in > types: > > * We generate code for built-in types into .c only with option > --builtins. The user is responsible to generate code for exactly > one QAPI schema per program with --builtins. > > * We generate code for them it into .h regardless of --builtins, > guarded by #ifndef QAPI_VISIT_BUILTIN. Because the code for > built-in types is exactly the same in all of them, including any > combination of these headers works. > > Replace this contraption by something more conventional: generate code > for built-in types into their very own files: qapi-builtin-types.c, > qapi-builtin-visit.c, qapi-builtin-types.h, qapi-builtin-visit.h, but > only with --builtins. Obey --output-dir, but ignore --prefix for > them. > > Make qapi-types.h include qapi-builtin-types.h. With multiple > schemata you now have multiple qapi-types.[ch], but only one > qapi-builtin-types.[ch]. Same for qapi-visit.[ch] and > qapi-builtin-visit.[ch]. > > Bonus: if all you need is built-in stuff, you can include a much > smaller header. To be exploited shortly. > > Signed-off-by: Markus Armbruster Reviewed-by: Marc-André Lureau > --- > Makefile | 13 +--- > Makefile.objs | 1 + > scripts/qapi/common.py | 18 +-- > scripts/qapi/types.py | 82 ++-- > scripts/qapi/visit.py | 84 > -- > 5 files changed, 111 insertions(+), 87 deletions(-) > > diff --git a/Makefile b/Makefile > index e02f0c13ef..f9b7900330 100644 > --- a/Makefile > +++ b/Makefile > @@ -88,10 +88,13 @@ endif > include $(SRC_PATH)/rules.mak > > GENERATED_FILES = qemu-version.h config-host.h qemu-options.def > -GENERATED_FILES += qmp-commands.h qapi-types.h qapi-visit.h qapi-event.h > -GENERATED_FILES += qmp-marshal.c qapi-types.c qapi-visit.c qapi-event.c > -GENERATED_FILES += qmp-introspect.h > -GENERATED_FILES += qmp-introspect.c > +GENERATED_FILES += qmp-commands.h qmp-marshal.c > +GENERATED_FILES += qapi-builtin-types.h qapi-builtin-types.c > +GENERATED_FILES += qapi-types.h qapi-types.c > +GENERATED_FILES += qapi-builtin-visit.h qapi-builtin-visit.c > +GENERATED_FILES += qapi-visit.h qapi-visit.c > +GENERATED_FILES += qapi-event.h qapi-event.c > +GENERATED_FILES += qmp-introspect.c qmp-introspect.h > GENERATED_FILES += qapi.texi > > GENERATED_FILES += trace/generated-tcg-tracers.h > @@ -514,7 +517,9 @@ qapi-modules = $(SRC_PATH)/qapi-schema.json > $(SRC_PATH)/qapi/common.json \ > $(SRC_PATH)/qapi/transaction.json \ > $(SRC_PATH)/qapi/ui.json > > +qapi-builtin-types.c qapi-builtin-types.h \ > qapi-types.c qapi-types.h \ > +qapi-builtin-visit.c qapi-builtin-visit.h \ > qapi-visit.c qapi-visit.h \ > qmp-commands.h qmp-marshal.c \ > qapi-event.c qapi-event.h \ > diff --git a/Makefile.objs b/Makefile.objs > index 323ef12384..f16cca06e7 100644 > --- a/Makefile.objs > +++ b/Makefile.objs > @@ -2,6 +2,7 @@ > # Common libraries for tools and emulators > stub-obj-y = stubs/ crypto/ > util-obj-y = util/ qobject/ qapi/ > +util-obj-y += qapi-builtin-types.o qapi-builtin-visit.o > util-obj-y += qmp-introspect.o qapi-types.o qapi-visit.o qapi-event.o > > chardev-obj-y = chardev/ > diff --git a/scripts/qapi/common.py b/scripts/qapi/common.py > index f4e9ebbb53..7c78d9 100644 > --- a/scripts/qapi/common.py > +++ b/scripts/qapi/common.py > @@ -1527,11 +1527,10 @@ class QAPISchema(object): > > def _def_builtin_type(self, name, json_type, c_type): > self._def_entity(QAPISchemaBuiltinType(name, json_type, c_type)) > -# TODO As long as we have QAPI_TYPES_BUILTIN to share multiple > -# qapi-types.h from a single .c, all arrays of builtins must be > -# declared in the first file whether or not they are used. Nicer > -# would be to use lazy instantiation, while figuring out how to > -# avoid compilation issues with multiple qapi-types.h. > +# Instantiating only the arrays that are actually used would > +# be nice, but we can't as long as their generated code > +# (qapi-builtin-types.[ch]) may be shared by some other > +# schema. > self._make_array_type(name, None) > > def _def_predefineds(self): > @@ -1985,14 +1984,15 @@ class QAPIGen(object): > return '' > > def write(self, output_dir, fname): > -if output_dir: > +pathname = os.path.join(output_dir, fname) > +dir = os.path.dirname(pathname) > +if dir: > try: > -os.makedirs(output_dir) > +os.makedirs(dir) > except os.error as e: > if e.errno != errno.EEXIST: > raise > -fd = os.open(os.path.join(output_dir, fname), > -
[Qemu-devel] [PATCH RFC 17/21] qapi/types qapi/visit: Generate built-in stuff into separate files
Linking code from multiple separate QAPI schemata into the same program is possible, but involves some weirdness around built-in types: * We generate code for built-in types into .c only with option --builtins. The user is responsible to generate code for exactly one QAPI schema per program with --builtins. * We generate code for them it into .h regardless of --builtins, guarded by #ifndef QAPI_VISIT_BUILTIN. Because the code for built-in types is exactly the same in all of them, including any combination of these headers works. Replace this contraption by something more conventional: generate code for built-in types into their very own files: qapi-builtin-types.c, qapi-builtin-visit.c, qapi-builtin-types.h, qapi-builtin-visit.h, but only with --builtins. Obey --output-dir, but ignore --prefix for them. Make qapi-types.h include qapi-builtin-types.h. With multiple schemata you now have multiple qapi-types.[ch], but only one qapi-builtin-types.[ch]. Same for qapi-visit.[ch] and qapi-builtin-visit.[ch]. Bonus: if all you need is built-in stuff, you can include a much smaller header. To be exploited shortly. Signed-off-by: Markus Armbruster --- Makefile | 13 +--- Makefile.objs | 1 + scripts/qapi/common.py | 18 +-- scripts/qapi/types.py | 82 ++-- scripts/qapi/visit.py | 84 -- 5 files changed, 111 insertions(+), 87 deletions(-) diff --git a/Makefile b/Makefile index e02f0c13ef..f9b7900330 100644 --- a/Makefile +++ b/Makefile @@ -88,10 +88,13 @@ endif include $(SRC_PATH)/rules.mak GENERATED_FILES = qemu-version.h config-host.h qemu-options.def -GENERATED_FILES += qmp-commands.h qapi-types.h qapi-visit.h qapi-event.h -GENERATED_FILES += qmp-marshal.c qapi-types.c qapi-visit.c qapi-event.c -GENERATED_FILES += qmp-introspect.h -GENERATED_FILES += qmp-introspect.c +GENERATED_FILES += qmp-commands.h qmp-marshal.c +GENERATED_FILES += qapi-builtin-types.h qapi-builtin-types.c +GENERATED_FILES += qapi-types.h qapi-types.c +GENERATED_FILES += qapi-builtin-visit.h qapi-builtin-visit.c +GENERATED_FILES += qapi-visit.h qapi-visit.c +GENERATED_FILES += qapi-event.h qapi-event.c +GENERATED_FILES += qmp-introspect.c qmp-introspect.h GENERATED_FILES += qapi.texi GENERATED_FILES += trace/generated-tcg-tracers.h @@ -514,7 +517,9 @@ qapi-modules = $(SRC_PATH)/qapi-schema.json $(SRC_PATH)/qapi/common.json \ $(SRC_PATH)/qapi/transaction.json \ $(SRC_PATH)/qapi/ui.json +qapi-builtin-types.c qapi-builtin-types.h \ qapi-types.c qapi-types.h \ +qapi-builtin-visit.c qapi-builtin-visit.h \ qapi-visit.c qapi-visit.h \ qmp-commands.h qmp-marshal.c \ qapi-event.c qapi-event.h \ diff --git a/Makefile.objs b/Makefile.objs index 323ef12384..f16cca06e7 100644 --- a/Makefile.objs +++ b/Makefile.objs @@ -2,6 +2,7 @@ # Common libraries for tools and emulators stub-obj-y = stubs/ crypto/ util-obj-y = util/ qobject/ qapi/ +util-obj-y += qapi-builtin-types.o qapi-builtin-visit.o util-obj-y += qmp-introspect.o qapi-types.o qapi-visit.o qapi-event.o chardev-obj-y = chardev/ diff --git a/scripts/qapi/common.py b/scripts/qapi/common.py index f4e9ebbb53..7c78d9 100644 --- a/scripts/qapi/common.py +++ b/scripts/qapi/common.py @@ -1527,11 +1527,10 @@ class QAPISchema(object): def _def_builtin_type(self, name, json_type, c_type): self._def_entity(QAPISchemaBuiltinType(name, json_type, c_type)) -# TODO As long as we have QAPI_TYPES_BUILTIN to share multiple -# qapi-types.h from a single .c, all arrays of builtins must be -# declared in the first file whether or not they are used. Nicer -# would be to use lazy instantiation, while figuring out how to -# avoid compilation issues with multiple qapi-types.h. +# Instantiating only the arrays that are actually used would +# be nice, but we can't as long as their generated code +# (qapi-builtin-types.[ch]) may be shared by some other +# schema. self._make_array_type(name, None) def _def_predefineds(self): @@ -1985,14 +1984,15 @@ class QAPIGen(object): return '' def write(self, output_dir, fname): -if output_dir: +pathname = os.path.join(output_dir, fname) +dir = os.path.dirname(pathname) +if dir: try: -os.makedirs(output_dir) +os.makedirs(dir) except os.error as e: if e.errno != errno.EEXIST: raise -fd = os.open(os.path.join(output_dir, fname), - os.O_RDWR | os.O_CREAT, 0666) +fd = os.open(pathname, os.O_RDWR | os.O_CREAT, 0666) f = os.fdopen(fd, 'r+') text = (self.top(fname) + self._preamble + self._body + self.bottom(fname)) diff --git a/scripts/qapi/types.py b/scripts/qapi/types.py inde