build-sys: meson: support elogind alternative for module-systemd-login
[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 libelogind_dep = dependency('libelogind', required : get_option('elogind'))
659 if libelogind_dep.found()
660   cdata.set('HAVE_SYSTEMD_LOGIN', 1)
661 endif
662
663 tcpwrap_dep = cc.find_library('wrap', required: get_option('tcpwrap'))
664 if cc.has_header('tcpd.h') and cc.has_function('hosts_access', dependencies : tcpwrap_dep)
665   cdata.set('HAVE_LIBWRAP', 1)
666 endif
667
668 x11_dep = dependency('x11-xcb', required : get_option('x11'))
669 if x11_dep.found()
670   xcb_dep  = dependency('xcb',  required : true, version : '>= 1.6')
671   ice_dep  = dependency('ice',  required : true)
672   sm_dep   = dependency('sm',   required : true)
673   xtst_dep = dependency('xtst', required : true)
674   cdata.set('HAVE_X11', 1)
675   if cc.has_function('XSetIOErrorExitHandler', dependencies: x11_dep)
676     cdata.set('HAVE_XSETIOERROREXITHANDLER', 1)
677   endif
678 endif
679
680 # Module dependencies
681 if cc.has_header('sys/soundcard.h', required: get_option('oss-output'))
682   cdata.set('HAVE_OSS_OUTPUT', 1)
683   cdata.set('HAVE_OSS_WRAPPER', 1)
684   cdata.set('PULSEDSP_LOCATION', pulsedsp_location)
685 endif
686
687 if get_option('hal-compat')
688   cdata.set('HAVE_HAL_COMPAT', 1)
689 endif
690
691 avahi_dep = dependency('avahi-client', version : '>= 0.6.0', required : get_option('avahi'), disabler : true)
692 if avahi_dep.found()
693   cdata.set('HAVE_AVAHI', 1)
694 endif
695
696 sbc_dep = dependency('sbc', version : '>= 1.0', required : false)
697 if get_option('bluez5')
698   assert(dbus_dep.found(), 'BlueZ requires D-Bus support')
699   assert(sbc_dep.found(), 'BlueZ requires SBC support')
700   cdata.set('HAVE_SBC', 1)
701   cdata.set('HAVE_BLUEZ', 1)
702   cdata.set('HAVE_BLUEZ_5', 1)
703   if get_option('bluez5-native-headset')
704     cdata.set('HAVE_BLUEZ_5_NATIVE_HEADSET', 1)
705   endif
706   if get_option('bluez5-ofono-headset')
707     cdata.set('HAVE_BLUEZ_5_OFONO_HEADSET', 1)
708   endif
709 endif
710
711 fftw_dep = dependency('fftw3f', required : get_option('fftw'))
712 if fftw_dep.found()
713   cdata.set('HAVE_FFTW', 1)
714 endif
715
716 jack_dep = dependency('jack', version : '>= 0.117.0', required : get_option('jack'))
717 if jack_dep.found()
718   cdata.set('HAVE_JACK', 1)
719 endif
720
721 lirc_dep = dependency('lirc', required : get_option('lirc'))
722 if lirc_dep.found()
723   cdata.set('HAVE_LIRC', 1)
724 endif
725
726 openssl_dep = dependency('openssl', version : '>= 0.9', required : get_option('openssl'))
727 if openssl_dep.found()
728   cdata.set('HAVE_OPENSSL', 1)
729 endif
730
731 speex_dep = dependency('speexdsp', version : '>= 1.2', required : get_option('speex'))
732 if speex_dep.found()
733   cdata.set('HAVE_SPEEX', 1)
734 endif
735
736 udev_dep = dependency('libudev', version : '>= 143', required : get_option('udev'))
737 if udev_dep.found()
738   cdata.set('HAVE_UDEV', 1)
739 endif
740
741 webrtc_dep = dependency('webrtc-audio-processing', version : '>= 0.2', required : get_option('webrtc-aec'))
742 if webrtc_dep.found()
743   cdata.set('HAVE_WEBRTC', 1)
744 endif
745
746 gst_dep = dependency('gstreamer-1.0', version : '>= 1.14', required : get_option('gstreamer'))
747 gstapp_dep = dependency('gstreamer-app-1.0', required : get_option('gstreamer'))
748 gstrtp_dep = dependency('gstreamer-rtp-1.0', required : get_option('gstreamer'))
749
750 have_gstreamer = false
751 if gst_dep.found() and gstapp_dep.found() and gstrtp_dep.found()
752   have_gstreamer = true
753 endif
754
755 bluez5_gst_dep = dependency('gstreamer-1.0', version : '>= 1.14', required : get_option('bluez5-gstreamer'))
756 bluez5_gstapp_dep = dependency('gstreamer-app-1.0', required : get_option('bluez5-gstreamer'))
757 have_bluez5_gstreamer = false
758 if bluez5_gst_dep.found() and bluez5_gstapp_dep.found()
759   have_bluez5_gstreamer = true
760   cdata.set('HAVE_GSTLDAC', 1)
761   cdata.set('HAVE_GSTAPTX', 1)
762 endif
763
764 # These are required for the CMake file generation
765 cdata.set('PA_LIBDIR', libdir)
766 cdata.set('PA_INCDIR', includedir)
767 if glib_dep.found()
768   cdata.set('HAVE_GLIB20', 1) # to match the AM_CONDITIONAL for CMake file generation
769 endif
770
771 # Test dependencies
772
773 check_dep = dependency('check', version : '>= 0.9.10', required : get_option('tests'))
774
775 # Subdirs
776
777 subdir('doxygen')
778 subdir('po')
779 if get_option('man')
780   subdir('man')
781 endif
782 subdir('shell-completion/bash')
783 subdir('shell-completion/zsh')
784 subdir('src')
785 subdir('vala')
786
787 # Now generate config.h from everything above
788 configure_file(output : 'config.h', configuration : cdata)
789
790 # pkg-config files
791
792 pc_cdata = configuration_data()
793
794 pc_cdata.set('prefix', prefix)
795 pc_cdata.set('exec_prefix', prefix)
796 pc_cdata.set('libdir', libdir)
797 pc_cdata.set('includedir', includedir)
798 pc_cdata.set('modlibexecdir', modlibexecdir)
799 pc_cdata.set('PACKAGE_VERSION', pa_version_str)
800 pc_cdata.set('PA_MAJORMINOR', pa_version_major_minor)
801 # FIXME: the line below is wrong. Currently the meson thread dep lacks documentation,
802 # and doesn't allow introspection, ie. none of get_pkgconfig_variable() or
803 # get_configtool_variable() work with it, so we have no way to get this flag right,
804 # unless we do all the work ourselves. See current work in glib, also meson #553.
805 pc_cdata.set('PTHREAD_LIBS', '-pthread')
806
807 pc_files = [
808   'libpulse.pc',
809   'libpulse-simple.pc',
810 ]
811
812 if glib_dep.found()
813   pc_files += 'libpulse-mainloop-glib.pc'
814 endif
815
816 foreach file : pc_files
817   configure_file(
818     input : file + '.in',
819     output : file,
820     configuration : pc_cdata,
821     install_dir : pkgconfigdir)
822 endforeach
823
824 # CMake files
825
826 m4 = find_program('m4', required: true)
827
828 cmakedir = join_paths(libdir, 'cmake', 'PulseAudio')
829
830 cmake_template_file = configure_file(
831   input : 'PulseAudioConfig.cmake.in',
832   output : 'PulseAudioConfig.cmake.tmp',
833   configuration: cdata,
834 )
835
836 custom_target('PulseAudioConfig.cmake',
837   input : cmake_template_file,
838   output : 'PulseAudioConfig.cmake',
839   capture : true,
840   command : [m4, '@INPUT@'],
841   build_by_default : true,
842   install : true,
843   install_dir : cmakedir,
844 )
845
846 configure_file(
847   input : 'PulseAudioConfigVersion.cmake.in',
848   output : 'PulseAudioConfigVersion.cmake',
849   configuration: cdata,
850   install : true,
851   install_dir : cmakedir,
852 )
853
854 ############################################################
855
856 # Final summary
857
858 summary = [
859   '',
860   '---{ @0@ @1@ }---'.format(meson.project_name(), meson.project_version()),
861   '',
862   'prefix:                        @0@'.format(prefix),
863   'bindir:                        @0@'.format(bindir),
864   'libdir:                        @0@'.format(libdir),
865   'libexecdir:                    @0@'.format(libexecdir),
866   'mandir:                        @0@'.format(mandir),
867   'datadir:                       @0@'.format(datadir),
868   'sysconfdir:                    @0@'.format(sysconfdir),
869   'localstatedir:                 @0@'.format(localstatedir),
870   'modlibexecdir:                 @0@'.format(modlibexecdir),
871   'alsadatadir:                   @0@'.format(alsadatadir),
872   'System Runtime Path:           @0@'.format(cdata.get_unquoted('PA_SYSTEM_RUNTIME_PATH')),
873   'System State Path:             @0@'.format(cdata.get_unquoted('PA_SYSTEM_STATE_PATH')),
874   'System Config Path:            @0@'.format(cdata.get_unquoted('PA_SYSTEM_CONFIG_PATH')),
875   'Bash completions directory:    @0@'.format(bashcompletiondir),
876   'Zsh completions directory:     @0@'.format(zshcompletiondir),
877   'Compiler:                      @0@ @1@'.format(cc.get_id(), cc.version()),
878 #  'CFLAGS:                        @0@'.format(${CFLAGS}),
879 #  'CPPFLAGS:                      @0@'.format(${CPPFLAGS}),
880 #  'LIBS:                          @0@'.format(${LIBS}),
881   '',
882   'Enable memfd shared memory:    @0@'.format(cdata.has('HAVE_MEMFD')),
883   'Enable X11:                    @0@'.format(x11_dep.found()),
884   '  Safe X11 I/O errors:         @0@'.format(cdata.has('HAVE_XSETIOERROREXITHANDLER')),
885   'Enable OSS Output:             @0@'.format(cdata.has('HAVE_OSS_OUTPUT')),
886   'Enable OSS Wrapper:            @0@'.format(cdata.has('HAVE_OSS_WRAPPER')),
887 #  'Enable EsounD:                 @0@'.format(${ENABLE_ESOUND}),
888   'Enable Alsa:                   @0@'.format(alsa_dep.found()),
889 #  'Enable CoreAudio:              @0@'.format(${ENABLE_COREAUDIO}),
890 #  'Enable Solaris:                @0@'.format(${ENABLE_SOLARIS}),
891 #  'Enable WaveOut:                @0@'.format(${ENABLE_WAVEOUT}),
892   'Enable GLib 2:                 @0@'.format(glib_dep.found()),
893   'Enable GSettings:              @0@'.format(gio_dep.found()),
894   'Enable Gtk+ 3:                 @0@'.format(gtk_dep.found()),
895   'Enable Avahi:                  @0@'.format(avahi_dep.found()),
896   'Enable Jack:                   @0@'.format(jack_dep.found()),
897   'Enable Async DNS:              @0@'.format(asyncns_dep.found()),
898   'Enable LIRC:                   @0@'.format(lirc_dep.found()),
899   'Enable D-Bus:                  @0@'.format(dbus_dep.found()),
900   '  Enable BlueZ 5:              @0@'.format(get_option('bluez5')),
901   '    Enable native headsets:    @0@'.format(get_option('bluez5-native-headset')),
902   '    Enable  ofono headsets:    @0@'.format(get_option('bluez5-ofono-headset')),
903   '    Enable GStreamer based codecs: @0@'.format(have_bluez5_gstreamer),
904   'Enable udev:                   @0@'.format(udev_dep.found()),
905   '  Enable HAL->udev compat:     @0@'.format(get_option('hal-compat')),
906   'Enable systemd:                @0@'.format(libsystemd_dep.found()),
907   'Enable elogind:                @0@'.format(libelogind_dep.found()),
908   'Enable TCP Wrappers:           @0@'.format(tcpwrap_dep.found()),
909   'Enable libsamplerate:          @0@'.format(samplerate_dep.found()),
910   'Enable IPv6:                   @0@'.format(get_option('ipv6')),
911   'Enable OpenSSL (for Airtunes): @0@'.format(openssl_dep.found()),
912   'Enable FFTW:                   @0@'.format(fftw_dep.found()),
913   'Enable ORC:                    @0@'.format(have_orcc),
914   'Enable GStreamer:              @0@'.format(have_gstreamer),
915   'Enable Adrian echo canceller:  @0@'.format(get_option('adrian-aec')),
916   'Enable Speex (resampler, AEC): @0@'.format(speex_dep.found()),
917   'Enable SoXR (resampler):       @0@'.format(soxr_dep.found()),
918   'Enable WebRTC echo canceller:  @0@'.format(webrtc_dep.found()),
919   'Enable Gcov coverage:          @0@'.format(get_option('gcov')),
920   'Enable Valgrind:               @0@'.format(cdata.has('HAVE_VALGRIND_MEMCHECK_H')),
921   'Enable man pages:              @0@'.format(get_option('man')),
922   'Enable unit tests:             @0@'.format(get_option('tests')),
923   '',
924   'Database:                      @0@'.format(get_option('database')),
925   'Legacy Database Entry Support: @0@'.format(get_option('legacy-database-entry-format')),
926   'module-stream-restore:',
927   '  Clear old devices:           @0@'.format(get_option('stream-restore-clear-old-devices')),
928   'Running from build tree:       @0@'.format(get_option('running-from-build-tree')),
929   'System User:                   @0@'.format(cdata.get_unquoted('PA_SYSTEM_USER')),
930   'System Group:                  @0@'.format(cdata.get_unquoted('PA_SYSTEM_GROUP')),
931   'Access Group:                  @0@'.format(cdata.get_unquoted('PA_ACCESS_GROUP')),
932 #  'Enable per-user EsounD socket: @0@'.format(${ENABLE_PER_USER_ESOUND_SOCKET}),
933 #  'Force preopen:                 @0@'.format(${FORCE_PREOPEN}),
934 #  'Preopened modules:             @0@'.format(${PREOPEN_MODS}),
935 ]
936
937 message('\n    '.join(summary))
938
939 # Sanity checks
940
941 if not speex_dep.found() and not webrtc_dep.found() and not get_option('adrian-aec')
942   error('At least one echo canceller implementation must be available!')
943 endif
944
945 if samplerate_dep.found()
946   warning('Support for libsamplerate is DEPRECATED')
947 endif
948
949 if host_machine.system() != 'windows'
950   if not dbus_dep.found()
951     message = [
952       'You do not have D-Bus support enabled. It is strongly recommended',
953       'that you enable D-Bus support if your platform supports it.',
954       'Many parts of PulseAudio use D-Bus, from ConsoleKit interaction',
955       'to the Device Reservation Protocol to speak to JACK, Bluetooth',
956       'support and even a native control protocol for communicating and',
957       'controlling the PulseAudio daemon itself.',
958     ]
959     warning('\n' + '\n'.join(message))
960   endif
961   if host_machine.system() == 'linux' and not udev_dep.found()
962     message = [
963       'You do not have udev support enabled. It is strongly recommended',
964       'that you enable udev support if your platform supports it as it is',
965       'the primary method used to detect hardware audio devices (on Linux)',
966       'and is thus a critical part of PulseAudio on that platform.',
967     ]
968     warning('\n' + '\n'.join(message))
969   endif
970   if not speex_dep.found()
971     message = [
972       'You do not have speex support enabled. It is strongly recommended',
973       'that you enable speex support if your platform supports it as it is',
974       'the primary method used for audio resampling and is thus a critical',
975       'part of PulseAudio on that platform.',
976     ]
977     warning('\n' + '\n'.join(message))
978   endif
979 endif