41aeb96825a328b9d44eb3f948ea254831d87329
[platform/upstream/libnice.git] / meson.build
1 project('libnice', 'c',
2   version: '0.1.18',
3   meson_version : '>= 0.52',
4   default_options : ['warning_level=1', 'buildtype=debugoptimized'])
5
6 nice_version = meson.project_version()
7 version_arr = nice_version.split('.')
8 version_major = version_arr[0]
9 version_minor = version_arr[1]
10 version_micro = version_arr[2]
11 if version_arr.length() == 4
12   version_nano = version_arr[3]
13 else
14   version_nano = 0
15 endif
16
17 # maintain compatibility with the previous libtool versioning
18 # libversion has 3 parts A.B.C
19 # A is the ABI version, change it if the ABI is broken, changing it resets B and C to 0. It matches soversion
20 # B is the ABI age, change it on new APIs that don't break existing ones, changing it resets C to 0
21 # C is the revision, change on new updates that don't change APIs
22 soversion = 10
23 libversion = '10.11.0'
24
25 glib_req = '>= 2.54'
26 gnutls_req = '>= 2.12.0'
27 gupnp_igd_req = '>= 0.2.4'
28 gst_req = '>= 1.0.0'
29
30 nice_datadir = join_paths(get_option('prefix'), get_option('datadir'))
31
32 cc = meson.get_compiler('c')
33
34 syslibs = []
35
36 if cc.get_id() == 'msvc'
37   add_project_arguments(
38       cc.get_supported_arguments(['/utf-8']), # set the input encoding to utf-8
39       language : 'c')
40 endif
41
42 if host_machine.system() == 'windows'
43   syslibs += [cc.find_library('iphlpapi')]
44   syslibs += [cc.find_library('ws2_32')]
45 elif host_machine.system() == 'sunos'
46   add_project_arguments('-D_XOPEN_SOURCE=600', language: 'c')
47   add_project_arguments('-D__EXTENSIONS__=1', language: 'c')
48   # inet_pton() is only used by the tests
49   syslibs += [cc.find_library('nsl')]
50   if not cc.has_function('inet_pton')
51     libnsl = cc.find_library('nsl', required: false)
52     if libnsl.found() and cc.has_function('inet_pton', dependencies: libnsl)
53       syslibs += [libnsl]
54     endif
55   endif
56   if not cc.has_function('socket')
57     libsocket = cc.find_library('socket', required: false)
58     libinet = cc.find_library('inet', required: false)
59     if cc.has_function('socket', dependencies: libsocket)
60       syslibs += [libsocket]
61     elif cc.has_function('socket', dependencies: libinet)
62       syslibs += [libinet]
63     else
64       error('Could not find right library for socket() on Solaris')
65     endif
66   endif
67 endif
68
69 if not cc.has_function('clock_gettime')
70   librt = cc.find_library('rt', required: false)
71   if cc.has_function('clock_gettime', dependencies: librt)
72     syslibs += [librt]
73   endif
74 endif
75
76 glib_req_minmax_str = glib_req.split().get(1).underscorify()
77 add_project_arguments('-D_GNU_SOURCE',
78   '-DHAVE_CONFIG_H',
79   '-DGLIB_VERSION_MIN_REQUIRED=GLIB_VERSION_' + glib_req_minmax_str,
80   '-DGLIB_VERSION_MAX_ALLOWED=GLIB_VERSION_' + glib_req_minmax_str,
81   language: 'c')
82
83 cdata = configuration_data()
84
85 cdata.set_quoted('PACKAGE_STRING', meson.project_name())
86 cdata.set_quoted('PACKAGE_NAME', meson.project_name())
87 cdata.set_quoted('PACKAGE', meson.project_name())
88 cdata.set_quoted('VERSION', meson.project_version())
89
90 cdata.set('NICEAPI_EXPORT', true,
91   description: 'Public library function implementation')
92
93 # headers
94 foreach h : ['arpa/inet.h', 'net/in.h', 'netdb.h', 'ifaddrs.h', 'unistd.h']
95   if cc.has_header(h)
96     define = 'HAVE_' + h.underscorify().to_upper()
97     cdata.set(define, 1)
98   endif
99 endforeach
100
101 # functions
102 foreach f : ['poll', 'getifaddrs']
103   if cc.has_function(f)
104     define = 'HAVE_' + f.underscorify().to_upper()
105     cdata.set(define, 1)
106   endif
107 endforeach
108
109 if cc.has_argument('-fno-strict-aliasing')
110   add_project_arguments('-fno-strict-aliasing', language: 'c')
111 endif
112
113 # Extra compiler warnings (FIXME: not sure this makes sense to keep like this)
114 warning_level = get_option('warning_level').to_int()
115 werror = get_option('werror')
116
117 warnings = []
118
119 message('warning level: @0@'.format(warning_level))
120 message('werror enabled: @0@'.format(werror))
121
122 if warning_level >= 2
123   warnings += [
124     '-Wundef',
125     '-Wnested-externs',
126     '-Wwrite-strings',
127     '-Wpointer-arith',
128     '-Wmissing-declarations',
129     '-Wmissing-prototypes',
130     '-Wstrict-prototypes',
131     '-Wredundant-decls',
132     '-Wno-unused-parameter',
133     '-Wno-missing-field-initializers',
134     '-Wdeclaration-after-statement',
135     '-Wformat=2',
136     '-Wold-style-definition',
137     '-Wcast-align',
138     '-Wformat-nonliteral',
139     '-Wformat-security',
140   ]
141 endif
142 if warning_level >= 3
143   warnings += [
144     '-Wsign-compare',
145     '-Wstrict-aliasing',
146     '-Wshadow',
147     '-Winline',
148     '-Wpacked',
149     '-Wmissing-format-attribute',
150     '-Winit-self',
151     '-Wredundant-decls',
152     '-Wmissing-include-dirs',
153     '-Wunused-but-set-variable',
154     '-Warray-bounds',
155   ]
156   warnings += [
157     '-Wswitch-default',
158     '-Waggregate-return',
159   ]
160 endif
161 if werror
162   warnings += [
163     '-Wno-suggest-attribute=format',
164     '-Wno-cast-function-type',
165   ]
166 endif
167
168 foreach w : warnings
169   if cc.has_argument(w)
170     add_project_arguments(w, language: 'c')
171   endif
172 endforeach
173
174 # Dependencies
175 gio_dep = dependency('gio-2.0', version: glib_req,
176   fallback: ['glib', 'libgio_dep'])
177 gio_deps = [gio_dep]
178 if gio_dep.type_name() == 'internal'
179   # A workaround for libgio_dep not having its dependencies correctly declared.
180   # Should be fixed in GLib 2.60.
181   gio_deps += [
182     dependency('', fallback: ['glib', 'libglib_dep']),
183     dependency('', fallback: ['glib', 'libgmodule_dep']),
184     dependency('', fallback: ['glib', 'libgobject_dep'])
185   ]
186 endif
187 gthread_dep = dependency('gthread-2.0',
188   fallback: ['glib', 'libgthread_dep'])
189
190 # Cryto library
191 opt_cryptolib = get_option('crypto-library')
192 message('Crypto library requested: ' + opt_cryptolib)
193 if opt_cryptolib != 'openssl'
194   crypto_dep = dependency('gnutls', version: gnutls_req, required: false)
195   cdata.set('HAVE_GNUTLS', crypto_dep.found())
196   if not crypto_dep.found() and opt_cryptolib == 'auto'
197     crypto_dep = dependency('openssl', required: false,
198       fallback: ['openssl', 'openssl_dep'])
199     cdata.set('HAVE_OPENSSL', crypto_dep.found())
200   endif
201 else
202   crypto_dep = dependency('openssl', required: false)
203   cdata.set('HAVE_OPENSSL', crypto_dep.found())
204   if not crypto_dep.found() and openssl == 'auto'
205     crypto_dep = dependency('gnutls', version: gnutls_req, required: false)
206     cdata.set('HAVE_GNUTLS', crypto_dep.found())
207   endif
208 endif
209
210 crypto_found = crypto_dep.found()
211 if not crypto_found and opt_cryptolib != 'gnutls'
212   # MSVC builds of OpenSSL does not generate pkg-config files,
213   # so we check for it manually here in this case, if we can't find those files
214   # Based on the CMake check for OpenSSL in CURL's CMakeLists.txt,
215   # on which headers we should check for
216   openssl_headers = []
217   foreach h : ['crypto.h', 'engine.h', 'err.h', 'pem.h',
218                'rsa.h', 'ssl.h', 'x509.h', 'rand.h', 'tls1.h']
219     openssl_headers += 'openssl/' + h
220   endforeach
221
222   # OpenSSL 1.1.x and 1.0.x (or earlier) have different .lib names,
223   # so we need to look for the correct pair
224
225   # Find either libcrypto.lib (1.1.x) or libeay32.lib (1.0.x or earlier) first
226   libcrypto_dep = cc.find_library('crypto', required: false)
227   if libcrypto_dep.found()
228     libssl = 'ssl'
229   else
230     libcrypto_dep = cc.find_library('eay32', required: false)
231     libssl = 'ssleay32'
232   endif
233
234   if libcrypto_dep.found()
235     # Find the corresponding SSL library depending on which crypto .lib we found
236     libssl_dep = cc.find_library(libssl, required: false, has_headers: openssl_headers)
237   endif
238
239   if libcrypto_dep.found() and libssl_dep.found()
240     crypto_dep = [libcrypto_dep, libssl_dep]
241     crypto_found = true
242   endif
243 endif
244
245 if not crypto_found
246   if opt_cryptolib == 'gnutls'
247     error('GnuTLS requested as crypto library, but not found')
248   elif opt_cryptolib == 'openssl'
249     error('OpenSSL requested as crypto library, but not found')
250   else
251     error('Either GnuTLS or OpenSSL is required as crypto library, but neither was found')
252   endif
253 endif
254
255 # GStreamer
256 gst_dep = dependency('gstreamer-base-1.0', version: gst_req,
257   required: get_option('gstreamer'),
258   fallback : ['gstreamer', 'gst_base_dep'])
259
260 cdata.set('HAVE_GSTREAMER', gst_dep.found(), description: 'Build GStreamer plugin')
261
262 # GUPnP IGD
263 gupnp_igd_dep = dependency('gupnp-igd-1.0', version: gupnp_igd_req, required: get_option('gupnp'))
264 cdata.set('HAVE_GUPNP', gupnp_igd_dep.found(), description: 'Use the GUPnP IGD library')
265
266 libm = cc.find_library('m', required: false)
267
268 nice_incs = include_directories('.', 'agent', 'random', 'socket', 'stun')
269
270 nice_deps = gio_deps + [gthread_dep, crypto_dep, gupnp_igd_dep] + syslibs
271
272 ignored_iface_prefix = get_option('ignored-network-interface-prefix')
273 if ignored_iface_prefix != []
274   ignored_iface_prefix_quoted = []
275   foreach i : ignored_iface_prefix
276     ignored_iface_prefix_quoted += '"' + i + '"'
277   endforeach
278   cdata.set('IGNORED_IFACE_PREFIX', ','.join(ignored_iface_prefix_quoted))
279 endif
280
281 gir = find_program('g-ir-scanner', required : get_option('introspection'))
282
283 subdir('agent')
284 subdir('stun')
285 subdir('socket')
286 subdir('random')
287 subdir('nice')
288
289 if gst_dep.found()
290   subdir('gst')
291 endif
292
293 if build_machine.system() == 'windows'
294   message('Disabling gtk-doc while building on Windows')
295 else
296   if find_program('gtkdoc-scan', required: get_option('gtk_doc')).found()
297     subdir('docs/reference/libnice')
298   else
299     message('Not building documentation as gtk-doc was not found or disabled')
300   endif
301 endif
302
303 if not get_option('tests').disabled()
304   subdir('tests')
305 endif
306
307 if not get_option('examples').disabled()
308   subdir('examples')
309 endif
310
311 add_test_setup('valgrind',
312                exe_wrapper: ['valgrind',
313                              '--leak-check=full',
314                              '--show-reachable=no',
315                              '--error-exitcode=1',
316                              '--suppressions='+meson.current_source_dir()+'/tests/libnice.supp',
317                              '--num-callers=10'],
318                timeout_multiplier: 10,
319                env: ['CK_FORK=no']
320               )
321
322 configure_file(output : 'config.h', configuration : cdata)