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