diff --git a/.gitignore b/.gitignore index 7de868d1ea..efad605e1a 100644 --- a/.gitignore +++ b/.gitignore @@ -37,6 +37,7 @@ /qapi/qapi-emit-events.[ch] /qapi/qapi-events-*.[ch] /qapi/qapi-events.[ch] +/qapi/qapi-init-commands.[ch] /qapi/qapi-introspect.[ch] /qapi/qapi-types-*.[ch] /qapi/qapi-types.[ch] diff --git a/Makefile b/Makefile index 32bd554480..afa5cb6548 100644 --- a/Makefile +++ b/Makefile @@ -117,6 +117,7 @@ GENERATED_QAPI_FILES += qapi/qapi-builtin-visit.h qapi/qapi-builtin-visit.c GENERATED_QAPI_FILES += qapi/qapi-visit.h qapi/qapi-visit.c GENERATED_QAPI_FILES += $(QAPI_MODULES:%=qapi/qapi-visit-%.h) GENERATED_QAPI_FILES += $(QAPI_MODULES:%=qapi/qapi-visit-%.c) +GENERATED_QAPI_FILES += qapi/qapi-init-commands.h qapi/qapi-init-commands.c GENERATED_QAPI_FILES += qapi/qapi-commands.h qapi/qapi-commands.c GENERATED_QAPI_FILES += $(QAPI_MODULES:%=qapi/qapi-commands-%.h) GENERATED_QAPI_FILES += $(QAPI_MODULES:%=qapi/qapi-commands-%.c) @@ -602,6 +603,7 @@ $(SRC_PATH)/scripts/qapi-gen.py qga/qapi-generated/qga-qapi-types.c qga/qapi-generated/qga-qapi-types.h \ qga/qapi-generated/qga-qapi-visit.c qga/qapi-generated/qga-qapi-visit.h \ qga/qapi-generated/qga-qapi-commands.h qga/qapi-generated/qga-qapi-commands.c \ +qga/qapi-generated/qga-qapi-init-commands.h qga/qapi-generated/qga-qapi-init-commands.c \ qga/qapi-generated/qga-qapi-doc.texi: \ qga/qapi-generated/qapi-gen-timestamp ; qga/qapi-generated/qapi-gen-timestamp: $(SRC_PATH)/qga/qapi-schema.json $(qapi-py) @@ -620,7 +622,7 @@ qapi-gen-timestamp: $(qapi-modules) $(qapi-py) "GEN","$(@:%-timestamp=%)") @>$@ -QGALIB_GEN=$(addprefix qga/qapi-generated/, qga-qapi-types.h qga-qapi-visit.h qga-qapi-commands.h) +QGALIB_GEN=$(addprefix qga/qapi-generated/, qga-qapi-types.h qga-qapi-visit.h qga-qapi-commands.h qga-qapi-init-commands.h) $(qga-obj-y): $(QGALIB_GEN) qemu-ga$(EXESUF): $(qga-obj-y) $(COMMON_LDADDS) diff --git a/docs/devel/qapi-code-gen.txt b/docs/devel/qapi-code-gen.txt index 45c93a43cc..59d6973e1e 100644 --- a/docs/devel/qapi-code-gen.txt +++ b/docs/devel/qapi-code-gen.txt @@ -1493,6 +1493,10 @@ $(prefix)qapi-commands.c: Command marshal/dispatch functions for each $(prefix)qapi-commands.h: Function prototypes for the QMP commands specified in the schema +$(prefix)qapi-init-commands.h - Command initialization prototype + +$(prefix)qapi-init-commands.c - Command initialization code + Example: $ cat qapi-generated/example-qapi-commands.h @@ -1502,11 +1506,9 @@ Example: #define EXAMPLE_QAPI_COMMANDS_H #include "example-qapi-types.h" - #include "qapi/qmp/dispatch.h" UserDefOne *qmp_my_command(UserDefOneList *arg1, Error **errp); void qmp_marshal_my_command(QDict *args, QObject **ret, Error **errp); - void example_qmp_init_marshal(QmpCommandList *cmds); #endif /* EXAMPLE_QAPI_COMMANDS_H */ $ cat qapi-generated/example-qapi-commands.c @@ -1566,7 +1568,19 @@ Example: visit_end_struct(v, NULL); visit_free(v); } +[Uninteresting stuff omitted...] + $ cat qapi-generated/example-qapi-init-commands.h +[Uninteresting stuff omitted...] + #ifndef EXAMPLE_QAPI_INIT_COMMANDS_H + #define EXAMPLE_QAPI_INIT_COMMANDS_H + #include "qapi/qmp/dispatch.h" + + void example_qmp_init_marshal(QmpCommandList *cmds); + + #endif /* EXAMPLE_QAPI_INIT_COMMANDS_H */ + $ cat qapi-generated/example-qapi-init-commands.c +[Uninteresting stuff omitted...] void example_qmp_init_marshal(QmpCommandList *cmds) { QTAILQ_INIT(cmds); @@ -1574,7 +1588,6 @@ Example: qmp_register_command(cmds, "my-command", qmp_marshal_my_command, QCO_NO_OPTIONS); } - [Uninteresting stuff omitted...] For a modular QAPI schema (see section Include directives), code for diff --git a/monitor/misc.c b/monitor/misc.c index a04d7edde0..de1ca4d114 100644 --- a/monitor/misc.c +++ b/monitor/misc.c @@ -66,8 +66,13 @@ #include "qemu/option.h" #include "qemu/thread.h" #include "block/qapi.h" -#include "qapi/qapi-commands.h" +#include "qapi/qapi-commands-char.h" +#include "qapi/qapi-commands-migration.h" +#include "qapi/qapi-commands-misc.h" +#include "qapi/qapi-commands-qom.h" +#include "qapi/qapi-commands-trace.h" #include "qapi/qapi-emit-events.h" +#include "qapi/qapi-init-commands.h" #include "qapi/error.h" #include "qapi/qmp-event.h" #include "qapi/qapi-introspect.h" diff --git a/qapi/Makefile.objs b/qapi/Makefile.objs index dd3f5e6f94..a8f1f4c35e 100644 --- a/qapi/Makefile.objs +++ b/qapi/Makefile.objs @@ -30,3 +30,4 @@ obj-y += $(QAPI_TARGET_MODULES:%=qapi-events-%.o) obj-y += qapi-events.o obj-y += $(QAPI_TARGET_MODULES:%=qapi-commands-%.o) obj-y += qapi-commands.o +obj-y += qapi-init-commands.o diff --git a/qga/Makefile.objs b/qga/Makefile.objs index 80e6bb3c2e..9c558ae51c 100644 --- a/qga/Makefile.objs +++ b/qga/Makefile.objs @@ -5,5 +5,6 @@ qga-obj-$(CONFIG_WIN32) += commands-win32.o channel-win32.o service-win32.o qga-obj-$(CONFIG_WIN32) += vss-win32.o qga-obj-y += qapi-generated/qga-qapi-types.o qapi-generated/qga-qapi-visit.o qga-obj-y += qapi-generated/qga-qapi-commands.o +qga-obj-y += qapi-generated/qga-qapi-init-commands.o qga-vss-dll-obj-$(CONFIG_QGA_VSS) += vss-win32/ diff --git a/qga/main.c b/qga/main.c index c35c2a2120..e5c39c189a 100644 --- a/qga/main.c +++ b/qga/main.c @@ -24,7 +24,7 @@ #include "qapi/qmp/qjson.h" #include "qapi/qmp/qstring.h" #include "guest-agent-core.h" -#include "qga-qapi-commands.h" +#include "qga-qapi-init-commands.h" #include "qapi/qmp/qerror.h" #include "qapi/error.h" #include "channel.h" diff --git a/scripts/qapi/commands.py b/scripts/qapi/commands.py index ab98e504f3..afa55b055c 100644 --- a/scripts/qapi/commands.py +++ b/scripts/qapi/commands.py @@ -239,7 +239,7 @@ class QAPISchemaGenCommandVisitor(QAPISchemaModularCVisitor): def __init__(self, prefix): QAPISchemaModularCVisitor.__init__( self, prefix, 'qapi-commands', - ' * Schema-defined QAPI/QMP commands', __doc__) + ' * Schema-defined QAPI/QMP commands', None, __doc__) self._regy = QAPIGenCCode(None) self._visited_ret_types = {} @@ -263,18 +263,25 @@ class QAPISchemaGenCommandVisitor(QAPISchemaModularCVisitor): commands=commands, visit=visit)) self._genh.add(mcgen(''' #include "%(types)s.h" -#include "qapi/qmp/dispatch.h" ''', types=types)) def visit_end(self): - (genc, genh) = self._module[self._main_module] - genh.add(mcgen(''' + self._add_system_module('init', ' * QAPI Commands initialization') + self._genh.add(mcgen(''' +#include "qapi/qmp/dispatch.h" + void %(c_prefix)sqmp_init_marshal(QmpCommandList *cmds); ''', c_prefix=c_name(self._prefix, protect=False))) - genc.add(gen_registry(self._regy.get_content(), self._prefix)) + self._genc.preamble_add(mcgen(''' +#include "qemu/osdep.h" +#include "%(prefix)sqapi-commands.h" +#include "%(prefix)sqapi-init-commands.h" +''', + prefix=self._prefix)) + self._genc.add(gen_registry(self._regy.get_content(), self._prefix)) def visit_command(self, name, info, ifcond, arg_type, ret_type, gen, success_response, boxed, allow_oob, allow_preconfig, diff --git a/scripts/qapi/events.py b/scripts/qapi/events.py index 10fc509fa9..2bde3e6128 100644 --- a/scripts/qapi/events.py +++ b/scripts/qapi/events.py @@ -140,7 +140,7 @@ class QAPISchemaGenEventVisitor(QAPISchemaModularCVisitor): def __init__(self, prefix): QAPISchemaModularCVisitor.__init__( self, prefix, 'qapi-events', - ' * Schema-defined QAPI/QMP events', __doc__) + ' * Schema-defined QAPI/QMP events', None, __doc__) self._event_enum_name = c_name(prefix + 'QAPIEvent', protect=False) self._event_enum_members = [] self._event_emit_name = c_name(prefix + 'qapi_event_emit') diff --git a/scripts/qapi/gen.py b/scripts/qapi/gen.py index 112b6d94c5..95afae0615 100644 --- a/scripts/qapi/gen.py +++ b/scripts/qapi/gen.py @@ -201,10 +201,11 @@ class QAPISchemaMonolithicCVisitor(QAPISchemaVisitor): class QAPISchemaModularCVisitor(QAPISchemaVisitor): - def __init__(self, prefix, what, blurb, pydoc): + def __init__(self, prefix, what, user_blurb, builtin_blurb, pydoc): self._prefix = prefix self._what = what - self._blurb = blurb + self._user_blurb = user_blurb + self._builtin_blurb = builtin_blurb self._pydoc = pydoc self._genc = None self._genh = None @@ -245,7 +246,7 @@ class QAPISchemaModularCVisitor(QAPISchemaVisitor): genc = QAPIGenC(basename + '.c', blurb, self._pydoc) genh = QAPIGenH(basename + '.h', blurb, self._pydoc) self._module[name] = (genc, genh) - self._set_module(name) + self._genc, self._genh = self._module[name] def _add_user_module(self, name, blurb): assert self._is_user_module(name) @@ -256,9 +257,6 @@ class QAPISchemaModularCVisitor(QAPISchemaVisitor): def _add_system_module(self, name, blurb): self._add_module(name and './' + name, blurb) - def _set_module(self, name): - self._genc, self._genh = self._module[name] - def write(self, output_dir, opt_builtins=False): for name in self._module: if self._is_builtin_module(name) and not opt_builtins: @@ -271,15 +269,17 @@ class QAPISchemaModularCVisitor(QAPISchemaVisitor): pass def visit_module(self, name): - if name in self._module: - self._set_module(name) - elif self._is_builtin_module(name): - # The built-in module has not been created. No code may - # be generated. - self._genc = None - self._genh = None + if name is None: + if self._builtin_blurb: + self._add_system_module(None, self._builtin_blurb) + self._begin_system_module(name) + else: + # The built-in module has not been created. No code may + # be generated. + self._genc = None + self._genh = None else: - self._add_user_module(name, self._blurb) + self._add_user_module(name, self._user_blurb) self._begin_user_module(name) def visit_include(self, name, info): diff --git a/scripts/qapi/schema.py b/scripts/qapi/schema.py index cf0045f34e..0bfc5256fb 100644 --- a/scripts/qapi/schema.py +++ b/scripts/qapi/schema.py @@ -50,9 +50,6 @@ class QAPISchemaEntity(object): def check(self, schema): assert not self._checked - if self.info: - self._module = os.path.relpath(self.info.fname, - os.path.dirname(schema.fname)) seen = {} for f in self.features: f.check_clash(self.info, seen) @@ -68,16 +65,19 @@ class QAPISchemaEntity(object): if self.doc: self.doc.check() + def _set_module(self, schema, info): + assert self._checked + self._module = schema.module_by_fname(info and info.fname) + self._module.add_entity(self) + + def set_module(self, schema): + self._set_module(schema, self.info) + @property def ifcond(self): assert self._checked return self._ifcond - @property - def module(self): - assert self._checked - return self._module - def is_implicit(self): return not self.info @@ -135,15 +135,29 @@ class QAPISchemaVisitor(object): pass -class QAPISchemaInclude(QAPISchemaEntity): +class QAPISchemaModule(object): + def __init__(self, name): + self.name = name + self._entity_list = [] - def __init__(self, fname, info): + def add_entity(self, ent): + self._entity_list.append(ent) + + def visit(self, visitor): + visitor.visit_module(self.name) + for entity in self._entity_list: + if visitor.visit_needed(entity): + entity.visit(visitor) + + +class QAPISchemaInclude(QAPISchemaEntity): + def __init__(self, sub_module, info): QAPISchemaEntity.__init__(self, None, info, None) - self.fname = fname + self._sub_module = sub_module def visit(self, visitor): QAPISchemaEntity.visit(self, visitor) - visitor.visit_include(self.fname, self.info) + visitor.visit_include(self._sub_module.name, self.info) class QAPISchemaType(QAPISchemaEntity): @@ -276,16 +290,14 @@ class QAPISchemaArrayType(QAPISchemaType): self.info and self.info.defn_meta) assert not isinstance(self.element_type, QAPISchemaArrayType) + def set_module(self, schema): + self._set_module(schema, self.element_type.info) + @property def ifcond(self): assert self._checked return self.element_type.ifcond - @property - def module(self): - assert self._checked - return self.element_type.module - def is_implicit(self): return True @@ -711,10 +723,11 @@ class QAPISchemaCommand(QAPISchemaEntity): self.ret_type = schema.resolve_type( self._ret_type_name, self.info, "command's 'returns'") if self.name not in self.info.pragma.returns_whitelist: - if not (isinstance(self.ret_type, QAPISchemaObjectType) - or (isinstance(self.ret_type, QAPISchemaArrayType) - and isinstance(self.ret_type.element_type, - QAPISchemaObjectType))): + typ = self.ret_type + if isinstance(typ, QAPISchemaArrayType): + typ = self.ret_type.element_type + assert typ + if not isinstance(typ, QAPISchemaObjectType): raise QAPISemError( self.info, "command's 'returns' cannot take %s" @@ -782,6 +795,10 @@ class QAPISchema(object): self.docs = parser.docs self._entity_list = [] self._entity_dict = {} + self._module_dict = {} + self._schema_dir = os.path.dirname(fname) + self._make_module(None) # built-ins + self._make_module(fname) self._predefining = True self._def_predefineds() self._predefining = False @@ -825,14 +842,26 @@ class QAPISchema(object): info, "%s uses unknown type '%s'" % (what, name)) return typ + def _module_name(self, fname): + if fname is None: + return None + return os.path.relpath(fname, self._schema_dir) + + def _make_module(self, fname): + name = self._module_name(fname) + if not name in self._module_dict: + self._module_dict[name] = QAPISchemaModule(name) + return self._module_dict[name] + + def module_by_fname(self, fname): + name = self._module_name(fname) + assert name in self._module_dict + return self._module_dict[name] + def _def_include(self, expr, info, doc): include = expr['include'] assert doc is None - main_info = info - while main_info.parent: - main_info = main_info.parent - fname = os.path.relpath(include, os.path.dirname(main_info.fname)) - self._def_entity(QAPISchemaInclude(fname, info)) + self._def_entity(QAPISchemaInclude(self._make_module(include), info)) def _def_builtin_type(self, name, json_type, c_type): self._def_entity(QAPISchemaBuiltinType(name, json_type, c_type)) @@ -1064,15 +1093,12 @@ class QAPISchema(object): ent.check(self) ent.connect_doc() ent.check_doc() + for ent in self._entity_list: + ent.set_module(self) def visit(self, visitor): visitor.visit_begin(self) module = None - visitor.visit_module(module) - for entity in self._entity_list: - if visitor.visit_needed(entity): - if entity.module != module: - module = entity.module - visitor.visit_module(module) - entity.visit(visitor) + for mod in self._module_dict.values(): + mod.visit(visitor) visitor.visit_end() diff --git a/scripts/qapi/types.py b/scripts/qapi/types.py index d8751daa04..99dcaf7074 100644 --- a/scripts/qapi/types.py +++ b/scripts/qapi/types.py @@ -243,8 +243,9 @@ class QAPISchemaGenTypeVisitor(QAPISchemaModularCVisitor): def __init__(self, prefix): QAPISchemaModularCVisitor.__init__( self, prefix, 'qapi-types', ' * Schema-defined QAPI types', - __doc__) - self._add_system_module(None, ' * Built-in QAPI types') + ' * Built-in QAPI types', __doc__) + + def _begin_system_module(self, name): self._genc.preamble_add(mcgen(''' #include "qemu/osdep.h" #include "qapi/dealloc-visitor.h" diff --git a/scripts/qapi/visit.py b/scripts/qapi/visit.py index c72f2bc5c0..4efce62b0c 100644 --- a/scripts/qapi/visit.py +++ b/scripts/qapi/visit.py @@ -285,8 +285,9 @@ class QAPISchemaGenVisitVisitor(QAPISchemaModularCVisitor): def __init__(self, prefix): QAPISchemaModularCVisitor.__init__( self, prefix, 'qapi-visit', ' * Schema-defined QAPI visitors', - __doc__) - self._add_system_module(None, ' * Built-in QAPI visitors') + ' * Built-in QAPI visitors', __doc__) + + def _begin_system_module(self, name): self._genc.preamble_add(mcgen(''' #include "qemu/osdep.h" #include "qapi/error.h" @@ -296,8 +297,7 @@ class QAPISchemaGenVisitVisitor(QAPISchemaModularCVisitor): #include "qapi/visitor.h" #include "qapi/qapi-builtin-types.h" -''', - prefix=prefix)) +''')) def _begin_user_module(self, name): types = self._module_basename('qapi-types', name) diff --git a/tests/.gitignore b/tests/.gitignore index f9c0170881..7306866f21 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -12,6 +12,7 @@ test-* !test-*.c !docker/test-* test-qapi-commands.[ch] +test-qapi-init-commands.[ch] include/test-qapi-commands-sub-module.[ch] test-qapi-commands-sub-sub-module.[ch] test-qapi-emit-events.[ch] diff --git a/tests/Makefile.include b/tests/Makefile.include index 1ae14a8b15..c6827ce8c2 100644 --- a/tests/Makefile.include +++ b/tests/Makefile.include @@ -350,8 +350,10 @@ generated-files-y += tests/test-qapi-visit.h generated-files-y += tests/include/test-qapi-visit-sub-module.h generated-files-y += tests/test-qapi-visit-sub-sub-module.h generated-files-y += tests/test-qapi-commands.h +generated-files-y += tests/test-qapi-init-commands.h generated-files-y += tests/include/test-qapi-commands-sub-module.h generated-files-y += tests/test-qapi-commands-sub-sub-module.h +generated-files-y += tests/test-qapi-emit-events.h generated-files-y += tests/test-qapi-events.h generated-files-y += tests/include/test-qapi-events-sub-module.h generated-files-y += tests/test-qapi-events-sub-sub-module.h @@ -465,7 +467,10 @@ tests/include/test-qapi-commands-sub-module.h \ tests/include/test-qapi-commands-sub-module.c \ tests/test-qapi-commands-sub-sub-module.h \ tests/test-qapi-commands-sub-sub-module.c \ +tests/test-qapi-emit-events.c tests/test-qapi-emit-events.h \ tests/test-qapi-events.c tests/test-qapi-events.h \ +tests/test-qapi-init-commands.c \ +tests/test-qapi-init-commands.h \ tests/include/test-qapi-events-sub-module.c \ tests/include/test-qapi-events-sub-module.h \ tests/test-qapi-events-sub-sub-module.c \ @@ -505,11 +510,11 @@ tests/qtest/dbus-vmstate-test.o: tests/qtest/dbus-vmstate1.h tests/test-string-output-visitor$(EXESUF): tests/test-string-output-visitor.o $(test-qapi-obj-y) tests/test-string-input-visitor$(EXESUF): tests/test-string-input-visitor.o $(test-qapi-obj-y) -tests/test-qmp-event$(EXESUF): tests/test-qmp-event.o $(test-qapi-obj-y) tests/test-qapi-events.o +tests/test-qmp-event$(EXESUF): tests/test-qmp-event.o $(test-qapi-obj-y) tests/test-qapi-emit-events.o tests/test-qapi-events.o tests/test-qobject-output-visitor$(EXESUF): tests/test-qobject-output-visitor.o $(test-qapi-obj-y) tests/test-clone-visitor$(EXESUF): tests/test-clone-visitor.o $(test-qapi-obj-y) tests/test-qobject-input-visitor$(EXESUF): tests/test-qobject-input-visitor.o $(test-qapi-obj-y) -tests/test-qmp-cmds$(EXESUF): tests/test-qmp-cmds.o tests/test-qapi-commands.o $(test-qapi-obj-y) +tests/test-qmp-cmds$(EXESUF): tests/test-qmp-cmds.o tests/test-qapi-commands.o tests/test-qapi-init-commands.o $(test-qapi-obj-y) tests/test-visitor-serialization$(EXESUF): tests/test-visitor-serialization.o $(test-qapi-obj-y) tests/test-opts-visitor$(EXESUF): tests/test-opts-visitor.o $(test-qapi-obj-y) diff --git a/tests/qapi-schema/empty.out b/tests/qapi-schema/empty.out index 5b53d00702..69666c39ad 100644 --- a/tests/qapi-schema/empty.out +++ b/tests/qapi-schema/empty.out @@ -9,3 +9,4 @@ enum QType member qdict member qlist member qbool +module empty.json diff --git a/tests/qapi-schema/include-repetition.out b/tests/qapi-schema/include-repetition.out index 5423983239..0b654ddebb 100644 --- a/tests/qapi-schema/include-repetition.out +++ b/tests/qapi-schema/include-repetition.out @@ -11,15 +11,13 @@ enum QType member qbool module include-repetition.json include comments.json +include include-repetition-sub.json +include comments.json module comments.json enum Status member good member bad member ugly -module include-repetition.json -include include-repetition-sub.json module include-repetition-sub.json include comments.json include comments.json -module include-repetition.json -include comments.json diff --git a/tests/qapi-schema/qapi-schema-test.out b/tests/qapi-schema/qapi-schema-test.out index 3660e75a48..9bd3c4a490 100644 --- a/tests/qapi-schema/qapi-schema-test.out +++ b/tests/qapi-schema/qapi-schema-test.out @@ -153,9 +153,6 @@ object q_obj_sizeList-wrapper member data: sizeList optional=False object q_obj_anyList-wrapper member data: anyList optional=False -module sub-sub-module.json -array StatusList Status -module qapi-schema-test.json object q_obj_StatusList-wrapper member data: StatusList optional=False enum UserDefListUnionKind @@ -193,17 +190,6 @@ object UserDefListUnion case any: q_obj_anyList-wrapper case user: q_obj_StatusList-wrapper include include/sub-module.json -module include/sub-module.json -include sub-sub-module.json -module sub-sub-module.json -enum Status - member good - member bad - member ugly -module include/sub-module.json -object SecondArrayRef - member s: StatusList optional=False -module qapi-schema-test.json command user_def_cmd None -> None gen=True success_response=True boxed=False oob=False preconfig=False object q_obj_user_def_cmd1-arg @@ -435,3 +421,13 @@ command test-command-cond-features3 None -> None gen=True success_response=True boxed=False oob=False preconfig=False feature feature1 if ['defined(TEST_IF_COND_1)', 'defined(TEST_IF_COND_2)'] +module include/sub-module.json +include sub-sub-module.json +object SecondArrayRef + member s: StatusList optional=False +module sub-sub-module.json +array StatusList Status +enum Status + member good + member bad + member ugly diff --git a/tests/test-qmp-cmds.c b/tests/test-qmp-cmds.c index 27b0afe55a..79507d9e54 100644 --- a/tests/test-qmp-cmds.c +++ b/tests/test-qmp-cmds.c @@ -7,6 +7,7 @@ #include "tests/test-qapi-types.h" #include "tests/test-qapi-visit.h" #include "test-qapi-commands.h" +#include "test-qapi-init-commands.h" static QmpCommandList qmp_commands;