meson: Enable (almost) all tests
[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 = 33
23
24 apiversion = '1.0'
25 soversion = 0
26 # FIXME: this doesn't actually do what we want it to
27 # maintaining compatibility with the previous libtool versioning
28 # current = minor * 100 + micro
29 libversion = '@0@.@1@.0'.format(soversion, pa_version_minor.to_int() * 100 + pa_version_micro.to_int())
30
31 # A simplified, synchronous, ABI-stable interface for client applications.
32 # For the version x:y:z always will hold y=z.
33 libpulse_simple_version = '1.1.1'
34
35 # The ABI-stable GLib adapter for client applications.
36 # For the version x:y:z always will hold y=z.
37 libpulse_mainloop_glib_version = '0.5.0'
38
39 # Paths
40
41 prefix = get_option('prefix')
42 assert(prefix.startswith('/'), 'Prefix is not absolute: "@0@"'.format(prefix))
43
44 bindir = join_paths(prefix, get_option('bindir'))
45 libdir = join_paths(prefix, get_option('libdir'))
46 libexecdir = join_paths(prefix, get_option('libexecdir'))
47 datadir = join_paths(prefix, get_option('datadir'))
48 localstatedir = join_paths(prefix, get_option('localstatedir'))
49 sysconfdir = join_paths(prefix, get_option('sysconfdir'))
50 privlibdir = join_paths(get_option('libdir'), 'pulseaudio')
51 alsadatadir = join_paths(datadir, 'pulseaudio', 'alsa-mixer')
52
53 pulselibexecdir = join_paths(libexecdir, 'pulse')
54 pulsesysconfdir = join_paths(sysconfdir, 'pulse')
55
56 modlibexecdir = get_option('modlibexecdir')
57 if modlibexecdir == ''
58   modlibexecdir = join_paths(libdir, 'pulse-' + pa_version_major_minor, 'modules')
59 endif
60
61 pulsedspdir = get_option('pulsedspdir')
62 if pulsedspdir == ''
63   join_paths(libdir, 'pulseaudio')
64 endif
65
66 # Configuration data
67
68 cc = meson.get_compiler('c')
69
70 cdata = configuration_data()
71 cdata.set_quoted('PACKAGE', 'pulseaudio')
72 cdata.set_quoted('PACKAGE_NAME', 'pulseaudio')
73 cdata.set_quoted('PACKAGE_VERSION', pa_version_str)
74 cdata.set_quoted('CANONICAL_HOST', host_machine.cpu())
75 cdata.set('PA_MAJOR', pa_version_major)
76 cdata.set('PA_MINOR', pa_version_minor)
77 cdata.set('PA_API_VERSION', pa_api_version)
78 cdata.set('PA_PROTOCOL_VERSION', pa_protocol_version)
79 cdata.set_quoted('PA_MACHINE_ID', join_paths(sysconfdir, 'machine-id'))
80 cdata.set_quoted('PA_MACHINE_ID_FALLBACK', join_paths(localstatedir, 'lib', 'dbus', 'machine-id'))
81 cdata.set_quoted('PA_SRCDIR', join_paths(meson.current_source_dir(), 'src'))
82 cdata.set_quoted('PA_BUILDDIR', meson.current_build_dir())
83 cdata.set_quoted('PA_SOEXT', '.so')
84 cdata.set_quoted('PA_DEFAULT_CONFIG_DIR', pulsesysconfdir)
85 cdata.set_quoted('PA_BINARY', join_paths(bindir, 'pulseaudio'))
86 cdata.set_quoted('PA_SYSTEM_RUNTIME_PATH', join_paths(localstatedir, 'run', 'pulse'))
87 cdata.set_quoted('PA_SYSTEM_CONFIG_PATH', join_paths(localstatedir, 'lib', 'pulse'))
88 cdata.set_quoted('PA_SYSTEM_STATE_PATH', join_paths(localstatedir, 'lib', 'pulse'))
89 cdata.set_quoted('PA_DLSEARCHPATH', modlibexecdir)
90 cdata.set_quoted('PA_SYSTEM_USER', get_option('system_user'))
91 cdata.set_quoted('PA_SYSTEM_GROUP', get_option('system_group'))
92 cdata.set_quoted('PA_ACCESS_GROUP', get_option('access_group'))
93 cdata.set_quoted('PA_CFLAGS', 'Not yet supported on meson')
94 cdata.set_quoted('PA_ALSA_PATHS_DIR', join_paths(alsadatadir, 'paths'))
95 cdata.set_quoted('PA_ALSA_PROFILE_SETS_DIR', join_paths(alsadatadir, 'profile-sets'))
96 cdata.set_quoted('DESKTOPFILEDIR', join_paths(datadir, 'applications'))
97
98 # Platform specifics
99 # First some defaults to keep config file generation happy
100 cdata.set('HAVE_COREAUDIO', 0)
101 cdata.set('HAVE_WAVEOUT', 0)
102 # FIXME: This was not tested. Maybe some flags should better be CFLAGS,
103 # rather than ending up in the config.h file?
104 if host_machine.system() == 'darwin'
105   cdata.set('OS_IS_DARWIN', 1)
106   cdata.set('_DARWIN_C_SOURCE', '200112L') # Needed to get NSIG on Mac OS
107 elif host_machine.system() == 'windows'
108   cdata.set('OS_IS_WIN32', 1)
109   cdata.set('WIN32_LEAN_AND_MEAN', 1) # Needed to avoid including unnecessary headers on Windows
110 #elif host_machine.system() == 'solaris'
111 #  # Apparently meson has no solaris support?
112 #  # Needed to get declarations for msg_control and msg_controllen on Solaris
113 #  cdata.set('_XOPEN_SOURCE', 600)
114 #  cdata.set('__EXTENSIONS__', 1)
115 endif
116
117 # Headers
118
119 check_headers = [
120   'arpa/inet.h',
121   'cpuid.h',
122   'execinfo.h',
123   'grp.h',
124   'langinfo.h',
125   'locale.h',
126   'netdb.h',
127   'netinet/in.h',
128   'netinet/in_systm.h',
129   'netinet/ip.h',
130   'netinet/tcp.h',
131   'pcreposix.h',
132   'poll.h',
133   'pwd.h',
134   'regex.h',
135   'sched.h',
136   'sys/capability.h',
137   'sys/eventfd.h',
138   'sys/ioctl.h',
139   'sys/mman.h',
140   'sys/prctl.h',
141   'sys/resource.h',
142   'sys/select.h',
143   'sys/socket.h',
144   'sys/wait.h',
145   'valgrind/memcheck.h',
146   'xlocale.h',
147 ]
148
149 foreach h : check_headers
150   if cc.has_header(h)
151     define = 'HAVE_' + h.underscorify().to_upper()
152     cdata.set(define, 1)
153   endif
154 endforeach
155
156 # FIXME: move this to the above set
157 if cc.has_header('pthread.h')
158   cdata.set('HAVE_PTHREAD', 1)
159 endif
160
161 # FIXME: move this to the above set
162 if cc.has_header('sys/un.h')
163   cdata.set('HAVE_AF_UNIX', 1)
164 endif
165
166 # Functions
167
168 check_functions = [
169   'accept4',
170   'clock_gettime',
171   'fchmod',
172   'fchown',
173   'fork',
174   'fstat',
175   'getaddrinfo',
176   'getgrgid_r',
177   'getpwnam_r',
178   'gettimeofday',
179   'getuid',
180   'lstat',
181   'memfd_create',
182   'mkfifo',
183   'mlock',
184   'nanosleep',
185   'paccept',
186   'pipe',
187   'pipe2',
188   'posix_madvise',
189   'readlink',
190   'setegid',
191   'seteuid',
192   'setregid',
193   'setreuid',
194   'setresgid',
195   'setresuid',
196   'setsid',
197   'sig2str',
198   'sigaction',
199   'strtod_l',
200   'symlink',
201   'sysconf',
202   'uname',
203 ]
204
205 foreach f : check_functions
206   if cc.has_function(f)
207     define = 'HAVE_' + f.underscorify().to_upper()
208     cdata.set(define, 1)
209   endif
210 endforeach
211
212 if cc.has_function('SYS_memfd_create', prefix : '#include <sys/syscall.h>')
213   cdata.set('HAVE_MEMFD', 1)
214 endif
215
216 # Symbols
217
218 if cc.has_header_symbol('signal.h', 'SIGXCPU')
219   cdata.set('HAVE_SIGXCPU', 1)
220 endif
221
222 if not cc.has_header_symbol('netinet/in.h', 'INADDR_NONE')
223   if not cc.has_header_symbol('winsock2.h', 'INADDR_NONE')
224     # Define INADDR_NONE if not found (Solaris)
225     cdata.set('INADDR_NONE', '0xffffffff')
226   endif
227 endif
228
229 # Types
230
231 # FIXME: do we ever care about gid_t not being defined / smaller than an int?
232 cdata.set('GETGROUPS_T', 'gid_t')
233
234 # Include paths
235
236 configinc = include_directories('.')
237 topinc = include_directories('src')
238
239 # CFLAGS
240
241 pa_c_args = ['-DHAVE_CONFIG_H', '-D_GNU_SOURCE']
242 server_c_args = ['-D__INCLUDED_FROM_PULSE_AUDIO']
243 cdata.set('MESON_BUILD', 1)
244
245 # Core Dependencies
246
247 libm_dep = cc.find_library('m', required : true)
248 thread_dep = dependency('threads')
249 cap_dep = cc.find_library('cap', required : false)
250
251 shm_dep = cc.find_library('rt', required : false)
252 if shm_dep.found()
253   cdata.set('HAVE_SHM_OPEN', 1)
254 endif
255
256 atomictest = '''void func() {
257   volatile int atomic = 2;
258   __sync_bool_compare_and_swap (&atomic, 2, 3);
259 }
260 '''
261 if cc.compiles(atomictest)
262   cdata.set('HAVE_ATOMIC_BUILTINS', true)
263 else
264   # FIXME: check if we need libatomic_ops
265 endif
266
267 # FIXME: make sure it's >= 2.2
268 ltdl_dep = cc.find_library('ltdl', required : true)
269 # FIXME: can meson support libtool -dlopen/-dlpreopen things?
270 #        and do we still want to support this at all?
271 cdata.set('DISABLE_LIBTOOL_PRELOAD', 1)
272
273 if get_option('database') == 'tdb'
274   database_dep = dependency('tdb')
275 elif get_option('database') == 'gdbm'
276   database_dep = cc.find_library('gdbm', required : true)
277 else
278   database_dep = dependency('', required: false)
279 endif
280
281 if get_option('ipv6')
282   cdata.set('HAVE_IPV6', 1)
283 endif
284
285 if get_option('legacy-database-entry-format')
286   cdata.set('ENABLE_LEGACY_DATABASE_ENTRY_FORMAT', 1)
287 endif
288
289 alsa_dep = dependency('alsa', version : '>= 1.0.24', required : get_option('alsa'))
290 if alsa_dep.found()
291   cdata.set('HAVE_ALSA', 1)
292   cdata.set('HAVE_ALSA_UCM', 1)
293 endif
294
295 asyncns_dep = dependency('libasyncns', version : '>= 0.1', required : get_option('asyncns'))
296 if asyncns_dep.found()
297   cdata.set('HAVE_LIBASYNCNS', 1)
298 endif
299
300 dbus_dep = dependency('dbus-1', version : '>= 1.4.12', required : get_option('dbus'))
301 if dbus_dep.found()
302   cdata.set('HAVE_DBUS', 1)
303 endif
304
305 gio_dep = dependency('gio-2.0', version : '>= 2.26.0', required : get_option('gsettings'))
306 if gio_dep.found()
307   cdata.set('HAVE_GSETTINGS', 1)
308 endif
309
310 glib_dep = dependency('glib-2.0', version : '>= 2.4.0', required: get_option('glib'))
311 if glib_dep.found()
312   cdata.set('HAVE_GLIB', 1)
313 endif
314
315 gtk_dep = dependency('gtk+-3.0', required : get_option('gtk'))
316 if gtk_dep.found()
317   cdata.set('HAVE_GTK', 1)
318 endif
319
320 samplerate_dep = dependency('samplerate', version : '>= 0.1.0', required : get_option('samplerate'))
321 if samplerate_dep.found()
322   cdata.set('HAVE_LIBSAMPLERATE', 1)
323 endif
324
325 sndfile_dep = dependency('sndfile', version : '>= 1.0.20')
326
327 soxr_dep = dependency('soxr', version : '>= 0.1.1', required : get_option('soxr'))
328 if soxr_dep.found()
329   cdata.set('HAVE_SOXR', 1)
330 endif
331
332 systemd_dep = dependency('libsystemd', required : get_option('systemd'))
333 if systemd_dep.found()
334   cdata.set('HAVE_SYSTEMD_DAEMON', 1)
335   cdata.set('HAVE_SYSTEMD_LOGIN', 1)
336   cdata.set('HAVE_SYSTEMD_JOURNAL', 1)
337 endif
338
339 x11_dep = dependency('x11-xcb', required : get_option('x11'))
340 if x11_dep.found()
341   xcb_dep  = dependency('xcb',  required : true, version : '>= 1.6')
342   ice_dep  = dependency('ice',  required : true)
343   sm_dep   = dependency('sm',   required : true)
344   xtst_dep = dependency('xtst', required : true)
345   cdata.set('HAVE_X11', 1)
346 endif
347
348 # FIXME: support ORC
349 cdata.set('DISABLE_ORC', 1)
350
351 # Module dependencies
352
353 if cc.has_header('sys/soundcard.h')
354   cdata.set('HAVE_OSS_OUTPUT', 1)
355   cdata.set('HAVE_OSS_WRAPPER', 1)
356   cdata.set_quoted('PULSEDSP_LOCATION', pulsedspdir)
357 endif
358
359 if get_option('hal-compat')
360   cdata.set('HAVE_HAL_COMPAT', 1)
361 endif
362
363 avahi_dep = dependency('avahi-client', version : '>= 0.6.0', required : get_option('avahi'), disabler : true)
364 if avahi_dep.found()
365   cdata.set('HAVE_AVAHI', 1)
366 endif
367
368 bluez_dep = dependency('bluez', version : '>= 5.0', required : get_option('bluez5'))
369 sbc_dep = dependency('sbc', version : '>= 1.0', required : false)
370 if bluez_dep.found()
371   assert(dbus_dep.found(), 'BlueZ requires D-Bus support')
372   assert(sbc_dep.found(), 'BlueZ requires SBC support')
373   cdata.set('HAVE_SBC', 1)
374   cdata.set('HAVE_BLUEZ', 1)
375   cdata.set('HAVE_BLUEZ_5', 1)
376   if get_option('bluez5-native-headset')
377     cdata.set('HAVE_BLUEZ_5_NATIVE_HEADSET', 1)
378   endif
379   if get_option('bluez5-ofono-headset')
380     cdata.set('HAVE_BLUEZ_5_OFONO_HEADSET', 1)
381   endif
382 endif
383
384 fftw_dep = dependency('fftw3f', required : get_option('fftw'))
385 if fftw_dep.found()
386   cdata.set('HAVE_FFTW', 1)
387 endif
388
389 jack_dep = dependency('jack', version : '>= 0.117.0', required : get_option('jack'))
390 if jack_dep.found()
391   cdata.set('HAVE_JACK', 1)
392 endif
393
394 lirc_dep = dependency('lirc', required : get_option('lirc'))
395 if lirc_dep.found()
396   cdata.set('HAVE_LIRC', 1)
397 endif
398
399 openssl_dep = dependency('openssl', version : '>= 0.9', required : get_option('openssl'))
400 if openssl_dep.found()
401   cdata.set('HAVE_OPENSSL', 1)
402 endif
403
404 speex_dep = dependency('speexdsp', version : '>= 1.2', required : get_option('speex'))
405 if speex_dep.found()
406   cdata.set('HAVE_SPEEX', 1)
407 endif
408
409 udev_dep = dependency('libudev', version : '>= 143', required : get_option('udev'))
410 if udev_dep.found()
411   cdata.set('HAVE_UDEV', 1)
412 endif
413
414 webrtc_dep = dependency('webrtc-audio-processing', version : '>= 0.2', required : get_option('webrtc-aec'))
415 if webrtc_dep.found()
416   cdata.set('HAVE_WEBRTC', 1)
417 endif
418
419 # Test dependencies
420
421 check_dep = dependency('check', version : '>= 0.9.10', required : get_option('tests'))
422
423 # Now generate config.h from everything above
424 configure_file(output : 'config.h', configuration : cdata)
425
426 subdir('man')
427 subdir('src')
428
429 ############################################################
430
431 # Final summary
432
433 summary = [
434   '',
435   '---{ @0@ @1@ }---'.format(meson.project_name(), meson.project_version()),
436   '',
437   'prefix:                        @0@'.format(prefix),
438   'bindir:                        @0@'.format(bindir),
439   'libdir:                        @0@'.format(libdir),
440   'libexecdir:                    @0@'.format(libexecdir),
441   'datadir:                       @0@'.format(datadir),
442   'sysconfdir:                    @0@'.format(sysconfdir),
443   'localstatedir:                 @0@'.format(localstatedir),
444   'modlibexecdir:                 @0@'.format(modlibexecdir),
445   'System Runtime Path:           @0@'.format(cdata.get_unquoted('PA_SYSTEM_RUNTIME_PATH')),
446   'System State Path:             @0@'.format(cdata.get_unquoted('PA_SYSTEM_STATE_PATH')),
447   'System Config Path:            @0@'.format(cdata.get_unquoted('PA_SYSTEM_CONFIG_PATH')),
448 #  'Zsh completions directory:     @0@'.format(${zshcompletiondir}),
449 #  'Bash completions directory:    @0@'.format(${bashcompletiondir}),
450   'Compiler:                      @0@ @1@'.format(cc.get_id(), cc.version()),
451 #  'CFLAGS:                        @0@'.format(${CFLAGS}),
452 #  'CPPFLAGS:                      @0@'.format(${CPPFLAGS}),
453 #  'LIBS:                          @0@'.format(${LIBS}),
454   '',
455   'Enable memfd shared memory:    @0@'.format(cdata.has('HAVE_MEMFD')),
456   'Enable X11:                    @0@'.format(x11_dep.found()),
457 #  'Enable OSS Output:             @0@'.format(${ENABLE_OSS_OUTPUT}),
458 #  'Enable OSS Wrapper:            @0@'.format(${ENABLE_OSS_WRAPPER}),
459 #  'Enable EsounD:                 @0@'.format(${ENABLE_ESOUND}),
460   'Enable Alsa:                   @0@'.format(alsa_dep.found()),
461 #  'Enable CoreAudio:              @0@'.format(${ENABLE_COREAUDIO}),
462 #  'Enable Solaris:                @0@'.format(${ENABLE_SOLARIS}),
463 #  'Enable WaveOut:                @0@'.format(${ENABLE_WAVEOUT}),
464   'Enable GLib 2:                 @0@'.format(glib_dep.found()),
465 #  'Enable GConf:                  @0@'.format(${ENABLE_GCONF}),
466   'Enable GSettings:              @0@'.format(gio_dep.found()),
467   'Enable Gtk+ 3:                 @0@'.format(gtk_dep.found()),
468   'Enable Avahi:                  @0@'.format(avahi_dep.found()),
469   'Enable Jack:                   @0@'.format(jack_dep.found()),
470   'Enable Async DNS:              @0@'.format(asyncns_dep.found()),
471   'Enable LIRC:                   @0@'.format(lirc_dep.found()),
472   'Enable D-Bus:                  @0@'.format(dbus_dep.found()),
473   '  Enable BlueZ 5:              @0@'.format(bluez_dep.found()),
474   '    Enable native headsets:    @0@'.format(get_option('bluez5-native-headset')),
475   '    Enable  ofono headsets:    @0@'.format(get_option('bluez5-ofono-headset')),
476   'Enable udev:                   @0@'.format(udev_dep.found()),
477   '  Enable HAL->udev compat:     @0@'.format(get_option('hal-compat')),
478   'Enable systemd:                @0@'.format(systemd_dep.found()),
479 #  'Enable TCP Wrappers:           @0@'.format(${ENABLE_TCPWRAP}),
480   'Enable libsamplerate:          @0@'.format(samplerate_dep.found()),
481   'Enable IPv6:                   @0@'.format(get_option('ipv6')),
482   'Enable OpenSSL (for Airtunes): @0@'.format(openssl_dep.found()),
483   'Enable FFTW:                   @0@'.format(fftw_dep.found()),
484 #  'Enable orc:                    @0@'.format(${ENABLE_ORC}),
485   'Enable Adrian echo canceller:  @0@'.format(get_option('adrian-aec')),
486   'Enable Speex (resampler, AEC): @0@'.format(speex_dep.found()),
487   'Enable SoXR (resampler):       @0@'.format(soxr_dep.found()),
488   'Enable WebRTC echo canceller:  @0@'.format(webrtc_dep.found()),
489 #  'Enable gcov coverage:          @0@'.format(${ENABLE_GCOV}),
490   'Enable unit tests:             @0@'.format(get_option('tests')),
491   '',
492   'Database:                      @0@'.format(get_option('database')),
493   'Legacy Database Entry Support: @0@'.format(get_option('legacy-database-entry-format')),
494   'System User:                   @0@'.format(cdata.get_unquoted('PA_SYSTEM_USER')),
495   'System Group:                  @0@'.format(cdata.get_unquoted('PA_SYSTEM_GROUP')),
496   'Access Group:                  @0@'.format(cdata.get_unquoted('PA_ACCESS_GROUP')),
497 #  'Enable per-user EsounD socket: @0@'.format(${ENABLE_PER_USER_ESOUND_SOCKET}),
498 #  'Force preopen:                 @0@'.format(${FORCE_PREOPEN}),
499 #  'Preopened modules:             @0@'.format(${PREOPEN_MODS}),
500 ]
501
502 message('\n    '.join(summary))
503
504 # Sanity checks
505
506 if not speex_dep.found() and not webrtc_dep.found() and not get_option('adrian-aec')
507   error('At least one echo canceller implementation must be available!')
508 endif
509
510 if samplerate_dep.found()
511   warning('Support for libsamplerate is DEPRECATED')
512 endif
513
514 if host_machine.system() != 'windows'
515   if not dbus_dep.found()
516     message = [
517       'You do not have D-Bus support enabled. It is strongly recommended',
518       'that you enable D-Bus support if your platform supports it.',
519       'Many parts of PulseAudio use D-Bus, from ConsoleKit interaction',
520       'to the Device Reservation Protocol to speak to JACK, Bluetooth',
521       'support and even a native control protocol for communicating and',
522       'controlling the PulseAudio daemon itself.',
523     ]
524     warning('\n' + '\n'.join(message))
525   endif
526   if not udev_dep.found()
527     message = [
528       'You do not have udev support enabled. It is strongly recommended',
529       'that you enable udev support if your platform supports it as it is',
530       'the primary method used to detect hardware audio devices (on Linux)',
531       'and is thus a critical part of PulseAudio on that platform.',
532     ]
533     warning('\n' + '\n'.join(message))
534   endif
535   if not speex_dep.found()
536     message = [
537       'You do not have speex support enabled. It is strongly recommended',
538       'that you enable speex support if your platform supports it as it is',
539       'the primary method used for audio resampling and is thus a critical',
540       'part of PulseAudio on that platform.',
541     ]
542     warning('\n' + '\n'.join(message))
543   endif
544 endif