Re: [Qemu-devel] [PATCH RFC 17/21] qapi/types qapi/visit: Generate built-in stuff into separate files

2018-02-06 Thread Eric Blake

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

2018-02-05 Thread Marc-Andre Lureau
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

2018-02-02 Thread Markus Armbruster
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