]> git.proxmox.com Git - mirror_qemu.git/blob - meson.build
test/docker/dockerfiles: Add missing packages for acceptance tests
[mirror_qemu.git] / meson.build
1 project('qemu', ['c'], meson_version: '>=0.55.0',
2 default_options: ['warning_level=1', 'c_std=gnu99', 'cpp_std=gnu++11',
3 'b_colorout=auto'],
4 version: run_command('head', meson.source_root() / 'VERSION').stdout().strip())
5
6 not_found = dependency('', required: false)
7 if meson.version().version_compare('>=0.56.0')
8 keyval = import('keyval')
9 else
10 keyval = import('unstable-keyval')
11 endif
12 ss = import('sourceset')
13 fs = import('fs')
14
15 sh = find_program('sh')
16 cc = meson.get_compiler('c')
17 config_host = keyval.load(meson.current_build_dir() / 'config-host.mak')
18 enable_modules = 'CONFIG_MODULES' in config_host
19 enable_static = 'CONFIG_STATIC' in config_host
20
21 # Temporary directory used for files created while
22 # configure runs. Since it is in the build directory
23 # we can safely blow away any previous version of it
24 # (and we need not jump through hoops to try to delete
25 # it when configure exits.)
26 tmpdir = meson.current_build_dir() / 'meson-private/temp'
27
28 if get_option('qemu_suffix').startswith('/')
29 error('qemu_suffix cannot start with a /')
30 endif
31
32 qemu_datadir = get_option('datadir') / get_option('qemu_suffix')
33 qemu_docdir = get_option('docdir') / get_option('qemu_suffix')
34 config_host_data = configuration_data()
35 genh = []
36
37 target_dirs = config_host['TARGET_DIRS'].split()
38 have_user = false
39 have_system = false
40 foreach target : target_dirs
41 have_user = have_user or target.endswith('-user')
42 have_system = have_system or target.endswith('-softmmu')
43 endforeach
44 have_tools = 'CONFIG_TOOLS' in config_host
45 have_block = have_system or have_tools
46
47 python = import('python').find_installation()
48
49 supported_oses = ['windows', 'freebsd', 'netbsd', 'openbsd', 'darwin', 'sunos', 'linux']
50 supported_cpus = ['ppc', 'ppc64', 's390x', 'riscv32', 'riscv64', 'x86', 'x86_64',
51 'arm', 'aarch64', 'mips', 'mips64', 'sparc', 'sparc64']
52
53 cpu = host_machine.cpu_family()
54 targetos = host_machine.system()
55
56 if cpu in ['x86', 'x86_64']
57 kvm_targets = ['i386-softmmu', 'x86_64-softmmu']
58 elif cpu == 'aarch64'
59 kvm_targets = ['aarch64-softmmu']
60 elif cpu == 's390x'
61 kvm_targets = ['s390x-softmmu']
62 elif cpu in ['ppc', 'ppc64']
63 kvm_targets = ['ppc-softmmu', 'ppc64-softmmu']
64 elif cpu in ['mips', 'mips64']
65 kvm_targets = ['mips-softmmu', 'mipsel-softmmu', 'mips64-softmmu', 'mips64el-softmmu']
66 else
67 kvm_targets = []
68 endif
69
70 accelerator_targets = { 'CONFIG_KVM': kvm_targets }
71 if cpu in ['x86', 'x86_64']
72 accelerator_targets += {
73 'CONFIG_HAX': ['i386-softmmu', 'x86_64-softmmu'],
74 'CONFIG_XEN': ['i386-softmmu', 'x86_64-softmmu'],
75 'CONFIG_HVF': ['x86_64-softmmu'],
76 'CONFIG_WHPX': ['i386-softmmu', 'x86_64-softmmu'],
77 }
78 endif
79
80 ##################
81 # Compiler flags #
82 ##################
83
84 # Specify linker-script with add_project_link_arguments so that it is not placed
85 # within a linker --start-group/--end-group pair
86 if 'CONFIG_FUZZ' in config_host
87 add_project_link_arguments(['-Wl,-T,',
88 (meson.current_source_dir() / 'tests/qtest/fuzz/fork_fuzz.ld')],
89 native: false, language: ['c', 'cpp', 'objc'])
90 endif
91
92 add_project_arguments(config_host['QEMU_CFLAGS'].split(),
93 native: false, language: ['c', 'objc'])
94 add_project_arguments(config_host['QEMU_CXXFLAGS'].split(),
95 native: false, language: 'cpp')
96 add_project_link_arguments(config_host['QEMU_LDFLAGS'].split(),
97 native: false, language: ['c', 'cpp', 'objc'])
98
99 if targetos == 'linux'
100 add_project_arguments('-isystem', meson.current_source_dir() / 'linux-headers',
101 '-isystem', 'linux-headers',
102 language: ['c', 'cpp'])
103 endif
104
105 if 'CONFIG_TCG_INTERPRETER' in config_host
106 tcg_arch = 'tci'
107 elif config_host['ARCH'] == 'sparc64'
108 tcg_arch = 'sparc'
109 elif config_host['ARCH'] == 's390x'
110 tcg_arch = 's390'
111 elif config_host['ARCH'] in ['x86_64', 'x32']
112 tcg_arch = 'i386'
113 elif config_host['ARCH'] == 'ppc64'
114 tcg_arch = 'ppc'
115 elif config_host['ARCH'] in ['riscv32', 'riscv64']
116 tcg_arch = 'riscv'
117 else
118 tcg_arch = config_host['ARCH']
119 endif
120 add_project_arguments('-iquote', meson.current_source_dir() / 'tcg' / tcg_arch,
121 '-iquote', '.',
122 '-iquote', meson.current_source_dir(),
123 '-iquote', meson.current_source_dir() / 'accel/tcg',
124 '-iquote', meson.current_source_dir() / 'include',
125 '-iquote', meson.current_source_dir() / 'disas/libvixl',
126 language: ['c', 'cpp', 'objc'])
127
128 link_language = meson.get_external_property('link_language', 'cpp')
129 if link_language == 'cpp'
130 add_languages('cpp', required: true, native: false)
131 endif
132 if host_machine.system() == 'darwin'
133 add_languages('objc', required: false, native: false)
134 endif
135
136 sparse = find_program('cgcc', required: get_option('sparse'))
137 if sparse.found()
138 run_target('sparse',
139 command: [find_program('scripts/check_sparse.py'),
140 'compile_commands.json', sparse.full_path(), '-Wbitwise',
141 '-Wno-transparent-union', '-Wno-old-initializer',
142 '-Wno-non-pointer-null'])
143 endif
144
145 ###########################################
146 # Target-specific checks and dependencies #
147 ###########################################
148
149 if targetos != 'linux' and get_option('mpath').enabled()
150 error('Multipath is supported only on Linux')
151 endif
152
153 m = cc.find_library('m', required: false)
154 util = cc.find_library('util', required: false)
155 winmm = []
156 socket = []
157 version_res = []
158 coref = []
159 iokit = []
160 emulator_link_args = []
161 cocoa = not_found
162 hvf = not_found
163 if targetos == 'windows'
164 socket = cc.find_library('ws2_32')
165 winmm = cc.find_library('winmm')
166
167 win = import('windows')
168 version_res = win.compile_resources('version.rc',
169 depend_files: files('pc-bios/qemu-nsis.ico'),
170 include_directories: include_directories('.'))
171 elif targetos == 'darwin'
172 coref = dependency('appleframeworks', modules: 'CoreFoundation')
173 iokit = dependency('appleframeworks', modules: 'IOKit')
174 cocoa = dependency('appleframeworks', modules: 'Cocoa', required: get_option('cocoa'))
175 elif targetos == 'sunos'
176 socket = [cc.find_library('socket'),
177 cc.find_library('nsl'),
178 cc.find_library('resolv')]
179 elif targetos == 'haiku'
180 socket = [cc.find_library('posix_error_mapper'),
181 cc.find_library('network'),
182 cc.find_library('bsd')]
183 elif targetos == 'openbsd'
184 if not get_option('tcg').disabled() and target_dirs.length() > 0
185 # Disable OpenBSD W^X if available
186 emulator_link_args = cc.get_supported_link_arguments('-Wl,-z,wxneeded')
187 endif
188 endif
189
190 accelerators = []
191 if not get_option('kvm').disabled() and targetos == 'linux'
192 accelerators += 'CONFIG_KVM'
193 endif
194 if not get_option('xen').disabled() and 'CONFIG_XEN_BACKEND' in config_host
195 accelerators += 'CONFIG_XEN'
196 have_xen_pci_passthrough = not get_option('xen_pci_passthrough').disabled() and targetos == 'linux'
197 else
198 have_xen_pci_passthrough = false
199 endif
200 if not get_option('whpx').disabled() and targetos == 'windows'
201 if get_option('whpx').enabled() and cpu != 'x86_64'
202 error('WHPX requires 64-bit host')
203 elif cc.has_header('WinHvPlatform.h', required: get_option('whpx')) and \
204 cc.has_header('WinHvEmulation.h', required: get_option('whpx'))
205 accelerators += 'CONFIG_WHPX'
206 endif
207 endif
208 if not get_option('hvf').disabled()
209 hvf = dependency('appleframeworks', modules: 'Hypervisor',
210 required: get_option('hvf'))
211 if hvf.found()
212 accelerators += 'CONFIG_HVF'
213 endif
214 endif
215 if not get_option('hax').disabled()
216 if get_option('hax').enabled() or targetos in ['windows', 'darwin', 'netbsd']
217 accelerators += 'CONFIG_HAX'
218 endif
219 endif
220 if not get_option('tcg').disabled()
221 if cpu not in supported_cpus
222 if 'CONFIG_TCG_INTERPRETER' in config_host
223 warning('Unsupported CPU @0@, will use TCG with TCI (experimental)'.format(cpu))
224 else
225 error('Unsupported CPU @0@, try --enable-tcg-interpreter'.format(cpu))
226 endif
227 endif
228 accelerators += 'CONFIG_TCG'
229 config_host += { 'CONFIG_TCG': 'y' }
230 endif
231
232 if 'CONFIG_KVM' not in accelerators and get_option('kvm').enabled()
233 error('KVM not available on this platform')
234 endif
235 if 'CONFIG_HVF' not in accelerators and get_option('hvf').enabled()
236 error('HVF not available on this platform')
237 endif
238 if 'CONFIG_WHPX' not in accelerators and get_option('whpx').enabled()
239 error('WHPX not available on this platform')
240 endif
241 if not have_xen_pci_passthrough and get_option('xen_pci_passthrough').enabled()
242 if 'CONFIG_XEN' in accelerators
243 error('Xen PCI passthrough not available on this platform')
244 else
245 error('Xen PCI passthrough requested but Xen not enabled')
246 endif
247 endif
248 if not cocoa.found() and get_option('cocoa').enabled()
249 error('Cocoa not available on this platform')
250 endif
251
252 ################
253 # Dependencies #
254 ################
255
256 # The path to glib.h is added to all compilation commands. This was
257 # grandfathered in from the QEMU Makefiles.
258 add_project_arguments(config_host['GLIB_CFLAGS'].split(),
259 native: false, language: ['c', 'cpp', 'objc'])
260 glib = declare_dependency(link_args: config_host['GLIB_LIBS'].split())
261 gio = not_found
262 if 'CONFIG_GIO' in config_host
263 gio = declare_dependency(compile_args: config_host['GIO_CFLAGS'].split(),
264 link_args: config_host['GIO_LIBS'].split())
265 endif
266 lttng = not_found
267 if 'CONFIG_TRACE_UST' in config_host
268 lttng = declare_dependency(link_args: config_host['LTTNG_UST_LIBS'].split())
269 endif
270 urcubp = not_found
271 if 'CONFIG_TRACE_UST' in config_host
272 urcubp = declare_dependency(link_args: config_host['URCU_BP_LIBS'].split())
273 endif
274 gcrypt = not_found
275 if 'CONFIG_GCRYPT' in config_host
276 gcrypt = declare_dependency(compile_args: config_host['GCRYPT_CFLAGS'].split(),
277 link_args: config_host['GCRYPT_LIBS'].split())
278 endif
279 nettle = not_found
280 if 'CONFIG_NETTLE' in config_host
281 nettle = declare_dependency(compile_args: config_host['NETTLE_CFLAGS'].split(),
282 link_args: config_host['NETTLE_LIBS'].split())
283 endif
284 gnutls = not_found
285 if 'CONFIG_GNUTLS' in config_host
286 gnutls = declare_dependency(compile_args: config_host['GNUTLS_CFLAGS'].split(),
287 link_args: config_host['GNUTLS_LIBS'].split())
288 endif
289 pixman = not_found
290 if have_system or have_tools
291 pixman = dependency('pixman-1', required: have_system, version:'>=0.21.8',
292 method: 'pkg-config', static: enable_static)
293 endif
294 pam = not_found
295 if 'CONFIG_AUTH_PAM' in config_host
296 pam = cc.find_library('pam')
297 endif
298 libaio = cc.find_library('aio', required: false)
299 zlib = dependency('zlib', required: true, static: enable_static)
300 linux_io_uring = not_found
301 if 'CONFIG_LINUX_IO_URING' in config_host
302 linux_io_uring = declare_dependency(compile_args: config_host['LINUX_IO_URING_CFLAGS'].split(),
303 link_args: config_host['LINUX_IO_URING_LIBS'].split())
304 endif
305 libxml2 = not_found
306 if 'CONFIG_LIBXML2' in config_host
307 libxml2 = declare_dependency(compile_args: config_host['LIBXML2_CFLAGS'].split(),
308 link_args: config_host['LIBXML2_LIBS'].split())
309 endif
310 libnfs = not_found
311 if 'CONFIG_LIBNFS' in config_host
312 libnfs = declare_dependency(link_args: config_host['LIBNFS_LIBS'].split())
313 endif
314 libattr = not_found
315 if 'CONFIG_ATTR' in config_host
316 libattr = declare_dependency(link_args: config_host['LIBATTR_LIBS'].split())
317 endif
318 seccomp = not_found
319 if 'CONFIG_SECCOMP' in config_host
320 seccomp = declare_dependency(compile_args: config_host['SECCOMP_CFLAGS'].split(),
321 link_args: config_host['SECCOMP_LIBS'].split())
322 endif
323 libcap_ng = not_found
324 if 'CONFIG_LIBCAP_NG' in config_host
325 libcap_ng = declare_dependency(link_args: config_host['LIBCAP_NG_LIBS'].split())
326 endif
327 if get_option('xkbcommon').auto() and not have_system and not have_tools
328 xkbcommon = not_found
329 else
330 xkbcommon = dependency('xkbcommon', required: get_option('xkbcommon'),
331 method: 'pkg-config', static: enable_static)
332 endif
333 vde = not_found
334 if config_host.has_key('CONFIG_VDE')
335 vde = declare_dependency(link_args: config_host['VDE_LIBS'].split())
336 endif
337 pulse = not_found
338 if 'CONFIG_LIBPULSE' in config_host
339 pulse = declare_dependency(compile_args: config_host['PULSE_CFLAGS'].split(),
340 link_args: config_host['PULSE_LIBS'].split())
341 endif
342 alsa = not_found
343 if 'CONFIG_ALSA' in config_host
344 alsa = declare_dependency(compile_args: config_host['ALSA_CFLAGS'].split(),
345 link_args: config_host['ALSA_LIBS'].split())
346 endif
347 jack = not_found
348 if 'CONFIG_LIBJACK' in config_host
349 jack = declare_dependency(link_args: config_host['JACK_LIBS'].split())
350 endif
351 spice = not_found
352 spice_headers = not_found
353 if 'CONFIG_SPICE' in config_host
354 spice = declare_dependency(compile_args: config_host['SPICE_CFLAGS'].split(),
355 link_args: config_host['SPICE_LIBS'].split())
356 spice_headers = declare_dependency(compile_args: config_host['SPICE_CFLAGS'].split())
357 endif
358 rt = cc.find_library('rt', required: false)
359 libdl = not_found
360 if 'CONFIG_PLUGIN' in config_host
361 libdl = cc.find_library('dl', required: true)
362 endif
363 libiscsi = not_found
364 if 'CONFIG_LIBISCSI' in config_host
365 libiscsi = declare_dependency(compile_args: config_host['LIBISCSI_CFLAGS'].split(),
366 link_args: config_host['LIBISCSI_LIBS'].split())
367 endif
368 zstd = not_found
369 if 'CONFIG_ZSTD' in config_host
370 zstd = declare_dependency(compile_args: config_host['ZSTD_CFLAGS'].split(),
371 link_args: config_host['ZSTD_LIBS'].split())
372 endif
373 gbm = not_found
374 if 'CONFIG_GBM' in config_host
375 gbm = declare_dependency(compile_args: config_host['GBM_CFLAGS'].split(),
376 link_args: config_host['GBM_LIBS'].split())
377 endif
378 virgl = not_found
379 if 'CONFIG_VIRGL' in config_host
380 virgl = declare_dependency(compile_args: config_host['VIRGL_CFLAGS'].split(),
381 link_args: config_host['VIRGL_LIBS'].split())
382 endif
383 curl = not_found
384 if 'CONFIG_CURL' in config_host
385 curl = declare_dependency(compile_args: config_host['CURL_CFLAGS'].split(),
386 link_args: config_host['CURL_LIBS'].split())
387 endif
388 libudev = not_found
389 if targetos == 'linux' and (have_system or have_tools)
390 libudev = dependency('libudev',
391 required: get_option('libudev'),
392 static: enable_static)
393 endif
394
395 mpathlibs = [libudev]
396 mpathpersist = not_found
397 mpathpersist_new_api = false
398 if targetos == 'linux' and have_tools and not get_option('mpath').disabled()
399 mpath_test_source_new = '''
400 #include <libudev.h>
401 #include <mpath_persist.h>
402 unsigned mpath_mx_alloc_len = 1024;
403 int logsink;
404 static struct config *multipath_conf;
405 extern struct udev *udev;
406 extern struct config *get_multipath_config(void);
407 extern void put_multipath_config(struct config *conf);
408 struct udev *udev;
409 struct config *get_multipath_config(void) { return multipath_conf; }
410 void put_multipath_config(struct config *conf) { }
411 int main(void) {
412 udev = udev_new();
413 multipath_conf = mpath_lib_init();
414 return 0;
415 }'''
416 mpath_test_source_old = '''
417 #include <libudev.h>
418 #include <mpath_persist.h>
419 unsigned mpath_mx_alloc_len = 1024;
420 int logsink;
421 int main(void) {
422 struct udev *udev = udev_new();
423 mpath_lib_init(udev);
424 return 0;
425 }'''
426 libmpathpersist = cc.find_library('mpathpersist',
427 required: get_option('mpath'),
428 static: enable_static)
429 if libmpathpersist.found()
430 mpathlibs += libmpathpersist
431 if enable_static
432 mpathlibs += cc.find_library('devmapper',
433 required: get_option('mpath'),
434 static: enable_static)
435 endif
436 mpathlibs += cc.find_library('multipath',
437 required: get_option('mpath'),
438 static: enable_static)
439 foreach lib: mpathlibs
440 if not lib.found()
441 mpathlibs = []
442 break
443 endif
444 endforeach
445 if mpathlibs.length() == 0
446 msg = 'Dependencies missing for libmpathpersist'
447 elif cc.links(mpath_test_source_new, dependencies: mpathlibs)
448 mpathpersist = declare_dependency(dependencies: mpathlibs)
449 mpathpersist_new_api = true
450 elif cc.links(mpath_test_source_old, dependencies: mpathlibs)
451 mpathpersist = declare_dependency(dependencies: mpathlibs)
452 else
453 msg = 'Cannot detect libmpathpersist API'
454 endif
455 if not mpathpersist.found()
456 if get_option('mpath').enabled()
457 error(msg)
458 else
459 warning(msg + ', disabling')
460 endif
461 endif
462 endif
463 endif
464
465 iconv = not_found
466 curses = not_found
467 if have_system and not get_option('curses').disabled()
468 if not get_option('iconv').disabled()
469 libiconv = cc.find_library('iconv',
470 required: false,
471 static: enable_static)
472 if cc.links('''
473 #include <iconv.h>
474 int main(void) {
475 iconv_t conv = iconv_open("WCHAR_T", "UCS-2");
476 return conv != (iconv_t) -1;
477 }''', dependencies: [libiconv])
478 iconv = declare_dependency(dependencies: [libiconv])
479 endif
480 endif
481 if get_option('iconv').enabled() and not iconv.found()
482 error('Cannot detect iconv API')
483 endif
484 if iconv.found()
485 curses_libname_list = ['ncursesw', 'ncurses', 'cursesw', 'pdcurses']
486 curses_test = '''
487 #include <locale.h>
488 #include <curses.h>
489 #include <wchar.h>
490 int main(void) {
491 wchar_t wch = L'w';
492 setlocale(LC_ALL, "");
493 resize_term(0, 0);
494 addwstr(L"wide chars\n");
495 addnwstr(&wch, 1);
496 add_wch(WACS_DEGREE);
497 return 0;
498 }'''
499 foreach curses_libname : curses_libname_list
500 libcurses = dependency(curses_libname,
501 required: false,
502 method: 'pkg-config',
503 static: enable_static)
504
505 if not libcurses.found()
506 dirs = ['/usr/include/ncursesw']
507 if targetos == 'windows'
508 dirs = []
509 endif
510 libcurses = cc.find_library(curses_libname,
511 required: false,
512 dirs: dirs,
513 static: enable_static)
514 endif
515 if libcurses.found()
516 if cc.links(curses_test, dependencies: [libcurses])
517 curses = declare_dependency(compile_args: '-DNCURSES_WIDECHAR', dependencies: [libcurses])
518 break
519 endif
520 endif
521 endforeach
522 endif
523 if not curses.found()
524 if iconv.found()
525 if get_option('curses').enabled()
526 error('Cannot find curses')
527 endif
528 elif get_option('curses').enabled()
529 error('iconv required for curses UI but not available')
530 else
531 warning('iconv required for curses UI but not available, disabling')
532 endif
533 endif
534 endif
535
536 brlapi = not_found
537 if 'CONFIG_BRLAPI' in config_host
538 brlapi = declare_dependency(link_args: config_host['BRLAPI_LIBS'].split())
539 endif
540
541 sdl = not_found
542 if have_system
543 sdl = dependency('sdl2', required: get_option('sdl'), static: enable_static)
544 sdl_image = not_found
545 endif
546 if sdl.found()
547 # work around 2.0.8 bug
548 sdl = declare_dependency(compile_args: '-Wno-undef',
549 dependencies: sdl)
550 sdl_image = dependency('SDL2_image', required: get_option('sdl_image'),
551 method: 'pkg-config', static: enable_static)
552 else
553 if get_option('sdl_image').enabled()
554 error('sdl-image required, but SDL was @0@'.format(
555 get_option('sdl').disabled() ? 'disabled' : 'not found'))
556 endif
557 sdl_image = not_found
558 endif
559
560 rbd = not_found
561 if 'CONFIG_RBD' in config_host
562 rbd = declare_dependency(link_args: config_host['RBD_LIBS'].split())
563 endif
564 glusterfs = not_found
565 if 'CONFIG_GLUSTERFS' in config_host
566 glusterfs = declare_dependency(compile_args: config_host['GLUSTERFS_CFLAGS'].split(),
567 link_args: config_host['GLUSTERFS_LIBS'].split())
568 endif
569 libssh = not_found
570 if 'CONFIG_LIBSSH' in config_host
571 libssh = declare_dependency(compile_args: config_host['LIBSSH_CFLAGS'].split(),
572 link_args: config_host['LIBSSH_LIBS'].split())
573 endif
574 libbzip2 = not_found
575 if 'CONFIG_BZIP2' in config_host
576 libbzip2 = declare_dependency(link_args: config_host['BZIP2_LIBS'].split())
577 endif
578 liblzfse = not_found
579 if 'CONFIG_LZFSE' in config_host
580 liblzfse = declare_dependency(link_args: config_host['LZFSE_LIBS'].split())
581 endif
582 oss = not_found
583 if 'CONFIG_AUDIO_OSS' in config_host
584 oss = declare_dependency(link_args: config_host['OSS_LIBS'].split())
585 endif
586 dsound = not_found
587 if 'CONFIG_AUDIO_DSOUND' in config_host
588 dsound = declare_dependency(link_args: config_host['DSOUND_LIBS'].split())
589 endif
590 coreaudio = not_found
591 if 'CONFIG_AUDIO_COREAUDIO' in config_host
592 coreaudio = declare_dependency(link_args: config_host['COREAUDIO_LIBS'].split())
593 endif
594 opengl = not_found
595 if 'CONFIG_OPENGL' in config_host
596 opengl = declare_dependency(compile_args: config_host['OPENGL_CFLAGS'].split(),
597 link_args: config_host['OPENGL_LIBS'].split())
598 endif
599 gtk = not_found
600 if 'CONFIG_GTK' in config_host
601 gtk = declare_dependency(compile_args: config_host['GTK_CFLAGS'].split(),
602 link_args: config_host['GTK_LIBS'].split())
603 endif
604 vte = not_found
605 if 'CONFIG_VTE' in config_host
606 vte = declare_dependency(compile_args: config_host['VTE_CFLAGS'].split(),
607 link_args: config_host['VTE_LIBS'].split())
608 endif
609 x11 = not_found
610 if 'CONFIG_X11' in config_host
611 x11 = declare_dependency(compile_args: config_host['X11_CFLAGS'].split(),
612 link_args: config_host['X11_LIBS'].split())
613 endif
614 vnc = not_found
615 png = not_found
616 jpeg = not_found
617 sasl = not_found
618 if get_option('vnc').enabled()
619 vnc = declare_dependency() # dummy dependency
620 png = dependency('libpng', required: get_option('vnc_png'),
621 method: 'pkg-config', static: enable_static)
622 jpeg = cc.find_library('jpeg', has_headers: ['jpeglib.h'],
623 required: get_option('vnc_jpeg'),
624 static: enable_static)
625 sasl = cc.find_library('sasl2', has_headers: ['sasl/sasl.h'],
626 required: get_option('vnc_sasl'),
627 static: enable_static)
628 if sasl.found()
629 sasl = declare_dependency(dependencies: sasl,
630 compile_args: '-DSTRUCT_IOVEC_DEFINED')
631 endif
632 endif
633 snappy = not_found
634 if 'CONFIG_SNAPPY' in config_host
635 snappy = declare_dependency(link_args: config_host['SNAPPY_LIBS'].split())
636 endif
637 lzo = not_found
638 if 'CONFIG_LZO' in config_host
639 lzo = declare_dependency(link_args: config_host['LZO_LIBS'].split())
640 endif
641 rdma = not_found
642 if 'CONFIG_RDMA' in config_host
643 rdma = declare_dependency(link_args: config_host['RDMA_LIBS'].split())
644 endif
645 numa = not_found
646 if 'CONFIG_NUMA' in config_host
647 numa = declare_dependency(link_args: config_host['NUMA_LIBS'].split())
648 endif
649 xen = not_found
650 if 'CONFIG_XEN_BACKEND' in config_host
651 xen = declare_dependency(compile_args: config_host['XEN_CFLAGS'].split(),
652 link_args: config_host['XEN_LIBS'].split())
653 endif
654 cacard = not_found
655 if 'CONFIG_SMARTCARD' in config_host
656 cacard = declare_dependency(compile_args: config_host['SMARTCARD_CFLAGS'].split(),
657 link_args: config_host['SMARTCARD_LIBS'].split())
658 endif
659 u2f = not_found
660 if have_system
661 u2f = dependency('u2f-emu', required: get_option('u2f'),
662 method: 'pkg-config',
663 static: enable_static)
664 endif
665 usbredir = not_found
666 if 'CONFIG_USB_REDIR' in config_host
667 usbredir = declare_dependency(compile_args: config_host['USB_REDIR_CFLAGS'].split(),
668 link_args: config_host['USB_REDIR_LIBS'].split())
669 endif
670 libusb = not_found
671 if 'CONFIG_USB_LIBUSB' in config_host
672 libusb = declare_dependency(compile_args: config_host['LIBUSB_CFLAGS'].split(),
673 link_args: config_host['LIBUSB_LIBS'].split())
674 endif
675 libpmem = not_found
676 if 'CONFIG_LIBPMEM' in config_host
677 libpmem = declare_dependency(compile_args: config_host['LIBPMEM_CFLAGS'].split(),
678 link_args: config_host['LIBPMEM_LIBS'].split())
679 endif
680 libdaxctl = not_found
681 if 'CONFIG_LIBDAXCTL' in config_host
682 libdaxctl = declare_dependency(link_args: config_host['LIBDAXCTL_LIBS'].split())
683 endif
684 tasn1 = not_found
685 if 'CONFIG_TASN1' in config_host
686 tasn1 = declare_dependency(compile_args: config_host['TASN1_CFLAGS'].split(),
687 link_args: config_host['TASN1_LIBS'].split())
688 endif
689 keyutils = dependency('libkeyutils', required: false,
690 method: 'pkg-config', static: enable_static)
691
692 has_gettid = cc.has_function('gettid')
693
694 # Malloc tests
695
696 malloc = []
697 if get_option('malloc') == 'system'
698 has_malloc_trim = \
699 not get_option('malloc_trim').disabled() and \
700 cc.links('''#include <malloc.h>
701 int main(void) { malloc_trim(0); return 0; }''')
702 else
703 has_malloc_trim = false
704 malloc = cc.find_library(get_option('malloc'), required: true)
705 endif
706 if not has_malloc_trim and get_option('malloc_trim').enabled()
707 if get_option('malloc') == 'system'
708 error('malloc_trim not available on this platform.')
709 else
710 error('malloc_trim not available with non-libc memory allocator')
711 endif
712 endif
713
714 #################
715 # config-host.h #
716 #################
717
718 config_host_data.set('CONFIG_COCOA', cocoa.found())
719 config_host_data.set('CONFIG_LIBUDEV', libudev.found())
720 config_host_data.set('CONFIG_MPATH', mpathpersist.found())
721 config_host_data.set('CONFIG_MPATH_NEW_API', mpathpersist_new_api)
722 config_host_data.set('CONFIG_CURSES', curses.found())
723 config_host_data.set('CONFIG_SDL', sdl.found())
724 config_host_data.set('CONFIG_SDL_IMAGE', sdl_image.found())
725 config_host_data.set('CONFIG_VNC', vnc.found())
726 config_host_data.set('CONFIG_VNC_JPEG', jpeg.found())
727 config_host_data.set('CONFIG_VNC_PNG', png.found())
728 config_host_data.set('CONFIG_VNC_SASL', sasl.found())
729 config_host_data.set('CONFIG_XKBCOMMON', xkbcommon.found())
730 config_host_data.set('CONFIG_KEYUTILS', keyutils.found())
731 config_host_data.set('CONFIG_GETTID', has_gettid)
732 config_host_data.set('CONFIG_MALLOC_TRIM', has_malloc_trim)
733 config_host_data.set('QEMU_VERSION', '"@0@"'.format(meson.project_version()))
734 config_host_data.set('QEMU_VERSION_MAJOR', meson.project_version().split('.')[0])
735 config_host_data.set('QEMU_VERSION_MINOR', meson.project_version().split('.')[1])
736 config_host_data.set('QEMU_VERSION_MICRO', meson.project_version().split('.')[2])
737
738 ignored = ['CONFIG_QEMU_INTERP_PREFIX'] # actually per-target
739 arrays = ['CONFIG_AUDIO_DRIVERS', 'CONFIG_BDRV_RW_WHITELIST', 'CONFIG_BDRV_RO_WHITELIST']
740 strings = ['HOST_DSOSUF', 'CONFIG_IASL', 'bindir', 'prefix', 'qemu_confdir', 'qemu_datadir',
741 'qemu_moddir', 'qemu_localstatedir', 'qemu_helperdir', 'qemu_localedir',
742 'qemu_icondir', 'qemu_desktopdir', 'qemu_firmwarepath', 'sysconfdir']
743 foreach k, v: config_host
744 if ignored.contains(k)
745 # do nothing
746 elif arrays.contains(k)
747 if v != ''
748 v = '"' + '", "'.join(v.split()) + '", '
749 endif
750 config_host_data.set(k, v)
751 elif k == 'ARCH'
752 config_host_data.set('HOST_' + v.to_upper(), 1)
753 elif strings.contains(k)
754 if not k.startswith('CONFIG_')
755 k = 'CONFIG_' + k.to_upper()
756 endif
757 config_host_data.set_quoted(k, v)
758 elif k.startswith('CONFIG_') or k.startswith('HAVE_') or k.startswith('HOST_')
759 config_host_data.set(k, v == 'y' ? 1 : v)
760 endif
761 endforeach
762
763 ########################
764 # Target configuration #
765 ########################
766
767 minikconf = find_program('scripts/minikconf.py')
768 config_all = {}
769 config_all_devices = {}
770 config_all_disas = {}
771 config_devices_mak_list = []
772 config_devices_h = {}
773 config_target_h = {}
774 config_target_mak = {}
775
776 disassemblers = {
777 'alpha' : ['CONFIG_ALPHA_DIS'],
778 'arm' : ['CONFIG_ARM_DIS'],
779 'avr' : ['CONFIG_AVR_DIS'],
780 'cris' : ['CONFIG_CRIS_DIS'],
781 'hppa' : ['CONFIG_HPPA_DIS'],
782 'i386' : ['CONFIG_I386_DIS'],
783 'x86_64' : ['CONFIG_I386_DIS'],
784 'x32' : ['CONFIG_I386_DIS'],
785 'lm32' : ['CONFIG_LM32_DIS'],
786 'm68k' : ['CONFIG_M68K_DIS'],
787 'microblaze' : ['CONFIG_MICROBLAZE_DIS'],
788 'mips' : ['CONFIG_MIPS_DIS'],
789 'moxie' : ['CONFIG_MOXIE_DIS'],
790 'nios2' : ['CONFIG_NIOS2_DIS'],
791 'or1k' : ['CONFIG_OPENRISC_DIS'],
792 'ppc' : ['CONFIG_PPC_DIS'],
793 'riscv' : ['CONFIG_RISCV_DIS'],
794 'rx' : ['CONFIG_RX_DIS'],
795 's390' : ['CONFIG_S390_DIS'],
796 'sh4' : ['CONFIG_SH4_DIS'],
797 'sparc' : ['CONFIG_SPARC_DIS'],
798 'xtensa' : ['CONFIG_XTENSA_DIS'],
799 }
800 if link_language == 'cpp'
801 disassemblers += {
802 'aarch64' : [ 'CONFIG_ARM_A64_DIS'],
803 'arm' : [ 'CONFIG_ARM_DIS', 'CONFIG_ARM_A64_DIS'],
804 'mips' : [ 'CONFIG_MIPS_DIS', 'CONFIG_NANOMIPS_DIS'],
805 }
806 endif
807
808 kconfig_external_symbols = [
809 'CONFIG_KVM',
810 'CONFIG_XEN',
811 'CONFIG_TPM',
812 'CONFIG_SPICE',
813 'CONFIG_IVSHMEM',
814 'CONFIG_OPENGL',
815 'CONFIG_X11',
816 'CONFIG_VHOST_USER',
817 'CONFIG_VHOST_VDPA',
818 'CONFIG_VHOST_KERNEL',
819 'CONFIG_VIRTFS',
820 'CONFIG_LINUX',
821 'CONFIG_PVRDMA',
822 ]
823 ignored = [ 'TARGET_XML_FILES', 'TARGET_ABI_DIR', 'TARGET_ARCH' ]
824
825 default_targets = 'CONFIG_DEFAULT_TARGETS' in config_host
826 actual_target_dirs = []
827 fdt_required = []
828 foreach target : target_dirs
829 config_target = { 'TARGET_NAME': target.split('-')[0] }
830 if target.endswith('linux-user')
831 if targetos != 'linux'
832 if default_targets
833 continue
834 endif
835 error('Target @0@ is only available on a Linux host'.format(target))
836 endif
837 config_target += { 'CONFIG_LINUX_USER': 'y' }
838 elif target.endswith('bsd-user')
839 if 'CONFIG_BSD' not in config_host
840 if default_targets
841 continue
842 endif
843 error('Target @0@ is only available on a BSD host'.format(target))
844 endif
845 config_target += { 'CONFIG_BSD_USER': 'y' }
846 elif target.endswith('softmmu')
847 config_target += { 'CONFIG_SOFTMMU': 'y' }
848 endif
849 if target.endswith('-user')
850 config_target += {
851 'CONFIG_USER_ONLY': 'y',
852 'CONFIG_QEMU_INTERP_PREFIX':
853 config_host['CONFIG_QEMU_INTERP_PREFIX'].format(config_target['TARGET_NAME'])
854 }
855 endif
856
857 have_accel = false
858 foreach sym: accelerators
859 if sym == 'CONFIG_TCG' or target in accelerator_targets.get(sym, [])
860 config_target += { sym: 'y' }
861 config_all += { sym: 'y' }
862 if sym == 'CONFIG_XEN' and have_xen_pci_passthrough
863 config_target += { 'CONFIG_XEN_PCI_PASSTHROUGH': 'y' }
864 endif
865 have_accel = true
866 endif
867 endforeach
868 if not have_accel
869 if default_targets
870 continue
871 endif
872 error('No accelerator available for target @0@'.format(target))
873 endif
874
875 actual_target_dirs += target
876 config_target += keyval.load('default-configs/targets' / target + '.mak')
877 config_target += { 'TARGET_' + config_target['TARGET_ARCH'].to_upper(): 'y' }
878
879 if 'TARGET_NEED_FDT' in config_target
880 fdt_required += target
881 endif
882
883 # Add default keys
884 if 'TARGET_BASE_ARCH' not in config_target
885 config_target += {'TARGET_BASE_ARCH': config_target['TARGET_ARCH']}
886 endif
887 if 'TARGET_ABI_DIR' not in config_target
888 config_target += {'TARGET_ABI_DIR': config_target['TARGET_ARCH']}
889 endif
890
891 foreach k, v: disassemblers
892 if config_host['ARCH'].startswith(k) or config_target['TARGET_BASE_ARCH'].startswith(k)
893 foreach sym: v
894 config_target += { sym: 'y' }
895 config_all_disas += { sym: 'y' }
896 endforeach
897 endif
898 endforeach
899
900 config_target_data = configuration_data()
901 foreach k, v: config_target
902 if not k.startswith('TARGET_') and not k.startswith('CONFIG_')
903 # do nothing
904 elif ignored.contains(k)
905 # do nothing
906 elif k == 'TARGET_BASE_ARCH'
907 # Note that TARGET_BASE_ARCH ends up in config-target.h but it is
908 # not used to select files from sourcesets.
909 config_target_data.set('TARGET_' + v.to_upper(), 1)
910 elif k == 'TARGET_NAME' or k == 'CONFIG_QEMU_INTERP_PREFIX'
911 config_target_data.set_quoted(k, v)
912 elif v == 'y'
913 config_target_data.set(k, 1)
914 else
915 config_target_data.set(k, v)
916 endif
917 endforeach
918 config_target_h += {target: configure_file(output: target + '-config-target.h',
919 configuration: config_target_data)}
920
921 if target.endswith('-softmmu')
922 base_kconfig = []
923 foreach sym : kconfig_external_symbols
924 if sym in config_target or sym in config_host
925 base_kconfig += '@0@=y'.format(sym)
926 endif
927 endforeach
928
929 config_devices_mak = target + '-config-devices.mak'
930 config_devices_mak = configure_file(
931 input: ['default-configs/devices' / target + '.mak', 'Kconfig'],
932 output: config_devices_mak,
933 depfile: config_devices_mak + '.d',
934 capture: true,
935 command: [minikconf, config_host['CONFIG_MINIKCONF_MODE'],
936 config_devices_mak, '@DEPFILE@', '@INPUT@',
937 base_kconfig])
938
939 config_devices_data = configuration_data()
940 config_devices = keyval.load(config_devices_mak)
941 foreach k, v: config_devices
942 config_devices_data.set(k, 1)
943 endforeach
944 config_devices_mak_list += config_devices_mak
945 config_devices_h += {target: configure_file(output: target + '-config-devices.h',
946 configuration: config_devices_data)}
947 config_target += config_devices
948 config_all_devices += config_devices
949 endif
950 config_target_mak += {target: config_target}
951 endforeach
952 target_dirs = actual_target_dirs
953
954 # This configuration is used to build files that are shared by
955 # multiple binaries, and then extracted out of the "common"
956 # static_library target.
957 #
958 # We do not use all_sources()/all_dependencies(), because it would
959 # build literally all source files, including devices only used by
960 # targets that are not built for this compilation. The CONFIG_ALL
961 # pseudo symbol replaces it.
962
963 config_all += config_all_devices
964 config_all += config_host
965 config_all += config_all_disas
966 config_all += {
967 'CONFIG_XEN': config_host.has_key('CONFIG_XEN_BACKEND'),
968 'CONFIG_SOFTMMU': have_system,
969 'CONFIG_USER_ONLY': have_user,
970 'CONFIG_ALL': true,
971 }
972
973 ##############
974 # Submodules #
975 ##############
976
977 capstone = not_found
978 capstone_opt = get_option('capstone')
979 if capstone_opt in ['enabled', 'auto', 'system']
980 have_internal = fs.exists(meson.current_source_dir() / 'capstone/Makefile')
981 capstone = dependency('capstone', version: '>=4.0',
982 static: enable_static, method: 'pkg-config',
983 required: capstone_opt == 'system' or
984 capstone_opt == 'enabled' and not have_internal)
985 if capstone.found()
986 capstone_opt = 'system'
987 elif have_internal
988 capstone_opt = 'internal'
989 else
990 capstone_opt = 'disabled'
991 endif
992 endif
993 if capstone_opt == 'internal'
994 capstone_data = configuration_data()
995 capstone_data.set('CAPSTONE_USE_SYS_DYN_MEM', '1')
996
997 capstone_files = files(
998 'capstone/cs.c',
999 'capstone/MCInst.c',
1000 'capstone/MCInstrDesc.c',
1001 'capstone/MCRegisterInfo.c',
1002 'capstone/SStream.c',
1003 'capstone/utils.c'
1004 )
1005
1006 if 'CONFIG_ARM_DIS' in config_all_disas
1007 capstone_data.set('CAPSTONE_HAS_ARM', '1')
1008 capstone_files += files(
1009 'capstone/arch/ARM/ARMDisassembler.c',
1010 'capstone/arch/ARM/ARMInstPrinter.c',
1011 'capstone/arch/ARM/ARMMapping.c',
1012 'capstone/arch/ARM/ARMModule.c'
1013 )
1014 endif
1015
1016 # FIXME: This config entry currently depends on a c++ compiler.
1017 # Which is needed for building libvixl, but not for capstone.
1018 if 'CONFIG_ARM_A64_DIS' in config_all_disas
1019 capstone_data.set('CAPSTONE_HAS_ARM64', '1')
1020 capstone_files += files(
1021 'capstone/arch/AArch64/AArch64BaseInfo.c',
1022 'capstone/arch/AArch64/AArch64Disassembler.c',
1023 'capstone/arch/AArch64/AArch64InstPrinter.c',
1024 'capstone/arch/AArch64/AArch64Mapping.c',
1025 'capstone/arch/AArch64/AArch64Module.c'
1026 )
1027 endif
1028
1029 if 'CONFIG_PPC_DIS' in config_all_disas
1030 capstone_data.set('CAPSTONE_HAS_POWERPC', '1')
1031 capstone_files += files(
1032 'capstone/arch/PowerPC/PPCDisassembler.c',
1033 'capstone/arch/PowerPC/PPCInstPrinter.c',
1034 'capstone/arch/PowerPC/PPCMapping.c',
1035 'capstone/arch/PowerPC/PPCModule.c'
1036 )
1037 endif
1038
1039 if 'CONFIG_S390_DIS' in config_all_disas
1040 capstone_data.set('CAPSTONE_HAS_SYSZ', '1')
1041 capstone_files += files(
1042 'capstone/arch/SystemZ/SystemZDisassembler.c',
1043 'capstone/arch/SystemZ/SystemZInstPrinter.c',
1044 'capstone/arch/SystemZ/SystemZMapping.c',
1045 'capstone/arch/SystemZ/SystemZModule.c',
1046 'capstone/arch/SystemZ/SystemZMCTargetDesc.c'
1047 )
1048 endif
1049
1050 if 'CONFIG_I386_DIS' in config_all_disas
1051 capstone_data.set('CAPSTONE_HAS_X86', 1)
1052 capstone_files += files(
1053 'capstone/arch/X86/X86Disassembler.c',
1054 'capstone/arch/X86/X86DisassemblerDecoder.c',
1055 'capstone/arch/X86/X86ATTInstPrinter.c',
1056 'capstone/arch/X86/X86IntelInstPrinter.c',
1057 'capstone/arch/X86/X86InstPrinterCommon.c',
1058 'capstone/arch/X86/X86Mapping.c',
1059 'capstone/arch/X86/X86Module.c'
1060 )
1061 endif
1062
1063 configure_file(output: 'capstone-defs.h', configuration: capstone_data)
1064
1065 capstone_cargs = [
1066 # FIXME: There does not seem to be a way to completely replace the c_args
1067 # that come from add_project_arguments() -- we can only add to them.
1068 # So: disable all warnings with a big hammer.
1069 '-Wno-error', '-w',
1070
1071 # Include all configuration defines via a header file, which will wind up
1072 # as a dependency on the object file, and thus changes here will result
1073 # in a rebuild.
1074 '-include', 'capstone-defs.h'
1075 ]
1076
1077 libcapstone = static_library('capstone',
1078 sources: capstone_files,
1079 c_args: capstone_cargs,
1080 include_directories: 'capstone/include')
1081 capstone = declare_dependency(link_with: libcapstone,
1082 include_directories: 'capstone/include/capstone')
1083 endif
1084
1085 slirp = not_found
1086 slirp_opt = 'disabled'
1087 if have_system
1088 slirp_opt = get_option('slirp')
1089 if slirp_opt in ['enabled', 'auto', 'system']
1090 have_internal = fs.exists(meson.current_source_dir() / 'slirp/meson.build')
1091 slirp = dependency('slirp', static: enable_static,
1092 method: 'pkg-config',
1093 required: slirp_opt == 'system' or
1094 slirp_opt == 'enabled' and not have_internal)
1095 if slirp.found()
1096 slirp_opt = 'system'
1097 elif have_internal
1098 slirp_opt = 'internal'
1099 else
1100 slirp_opt = 'disabled'
1101 endif
1102 endif
1103 if slirp_opt == 'internal'
1104 slirp_deps = []
1105 if targetos == 'windows'
1106 slirp_deps = cc.find_library('iphlpapi')
1107 endif
1108 slirp_conf = configuration_data()
1109 slirp_conf.set('SLIRP_MAJOR_VERSION', meson.project_version().split('.')[0])
1110 slirp_conf.set('SLIRP_MINOR_VERSION', meson.project_version().split('.')[1])
1111 slirp_conf.set('SLIRP_MICRO_VERSION', meson.project_version().split('.')[2])
1112 slirp_conf.set_quoted('SLIRP_VERSION_STRING', meson.project_version())
1113 slirp_cargs = ['-DG_LOG_DOMAIN="Slirp"']
1114 slirp_files = [
1115 'slirp/src/arp_table.c',
1116 'slirp/src/bootp.c',
1117 'slirp/src/cksum.c',
1118 'slirp/src/dhcpv6.c',
1119 'slirp/src/dnssearch.c',
1120 'slirp/src/if.c',
1121 'slirp/src/ip6_icmp.c',
1122 'slirp/src/ip6_input.c',
1123 'slirp/src/ip6_output.c',
1124 'slirp/src/ip_icmp.c',
1125 'slirp/src/ip_input.c',
1126 'slirp/src/ip_output.c',
1127 'slirp/src/mbuf.c',
1128 'slirp/src/misc.c',
1129 'slirp/src/ncsi.c',
1130 'slirp/src/ndp_table.c',
1131 'slirp/src/sbuf.c',
1132 'slirp/src/slirp.c',
1133 'slirp/src/socket.c',
1134 'slirp/src/state.c',
1135 'slirp/src/stream.c',
1136 'slirp/src/tcp_input.c',
1137 'slirp/src/tcp_output.c',
1138 'slirp/src/tcp_subr.c',
1139 'slirp/src/tcp_timer.c',
1140 'slirp/src/tftp.c',
1141 'slirp/src/udp.c',
1142 'slirp/src/udp6.c',
1143 'slirp/src/util.c',
1144 'slirp/src/version.c',
1145 'slirp/src/vmstate.c',
1146 ]
1147
1148 configure_file(
1149 input : 'slirp/src/libslirp-version.h.in',
1150 output : 'libslirp-version.h',
1151 configuration: slirp_conf)
1152
1153 slirp_inc = include_directories('slirp', 'slirp/src')
1154 libslirp = static_library('slirp',
1155 sources: slirp_files,
1156 c_args: slirp_cargs,
1157 include_directories: slirp_inc)
1158 slirp = declare_dependency(link_with: libslirp,
1159 dependencies: slirp_deps,
1160 include_directories: slirp_inc)
1161 endif
1162 endif
1163
1164 fdt = not_found
1165 fdt_opt = get_option('fdt')
1166 if have_system
1167 if fdt_opt in ['enabled', 'auto', 'system']
1168 have_internal = fs.exists(meson.current_source_dir() / 'dtc/libfdt/Makefile.libfdt')
1169 fdt = cc.find_library('fdt', static: enable_static,
1170 required: fdt_opt == 'system' or
1171 fdt_opt == 'enabled' and not have_internal)
1172 if fdt.found() and cc.links('''
1173 #include <libfdt.h>
1174 #include <libfdt_env.h>
1175 int main(void) { fdt_check_full(NULL, 0); return 0; }''',
1176 dependencies: fdt)
1177 fdt_opt = 'system'
1178 elif have_internal
1179 fdt_opt = 'internal'
1180 else
1181 fdt_opt = 'disabled'
1182 endif
1183 endif
1184 if fdt_opt == 'internal'
1185 fdt_files = files(
1186 'dtc/libfdt/fdt.c',
1187 'dtc/libfdt/fdt_ro.c',
1188 'dtc/libfdt/fdt_wip.c',
1189 'dtc/libfdt/fdt_sw.c',
1190 'dtc/libfdt/fdt_rw.c',
1191 'dtc/libfdt/fdt_strerror.c',
1192 'dtc/libfdt/fdt_empty_tree.c',
1193 'dtc/libfdt/fdt_addresses.c',
1194 'dtc/libfdt/fdt_overlay.c',
1195 'dtc/libfdt/fdt_check.c',
1196 )
1197
1198 fdt_inc = include_directories('dtc/libfdt')
1199 libfdt = static_library('fdt',
1200 sources: fdt_files,
1201 include_directories: fdt_inc)
1202 fdt = declare_dependency(link_with: libfdt,
1203 include_directories: fdt_inc)
1204 endif
1205 endif
1206 if not fdt.found() and fdt_required.length() > 0
1207 error('fdt not available but required by targets ' + ', '.join(fdt_required))
1208 endif
1209
1210 config_host_data.set('CONFIG_CAPSTONE', capstone.found())
1211 config_host_data.set('CONFIG_FDT', fdt.found())
1212 config_host_data.set('CONFIG_SLIRP', slirp.found())
1213
1214 #####################
1215 # Generated sources #
1216 #####################
1217
1218 genh += configure_file(output: 'config-host.h', configuration: config_host_data)
1219
1220 hxtool = find_program('scripts/hxtool')
1221 shaderinclude = find_program('scripts/shaderinclude.pl')
1222 qapi_gen = find_program('scripts/qapi-gen.py')
1223 qapi_gen_depends = [ meson.source_root() / 'scripts/qapi/__init__.py',
1224 meson.source_root() / 'scripts/qapi/commands.py',
1225 meson.source_root() / 'scripts/qapi/common.py',
1226 meson.source_root() / 'scripts/qapi/error.py',
1227 meson.source_root() / 'scripts/qapi/events.py',
1228 meson.source_root() / 'scripts/qapi/expr.py',
1229 meson.source_root() / 'scripts/qapi/gen.py',
1230 meson.source_root() / 'scripts/qapi/introspect.py',
1231 meson.source_root() / 'scripts/qapi/parser.py',
1232 meson.source_root() / 'scripts/qapi/schema.py',
1233 meson.source_root() / 'scripts/qapi/source.py',
1234 meson.source_root() / 'scripts/qapi/types.py',
1235 meson.source_root() / 'scripts/qapi/visit.py',
1236 meson.source_root() / 'scripts/qapi/common.py',
1237 meson.source_root() / 'scripts/qapi-gen.py'
1238 ]
1239
1240 tracetool = [
1241 python, files('scripts/tracetool.py'),
1242 '--backend=' + config_host['TRACE_BACKENDS']
1243 ]
1244
1245 qemu_version_cmd = [find_program('scripts/qemu-version.sh'),
1246 meson.current_source_dir(),
1247 config_host['PKGVERSION'], meson.project_version()]
1248 qemu_version = custom_target('qemu-version.h',
1249 output: 'qemu-version.h',
1250 command: qemu_version_cmd,
1251 capture: true,
1252 build_by_default: true,
1253 build_always_stale: true)
1254 genh += qemu_version
1255
1256 hxdep = []
1257 hx_headers = [
1258 ['qemu-options.hx', 'qemu-options.def'],
1259 ['qemu-img-cmds.hx', 'qemu-img-cmds.h'],
1260 ]
1261 if have_system
1262 hx_headers += [
1263 ['hmp-commands.hx', 'hmp-commands.h'],
1264 ['hmp-commands-info.hx', 'hmp-commands-info.h'],
1265 ]
1266 endif
1267 foreach d : hx_headers
1268 hxdep += custom_target(d[1],
1269 input: files(d[0]),
1270 output: d[1],
1271 capture: true,
1272 build_by_default: true, # to be removed when added to a target
1273 command: [hxtool, '-h', '@INPUT0@'])
1274 endforeach
1275 genh += hxdep
1276
1277 ###################
1278 # Collect sources #
1279 ###################
1280
1281 authz_ss = ss.source_set()
1282 blockdev_ss = ss.source_set()
1283 block_ss = ss.source_set()
1284 bsd_user_ss = ss.source_set()
1285 chardev_ss = ss.source_set()
1286 common_ss = ss.source_set()
1287 crypto_ss = ss.source_set()
1288 io_ss = ss.source_set()
1289 linux_user_ss = ss.source_set()
1290 qmp_ss = ss.source_set()
1291 qom_ss = ss.source_set()
1292 softmmu_ss = ss.source_set()
1293 specific_fuzz_ss = ss.source_set()
1294 specific_ss = ss.source_set()
1295 stub_ss = ss.source_set()
1296 trace_ss = ss.source_set()
1297 user_ss = ss.source_set()
1298 util_ss = ss.source_set()
1299
1300 modules = {}
1301 hw_arch = {}
1302 target_arch = {}
1303 target_softmmu_arch = {}
1304
1305 ###############
1306 # Trace files #
1307 ###############
1308
1309 # TODO: add each directory to the subdirs from its own meson.build, once
1310 # we have those
1311 trace_events_subdirs = [
1312 'accel/kvm',
1313 'accel/tcg',
1314 'crypto',
1315 'monitor',
1316 ]
1317 if have_user
1318 trace_events_subdirs += [ 'linux-user' ]
1319 endif
1320 if have_block
1321 trace_events_subdirs += [
1322 'authz',
1323 'block',
1324 'io',
1325 'nbd',
1326 'scsi',
1327 ]
1328 endif
1329 if have_system
1330 trace_events_subdirs += [
1331 'audio',
1332 'backends',
1333 'backends/tpm',
1334 'chardev',
1335 'hw/9pfs',
1336 'hw/acpi',
1337 'hw/alpha',
1338 'hw/arm',
1339 'hw/audio',
1340 'hw/block',
1341 'hw/block/dataplane',
1342 'hw/char',
1343 'hw/display',
1344 'hw/dma',
1345 'hw/hppa',
1346 'hw/hyperv',
1347 'hw/i2c',
1348 'hw/i386',
1349 'hw/i386/xen',
1350 'hw/ide',
1351 'hw/input',
1352 'hw/intc',
1353 'hw/isa',
1354 'hw/mem',
1355 'hw/mips',
1356 'hw/misc',
1357 'hw/misc/macio',
1358 'hw/net',
1359 'hw/nvram',
1360 'hw/pci',
1361 'hw/pci-host',
1362 'hw/ppc',
1363 'hw/rdma',
1364 'hw/rdma/vmw',
1365 'hw/rtc',
1366 'hw/s390x',
1367 'hw/scsi',
1368 'hw/sd',
1369 'hw/sparc',
1370 'hw/sparc64',
1371 'hw/ssi',
1372 'hw/timer',
1373 'hw/tpm',
1374 'hw/usb',
1375 'hw/vfio',
1376 'hw/virtio',
1377 'hw/watchdog',
1378 'hw/xen',
1379 'hw/gpio',
1380 'migration',
1381 'net',
1382 'softmmu',
1383 'ui',
1384 ]
1385 endif
1386 trace_events_subdirs += [
1387 'hw/core',
1388 'qapi',
1389 'qom',
1390 'target/arm',
1391 'target/hppa',
1392 'target/i386',
1393 'target/mips',
1394 'target/ppc',
1395 'target/riscv',
1396 'target/s390x',
1397 'target/sparc',
1398 'util',
1399 ]
1400
1401 subdir('qapi')
1402 subdir('qobject')
1403 subdir('stubs')
1404 subdir('trace')
1405 subdir('util')
1406 subdir('qom')
1407 subdir('authz')
1408 subdir('crypto')
1409 subdir('ui')
1410
1411
1412 if enable_modules
1413 libmodulecommon = static_library('module-common', files('module-common.c') + genh, pic: true, c_args: '-DBUILD_DSO')
1414 modulecommon = declare_dependency(link_whole: libmodulecommon, compile_args: '-DBUILD_DSO')
1415 endif
1416
1417 stub_ss = stub_ss.apply(config_all, strict: false)
1418
1419 util_ss.add_all(trace_ss)
1420 util_ss = util_ss.apply(config_all, strict: false)
1421 libqemuutil = static_library('qemuutil',
1422 sources: util_ss.sources() + stub_ss.sources() + genh,
1423 dependencies: [util_ss.dependencies(), m, glib, socket, malloc])
1424 qemuutil = declare_dependency(link_with: libqemuutil,
1425 sources: genh + version_res)
1426
1427 decodetree = generator(find_program('scripts/decodetree.py'),
1428 output: 'decode-@BASENAME@.c.inc',
1429 arguments: ['@INPUT@', '@EXTRA_ARGS@', '-o', '@OUTPUT@'])
1430
1431 subdir('audio')
1432 subdir('io')
1433 subdir('chardev')
1434 subdir('fsdev')
1435 subdir('libdecnumber')
1436 subdir('target')
1437 subdir('dump')
1438
1439 block_ss.add(files(
1440 'block.c',
1441 'blockdev-nbd.c',
1442 'blockjob.c',
1443 'job.c',
1444 'qemu-io-cmds.c',
1445 ))
1446 block_ss.add(when: 'CONFIG_REPLICATION', if_true: files('replication.c'))
1447
1448 subdir('nbd')
1449 subdir('scsi')
1450 subdir('block')
1451
1452 blockdev_ss.add(files(
1453 'blockdev.c',
1454 'iothread.c',
1455 'job-qmp.c',
1456 ))
1457
1458 # os-posix.c contains POSIX-specific functions used by qemu-storage-daemon,
1459 # os-win32.c does not
1460 blockdev_ss.add(when: 'CONFIG_POSIX', if_true: files('os-posix.c'))
1461 softmmu_ss.add(when: 'CONFIG_WIN32', if_true: [files('os-win32.c')])
1462 softmmu_ss.add_all(blockdev_ss)
1463
1464 common_ss.add(files('cpus-common.c'))
1465
1466 subdir('softmmu')
1467
1468 common_ss.add(capstone)
1469 specific_ss.add(files('cpu.c', 'disas.c', 'gdbstub.c'), capstone)
1470 specific_ss.add(files('exec-vary.c'))
1471 specific_ss.add(when: 'CONFIG_TCG', if_true: files(
1472 'fpu/softfloat.c',
1473 'tcg/optimize.c',
1474 'tcg/tcg-common.c',
1475 'tcg/tcg-op-gvec.c',
1476 'tcg/tcg-op-vec.c',
1477 'tcg/tcg-op.c',
1478 'tcg/tcg.c',
1479 ))
1480 specific_ss.add(when: 'CONFIG_TCG_INTERPRETER', if_true: files('disas/tci.c', 'tcg/tci.c'))
1481
1482 subdir('backends')
1483 subdir('disas')
1484 subdir('migration')
1485 subdir('monitor')
1486 subdir('net')
1487 subdir('replay')
1488 subdir('hw')
1489 subdir('accel')
1490 subdir('plugins')
1491 subdir('bsd-user')
1492 subdir('linux-user')
1493
1494 bsd_user_ss.add(files('gdbstub.c'))
1495 specific_ss.add_all(when: 'CONFIG_BSD_USER', if_true: bsd_user_ss)
1496
1497 linux_user_ss.add(files('gdbstub.c', 'thunk.c'))
1498 specific_ss.add_all(when: 'CONFIG_LINUX_USER', if_true: linux_user_ss)
1499
1500 # needed for fuzzing binaries
1501 subdir('tests/qtest/libqos')
1502 subdir('tests/qtest/fuzz')
1503
1504 ########################
1505 # Library dependencies #
1506 ########################
1507
1508 block_mods = []
1509 softmmu_mods = []
1510 foreach d, list : modules
1511 foreach m, module_ss : list
1512 if enable_modules and targetos != 'windows'
1513 module_ss = module_ss.apply(config_all, strict: false)
1514 sl = static_library(d + '-' + m, [genh, module_ss.sources()],
1515 dependencies: [modulecommon, module_ss.dependencies()], pic: true)
1516 if d == 'block'
1517 block_mods += sl
1518 else
1519 softmmu_mods += sl
1520 endif
1521 else
1522 if d == 'block'
1523 block_ss.add_all(module_ss)
1524 else
1525 softmmu_ss.add_all(module_ss)
1526 endif
1527 endif
1528 endforeach
1529 endforeach
1530
1531 nm = find_program('nm')
1532 undefsym = find_program('scripts/undefsym.py')
1533 block_syms = custom_target('block.syms', output: 'block.syms',
1534 input: [libqemuutil, block_mods],
1535 capture: true,
1536 command: [undefsym, nm, '@INPUT@'])
1537 qemu_syms = custom_target('qemu.syms', output: 'qemu.syms',
1538 input: [libqemuutil, softmmu_mods],
1539 capture: true,
1540 command: [undefsym, nm, '@INPUT@'])
1541
1542 qom_ss = qom_ss.apply(config_host, strict: false)
1543 libqom = static_library('qom', qom_ss.sources() + genh,
1544 dependencies: [qom_ss.dependencies()],
1545 name_suffix: 'fa')
1546
1547 qom = declare_dependency(link_whole: libqom)
1548
1549 authz_ss = authz_ss.apply(config_host, strict: false)
1550 libauthz = static_library('authz', authz_ss.sources() + genh,
1551 dependencies: [authz_ss.dependencies()],
1552 name_suffix: 'fa',
1553 build_by_default: false)
1554
1555 authz = declare_dependency(link_whole: libauthz,
1556 dependencies: qom)
1557
1558 crypto_ss = crypto_ss.apply(config_host, strict: false)
1559 libcrypto = static_library('crypto', crypto_ss.sources() + genh,
1560 dependencies: [crypto_ss.dependencies()],
1561 name_suffix: 'fa',
1562 build_by_default: false)
1563
1564 crypto = declare_dependency(link_whole: libcrypto,
1565 dependencies: [authz, qom])
1566
1567 io_ss = io_ss.apply(config_host, strict: false)
1568 libio = static_library('io', io_ss.sources() + genh,
1569 dependencies: [io_ss.dependencies()],
1570 link_with: libqemuutil,
1571 name_suffix: 'fa',
1572 build_by_default: false)
1573
1574 io = declare_dependency(link_whole: libio, dependencies: [crypto, qom])
1575
1576 libmigration = static_library('migration', sources: migration_files + genh,
1577 name_suffix: 'fa',
1578 build_by_default: false)
1579 migration = declare_dependency(link_with: libmigration,
1580 dependencies: [zlib, qom, io])
1581 softmmu_ss.add(migration)
1582
1583 block_ss = block_ss.apply(config_host, strict: false)
1584 libblock = static_library('block', block_ss.sources() + genh,
1585 dependencies: block_ss.dependencies(),
1586 link_depends: block_syms,
1587 name_suffix: 'fa',
1588 build_by_default: false)
1589
1590 block = declare_dependency(link_whole: [libblock],
1591 link_args: '@block.syms',
1592 dependencies: [crypto, io])
1593
1594 qmp_ss = qmp_ss.apply(config_host, strict: false)
1595 libqmp = static_library('qmp', qmp_ss.sources() + genh,
1596 dependencies: qmp_ss.dependencies(),
1597 name_suffix: 'fa',
1598 build_by_default: false)
1599
1600 qmp = declare_dependency(link_whole: [libqmp])
1601
1602 libchardev = static_library('chardev', chardev_ss.sources() + genh,
1603 name_suffix: 'fa',
1604 build_by_default: false)
1605
1606 chardev = declare_dependency(link_whole: libchardev)
1607
1608 libhwcore = static_library('hwcore', sources: hwcore_files + genh,
1609 name_suffix: 'fa',
1610 build_by_default: false)
1611 hwcore = declare_dependency(link_whole: libhwcore)
1612 common_ss.add(hwcore)
1613
1614 ###########
1615 # Targets #
1616 ###########
1617
1618 foreach m : block_mods + softmmu_mods
1619 shared_module(m.name(),
1620 name_prefix: '',
1621 link_whole: m,
1622 install: true,
1623 install_dir: config_host['qemu_moddir'])
1624 endforeach
1625
1626 softmmu_ss.add(authz, block, chardev, crypto, io, qmp)
1627 common_ss.add(qom, qemuutil)
1628
1629 common_ss.add_all(when: 'CONFIG_SOFTMMU', if_true: [softmmu_ss])
1630 common_ss.add_all(when: 'CONFIG_USER_ONLY', if_true: user_ss)
1631
1632 common_all = common_ss.apply(config_all, strict: false)
1633 common_all = static_library('common',
1634 build_by_default: false,
1635 sources: common_all.sources() + genh,
1636 dependencies: common_all.dependencies(),
1637 name_suffix: 'fa')
1638
1639 feature_to_c = find_program('scripts/feature_to_c.sh')
1640
1641 emulators = {}
1642 foreach target : target_dirs
1643 config_target = config_target_mak[target]
1644 target_name = config_target['TARGET_NAME']
1645 arch = config_target['TARGET_BASE_ARCH']
1646 arch_srcs = [config_target_h[target]]
1647 arch_deps = []
1648 c_args = ['-DNEED_CPU_H',
1649 '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
1650 '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
1651 link_args = emulator_link_args
1652
1653 config_target += config_host
1654 target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
1655 if targetos == 'linux'
1656 target_inc += include_directories('linux-headers', is_system: true)
1657 endif
1658 if target.endswith('-softmmu')
1659 qemu_target_name = 'qemu-system-' + target_name
1660 target_type='system'
1661 t = target_softmmu_arch[arch].apply(config_target, strict: false)
1662 arch_srcs += t.sources()
1663 arch_deps += t.dependencies()
1664
1665 hw_dir = target_name == 'sparc64' ? 'sparc64' : arch
1666 hw = hw_arch[hw_dir].apply(config_target, strict: false)
1667 arch_srcs += hw.sources()
1668 arch_deps += hw.dependencies()
1669
1670 arch_srcs += config_devices_h[target]
1671 link_args += ['@block.syms', '@qemu.syms']
1672 else
1673 abi = config_target['TARGET_ABI_DIR']
1674 target_type='user'
1675 qemu_target_name = 'qemu-' + target_name
1676 if 'CONFIG_LINUX_USER' in config_target
1677 base_dir = 'linux-user'
1678 target_inc += include_directories('linux-user/host/' / config_host['ARCH'])
1679 else
1680 base_dir = 'bsd-user'
1681 endif
1682 target_inc += include_directories(
1683 base_dir,
1684 base_dir / abi,
1685 )
1686 if 'CONFIG_LINUX_USER' in config_target
1687 dir = base_dir / abi
1688 arch_srcs += files(dir / 'signal.c', dir / 'cpu_loop.c')
1689 if config_target.has_key('TARGET_SYSTBL_ABI')
1690 arch_srcs += \
1691 syscall_nr_generators[abi].process(base_dir / abi / config_target['TARGET_SYSTBL'],
1692 extra_args : config_target['TARGET_SYSTBL_ABI'])
1693 endif
1694 endif
1695 endif
1696
1697 if 'TARGET_XML_FILES' in config_target
1698 gdbstub_xml = custom_target(target + '-gdbstub-xml.c',
1699 output: target + '-gdbstub-xml.c',
1700 input: files(config_target['TARGET_XML_FILES'].split()),
1701 command: [feature_to_c, '@INPUT@'],
1702 capture: true)
1703 arch_srcs += gdbstub_xml
1704 endif
1705
1706 t = target_arch[arch].apply(config_target, strict: false)
1707 arch_srcs += t.sources()
1708 arch_deps += t.dependencies()
1709
1710 target_common = common_ss.apply(config_target, strict: false)
1711 objects = common_all.extract_objects(target_common.sources())
1712 deps = target_common.dependencies()
1713
1714 target_specific = specific_ss.apply(config_target, strict: false)
1715 arch_srcs += target_specific.sources()
1716 arch_deps += target_specific.dependencies()
1717
1718 lib = static_library('qemu-' + target,
1719 sources: arch_srcs + genh,
1720 dependencies: arch_deps,
1721 objects: objects,
1722 include_directories: target_inc,
1723 c_args: c_args,
1724 build_by_default: false,
1725 name_suffix: 'fa')
1726
1727 if target.endswith('-softmmu')
1728 execs = [{
1729 'name': 'qemu-system-' + target_name,
1730 'gui': false,
1731 'sources': files('softmmu/main.c'),
1732 'dependencies': []
1733 }]
1734 if targetos == 'windows' and (sdl.found() or gtk.found())
1735 execs += [{
1736 'name': 'qemu-system-' + target_name + 'w',
1737 'gui': true,
1738 'sources': files('softmmu/main.c'),
1739 'dependencies': []
1740 }]
1741 endif
1742 if config_host.has_key('CONFIG_FUZZ')
1743 specific_fuzz = specific_fuzz_ss.apply(config_target, strict: false)
1744 execs += [{
1745 'name': 'qemu-fuzz-' + target_name,
1746 'gui': false,
1747 'sources': specific_fuzz.sources(),
1748 'dependencies': specific_fuzz.dependencies(),
1749 }]
1750 endif
1751 else
1752 execs = [{
1753 'name': 'qemu-' + target_name,
1754 'gui': false,
1755 'sources': [],
1756 'dependencies': []
1757 }]
1758 endif
1759 foreach exe: execs
1760 emulators += {exe['name']:
1761 executable(exe['name'], exe['sources'],
1762 install: true,
1763 c_args: c_args,
1764 dependencies: arch_deps + deps + exe['dependencies'],
1765 objects: lib.extract_all_objects(recursive: true),
1766 link_language: link_language,
1767 link_depends: [block_syms, qemu_syms] + exe.get('link_depends', []),
1768 link_args: link_args,
1769 gui_app: exe['gui'])
1770 }
1771
1772 if 'CONFIG_TRACE_SYSTEMTAP' in config_host
1773 foreach stp: [
1774 {'ext': '.stp-build', 'fmt': 'stap', 'bin': meson.current_build_dir() / exe['name'], 'install': false},
1775 {'ext': '.stp', 'fmt': 'stap', 'bin': get_option('prefix') / get_option('bindir') / exe['name'], 'install': true},
1776 {'ext': '-simpletrace.stp', 'fmt': 'simpletrace-stap', 'bin': '', 'install': true},
1777 {'ext': '-log.stp', 'fmt': 'log-stap', 'bin': '', 'install': true},
1778 ]
1779 custom_target(exe['name'] + stp['ext'],
1780 input: trace_events_all,
1781 output: exe['name'] + stp['ext'],
1782 capture: true,
1783 install: stp['install'],
1784 install_dir: qemu_datadir / '../systemtap/tapset',
1785 command: [
1786 tracetool, '--group=all', '--format=' + stp['fmt'],
1787 '--binary=' + stp['bin'],
1788 '--target-name=' + target_name,
1789 '--target-type=' + target_type,
1790 '--probe-prefix=qemu.' + target_type + '.' + target_name,
1791 '@INPUT@',
1792 ])
1793 endforeach
1794 endif
1795 endforeach
1796 endforeach
1797
1798 # Other build targets
1799
1800 if 'CONFIG_PLUGIN' in config_host
1801 install_headers('include/qemu/qemu-plugin.h')
1802 endif
1803
1804 if 'CONFIG_GUEST_AGENT' in config_host
1805 subdir('qga')
1806 endif
1807
1808 # Don't build qemu-keymap if xkbcommon is not explicitly enabled
1809 # when we don't build tools or system
1810 if xkbcommon.found()
1811 # used for the update-keymaps target, so include rules even if !have_tools
1812 qemu_keymap = executable('qemu-keymap', files('qemu-keymap.c', 'ui/input-keymap.c') + genh,
1813 dependencies: [qemuutil, xkbcommon], install: have_tools)
1814 endif
1815
1816 if have_tools
1817 qemu_img = executable('qemu-img', [files('qemu-img.c'), hxdep],
1818 dependencies: [authz, block, crypto, io, qom, qemuutil], install: true)
1819 qemu_io = executable('qemu-io', files('qemu-io.c'),
1820 dependencies: [block, qemuutil], install: true)
1821 qemu_nbd = executable('qemu-nbd', files('qemu-nbd.c'),
1822 dependencies: [block, qemuutil], install: true)
1823
1824 subdir('storage-daemon')
1825 subdir('contrib/rdmacm-mux')
1826 subdir('contrib/elf2dmp')
1827
1828 executable('qemu-edid', files('qemu-edid.c', 'hw/display/edid-generate.c'),
1829 dependencies: qemuutil,
1830 install: true)
1831
1832 if 'CONFIG_VHOST_USER' in config_host
1833 subdir('contrib/libvhost-user')
1834 subdir('contrib/vhost-user-blk')
1835 subdir('contrib/vhost-user-gpu')
1836 subdir('contrib/vhost-user-input')
1837 subdir('contrib/vhost-user-scsi')
1838 endif
1839
1840 if targetos == 'linux'
1841 executable('qemu-bridge-helper', files('qemu-bridge-helper.c'),
1842 dependencies: [qemuutil, libcap_ng],
1843 install: true,
1844 install_dir: get_option('libexecdir'))
1845
1846 executable('qemu-pr-helper', files('scsi/qemu-pr-helper.c', 'scsi/utils.c'),
1847 dependencies: [authz, crypto, io, qom, qemuutil,
1848 libcap_ng, mpathpersist],
1849 install: true)
1850 endif
1851
1852 if 'CONFIG_IVSHMEM' in config_host
1853 subdir('contrib/ivshmem-client')
1854 subdir('contrib/ivshmem-server')
1855 endif
1856 endif
1857
1858 subdir('scripts')
1859 subdir('tools')
1860 subdir('pc-bios')
1861 subdir('docs')
1862 subdir('tests')
1863 if 'CONFIG_GTK' in config_host
1864 subdir('po')
1865 endif
1866
1867 if host_machine.system() == 'windows'
1868 nsis_cmd = [
1869 find_program('scripts/nsis.py'),
1870 '@OUTPUT@',
1871 get_option('prefix'),
1872 meson.current_source_dir(),
1873 host_machine.cpu_family(),
1874 '--',
1875 '-DDISPLAYVERSION=' + meson.project_version(),
1876 ]
1877 if build_docs
1878 nsis_cmd += '-DCONFIG_DOCUMENTATION=y'
1879 endif
1880 if 'CONFIG_GTK' in config_host
1881 nsis_cmd += '-DCONFIG_GTK=y'
1882 endif
1883
1884 nsis = custom_target('nsis',
1885 output: 'qemu-setup-' + meson.project_version() + '.exe',
1886 input: files('qemu.nsi'),
1887 build_always_stale: true,
1888 command: nsis_cmd + ['@INPUT@'])
1889 alias_target('installer', nsis)
1890 endif
1891
1892 #########################
1893 # Configuration summary #
1894 #########################
1895
1896 summary_info = {}
1897 summary_info += {'Install prefix': config_host['prefix']}
1898 summary_info += {'BIOS directory': config_host['qemu_datadir']}
1899 summary_info += {'firmware path': config_host['qemu_firmwarepath']}
1900 summary_info += {'binary directory': config_host['bindir']}
1901 summary_info += {'library directory': config_host['libdir']}
1902 summary_info += {'module directory': config_host['qemu_moddir']}
1903 summary_info += {'libexec directory': config_host['libexecdir']}
1904 summary_info += {'include directory': config_host['includedir']}
1905 summary_info += {'config directory': config_host['sysconfdir']}
1906 if targetos != 'windows'
1907 summary_info += {'local state directory': config_host['qemu_localstatedir']}
1908 summary_info += {'Manual directory': get_option('mandir')}
1909 else
1910 summary_info += {'local state directory': 'queried at runtime'}
1911 endif
1912 summary_info += {'Doc directory': get_option('docdir')}
1913 summary_info += {'Build directory': meson.current_build_dir()}
1914 summary_info += {'Source path': meson.current_source_dir()}
1915 summary_info += {'GIT binary': config_host['GIT']}
1916 summary_info += {'GIT submodules': config_host['GIT_SUBMODULES']}
1917 summary_info += {'C compiler': meson.get_compiler('c').cmd_array()[0]}
1918 summary_info += {'Host C compiler': meson.get_compiler('c', native: true).cmd_array()[0]}
1919 if link_language == 'cpp'
1920 summary_info += {'C++ compiler': meson.get_compiler('cpp').cmd_array()[0]}
1921 else
1922 summary_info += {'C++ compiler': false}
1923 endif
1924 if targetos == 'darwin'
1925 summary_info += {'Objective-C compiler': meson.get_compiler('objc').cmd_array()[0]}
1926 endif
1927 summary_info += {'ARFLAGS': config_host['ARFLAGS']}
1928 summary_info += {'CFLAGS': ' '.join(get_option('c_args')
1929 + ['-O' + get_option('optimization')]
1930 + (get_option('debug') ? ['-g'] : []))}
1931 if link_language == 'cpp'
1932 summary_info += {'CXXFLAGS': ' '.join(get_option('cpp_args')
1933 + ['-O' + get_option('optimization')]
1934 + (get_option('debug') ? ['-g'] : []))}
1935 endif
1936 link_args = get_option(link_language + '_link_args')
1937 if link_args.length() > 0
1938 summary_info += {'LDFLAGS': ' '.join(link_args)}
1939 endif
1940 summary_info += {'QEMU_CFLAGS': config_host['QEMU_CFLAGS']}
1941 summary_info += {'QEMU_LDFLAGS': config_host['QEMU_LDFLAGS']}
1942 summary_info += {'make': config_host['MAKE']}
1943 summary_info += {'python': '@0@ (version: @1@)'.format(python.full_path(), python.language_version())}
1944 summary_info += {'sphinx-build': sphinx_build.found()}
1945 summary_info += {'genisoimage': config_host['GENISOIMAGE']}
1946 # TODO: add back version
1947 summary_info += {'slirp support': slirp_opt == 'disabled' ? false : slirp_opt}
1948 if slirp_opt != 'disabled'
1949 summary_info += {'smbd': config_host['CONFIG_SMBD_COMMAND']}
1950 endif
1951 summary_info += {'module support': config_host.has_key('CONFIG_MODULES')}
1952 if config_host.has_key('CONFIG_MODULES')
1953 summary_info += {'alternative module path': config_host.has_key('CONFIG_MODULE_UPGRADES')}
1954 endif
1955 summary_info += {'host CPU': cpu}
1956 summary_info += {'host endianness': build_machine.endian()}
1957 summary_info += {'target list': ' '.join(target_dirs)}
1958 summary_info += {'gprof enabled': config_host.has_key('CONFIG_GPROF')}
1959 summary_info += {'sparse enabled': sparse.found()}
1960 summary_info += {'strip binaries': get_option('strip')}
1961 summary_info += {'profiler': config_host.has_key('CONFIG_PROFILER')}
1962 summary_info += {'static build': config_host.has_key('CONFIG_STATIC')}
1963 if targetos == 'darwin'
1964 summary_info += {'Cocoa support': config_host.has_key('CONFIG_COCOA')}
1965 endif
1966 # TODO: add back version
1967 summary_info += {'SDL support': sdl.found()}
1968 summary_info += {'SDL image support': sdl_image.found()}
1969 # TODO: add back version
1970 summary_info += {'GTK support': config_host.has_key('CONFIG_GTK')}
1971 summary_info += {'GTK GL support': config_host.has_key('CONFIG_GTK_GL')}
1972 summary_info += {'pixman': pixman.found()}
1973 # TODO: add back version
1974 summary_info += {'VTE support': config_host.has_key('CONFIG_VTE')}
1975 summary_info += {'TLS priority': config_host['CONFIG_TLS_PRIORITY']}
1976 summary_info += {'GNUTLS support': config_host.has_key('CONFIG_GNUTLS')}
1977 # TODO: add back version
1978 summary_info += {'libgcrypt': config_host.has_key('CONFIG_GCRYPT')}
1979 if config_host.has_key('CONFIG_GCRYPT')
1980 summary_info += {' hmac': config_host.has_key('CONFIG_GCRYPT_HMAC')}
1981 summary_info += {' XTS': not config_host.has_key('CONFIG_QEMU_PRIVATE_XTS')}
1982 endif
1983 # TODO: add back version
1984 summary_info += {'nettle': config_host.has_key('CONFIG_NETTLE')}
1985 if config_host.has_key('CONFIG_NETTLE')
1986 summary_info += {' XTS': not config_host.has_key('CONFIG_QEMU_PRIVATE_XTS')}
1987 endif
1988 summary_info += {'libtasn1': config_host.has_key('CONFIG_TASN1')}
1989 summary_info += {'PAM': config_host.has_key('CONFIG_AUTH_PAM')}
1990 summary_info += {'iconv support': iconv.found()}
1991 summary_info += {'curses support': curses.found()}
1992 # TODO: add back version
1993 summary_info += {'virgl support': config_host.has_key('CONFIG_VIRGL')}
1994 summary_info += {'curl support': config_host.has_key('CONFIG_CURL')}
1995 summary_info += {'mingw32 support': targetos == 'windows'}
1996 summary_info += {'Audio drivers': config_host['CONFIG_AUDIO_DRIVERS']}
1997 summary_info += {'Block whitelist (rw)': config_host['CONFIG_BDRV_RW_WHITELIST']}
1998 summary_info += {'Block whitelist (ro)': config_host['CONFIG_BDRV_RO_WHITELIST']}
1999 summary_info += {'VirtFS support': config_host.has_key('CONFIG_VIRTFS')}
2000 summary_info += {'Multipath support': mpathpersist.found()}
2001 summary_info += {'VNC support': vnc.found()}
2002 if vnc.found()
2003 summary_info += {'VNC SASL support': sasl.found()}
2004 summary_info += {'VNC JPEG support': jpeg.found()}
2005 summary_info += {'VNC PNG support': png.found()}
2006 endif
2007 summary_info += {'xen support': config_host.has_key('CONFIG_XEN_BACKEND')}
2008 if config_host.has_key('CONFIG_XEN_BACKEND')
2009 summary_info += {'xen ctrl version': config_host['CONFIG_XEN_CTRL_INTERFACE_VERSION']}
2010 endif
2011 summary_info += {'brlapi support': config_host.has_key('CONFIG_BRLAPI')}
2012 summary_info += {'Documentation': build_docs}
2013 summary_info += {'PIE': get_option('b_pie')}
2014 summary_info += {'vde support': config_host.has_key('CONFIG_VDE')}
2015 summary_info += {'netmap support': config_host.has_key('CONFIG_NETMAP')}
2016 summary_info += {'Linux AIO support': config_host.has_key('CONFIG_LINUX_AIO')}
2017 summary_info += {'Linux io_uring support': config_host.has_key('CONFIG_LINUX_IO_URING')}
2018 summary_info += {'ATTR/XATTR support': config_host.has_key('CONFIG_ATTR')}
2019 summary_info += {'Install blobs': config_host.has_key('INSTALL_BLOBS')}
2020 summary_info += {'KVM support': config_all.has_key('CONFIG_KVM')}
2021 summary_info += {'HAX support': config_all.has_key('CONFIG_HAX')}
2022 summary_info += {'HVF support': config_all.has_key('CONFIG_HVF')}
2023 summary_info += {'WHPX support': config_all.has_key('CONFIG_WHPX')}
2024 summary_info += {'TCG support': config_all.has_key('CONFIG_TCG')}
2025 if config_all.has_key('CONFIG_TCG')
2026 summary_info += {'TCG debug enabled': config_host.has_key('CONFIG_DEBUG_TCG')}
2027 summary_info += {'TCG interpreter': config_host.has_key('CONFIG_TCG_INTERPRETER')}
2028 endif
2029 summary_info += {'malloc trim support': has_malloc_trim}
2030 summary_info += {'RDMA support': config_host.has_key('CONFIG_RDMA')}
2031 summary_info += {'PVRDMA support': config_host.has_key('CONFIG_PVRDMA')}
2032 summary_info += {'fdt support': fdt_opt == 'disabled' ? false : fdt_opt}
2033 summary_info += {'membarrier': config_host.has_key('CONFIG_MEMBARRIER')}
2034 summary_info += {'preadv support': config_host.has_key('CONFIG_PREADV')}
2035 summary_info += {'fdatasync': config_host.has_key('CONFIG_FDATASYNC')}
2036 summary_info += {'madvise': config_host.has_key('CONFIG_MADVISE')}
2037 summary_info += {'posix_madvise': config_host.has_key('CONFIG_POSIX_MADVISE')}
2038 summary_info += {'posix_memalign': config_host.has_key('CONFIG_POSIX_MEMALIGN')}
2039 summary_info += {'libcap-ng support': config_host.has_key('CONFIG_LIBCAP_NG')}
2040 summary_info += {'vhost-net support': config_host.has_key('CONFIG_VHOST_NET')}
2041 summary_info += {'vhost-crypto support': config_host.has_key('CONFIG_VHOST_CRYPTO')}
2042 summary_info += {'vhost-scsi support': config_host.has_key('CONFIG_VHOST_SCSI')}
2043 summary_info += {'vhost-vsock support': config_host.has_key('CONFIG_VHOST_VSOCK')}
2044 summary_info += {'vhost-user support': config_host.has_key('CONFIG_VHOST_KERNEL')}
2045 summary_info += {'vhost-user-fs support': config_host.has_key('CONFIG_VHOST_USER_FS')}
2046 summary_info += {'vhost-vdpa support': config_host.has_key('CONFIG_VHOST_VDPA')}
2047 summary_info += {'Trace backends': config_host['TRACE_BACKENDS']}
2048 if config_host['TRACE_BACKENDS'].split().contains('simple')
2049 summary_info += {'Trace output file': config_host['CONFIG_TRACE_FILE'] + '-<pid>'}
2050 endif
2051 # TODO: add back protocol and server version
2052 summary_info += {'spice support': config_host.has_key('CONFIG_SPICE')}
2053 summary_info += {'rbd support': config_host.has_key('CONFIG_RBD')}
2054 summary_info += {'xfsctl support': config_host.has_key('CONFIG_XFS')}
2055 summary_info += {'smartcard support': config_host.has_key('CONFIG_SMARTCARD')}
2056 summary_info += {'U2F support': u2f.found()}
2057 summary_info += {'libusb': config_host.has_key('CONFIG_USB_LIBUSB')}
2058 summary_info += {'usb net redir': config_host.has_key('CONFIG_USB_REDIR')}
2059 summary_info += {'OpenGL support': config_host.has_key('CONFIG_OPENGL')}
2060 summary_info += {'OpenGL dmabufs': config_host.has_key('CONFIG_OPENGL_DMABUF')}
2061 summary_info += {'libiscsi support': config_host.has_key('CONFIG_LIBISCSI')}
2062 summary_info += {'libnfs support': config_host.has_key('CONFIG_LIBNFS')}
2063 summary_info += {'build guest agent': config_host.has_key('CONFIG_GUEST_AGENT')}
2064 if targetos == 'windows'
2065 if 'WIN_SDK' in config_host
2066 summary_info += {'Windows SDK': config_host['WIN_SDK']}
2067 endif
2068 summary_info += {'QGA VSS support': config_host.has_key('CONFIG_QGA_VSS')}
2069 summary_info += {'QGA w32 disk info': config_host.has_key('CONFIG_QGA_NTDDSCSI')}
2070 summary_info += {'QGA MSI support': config_host.has_key('CONFIG_QGA_MSI')}
2071 endif
2072 summary_info += {'seccomp support': config_host.has_key('CONFIG_SECCOMP')}
2073 summary_info += {'coroutine backend': config_host['CONFIG_COROUTINE_BACKEND']}
2074 summary_info += {'coroutine pool': config_host['CONFIG_COROUTINE_POOL'] == '1'}
2075 summary_info += {'debug stack usage': config_host.has_key('CONFIG_DEBUG_STACK_USAGE')}
2076 summary_info += {'mutex debugging': config_host.has_key('CONFIG_DEBUG_MUTEX')}
2077 summary_info += {'crypto afalg': config_host.has_key('CONFIG_AF_ALG')}
2078 summary_info += {'GlusterFS support': config_host.has_key('CONFIG_GLUSTERFS')}
2079 summary_info += {'gcov': get_option('b_coverage')}
2080 summary_info += {'TPM support': config_host.has_key('CONFIG_TPM')}
2081 summary_info += {'libssh support': config_host.has_key('CONFIG_LIBSSH')}
2082 summary_info += {'QOM debugging': config_host.has_key('CONFIG_QOM_CAST_DEBUG')}
2083 summary_info += {'Live block migration': config_host.has_key('CONFIG_LIVE_BLOCK_MIGRATION')}
2084 summary_info += {'lzo support': config_host.has_key('CONFIG_LZO')}
2085 summary_info += {'snappy support': config_host.has_key('CONFIG_SNAPPY')}
2086 summary_info += {'bzip2 support': config_host.has_key('CONFIG_BZIP2')}
2087 summary_info += {'lzfse support': config_host.has_key('CONFIG_LZFSE')}
2088 summary_info += {'zstd support': config_host.has_key('CONFIG_ZSTD')}
2089 summary_info += {'NUMA host support': config_host.has_key('CONFIG_NUMA')}
2090 summary_info += {'libxml2': config_host.has_key('CONFIG_LIBXML2')}
2091 summary_info += {'memory allocator': get_option('malloc')}
2092 summary_info += {'avx2 optimization': config_host.has_key('CONFIG_AVX2_OPT')}
2093 summary_info += {'avx512f optimization': config_host.has_key('CONFIG_AVX512F_OPT')}
2094 summary_info += {'replication support': config_host.has_key('CONFIG_REPLICATION')}
2095 summary_info += {'bochs support': config_host.has_key('CONFIG_BOCHS')}
2096 summary_info += {'cloop support': config_host.has_key('CONFIG_CLOOP')}
2097 summary_info += {'dmg support': config_host.has_key('CONFIG_DMG')}
2098 summary_info += {'qcow v1 support': config_host.has_key('CONFIG_QCOW1')}
2099 summary_info += {'vdi support': config_host.has_key('CONFIG_VDI')}
2100 summary_info += {'vvfat support': config_host.has_key('CONFIG_VVFAT')}
2101 summary_info += {'qed support': config_host.has_key('CONFIG_QED')}
2102 summary_info += {'parallels support': config_host.has_key('CONFIG_PARALLELS')}
2103 summary_info += {'sheepdog support': config_host.has_key('CONFIG_SHEEPDOG')}
2104 summary_info += {'capstone': capstone_opt == 'disabled' ? false : capstone_opt}
2105 summary_info += {'libpmem support': config_host.has_key('CONFIG_LIBPMEM')}
2106 summary_info += {'libdaxctl support': config_host.has_key('CONFIG_LIBDAXCTL')}
2107 summary_info += {'libudev': libudev.found()}
2108 summary_info += {'default devices': config_host['CONFIG_MINIKCONF_MODE'] == '--defconfig'}
2109 summary_info += {'plugin support': config_host.has_key('CONFIG_PLUGIN')}
2110 summary_info += {'fuzzing support': config_host.has_key('CONFIG_FUZZ')}
2111 if config_host.has_key('HAVE_GDB_BIN')
2112 summary_info += {'gdb': config_host['HAVE_GDB_BIN']}
2113 endif
2114 summary_info += {'thread sanitizer': config_host.has_key('CONFIG_TSAN')}
2115 summary_info += {'rng-none': config_host.has_key('CONFIG_RNG_NONE')}
2116 summary_info += {'Linux keyring': config_host.has_key('CONFIG_SECRET_KEYRING')}
2117 summary(summary_info, bool_yn: true)
2118
2119 if not supported_cpus.contains(cpu)
2120 message()
2121 warning('SUPPORT FOR THIS HOST CPU WILL GO AWAY IN FUTURE RELEASES!')
2122 message()
2123 message('CPU host architecture ' + cpu + ' support is not currently maintained.')
2124 message('The QEMU project intends to remove support for this host CPU in')
2125 message('a future release if nobody volunteers to maintain it and to')
2126 message('provide a build host for our continuous integration setup.')
2127 message('configure has succeeded and you can continue to build, but')
2128 message('if you care about QEMU on this platform you should contact')
2129 message('us upstream at qemu-devel@nongnu.org.')
2130 endif
2131
2132 if not supported_oses.contains(targetos)
2133 message()
2134 warning('WARNING: SUPPORT FOR THIS HOST OS WILL GO AWAY IN FUTURE RELEASES!')
2135 message()
2136 message('Host OS ' + targetos + 'support is not currently maintained.')
2137 message('The QEMU project intends to remove support for this host OS in')
2138 message('a future release if nobody volunteers to maintain it and to')
2139 message('provide a build host for our continuous integration setup.')
2140 message('configure has succeeded and you can continue to build, but')
2141 message('if you care about QEMU on this platform you should contact')
2142 message('us upstream at qemu-devel@nongnu.org.')
2143 endif