Révision | cfe63e46be0a1f8a7fd2fd5547222f8344a43279 (tree) |
---|---|
l'heure | 2022-01-28 00:45:13 |
Auteur | Peter Maydell <peter.maydell@lina...> |
Commiter | Peter Maydell |
Merge remote-tracking branch 'remotes/armbru/tags/pull-qapi-2022-01-27-v2' into staging
QAPI patches patches for 2022-01-27
# gpg: Signature made Thu 27 Jan 2022 14:19:51 GMT
# gpg: using RSA key 354BC8B3D7EB2A6B68674E5F3870B400EB918653
# gpg: issuer "armbru@redhat.com"
# gpg: Good signature from "Markus Armbruster <armbru@redhat.com>" [full]
# gpg: aka "Markus Armbruster <armbru@pond.sub.org>" [full]
# Primary key fingerprint: 354B C8B3 D7EB 2A6B 6867 4E5F 3870 B400 EB91 8653
* remotes/armbru/tags/pull-qapi-2022-01-27-v2:
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
@@ -1630,6 +1630,9 @@ The following files are generated: | ||
1630 | 1630 | ``$(prefix)qapi-commands.h`` |
1631 | 1631 | Function prototypes for the QMP commands specified in the schema |
1632 | 1632 | |
1633 | + ``$(prefix)qapi-commands.trace-events`` | |
1634 | + Trace event declarations, see :ref:`tracing`. | |
1635 | + | |
1633 | 1636 | ``$(prefix)qapi-init-commands.h`` |
1634 | 1637 | Command initialization prototype |
1635 | 1638 |
@@ -1650,6 +1653,13 @@ Example:: | ||
1650 | 1653 | void qmp_marshal_my_command(QDict *args, QObject **ret, Error **errp); |
1651 | 1654 | |
1652 | 1655 | #endif /* EXAMPLE_QAPI_COMMANDS_H */ |
1656 | + | |
1657 | + $ cat qapi-generated/example-qapi-commands.trace-events | |
1658 | + # AUTOMATICALLY GENERATED, DO NOT MODIFY | |
1659 | + | |
1660 | + qmp_enter_my_command(const char *json) "%s" | |
1661 | + qmp_exit_my_command(const char *result, bool succeeded) "%s %d" | |
1662 | + | |
1653 | 1663 | $ cat qapi-generated/example-qapi-commands.c |
1654 | 1664 | [Uninteresting stuff omitted...] |
1655 | 1665 |
@@ -1689,14 +1699,27 @@ Example:: | ||
1689 | 1699 | goto out; |
1690 | 1700 | } |
1691 | 1701 | |
1702 | + if (trace_event_get_state_backends(TRACE_QMP_ENTER_MY_COMMAND)) { | |
1703 | + g_autoptr(GString) req_json = qobject_to_json(QOBJECT(args)); | |
1704 | + | |
1705 | + trace_qmp_enter_my_command(req_json->str); | |
1706 | + } | |
1707 | + | |
1692 | 1708 | retval = qmp_my_command(arg.arg1, &err); |
1693 | - error_propagate(errp, err); | |
1694 | 1709 | if (err) { |
1710 | + trace_qmp_exit_my_command(error_get_pretty(err), false); | |
1711 | + error_propagate(errp, err); | |
1695 | 1712 | goto out; |
1696 | 1713 | } |
1697 | 1714 | |
1698 | 1715 | qmp_marshal_output_UserDefOne(retval, ret, errp); |
1699 | 1716 | |
1717 | + if (trace_event_get_state_backends(TRACE_QMP_EXIT_MY_COMMAND)) { | |
1718 | + g_autoptr(GString) ret_json = qobject_to_json(*ret); | |
1719 | + | |
1720 | + trace_qmp_exit_my_command(ret_json->str, true); | |
1721 | + } | |
1722 | + | |
1700 | 1723 | out: |
1701 | 1724 | visit_free(v); |
1702 | 1725 | v = qapi_dealloc_visitor_new(); |
@@ -1,3 +1,5 @@ | ||
1 | +.. _tracing: | |
2 | + | |
1 | 3 | ======= |
2 | 4 | Tracing |
3 | 5 | ======= |
@@ -41,6 +41,7 @@ qemu_icondir = get_option('datadir') / 'icons' | ||
41 | 41 | |
42 | 42 | config_host_data = configuration_data() |
43 | 43 | genh = [] |
44 | +qapi_trace_events = [] | |
44 | 45 | |
45 | 46 | target_dirs = config_host['TARGET_DIRS'].split() |
46 | 47 | have_linux_user = false |
@@ -2557,6 +2558,8 @@ if 'CONFIG_VHOST_USER' in config_host | ||
2557 | 2558 | vhost_user = libvhost_user.get_variable('vhost_user_dep') |
2558 | 2559 | endif |
2559 | 2560 | |
2561 | +# NOTE: the trace/ subdirectory needs the qapi_trace_events variable | |
2562 | +# that is filled in by qapi/. | |
2560 | 2563 | subdir('qapi') |
2561 | 2564 | subdir('qobject') |
2562 | 2565 | subdir('stubs') |
@@ -1,4 +1,5 @@ | ||
1 | 1 | # -*- mode: python -*- |
2 | +# vim: filetype=python | |
2 | 3 | # |
3 | 4 | # Copyright (C) 2015-2019 Zoltán Kővágó <DirtY.iCE.hu@gmail.com> |
4 | 5 | # |
@@ -1,4 +1,5 @@ | ||
1 | 1 | # -*- Mode: Python -*- |
2 | +# vim: filetype=python | |
2 | 3 | |
3 | 4 | ## |
4 | 5 | # = Compatibility policy |
@@ -114,6 +114,7 @@ foreach module : qapi_all_modules | ||
114 | 114 | 'qapi-events-@0@.h'.format(module), |
115 | 115 | 'qapi-commands-@0@.c'.format(module), |
116 | 116 | 'qapi-commands-@0@.h'.format(module), |
117 | + 'qapi-commands-@0@.trace-events'.format(module), | |
117 | 118 | ] |
118 | 119 | endif |
119 | 120 | if module.endswith('-target') |
@@ -137,6 +138,9 @@ foreach output : qapi_util_outputs | ||
137 | 138 | if output.endswith('.h') |
138 | 139 | genh += qapi_files[i] |
139 | 140 | endif |
141 | + if output.endswith('.trace-events') | |
142 | + qapi_trace_events += qapi_files[i] | |
143 | + endif | |
140 | 144 | util_ss.add(qapi_files[i]) |
141 | 145 | i = i + 1 |
142 | 146 | endforeach |
@@ -145,6 +149,9 @@ foreach output : qapi_specific_outputs + qapi_nonmodule_outputs | ||
145 | 149 | if output.endswith('.h') |
146 | 150 | genh += qapi_files[i] |
147 | 151 | endif |
152 | + if output.endswith('.trace-events') | |
153 | + qapi_trace_events += qapi_files[i] | |
154 | + endif | |
148 | 155 | specific_ss.add(when: 'CONFIG_SOFTMMU', if_true: qapi_files[i]) |
149 | 156 | i = i + 1 |
150 | 157 | endforeach |
@@ -1,4 +1,5 @@ | ||
1 | 1 | # -*- Mode: Python -*- |
2 | +# vim: filetype=python | |
2 | 3 | # |
3 | 4 | |
4 | 5 | ## |
@@ -1,4 +1,5 @@ | ||
1 | 1 | # -*- mode: python -*- |
2 | +# vim: filetype=python | |
2 | 3 | # |
3 | 4 | # Copyright (C) 2011-2016 Lluís Vilanova <vilanova@ac.upc.edu> |
4 | 5 | # |
@@ -15,10 +15,18 @@ qga_qapi_outputs = [ | ||
15 | 15 | 'qga-qapi-visit.h', |
16 | 16 | ] |
17 | 17 | |
18 | +# Problem: to generate trace events, we'd have to add the .trace-events | |
19 | +# file to qapi_trace_events like we do in qapi/meson.build. Since | |
20 | +# qapi_trace_events is used by trace/meson.build, we'd have to move | |
21 | +# subdir('qga') above subdir('trace') in the top-level meson.build. | |
22 | +# Can't, because it would break the dependency of qga on qemuutil (which | |
23 | +# depends on trace_ss). Not worth solving now; simply suppress trace | |
24 | +# event generation instead. | |
18 | 25 | qga_qapi_files = custom_target('QGA QAPI files', |
19 | 26 | output: qga_qapi_outputs, |
20 | 27 | input: 'qapi-schema.json', |
21 | - command: [ qapi_gen, '-o', 'qga', '-p', 'qga-', '@INPUT0@' ], | |
28 | + command: [ qapi_gen, '-o', 'qga', '-p', 'qga-', '@INPUT0@', | |
29 | + '--suppress-tracing' ], | |
22 | 30 | depend_files: qapi_gen_depends) |
23 | 31 | |
24 | 32 | qga_ss = ss.source_set() |
@@ -53,7 +53,8 @@ def gen_command_decl(name: str, | ||
53 | 53 | def gen_call(name: str, |
54 | 54 | arg_type: Optional[QAPISchemaObjectType], |
55 | 55 | boxed: bool, |
56 | - ret_type: Optional[QAPISchemaType]) -> str: | |
56 | + ret_type: Optional[QAPISchemaType], | |
57 | + gen_tracing: bool) -> str: | |
57 | 58 | ret = '' |
58 | 59 | |
59 | 60 | argstr = '' |
@@ -71,21 +72,67 @@ def gen_call(name: str, | ||
71 | 72 | if ret_type: |
72 | 73 | lhs = 'retval = ' |
73 | 74 | |
74 | - ret = mcgen(''' | |
75 | + name = c_name(name) | |
76 | + upper = name.upper() | |
75 | 77 | |
76 | - %(lhs)sqmp_%(c_name)s(%(args)s&err); | |
77 | - error_propagate(errp, err); | |
78 | -''', | |
79 | - c_name=c_name(name), args=argstr, lhs=lhs) | |
80 | - if ret_type: | |
78 | + if gen_tracing: | |
81 | 79 | ret += mcgen(''' |
80 | + | |
81 | + if (trace_event_get_state_backends(TRACE_QMP_ENTER_%(upper)s)) { | |
82 | + g_autoptr(GString) req_json = qobject_to_json(QOBJECT(args)); | |
83 | + | |
84 | + trace_qmp_enter_%(name)s(req_json->str); | |
85 | + } | |
86 | + ''', | |
87 | + upper=upper, name=name) | |
88 | + | |
89 | + ret += mcgen(''' | |
90 | + | |
91 | + %(lhs)sqmp_%(name)s(%(args)s&err); | |
92 | +''', | |
93 | + name=name, args=argstr, lhs=lhs) | |
94 | + | |
95 | + ret += mcgen(''' | |
82 | 96 | if (err) { |
97 | +''') | |
98 | + | |
99 | + if gen_tracing: | |
100 | + ret += mcgen(''' | |
101 | + trace_qmp_exit_%(name)s(error_get_pretty(err), false); | |
102 | +''', | |
103 | + name=name) | |
104 | + | |
105 | + ret += mcgen(''' | |
106 | + error_propagate(errp, err); | |
83 | 107 | goto out; |
84 | 108 | } |
109 | +''') | |
110 | + | |
111 | + if ret_type: | |
112 | + ret += mcgen(''' | |
85 | 113 | |
86 | 114 | qmp_marshal_output_%(c_name)s(retval, ret, errp); |
87 | 115 | ''', |
88 | 116 | c_name=ret_type.c_name()) |
117 | + | |
118 | + if gen_tracing: | |
119 | + if ret_type: | |
120 | + ret += mcgen(''' | |
121 | + | |
122 | + if (trace_event_get_state_backends(TRACE_QMP_EXIT_%(upper)s)) { | |
123 | + g_autoptr(GString) ret_json = qobject_to_json(*ret); | |
124 | + | |
125 | + trace_qmp_exit_%(name)s(ret_json->str, true); | |
126 | + } | |
127 | + ''', | |
128 | + upper=upper, name=name) | |
129 | + else: | |
130 | + ret += mcgen(''' | |
131 | + | |
132 | + trace_qmp_exit_%(name)s("{}", true); | |
133 | + ''', | |
134 | + name=name) | |
135 | + | |
89 | 136 | return ret |
90 | 137 | |
91 | 138 |
@@ -122,10 +169,19 @@ def gen_marshal_decl(name: str) -> str: | ||
122 | 169 | proto=build_marshal_proto(name)) |
123 | 170 | |
124 | 171 | |
172 | +def gen_trace(name: str) -> str: | |
173 | + return mcgen(''' | |
174 | +qmp_enter_%(name)s(const char *json) "%%s" | |
175 | +qmp_exit_%(name)s(const char *result, bool succeeded) "%%s %%d" | |
176 | +''', | |
177 | + name=c_name(name)) | |
178 | + | |
179 | + | |
125 | 180 | def gen_marshal(name: str, |
126 | 181 | arg_type: Optional[QAPISchemaObjectType], |
127 | 182 | boxed: bool, |
128 | - ret_type: Optional[QAPISchemaType]) -> str: | |
183 | + ret_type: Optional[QAPISchemaType], | |
184 | + gen_tracing: bool) -> str: | |
129 | 185 | have_args = boxed or (arg_type and not arg_type.is_empty()) |
130 | 186 | if have_args: |
131 | 187 | assert arg_type is not None |
@@ -180,7 +236,7 @@ def gen_marshal(name: str, | ||
180 | 236 | } |
181 | 237 | ''') |
182 | 238 | |
183 | - ret += gen_call(name, arg_type, boxed, ret_type) | |
239 | + ret += gen_call(name, arg_type, boxed, ret_type, gen_tracing) | |
184 | 240 | |
185 | 241 | ret += mcgen(''' |
186 | 242 |
@@ -238,11 +294,13 @@ def gen_register_command(name: str, | ||
238 | 294 | |
239 | 295 | |
240 | 296 | class QAPISchemaGenCommandVisitor(QAPISchemaModularCVisitor): |
241 | - def __init__(self, prefix: str): | |
297 | + def __init__(self, prefix: str, gen_tracing: bool): | |
242 | 298 | super().__init__( |
243 | 299 | prefix, 'qapi-commands', |
244 | - ' * Schema-defined QAPI/QMP commands', None, __doc__) | |
300 | + ' * Schema-defined QAPI/QMP commands', None, __doc__, | |
301 | + gen_tracing=gen_tracing) | |
245 | 302 | self._visited_ret_types: Dict[QAPIGenC, Set[QAPISchemaType]] = {} |
303 | + self._gen_tracing = gen_tracing | |
246 | 304 | |
247 | 305 | def _begin_user_module(self, name: str) -> None: |
248 | 306 | self._visited_ret_types[self._genc] = set() |
@@ -261,6 +319,16 @@ class QAPISchemaGenCommandVisitor(QAPISchemaModularCVisitor): | ||
261 | 319 | |
262 | 320 | ''', |
263 | 321 | commands=commands, visit=visit)) |
322 | + | |
323 | + if self._gen_tracing and commands != 'qapi-commands': | |
324 | + self._genc.add(mcgen(''' | |
325 | +#include "qapi/qmp/qjson.h" | |
326 | +#include "trace/trace-%(nm)s_trace_events.h" | |
327 | +''', | |
328 | + nm=c_name(commands, protect=False))) | |
329 | + # We use c_name(commands, protect=False) to turn '-' into '_', to | |
330 | + # match .underscorify() in trace/meson.build | |
331 | + | |
264 | 332 | self._genh.add(mcgen(''' |
265 | 333 | #include "%(types)s.h" |
266 | 334 |
@@ -322,7 +390,10 @@ void %(c_prefix)sqmp_init_marshal(QmpCommandList *cmds) | ||
322 | 390 | with ifcontext(ifcond, self._genh, self._genc): |
323 | 391 | self._genh.add(gen_command_decl(name, arg_type, boxed, ret_type)) |
324 | 392 | self._genh.add(gen_marshal_decl(name)) |
325 | - self._genc.add(gen_marshal(name, arg_type, boxed, ret_type)) | |
393 | + self._genc.add(gen_marshal(name, arg_type, boxed, ret_type, | |
394 | + self._gen_tracing)) | |
395 | + if self._gen_tracing: | |
396 | + self._gen_trace_events.add(gen_trace(name)) | |
326 | 397 | with self._temp_module('./init'): |
327 | 398 | with ifcontext(ifcond, self._genh, self._genc): |
328 | 399 | self._genc.add(gen_register_command( |
@@ -332,7 +403,8 @@ void %(c_prefix)sqmp_init_marshal(QmpCommandList *cmds) | ||
332 | 403 | |
333 | 404 | def gen_commands(schema: QAPISchema, |
334 | 405 | output_dir: str, |
335 | - prefix: str) -> None: | |
336 | - vis = QAPISchemaGenCommandVisitor(prefix) | |
406 | + prefix: str, | |
407 | + gen_tracing: bool) -> None: | |
408 | + vis = QAPISchemaGenCommandVisitor(prefix, gen_tracing) | |
337 | 409 | schema.visit(vis) |
338 | 410 | vis.write(output_dir) |
@@ -192,6 +192,11 @@ class QAPIGenH(QAPIGenC): | ||
192 | 192 | return guardend(self.fname) |
193 | 193 | |
194 | 194 | |
195 | +class QAPIGenTrace(QAPIGen): | |
196 | + def _top(self) -> str: | |
197 | + return super()._top() + '# AUTOMATICALLY GENERATED, DO NOT MODIFY\n\n' | |
198 | + | |
199 | + | |
195 | 200 | @contextmanager |
196 | 201 | def ifcontext(ifcond: QAPISchemaIfCond, *args: QAPIGenCCode) -> Iterator[None]: |
197 | 202 | """ |
@@ -244,15 +249,18 @@ class QAPISchemaModularCVisitor(QAPISchemaVisitor): | ||
244 | 249 | what: str, |
245 | 250 | user_blurb: str, |
246 | 251 | builtin_blurb: Optional[str], |
247 | - pydoc: str): | |
252 | + pydoc: str, | |
253 | + gen_tracing: bool = False): | |
248 | 254 | self._prefix = prefix |
249 | 255 | self._what = what |
250 | 256 | self._user_blurb = user_blurb |
251 | 257 | self._builtin_blurb = builtin_blurb |
252 | 258 | self._pydoc = pydoc |
253 | 259 | self._current_module: Optional[str] = None |
254 | - self._module: Dict[str, Tuple[QAPIGenC, QAPIGenH]] = {} | |
260 | + self._module: Dict[str, Tuple[QAPIGenC, QAPIGenH, | |
261 | + Optional[QAPIGenTrace]]] = {} | |
255 | 262 | self._main_module: Optional[str] = None |
263 | + self._gen_tracing = gen_tracing | |
256 | 264 | |
257 | 265 | @property |
258 | 266 | def _genc(self) -> QAPIGenC: |
@@ -264,6 +272,14 @@ class QAPISchemaModularCVisitor(QAPISchemaVisitor): | ||
264 | 272 | assert self._current_module is not None |
265 | 273 | return self._module[self._current_module][1] |
266 | 274 | |
275 | + @property | |
276 | + def _gen_trace_events(self) -> QAPIGenTrace: | |
277 | + assert self._gen_tracing | |
278 | + assert self._current_module is not None | |
279 | + gent = self._module[self._current_module][2] | |
280 | + assert gent is not None | |
281 | + return gent | |
282 | + | |
267 | 283 | @staticmethod |
268 | 284 | def _module_dirname(name: str) -> str: |
269 | 285 | if QAPISchemaModule.is_user_module(name): |
@@ -293,7 +309,12 @@ class QAPISchemaModularCVisitor(QAPISchemaVisitor): | ||
293 | 309 | basename = self._module_filename(self._what, name) |
294 | 310 | genc = QAPIGenC(basename + '.c', blurb, self._pydoc) |
295 | 311 | genh = QAPIGenH(basename + '.h', blurb, self._pydoc) |
296 | - self._module[name] = (genc, genh) | |
312 | + | |
313 | + gent: Optional[QAPIGenTrace] = None | |
314 | + if self._gen_tracing: | |
315 | + gent = QAPIGenTrace(basename + '.trace-events') | |
316 | + | |
317 | + self._module[name] = (genc, genh, gent) | |
297 | 318 | self._current_module = name |
298 | 319 | |
299 | 320 | @contextmanager |
@@ -304,11 +325,13 @@ class QAPISchemaModularCVisitor(QAPISchemaVisitor): | ||
304 | 325 | self._current_module = old_module |
305 | 326 | |
306 | 327 | def write(self, output_dir: str, opt_builtins: bool = False) -> None: |
307 | - for name, (genc, genh) in self._module.items(): | |
328 | + for name, (genc, genh, gent) in self._module.items(): | |
308 | 329 | if QAPISchemaModule.is_builtin_module(name) and not opt_builtins: |
309 | 330 | continue |
310 | 331 | genc.write(output_dir) |
311 | 332 | genh.write(output_dir) |
333 | + if gent is not None: | |
334 | + gent.write(output_dir) | |
312 | 335 | |
313 | 336 | def _begin_builtin_module(self) -> None: |
314 | 337 | pass |
@@ -32,7 +32,8 @@ def generate(schema_file: str, | ||
32 | 32 | output_dir: str, |
33 | 33 | prefix: str, |
34 | 34 | unmask: bool = False, |
35 | - builtins: bool = False) -> None: | |
35 | + builtins: bool = False, | |
36 | + gen_tracing: bool = False) -> None: | |
36 | 37 | """ |
37 | 38 | Generate C code for the given schema into the target directory. |
38 | 39 |
@@ -49,7 +50,7 @@ def generate(schema_file: str, | ||
49 | 50 | schema = QAPISchema(schema_file) |
50 | 51 | gen_types(schema, output_dir, prefix, builtins) |
51 | 52 | gen_visit(schema, output_dir, prefix, builtins) |
52 | - gen_commands(schema, output_dir, prefix) | |
53 | + gen_commands(schema, output_dir, prefix, gen_tracing) | |
53 | 54 | gen_events(schema, output_dir, prefix) |
54 | 55 | gen_introspect(schema, output_dir, prefix, unmask) |
55 | 56 |
@@ -74,6 +75,12 @@ def main() -> int: | ||
74 | 75 | parser.add_argument('-u', '--unmask-non-abi-names', action='store_true', |
75 | 76 | dest='unmask', |
76 | 77 | help="expose non-ABI names in introspection") |
78 | + | |
79 | + # Option --suppress-tracing exists so we can avoid solving build system | |
80 | + # problems. TODO Drop it when we no longer need it. | |
81 | + parser.add_argument('--suppress-tracing', action='store_true', | |
82 | + help="suppress adding trace events to qmp marshals") | |
83 | + | |
77 | 84 | parser.add_argument('schema', action='store') |
78 | 85 | args = parser.parse_args() |
79 | 86 |
@@ -88,7 +95,8 @@ def main() -> int: | ||
88 | 95 | output_dir=args.output_dir, |
89 | 96 | prefix=args.prefix, |
90 | 97 | unmask=args.unmask, |
91 | - builtins=args.builtins) | |
98 | + builtins=args.builtins, | |
99 | + gen_tracing=not args.suppress_tracing) | |
92 | 100 | except QAPIError as err: |
93 | 101 | print(f"{sys.argv[0]}: {str(err)}", file=sys.stderr) |
94 | 102 | return 1 |
@@ -31,13 +31,21 @@ test_qapi_outputs = [ | ||
31 | 31 | 'test-qapi-visit.h', |
32 | 32 | ] |
33 | 33 | |
34 | +# Problem: to generate trace events, we'd have to add the .trace-events | |
35 | +# file to qapi_trace_events like we do in qapi/meson.build. Since | |
36 | +# qapi_trace_events is used by trace/meson.build, we'd have to move | |
37 | +# subdir('tests') above subdir('trace') in the top-level meson.build. | |
38 | +# Can't, because it would break the dependency of qga on qemuutil (which | |
39 | +# depends on trace_ss). Not worth solving now; simply suppress trace | |
40 | +# event generation instead. | |
34 | 41 | test_qapi_files = custom_target('Test QAPI files', |
35 | 42 | output: test_qapi_outputs, |
36 | 43 | input: files('qapi-schema/qapi-schema-test.json', |
37 | 44 | 'qapi-schema/include/sub-module.json', |
38 | 45 | 'qapi-schema/sub-sub-module.json'), |
39 | 46 | command: [ qapi_gen, '-o', meson.current_build_dir(), |
40 | - '-b', '-p', 'test-', '@INPUT0@' ], | |
47 | + '-b', '-p', 'test-', '@INPUT0@', | |
48 | + '--suppress-tracing' ], | |
41 | 49 | depend_files: qapi_gen_depends) |
42 | 50 | |
43 | 51 | # meson doesn't like generated output in other directories |
@@ -2,10 +2,15 @@ | ||
2 | 2 | specific_ss.add(files('control-target.c')) |
3 | 3 | |
4 | 4 | trace_events_files = [] |
5 | -foreach dir : [ '.' ] + trace_events_subdirs | |
6 | - trace_events_file = meson.project_source_root() / dir / 'trace-events' | |
5 | +foreach item : [ '.' ] + trace_events_subdirs + qapi_trace_events | |
6 | + if item in qapi_trace_events | |
7 | + trace_events_file = item | |
8 | + group_name = item.full_path().split('/')[-1].underscorify() | |
9 | + else | |
10 | + trace_events_file = meson.project_source_root() / item / 'trace-events' | |
11 | + group_name = item == '.' ? 'root' : item.underscorify() | |
12 | + endif | |
7 | 13 | trace_events_files += [ trace_events_file ] |
8 | - group_name = dir == '.' ? 'root' : dir.underscorify() | |
9 | 14 | group = '--group=' + group_name |
10 | 15 | fmt = '@0@-' + group_name + '.@1@' |
11 | 16 |