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