xref: /openbmc/qemu/meson.build (revision 708eab42)
1project('qemu', ['c'], meson_version: '>=0.55.0',
2        default_options: ['warning_level=1', 'c_std=gnu99', 'cpp_std=gnu++11', 'b_lundef=false'],
3        version: run_command('head', meson.source_root() / 'VERSION').stdout().strip())
4
5not_found = dependency('', required: false)
6keyval = import('unstable-keyval')
7ss = import('sourceset')
8
9sh = find_program('sh')
10cc = meson.get_compiler('c')
11config_host = keyval.load(meson.current_build_dir() / 'config-host.mak')
12config_all_disas = keyval.load(meson.current_build_dir() / 'config-all-disas.mak')
13enable_modules = 'CONFIG_MODULES' in config_host
14
15add_project_arguments(config_host['QEMU_CFLAGS'].split(),
16                      native: false, language: ['c', 'objc'])
17add_project_arguments(config_host['QEMU_CXXFLAGS'].split(),
18                      native: false, language: 'cpp')
19add_project_link_arguments(config_host['QEMU_LDFLAGS'].split(),
20                           native: false, language: ['c', 'cpp', 'objc'])
21add_project_arguments(config_host['QEMU_INCLUDES'].split(),
22                      language: ['c', 'cpp', 'objc'])
23
24python = import('python').find_installation()
25
26link_language = meson.get_external_property('link_language', 'cpp')
27if link_language == 'cpp'
28  add_languages('cpp', required: true, native: false)
29endif
30if host_machine.system() == 'darwin'
31  add_languages('objc', required: false, native: false)
32endif
33
34if 'SPARSE_CFLAGS' in config_host
35  run_target('sparse',
36             command: [find_program('scripts/check_sparse.py'),
37                       config_host['SPARSE_CFLAGS'].split(),
38                       'compile_commands.json'])
39endif
40
41configure_file(input: files('scripts/ninjatool.py'),
42               output: 'ninjatool',
43               configuration: config_host)
44
45supported_oses = ['windows', 'freebsd', 'netbsd', 'openbsd', 'darwin', 'sunos', 'linux']
46supported_cpus = ['ppc', 'ppc64', 's390x', 'sparc64', 'riscv32', 'riscv64', 'x86', 'x86_64',
47  'arm', 'aarch64', 'mips', 'mips64', 'sparc', 'sparc64']
48
49cpu = host_machine.cpu_family()
50targetos = host_machine.system()
51
52m = cc.find_library('m', required: false)
53util = cc.find_library('util', required: false)
54winmm = []
55socket = []
56version_res = []
57coref = []
58iokit = []
59cocoa = []
60hvf = []
61if targetos == 'windows'
62  socket = cc.find_library('ws2_32')
63  winmm = cc.find_library('winmm')
64
65  win = import('windows')
66  version_res = win.compile_resources('version.rc',
67                                      depend_files: files('pc-bios/qemu-nsis.ico'),
68                                      include_directories: include_directories('.'))
69elif targetos == 'darwin'
70  coref = dependency('appleframeworks', modules: 'CoreFoundation')
71  iokit = dependency('appleframeworks', modules: 'IOKit')
72  cocoa = dependency('appleframeworks', modules: 'Cocoa')
73  hvf = dependency('appleframeworks', modules: 'Hypervisor')
74elif targetos == 'sunos'
75  socket = [cc.find_library('socket'),
76            cc.find_library('nsl'),
77            cc.find_library('resolv')]
78elif targetos == 'haiku'
79  socket = [cc.find_library('posix_error_mapper'),
80            cc.find_library('network'),
81            cc.find_library('bsd')]
82endif
83glib = declare_dependency(compile_args: config_host['GLIB_CFLAGS'].split(),
84                          link_args: config_host['GLIB_LIBS'].split())
85gio = not_found
86if 'CONFIG_GIO' in config_host
87  gio = declare_dependency(compile_args: config_host['GIO_CFLAGS'].split(),
88                           link_args: config_host['GIO_LIBS'].split())
89endif
90lttng = not_found
91if 'CONFIG_TRACE_UST' in config_host
92  lttng = declare_dependency(link_args: config_host['LTTNG_UST_LIBS'].split())
93endif
94urcubp = not_found
95if 'CONFIG_TRACE_UST' in config_host
96  urcubp = declare_dependency(link_args: config_host['URCU_BP_LIBS'].split())
97endif
98nettle = not_found
99if 'CONFIG_NETTLE' in config_host
100  nettle = declare_dependency(compile_args: config_host['NETTLE_CFLAGS'].split(),
101                              link_args: config_host['NETTLE_LIBS'].split())
102endif
103gnutls = not_found
104if 'CONFIG_GNUTLS' in config_host
105  gnutls = declare_dependency(compile_args: config_host['GNUTLS_CFLAGS'].split(),
106                              link_args: config_host['GNUTLS_LIBS'].split())
107endif
108pixman = declare_dependency(compile_args: config_host['PIXMAN_CFLAGS'].split(),
109                            link_args: config_host['PIXMAN_LIBS'].split())
110pam = not_found
111if 'CONFIG_AUTH_PAM' in config_host
112  pam = cc.find_library('pam')
113endif
114libaio = cc.find_library('aio', required: false)
115zlib = not_found
116if 'CONFIG_ZLIB' in config_host
117  zlib = declare_dependency(compile_args: config_host['ZLIB_CFLAGS'].split(),
118                            link_args: config_host['ZLIB_LIBS'].split())
119endif
120linux_io_uring = not_found
121if 'CONFIG_LINUX_IO_URING' in config_host
122  linux_io_uring = declare_dependency(compile_args: config_host['LINUX_IO_URING_CFLAGS'].split(),
123                                      link_args: config_host['LINUX_IO_URING_LIBS'].split())
124endif
125libxml2 = not_found
126if 'CONFIG_LIBXML2' in config_host
127  libxml2 = declare_dependency(compile_args: config_host['LIBXML2_CFLAGS'].split(),
128                               link_args: config_host['LIBXML2_LIBS'].split())
129endif
130libnfs = not_found
131if 'CONFIG_LIBNFS' in config_host
132  libnfs = declare_dependency(link_args: config_host['LIBNFS_LIBS'].split())
133endif
134libattr = not_found
135if 'CONFIG_ATTR' in config_host
136  libattr = declare_dependency(link_args: config_host['LIBATTR_LIBS'].split())
137endif
138seccomp = not_found
139if 'CONFIG_SECCOMP' in config_host
140  seccomp = declare_dependency(compile_args: config_host['SECCOMP_CFLAGS'].split(),
141                               link_args: config_host['SECCOMP_LIBS'].split())
142endif
143libcap_ng = not_found
144if 'CONFIG_LIBCAP_NG' in config_host
145  libcap_ng = declare_dependency(link_args: config_host['LIBCAP_NG_LIBS'].split())
146endif
147xkbcommon = not_found
148if 'CONFIG_XKBCOMMON' in config_host
149  xkbcommon = declare_dependency(compile_args: config_host['XKBCOMMON_CFLAGS'].split(),
150                                 link_args: config_host['XKBCOMMON_LIBS'].split())
151endif
152pulse = not_found
153if 'CONFIG_LIBPULSE' in config_host
154  pulse = declare_dependency(compile_args: config_host['PULSE_CFLAGS'].split(),
155                             link_args: config_host['PULSE_LIBS'].split())
156endif
157alsa = not_found
158if 'CONFIG_ALSA' in config_host
159  alsa = declare_dependency(compile_args: config_host['ALSA_CFLAGS'].split(),
160                            link_args: config_host['ALSA_LIBS'].split())
161endif
162jack = not_found
163if 'CONFIG_LIBJACK' in config_host
164  jack = declare_dependency(link_args: config_host['JACK_LIBS'].split())
165endif
166spice = not_found
167if 'CONFIG_SPICE' in config_host
168  spice = declare_dependency(compile_args: config_host['SPICE_CFLAGS'].split(),
169                             link_args: config_host['SPICE_LIBS'].split())
170endif
171rt = cc.find_library('rt', required: false)
172libmpathpersist = not_found
173if config_host.has_key('CONFIG_MPATH')
174  libmpathpersist = cc.find_library('mpathpersist')
175endif
176libiscsi = not_found
177if 'CONFIG_LIBISCSI' in config_host
178  libiscsi = declare_dependency(compile_args: config_host['LIBISCSI_CFLAGS'].split(),
179                                link_args: config_host['LIBISCSI_LIBS'].split())
180endif
181zstd = not_found
182if 'CONFIG_ZSTD' in config_host
183  zstd = declare_dependency(compile_args: config_host['ZSTD_CFLAGS'].split(),
184                            link_args: config_host['ZSTD_LIBS'].split())
185endif
186gbm = not_found
187if 'CONFIG_GBM' in config_host
188  gbm = declare_dependency(compile_args: config_host['GBM_CFLAGS'].split(),
189                           link_args: config_host['GBM_LIBS'].split())
190endif
191virgl = not_found
192if 'CONFIG_VIRGL' in config_host
193  virgl = declare_dependency(compile_args: config_host['VIRGL_CFLAGS'].split(),
194                             link_args: config_host['VIRGL_LIBS'].split())
195endif
196curl = not_found
197if 'CONFIG_CURL' in config_host
198  curl = declare_dependency(compile_args: config_host['CURL_CFLAGS'].split(),
199                            link_args: config_host['CURL_LIBS'].split())
200endif
201libudev = not_found
202if 'CONFIG_LIBUDEV' in config_host
203  libudev = declare_dependency(link_args: config_host['LIBUDEV_LIBS'].split())
204endif
205brlapi = not_found
206if 'CONFIG_BRLAPI' in config_host
207  brlapi = declare_dependency(link_args: config_host['BRLAPI_LIBS'].split())
208endif
209sdl = not_found
210if 'CONFIG_SDL' in config_host
211  sdl = declare_dependency(compile_args: config_host['SDL_CFLAGS'].split(),
212                           link_args: config_host['SDL_LIBS'].split())
213endif
214rbd = not_found
215if 'CONFIG_RBD' in config_host
216  rbd = declare_dependency(link_args: config_host['RBD_LIBS'].split())
217endif
218glusterfs = not_found
219if 'CONFIG_GLUSTERFS' in config_host
220  glusterfs = declare_dependency(compile_args: config_host['GLUSTERFS_CFLAGS'].split(),
221                                 link_args: config_host['GLUSTERFS_LIBS'].split())
222endif
223libssh = not_found
224if 'CONFIG_LIBSSH' in config_host
225  libssh = declare_dependency(compile_args: config_host['LIBSSH_CFLAGS'].split(),
226                              link_args: config_host['LIBSSH_LIBS'].split())
227endif
228libbzip2 = not_found
229if 'CONFIG_BZIP2' in config_host
230  libbzip2 = declare_dependency(link_args: config_host['BZIP2_LIBS'].split())
231endif
232liblzfse = not_found
233if 'CONFIG_LZFSE' in config_host
234  liblzfse = declare_dependency(link_args: config_host['LZFSE_LIBS'].split())
235endif
236oss = not_found
237if 'CONFIG_AUDIO_OSS' in config_host
238  oss = declare_dependency(link_args: config_host['OSS_LIBS'].split())
239endif
240dsound = not_found
241if 'CONFIG_AUDIO_DSOUND' in config_host
242  dsound = declare_dependency(link_args: config_host['DSOUND_LIBS'].split())
243endif
244coreaudio = not_found
245if 'CONFIG_AUDIO_COREAUDIO' in config_host
246  coreaudio = declare_dependency(link_args: config_host['COREAUDIO_LIBS'].split())
247endif
248opengl = not_found
249if 'CONFIG_OPENGL' in config_host
250  opengl = declare_dependency(link_args: config_host['OPENGL_LIBS'].split())
251else
252endif
253gtk = not_found
254if 'CONFIG_GTK' in config_host
255  gtk = declare_dependency(compile_args: config_host['GTK_CFLAGS'].split(),
256                              link_args: config_host['GTK_LIBS'].split())
257endif
258vte = not_found
259if 'CONFIG_VTE' in config_host
260  vte = declare_dependency(compile_args: config_host['VTE_CFLAGS'].split(),
261                           link_args: config_host['VTE_LIBS'].split())
262endif
263x11 = not_found
264if 'CONFIG_X11' in config_host
265  x11 = declare_dependency(compile_args: config_host['X11_CFLAGS'].split(),
266                           link_args: config_host['X11_LIBS'].split())
267endif
268curses = not_found
269if 'CONFIG_CURSES' in config_host
270  curses = declare_dependency(compile_args: config_host['CURSES_CFLAGS'].split(),
271                              link_args: config_host['CURSES_LIBS'].split())
272endif
273iconv = not_found
274if 'CONFIG_ICONV' in config_host
275  iconv = declare_dependency(compile_args: config_host['ICONV_CFLAGS'].split(),
276                             link_args: config_host['ICONV_LIBS'].split())
277endif
278gio = not_found
279if 'CONFIG_GIO' in config_host
280  gio = declare_dependency(compile_args: config_host['GIO_CFLAGS'].split(),
281                           link_args: config_host['GIO_LIBS'].split())
282endif
283png = not_found
284if 'CONFIG_VNC_PNG' in config_host
285  png = declare_dependency(compile_args: config_host['PNG_CFLAGS'].split(),
286                           link_args: config_host['PNG_LIBS'].split())
287endif
288jpeg = not_found
289if 'CONFIG_VNC_JPEG' in config_host
290  jpeg = declare_dependency(compile_args: config_host['JPEG_CFLAGS'].split(),
291                            link_args: config_host['JPEG_LIBS'].split())
292endif
293sasl = not_found
294if 'CONFIG_VNC_SASL' in config_host
295  sasl = declare_dependency(compile_args: config_host['SASL_CFLAGS'].split(),
296                            link_args: config_host['SASL_LIBS'].split())
297endif
298fdt = not_found
299if 'CONFIG_FDT' in config_host
300  fdt = declare_dependency(compile_args: config_host['FDT_CFLAGS'].split(),
301                           link_args: config_host['FDT_LIBS'].split())
302endif
303snappy = not_found
304if 'CONFIG_SNAPPY' in config_host
305  snappy = declare_dependency(link_args: config_host['SNAPPY_LIBS'].split())
306endif
307lzo = not_found
308if 'CONFIG_LZO' in config_host
309  lzo = declare_dependency(link_args: config_host['LZO_LIBS'].split())
310endif
311
312create_config = find_program('scripts/create_config')
313minikconf = find_program('scripts/minikconf.py')
314target_dirs = config_host['TARGET_DIRS'].split()
315have_user = false
316have_system = false
317config_devices_mak_list = []
318config_devices_h = {}
319config_target_mak = {}
320kconfig_external_symbols = [
321  'CONFIG_KVM',
322  'CONFIG_XEN',
323  'CONFIG_TPM',
324  'CONFIG_SPICE',
325  'CONFIG_IVSHMEM',
326  'CONFIG_OPENGL',
327  'CONFIG_X11',
328  'CONFIG_VHOST_USER',
329  'CONFIG_VHOST_KERNEL',
330  'CONFIG_VIRTFS',
331  'CONFIG_LINUX',
332  'CONFIG_PVRDMA',
333]
334foreach target : target_dirs
335  have_user = have_user or target.endswith('-user')
336  config_target = keyval.load(meson.current_build_dir() / target / 'config-target.mak') + config_host
337
338  if target.endswith('-softmmu')
339    have_system = true
340
341    base_kconfig = []
342    foreach sym : kconfig_external_symbols
343      if sym in config_target
344        base_kconfig += '@0@=y'.format(sym)
345      endif
346    endforeach
347
348    config_devices_mak = target + '-config-devices.mak'
349    config_devices_mak = configure_file(
350      input: ['default-configs' / target + '.mak', 'Kconfig'],
351      output: config_devices_mak,
352      depfile: config_devices_mak + '.d',
353      capture: true,
354      command: [minikconf, config_host['CONFIG_MINIKCONF_MODE'],
355                config_devices_mak, '@DEPFILE@', '@INPUT@',
356                base_kconfig])
357    config_devices_h += {target: custom_target(
358      target + '-config-devices.h',
359      input: config_devices_mak,
360      output: target + '-config-devices.h',
361      capture: true,
362      command: [create_config, '@INPUT@'])}
363    config_devices_mak_list += config_devices_mak
364    config_target += keyval.load(config_devices_mak)
365  endif
366  config_target_mak += {target: config_target}
367endforeach
368have_tools = 'CONFIG_TOOLS' in config_host
369have_block = have_system or have_tools
370
371grepy = find_program('scripts/grepy.sh')
372# This configuration is used to build files that are shared by
373# multiple binaries, and then extracted out of the "common"
374# static_library target.
375#
376# We do not use all_sources()/all_dependencies(), because it would
377# build literally all source files, including devices only used by
378# targets that are not built for this compilation.  The CONFIG_ALL
379# pseudo symbol replaces it.
380
381if have_system
382  config_all_devices_mak = configure_file(
383    output: 'config-all-devices.mak',
384    input: config_devices_mak_list,
385    capture: true,
386    command: [grepy, '@INPUT@'],
387  )
388  config_all_devices = keyval.load(config_all_devices_mak)
389else
390  config_all_devices = {}
391endif
392config_all = config_all_devices
393config_all += config_host
394config_all += config_all_disas
395config_all += {
396  'CONFIG_XEN': config_host.has_key('CONFIG_XEN_BACKEND'),
397  'CONFIG_SOFTMMU': have_system,
398  'CONFIG_USER_ONLY': have_user,
399  'CONFIG_ALL': true,
400}
401
402# Generators
403
404genh = []
405hxtool = find_program('scripts/hxtool')
406shaderinclude = find_program('scripts/shaderinclude.pl')
407qapi_gen = find_program('scripts/qapi-gen.py')
408qapi_gen_depends = [ meson.source_root() / 'scripts/qapi/__init__.py',
409                     meson.source_root() / 'scripts/qapi/commands.py',
410                     meson.source_root() / 'scripts/qapi/common.py',
411                     meson.source_root() / 'scripts/qapi/doc.py',
412                     meson.source_root() / 'scripts/qapi/error.py',
413                     meson.source_root() / 'scripts/qapi/events.py',
414                     meson.source_root() / 'scripts/qapi/expr.py',
415                     meson.source_root() / 'scripts/qapi/gen.py',
416                     meson.source_root() / 'scripts/qapi/introspect.py',
417                     meson.source_root() / 'scripts/qapi/parser.py',
418                     meson.source_root() / 'scripts/qapi/schema.py',
419                     meson.source_root() / 'scripts/qapi/source.py',
420                     meson.source_root() / 'scripts/qapi/types.py',
421                     meson.source_root() / 'scripts/qapi/visit.py',
422                     meson.source_root() / 'scripts/qapi/common.py',
423                     meson.source_root() / 'scripts/qapi/doc.py',
424                     meson.source_root() / 'scripts/qapi-gen.py'
425]
426
427tracetool = [
428  python, files('scripts/tracetool.py'),
429   '--backend=' + config_host['TRACE_BACKENDS']
430]
431
432qemu_version_cmd = [find_program('scripts/qemu-version.sh'),
433                    meson.current_source_dir(),
434                    config_host['PKGVERSION'], config_host['VERSION']]
435qemu_version = custom_target('qemu-version.h',
436                             output: 'qemu-version.h',
437                             command: qemu_version_cmd,
438                             capture: true,
439                             build_by_default: true,
440                             build_always_stale: true)
441genh += qemu_version
442
443config_host_h = custom_target('config-host.h',
444                              input: meson.current_build_dir() / 'config-host.mak',
445                              output: 'config-host.h',
446                              capture: true,
447                              command: [create_config, '@INPUT@'])
448genh += config_host_h
449
450hxdep = []
451hx_headers = [
452  ['qemu-options.hx', 'qemu-options.def'],
453  ['qemu-img-cmds.hx', 'qemu-img-cmds.h'],
454]
455if have_system
456  hx_headers += [
457    ['hmp-commands.hx', 'hmp-commands.h'],
458    ['hmp-commands-info.hx', 'hmp-commands-info.h'],
459  ]
460endif
461foreach d : hx_headers
462  hxdep += custom_target(d[1],
463                input: files(d[0]),
464                output: d[1],
465                capture: true,
466                build_by_default: true, # to be removed when added to a target
467                command: [hxtool, '-h', '@INPUT0@'])
468endforeach
469genh += hxdep
470
471# Collect sourcesets.
472
473util_ss = ss.source_set()
474stub_ss = ss.source_set()
475trace_ss = ss.source_set()
476block_ss = ss.source_set()
477blockdev_ss = ss.source_set()
478common_ss = ss.source_set()
479softmmu_ss = ss.source_set()
480user_ss = ss.source_set()
481bsd_user_ss = ss.source_set()
482linux_user_ss = ss.source_set()
483specific_ss = ss.source_set()
484
485modules = {}
486hw_arch = {}
487target_arch = {}
488target_softmmu_arch = {}
489
490###############
491# Trace files #
492###############
493
494trace_events_subdirs = [
495  'accel/kvm',
496  'accel/tcg',
497  'crypto',
498  'monitor',
499]
500if have_user
501  trace_events_subdirs += [ 'linux-user' ]
502endif
503if have_block
504  trace_events_subdirs += [
505    'authz',
506    'block',
507    'io',
508    'nbd',
509    'scsi',
510  ]
511endif
512if have_system
513  trace_events_subdirs += [
514    'audio',
515    'backends',
516    'backends/tpm',
517    'chardev',
518    'hw/9pfs',
519    'hw/acpi',
520    'hw/alpha',
521    'hw/arm',
522    'hw/audio',
523    'hw/block',
524    'hw/block/dataplane',
525    'hw/char',
526    'hw/display',
527    'hw/dma',
528    'hw/hppa',
529    'hw/hyperv',
530    'hw/i2c',
531    'hw/i386',
532    'hw/i386/xen',
533    'hw/ide',
534    'hw/input',
535    'hw/intc',
536    'hw/isa',
537    'hw/mem',
538    'hw/mips',
539    'hw/misc',
540    'hw/misc/macio',
541    'hw/net',
542    'hw/nvram',
543    'hw/pci',
544    'hw/pci-host',
545    'hw/ppc',
546    'hw/rdma',
547    'hw/rdma/vmw',
548    'hw/rtc',
549    'hw/s390x',
550    'hw/scsi',
551    'hw/sd',
552    'hw/sparc',
553    'hw/sparc64',
554    'hw/ssi',
555    'hw/timer',
556    'hw/tpm',
557    'hw/usb',
558    'hw/vfio',
559    'hw/virtio',
560    'hw/watchdog',
561    'hw/xen',
562    'hw/gpio',
563    'hw/riscv',
564    'migration',
565    'net',
566    'ui',
567  ]
568endif
569trace_events_subdirs += [
570  'hw/core',
571  'qapi',
572  'qom',
573  'target/arm',
574  'target/hppa',
575  'target/i386',
576  'target/mips',
577  'target/ppc',
578  'target/riscv',
579  'target/s390x',
580  'target/sparc',
581  'util',
582]
583
584subdir('qapi')
585subdir('qobject')
586subdir('stubs')
587subdir('trace')
588subdir('util')
589subdir('qom')
590subdir('authz')
591subdir('crypto')
592subdir('storage-daemon')
593subdir('ui')
594
595
596if enable_modules
597  libmodulecommon = static_library('module-common', files('module-common.c') + genh, pic: true, c_args: '-DBUILD_DSO')
598  modulecommon = declare_dependency(link_whole: libmodulecommon, compile_args: '-DBUILD_DSO')
599endif
600
601# Build targets from sourcesets
602
603stub_ss = stub_ss.apply(config_all, strict: false)
604
605util_ss.add_all(trace_ss)
606util_ss = util_ss.apply(config_all, strict: false)
607libqemuutil = static_library('qemuutil',
608                             sources: util_ss.sources() + stub_ss.sources() + genh,
609                             dependencies: [util_ss.dependencies(), m, glib, socket])
610qemuutil = declare_dependency(link_with: libqemuutil,
611                              sources: genh + version_res)
612
613subdir('audio')
614subdir('io')
615subdir('chardev')
616subdir('fsdev')
617subdir('target')
618subdir('dump')
619
620block_ss.add(files(
621  'block.c',
622  'blockjob.c',
623  'job.c',
624  'qemu-io-cmds.c',
625))
626block_ss.add(when: 'CONFIG_REPLICATION', if_true: files('replication.c'))
627
628subdir('nbd')
629subdir('scsi')
630subdir('block')
631
632blockdev_ss.add(files(
633  'blockdev.c',
634  'blockdev-nbd.c',
635  'iothread.c',
636  'job-qmp.c',
637))
638
639# os-posix.c contains POSIX-specific functions used by qemu-storage-daemon,
640# os-win32.c does not
641blockdev_ss.add(when: 'CONFIG_POSIX', if_true: files('os-posix.c'))
642softmmu_ss.add(when: 'CONFIG_WIN32', if_true: [files('os-win32.c')])
643
644softmmu_ss.add_all(blockdev_ss)
645softmmu_ss.add(files(
646  'bootdevice.c',
647  'dma-helpers.c',
648  'qdev-monitor.c',
649), sdl)
650
651softmmu_ss.add(when: 'CONFIG_TPM', if_true: files('tpm.c'))
652softmmu_ss.add(when: 'CONFIG_SECCOMP', if_true: [files('qemu-seccomp.c'), seccomp])
653softmmu_ss.add(when: ['CONFIG_FDT', fdt],  if_true: [files('device_tree.c')])
654
655common_ss.add(files('cpus-common.c'))
656
657subdir('softmmu')
658
659# needed for fuzzing binaries
660subdir('tests/qtest/libqos')
661
662block_mods = []
663softmmu_mods = []
664foreach d, list : modules
665  foreach m, module_ss : list
666    if enable_modules and targetos != 'windows'
667      module_ss = module_ss.apply(config_host, strict: false)
668      sl = static_library(d + '-' + m, [genh, module_ss.sources()],
669                          dependencies: [modulecommon, module_ss.dependencies()], pic: true)
670      if d == 'block'
671        block_mods += sl
672      else
673        softmmu_mods += sl
674      endif
675    else
676      if d == 'block'
677        block_ss.add_all(module_ss)
678      else
679        softmmu_ss.add_all(module_ss)
680      endif
681    endif
682  endforeach
683endforeach
684
685nm = find_program('nm')
686undefsym = find_program('scripts/undefsym.sh')
687block_syms = custom_target('block.syms', output: 'block.syms',
688                             input: [libqemuutil, block_mods],
689                             capture: true,
690                             command: [undefsym, nm, '@INPUT@'])
691qemu_syms = custom_target('qemu.syms', output: 'qemu.syms',
692                             input: [libqemuutil, softmmu_mods],
693                             capture: true,
694                             command: [undefsym, nm, '@INPUT@'])
695
696block_ss = block_ss.apply(config_host, strict: false)
697libblock = static_library('block', block_ss.sources() + genh,
698                          dependencies: block_ss.dependencies(),
699                          link_depends: block_syms,
700                          name_suffix: 'fa',
701                          build_by_default: false)
702
703block = declare_dependency(link_whole: [libblock],
704                           link_args: '@block.syms',
705                           dependencies: [crypto, io])
706
707foreach m : block_mods + softmmu_mods
708  shared_module(m.name(),
709                name_prefix: '',
710                link_whole: m,
711                install: true,
712                install_dir: config_host['qemu_moddir'])
713endforeach
714
715common_ss.add_all(when: 'CONFIG_SOFTMMU', if_true: softmmu_ss)
716common_ss.add_all(when: 'CONFIG_USER_ONLY', if_true: user_ss)
717
718common_all = common_ss.apply(config_all, strict: false)
719common_all = static_library('common',
720                            build_by_default: false,
721                            sources: common_all.sources() + genh,
722                            dependencies: common_all.dependencies(),
723                            name_suffix: 'fa')
724
725foreach target : target_dirs
726  config_target = config_target_mak[target]
727  target_name = config_target['TARGET_NAME']
728  arch = config_target['TARGET_BASE_ARCH']
729  arch_srcs = []
730
731  target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
732  if targetos == 'linux'
733    target_inc += include_directories('linux-headers', is_system: true)
734  endif
735  if target.endswith('-softmmu')
736    qemu_target_name = 'qemu-system-' + target_name
737    target_type='system'
738    arch_srcs += config_devices_h[target]
739  else
740    target_type='user'
741    qemu_target_name = 'qemu-' + target_name
742    if 'CONFIG_LINUX_USER' in config_target
743      base_dir = 'linux-user'
744      target_inc += include_directories('linux-user/host/' / config_host['ARCH'])
745    else
746      base_dir = 'bsd-user'
747    endif
748    target_inc += include_directories(
749      base_dir,
750      base_dir / config_target['TARGET_ABI_DIR'],
751    )
752  endif
753
754  target_common = common_ss.apply(config_target, strict: false)
755  objects = common_all.extract_objects(target_common.sources())
756
757  # TODO: Change to generator once obj-y goes away
758  config_target_h = custom_target(target + '-config-target.h',
759                              input: meson.current_build_dir() / target / 'config-target.mak',
760                              output: target + '-config-target.h',
761                              capture: true,
762                              command: [create_config, '@INPUT@'])
763
764  target_specific = specific_ss.apply(config_target, strict: false)
765  arch_srcs += target_specific.sources()
766
767  static_library('qemu-' + target,
768                 sources: arch_srcs + [config_target_h] + genh,
769                 objects: objects,
770                 include_directories: target_inc,
771                 c_args: ['-DNEED_CPU_H',
772                          '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
773                          '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)],
774                 name_suffix: 'fa')
775endforeach
776
777# Other build targets
778
779if 'CONFIG_GUEST_AGENT' in config_host
780  subdir('qga')
781endif
782
783if have_tools
784  qemu_img = executable('qemu-img', [files('qemu-img.c'), hxdep],
785             dependencies: [authz, block, crypto, io, qom, qemuutil], install: true)
786  qemu_io = executable('qemu-io', files('qemu-io.c'),
787             dependencies: [block, qemuutil], install: true)
788  if targetos == 'linux' or targetos == 'sunos' or targetos.endswith('bsd')
789    qemu_nbd = executable('qemu-nbd', files('qemu-nbd.c'),
790               dependencies: [block, qemuutil], install: true)
791  endif
792
793  subdir('contrib/rdmacm-mux')
794  subdir('contrib/elf2dmp')
795
796  if 'CONFIG_XKBCOMMON' in config_host
797    executable('qemu-keymap', files('qemu-keymap.c', 'ui/input-keymap.c'),
798               dependencies: [qemuutil, xkbcommon], install: true)
799  endif
800
801  executable('qemu-edid', files('qemu-edid.c', 'hw/display/edid-generate.c'),
802             dependencies: qemuutil,
803             install: true)
804
805  if 'CONFIG_VHOST_USER' in config_host
806    subdir('contrib/libvhost-user')
807    subdir('contrib/vhost-user-blk')
808    if 'CONFIG_LINUX' in config_host
809      subdir('contrib/vhost-user-gpu')
810    endif
811    subdir('contrib/vhost-user-input')
812    subdir('contrib/vhost-user-scsi')
813  endif
814
815  if targetos == 'linux'
816    executable('qemu-bridge-helper', files('qemu-bridge-helper.c'),
817               dependencies: [qemuutil, libcap_ng],
818               install: true,
819               install_dir: get_option('libexecdir'))
820
821    executable('qemu-pr-helper', files('scsi/qemu-pr-helper.c', 'scsi/utils.c'),
822               dependencies: [authz, crypto, io, qom, qemuutil,
823                              libcap_ng, libudev, libmpathpersist],
824               install: true)
825  endif
826
827  if 'CONFIG_IVSHMEM' in config_host
828    subdir('contrib/ivshmem-client')
829    subdir('contrib/ivshmem-server')
830  endif
831endif
832
833subdir('tools')
834subdir('pc-bios')
835subdir('tests')
836
837summary_info = {}
838summary_info += {'Install prefix':    config_host['prefix']}
839summary_info += {'BIOS directory':    config_host['qemu_datadir']}
840summary_info += {'firmware path':     config_host['qemu_firmwarepath']}
841summary_info += {'binary directory':  config_host['bindir']}
842summary_info += {'library directory': config_host['libdir']}
843summary_info += {'module directory':  config_host['qemu_moddir']}
844summary_info += {'libexec directory': config_host['libexecdir']}
845summary_info += {'include directory': config_host['includedir']}
846summary_info += {'config directory':  config_host['sysconfdir']}
847if targetos != 'windows'
848  summary_info += {'local state directory': config_host['qemu_localstatedir']}
849  summary_info += {'Manual directory':      config_host['mandir']}
850else
851  summary_info += {'local state directory': 'queried at runtime'}
852endif
853summary_info += {'Build directory':   meson.current_build_dir()}
854summary_info += {'Source path':       meson.current_source_dir()}
855summary_info += {'GIT binary':        config_host['GIT']}
856summary_info += {'GIT submodules':    config_host['GIT_SUBMODULES']}
857summary_info += {'C compiler':        meson.get_compiler('c').cmd_array()[0]}
858summary_info += {'Host C compiler':   meson.get_compiler('c', native: true).cmd_array()[0]}
859if link_language == 'cpp'
860  summary_info += {'C++ compiler':      meson.get_compiler('cpp').cmd_array()[0]}
861else
862  summary_info += {'C++ compiler':      false}
863endif
864if targetos == 'darwin'
865  summary_info += {'Objective-C compiler': meson.get_compiler('objc').cmd_array()[0]}
866endif
867summary_info += {'ARFLAGS':           config_host['ARFLAGS']}
868summary_info += {'CFLAGS':            config_host['CFLAGS']}
869summary_info += {'QEMU_CFLAGS':       config_host['QEMU_CFLAGS']}
870summary_info += {'QEMU_LDFLAGS':      config_host['QEMU_LDFLAGS']}
871summary_info += {'make':              config_host['MAKE']}
872summary_info += {'install':           config_host['INSTALL']}
873summary_info += {'python':            '@0@ (version: @1@)'.format(python.full_path(), python.language_version())}
874summary_info += {'sphinx-build':      config_host['SPHINX_BUILD']}
875summary_info += {'genisoimage':       config_host['GENISOIMAGE']}
876# TODO: add back version
877summary_info += {'slirp support':     config_host.has_key('CONFIG_SLIRP')}
878if config_host.has_key('CONFIG_SLIRP')
879  summary_info += {'smbd':            config_host['CONFIG_SMBD_COMMAND']}
880endif
881summary_info += {'module support':    config_host.has_key('CONFIG_MODULES')}
882if config_host.has_key('CONFIG_MODULES')
883  summary_info += {'alternative module path': config_host.has_key('CONFIG_MODULE_UPGRADES')}
884endif
885summary_info += {'host CPU':          cpu}
886summary_info += {'host endianness':   build_machine.endian()}
887summary_info += {'target list':       config_host['TARGET_DIRS']}
888summary_info += {'gprof enabled':     config_host.has_key('CONFIG_GPROF')}
889summary_info += {'sparse enabled':    meson.get_compiler('c').cmd_array().contains('cgcc')}
890summary_info += {'strip binaries':    get_option('strip')}
891summary_info += {'profiler':          config_host.has_key('CONFIG_PROFILER')}
892summary_info += {'static build':      config_host.has_key('CONFIG_TOOLS')}
893if targetos == 'darwin'
894  summary_info += {'Cocoa support': config_host.has_key('CONFIG_COCOA')}
895endif
896# TODO: add back version
897summary_info += {'SDL support':       config_host.has_key('CONFIG_SDL')}
898summary_info += {'SDL image support': config_host.has_key('CONFIG_SDL_IMAGE')}
899# TODO: add back version
900summary_info += {'GTK support':       config_host.has_key('CONFIG_GTK')}
901summary_info += {'GTK GL support':    config_host.has_key('CONFIG_GTK_GL')}
902# TODO: add back version
903summary_info += {'VTE support':       config_host.has_key('CONFIG_VTE')}
904summary_info += {'TLS priority':      config_host['CONFIG_TLS_PRIORITY']}
905summary_info += {'GNUTLS support':    config_host.has_key('CONFIG_GNUTLS')}
906# TODO: add back version
907summary_info += {'libgcrypt':         config_host.has_key('CONFIG_GCRYPT')}
908if config_host.has_key('CONFIG_GCRYPT')
909   summary_info += {'  hmac':            config_host.has_key('CONFIG_GCRYPT_HMAC')}
910   summary_info += {'  XTS':             not config_host.has_key('CONFIG_QEMU_PRIVATE_XTS')}
911endif
912# TODO: add back version
913summary_info += {'nettle':            config_host.has_key('CONFIG_NETTLE')}
914if config_host.has_key('CONFIG_NETTLE')
915   summary_info += {'  XTS':             not config_host.has_key('CONFIG_QEMU_PRIVATE_XTS')}
916endif
917summary_info += {'libtasn1':          config_host.has_key('CONFIG_TASN1')}
918summary_info += {'PAM':               config_host.has_key('CONFIG_AUTH_PAM')}
919summary_info += {'iconv support':     config_host.has_key('CONFIG_ICONV')}
920summary_info += {'curses support':    config_host.has_key('CONFIG_CURSES')}
921# TODO: add back version
922summary_info += {'virgl support':     config_host.has_key('CONFIG_VIRGL')}
923summary_info += {'curl support':      config_host.has_key('CONFIG_CURL')}
924summary_info += {'mingw32 support':   targetos == 'windows'}
925summary_info += {'Audio drivers':     config_host['CONFIG_AUDIO_DRIVERS']}
926summary_info += {'Block whitelist (rw)': config_host['CONFIG_BDRV_RW_WHITELIST']}
927summary_info += {'Block whitelist (ro)': config_host['CONFIG_BDRV_RO_WHITELIST']}
928summary_info += {'VirtFS support':    config_host.has_key('CONFIG_VIRTFS')}
929summary_info += {'Multipath support': config_host.has_key('CONFIG_MPATH')}
930summary_info += {'VNC support':       config_host.has_key('CONFIG_VNC')}
931if config_host.has_key('CONFIG_VNC')
932  summary_info += {'VNC SASL support':  config_host.has_key('CONFIG_VNC_SASL')}
933  summary_info += {'VNC JPEG support':  config_host.has_key('CONFIG_VNC_JPEG')}
934  summary_info += {'VNC PNG support':   config_host.has_key('CONFIG_VNC_PNG')}
935endif
936summary_info += {'xen support':       config_host.has_key('CONFIG_XEN_BACKEND')}
937if config_host.has_key('CONFIG_XEN_BACKEND')
938  summary_info += {'xen ctrl version':  config_host['CONFIG_XEN_CTRL_INTERFACE_VERSION']}
939endif
940summary_info += {'brlapi support':    config_host.has_key('CONFIG_BRLAPI')}
941summary_info += {'Documentation':     config_host.has_key('BUILD_DOCS')}
942summary_info += {'PIE':               get_option('b_pie')}
943summary_info += {'vde support':       config_host.has_key('CONFIG_VDE')}
944summary_info += {'netmap support':    config_host.has_key('CONFIG_NETMAP')}
945summary_info += {'Linux AIO support': config_host.has_key('CONFIG_LINUX_AIO')}
946summary_info += {'Linux io_uring support': config_host.has_key('CONFIG_LINUX_IO_URING')}
947summary_info += {'ATTR/XATTR support': config_host.has_key('CONFIG_ATTR')}
948summary_info += {'Install blobs':     config_host.has_key('INSTALL_BLOBS')}
949# TODO: add back KVM/HAX/HVF/WHPX/TCG
950#summary_info += {'KVM support':       have_kvm'}
951#summary_info += {'HAX support':       have_hax'}
952#summary_info += {'HVF support':       have_hvf'}
953#summary_info += {'WHPX support':      have_whpx'}
954#summary_info += {'TCG support':       have_tcg'}
955#if get_option('tcg')
956#  summary_info += {'TCG debug enabled': config_host.has_key('CONFIG_DEBUG_TCG')}
957#  summary_info += {'TCG interpreter':   config_host.has_key('CONFIG_TCG_INTERPRETER')}
958#endif
959summary_info += {'malloc trim support': config_host.has_key('CONFIG_MALLOC_TRIM')}
960summary_info += {'RDMA support':      config_host.has_key('CONFIG_RDMA')}
961summary_info += {'PVRDMA support':    config_host.has_key('CONFIG_PVRDMA')}
962summary_info += {'fdt support':       config_host.has_key('CONFIG_FDT')}
963summary_info += {'membarrier':        config_host.has_key('CONFIG_MEMBARRIER')}
964summary_info += {'preadv support':    config_host.has_key('CONFIG_PREADV')}
965summary_info += {'fdatasync':         config_host.has_key('CONFIG_FDATASYNC')}
966summary_info += {'madvise':           config_host.has_key('CONFIG_MADVISE')}
967summary_info += {'posix_madvise':     config_host.has_key('CONFIG_POSIX_MADVISE')}
968summary_info += {'posix_memalign':    config_host.has_key('CONFIG_POSIX_MEMALIGN')}
969summary_info += {'libcap-ng support': config_host.has_key('CONFIG_LIBCAP_NG')}
970summary_info += {'vhost-net support': config_host.has_key('CONFIG_VHOST_NET')}
971summary_info += {'vhost-crypto support': config_host.has_key('CONFIG_VHOST_CRYPTO')}
972summary_info += {'vhost-scsi support': config_host.has_key('CONFIG_VHOST_SCSI')}
973summary_info += {'vhost-vsock support': config_host.has_key('CONFIG_VHOST_VSOCK')}
974summary_info += {'vhost-user support': config_host.has_key('CONFIG_VHOST_KERNEL')}
975summary_info += {'vhost-user-fs support': config_host.has_key('CONFIG_VHOST_USER_FS')}
976summary_info += {'vhost-vdpa support': config_host.has_key('CONFIG_VHOST_VDPA')}
977summary_info += {'Trace backends':    config_host['TRACE_BACKENDS']}
978if config_host['TRACE_BACKENDS'].split().contains('simple')
979  summary_info += {'Trace output file': config_host['CONFIG_TRACE_FILE'] + '-<pid>'}
980endif
981# TODO: add back protocol and server version
982summary_info += {'spice support':     config_host.has_key('CONFIG_SPICE')}
983summary_info += {'rbd support':       config_host.has_key('CONFIG_RBD')}
984summary_info += {'xfsctl support':    config_host.has_key('CONFIG_XFS')}
985summary_info += {'smartcard support': config_host.has_key('CONFIG_SMARTCARD')}
986summary_info += {'libusb':            config_host.has_key('CONFIG_USB_LIBUSB')}
987summary_info += {'usb net redir':     config_host.has_key('CONFIG_USB_REDIR')}
988summary_info += {'OpenGL support':    config_host.has_key('CONFIG_OPENGL')}
989summary_info += {'OpenGL dmabufs':    config_host.has_key('CONFIG_OPENGL_DMABUF')}
990summary_info += {'libiscsi support':  config_host.has_key('CONFIG_LIBISCSI')}
991summary_info += {'libnfs support':    config_host.has_key('CONFIG_LIBNFS')}
992summary_info += {'build guest agent': config_host.has_key('CONFIG_GUEST_AGENT')}
993if targetos == 'windows'
994  if 'WIN_SDK' in config_host
995    summary_info += {'Windows SDK':       config_host['WIN_SDK']}
996  endif
997  summary_info += {'QGA VSS support':   config_host.has_key('CONFIG_QGA_VSS')}
998  summary_info += {'QGA w32 disk info': config_host.has_key('CONFIG_QGA_NTDDSCSI')}
999  summary_info += {'QGA MSI support':   config_host.has_key('CONFIG_QGA_MSI_ENABLED')}
1000endif
1001summary_info += {'seccomp support':   config_host.has_key('CONFIG_SECCOMP')}
1002summary_info += {'coroutine backend': config_host['CONFIG_COROUTINE_BACKEND']}
1003summary_info += {'coroutine pool':    config_host['CONFIG_COROUTINE_POOL'] == '1'}
1004summary_info += {'debug stack usage': config_host.has_key('CONFIG_DEBUG_STACK_USAGE')}
1005summary_info += {'mutex debugging':   config_host.has_key('CONFIG_DEBUG_MUTEX')}
1006summary_info += {'crypto afalg':      config_host.has_key('CONFIG_AF_ALG')}
1007summary_info += {'GlusterFS support': config_host.has_key('CONFIG_GLUSTERFS')}
1008summary_info += {'gcov':              get_option('b_coverage')}
1009summary_info += {'TPM support':       config_host.has_key('CONFIG_TPM')}
1010summary_info += {'libssh support':    config_host.has_key('CONFIG_LIBSSH')}
1011summary_info += {'QOM debugging':     config_host.has_key('CONFIG_QOM_CAST_DEBUG')}
1012summary_info += {'Live block migration': config_host.has_key('CONFIG_LIVE_BLOCK_MIGRATION')}
1013summary_info += {'lzo support':       config_host.has_key('CONFIG_LZO')}
1014summary_info += {'snappy support':    config_host.has_key('CONFIG_SNAPPY')}
1015summary_info += {'bzip2 support':     config_host.has_key('CONFIG_BZIP2')}
1016summary_info += {'lzfse support':     config_host.has_key('CONFIG_LZFSE')}
1017summary_info += {'zstd support':      config_host.has_key('CONFIG_ZSTD')}
1018summary_info += {'NUMA host support': config_host.has_key('CONFIG_NUMA')}
1019summary_info += {'libxml2':           config_host.has_key('CONFIG_LIBXML2')}
1020summary_info += {'tcmalloc support':  config_host.has_key('CONFIG_TCMALLOC')}
1021summary_info += {'jemalloc support':  config_host.has_key('CONFIG_JEMALLOC')}
1022summary_info += {'avx2 optimization': config_host.has_key('CONFIG_AVX2_OPT')}
1023summary_info += {'avx512f optimization': config_host.has_key('CONFIG_AVX512F_OPT')}
1024summary_info += {'replication support': config_host.has_key('CONFIG_REPLICATION')}
1025summary_info += {'bochs support':     config_host.has_key('CONFIG_BOCHS')}
1026summary_info += {'cloop support':     config_host.has_key('CONFIG_CLOOP')}
1027summary_info += {'dmg support':       config_host.has_key('CONFIG_DMG')}
1028summary_info += {'qcow v1 support':   config_host.has_key('CONFIG_QCOW1')}
1029summary_info += {'vdi support':       config_host.has_key('CONFIG_VDI')}
1030summary_info += {'vvfat support':     config_host.has_key('CONFIG_VVFAT')}
1031summary_info += {'qed support':       config_host.has_key('CONFIG_QED')}
1032summary_info += {'parallels support': config_host.has_key('CONFIG_PARALLELS')}
1033summary_info += {'sheepdog support':  config_host.has_key('CONFIG_SHEEPDOG')}
1034summary_info += {'capstone':          config_host.has_key('CONFIG_CAPSTONE')}
1035summary_info += {'libpmem support':   config_host.has_key('CONFIG_LIBPMEM')}
1036summary_info += {'libdaxctl support': config_host.has_key('CONFIG_LIBDAXCTL')}
1037summary_info += {'libudev':           config_host.has_key('CONFIG_LIBUDEV')}
1038summary_info += {'default devices':   config_host['CONFIG_MINIKCONF_MODE'] == '--defconfig'}
1039summary_info += {'plugin support':    config_host.has_key('CONFIG_PLUGIN')}
1040summary_info += {'fuzzing support':   config_host.has_key('CONFIG_FUZZ')}
1041if config_host.has_key('HAVE_GDB_BIN')
1042  summary_info += {'gdb':             config_host['HAVE_GDB_BIN']}
1043endif
1044summary_info += {'thread sanitizer':  config_host.has_key('CONFIG_TSAN')}
1045summary_info += {'rng-none':          config_host.has_key('CONFIG_RNG_NONE')}
1046summary_info += {'Linux keyring':     config_host.has_key('CONFIG_SECRET_KEYRING')}
1047summary(summary_info, bool_yn: true)
1048
1049if not supported_cpus.contains(cpu)
1050  message()
1051  warning('SUPPORT FOR THIS HOST CPU WILL GO AWAY IN FUTURE RELEASES!')
1052  message()
1053  message('CPU host architecture ' + cpu + ' support is not currently maintained.')
1054  message('The QEMU project intends to remove support for this host CPU in')
1055  message('a future release if nobody volunteers to maintain it and to')
1056  message('provide a build host for our continuous integration setup.')
1057  message('configure has succeeded and you can continue to build, but')
1058  message('if you care about QEMU on this platform you should contact')
1059  message('us upstream at qemu-devel@nongnu.org.')
1060endif
1061
1062if not supported_oses.contains(targetos)
1063  message()
1064  warning('WARNING: SUPPORT FOR THIS HOST OS WILL GO AWAY IN FUTURE RELEASES!')
1065  message()
1066  message('Host OS ' + targetos + 'support is not currently maintained.')
1067  message('The QEMU project intends to remove support for this host OS in')
1068  message('a future release if nobody volunteers to maintain it and to')
1069  message('provide a build host for our continuous integration setup.')
1070  message('configure has succeeded and you can continue to build, but')
1071  message('if you care about QEMU on this platform you should contact')
1072  message('us upstream at qemu-devel@nongnu.org.')
1073endif
1074