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