xref: /aosp_15_r20/external/libxml2/meson.build (revision 7c5688314b92172186c154356a6374bf7684c3ca)
1project(
2    'libxml2',
3    'c',
4    version: files('VERSION'),
5    license: 'MIT',
6    default_options: ['buildtype=debug', 'warning_level=3'],
7    meson_version: '>= 0.61',
8)
9
10v_array = meson.project_version().split('.')
11v_maj = v_array[0].to_int()
12v_min = v_array[1].to_int()
13v_mic = v_array[2].to_int()
14v_nbr = v_maj * 10000 + v_min * 100 + v_mic
15v_extra = ''
16r = run_command('git', 'describe', check: false)
17if (r.returncode() == 0)
18    v_extra = '-GIT' + r.stdout().strip()
19endif
20
21# install paths
22dir_prefix = get_option('prefix')
23dir_bin = dir_prefix / get_option('bindir')
24dir_include = dir_prefix / get_option('includedir')
25dir_pkginclude = dir_include / meson.project_name()
26dir_lib = dir_prefix / get_option('libdir')
27dir_data = dir_prefix / get_option('datadir')
28dir_doc = dir_data / 'doc' / 'libxml2'
29dir_locale = dir_prefix / get_option('localedir')
30
31# host
32
33host_os = host_machine.system()
34
35cygwin = 'cygwin'
36windows = 'windows'
37sys_cygwin = cygwin.contains(host_os)
38sys_windows = windows.contains(host_os)
39
40libxml2_cflags = []
41xml_cflags = ''
42dep_args = []
43
44if sys_cygwin or sys_windows
45    if get_option('default_library') == 'static'
46        xml_cflags = '-DLIBXML_STATIC'
47        libxml2_cflags += '-DLIBXML_STATIC'
48        dep_args += '-DLIBXML_STATIC'
49    endif
50endif
51
52# binaries
53cc = meson.get_compiler('c')
54
55# options
56
57# disabled by default
58want_icu = get_option('icu').enabled()
59want_legacy = get_option('legacy').enabled()
60want_thread_alloc = get_option('thread-alloc').enabled()
61want_tls = get_option('tls').enabled()
62
63# default depends on minimum option
64
65want_minimum = get_option('minimum')
66
67feature = get_option('catalog')
68want_catalog = want_minimum ? feature.enabled() : feature.allowed()
69
70feature = get_option('debugging')
71want_debug = want_minimum ? feature.enabled() : feature.allowed()
72
73feature = get_option('html')
74want_html = want_minimum ? feature.enabled() : feature.allowed()
75
76feature = get_option('iconv')
77want_iconv = want_minimum ? feature.enabled() : feature.allowed()
78
79feature = get_option('iso8859x')
80want_iso8859x = want_minimum ? feature.enabled() : feature.allowed()
81
82feature = get_option('python')
83want_python = want_minimum ? feature.enabled() : feature.allowed()
84
85feature = get_option('modules')
86want_modules = want_minimum ? feature.enabled() : feature.allowed()
87
88feature = get_option('sax1')
89want_sax1 = want_minimum ? feature.enabled() : feature.allowed()
90
91feature = get_option('threads')
92want_threads = want_minimum ? feature.enabled() : feature.allowed()
93
94feature = get_option('valid')
95want_valid = want_minimum ? feature.enabled() : feature.allowed()
96
97# default depends on legacy option
98
99feature = get_option('http')
100want_http = want_legacy ? feature.allowed() : feature.enabled()
101
102feature = get_option('lzma')
103want_lzma = want_legacy ? feature.allowed() : feature.enabled()
104
105feature = get_option('zlib')
106want_zlib = want_legacy ? feature.allowed() : feature.enabled()
107
108# dependencies
109
110feature = get_option('output')
111want_output = not want_minimum \
112    or get_option('c14n').enabled() \
113    or get_option('writer').enabled() ? \
114    feature.allowed() : feature.enabled()
115
116feature = get_option('pattern')
117want_pattern = not want_minimum \
118    or get_option('schemas').enabled() \
119    or get_option('schematron').enabled() ? \
120    feature.allowed() : feature.enabled()
121
122feature = get_option('regexps')
123want_regexps = not want_minimum \
124    or get_option('schemas').enabled() ? \
125    feature.allowed() : feature.enabled()
126
127feature = get_option('push')
128want_push = not want_minimum \
129    or get_option('reader').enabled() \
130    or get_option('writer').enabled() ? \
131    feature.allowed() : feature.enabled()
132
133feature = get_option('readline')
134want_readline = get_option('history').enabled() ? \
135    feature.allowed() : feature.enabled()
136
137feature = get_option('xpath')
138want_xpath = not want_minimum \
139    or get_option('c14n').enabled() \
140    or get_option('schematron').enabled() \
141    or get_option('xinclude').enabled() \
142    or get_option('xptr').enabled() ? \
143    feature.allowed() : feature.enabled()
144
145feature = get_option('c14n') \
146    .require(want_output, error_message: 'c14n requires output') \
147    .require(want_xpath, error_message: 'c14n requires xpath')
148want_c14n = want_minimum ? feature.enabled() : feature.allowed()
149
150feature = get_option('history') \
151    .require(want_readline, error_message: 'history requires readline')
152want_history = feature.enabled()
153
154feature = get_option('reader') \
155    .require(want_push, error_message: 'reader requires push')
156want_reader = want_minimum ? feature.enabled() : feature.allowed()
157
158feature = get_option('schemas') \
159    .require(want_pattern, error_message: 'schemas requires pattern') \
160    .require(want_regexps, error_message: 'schemas requires regexps')
161want_schemas = want_minimum ? feature.enabled() : feature.allowed()
162
163feature = get_option('schematron') \
164    .require(want_pattern, error_message: 'schematron requires pattern') \
165    .require(want_xpath, error_message: 'schematron requires xpath')
166want_schematron = want_minimum ? feature.enabled() : feature.allowed()
167
168feature = get_option('writer') \
169    .require(want_output, error_message: 'writer requires output') \
170    .require(want_push, error_message: 'writer requires push')
171want_writer = want_minimum ? feature.enabled() : feature.allowed()
172
173feature = get_option('xinclude') \
174    .require(want_xpath, error_message: 'xinclude requires xpath')
175want_xinclude = want_minimum ? feature.enabled() : feature.allowed()
176
177feature = get_option('xptr') \
178    .require(want_xpath, error_message: 'xptr requires xpath')
179want_xptr = want_minimum ? feature.enabled() : feature.allowed()
180
181cflags_try = []
182
183### workaround for native compilers, see configure.ac
184if cc.get_argument_syntax() == 'gcc'
185    cflags_try += [
186        '-Wshadow',
187        '-Wpointer-arith',
188        '-Wcast-align',
189        '-Wwrite-strings',
190        '-Wstrict-prototypes',
191        '-Wmissing-prototypes',
192        '-Wno-long-long',
193        '-Wno-format-extra-args',
194        '-Wno-array-bounds',
195    ]
196
197    if host_machine.cpu_family() == 'alpha'
198        cflags_try += '-mieee'
199    endif
200else
201    if host_machine.cpu_family() == 'alpha'
202        cflags_try += '-ieee'
203    elif host_machine.cpu_family() == 'parisc'
204        cflags_try += '-Wp,-H30000'
205    endif
206endif
207
208foreach cf : cflags_try
209    if cc.has_argument(cf)
210        libxml2_cflags += cf
211    endif
212endforeach
213
214# configuration
215#
216# X : done
217# N : not done
218#
219# [X] config.h.in
220# [X] include/libxml/xmlversion.h.in
221# [X] libxml-2.0.pc.in
222# [X] libxml2-config.cmake.in
223# [X] python/setup.py.in
224# [N] xml2-config.in
225
226## config.h
227config_h = configuration_data()
228config_h.set_quoted('PACKAGE_NAME', meson.project_name())
229config_h.set_quoted('PACKAGE_VERSION', meson.project_version())
230config_h.set_quoted('PACKAGE_BIN_DIR', dir_bin)
231config_h.set_quoted('PACKAGE_LIB_DIR', dir_lib)
232config_h.set_quoted('PACKAGE_DATA_DIR', dir_data)
233config_h.set_quoted('LOCALEDIR', dir_locale)
234
235# header files
236xml_check_headers = [
237    [ 'stdint.h', true ],
238    [ 'poll.h', want_http ],
239]
240
241foreach header : xml_check_headers
242    if header[1] and cc.has_header(header[0])
243        config_h.set10('HAVE_' + header[0].underscorify().to_upper(), true)
244    endif
245endforeach
246
247# library functions
248xml_check_functions = [
249    # fct             | header
250    ['getentropy', 'sys/random.h'],
251    ['glob', 'glob.h'],
252    ['mmap', 'sys/mman.h'],
253]
254
255foreach function : xml_check_functions
256    config_h.set10('HAVE_DECL_' + function[0].underscorify().to_upper(),
257                   cc.has_header_symbol(function[1], function[0]))
258endforeach
259
260# library
261
262config_dir = [include_directories('.'), include_directories('include')]
263
264## dependencies
265
266xml_deps = []
267
268### math library
269if sys_windows == false
270    m_dep = cc.find_library('m', required: false)
271    if m_dep.found()
272        xml_deps += m_dep
273    endif
274endif
275
276### thread local storage
277if want_tls
278    foreach t : ['_Thread_local', '__thread', '__declspec(thread)']
279        if cc.compiles('@0@ int v;'.format(t))
280            config_h.set('XML_THREAD_LOCAL', t)
281            break
282        endif
283    endforeach
284endif
285
286### __attribute__((destructor))
287if cc.has_function_attribute('destructor')
288    config_h.set10('HAVE_FUNC_ATTRIBUTE_DESTRUCTOR', true)
289endif
290
291### DSO support
292if sys_cygwin == true
293    module_extension = '.dll'
294elif sys_windows == true
295    module_extension = '.dll'
296else
297    module_extension = '.so'
298endif
299
300if want_modules and host_machine.system() != 'windows'
301    if meson.version().version_compare('>=0.62')
302        dl_dep = dependency('dl', required: false)
303    else
304        dl_dep = cc.find_library('dl', required: false)
305    endif
306    if dl_dep.found()
307        config_h.set10('HAVE_DLOPEN', true)
308        xml_deps += dl_dep
309    endif
310endif
311
312### threads
313if want_threads
314    threads_dep = dependency('threads')
315    xml_deps += threads_dep
316else
317    threads_dep = dependency('', required: false)
318endif
319
320### xmllint shell history
321xmllint_deps = []
322
323if want_readline
324    readline_dep = dependency('readline')
325    config_h.set('HAVE_LIBREADLINE', true)
326    xmllint_deps += readline_dep
327endif
328
329if want_history
330    history_dep = dependency('history')
331    config_h.set('HAVE_LIBHISTORY', true)
332    xmllint_deps += history_dep
333endif
334
335### crypto
336if sys_windows == true
337    bcrypt_dep = cc.find_library('bcrypt', required: true)
338    xml_deps += bcrypt_dep
339endif
340
341### inet
342if want_http == true
343    if sys_windows == true
344        net_dep = cc.find_library('ws2_32', required: true)
345        xml_deps += net_dep
346    else
347        net_dep = dependency('', required: false)
348        has_in_libc = cc.has_function('gethostbyname')
349        if has_in_libc == false
350            net_dep = cc.find_library('nsl', required: true)
351            if net_dep.found()
352                has_in_nsl = cc.has_function(
353                    'gethostbyname',
354                    dependencies: net_dep,
355                    required: false,
356                )
357                if has_in_nsl == true
358                    xml_deps += net_dep
359                endif
360            endif
361        endif
362    endif
363endif
364
365### zlib
366if want_zlib
367    xml_deps += dependency('zlib')
368endif
369
370### lzma
371if want_lzma
372    xml_deps += dependency('liblzma')
373endif
374
375# icu
376if want_icu
377    icu_dep = dependency('icu-i18n', method: 'pkg-config')
378    defs = icu_dep.get_variable(pkgconfig: 'DEFS')
379    if cc.has_argument(defs)
380        libxml2_cflags += defs
381    endif
382    xml_deps += icu_dep
383endif
384
385### iconv
386if want_iconv
387    xml_deps += dependency('iconv')
388endif
389
390subdir('include/libxml')
391
392# Set config_h after all subdirs and dependencies have set values
393
394configure_file(output: 'config.h', configuration: config_h)
395
396## libxml2 library
397
398xml_src = [
399    'buf.c',
400    'chvalid.c',
401    'dict.c',
402    'entities.c',
403    'encoding.c',
404    'error.c',
405    'globals.c',
406    'hash.c',
407    'list.c',
408    'parser.c',
409    'parserInternals.c',
410    'SAX2.c',
411    'threads.c',
412    'tree.c',
413    'uri.c',
414    'valid.c',
415    'xmlIO.c',
416    'xmlmemory.c',
417    'xmlstring.c',
418]
419
420xml_opt_src = [
421    [want_c14n, ['c14n.c']],
422    [want_catalog, ['catalog.c']],
423    [want_debug, ['debugXML.c']],
424    [want_html, ['HTMLparser.c', 'HTMLtree.c']],
425    [want_http, ['nanohttp.c']],
426    [want_legacy, ['legacy.c']],
427    [want_lzma, ['xzlib.c']],
428    [want_modules, ['xmlmodule.c']],
429    [want_output, ['xmlsave.c']],
430    [want_pattern, ['pattern.c']],
431    [want_reader, ['xmlreader.c']],
432    [want_regexps, ['xmlregexp.c', 'xmlunicode.c']],
433    [want_schemas, ['relaxng.c', 'xmlschemas.c', 'xmlschemastypes.c']],
434    [want_schemas and not want_xpath, ['xpath.c']],
435    [want_schematron, ['schematron.c']],
436    [want_writer, ['xmlwriter.c']],
437    [want_xinclude, ['xinclude.c']],
438    [want_xpath, ['xpath.c']],
439    [want_xptr, ['xlink.c', 'xpointer.c']],
440]
441
442foreach file : xml_opt_src
443    want = file[0]
444    src = file[1]
445    if want == true
446        if src.length() > 1
447            foreach s : src
448                xml_src += s
449            endforeach
450        else
451            xml_src += src
452        endif
453    endif
454endforeach
455
456v_min_compat = 0
457xml_lib = library(
458    'xml2',
459    files(xml_src),
460    c_args: libxml2_cflags,
461    dependencies: xml_deps,
462    include_directories: config_dir,
463    install: true,
464    version: meson.project_version(),
465    soversion: v_maj + v_min_compat,
466)
467
468dep_inc = include_directories('include')
469xml_dep = declare_dependency(include_directories: dep_inc, link_with: xml_lib, compile_args: dep_args)
470
471meson.override_dependency('libxml-2.0', xml_dep)
472
473## xmllint tool
474
475executable(
476    'xmllint',
477    files('xmllint.c', 'shell.c'),
478    dependencies: [xml_dep, xmllint_deps],
479    include_directories: config_dir,
480    install: true,
481)
482
483## xmlcatalog tool
484
485executable(
486    'xmlcatalog',
487    files('xmlcatalog.c'),
488    dependencies: [xml_dep, xmllint_deps],
489    include_directories: config_dir,
490    install: true,
491)
492
493## testdso module
494
495testdso_mod = shared_module(
496    'testdso',
497    files('testdso.c'),
498    build_rpath: get_option('libdir'),
499    include_directories: config_dir,
500    name_prefix: '',
501)
502
503## tests
504
505checks = {
506    'runsuite': [],
507    'runtest': threads_dep,
508    'runxmlconf': [],
509# Disabled for now, see #694
510#    'testModule': [],
511    'testapi': [],
512    'testchar': [],
513    'testdict': [],
514    'testlimits': [],
515    'testparser': [],
516    'testrecurse': [],
517}
518
519foreach check, deps : checks
520    exe = executable(
521        check,
522        files(check + '.c'),
523        dependencies: [deps, xml_dep],
524        include_directories: config_dir,
525    )
526    if check != 'testlimits'
527        test(check, exe, timeout: 0, workdir: meson.current_source_dir())
528    endif
529endforeach
530
531subdir('example')
532subdir('doc')
533
534if want_python == true
535    subdir('python')
536endif
537
538## pc files
539
540pkgmod = import('pkgconfig')
541
542pkgmod.generate(
543    xml_lib,
544    description: 'libXML library version2.',
545    filebase: 'libxml-2.0',
546    name: 'libXML',
547    subdirs:  [meson.project_name()],
548    variables: 'modules=' + want_modules.to_string('1', '0'),
549)
550
551## libxml2-config.cmake file
552
553config_cmake = configuration_data()
554config_cmake.set('LIBXML_MAJOR_VERSION', v_maj)
555config_cmake.set('LIBXML_MINOR_VERSION', v_min)
556config_cmake.set('LIBXML_MICRO_VERSION', v_mic)
557config_cmake.set('VERSION', meson.project_version())
558config_cmake.set('WITH_ICONV', want_iconv.to_int().to_string())
559config_cmake.set('WITH_ICU', want_icu.to_int().to_string())
560config_cmake.set('WITH_LZMA', want_lzma.to_int().to_string())
561config_cmake.set('WITH_MODULES', want_modules.to_int().to_string())
562config_cmake.set('WITH_THREADS', want_threads.to_int().to_string())
563config_cmake.set('WITH_ZLIB', want_zlib.to_int().to_string())
564config_cmake.set('XML_CFLAGS', xml_cflags)
565configure_file(
566    input: 'libxml2-config.cmake.in',
567    output: 'libxml2-config.cmake',
568    configuration: config_cmake,
569    install_dir: dir_lib / 'cmake' / 'libxml2',
570)
571
572# summary
573
574summary(
575    {
576        'OS': host_os,
577        'c14n': want_c14n,
578        'catalog': want_catalog,
579        'debug': want_debug,
580        'history': want_history,
581        'html': want_html,
582        'http': want_http,
583        'iconv': want_iconv,
584        'icu': want_icu,
585        'iso8859x': want_iso8859x,
586        'legacy': want_legacy,
587        'lzma': want_lzma,
588        'modules': want_modules,
589        'output': want_output,
590        'pattern': want_pattern,
591        'push': want_push,
592        'python': want_python,
593        'reader': want_reader,
594        'readline': want_readline,
595        'regexps': want_regexps,
596        'sax1': want_sax1,
597        'schemas': want_schemas,
598        'schematron': want_schematron,
599        'threads': want_threads,
600        'thread-alloc': want_thread_alloc,
601        'tls': want_tls,
602        'valid': want_valid,
603        'writer': want_writer,
604        'xinclude': want_xinclude,
605        'xpath': want_xpath,
606        'xptr': want_xptr,
607        'zlib': want_zlib,
608    },
609    section: 'Configuration Options Summary:',
610)
611