Fix NICE_CHECK_VERSION in public install
[platform/upstream/libnice.git] / meson.build
1 project('libnice', 'c',
2   version: '0.1.19.1',
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.12.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   '-DNICE_VERSION_MAJOR=' + version_major,
82   '-DNICE_VERSION_MINOR=' + version_minor,
83   '-DNICE_VERSION_MICRO=' + version_micro,
84   '-DNICE_VERSION_NANO=' + version_nano,
85   language: 'c')
86
87 version_conf = configuration_data()
88 version_conf.set('NICE_VERSION_MAJOR', version_major)
89 version_conf.set('NICE_VERSION_MINOR', version_minor)
90 version_conf.set('NICE_VERSION_MICRO', version_micro)
91 version_conf.set('NICE_VERSION_NANO', version_nano)
92 nice_version_h = configure_file(output: 'nice-version.h',
93   install_dir: get_option('includedir') / 'nice',
94   configuration: version_conf)
95
96 cdata = configuration_data()
97
98 cdata.set_quoted('PACKAGE_STRING', meson.project_name())
99 cdata.set_quoted('PACKAGE_NAME', meson.project_name())
100 cdata.set_quoted('PACKAGE', meson.project_name())
101 cdata.set_quoted('VERSION', meson.project_version())
102
103 cdata.set('NICEAPI_EXPORT', true,
104   description: 'Public library function implementation')
105
106 # headers
107 foreach h : ['arpa/inet.h', 'net/in.h', 'net/if_media.h', 'netdb.h', 'ifaddrs.h', 'unistd.h']
108   if cc.has_header(h)
109     define = 'HAVE_' + h.underscorify().to_upper()
110     cdata.set(define, 1)
111   endif
112 endforeach
113
114 # functions
115 foreach f : ['poll', 'getifaddrs']
116   if cc.has_function(f)
117     define = 'HAVE_' + f.underscorify().to_upper()
118     cdata.set(define, 1)
119   endif
120 endforeach
121
122 if cc.has_argument('-fno-strict-aliasing')
123   add_project_arguments('-fno-strict-aliasing', language: 'c')
124 endif
125
126 # Extra compiler warnings (FIXME: not sure this makes sense to keep like this)
127 warning_level = get_option('warning_level').to_int()
128 werror = get_option('werror')
129
130 warnings = []
131
132 message('warning level: @0@'.format(warning_level))
133 message('werror enabled: @0@'.format(werror))
134
135 if warning_level >= 2
136   warnings += [
137     '-Wundef',
138     '-Wnested-externs',
139     '-Wwrite-strings',
140     '-Wpointer-arith',
141     '-Wmissing-declarations',
142     '-Wmissing-prototypes',
143     '-Wstrict-prototypes',
144     '-Wredundant-decls',
145     '-Wno-unused-parameter',
146     '-Wno-missing-field-initializers',
147     '-Wdeclaration-after-statement',
148     '-Wformat=2',
149     '-Wold-style-definition',
150     '-Wcast-align',
151     '-Wformat-nonliteral',
152     '-Wformat-security',
153   ]
154 endif
155 if warning_level >= 3
156   warnings += [
157     '-Wsign-compare',
158     '-Wstrict-aliasing',
159     '-Wshadow',
160     '-Winline',
161     '-Wpacked',
162     '-Wmissing-format-attribute',
163     '-Winit-self',
164     '-Wredundant-decls',
165     '-Wmissing-include-dirs',
166     '-Wunused-but-set-variable',
167     '-Warray-bounds',
168   ]
169   warnings += [
170     '-Wswitch-default',
171     '-Waggregate-return',
172   ]
173 endif
174 if werror
175   warnings += [
176     '-Wno-suggest-attribute=format',
177     '-Wno-cast-function-type',
178   ]
179 endif
180
181 foreach w : warnings
182   if cc.has_argument(w)
183     add_project_arguments(w, language: 'c')
184   endif
185 endforeach
186
187 # Dependencies
188 gio_dep = dependency('gio-2.0', version: glib_req,
189   fallback: ['glib', 'libgio_dep'])
190 gio_deps = [gio_dep]
191 if gio_dep.type_name() == 'internal'
192   # A workaround for libgio_dep not having its dependencies correctly declared.
193   # Should be fixed in GLib 2.60.
194   gio_deps += [
195     dependency('', fallback: ['glib', 'libglib_dep']),
196     dependency('', fallback: ['glib', 'libgmodule_dep']),
197     dependency('', fallback: ['glib', 'libgobject_dep'])
198   ]
199 endif
200 gthread_dep = dependency('gthread-2.0',
201   fallback: ['glib', 'libgthread_dep'])
202
203 # Cryto library
204 opt_cryptolib = get_option('crypto-library')
205 message('Crypto library requested: ' + opt_cryptolib)
206 crypto_dep = dependency('', required: false) # special always not found
207 if opt_cryptolib == 'auto' and host_machine.system() == 'windows'
208   crypto_dep = cc.find_library('advapi32')
209   cdata.set('USE_WIN32_CRYPTO', crypto_dep.found())
210 endif
211
212 if not crypto_dep.found() and opt_cryptolib != 'openssl'
213   crypto_dep = dependency('gnutls', version: gnutls_req, required: false)
214   cdata.set('HAVE_GNUTLS', crypto_dep.found())
215 endif
216
217 if not crypto_dep.found() and opt_cryptolib != 'gnutls'
218   crypto_dep = dependency('openssl', required: false,
219                           fallback: ['openssl', 'openssl_dep'])
220   cdata.set('HAVE_OPENSSL', crypto_dep.found())
221 endif
222
223 crypto_found = crypto_dep.found()
224 if not crypto_found and opt_cryptolib != 'gnutls'
225   # MSVC builds of OpenSSL does not generate pkg-config files,
226   # so we check for it manually here in this case, if we can't find those files
227   # Based on the CMake check for OpenSSL in CURL's CMakeLists.txt,
228   # on which headers we should check for
229   openssl_headers = []
230   foreach h : ['crypto.h', 'engine.h', 'err.h', 'pem.h',
231                'rsa.h', 'ssl.h', 'x509.h', 'rand.h', 'tls1.h']
232     openssl_headers += 'openssl/' + h
233   endforeach
234
235   # OpenSSL 1.1.x and 1.0.x (or earlier) have different .lib names,
236   # so we need to look for the correct pair
237
238   # Find either libcrypto.lib (1.1.x) or libeay32.lib (1.0.x or earlier) first
239   libcrypto_dep = cc.find_library('crypto', required: false)
240   if libcrypto_dep.found()
241     libssl = 'ssl'
242   else
243     libcrypto_dep = cc.find_library('eay32', required: false)
244     libssl = 'ssleay32'
245   endif
246
247   if libcrypto_dep.found()
248     # Find the corresponding SSL library depending on which crypto .lib we found
249     libssl_dep = cc.find_library(libssl, required: false, has_headers: openssl_headers)
250   endif
251
252   if libcrypto_dep.found() and libssl_dep.found()
253     crypto_dep = [libcrypto_dep, libssl_dep]
254     cdata.set('HAVE_OPENSSL', true)
255     crypto_found = true
256   endif
257 endif
258
259 if not crypto_found
260   if opt_cryptolib == 'gnutls'
261     error('GnuTLS requested as crypto library, but not found')
262   elif opt_cryptolib == 'openssl'
263     error('OpenSSL requested as crypto library, but not found')
264   else
265     error('Either GnuTLS or OpenSSL is required as crypto library, but neither was found')
266   endif
267 endif
268
269 # GStreamer
270 gst_dep = dependency('gstreamer-base-1.0', version: gst_req,
271   required: get_option('gstreamer'),
272   fallback : ['gstreamer', 'gst_base_dep'])
273
274 cdata.set('HAVE_GSTREAMER', gst_dep.found(), description: 'Build GStreamer plugin')
275
276 # GUPnP IGD
277 gupnp_igd_dep = dependency('gupnp-igd-1.0', version: gupnp_igd_req, required: get_option('gupnp'))
278 cdata.set('HAVE_GUPNP', gupnp_igd_dep.found(), description: 'Use the GUPnP IGD library')
279
280 libm = cc.find_library('m', required: false)
281
282 nice_incs = include_directories('.', 'agent', 'random', 'socket', 'stun')
283
284 nice_deps = gio_deps + [gthread_dep, crypto_dep, gupnp_igd_dep] + syslibs
285
286 ignored_iface_prefix = get_option('ignored-network-interface-prefix')
287 if ignored_iface_prefix != []
288   ignored_iface_prefix_quoted = []
289   foreach i : ignored_iface_prefix
290     ignored_iface_prefix_quoted += '"' + i + '"'
291   endforeach
292   cdata.set('IGNORED_IFACE_PREFIX', ','.join(ignored_iface_prefix_quoted))
293 endif
294
295 gir = find_program('g-ir-scanner', required : get_option('introspection'))
296
297 subdir('agent')
298 subdir('stun')
299 subdir('socket')
300 subdir('random')
301 subdir('nice')
302
303 if gst_dep.found()
304   subdir('gst')
305 endif
306
307 if build_machine.system() == 'windows'
308   message('Disabling gtk-doc while building on Windows')
309 else
310   if find_program('gtkdoc-scan', required: get_option('gtk_doc')).found()
311     subdir('docs/reference/libnice')
312   else
313     message('Not building documentation as gtk-doc was not found or disabled')
314   endif
315 endif
316
317 if not get_option('tests').disabled()
318   subdir('tests')
319 endif
320
321 if not get_option('examples').disabled()
322   subdir('examples')
323 endif
324
325 add_test_setup('valgrind',
326                exe_wrapper: ['valgrind',
327                              '--leak-check=full',
328                              '--show-reachable=no',
329                              '--error-exitcode=1',
330                              '--suppressions='+meson.current_source_dir()+'/tests/libnice.supp',
331                              '--num-callers=10'],
332                timeout_multiplier: 10,
333                env: ['CK_FORK=no']
334               )
335
336 configure_file(output : 'config.h', configuration : cdata)