Add LGPL 2.1 license file for soup-websocket-connection.c
[platform/upstream/libsoup.git] / meson.build
1 project('libsoup', 'c',
2         version: '2.72.0',
3         meson_version : '>=0.50',
4         license : 'LGPL2',
5         default_options : 'c_std=c99')
6
7 gnome = import('gnome')
8
9 soup_version = meson.project_version()
10 version_arr = soup_version.split('.')
11 soup_version_major = version_arr[0]
12 soup_version_minor = version_arr[1]
13 soup_version_micro = version_arr[2]
14
15 # Before making a release, the libversion string should be modified.
16 #
17 #  * Bump the first component if binary compatibility has been broken; or
18 #  * Bump the second component if new APIs are added; or
19 #  * Bump the third component otherwise.
20 #
21 # When bumping the first component version, set the second and third components
22 # to 0. When bumping the second version, set the third one to zero.
23 libversion = '1.11.0'
24 apiversion = '2.4'
25 soversion = libversion.split('.')[0]
26 libsoup_api_name = '@0@-@1@'.format(meson.project_name(), apiversion)
27 libversion_arr = libversion.split('.')
28 darwin_version_major = libversion_arr[0].to_int()
29 darwin_version_minor = libversion_arr[1].to_int()
30 darwin_version_micro = libversion_arr[2].to_int()
31 darwin_versions = [darwin_version_major + darwin_version_minor + 1, '@0@.@1@'.format(darwin_version_major + darwin_version_minor + 1, darwin_version_micro)]
32
33 host_system = host_machine.system()
34
35 # Needed for the gmtime_r check and for some system types availability.
36 default_source_flag = [
37   '-D_DEFAULT_SOURCE'
38 ]
39
40 add_project_arguments(default_source_flag, language: 'c')
41
42 if host_system == 'sunos'
43       add_project_arguments('-D__EXTENSIONS__', language: 'c')
44       add_project_link_arguments('-lsocket', language: 'c')
45 endif
46
47 common_flags = [
48   '-DHAVE_CONFIG_H',
49 ]
50
51 cc = meson.get_compiler('c')
52 # Enable extra warnings if compiler supports them.
53 if cc.get_id() == 'msvc'
54   common_flags += ['/FImsvc_recommended_pragmas.h']
55
56   # set the input encoding to utf-8
57   add_project_arguments(cc.get_supported_arguments(['/utf-8']), language: 'c')
58 else
59   test_cflags = [
60       '-Wall',
61       '-Wmissing-include-dirs',
62       '-Wpointer-arith',
63       '-Winit-self',
64       '-Wdeclaration-after-statement',
65       '-Werror=missing-prototypes',
66       '-Werror=implicit-function-declaration',
67       '-Werror=aggregate-return',
68       '-Werror=format=2',
69       '-Wstrict-prototypes',
70       '-Wno-format-zero-length',
71   ]
72
73   common_flags += cc.get_supported_arguments(test_cflags)
74 endif
75
76 if cc.get_id() != 'msvc' and host_system == 'windows'
77   # For "%2hhx" sscanf format and the like
78   add_project_arguments('-D__USE_MINGW_ANSI_STDIO=1', language : 'c')
79 endif
80
81 add_project_arguments(common_flags, language : 'c')
82
83 glib_required_version = '>= 2.58'
84 glib_dep = dependency('glib-2.0', version : glib_required_version,
85                        fallback: ['glib', 'libglib_dep'])
86 gobject_dep = dependency('gobject-2.0', version : glib_required_version,
87                        fallback: ['glib', 'libgobject_dep'])
88 gio_dep = dependency('gio-2.0', version : glib_required_version,
89                        fallback: ['glib', 'libgio_dep'])
90
91 glib_deps = [glib_dep, gobject_dep, gio_dep]
92
93 sqlite_dep = dependency('sqlite3', required: false)
94
95 # Fallback check for sqlite, not all platforms ship pkg-config file
96 if not sqlite_dep.found()
97   sqlite_dep = cc.find_library('sqlite3',
98     has_headers : ['sqlite3.h'],
99     required: false)
100 endif
101
102 if not sqlite_dep.found()
103   sqlite_dep = subproject('sqlite').get_variable('sqlite_dep')
104 endif
105
106 libxml_dep = dependency('libxml-2.0', required: false)
107
108 # Fallback check for libxml2, not all platforms ship pkg-config file
109 if not libxml_dep.found()
110   # Note: The XML include dir needs to be within the INCLUDE envvar,
111   # such as <INCLUDEDIR>\libxml2
112   libxml2_libname = cc.get_id() == 'msvc' ? 'libxml2' : 'xml2'
113   libxml_dep = cc.find_library(libxml2_libname,
114     has_headers : 'libxml/tree.h',
115     required: false)
116 endif
117
118 if not libxml_dep.found()
119   libxml_dep = subproject('libxml2').get_variable('xml2lib_dep')
120 endif
121
122 cdata = configuration_data()
123
124 brotlidec_dep = dependency('libbrotlidec', required : get_option('brotli'))
125 if brotlidec_dep.found()
126   cdata.set('WITH_BROTLI', true)
127 endif
128
129 platform_deps = []
130 hidden_visibility_flag = []
131 is_static_library = get_option('default_library') == 'static'
132 if not is_static_library
133   if host_machine.system() == 'windows'
134     platform_deps = [cc.find_library('ws2_32')]
135     cdata.set('DLL_EXPORT', true)
136     cdata.set('_SOUP_EXTERN', '__declspec(dllexport) extern')
137     if cc.get_id() != 'msvc'
138       hidden_visibility_flag += ['-fvisibility=hidden']
139     endif
140   else
141     cdata.set('_SOUP_EXTERN', '__attribute__((visibility("default"))) extern')
142     hidden_visibility_flag += ['-fvisibility=hidden']
143   endif
144 endif
145
146 libpsl_required_version = '>= 0.20'
147 libpsl_dep = dependency('libpsl', version : libpsl_required_version,
148   fallback : ['libpsl', 'libpsl_dep'])
149
150 if cc.has_function('gmtime_r', prefix : '#include <time.h>', args : default_source_flag)
151     cdata.set('HAVE_GMTIME_R', '1')
152 endif
153
154 # sysprof support
155 libsysprof_capture_dep = dependency('sysprof-capture-4',
156   required: get_option('sysprof'),
157   default_options: [
158     'enable_examples=false',
159     'enable_gtk=false',
160     'enable_tests=false',
161     'enable_tools=false',
162     'libsysprof=false',
163     'with_sysprofd=none',
164     'help=false',
165   ],
166   fallback: ['sysprof', 'libsysprof_capture_dep'],
167 )
168 cdata.set('HAVE_SYSPROF', libsysprof_capture_dep.found())
169
170 ###################
171 # GIO TLS support #
172 ###################
173 enable_tls_check = get_option('tls_check')
174 if enable_tls_check
175   if gio_dep.type_name() == 'internal'
176     warning('TLS check was enabled but required dependency is internal')
177   else
178     check_gio_tls_src = '''#include <gio/gio.h>
179     int main(void) {
180       return !g_tls_backend_supports_tls (g_tls_backend_get_default ());
181     }
182     '''
183
184     rres = cc.run(check_gio_tls_src, name : 'GIO has real TLS support', dependencies : glib_deps)
185     assert(rres.compiled() and rres.returncode() == 0, 'libsoup requires glib-networking for TLS support')
186   endif
187 endif
188
189 libz_dep = dependency('zlib', required : false)
190 if not libz_dep.found()
191   if cc.get_id() != 'msvc'
192     libz_dep = cc.find_library('z', required : false)
193   else
194     libz_dep = cc.find_library('zlib1', required : false)
195     if not libz_dep.found()
196       libz_dep = cc.find_library('zlib', required : false)
197     endif
198   endif
199   if not libz_dep.found() or not cc.has_header('zlib.h')
200     libz_dep = subproject('zlib').get_variable('zlib_dep')
201   endif
202 endif
203
204 #################################
205 # Regression tests dependencies #
206 #################################
207
208 # The situation here is a little bit complicated. For running some of the tests
209 # we need the Apache's httpd binary. As we want to know more about its
210 # configuration we have to run it and parse the output. But here is the first
211 # problem, because on Debian we can't run the binary unless the
212 # /etc/apache2/envvars file is sourced, otherwise it ends with failure. The
213 # recommended way to communicate with the Apache is the apachectl that passes
214 # the arguments to httpd and also sources the envvars file. In the ideal world
215 # we could use the apachectl to run the tests as well, but on Fedora any non
216 # trivial call to it ends with the following error:
217 #     Passing arguments to httpd using apachectl is no longer supported.
218 #
219 # The summary is that for the configuration parsing we will use the apachectl,
220 # but for running the tests we will use the httpd binary.
221 apachectl = find_program('apachectl', '/sbin/apachectl', '/usr/sbin/apachectl', required : false)
222 # This abomination is a result of https://github.com/mesonbuild/meson/issues/1576
223 apache_httpd2 = find_program('httpd2', 'httpd', 'apache2', 'apache',
224              '/sbin/httpd2', '/sbin/httpd', '/sbin/apache2', '/sbin/apache',
225              '/usr/sbin/httpd2', '/usr/sbin/httpd', '/usr/sbin/apache2', '/usr/sbin/apache',
226              required : false)
227 have_apache=false
228 apache_httpd2_version = ''
229 if apache_httpd2.found() and apachectl.found()
230   apache_httpd2_version_raw = run_command(apachectl.path(), '-v')
231   # It seems that from version 2.4.39 apachectl doesn't take arguments, fallback
232   # to calling apache directly just in case.
233   if apache_httpd2_version_raw.returncode() != 0
234     apache_httpd2_version_raw = run_command(apache_httpd2.path(), '-v')
235   endif
236   if apache_httpd2_version_raw.returncode() == 0
237     apache_httpd2_version = apache_httpd2_version_raw.stdout().split('\n')[0]
238     apache_httpd2_version = apache_httpd2_version.split('/')[1].split(' ')[0]
239     if apache_httpd2_version.version_compare('>=2.4')
240       have_apache = true
241       cdata.set_quoted('APACHE_HTTPD', apache_httpd2.path())
242     else
243       message('Found ' + apache_httpd2_version + ', but at least 2.4 is needed - ignoring')
244     endif
245   endif
246 endif
247
248 if have_apache
249   apache_modules_dirs_out = run_command('get_apache_modules_dirs.py', apachectl.path())
250   have_apache = (apache_modules_dirs_out.returncode() == 0)
251   # Same as above, using apachectl might fail, try apache directly.
252   if not have_apache
253     apache_modules_dirs_out = run_command('get_apache_modules_dirs.py', apache_httpd2.path())
254     have_apache = (apache_modules_dirs_out.returncode() == 0)
255   endif
256   if have_apache
257     apache_modules_dirs = apache_modules_dirs_out.stdout().split(':')
258     message('Apache modules directory: ' + apache_modules_dirs[0])
259     cdata.set('APACHE_MODULE_DIR', apache_modules_dirs[0])
260     message('Apache SSL module directory: ' + apache_modules_dirs[1])
261     cdata.set('APACHE_SSL_MODULE_DIR', apache_modules_dirs[1])
262     message('Apache PHP module file: ' + apache_modules_dirs[2])
263     cdata.set('APACHE_PHP_MODULE_FILE', apache_modules_dirs[2])
264     message('Apache mod_unixd module directory: ' + (apache_modules_dirs[3] != '' ? apache_modules_dirs[3] : '(none)'))
265     cdata.set('IF_HAVE_MOD_UNIXD', apache_modules_dirs[3] != '' ? '' : '#')
266     cdata.set('HAVE_APACHE', have_apache)
267   else
268     message('Failed to locate necessary Apache modules for full test coverage')
269     message('stdout: ' + apache_modules_dirs_out.stdout())
270     message('stderr: ' + apache_modules_dirs_out.stderr())
271   endif
272 endif
273
274 have_php = false
275 have_php_xmlrpc = false
276 if have_apache
277   php = find_program('php', required : false)
278   message(cdata.get('APACHE_PHP_MODULE_FILE'))
279   if php.found() and cdata.get('APACHE_PHP_MODULE_FILE') != ''
280     have_php = true
281     php_xmlrpc = run_command(php, '-d', 'extension=xmlrpc', '-r', 'exit(function_exists("xmlrpc_server_create")?0:1);')
282     if php_xmlrpc.returncode() == 0
283       message('php-xmlrpc found')
284       have_php_xmlrpc = true
285       cdata.set('HAVE_PHP_XMLRPC', '1')
286     else
287       message('php-xmlrpc not found')
288     endif
289   endif
290   cdata.set('IF_HAVE_PHP', have_php ? '' : '#')
291   cdata.set('IF_HAVE_PHP_XMLRPC', have_php_xmlrpc ? '' : ';')
292 endif
293
294 tests_ready = have_apache and have_php and have_php_xmlrpc
295 if not tests_ready
296   warning('Some regression tests will not be compiled due to missing libraries or modules. Please check the logs for more details.')
297 endif
298
299 ##################
300 # GSSAPI support #
301 ##################
302 gssapi_opt = get_option('gssapi')
303 enable_gssapi = false
304 if cc.get_id() == 'msvc'
305   if host_machine.cpu_family() == 'x86'
306     gssapi_lib_type = '32'
307   else
308     gssapi_lib_type = '64'
309   endif
310   gssapi_lib = cc.find_library('gssapi' + gssapi_lib_type,
311     has_headers: 'gssapi/gssapi.h',
312     required: gssapi_opt)
313   if gssapi_lib.found()
314       enable_gssapi = true
315       add_project_link_arguments('gssapi@0@.lib'.format(gssapi_lib_type), language : 'c')
316   endif
317 else
318   krb5_config_path = get_option('krb5_config')
319   if not meson.is_cross_build() and krb5_config_path == ''
320     krb5_config_path = 'krb5-config'
321   endif
322   krb5_config = find_program(krb5_config_path, required : gssapi_opt)
323   if krb5_config.found()
324     libs_output = run_command (krb5_config, '--libs', 'gssapi', check: gssapi_opt.enabled())
325     cflags_output = run_command (krb5_config, '--cflags', 'gssapi', check: gssapi_opt.enabled())
326     if libs_output.returncode() == 0 and cflags_output.returncode() == 0
327       enable_gssapi = true
328       add_project_link_arguments(libs_output.stdout().split(), language : 'c')
329       add_project_arguments(cflags_output.stdout().split(), language : 'c')
330     endif
331   endif
332 endif
333
334 if enable_gssapi
335   add_project_arguments('-DLIBSOUP_HAVE_GSSAPI=1', language : 'c')
336 endif
337
338 ################
339 # NTLM support #
340 ################
341 # NTLM not supported on Windows
342 if host_machine.system() != 'windows'
343   ntlm_auth = find_program(get_option('ntlm_auth'), required: get_option('ntlm'))
344
345   if ntlm_auth.found()
346     add_project_arguments('-DUSE_NTLM_AUTH=1', language : 'c')
347     add_project_arguments('-DNTLM_AUTH="' + ntlm_auth.path() + '"', language : 'c')
348   endif
349 endif
350
351 #################
352 # GNOME support #
353 #################
354 enable_gnome = get_option('gnome')
355
356 #########################
357 # GObject introspection #
358 #########################
359 gir = find_program('g-ir-scanner', required: get_option('introspection'))
360 enable_introspection = gir.found()
361
362 ############
363 # Vala API #
364 ############
365 vapi_opt = get_option('vapi')
366 enable_vapi = add_languages('vala', required: vapi_opt)
367 if enable_vapi and not enable_introspection
368   enable_vapi = false
369   if vapi_opt.enabled()
370     error('vapi support was requested, but introspection support is mandatory.')
371   endif
372 endif
373
374 configinc = include_directories('.')
375
376 prefix = get_option('prefix')
377
378 cdata.set_quoted('PACKAGE_VERSION', soup_version)
379 cdata.set_quoted('LOCALEDIR', join_paths(prefix, get_option('localedir')))
380 cdata.set_quoted('GETTEXT_PACKAGE', libsoup_api_name)
381 configure_file(output : 'config.h', configuration : cdata)
382
383 subdir('libsoup')
384 # xgettext is optional (on Windows for instance)
385 if find_program('xgettext', required : false).found()
386   subdir('po')
387 endif
388 subdir('examples')
389
390 if get_option('tests')
391   subdir('tests')
392  endif
393
394 if get_option('gtk_doc')
395   srcdir = include_directories('libsoup')
396   subdir('docs/reference')
397 endif