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