build-sys: meson: support memfd without SYS_memfd_create (FreeBSD 13)
[platform/upstream/pulseaudio.git] / meson.build
1 project('pulseaudio', 'c', 'cpp',
2         version : run_command(find_program('git-version-gen'), join_paths(meson.current_source_dir(), '.tarball-version')).stdout().strip(),
3         meson_version : '>= 0.50.0',
4         default_options : [ 'c_std=gnu11', 'cpp_std=c++11' ]
5         )
6
7 pa_version_str = meson.project_version()
8 # For tarballs, the first split will do nothing, but for builds in git, we
9 # split out suffixes when there are commits since the last tag
10 # (e.g.: v11.99.1-3-gad14bdb24 -> v11.99.1)
11 version_split = pa_version_str.split('-')[0].split('.')
12 pa_version_major = version_split[0].split('v')[0]
13 pa_version_minor = version_split[1]
14 if version_split.length() > 2
15   pa_version_micro = version_split[2]
16 else
17   pa_version_micro = '0'
18 endif
19 pa_version_major_minor = pa_version_major + '.' + pa_version_minor
20
21 pa_api_version = 12
22 pa_protocol_version = 35
23
24 # The stable ABI for client applications, for the version info x:y:z
25 # always will hold x=z
26 libpulse_version_info = [23, 0, 23]
27
28 # A simplified, synchronous, ABI-stable interface for client
29 # applications, for the version info x:y:z always will hold x=z
30 libpulse_simple_version_info = [1, 1, 1]
31
32 # The ABI-stable GLib adapter for client applications, for the version
33 # info x:y:z always will hold x=z
34 libpulse_mainloop_glib_version_info = [0, 6, 0]
35
36 libpulse_version = '@0@.@1@.@2@'.format(
37   libpulse_version_info[0] - libpulse_version_info[2],
38   libpulse_version_info[0],
39   libpulse_version_info[1],
40 )
41
42 libpulse_simple_version = '@0@.@1@.@2@'.format(
43   libpulse_simple_version_info[0] - libpulse_simple_version_info[2],
44   libpulse_simple_version_info[0],
45   libpulse_simple_version_info[1],
46 )
47
48 libpulse_mainloop_glib_version = '@0@.@1@.@2@'.format(
49   libpulse_mainloop_glib_version_info[0] - libpulse_mainloop_glib_version_info[2],
50   libpulse_mainloop_glib_version_info[0],
51   libpulse_mainloop_glib_version_info[1],
52 )
53
54 # Paths
55
56 prefix = get_option('prefix')
57 assert(prefix.startswith('/'), 'Prefix is not absolute: "@0@"'.format(prefix))
58
59 bindir = join_paths(prefix, get_option('bindir'))
60 includedir = join_paths(prefix, get_option('includedir'))
61 libdir = join_paths(prefix, get_option('libdir'))
62 libexecdir = join_paths(prefix, get_option('libexecdir'))
63 mandir = join_paths(prefix, get_option('mandir'))
64 datadir = join_paths(prefix, get_option('datadir'))
65 localedir = join_paths(prefix, get_option('localedir'))
66 localstatedir = join_paths(prefix, get_option('localstatedir'))
67 sysconfdir = join_paths(prefix, get_option('sysconfdir'))
68 privlibdir = join_paths(libdir, 'pulseaudio')
69
70 if host_machine.system() == 'windows'
71   # Windows only supports loading libraries from the same dir as the executable
72   privlibdir = bindir
73 endif
74
75 alsadatadir = get_option('alsadatadir')
76 if alsadatadir == ''
77   alsadatadir = join_paths(datadir, 'pulseaudio', 'alsa-mixer')
78 endif
79
80 pkgconfigdir = join_paths(libdir, 'pkgconfig')
81 pulselibexecdir = join_paths(libexecdir, 'pulse')
82 pulsesysconfdir = join_paths(sysconfdir, 'pulse')
83
84 modlibexecdir = get_option('modlibexecdir')
85 if modlibexecdir == ''
86   modlibexecdir = join_paths(libdir, 'pulse-' + pa_version_major_minor, 'modules')
87 endif
88
89 padsplibdir = get_option('padsplibdir')
90 if padsplibdir == ''
91   padsplibdir = privlibdir
92 endif
93
94 pulsedsp_location = get_option('pulsedsp-location')
95 if pulsedsp_location == ''
96   pulsedsp_location = join_paths(prefix, padsplibdir)
97 endif
98
99 systemduserunitdir = get_option('systemduserunitdir')
100 # the default value is set below
101
102 udevrulesdir = get_option('udevrulesdir')
103 if udevrulesdir == ''
104   # absolute path, otherwise meson prepends the prefix
105   udevrulesdir = '/lib/udev/rules.d'
106 endif
107
108 vapidir = join_paths(datadir, 'vala', 'vapi')
109
110 bashcompletiondir = get_option('bashcompletiondir')
111 if bashcompletiondir == ''
112   bash_completion_dep = dependency('bash-completion', required : false)
113   if bash_completion_dep.found()
114     bashcompletiondir = bash_completion_dep.get_pkgconfig_variable('completionsdir')
115   else
116     bashcompletiondir = join_paths(datadir, 'bash-completion', 'completions')
117   endif
118 endif
119
120 zshcompletiondir = get_option('zshcompletiondir')
121 if zshcompletiondir == ''
122   zshcompletiondir = join_paths(datadir, 'zsh', 'site-functions')
123 endif
124
125 # Configuration data
126
127 cc = meson.get_compiler('c')
128
129 cdata = configuration_data()
130 cdata.set_quoted('PACKAGE', 'pulseaudio')
131 cdata.set_quoted('PACKAGE_NAME', 'pulseaudio')
132 cdata.set_quoted('PACKAGE_VERSION', pa_version_str)
133 cdata.set('PA_MAJOR', pa_version_major)
134 cdata.set('PA_MINOR', pa_version_minor)
135 cdata.set('PA_API_VERSION', pa_api_version)
136 cdata.set('PA_PROTOCOL_VERSION', pa_protocol_version)
137 cdata.set_quoted('PA_MACHINE_ID', join_paths(sysconfdir, 'machine-id'))
138 cdata.set_quoted('PA_MACHINE_ID_FALLBACK', join_paths(localstatedir, 'lib', 'dbus', 'machine-id'))
139 cdata.set_quoted('PA_SRCDIR', join_paths(meson.current_source_dir(), 'src'))
140 cdata.set_quoted('PA_BUILDDIR', meson.current_build_dir())
141 cdata.set_quoted('PA_SOEXT', '.so')
142 cdata.set_quoted('PA_DEFAULT_CONFIG_DIR', pulsesysconfdir)
143 cdata.set('PA_DEFAULT_CONFIG_DIR_UNQUOTED', pulsesysconfdir)
144 cdata.set_quoted('PA_BINARY', join_paths(bindir, 'pulseaudio'))
145 cdata.set_quoted('PA_SYSTEM_RUNTIME_PATH', join_paths(localstatedir, 'run', 'pulse'))
146 cdata.set_quoted('PA_SYSTEM_CONFIG_PATH', join_paths(localstatedir, 'lib', 'pulse'))
147 cdata.set_quoted('PA_SYSTEM_STATE_PATH', join_paths(localstatedir, 'lib', 'pulse'))
148 cdata.set_quoted('PA_DLSEARCHPATH', modlibexecdir)
149 cdata.set_quoted('PA_SYSTEM_USER', get_option('system_user'))
150 cdata.set_quoted('PA_SYSTEM_GROUP', get_option('system_group'))
151 cdata.set_quoted('PA_ACCESS_GROUP', get_option('access_group'))
152 cdata.set_quoted('PA_CFLAGS', 'Not yet supported on meson')
153 cdata.set_quoted('PA_ALSA_PATHS_DIR', join_paths(alsadatadir, 'paths'))
154 cdata.set_quoted('PA_ALSA_PROFILE_SETS_DIR', join_paths(alsadatadir, 'profile-sets'))
155 cdata.set_quoted('DESKTOPFILEDIR', join_paths(datadir, 'applications'))
156 cdata.set_quoted('PULSE_LOCALEDIR', localedir)
157 cdata.set_quoted('GETTEXT_PACKAGE', 'pulseaudio')
158 cdata.set('ENABLE_NLS', 1)
159 cdata.set('top_srcdir', meson.source_root())
160
161 # Platform specifics
162 # First some defaults to keep config file generation happy
163 cdata.set('HAVE_COREAUDIO', 0)
164 cdata.set('HAVE_WAVEOUT', 0)
165
166 platform_socket_dep = []
167 platform_dep = []
168
169 # FIXME: This was not tested. Maybe some flags should better be CFLAGS,
170 # rather than ending up in the config.h file?
171 if host_machine.system() == 'darwin'
172   cdata.set('OS_IS_DARWIN', 1)
173   cdata.set('_DARWIN_C_SOURCE', '200112L') # Needed to get NSIG on Mac OS
174 elif host_machine.system() == 'windows'
175   cdata.set('OS_IS_WIN32', 1)
176   cdata.set('HAVE_WINDOWS_H', 1)
177   cdata.set('HAVE_WAVEOUT', 1)
178   cdata.set('HAVE_WINSOCK2_H', 1)
179   cdata.set('HAVE_WS2TCPIP_H', 1)
180   cdata.set('WIN32_LEAN_AND_MEAN', 1) # Needed to avoid including unnecessary headers on Windows
181   cdata.set('gid_t', 'int')
182   cdata.set('uid_t', 'int')
183   ws2_32_dep = meson.get_compiler('c').find_library('ws2_32')
184   winsock_dep = meson.get_compiler('c').find_library('wsock32')
185   ole32_dep = meson.get_compiler('c').find_library('ole32')
186   ssp_dep = meson.get_compiler('c').find_library('ssp')
187   pcreposix_dep = meson.get_compiler('c').find_library('pcreposix')
188   platform_socket_dep = [ws2_32_dep, winsock_dep]
189   platform_dep = [ole32_dep, ssp_dep, pcreposix_dep]
190 #elif host_machine.system() == 'solaris'
191 #  # Apparently meson has no solaris support?
192 #  # Needed to get declarations for msg_control and msg_controllen on Solaris
193 #  cdata.set('_XOPEN_SOURCE', 600)
194 #  cdata.set('__EXTENSIONS__', 1)
195 endif
196
197 if cc.has_type('_Bool')
198   cdata.set('HAVE_STD_BOOL', 1)
199 endif
200
201 if host_machine.cpu_family() == 'x86_64' or cc.sizeof('void *') >= 8
202   cdata.set('HAVE_FAST_64BIT_OPERATIONS', 1)
203 endif
204
205 # Headers
206
207 check_headers = [
208   'arpa/inet.h',
209   'byteswap.h',
210   'cpuid.h',
211   'dlfcn.h',
212   'execinfo.h',
213   'grp.h',
214   'langinfo.h',
215   'linux/sockios.h',
216   'locale.h',
217   'netdb.h',
218   'netinet/in.h',
219   'netinet/in_systm.h',
220   'netinet/ip.h',
221   'netinet/tcp.h',
222   'pcreposix.h',
223   'poll.h',
224   'pwd.h',
225   'regex.h',
226   'sched.h',
227   'stdint.h',
228   'sys/atomic.h',
229   'sys/capability.h',
230   'sys/conf.h',
231   'sys/dl.h',
232   'sys/eventfd.h',
233   'sys/filio.h',
234   'sys/ioctl.h',
235   'sys/mman.h',
236   'sys/prctl.h',
237   'sys/resource.h',
238   'sys/select.h',
239   'sys/socket.h',
240   'sys/syscall.h',
241   'sys/uio.h',
242   'sys/un.h',
243   'sys/wait.h',
244   'syslog.h',
245   'xlocale.h',
246 ]
247
248 foreach h : check_headers
249   if cc.has_header(h)
250     define = 'HAVE_' + h.underscorify().to_upper()
251     cdata.set(define, 1)
252   endif
253 endforeach
254
255 if cc.has_header('valgrind/memcheck.h', required: get_option('valgrind'))
256   cdata.set('HAVE_VALGRIND_MEMCHECK_H', 1)
257 endif
258
259 # FIXME: move this to the above set
260 if host_machine.system() != 'windows'
261   if cc.has_header('pthread.h')
262     cdata.set('HAVE_PTHREAD', 1)
263   endif
264 endif
265
266 if cc.has_header_symbol('pthread.h', 'PTHREAD_PRIO_INHERIT')
267   cdata.set('HAVE_PTHREAD_PRIO_INHERIT', 1)
268 endif
269
270 # Functions
271
272 check_functions = [
273   'accept4',
274   'clock_gettime',
275   'ctime_r',
276   'fchmod',
277   'fchown',
278   'fork',
279   'fstat',
280   'getaddrinfo',
281   'getgrgid_r',
282   'getgrnam_r',
283   'getpwnam_r',
284   'getpwuid_r',
285   'gettimeofday',
286   'getuid',
287   'lrintf',
288   'lstat',
289   'memfd_create',
290   'mkfifo',
291   'mlock',
292   'nanosleep',
293   'open64',
294   'paccept',
295   'pipe',
296   'pipe2',
297   'posix_fadvise',
298   'posix_madvise',
299   'posix_memalign',
300   'ppoll',
301   'readlink',
302   'setegid',
303   'seteuid',
304   'setpgid',
305   'setregid',
306   'setresgid',
307   'setresuid',
308   'setreuid',
309   'setsid',
310   'sig2str',
311   'sigaction',
312   'strerror_r',
313   'strtod_l',
314   'strtof',
315   'symlink',
316   'sysconf',
317   'uname',
318 ]
319
320 foreach f : check_functions
321   if cc.has_function(f)
322     define = 'HAVE_' + f.underscorify().to_upper()
323
324     if f == 'posix_memalign' and host_machine.system() == 'windows'
325       message('Win32/mingw32 does not properly define posix_memalign.')
326     elif f == 'fork' and host_machine.system() == 'windows'
327       # __builtin_fork is defined and compiles properly, but calling __builtin_fork() does not.
328       # This causes Meson to think that Windows has a fork() which causes a link error...
329       message('Win32/mingw32 does not properly define fork.')
330     else
331       cdata.set(define, 1)
332     endif
333   endif
334 endforeach
335
336 if cc.has_header_symbol('sys/syscall.h', 'SYS_memfd_create') \
337   or cc.has_function('memfd_create')
338   cdata.set('HAVE_MEMFD', 1)
339 endif
340
341 if cc.has_function('dgettext')
342   if host_machine.system() != 'windows'
343     libintl_dep = []
344   else
345     libintl_dep = cc.find_library('intl')
346   endif
347 else
348   libintl_dep = cc.find_library('intl')
349 endif
350
351 # Symbols
352
353 if cc.has_header_symbol('signal.h', 'SIGXCPU')
354   cdata.set('HAVE_SIGXCPU', 1)
355 endif
356
357 if not cc.has_header_symbol('netinet/in.h', 'INADDR_NONE')
358   if not cc.has_header_symbol('winsock2.h', 'INADDR_NONE')
359     # Define INADDR_NONE if not found (Solaris)
360     cdata.set('INADDR_NONE', '0xffffffff')
361   endif
362 endif
363
364 check_decls = [
365   [ 'environ', 'unistd.h', '#define _GNU_SOURCE' ],
366   [ 'SOUND_PCM_READ_RATE', 'sys/soundcard.h', '' ],
367   [ 'SOUND_PCM_READ_CHANNELS', 'sys/soundcard.h', '' ],
368   [ 'SOUND_PCM_READ_BITS', 'sys/soundcard.h', '' ],
369 ]
370
371 foreach s : check_decls
372   if cc.has_header_symbol(s[1], s[0], prefix : s[2])
373     define = 'HAVE_DECL_' + s[0].to_upper()
374     cdata.set(define, 1)
375   endif
376 endforeach
377
378 # Types
379
380 # FIXME: do we ever care about gid_t not being defined / smaller than an int?
381 cdata.set('GETGROUPS_T', 'gid_t')
382
383 # Include paths
384
385 configinc = include_directories('.')
386 topinc = include_directories('src')
387
388 # CFLAGS/LDFLAGS
389
390 pa_c_args = ['-DHAVE_CONFIG_H', '-D_GNU_SOURCE']
391 server_c_args = ['-D__INCLUDED_FROM_PULSE_AUDIO']
392 cdata.set('MESON_BUILD', 1)
393
394 # On ELF systems we don't want the libraries to be unloaded since we don't clean them up properly,
395 # so we request the nodelete flag to be enabled.
396 # On other systems, we don't really know how to do that, but it's welcome if somebody can tell.
397 # Windows doesn't support this flag.
398 if host_machine.system() != 'windows'
399   nodelete_link_args = ['-Wl,-z,nodelete']
400 else
401   nodelete_link_args = []
402 endif
403
404 # Code coverage
405
406 if get_option('gcov')
407   add_project_arguments('--coverage', language: ['c', 'cpp'])
408   add_project_link_arguments('--coverage', language: ['c', 'cpp'])
409 endif
410
411 # Core Dependencies
412
413 libm_dep = cc.find_library('m', required : true)
414
415 thread_dep = dependency('threads')
416 foreach f : [
417   'pthread_getname_np',
418   'pthread_setaffinity_np',
419   'pthread_setname_np',
420 ]
421   if cc.has_function(f, dependencies : thread_dep)
422     define = 'HAVE_' + f.underscorify().to_upper()
423     cdata.set(define, 1)
424   endif
425 endforeach
426
427 cap_dep = cc.find_library('cap', required : false)
428
429 shm_dep = cc.find_library('rt', required : false)
430 if cc.has_function('shm_open', dependencies : shm_dep)
431   cdata.set('HAVE_SHM_OPEN', 1)
432 endif
433
434 dl_dep = cc.find_library('dl', required : false)
435 if cc.has_function('dladdr', dependencies : dl_dep)
436   cdata.set('HAVE_DLADDR', 1)
437 endif
438
439 have_iconv = false
440 if cc.has_function('iconv_open')
441   iconv_dep = dependency('', required : false)
442   have_iconv = true
443   # tell the libiconv header to pretend to be libc iconv
444   cdata.set('LIBICONV_PLUG', 1)
445 else
446   iconv_dep = cc.find_library('iconv', required : false)
447   have_iconv = iconv_dep.found()
448 endif
449 if have_iconv
450   cdata.set('HAVE_ICONV', 1)
451   iconvconsttest = '''#include <iconv.h>
452 size_t iconv (iconv_t cd, char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);
453 '''
454   if cc.compiles(iconvconsttest, dependencies : iconv_dep)
455     cdata.set('ICONV_CONST', '')
456   else
457     cdata.set('ICONV_CONST', 'const')
458   endif
459 endif
460
461 # Used for backtraces on BSD
462 execinfo_dep = cc.find_library('execinfo', required : false)
463
464 # Atomic operations
465
466 if get_option('atomic-arm-memory-barrier')
467     cdata.set('ATOMIC_ARM_MEMORY_BARRIER_ENABLED', 1)
468 endif
469
470 need_libatomic_ops = false
471
472 atomictest = '''void func() {
473   volatile int atomic = 2;
474   __sync_bool_compare_and_swap (&atomic, 2, 3);
475 }
476 '''
477
478 if cc.compiles(atomictest)
479   cdata.set('HAVE_ATOMIC_BUILTINS', 1)
480
481   newatomictest = '''void func() {
482     int c = 0;
483     __atomic_store_n(&c, 4, __ATOMIC_SEQ_CST);
484   }
485   '''
486
487   if(cc.compiles(newatomictest))
488     cdata.set('HAVE_ATOMIC_BUILTINS_MEMORY_MODEL', 1)
489   endif
490
491 elif host_machine.cpu_family() == 'arm'
492   if host_machine.system() == 'linux' and get_option('atomic-arm-linux-helpers')
493     cdata.set('ATOMIC_ARM_LINUX_HELPERS', 1)
494   else
495     armatomictest = '''int func() {
496       volatile int a=0;
497       int o=0, n=1, r;
498       asm volatile (
499               "ldrex    %0, [%1]\n"
500               "subs  %0, %0, %2\n"
501               "strexeq %0, %3, [%1]\n"
502               : "=&r" (r)
503               : "r" (&a), "Ir" (o), "r" (n)
504       : "cc");
505       return (a==1 ? 0 : -1);
506     }
507     '''
508
509     if cc.compiles(armatomictest)
510       cdata.set('ATOMIC_ARM_INLINE_ASM', 1)
511     else
512       need_libatomic_ops = true
513     endif
514   endif # arm && !linux
515
516 elif not ['freebsd', 'netbsd'].contains(host_machine.system())
517   need_libatomic_ops = true
518 endif # !atomic helpers && !arm
519
520 if need_libatomic_ops
521   assert(cc.has_header('atomic_ops.h'), 'Need libatomic_ops')
522
523   cdata.set('AO_REQUIRE_CAS', 1)
524
525   if host_machine.system() != 'windows'
526     libatomic_ops_dep = cc.find_library('atomic_ops', required : true)
527   else
528     libatomic_ops_dep = dependency('', required: false)
529   endif
530 else
531   libatomic_ops_dep = dependency('', required: false)
532 endif
533
534 # ARM checks
535 # ARMV6 instructions we need
536 if host_machine.cpu_family() == 'arm'
537   armv6test = '''int func() {
538     volatile int a = -60000, b = 0xaaaabbbb, c = 0xccccdddd;
539     asm volatile ("ldr r0, %2 \n"
540                   "ldr r2, %3 \n"
541                   "ldr r3, %4 \n"
542                   "ssat r1, #8, r0 \n"
543                   "str r1, %0 \n"
544                   "pkhbt r1, r3, r2, LSL #8 \n"
545                   "str r1, %1 \n"
546                   : "=m" (a), "=m" (b)
547                   : "m" (a), "m" (b), "m" (c)
548                   : "r0", "r1", "r2", "r3", "cc");
549     return (a == -128 && b == 0xaabbdddd) ? 0 : -1;
550   }
551   '''
552
553   if cc.compiles(armv6test)
554     cdata.set('HAVE_ARMV6', 1)
555   endif
556 endif
557 # NEON checks are automatically done by the unstable-simd module
558
559 # FIXME: make sure it's >= 2.2
560 ltdl_dep = cc.find_library('ltdl', required : true)
561 # FIXME: can meson support libtool -dlopen/-dlpreopen things?
562 #        and do we still want to support this at all?
563 cdata.set('DISABLE_LIBTOOL_PRELOAD', 1)
564
565 if get_option('database') == 'tdb'
566   database_dep = dependency('tdb')
567 elif get_option('database') == 'gdbm'
568   database_dep = cc.find_library('gdbm', required : true)
569 else
570   database_dep = dependency('', required: false)
571 endif
572
573 if get_option('ipv6')
574   cdata.set('HAVE_IPV6', 1)
575 endif
576
577 if get_option('legacy-database-entry-format')
578   cdata.set('ENABLE_LEGACY_DATABASE_ENTRY_FORMAT', 1)
579 endif
580
581 if get_option('stream-restore-clear-old-devices')
582   cdata.set('STREAM_RESTORE_CLEAR_OLD_DEVICES', 1)
583 endif
584
585 if get_option('running-from-build-tree')
586   cdata.set('HAVE_RUNNING_FROM_BUILD_TREE', 1)
587 endif
588
589 alsa_dep = dependency('alsa', version : '>= 1.0.24', required : get_option('alsa'))
590 if alsa_dep.found()
591   cdata.set('HAVE_ALSA', 1)
592   cdata.set('HAVE_ALSA_UCM', 1)
593 endif
594
595 asyncns_dep = dependency('libasyncns', version : '>= 0.1', required : get_option('asyncns'))
596 if asyncns_dep.found()
597   cdata.set('HAVE_LIBASYNCNS', 1)
598 endif
599
600 dbus_dep = dependency('dbus-1', version : '>= 1.4.12', required : get_option('dbus'))
601 if dbus_dep.found()
602   cdata.set('HAVE_DBUS', 1)
603 endif
604
605 gio_dep = dependency('gio-2.0', version : '>= 2.26.0', required : get_option('gsettings'))
606 if gio_dep.found()
607   cdata.set('HAVE_GSETTINGS', 1)
608 endif
609
610 glib_dep = dependency('glib-2.0', version : '>= 2.28.0', required: get_option('glib'))
611 if glib_dep.found()
612   cdata.set('HAVE_GLIB', 1)
613 endif
614
615 gtk_dep = dependency('gtk+-3.0', required : get_option('gtk'))
616 if gtk_dep.found()
617   cdata.set('HAVE_GTK', 1)
618 endif
619
620 have_orcc = false
621 orcc_args = []
622 orc_dep = dependency('orc-0.4', version : '>= 0.4.11', required : get_option('orc'))
623 orcc = find_program('orcc', required : get_option('orc'))
624 if orc_dep.found() and orcc.found()
625   have_orcc = true
626   orcc_args = [orcc]
627   #orcc_args = [orcc, '--include', 'glib.h']
628   cdata.set('HAVE_ORC', 1)
629 else
630   cdata.set('DISABLE_ORC', 1)
631 endif
632
633 samplerate_dep = dependency('samplerate', version : '>= 0.1.0', required : get_option('samplerate'))
634 if samplerate_dep.found()
635   cdata.set('HAVE_LIBSAMPLERATE', 1)
636 endif
637
638 sndfile_dep = dependency('sndfile', version : '>= 1.0.20')
639
640 soxr_dep = dependency('soxr', version : '>= 0.1.1', required : get_option('soxr'))
641 if soxr_dep.found()
642   cdata.set('HAVE_SOXR', 1)
643 endif
644
645 libsystemd_dep = dependency('libsystemd', required : get_option('systemd'))
646 if libsystemd_dep.found()
647   cdata.set('HAVE_SYSTEMD_DAEMON', 1)
648   cdata.set('HAVE_SYSTEMD_LOGIN', 1)
649   cdata.set('HAVE_SYSTEMD_JOURNAL', 1)
650 endif
651 systemd_dep = dependency('systemd', required : get_option('systemd'))
652 if systemd_dep.found() and systemduserunitdir == ''
653   systemduserunitdir = systemd_dep.get_pkgconfig_variable('systemduserunitdir')
654 endif
655
656 x11_dep = dependency('x11-xcb', required : get_option('x11'))
657 if x11_dep.found()
658   xcb_dep  = dependency('xcb',  required : true, version : '>= 1.6')
659   ice_dep  = dependency('ice',  required : true)
660   sm_dep   = dependency('sm',   required : true)
661   xtst_dep = dependency('xtst', required : true)
662   cdata.set('HAVE_X11', 1)
663   if cc.has_function('XSetIOErrorExitHandler', dependencies: x11_dep)
664     cdata.set('HAVE_XSETIOERROREXITHANDLER', 1)
665   endif
666 endif
667
668 # Module dependencies
669 if cc.has_header('sys/soundcard.h', required: get_option('oss-output'))
670   cdata.set('HAVE_OSS_OUTPUT', 1)
671   cdata.set('HAVE_OSS_WRAPPER', 1)
672   cdata.set('PULSEDSP_LOCATION', pulsedsp_location)
673 endif
674
675 if get_option('hal-compat')
676   cdata.set('HAVE_HAL_COMPAT', 1)
677 endif
678
679 avahi_dep = dependency('avahi-client', version : '>= 0.6.0', required : get_option('avahi'), disabler : true)
680 if avahi_dep.found()
681   cdata.set('HAVE_AVAHI', 1)
682 endif
683
684 sbc_dep = dependency('sbc', version : '>= 1.0', required : false)
685 if get_option('bluez5')
686   assert(dbus_dep.found(), 'BlueZ requires D-Bus support')
687   assert(sbc_dep.found(), 'BlueZ requires SBC support')
688   cdata.set('HAVE_SBC', 1)
689   cdata.set('HAVE_BLUEZ', 1)
690   cdata.set('HAVE_BLUEZ_5', 1)
691   if get_option('bluez5-native-headset')
692     cdata.set('HAVE_BLUEZ_5_NATIVE_HEADSET', 1)
693   endif
694   if get_option('bluez5-ofono-headset')
695     cdata.set('HAVE_BLUEZ_5_OFONO_HEADSET', 1)
696   endif
697 endif
698
699 fftw_dep = dependency('fftw3f', required : get_option('fftw'))
700 if fftw_dep.found()
701   cdata.set('HAVE_FFTW', 1)
702 endif
703
704 jack_dep = dependency('jack', version : '>= 0.117.0', required : get_option('jack'))
705 if jack_dep.found()
706   cdata.set('HAVE_JACK', 1)
707 endif
708
709 lirc_dep = dependency('lirc', required : get_option('lirc'))
710 if lirc_dep.found()
711   cdata.set('HAVE_LIRC', 1)
712 endif
713
714 openssl_dep = dependency('openssl', version : '>= 0.9', required : get_option('openssl'))
715 if openssl_dep.found()
716   cdata.set('HAVE_OPENSSL', 1)
717 endif
718
719 speex_dep = dependency('speexdsp', version : '>= 1.2', required : get_option('speex'))
720 if speex_dep.found()
721   cdata.set('HAVE_SPEEX', 1)
722 endif
723
724 udev_dep = dependency('libudev', version : '>= 143', required : get_option('udev'))
725 if udev_dep.found()
726   cdata.set('HAVE_UDEV', 1)
727 endif
728
729 webrtc_dep = dependency('webrtc-audio-processing', version : '>= 0.2', required : get_option('webrtc-aec'))
730 if webrtc_dep.found()
731   cdata.set('HAVE_WEBRTC', 1)
732 endif
733
734 gst_dep = dependency('gstreamer-1.0', version : '>= 1.14', required : get_option('gstreamer'))
735 gstapp_dep = dependency('gstreamer-app-1.0', required : get_option('gstreamer'))
736 gstrtp_dep = dependency('gstreamer-rtp-1.0', required : get_option('gstreamer'))
737
738 have_gstreamer = false
739 if gst_dep.found() and gstapp_dep.found() and gstrtp_dep.found()
740   have_gstreamer = true
741 endif
742
743 # These are required for the CMake file generation
744 cdata.set('PA_LIBDIR', libdir)
745 cdata.set('PA_INCDIR', includedir)
746 if glib_dep.found()
747   cdata.set('HAVE_GLIB20', 1) # to match the AM_CONDITIONAL for CMake file generation
748 endif
749
750 # Test dependencies
751
752 check_dep = dependency('check', version : '>= 0.9.10', required : get_option('tests'))
753
754 # Subdirs
755
756 subdir('doxygen')
757 subdir('po')
758 if get_option('man')
759   subdir('man')
760 endif
761 subdir('shell-completion/bash')
762 subdir('shell-completion/zsh')
763 subdir('src')
764 subdir('vala')
765
766 # Now generate config.h from everything above
767 configure_file(output : 'config.h', configuration : cdata)
768
769 # pkg-config files
770
771 pc_cdata = configuration_data()
772
773 pc_cdata.set('prefix', prefix)
774 pc_cdata.set('exec_prefix', prefix)
775 pc_cdata.set('libdir', libdir)
776 pc_cdata.set('includedir', includedir)
777 pc_cdata.set('modlibexecdir', modlibexecdir)
778 pc_cdata.set('PACKAGE_VERSION', pa_version_str)
779 pc_cdata.set('PA_MAJORMINOR', pa_version_major_minor)
780 # FIXME: the line below is wrong. Currently the meson thread dep lacks documentation,
781 # and doesn't allow introspection, ie. none of get_pkgconfig_variable() or
782 # get_configtool_variable() work with it, so we have no way to get this flag right,
783 # unless we do all the work ourselves. See current work in glib, also meson #553.
784 pc_cdata.set('PTHREAD_LIBS', '-pthread')
785
786 pc_files = [
787   'libpulse.pc',
788   'libpulse-simple.pc',
789 ]
790
791 if glib_dep.found()
792   pc_files += 'libpulse-mainloop-glib.pc'
793 endif
794
795 foreach file : pc_files
796   configure_file(
797     input : file + '.in',
798     output : file,
799     configuration : pc_cdata,
800     install_dir : pkgconfigdir)
801 endforeach
802
803 # CMake files
804
805 m4 = find_program('m4', required: true)
806
807 cmakedir = join_paths(libdir, 'cmake', 'PulseAudio')
808
809 cmake_template_file = configure_file(
810   input : 'PulseAudioConfig.cmake.in',
811   output : 'PulseAudioConfig.cmake.tmp',
812   configuration: cdata,
813 )
814
815 custom_target('PulseAudioConfig.cmake',
816   input : cmake_template_file,
817   output : 'PulseAudioConfig.cmake',
818   capture : true,
819   command : [m4, '@INPUT@'],
820   build_by_default : true,
821   install : true,
822   install_dir : cmakedir,
823 )
824
825 configure_file(
826   input : 'PulseAudioConfigVersion.cmake.in',
827   output : 'PulseAudioConfigVersion.cmake',
828   configuration: cdata,
829   install : true,
830   install_dir : cmakedir,
831 )
832
833 ############################################################
834
835 # Final summary
836
837 summary = [
838   '',
839   '---{ @0@ @1@ }---'.format(meson.project_name(), meson.project_version()),
840   '',
841   'prefix:                        @0@'.format(prefix),
842   'bindir:                        @0@'.format(bindir),
843   'libdir:                        @0@'.format(libdir),
844   'libexecdir:                    @0@'.format(libexecdir),
845   'mandir:                        @0@'.format(mandir),
846   'datadir:                       @0@'.format(datadir),
847   'sysconfdir:                    @0@'.format(sysconfdir),
848   'localstatedir:                 @0@'.format(localstatedir),
849   'modlibexecdir:                 @0@'.format(modlibexecdir),
850   'alsadatadir:                   @0@'.format(alsadatadir),
851   'System Runtime Path:           @0@'.format(cdata.get_unquoted('PA_SYSTEM_RUNTIME_PATH')),
852   'System State Path:             @0@'.format(cdata.get_unquoted('PA_SYSTEM_STATE_PATH')),
853   'System Config Path:            @0@'.format(cdata.get_unquoted('PA_SYSTEM_CONFIG_PATH')),
854   'Bash completions directory:    @0@'.format(bashcompletiondir),
855   'Zsh completions directory:     @0@'.format(zshcompletiondir),
856   'Compiler:                      @0@ @1@'.format(cc.get_id(), cc.version()),
857 #  'CFLAGS:                        @0@'.format(${CFLAGS}),
858 #  'CPPFLAGS:                      @0@'.format(${CPPFLAGS}),
859 #  'LIBS:                          @0@'.format(${LIBS}),
860   '',
861   'Enable memfd shared memory:    @0@'.format(cdata.has('HAVE_MEMFD')),
862   'Enable X11:                    @0@'.format(x11_dep.found()),
863   '  Safe X11 I/O errors:         @0@'.format(cdata.has('HAVE_XSETIOERROREXITHANDLER')),
864   'Enable OSS Output:             @0@'.format(cdata.has('HAVE_OSS_OUTPUT')),
865   'Enable OSS Wrapper:            @0@'.format(cdata.has('HAVE_OSS_WRAPPER')),
866 #  'Enable EsounD:                 @0@'.format(${ENABLE_ESOUND}),
867   'Enable Alsa:                   @0@'.format(alsa_dep.found()),
868 #  'Enable CoreAudio:              @0@'.format(${ENABLE_COREAUDIO}),
869 #  'Enable Solaris:                @0@'.format(${ENABLE_SOLARIS}),
870 #  'Enable WaveOut:                @0@'.format(${ENABLE_WAVEOUT}),
871   'Enable GLib 2:                 @0@'.format(glib_dep.found()),
872 #  'Enable GConf:                  @0@'.format(${ENABLE_GCONF}),
873   'Enable GSettings:              @0@'.format(gio_dep.found()),
874   'Enable Gtk+ 3:                 @0@'.format(gtk_dep.found()),
875   'Enable Avahi:                  @0@'.format(avahi_dep.found()),
876   'Enable Jack:                   @0@'.format(jack_dep.found()),
877   'Enable Async DNS:              @0@'.format(asyncns_dep.found()),
878   'Enable LIRC:                   @0@'.format(lirc_dep.found()),
879   'Enable D-Bus:                  @0@'.format(dbus_dep.found()),
880   '  Enable BlueZ 5:              @0@'.format(get_option('bluez5')),
881   '    Enable native headsets:    @0@'.format(get_option('bluez5-native-headset')),
882   '    Enable  ofono headsets:    @0@'.format(get_option('bluez5-ofono-headset')),
883   'Enable udev:                   @0@'.format(udev_dep.found()),
884   '  Enable HAL->udev compat:     @0@'.format(get_option('hal-compat')),
885   'Enable systemd:                @0@'.format(libsystemd_dep.found()),
886 #  'Enable TCP Wrappers:           @0@'.format(${ENABLE_TCPWRAP}),
887   'Enable libsamplerate:          @0@'.format(samplerate_dep.found()),
888   'Enable IPv6:                   @0@'.format(get_option('ipv6')),
889   'Enable OpenSSL (for Airtunes): @0@'.format(openssl_dep.found()),
890   'Enable FFTW:                   @0@'.format(fftw_dep.found()),
891   'Enable ORC:                    @0@'.format(have_orcc),
892   'Enable GStreamer:              @0@'.format(have_gstreamer),
893   'Enable Adrian echo canceller:  @0@'.format(get_option('adrian-aec')),
894   'Enable Speex (resampler, AEC): @0@'.format(speex_dep.found()),
895   'Enable SoXR (resampler):       @0@'.format(soxr_dep.found()),
896   'Enable WebRTC echo canceller:  @0@'.format(webrtc_dep.found()),
897   'Enable Gcov coverage:          @0@'.format(get_option('gcov')),
898   'Enable Valgrind:               @0@'.format(cdata.has('HAVE_VALGRIND_MEMCHECK_H')),
899   'Enable man pages:              @0@'.format(get_option('man')),
900   'Enable unit tests:             @0@'.format(get_option('tests')),
901   '',
902   'Database:                      @0@'.format(get_option('database')),
903   'Legacy Database Entry Support: @0@'.format(get_option('legacy-database-entry-format')),
904   'module-stream-restore:',
905   '  Clear old devices:           @0@'.format(get_option('stream-restore-clear-old-devices')),
906   'Running from build tree:       @0@'.format(get_option('running-from-build-tree')),
907   'System User:                   @0@'.format(cdata.get_unquoted('PA_SYSTEM_USER')),
908   'System Group:                  @0@'.format(cdata.get_unquoted('PA_SYSTEM_GROUP')),
909   'Access Group:                  @0@'.format(cdata.get_unquoted('PA_ACCESS_GROUP')),
910 #  'Enable per-user EsounD socket: @0@'.format(${ENABLE_PER_USER_ESOUND_SOCKET}),
911 #  'Force preopen:                 @0@'.format(${FORCE_PREOPEN}),
912 #  'Preopened modules:             @0@'.format(${PREOPEN_MODS}),
913 ]
914
915 message('\n    '.join(summary))
916
917 # Sanity checks
918
919 if not speex_dep.found() and not webrtc_dep.found() and not get_option('adrian-aec')
920   error('At least one echo canceller implementation must be available!')
921 endif
922
923 if samplerate_dep.found()
924   warning('Support for libsamplerate is DEPRECATED')
925 endif
926
927 if host_machine.system() != 'windows'
928   if not dbus_dep.found()
929     message = [
930       'You do not have D-Bus support enabled. It is strongly recommended',
931       'that you enable D-Bus support if your platform supports it.',
932       'Many parts of PulseAudio use D-Bus, from ConsoleKit interaction',
933       'to the Device Reservation Protocol to speak to JACK, Bluetooth',
934       'support and even a native control protocol for communicating and',
935       'controlling the PulseAudio daemon itself.',
936     ]
937     warning('\n' + '\n'.join(message))
938   endif
939   if not udev_dep.found()
940     message = [
941       'You do not have udev support enabled. It is strongly recommended',
942       'that you enable udev support if your platform supports it as it is',
943       'the primary method used to detect hardware audio devices (on Linux)',
944       'and is thus a critical part of PulseAudio on that platform.',
945     ]
946     warning('\n' + '\n'.join(message))
947   endif
948   if not speex_dep.found()
949     message = [
950       'You do not have speex support enabled. It is strongly recommended',
951       'that you enable speex support if your platform supports it as it is',
952       'the primary method used for audio resampling and is thus a critical',
953       'part of PulseAudio on that platform.',
954     ]
955     warning('\n' + '\n'.join(message))
956   endif
957 endif