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