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