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