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