]> git.proxmox.com Git - mirror_qemu.git/blob - meson.build
docs/interop: Convert qemu-ga-ref to rST
[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
14 sh = find_program('sh')
15 cc = meson.get_compiler('c')
16 config_host = keyval.load(meson.current_build_dir() / 'config-host.mak')
17 enable_modules = 'CONFIG_MODULES' in config_host
18 enable_static = 'CONFIG_STATIC' in config_host
19 build_docs = 'BUILD_DOCS' in config_host
20 qemu_datadir = get_option('datadir') / get_option('qemu_suffix')
21 qemu_docdir = get_option('docdir') / get_option('qemu_suffix')
22 config_host_data = configuration_data()
23 genh = []
24
25 target_dirs = config_host['TARGET_DIRS'].split()
26 have_user = false
27 have_system = false
28 foreach target : target_dirs
29 have_user = have_user or target.endswith('-user')
30 have_system = have_system or target.endswith('-softmmu')
31 endforeach
32 have_tools = 'CONFIG_TOOLS' in config_host
33 have_block = have_system or have_tools
34
35 python = import('python').find_installation()
36
37 supported_oses = ['windows', 'freebsd', 'netbsd', 'openbsd', 'darwin', 'sunos', 'linux']
38 supported_cpus = ['ppc', 'ppc64', 's390x', 'sparc64', 'riscv32', 'riscv64', 'x86', 'x86_64',
39 'arm', 'aarch64', 'mips', 'mips64', 'sparc', 'sparc64']
40
41 cpu = host_machine.cpu_family()
42 targetos = host_machine.system()
43
44 configure_file(input: files('scripts/ninjatool.py'),
45 output: 'ninjatool',
46 configuration: config_host)
47
48 ##################
49 # Compiler flags #
50 ##################
51
52 add_project_arguments(config_host['QEMU_CFLAGS'].split(),
53 native: false, language: ['c', 'objc'])
54 add_project_arguments(config_host['QEMU_CXXFLAGS'].split(),
55 native: false, language: 'cpp')
56 add_project_link_arguments(config_host['QEMU_LDFLAGS'].split(),
57 native: false, language: ['c', 'cpp', 'objc'])
58 add_project_arguments(config_host['QEMU_INCLUDES'].split(),
59 language: ['c', 'cpp', 'objc'])
60
61 # Specify linker-script with add_project_link_arguments so that it is not placed
62 # within a linker --start-group/--end-group pair
63 if 'CONFIG_FUZZ' in config_host
64 add_project_link_arguments(['-Wl,-T,',
65 (meson.current_source_dir() / 'tests/qtest/fuzz/fork_fuzz.ld')],
66 native: false, language: ['c', 'cpp', 'objc'])
67 endif
68
69 link_language = meson.get_external_property('link_language', 'cpp')
70 if link_language == 'cpp'
71 add_languages('cpp', required: true, native: false)
72 endif
73 if host_machine.system() == 'darwin'
74 add_languages('objc', required: false, native: false)
75 endif
76
77 if 'SPARSE_CFLAGS' in config_host
78 run_target('sparse',
79 command: [find_program('scripts/check_sparse.py'),
80 config_host['SPARSE_CFLAGS'].split(),
81 'compile_commands.json'])
82 endif
83
84 m = cc.find_library('m', required: false)
85 util = cc.find_library('util', required: false)
86 winmm = []
87 socket = []
88 version_res = []
89 coref = []
90 iokit = []
91 cocoa = []
92 hvf = []
93 if targetos == 'windows'
94 socket = cc.find_library('ws2_32')
95 winmm = cc.find_library('winmm')
96
97 win = import('windows')
98 version_res = win.compile_resources('version.rc',
99 depend_files: files('pc-bios/qemu-nsis.ico'),
100 include_directories: include_directories('.'))
101 elif targetos == 'darwin'
102 coref = dependency('appleframeworks', modules: 'CoreFoundation')
103 iokit = dependency('appleframeworks', modules: 'IOKit')
104 cocoa = dependency('appleframeworks', modules: 'Cocoa')
105 hvf = dependency('appleframeworks', modules: 'Hypervisor')
106 elif targetos == 'sunos'
107 socket = [cc.find_library('socket'),
108 cc.find_library('nsl'),
109 cc.find_library('resolv')]
110 elif targetos == 'haiku'
111 socket = [cc.find_library('posix_error_mapper'),
112 cc.find_library('network'),
113 cc.find_library('bsd')]
114 endif
115 # The path to glib.h is added to all compilation commands. This was
116 # grandfathered in from the QEMU Makefiles.
117 add_project_arguments(config_host['GLIB_CFLAGS'].split(),
118 native: false, language: ['c', 'cpp', 'objc'])
119 glib = declare_dependency(link_args: config_host['GLIB_LIBS'].split())
120 gio = not_found
121 if 'CONFIG_GIO' in config_host
122 gio = declare_dependency(compile_args: config_host['GIO_CFLAGS'].split(),
123 link_args: config_host['GIO_LIBS'].split())
124 endif
125 lttng = not_found
126 if 'CONFIG_TRACE_UST' in config_host
127 lttng = declare_dependency(link_args: config_host['LTTNG_UST_LIBS'].split())
128 endif
129 urcubp = not_found
130 if 'CONFIG_TRACE_UST' in config_host
131 urcubp = declare_dependency(link_args: config_host['URCU_BP_LIBS'].split())
132 endif
133 gcrypt = not_found
134 if 'CONFIG_GCRYPT' in config_host
135 gcrypt = declare_dependency(compile_args: config_host['GCRYPT_CFLAGS'].split(),
136 link_args: config_host['GCRYPT_LIBS'].split())
137 endif
138 nettle = not_found
139 if 'CONFIG_NETTLE' in config_host
140 nettle = declare_dependency(compile_args: config_host['NETTLE_CFLAGS'].split(),
141 link_args: config_host['NETTLE_LIBS'].split())
142 endif
143 gnutls = not_found
144 if 'CONFIG_GNUTLS' in config_host
145 gnutls = declare_dependency(compile_args: config_host['GNUTLS_CFLAGS'].split(),
146 link_args: config_host['GNUTLS_LIBS'].split())
147 endif
148 pixman = not_found
149 if have_system or have_tools
150 pixman = dependency('pixman-1', required: have_system, version:'>=0.21.8',
151 method: 'pkg-config', static: enable_static)
152 endif
153 pam = not_found
154 if 'CONFIG_AUTH_PAM' in config_host
155 pam = cc.find_library('pam')
156 endif
157 libaio = cc.find_library('aio', required: false)
158 zlib = dependency('zlib', required: true, static: enable_static)
159 linux_io_uring = not_found
160 if 'CONFIG_LINUX_IO_URING' in config_host
161 linux_io_uring = declare_dependency(compile_args: config_host['LINUX_IO_URING_CFLAGS'].split(),
162 link_args: config_host['LINUX_IO_URING_LIBS'].split())
163 endif
164 libxml2 = not_found
165 if 'CONFIG_LIBXML2' in config_host
166 libxml2 = declare_dependency(compile_args: config_host['LIBXML2_CFLAGS'].split(),
167 link_args: config_host['LIBXML2_LIBS'].split())
168 endif
169 libnfs = not_found
170 if 'CONFIG_LIBNFS' in config_host
171 libnfs = declare_dependency(link_args: config_host['LIBNFS_LIBS'].split())
172 endif
173 libattr = not_found
174 if 'CONFIG_ATTR' in config_host
175 libattr = declare_dependency(link_args: config_host['LIBATTR_LIBS'].split())
176 endif
177 seccomp = not_found
178 if 'CONFIG_SECCOMP' in config_host
179 seccomp = declare_dependency(compile_args: config_host['SECCOMP_CFLAGS'].split(),
180 link_args: config_host['SECCOMP_LIBS'].split())
181 endif
182 libcap_ng = not_found
183 if 'CONFIG_LIBCAP_NG' in config_host
184 libcap_ng = declare_dependency(link_args: config_host['LIBCAP_NG_LIBS'].split())
185 endif
186 if get_option('xkbcommon').auto() and not have_system and not have_tools
187 xkbcommon = not_found
188 else
189 xkbcommon = dependency('xkbcommon', required: get_option('xkbcommon'),
190 method: 'pkg-config', static: enable_static)
191 endif
192 slirp = not_found
193 if config_host.has_key('CONFIG_SLIRP')
194 slirp = declare_dependency(compile_args: config_host['SLIRP_CFLAGS'].split(),
195 link_args: config_host['SLIRP_LIBS'].split())
196 endif
197 vde = not_found
198 if config_host.has_key('CONFIG_VDE')
199 vde = declare_dependency(link_args: config_host['VDE_LIBS'].split())
200 endif
201 pulse = not_found
202 if 'CONFIG_LIBPULSE' in config_host
203 pulse = declare_dependency(compile_args: config_host['PULSE_CFLAGS'].split(),
204 link_args: config_host['PULSE_LIBS'].split())
205 endif
206 alsa = not_found
207 if 'CONFIG_ALSA' in config_host
208 alsa = declare_dependency(compile_args: config_host['ALSA_CFLAGS'].split(),
209 link_args: config_host['ALSA_LIBS'].split())
210 endif
211 jack = not_found
212 if 'CONFIG_LIBJACK' in config_host
213 jack = declare_dependency(link_args: config_host['JACK_LIBS'].split())
214 endif
215 spice = not_found
216 if 'CONFIG_SPICE' in config_host
217 spice = declare_dependency(compile_args: config_host['SPICE_CFLAGS'].split(),
218 link_args: config_host['SPICE_LIBS'].split())
219 endif
220 rt = cc.find_library('rt', required: false)
221 libmpathpersist = not_found
222 if config_host.has_key('CONFIG_MPATH')
223 libmpathpersist = cc.find_library('mpathpersist')
224 endif
225 libdl = not_found
226 if 'CONFIG_PLUGIN' in config_host
227 libdl = cc.find_library('dl', required: true)
228 endif
229 libiscsi = not_found
230 if 'CONFIG_LIBISCSI' in config_host
231 libiscsi = declare_dependency(compile_args: config_host['LIBISCSI_CFLAGS'].split(),
232 link_args: config_host['LIBISCSI_LIBS'].split())
233 endif
234 zstd = not_found
235 if 'CONFIG_ZSTD' in config_host
236 zstd = declare_dependency(compile_args: config_host['ZSTD_CFLAGS'].split(),
237 link_args: config_host['ZSTD_LIBS'].split())
238 endif
239 gbm = not_found
240 if 'CONFIG_GBM' in config_host
241 gbm = declare_dependency(compile_args: config_host['GBM_CFLAGS'].split(),
242 link_args: config_host['GBM_LIBS'].split())
243 endif
244 virgl = not_found
245 if 'CONFIG_VIRGL' in config_host
246 virgl = declare_dependency(compile_args: config_host['VIRGL_CFLAGS'].split(),
247 link_args: config_host['VIRGL_LIBS'].split())
248 endif
249 curl = not_found
250 if 'CONFIG_CURL' in config_host
251 curl = declare_dependency(compile_args: config_host['CURL_CFLAGS'].split(),
252 link_args: config_host['CURL_LIBS'].split())
253 endif
254 libudev = not_found
255 if 'CONFIG_LIBUDEV' in config_host
256 libudev = declare_dependency(link_args: config_host['LIBUDEV_LIBS'].split())
257 endif
258 brlapi = not_found
259 if 'CONFIG_BRLAPI' in config_host
260 brlapi = declare_dependency(link_args: config_host['BRLAPI_LIBS'].split())
261 endif
262
263 sdl = not_found
264 if have_system
265 sdl = dependency('sdl2', required: get_option('sdl'), static: enable_static)
266 sdl_image = not_found
267 endif
268 if sdl.found()
269 # work around 2.0.8 bug
270 sdl = declare_dependency(compile_args: '-Wno-undef',
271 dependencies: sdl)
272 sdl_image = dependency('SDL2_image', required: get_option('sdl_image'),
273 method: 'pkg-config', static: enable_static)
274 else
275 if get_option('sdl_image').enabled()
276 error('sdl-image required, but SDL was @0@'.format(
277 get_option('sdl').disabled() ? 'disabled' : 'not found'))
278 endif
279 sdl_image = not_found
280 endif
281
282 rbd = not_found
283 if 'CONFIG_RBD' in config_host
284 rbd = declare_dependency(link_args: config_host['RBD_LIBS'].split())
285 endif
286 glusterfs = not_found
287 if 'CONFIG_GLUSTERFS' in config_host
288 glusterfs = declare_dependency(compile_args: config_host['GLUSTERFS_CFLAGS'].split(),
289 link_args: config_host['GLUSTERFS_LIBS'].split())
290 endif
291 libssh = not_found
292 if 'CONFIG_LIBSSH' in config_host
293 libssh = declare_dependency(compile_args: config_host['LIBSSH_CFLAGS'].split(),
294 link_args: config_host['LIBSSH_LIBS'].split())
295 endif
296 libbzip2 = not_found
297 if 'CONFIG_BZIP2' in config_host
298 libbzip2 = declare_dependency(link_args: config_host['BZIP2_LIBS'].split())
299 endif
300 liblzfse = not_found
301 if 'CONFIG_LZFSE' in config_host
302 liblzfse = declare_dependency(link_args: config_host['LZFSE_LIBS'].split())
303 endif
304 oss = not_found
305 if 'CONFIG_AUDIO_OSS' in config_host
306 oss = declare_dependency(link_args: config_host['OSS_LIBS'].split())
307 endif
308 dsound = not_found
309 if 'CONFIG_AUDIO_DSOUND' in config_host
310 dsound = declare_dependency(link_args: config_host['DSOUND_LIBS'].split())
311 endif
312 coreaudio = not_found
313 if 'CONFIG_AUDIO_COREAUDIO' in config_host
314 coreaudio = declare_dependency(link_args: config_host['COREAUDIO_LIBS'].split())
315 endif
316 opengl = not_found
317 if 'CONFIG_OPENGL' in config_host
318 opengl = declare_dependency(compile_args: config_host['OPENGL_CFLAGS'].split(),
319 link_args: config_host['OPENGL_LIBS'].split())
320 endif
321 gtk = not_found
322 if 'CONFIG_GTK' in config_host
323 gtk = declare_dependency(compile_args: config_host['GTK_CFLAGS'].split(),
324 link_args: config_host['GTK_LIBS'].split())
325 endif
326 vte = not_found
327 if 'CONFIG_VTE' in config_host
328 vte = declare_dependency(compile_args: config_host['VTE_CFLAGS'].split(),
329 link_args: config_host['VTE_LIBS'].split())
330 endif
331 x11 = not_found
332 if 'CONFIG_X11' in config_host
333 x11 = declare_dependency(compile_args: config_host['X11_CFLAGS'].split(),
334 link_args: config_host['X11_LIBS'].split())
335 endif
336 curses = not_found
337 if 'CONFIG_CURSES' in config_host
338 curses = declare_dependency(compile_args: config_host['CURSES_CFLAGS'].split(),
339 link_args: config_host['CURSES_LIBS'].split())
340 endif
341 iconv = not_found
342 if 'CONFIG_ICONV' in config_host
343 iconv = declare_dependency(compile_args: config_host['ICONV_CFLAGS'].split(),
344 link_args: config_host['ICONV_LIBS'].split())
345 endif
346 vnc = not_found
347 png = not_found
348 jpeg = not_found
349 sasl = not_found
350 if get_option('vnc').enabled()
351 vnc = declare_dependency() # dummy dependency
352 png = dependency('libpng', required: get_option('vnc_png'),
353 method: 'pkg-config', static: enable_static)
354 jpeg = cc.find_library('jpeg', has_headers: ['jpeglib.h'],
355 required: get_option('vnc_jpeg'),
356 static: enable_static)
357 sasl = cc.find_library('sasl2', has_headers: ['sasl/sasl.h'],
358 required: get_option('vnc_sasl'),
359 static: enable_static)
360 if sasl.found()
361 sasl = declare_dependency(dependencies: sasl,
362 compile_args: '-DSTRUCT_IOVEC_DEFINED')
363 endif
364 endif
365 fdt = not_found
366 if 'CONFIG_FDT' in config_host
367 fdt = declare_dependency(compile_args: config_host['FDT_CFLAGS'].split(),
368 link_args: config_host['FDT_LIBS'].split())
369 endif
370 snappy = not_found
371 if 'CONFIG_SNAPPY' in config_host
372 snappy = declare_dependency(link_args: config_host['SNAPPY_LIBS'].split())
373 endif
374 lzo = not_found
375 if 'CONFIG_LZO' in config_host
376 lzo = declare_dependency(link_args: config_host['LZO_LIBS'].split())
377 endif
378 rdma = not_found
379 if 'CONFIG_RDMA' in config_host
380 rdma = declare_dependency(link_args: config_host['RDMA_LIBS'].split())
381 endif
382 numa = not_found
383 if 'CONFIG_NUMA' in config_host
384 numa = declare_dependency(link_args: config_host['NUMA_LIBS'].split())
385 endif
386 xen = not_found
387 if 'CONFIG_XEN_BACKEND' in config_host
388 xen = declare_dependency(compile_args: config_host['XEN_CFLAGS'].split(),
389 link_args: config_host['XEN_LIBS'].split())
390 endif
391 cacard = not_found
392 if 'CONFIG_SMARTCARD' in config_host
393 cacard = declare_dependency(compile_args: config_host['SMARTCARD_CFLAGS'].split(),
394 link_args: config_host['SMARTCARD_LIBS'].split())
395 endif
396 u2f = not_found
397 if have_system
398 u2f = dependency('u2f-emu', required: get_option('u2f'),
399 method: 'pkg-config',
400 static: enable_static)
401 endif
402 usbredir = not_found
403 if 'CONFIG_USB_REDIR' in config_host
404 usbredir = declare_dependency(compile_args: config_host['USB_REDIR_CFLAGS'].split(),
405 link_args: config_host['USB_REDIR_LIBS'].split())
406 endif
407 libusb = not_found
408 if 'CONFIG_USB_LIBUSB' in config_host
409 libusb = declare_dependency(compile_args: config_host['LIBUSB_CFLAGS'].split(),
410 link_args: config_host['LIBUSB_LIBS'].split())
411 endif
412 capstone = not_found
413 if 'CONFIG_CAPSTONE' in config_host
414 capstone = declare_dependency(compile_args: config_host['CAPSTONE_CFLAGS'].split(),
415 link_args: config_host['CAPSTONE_LIBS'].split())
416 endif
417 libpmem = not_found
418 if 'CONFIG_LIBPMEM' in config_host
419 libpmem = declare_dependency(compile_args: config_host['LIBPMEM_CFLAGS'].split(),
420 link_args: config_host['LIBPMEM_LIBS'].split())
421 endif
422 libdaxctl = not_found
423 if 'CONFIG_LIBDAXCTL' in config_host
424 libdaxctl = declare_dependency(link_args: config_host['LIBDAXCTL_LIBS'].split())
425 endif
426 tasn1 = not_found
427 if 'CONFIG_TASN1' in config_host
428 tasn1 = declare_dependency(compile_args: config_host['TASN1_CFLAGS'].split(),
429 link_args: config_host['TASN1_LIBS'].split())
430 endif
431 keyutils = dependency('libkeyutils', required: false,
432 method: 'pkg-config', static: enable_static)
433
434 has_gettid = cc.has_function('gettid')
435
436 # Create config-host.h
437
438 config_host_data.set('CONFIG_SDL', sdl.found())
439 config_host_data.set('CONFIG_SDL_IMAGE', sdl_image.found())
440 config_host_data.set('CONFIG_VNC', vnc.found())
441 config_host_data.set('CONFIG_VNC_JPEG', jpeg.found())
442 config_host_data.set('CONFIG_VNC_PNG', png.found())
443 config_host_data.set('CONFIG_VNC_SASL', sasl.found())
444 config_host_data.set('CONFIG_XKBCOMMON', xkbcommon.found())
445 config_host_data.set('CONFIG_KEYUTILS', keyutils.found())
446 config_host_data.set('CONFIG_GETTID', has_gettid)
447 config_host_data.set('QEMU_VERSION', '"@0@"'.format(meson.project_version()))
448 config_host_data.set('QEMU_VERSION_MAJOR', meson.project_version().split('.')[0])
449 config_host_data.set('QEMU_VERSION_MINOR', meson.project_version().split('.')[1])
450 config_host_data.set('QEMU_VERSION_MICRO', meson.project_version().split('.')[2])
451
452 arrays = ['CONFIG_AUDIO_DRIVERS', 'CONFIG_BDRV_RW_WHITELIST', 'CONFIG_BDRV_RO_WHITELIST']
453 strings = ['HOST_DSOSUF', 'CONFIG_IASL', 'qemu_confdir', 'qemu_datadir',
454 'qemu_moddir', 'qemu_localstatedir', 'qemu_helperdir', 'qemu_localedir',
455 'qemu_icondir', 'qemu_desktopdir', 'qemu_firmwarepath']
456 foreach k, v: config_host
457 if arrays.contains(k)
458 if v != ''
459 v = '"' + '", "'.join(v.split()) + '", '
460 endif
461 config_host_data.set(k, v)
462 elif k == 'ARCH'
463 config_host_data.set('HOST_' + v.to_upper(), 1)
464 elif strings.contains(k)
465 if not k.startswith('CONFIG_')
466 k = 'CONFIG_' + k.to_upper()
467 endif
468 config_host_data.set_quoted(k, v)
469 elif k.startswith('CONFIG_') or k.startswith('HAVE_') or k.startswith('HOST_')
470 config_host_data.set(k, v == 'y' ? 1 : v)
471 endif
472 endforeach
473 genh += configure_file(output: 'config-host.h', configuration: config_host_data)
474
475 minikconf = find_program('scripts/minikconf.py')
476 config_all_devices = {}
477 config_all_disas = {}
478 config_devices_mak_list = []
479 config_devices_h = {}
480 config_target_h = {}
481 config_target_mak = {}
482
483 disassemblers = {
484 'alpha' : ['CONFIG_ALPHA_DIS'],
485 'arm' : ['CONFIG_ARM_DIS'],
486 'avr' : ['CONFIG_AVR_DIS'],
487 'cris' : ['CONFIG_CRIS_DIS'],
488 'hppa' : ['CONFIG_HPPA_DIS'],
489 'i386' : ['CONFIG_I386_DIS'],
490 'x86_64' : ['CONFIG_I386_DIS'],
491 'x32' : ['CONFIG_I386_DIS'],
492 'lm32' : ['CONFIG_LM32_DIS'],
493 'm68k' : ['CONFIG_M68K_DIS'],
494 'microblaze' : ['CONFIG_MICROBLAZE_DIS'],
495 'mips' : ['CONFIG_MIPS_DIS'],
496 'moxie' : ['CONFIG_MOXIE_DIS'],
497 'nios2' : ['CONFIG_NIOS2_DIS'],
498 'or1k' : ['CONFIG_OPENRISC_DIS'],
499 'ppc' : ['CONFIG_PPC_DIS'],
500 'riscv' : ['CONFIG_RISCV_DIS'],
501 'rx' : ['CONFIG_RX_DIS'],
502 's390' : ['CONFIG_S390_DIS'],
503 'sh4' : ['CONFIG_SH4_DIS'],
504 'sparc' : ['CONFIG_SPARC_DIS'],
505 'xtensa' : ['CONFIG_XTENSA_DIS'],
506 }
507 if link_language == 'cpp'
508 disassemblers += {
509 'aarch64' : [ 'CONFIG_ARM_A64_DIS'],
510 'arm' : [ 'CONFIG_ARM_DIS', 'CONFIG_ARM_A64_DIS'],
511 'mips' : [ 'CONFIG_MIPS_DIS', 'CONFIG_NANOMIPS_DIS'],
512 }
513 endif
514
515 kconfig_external_symbols = [
516 'CONFIG_KVM',
517 'CONFIG_XEN',
518 'CONFIG_TPM',
519 'CONFIG_SPICE',
520 'CONFIG_IVSHMEM',
521 'CONFIG_OPENGL',
522 'CONFIG_X11',
523 'CONFIG_VHOST_USER',
524 'CONFIG_VHOST_VDPA',
525 'CONFIG_VHOST_KERNEL',
526 'CONFIG_VIRTFS',
527 'CONFIG_LINUX',
528 'CONFIG_PVRDMA',
529 ]
530 ignored = ['TARGET_XML_FILES', 'TARGET_ABI_DIR', 'TARGET_DIRS']
531
532 foreach target : target_dirs
533 config_target = keyval.load(meson.current_build_dir() / target / 'config-target.mak')
534
535 foreach k, v: disassemblers
536 if config_host['ARCH'].startswith(k) or config_target['TARGET_BASE_ARCH'].startswith(k)
537 foreach sym: v
538 config_target += { sym: 'y' }
539 config_all_disas += { sym: 'y' }
540 endforeach
541 endif
542 endforeach
543
544 config_target_data = configuration_data()
545 foreach k, v: config_target
546 if not k.startswith('TARGET_') and not k.startswith('CONFIG_')
547 # do nothing
548 elif ignored.contains(k)
549 # do nothing
550 elif k == 'TARGET_BASE_ARCH'
551 config_target_data.set('TARGET_' + v.to_upper(), 1)
552 elif k == 'TARGET_NAME'
553 config_target_data.set_quoted(k, v)
554 elif v == 'y'
555 config_target_data.set(k, 1)
556 else
557 config_target_data.set(k, v)
558 endif
559 endforeach
560 config_target_h += {target: configure_file(output: target + '-config-target.h',
561 configuration: config_target_data)}
562
563 if target.endswith('-softmmu')
564 base_kconfig = []
565 foreach sym : kconfig_external_symbols
566 if sym in config_target or sym in config_host
567 base_kconfig += '@0@=y'.format(sym)
568 endif
569 endforeach
570
571 config_devices_mak = target + '-config-devices.mak'
572 config_devices_mak = configure_file(
573 input: ['default-configs' / target + '.mak', 'Kconfig'],
574 output: config_devices_mak,
575 depfile: config_devices_mak + '.d',
576 capture: true,
577 command: [minikconf, config_host['CONFIG_MINIKCONF_MODE'],
578 config_devices_mak, '@DEPFILE@', '@INPUT@',
579 base_kconfig])
580
581 config_devices_data = configuration_data()
582 config_devices = keyval.load(config_devices_mak)
583 foreach k, v: config_devices
584 config_devices_data.set(k, 1)
585 endforeach
586 config_devices_mak_list += config_devices_mak
587 config_devices_h += {target: configure_file(output: target + '-config-devices.h',
588 configuration: config_devices_data)}
589 config_target += config_devices
590 config_all_devices += config_devices
591 endif
592 config_target_mak += {target: config_target}
593 endforeach
594
595 # This configuration is used to build files that are shared by
596 # multiple binaries, and then extracted out of the "common"
597 # static_library target.
598 #
599 # We do not use all_sources()/all_dependencies(), because it would
600 # build literally all source files, including devices only used by
601 # targets that are not built for this compilation. The CONFIG_ALL
602 # pseudo symbol replaces it.
603
604 config_all = config_all_devices
605 config_all += config_host
606 config_all += config_all_disas
607 config_all += {
608 'CONFIG_XEN': config_host.has_key('CONFIG_XEN_BACKEND'),
609 'CONFIG_SOFTMMU': have_system,
610 'CONFIG_USER_ONLY': have_user,
611 'CONFIG_ALL': true,
612 }
613
614 # Generators
615
616 hxtool = find_program('scripts/hxtool')
617 shaderinclude = find_program('scripts/shaderinclude.pl')
618 qapi_gen = find_program('scripts/qapi-gen.py')
619 qapi_gen_depends = [ meson.source_root() / 'scripts/qapi/__init__.py',
620 meson.source_root() / 'scripts/qapi/commands.py',
621 meson.source_root() / 'scripts/qapi/common.py',
622 meson.source_root() / 'scripts/qapi/doc.py',
623 meson.source_root() / 'scripts/qapi/error.py',
624 meson.source_root() / 'scripts/qapi/events.py',
625 meson.source_root() / 'scripts/qapi/expr.py',
626 meson.source_root() / 'scripts/qapi/gen.py',
627 meson.source_root() / 'scripts/qapi/introspect.py',
628 meson.source_root() / 'scripts/qapi/parser.py',
629 meson.source_root() / 'scripts/qapi/schema.py',
630 meson.source_root() / 'scripts/qapi/source.py',
631 meson.source_root() / 'scripts/qapi/types.py',
632 meson.source_root() / 'scripts/qapi/visit.py',
633 meson.source_root() / 'scripts/qapi/common.py',
634 meson.source_root() / 'scripts/qapi/doc.py',
635 meson.source_root() / 'scripts/qapi-gen.py'
636 ]
637
638 tracetool = [
639 python, files('scripts/tracetool.py'),
640 '--backend=' + config_host['TRACE_BACKENDS']
641 ]
642
643 qemu_version_cmd = [find_program('scripts/qemu-version.sh'),
644 meson.current_source_dir(),
645 config_host['PKGVERSION'], meson.project_version()]
646 qemu_version = custom_target('qemu-version.h',
647 output: 'qemu-version.h',
648 command: qemu_version_cmd,
649 capture: true,
650 build_by_default: true,
651 build_always_stale: true)
652 genh += qemu_version
653
654 hxdep = []
655 hx_headers = [
656 ['qemu-options.hx', 'qemu-options.def'],
657 ['qemu-img-cmds.hx', 'qemu-img-cmds.h'],
658 ]
659 if have_system
660 hx_headers += [
661 ['hmp-commands.hx', 'hmp-commands.h'],
662 ['hmp-commands-info.hx', 'hmp-commands-info.h'],
663 ]
664 endif
665 foreach d : hx_headers
666 hxdep += custom_target(d[1],
667 input: files(d[0]),
668 output: d[1],
669 capture: true,
670 build_by_default: true, # to be removed when added to a target
671 command: [hxtool, '-h', '@INPUT0@'])
672 endforeach
673 genh += hxdep
674
675 # Collect sourcesets.
676
677 util_ss = ss.source_set()
678 stub_ss = ss.source_set()
679 trace_ss = ss.source_set()
680 block_ss = ss.source_set()
681 blockdev_ss = ss.source_set()
682 qmp_ss = ss.source_set()
683 common_ss = ss.source_set()
684 softmmu_ss = ss.source_set()
685 user_ss = ss.source_set()
686 bsd_user_ss = ss.source_set()
687 linux_user_ss = ss.source_set()
688 specific_ss = ss.source_set()
689 specific_fuzz_ss = ss.source_set()
690
691 modules = {}
692 hw_arch = {}
693 target_arch = {}
694 target_softmmu_arch = {}
695
696 ###############
697 # Trace files #
698 ###############
699
700 # TODO: add each directory to the subdirs from its own meson.build, once
701 # we have those
702 trace_events_subdirs = [
703 'accel/kvm',
704 'accel/tcg',
705 'crypto',
706 'monitor',
707 ]
708 if have_user
709 trace_events_subdirs += [ 'linux-user' ]
710 endif
711 if have_block
712 trace_events_subdirs += [
713 'authz',
714 'block',
715 'io',
716 'nbd',
717 'scsi',
718 ]
719 endif
720 if have_system
721 trace_events_subdirs += [
722 'audio',
723 'backends',
724 'backends/tpm',
725 'chardev',
726 'hw/9pfs',
727 'hw/acpi',
728 'hw/alpha',
729 'hw/arm',
730 'hw/audio',
731 'hw/block',
732 'hw/block/dataplane',
733 'hw/char',
734 'hw/display',
735 'hw/dma',
736 'hw/hppa',
737 'hw/hyperv',
738 'hw/i2c',
739 'hw/i386',
740 'hw/i386/xen',
741 'hw/ide',
742 'hw/input',
743 'hw/intc',
744 'hw/isa',
745 'hw/mem',
746 'hw/mips',
747 'hw/misc',
748 'hw/misc/macio',
749 'hw/net',
750 'hw/nvram',
751 'hw/pci',
752 'hw/pci-host',
753 'hw/ppc',
754 'hw/rdma',
755 'hw/rdma/vmw',
756 'hw/rtc',
757 'hw/s390x',
758 'hw/scsi',
759 'hw/sd',
760 'hw/sparc',
761 'hw/sparc64',
762 'hw/ssi',
763 'hw/timer',
764 'hw/tpm',
765 'hw/usb',
766 'hw/vfio',
767 'hw/virtio',
768 'hw/watchdog',
769 'hw/xen',
770 'hw/gpio',
771 'migration',
772 'net',
773 'softmmu',
774 'ui',
775 ]
776 endif
777 trace_events_subdirs += [
778 'hw/core',
779 'qapi',
780 'qom',
781 'target/arm',
782 'target/hppa',
783 'target/i386',
784 'target/mips',
785 'target/ppc',
786 'target/riscv',
787 'target/s390x',
788 'target/sparc',
789 'util',
790 ]
791
792 subdir('qapi')
793 subdir('qobject')
794 subdir('stubs')
795 subdir('trace')
796 subdir('util')
797 subdir('qom')
798 subdir('authz')
799 subdir('crypto')
800 subdir('ui')
801
802
803 if enable_modules
804 libmodulecommon = static_library('module-common', files('module-common.c') + genh, pic: true, c_args: '-DBUILD_DSO')
805 modulecommon = declare_dependency(link_whole: libmodulecommon, compile_args: '-DBUILD_DSO')
806 endif
807
808 # Build targets from sourcesets
809
810 stub_ss = stub_ss.apply(config_all, strict: false)
811
812 util_ss.add_all(trace_ss)
813 util_ss = util_ss.apply(config_all, strict: false)
814 libqemuutil = static_library('qemuutil',
815 sources: util_ss.sources() + stub_ss.sources() + genh,
816 dependencies: [util_ss.dependencies(), m, glib, socket])
817 qemuutil = declare_dependency(link_with: libqemuutil,
818 sources: genh + version_res)
819
820 decodetree = generator(find_program('scripts/decodetree.py'),
821 output: 'decode-@BASENAME@.c.inc',
822 arguments: ['@INPUT@', '@EXTRA_ARGS@', '-o', '@OUTPUT@'])
823
824 subdir('audio')
825 subdir('io')
826 subdir('chardev')
827 subdir('fsdev')
828 subdir('libdecnumber')
829 subdir('target')
830 subdir('dump')
831
832 block_ss.add(files(
833 'block.c',
834 'blockjob.c',
835 'job.c',
836 'qemu-io-cmds.c',
837 ))
838 block_ss.add(when: 'CONFIG_REPLICATION', if_true: files('replication.c'))
839
840 subdir('nbd')
841 subdir('scsi')
842 subdir('block')
843
844 blockdev_ss.add(files(
845 'blockdev.c',
846 'blockdev-nbd.c',
847 'iothread.c',
848 'job-qmp.c',
849 ))
850
851 # os-posix.c contains POSIX-specific functions used by qemu-storage-daemon,
852 # os-win32.c does not
853 blockdev_ss.add(when: 'CONFIG_POSIX', if_true: files('os-posix.c'))
854 softmmu_ss.add(when: 'CONFIG_WIN32', if_true: [files('os-win32.c')])
855
856 softmmu_ss.add_all(blockdev_ss)
857 softmmu_ss.add(files(
858 'bootdevice.c',
859 'dma-helpers.c',
860 'qdev-monitor.c',
861 ), sdl)
862
863 softmmu_ss.add(when: 'CONFIG_TPM', if_true: files('tpm.c'))
864 softmmu_ss.add(when: 'CONFIG_SECCOMP', if_true: [files('qemu-seccomp.c'), seccomp])
865 softmmu_ss.add(when: ['CONFIG_FDT', fdt], if_true: [files('device_tree.c')])
866
867 common_ss.add(files('cpus-common.c'))
868
869 subdir('softmmu')
870
871 specific_ss.add(files('disas.c', 'exec.c', 'gdbstub.c'), capstone, libpmem, libdaxctl)
872 specific_ss.add(files('exec-vary.c'))
873 specific_ss.add(when: 'CONFIG_TCG', if_true: files(
874 'fpu/softfloat.c',
875 'tcg/optimize.c',
876 'tcg/tcg-common.c',
877 'tcg/tcg-op-gvec.c',
878 'tcg/tcg-op-vec.c',
879 'tcg/tcg-op.c',
880 'tcg/tcg.c',
881 ))
882 specific_ss.add(when: 'CONFIG_TCG_INTERPRETER', if_true: files('disas/tci.c', 'tcg/tci.c'))
883
884 subdir('backends')
885 subdir('disas')
886 subdir('migration')
887 subdir('monitor')
888 subdir('net')
889 subdir('replay')
890 subdir('hw')
891 subdir('accel')
892 subdir('plugins')
893 subdir('bsd-user')
894 subdir('linux-user')
895
896 bsd_user_ss.add(files('gdbstub.c'))
897 specific_ss.add_all(when: 'CONFIG_BSD_USER', if_true: bsd_user_ss)
898
899 linux_user_ss.add(files('gdbstub.c', 'thunk.c'))
900 specific_ss.add_all(when: 'CONFIG_LINUX_USER', if_true: linux_user_ss)
901
902 # needed for fuzzing binaries
903 subdir('tests/qtest/libqos')
904 subdir('tests/qtest/fuzz')
905
906 block_mods = []
907 softmmu_mods = []
908 foreach d, list : modules
909 foreach m, module_ss : list
910 if enable_modules and targetos != 'windows'
911 module_ss = module_ss.apply(config_all, strict: false)
912 sl = static_library(d + '-' + m, [genh, module_ss.sources()],
913 dependencies: [modulecommon, module_ss.dependencies()], pic: true)
914 if d == 'block'
915 block_mods += sl
916 else
917 softmmu_mods += sl
918 endif
919 else
920 if d == 'block'
921 block_ss.add_all(module_ss)
922 else
923 softmmu_ss.add_all(module_ss)
924 endif
925 endif
926 endforeach
927 endforeach
928
929 nm = find_program('nm')
930 undefsym = find_program('scripts/undefsym.py')
931 block_syms = custom_target('block.syms', output: 'block.syms',
932 input: [libqemuutil, block_mods],
933 capture: true,
934 command: [undefsym, nm, '@INPUT@'])
935 qemu_syms = custom_target('qemu.syms', output: 'qemu.syms',
936 input: [libqemuutil, softmmu_mods],
937 capture: true,
938 command: [undefsym, nm, '@INPUT@'])
939
940 block_ss = block_ss.apply(config_host, strict: false)
941 libblock = static_library('block', block_ss.sources() + genh,
942 dependencies: block_ss.dependencies(),
943 link_depends: block_syms,
944 name_suffix: 'fa',
945 build_by_default: false)
946
947 block = declare_dependency(link_whole: [libblock],
948 link_args: '@block.syms',
949 dependencies: [crypto, io])
950
951 qmp_ss = qmp_ss.apply(config_host, strict: false)
952 libqmp = static_library('qmp', qmp_ss.sources() + genh,
953 dependencies: qmp_ss.dependencies(),
954 name_suffix: 'fa',
955 build_by_default: false)
956
957 qmp = declare_dependency(link_whole: [libqmp])
958
959 foreach m : block_mods + softmmu_mods
960 shared_module(m.name(),
961 name_prefix: '',
962 link_whole: m,
963 install: true,
964 install_dir: config_host['qemu_moddir'])
965 endforeach
966
967 softmmu_ss.add(authz, block, chardev, crypto, io, qmp)
968 common_ss.add(qom, qemuutil)
969
970 common_ss.add_all(when: 'CONFIG_SOFTMMU', if_true: [softmmu_ss])
971 common_ss.add_all(when: 'CONFIG_USER_ONLY', if_true: user_ss)
972
973 common_all = common_ss.apply(config_all, strict: false)
974 common_all = static_library('common',
975 build_by_default: false,
976 sources: common_all.sources() + genh,
977 dependencies: common_all.dependencies(),
978 name_suffix: 'fa')
979
980 feature_to_c = find_program('scripts/feature_to_c.sh')
981
982 emulators = []
983 foreach target : target_dirs
984 config_target = config_target_mak[target]
985 target_name = config_target['TARGET_NAME']
986 arch = config_target['TARGET_BASE_ARCH']
987 arch_srcs = [config_target_h[target]]
988 arch_deps = []
989 c_args = ['-DNEED_CPU_H',
990 '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
991 '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
992 link_args = []
993
994 config_target += config_host
995 target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
996 if targetos == 'linux'
997 target_inc += include_directories('linux-headers', is_system: true)
998 endif
999 if target.endswith('-softmmu')
1000 qemu_target_name = 'qemu-system-' + target_name
1001 target_type='system'
1002 t = target_softmmu_arch[arch].apply(config_target, strict: false)
1003 arch_srcs += t.sources()
1004 arch_deps += t.dependencies()
1005
1006 hw_dir = target_name == 'sparc64' ? 'sparc64' : arch
1007 hw = hw_arch[hw_dir].apply(config_target, strict: false)
1008 arch_srcs += hw.sources()
1009 arch_deps += hw.dependencies()
1010
1011 arch_srcs += config_devices_h[target]
1012 link_args += ['@block.syms', '@qemu.syms']
1013 else
1014 abi = config_target['TARGET_ABI_DIR']
1015 target_type='user'
1016 qemu_target_name = 'qemu-' + target_name
1017 if 'CONFIG_LINUX_USER' in config_target
1018 base_dir = 'linux-user'
1019 target_inc += include_directories('linux-user/host/' / config_host['ARCH'])
1020 else
1021 base_dir = 'bsd-user'
1022 endif
1023 target_inc += include_directories(
1024 base_dir,
1025 base_dir / abi,
1026 )
1027 if 'CONFIG_LINUX_USER' in config_target
1028 dir = base_dir / abi
1029 arch_srcs += files(dir / 'signal.c', dir / 'cpu_loop.c')
1030 if config_target.has_key('TARGET_SYSTBL_ABI')
1031 arch_srcs += \
1032 syscall_nr_generators[abi].process(base_dir / abi / config_target['TARGET_SYSTBL'],
1033 extra_args : config_target['TARGET_SYSTBL_ABI'])
1034 endif
1035 endif
1036 endif
1037
1038 if 'TARGET_XML_FILES' in config_target
1039 gdbstub_xml = custom_target(target + '-gdbstub-xml.c',
1040 output: target + '-gdbstub-xml.c',
1041 input: files(config_target['TARGET_XML_FILES'].split()),
1042 command: [feature_to_c, '@INPUT@'],
1043 capture: true)
1044 arch_srcs += gdbstub_xml
1045 endif
1046
1047 t = target_arch[arch].apply(config_target, strict: false)
1048 arch_srcs += t.sources()
1049 arch_deps += t.dependencies()
1050
1051 target_common = common_ss.apply(config_target, strict: false)
1052 objects = common_all.extract_objects(target_common.sources())
1053 deps = target_common.dependencies()
1054
1055 target_specific = specific_ss.apply(config_target, strict: false)
1056 arch_srcs += target_specific.sources()
1057 arch_deps += target_specific.dependencies()
1058
1059 lib = static_library('qemu-' + target,
1060 sources: arch_srcs + genh,
1061 dependencies: arch_deps,
1062 objects: objects,
1063 include_directories: target_inc,
1064 c_args: c_args,
1065 build_by_default: false,
1066 name_suffix: 'fa')
1067
1068 if target.endswith('-softmmu')
1069 execs = [{
1070 'name': 'qemu-system-' + target_name,
1071 'gui': false,
1072 'sources': files('softmmu/main.c'),
1073 'dependencies': []
1074 }]
1075 if targetos == 'windows' and (sdl.found() or gtk.found())
1076 execs += [{
1077 'name': 'qemu-system-' + target_name + 'w',
1078 'gui': true,
1079 'sources': files('softmmu/main.c'),
1080 'dependencies': []
1081 }]
1082 endif
1083 if config_host.has_key('CONFIG_FUZZ')
1084 specific_fuzz = specific_fuzz_ss.apply(config_target, strict: false)
1085 execs += [{
1086 'name': 'qemu-fuzz-' + target_name,
1087 'gui': false,
1088 'sources': specific_fuzz.sources(),
1089 'dependencies': specific_fuzz.dependencies(),
1090 }]
1091 endif
1092 else
1093 execs = [{
1094 'name': 'qemu-' + target_name,
1095 'gui': false,
1096 'sources': [],
1097 'dependencies': []
1098 }]
1099 endif
1100 foreach exe: execs
1101 emulators += executable(exe['name'], exe['sources'],
1102 install: true,
1103 c_args: c_args,
1104 dependencies: arch_deps + deps + exe['dependencies'],
1105 objects: lib.extract_all_objects(recursive: true),
1106 link_language: link_language,
1107 link_depends: [block_syms, qemu_syms] + exe.get('link_depends', []),
1108 link_args: link_args,
1109 gui_app: exe['gui'])
1110
1111 if 'CONFIG_TRACE_SYSTEMTAP' in config_host
1112 foreach stp: [
1113 {'ext': '.stp-build', 'fmt': 'stap', 'bin': meson.current_build_dir() / exe['name'], 'install': false},
1114 {'ext': '.stp', 'fmt': 'stap', 'bin': get_option('prefix') / get_option('bindir') / exe['name'], 'install': true},
1115 {'ext': '-simpletrace.stp', 'fmt': 'simpletrace-stap', 'bin': '', 'install': true},
1116 {'ext': '-log.stp', 'fmt': 'log-stap', 'bin': '', 'install': true},
1117 ]
1118 custom_target(exe['name'] + stp['ext'],
1119 input: trace_events_all,
1120 output: exe['name'] + stp['ext'],
1121 capture: true,
1122 install: stp['install'],
1123 install_dir: qemu_datadir / '../systemtap/tapset',
1124 command: [
1125 tracetool, '--group=all', '--format=' + stp['fmt'],
1126 '--binary=' + stp['bin'],
1127 '--target-name=' + target_name,
1128 '--target-type=' + target_type,
1129 '--probe-prefix=qemu.' + target_type + '.' + target_name,
1130 '@INPUT@',
1131 ])
1132 endforeach
1133 endif
1134 endforeach
1135 endforeach
1136
1137 # Other build targets
1138
1139 if 'CONFIG_PLUGIN' in config_host
1140 install_headers('include/qemu/qemu-plugin.h')
1141 endif
1142
1143 if 'CONFIG_GUEST_AGENT' in config_host
1144 subdir('qga')
1145 endif
1146
1147 # Don't build qemu-keymap if xkbcommon is not explicitly enabled
1148 # when we don't build tools or system
1149 if xkbcommon.found()
1150 # used for the update-keymaps target, so include rules even if !have_tools
1151 qemu_keymap = executable('qemu-keymap', files('qemu-keymap.c', 'ui/input-keymap.c') + genh,
1152 dependencies: [qemuutil, xkbcommon], install: have_tools)
1153 endif
1154
1155 qemu_block_tools = []
1156 if have_tools
1157 qemu_img = executable('qemu-img', [files('qemu-img.c'), hxdep],
1158 dependencies: [authz, block, crypto, io, qom, qemuutil], install: true)
1159 qemu_io = executable('qemu-io', files('qemu-io.c'),
1160 dependencies: [block, qemuutil], install: true)
1161 qemu_nbd = executable('qemu-nbd', files('qemu-nbd.c'),
1162 dependencies: [block, qemuutil], install: true)
1163
1164 subdir('storage-daemon')
1165 subdir('contrib/rdmacm-mux')
1166 subdir('contrib/elf2dmp')
1167
1168 executable('qemu-edid', files('qemu-edid.c', 'hw/display/edid-generate.c'),
1169 dependencies: qemuutil,
1170 install: true)
1171
1172 if 'CONFIG_VHOST_USER' in config_host
1173 subdir('contrib/libvhost-user')
1174 subdir('contrib/vhost-user-blk')
1175 subdir('contrib/vhost-user-gpu')
1176 subdir('contrib/vhost-user-input')
1177 subdir('contrib/vhost-user-scsi')
1178 endif
1179
1180 if targetos == 'linux'
1181 executable('qemu-bridge-helper', files('qemu-bridge-helper.c'),
1182 dependencies: [qemuutil, libcap_ng],
1183 install: true,
1184 install_dir: get_option('libexecdir'))
1185
1186 executable('qemu-pr-helper', files('scsi/qemu-pr-helper.c', 'scsi/utils.c'),
1187 dependencies: [authz, crypto, io, qom, qemuutil,
1188 libcap_ng, libudev, libmpathpersist],
1189 install: true)
1190 endif
1191
1192 if 'CONFIG_IVSHMEM' in config_host
1193 subdir('contrib/ivshmem-client')
1194 subdir('contrib/ivshmem-server')
1195 endif
1196 endif
1197
1198 subdir('scripts')
1199 subdir('tools')
1200 subdir('pc-bios')
1201 subdir('tests')
1202 subdir('docs')
1203 if 'CONFIG_GTK' in config_host
1204 subdir('po')
1205 endif
1206
1207 if build_docs
1208 makeinfo = find_program('makeinfo', required: build_docs)
1209
1210 docs_inc = [
1211 '-I', meson.current_source_dir(),
1212 '-I', meson.current_build_dir() / 'docs',
1213 '-I', '@OUTDIR@',
1214 ]
1215
1216 version_texi = configure_file(output: 'version.texi',
1217 input: 'version.texi.in',
1218 configuration: {'VERSION': meson.project_version(),
1219 'qemu_confdir': config_host['qemu_confdir']})
1220
1221 texi = {
1222 'qemu-qmp-ref': ['docs/interop/qemu-qmp-ref.texi', qapi_doc_texi, version_texi],
1223 }
1224
1225 if makeinfo.found()
1226 cmd = [
1227 'env', 'LC_ALL=C', makeinfo, '--no-split', '--number-sections', docs_inc,
1228 '@INPUT0@', '-o', '@OUTPUT@',
1229 ]
1230 foreach ext, args: {
1231 'info': [],
1232 'html': ['--no-headers', '--html'],
1233 'txt': ['--no-headers', '--plaintext'],
1234 }
1235 t = []
1236 foreach doc, input: texi
1237 output = doc + '.' + ext
1238 t += custom_target(output,
1239 input: input,
1240 output: output,
1241 install: true,
1242 install_dir: qemu_docdir / 'interop',
1243 command: cmd + args)
1244 endforeach
1245 alias_target(ext, t)
1246 endforeach
1247 endif
1248
1249 texi2pdf = find_program('texi2pdf', required: false)
1250
1251 if texi2pdf.found()
1252 pdfs = []
1253 foreach doc, input: texi
1254 output = doc + '.pdf'
1255 pdfs += custom_target(output,
1256 input: input,
1257 output: output,
1258 command: [texi2pdf, '-q', docs_inc, '@INPUT0@', '-o', '@OUTPUT@'],
1259 build_by_default: false)
1260 endforeach
1261 alias_target('pdf', pdfs)
1262 endif
1263
1264 texi2pod = find_program('scripts/texi2pod.pl')
1265 pod2man = find_program('pod2man', required: build_docs)
1266
1267 if pod2man.found()
1268 foreach doc, input: texi
1269 man = doc + '.7'
1270 pod = custom_target(man + '.pod',
1271 input: input,
1272 output: man + '.pod',
1273 command: [texi2pod,
1274 '-DVERSION="' + meson.project_version() + '"',
1275 '-DCONFDIR="' + config_host['qemu_confdir'] + '"',
1276 '@INPUT0@', '@OUTPUT@'])
1277 man = custom_target(man,
1278 input: pod,
1279 output: man,
1280 capture: true,
1281 install: true,
1282 install_dir: get_option('mandir') / 'man7',
1283 command: [pod2man, '--utf8', '--section=7', '--center=" "',
1284 '--release=" "', '@INPUT@'])
1285 endforeach
1286 endif
1287 endif
1288
1289 if host_machine.system() == 'windows'
1290 nsis_cmd = [
1291 find_program('scripts/nsis.py'),
1292 '@OUTPUT@',
1293 get_option('prefix'),
1294 meson.current_source_dir(),
1295 host_machine.cpu_family(),
1296 '--',
1297 '-DDISPLAYVERSION=' + meson.project_version(),
1298 ]
1299 if build_docs
1300 nsis_cmd += '-DCONFIG_DOCUMENTATION=y'
1301 endif
1302 if 'CONFIG_GTK' in config_host
1303 nsis_cmd += '-DCONFIG_GTK=y'
1304 endif
1305
1306 nsis = custom_target('nsis',
1307 output: 'qemu-setup-' + meson.project_version() + '.exe',
1308 input: files('qemu.nsi'),
1309 build_always_stale: true,
1310 command: nsis_cmd + ['@INPUT@'])
1311 alias_target('installer', nsis)
1312 endif
1313
1314 summary_info = {}
1315 summary_info += {'Install prefix': config_host['prefix']}
1316 summary_info += {'BIOS directory': config_host['qemu_datadir']}
1317 summary_info += {'firmware path': config_host['qemu_firmwarepath']}
1318 summary_info += {'binary directory': config_host['bindir']}
1319 summary_info += {'library directory': config_host['libdir']}
1320 summary_info += {'module directory': config_host['qemu_moddir']}
1321 summary_info += {'libexec directory': config_host['libexecdir']}
1322 summary_info += {'include directory': config_host['includedir']}
1323 summary_info += {'config directory': config_host['sysconfdir']}
1324 if targetos != 'windows'
1325 summary_info += {'local state directory': config_host['qemu_localstatedir']}
1326 summary_info += {'Manual directory': get_option('mandir')}
1327 else
1328 summary_info += {'local state directory': 'queried at runtime'}
1329 endif
1330 summary_info += {'Doc directory': get_option('docdir')}
1331 summary_info += {'Build directory': meson.current_build_dir()}
1332 summary_info += {'Source path': meson.current_source_dir()}
1333 summary_info += {'GIT binary': config_host['GIT']}
1334 summary_info += {'GIT submodules': config_host['GIT_SUBMODULES']}
1335 summary_info += {'C compiler': meson.get_compiler('c').cmd_array()[0]}
1336 summary_info += {'Host C compiler': meson.get_compiler('c', native: true).cmd_array()[0]}
1337 if link_language == 'cpp'
1338 summary_info += {'C++ compiler': meson.get_compiler('cpp').cmd_array()[0]}
1339 else
1340 summary_info += {'C++ compiler': false}
1341 endif
1342 if targetos == 'darwin'
1343 summary_info += {'Objective-C compiler': meson.get_compiler('objc').cmd_array()[0]}
1344 endif
1345 summary_info += {'ARFLAGS': config_host['ARFLAGS']}
1346 summary_info += {'CFLAGS': config_host['CFLAGS']}
1347 summary_info += {'QEMU_CFLAGS': config_host['QEMU_CFLAGS']}
1348 summary_info += {'QEMU_LDFLAGS': config_host['QEMU_LDFLAGS']}
1349 summary_info += {'make': config_host['MAKE']}
1350 summary_info += {'python': '@0@ (version: @1@)'.format(python.full_path(), python.language_version())}
1351 summary_info += {'sphinx-build': config_host['SPHINX_BUILD']}
1352 summary_info += {'genisoimage': config_host['GENISOIMAGE']}
1353 # TODO: add back version
1354 summary_info += {'slirp support': config_host.has_key('CONFIG_SLIRP')}
1355 if config_host.has_key('CONFIG_SLIRP')
1356 summary_info += {'smbd': config_host['CONFIG_SMBD_COMMAND']}
1357 endif
1358 summary_info += {'module support': config_host.has_key('CONFIG_MODULES')}
1359 if config_host.has_key('CONFIG_MODULES')
1360 summary_info += {'alternative module path': config_host.has_key('CONFIG_MODULE_UPGRADES')}
1361 endif
1362 summary_info += {'host CPU': cpu}
1363 summary_info += {'host endianness': build_machine.endian()}
1364 summary_info += {'target list': config_host['TARGET_DIRS']}
1365 summary_info += {'gprof enabled': config_host.has_key('CONFIG_GPROF')}
1366 summary_info += {'sparse enabled': meson.get_compiler('c').cmd_array().contains('cgcc')}
1367 summary_info += {'strip binaries': get_option('strip')}
1368 summary_info += {'profiler': config_host.has_key('CONFIG_PROFILER')}
1369 summary_info += {'static build': config_host.has_key('CONFIG_STATIC')}
1370 if targetos == 'darwin'
1371 summary_info += {'Cocoa support': config_host.has_key('CONFIG_COCOA')}
1372 endif
1373 # TODO: add back version
1374 summary_info += {'SDL support': sdl.found()}
1375 summary_info += {'SDL image support': sdl_image.found()}
1376 # TODO: add back version
1377 summary_info += {'GTK support': config_host.has_key('CONFIG_GTK')}
1378 summary_info += {'GTK GL support': config_host.has_key('CONFIG_GTK_GL')}
1379 summary_info += {'pixman': pixman.found()}
1380 # TODO: add back version
1381 summary_info += {'VTE support': config_host.has_key('CONFIG_VTE')}
1382 summary_info += {'TLS priority': config_host['CONFIG_TLS_PRIORITY']}
1383 summary_info += {'GNUTLS support': config_host.has_key('CONFIG_GNUTLS')}
1384 # TODO: add back version
1385 summary_info += {'libgcrypt': config_host.has_key('CONFIG_GCRYPT')}
1386 if config_host.has_key('CONFIG_GCRYPT')
1387 summary_info += {' hmac': config_host.has_key('CONFIG_GCRYPT_HMAC')}
1388 summary_info += {' XTS': not config_host.has_key('CONFIG_QEMU_PRIVATE_XTS')}
1389 endif
1390 # TODO: add back version
1391 summary_info += {'nettle': config_host.has_key('CONFIG_NETTLE')}
1392 if config_host.has_key('CONFIG_NETTLE')
1393 summary_info += {' XTS': not config_host.has_key('CONFIG_QEMU_PRIVATE_XTS')}
1394 endif
1395 summary_info += {'libtasn1': config_host.has_key('CONFIG_TASN1')}
1396 summary_info += {'PAM': config_host.has_key('CONFIG_AUTH_PAM')}
1397 summary_info += {'iconv support': config_host.has_key('CONFIG_ICONV')}
1398 summary_info += {'curses support': config_host.has_key('CONFIG_CURSES')}
1399 # TODO: add back version
1400 summary_info += {'virgl support': config_host.has_key('CONFIG_VIRGL')}
1401 summary_info += {'curl support': config_host.has_key('CONFIG_CURL')}
1402 summary_info += {'mingw32 support': targetos == 'windows'}
1403 summary_info += {'Audio drivers': config_host['CONFIG_AUDIO_DRIVERS']}
1404 summary_info += {'Block whitelist (rw)': config_host['CONFIG_BDRV_RW_WHITELIST']}
1405 summary_info += {'Block whitelist (ro)': config_host['CONFIG_BDRV_RO_WHITELIST']}
1406 summary_info += {'VirtFS support': config_host.has_key('CONFIG_VIRTFS')}
1407 summary_info += {'Multipath support': config_host.has_key('CONFIG_MPATH')}
1408 summary_info += {'VNC support': vnc.found()}
1409 if vnc.found()
1410 summary_info += {'VNC SASL support': sasl.found()}
1411 summary_info += {'VNC JPEG support': jpeg.found()}
1412 summary_info += {'VNC PNG support': png.found()}
1413 endif
1414 summary_info += {'xen support': config_host.has_key('CONFIG_XEN_BACKEND')}
1415 if config_host.has_key('CONFIG_XEN_BACKEND')
1416 summary_info += {'xen ctrl version': config_host['CONFIG_XEN_CTRL_INTERFACE_VERSION']}
1417 endif
1418 summary_info += {'brlapi support': config_host.has_key('CONFIG_BRLAPI')}
1419 summary_info += {'Documentation': config_host.has_key('BUILD_DOCS')}
1420 summary_info += {'PIE': get_option('b_pie')}
1421 summary_info += {'vde support': config_host.has_key('CONFIG_VDE')}
1422 summary_info += {'netmap support': config_host.has_key('CONFIG_NETMAP')}
1423 summary_info += {'Linux AIO support': config_host.has_key('CONFIG_LINUX_AIO')}
1424 summary_info += {'Linux io_uring support': config_host.has_key('CONFIG_LINUX_IO_URING')}
1425 summary_info += {'ATTR/XATTR support': config_host.has_key('CONFIG_ATTR')}
1426 summary_info += {'Install blobs': config_host.has_key('INSTALL_BLOBS')}
1427 # TODO: add back KVM/HAX/HVF/WHPX/TCG
1428 #summary_info += {'KVM support': have_kvm'}
1429 #summary_info += {'HAX support': have_hax'}
1430 #summary_info += {'HVF support': have_hvf'}
1431 #summary_info += {'WHPX support': have_whpx'}
1432 #summary_info += {'TCG support': have_tcg'}
1433 #if get_option('tcg')
1434 # summary_info += {'TCG debug enabled': config_host.has_key('CONFIG_DEBUG_TCG')}
1435 # summary_info += {'TCG interpreter': config_host.has_key('CONFIG_TCG_INTERPRETER')}
1436 #endif
1437 summary_info += {'malloc trim support': config_host.has_key('CONFIG_MALLOC_TRIM')}
1438 summary_info += {'RDMA support': config_host.has_key('CONFIG_RDMA')}
1439 summary_info += {'PVRDMA support': config_host.has_key('CONFIG_PVRDMA')}
1440 summary_info += {'fdt support': config_host.has_key('CONFIG_FDT')}
1441 summary_info += {'membarrier': config_host.has_key('CONFIG_MEMBARRIER')}
1442 summary_info += {'preadv support': config_host.has_key('CONFIG_PREADV')}
1443 summary_info += {'fdatasync': config_host.has_key('CONFIG_FDATASYNC')}
1444 summary_info += {'madvise': config_host.has_key('CONFIG_MADVISE')}
1445 summary_info += {'posix_madvise': config_host.has_key('CONFIG_POSIX_MADVISE')}
1446 summary_info += {'posix_memalign': config_host.has_key('CONFIG_POSIX_MEMALIGN')}
1447 summary_info += {'libcap-ng support': config_host.has_key('CONFIG_LIBCAP_NG')}
1448 summary_info += {'vhost-net support': config_host.has_key('CONFIG_VHOST_NET')}
1449 summary_info += {'vhost-crypto support': config_host.has_key('CONFIG_VHOST_CRYPTO')}
1450 summary_info += {'vhost-scsi support': config_host.has_key('CONFIG_VHOST_SCSI')}
1451 summary_info += {'vhost-vsock support': config_host.has_key('CONFIG_VHOST_VSOCK')}
1452 summary_info += {'vhost-user support': config_host.has_key('CONFIG_VHOST_KERNEL')}
1453 summary_info += {'vhost-user-fs support': config_host.has_key('CONFIG_VHOST_USER_FS')}
1454 summary_info += {'vhost-vdpa support': config_host.has_key('CONFIG_VHOST_VDPA')}
1455 summary_info += {'Trace backends': config_host['TRACE_BACKENDS']}
1456 if config_host['TRACE_BACKENDS'].split().contains('simple')
1457 summary_info += {'Trace output file': config_host['CONFIG_TRACE_FILE'] + '-<pid>'}
1458 endif
1459 # TODO: add back protocol and server version
1460 summary_info += {'spice support': config_host.has_key('CONFIG_SPICE')}
1461 summary_info += {'rbd support': config_host.has_key('CONFIG_RBD')}
1462 summary_info += {'xfsctl support': config_host.has_key('CONFIG_XFS')}
1463 summary_info += {'smartcard support': config_host.has_key('CONFIG_SMARTCARD')}
1464 summary_info += {'U2F support': u2f.found()}
1465 summary_info += {'libusb': config_host.has_key('CONFIG_USB_LIBUSB')}
1466 summary_info += {'usb net redir': config_host.has_key('CONFIG_USB_REDIR')}
1467 summary_info += {'OpenGL support': config_host.has_key('CONFIG_OPENGL')}
1468 summary_info += {'OpenGL dmabufs': config_host.has_key('CONFIG_OPENGL_DMABUF')}
1469 summary_info += {'libiscsi support': config_host.has_key('CONFIG_LIBISCSI')}
1470 summary_info += {'libnfs support': config_host.has_key('CONFIG_LIBNFS')}
1471 summary_info += {'build guest agent': config_host.has_key('CONFIG_GUEST_AGENT')}
1472 if targetos == 'windows'
1473 if 'WIN_SDK' in config_host
1474 summary_info += {'Windows SDK': config_host['WIN_SDK']}
1475 endif
1476 summary_info += {'QGA VSS support': config_host.has_key('CONFIG_QGA_VSS')}
1477 summary_info += {'QGA w32 disk info': config_host.has_key('CONFIG_QGA_NTDDSCSI')}
1478 summary_info += {'QGA MSI support': config_host.has_key('CONFIG_QGA_MSI_ENABLED')}
1479 endif
1480 summary_info += {'seccomp support': config_host.has_key('CONFIG_SECCOMP')}
1481 summary_info += {'coroutine backend': config_host['CONFIG_COROUTINE_BACKEND']}
1482 summary_info += {'coroutine pool': config_host['CONFIG_COROUTINE_POOL'] == '1'}
1483 summary_info += {'debug stack usage': config_host.has_key('CONFIG_DEBUG_STACK_USAGE')}
1484 summary_info += {'mutex debugging': config_host.has_key('CONFIG_DEBUG_MUTEX')}
1485 summary_info += {'crypto afalg': config_host.has_key('CONFIG_AF_ALG')}
1486 summary_info += {'GlusterFS support': config_host.has_key('CONFIG_GLUSTERFS')}
1487 summary_info += {'gcov': get_option('b_coverage')}
1488 summary_info += {'TPM support': config_host.has_key('CONFIG_TPM')}
1489 summary_info += {'libssh support': config_host.has_key('CONFIG_LIBSSH')}
1490 summary_info += {'QOM debugging': config_host.has_key('CONFIG_QOM_CAST_DEBUG')}
1491 summary_info += {'Live block migration': config_host.has_key('CONFIG_LIVE_BLOCK_MIGRATION')}
1492 summary_info += {'lzo support': config_host.has_key('CONFIG_LZO')}
1493 summary_info += {'snappy support': config_host.has_key('CONFIG_SNAPPY')}
1494 summary_info += {'bzip2 support': config_host.has_key('CONFIG_BZIP2')}
1495 summary_info += {'lzfse support': config_host.has_key('CONFIG_LZFSE')}
1496 summary_info += {'zstd support': config_host.has_key('CONFIG_ZSTD')}
1497 summary_info += {'NUMA host support': config_host.has_key('CONFIG_NUMA')}
1498 summary_info += {'libxml2': config_host.has_key('CONFIG_LIBXML2')}
1499 summary_info += {'tcmalloc support': config_host.has_key('CONFIG_TCMALLOC')}
1500 summary_info += {'jemalloc support': config_host.has_key('CONFIG_JEMALLOC')}
1501 summary_info += {'avx2 optimization': config_host.has_key('CONFIG_AVX2_OPT')}
1502 summary_info += {'avx512f optimization': config_host.has_key('CONFIG_AVX512F_OPT')}
1503 summary_info += {'replication support': config_host.has_key('CONFIG_REPLICATION')}
1504 summary_info += {'bochs support': config_host.has_key('CONFIG_BOCHS')}
1505 summary_info += {'cloop support': config_host.has_key('CONFIG_CLOOP')}
1506 summary_info += {'dmg support': config_host.has_key('CONFIG_DMG')}
1507 summary_info += {'qcow v1 support': config_host.has_key('CONFIG_QCOW1')}
1508 summary_info += {'vdi support': config_host.has_key('CONFIG_VDI')}
1509 summary_info += {'vvfat support': config_host.has_key('CONFIG_VVFAT')}
1510 summary_info += {'qed support': config_host.has_key('CONFIG_QED')}
1511 summary_info += {'parallels support': config_host.has_key('CONFIG_PARALLELS')}
1512 summary_info += {'sheepdog support': config_host.has_key('CONFIG_SHEEPDOG')}
1513 summary_info += {'capstone': config_host.has_key('CONFIG_CAPSTONE')}
1514 summary_info += {'libpmem support': config_host.has_key('CONFIG_LIBPMEM')}
1515 summary_info += {'libdaxctl support': config_host.has_key('CONFIG_LIBDAXCTL')}
1516 summary_info += {'libudev': config_host.has_key('CONFIG_LIBUDEV')}
1517 summary_info += {'default devices': config_host['CONFIG_MINIKCONF_MODE'] == '--defconfig'}
1518 summary_info += {'plugin support': config_host.has_key('CONFIG_PLUGIN')}
1519 summary_info += {'fuzzing support': config_host.has_key('CONFIG_FUZZ')}
1520 if config_host.has_key('HAVE_GDB_BIN')
1521 summary_info += {'gdb': config_host['HAVE_GDB_BIN']}
1522 endif
1523 summary_info += {'thread sanitizer': config_host.has_key('CONFIG_TSAN')}
1524 summary_info += {'rng-none': config_host.has_key('CONFIG_RNG_NONE')}
1525 summary_info += {'Linux keyring': config_host.has_key('CONFIG_SECRET_KEYRING')}
1526 summary(summary_info, bool_yn: true)
1527
1528 if not supported_cpus.contains(cpu)
1529 message()
1530 warning('SUPPORT FOR THIS HOST CPU WILL GO AWAY IN FUTURE RELEASES!')
1531 message()
1532 message('CPU host architecture ' + cpu + ' support is not currently maintained.')
1533 message('The QEMU project intends to remove support for this host CPU in')
1534 message('a future release if nobody volunteers to maintain it and to')
1535 message('provide a build host for our continuous integration setup.')
1536 message('configure has succeeded and you can continue to build, but')
1537 message('if you care about QEMU on this platform you should contact')
1538 message('us upstream at qemu-devel@nongnu.org.')
1539 endif
1540
1541 if not supported_oses.contains(targetos)
1542 message()
1543 warning('WARNING: SUPPORT FOR THIS HOST OS WILL GO AWAY IN FUTURE RELEASES!')
1544 message()
1545 message('Host OS ' + targetos + 'support is not currently maintained.')
1546 message('The QEMU project intends to remove support for this host OS in')
1547 message('a future release if nobody volunteers to maintain it and to')
1548 message('provide a build host for our continuous integration setup.')
1549 message('configure has succeeded and you can continue to build, but')
1550 message('if you care about QEMU on this platform you should contact')
1551 message('us upstream at qemu-devel@nongnu.org.')
1552 endif