1project( 2 'libvirt-glib', 'c', 3 version: '4.0.0', 4 license: 'LGPLv2+', 5 meson_version: '>= 0.50.0', 6 default_options: [ 7 'buildtype=debugoptimized', 8 'c_std=gnu99', 9 ], 10) 11 12python3 = find_program('python3', required: true) 13# Python3 < 3.7 treats the C locale as 7-bit only. We must force env vars so 14# it treats it as UTF-8 regardless of the user's locale. 15runutf8 = [ 'LC_ALL=', 'LANG=C', 'LC_CTYPE=en_US.UTF-8' ] 16 17cc = meson.get_compiler('c') 18git = run_command('test', '-d', '.git').returncode() == 0 19 20version_info = meson.project_version().split('.') 21version_major = version_info[0].to_int() 22version_minor = version_info[1].to_int() 23version_micro = version_info[2].to_int() 24 25libvirt_glib_interface_age = 0 26libvirt_glib_binary_age = 1000 * version_major + version_minor 27 28# Maintain version scheme with libtool 29libvirt_glib_soversion = 0 30libvirt_glib_version = '@0@.@1@.@2@'.format( 31 libvirt_glib_soversion, 32 (libvirt_glib_binary_age - libvirt_glib_interface_age), 33 libvirt_glib_interface_age) 34osx_current = libvirt_glib_binary_age - libvirt_glib_interface_age + 1 35libvirt_glib_darwin_versions = [ 36 osx_current, 37 '@0@.@1@.0'.format(osx_current, libvirt_glib_interface_age) 38] 39 40# Keep these two definitions in agreement. 41glib_version = '2.48.0' 42glib_min_version_symbol='GLIB_VERSION_2_48' 43glib_dep = dependency('glib-2.0', version: '>=' + glib_version) 44gobject_dep = dependency('gobject-2.0', version: '>=' + glib_version) 45gio_dep = dependency('gio-2.0', version: '>=' + glib_version) 46 47libvirt_version = '1.2.8' 48libvirt_dep = dependency('libvirt', version: '>=' + libvirt_version) 49 50libxml_min_version='>=2.9.1' 51libxml_dep = dependency('libxml-2.0', version: libxml_min_version) 52 53add_global_arguments('-DGLIB_VERSION_MIN_REQUIRED=@0@'.format(glib_min_version_symbol), language: 'c') 54add_global_arguments('-DGLIB_VERSION_MAX_ALLOWED=@0@'.format(glib_min_version_symbol), language: 'c') 55 56prefix = get_option('prefix') 57localedir = join_paths(prefix, get_option('localedir')) 58datadir = join_paths(prefix, get_option('datadir')) 59libdir = join_paths(prefix, get_option('libdir')) 60includedir = join_paths(prefix, get_option('includedir')) 61 62# gobject introspection 63gir = find_program('g-ir-scanner', required: get_option('introspection')) 64enable_introspection = gir.found() and not meson.is_cross_build() 65 66# vala 67vapi_opt = get_option('vapi') 68enable_vapi = add_languages('vala', required: vapi_opt) 69if enable_vapi and not enable_introspection 70 enable_vapi = false 71 if vapi_opt.enabled() 72 error('vala support was requested, but introspection support is mandatory.') 73 endif 74endif 75 76# gtk-doc 77if not get_option('docs').disabled() 78 gtk_doc = find_program('gtkdoc-scan', required: get_option('docs')) 79 enable_doc = gtk_doc.found() and not meson.is_cross_build() 80else 81 enable_doc = false 82endif 83 84# Add RPATH information when building for a non-standard prefix, or 85# when explicitly requested to do so 86 87if prefix == '/usr' and not get_option('rpath').enabled() 88 rpathdir = '' 89else 90 rpathdir = libdir 91endif 92 93common_link_args = [] 94if meson.get_compiler('c').has_link_argument('-Wl,--no-undefined') 95 common_link_args += ['-Wl,--no-undefined'] 96endif 97 98 99build_tests = not get_option('tests').disabled() 100 101girdir = join_paths(datadir, 'gir-1.0') 102typelibdir = join_paths(libdir, 'girepository-1.0') 103pkgconfdir = join_paths(libdir, 'pkgconfig') 104 105conf_data = configuration_data() 106conf_data.set('VERSION', meson.project_version()) 107conf_data.set('prefix', prefix) 108conf_data.set('includedir', includedir) 109conf_data.set('exec_prefix', prefix) 110conf_data.set('libdir', libdir) 111 112configure_file( 113 input: 'meson-config.h.in', 114 output: 'config.h', 115 configuration: conf_data 116) 117 118if git 119 configure_file( 120 input: 'libvirt-glib.spec.in', 121 output: 'libvirt-glib.spec', 122 configuration: conf_data 123 ) 124 125 configure_file( 126 input: 'mingw-libvirt-glib.spec.in', 127 output: 'mingw-libvirt-glib.spec', 128 configuration: conf_data 129 ) 130endif 131 132configure_file( 133 input: 'libvirt-glib-1.0.pc.in', 134 output: 'libvirt-glib-1.0.pc', 135 configuration: conf_data, 136 install: true, 137 install_dir: pkgconfdir 138) 139 140configure_file( 141 input: 'libvirt-gconfig-1.0.pc.in', 142 output: 'libvirt-gconfig-1.0.pc', 143 configuration: conf_data, 144 install: true, 145 install_dir: pkgconfdir 146) 147 148configure_file( 149 input: 'libvirt-gobject-1.0.pc.in', 150 output: 'libvirt-gobject-1.0.pc', 151 configuration: conf_data, 152 install: true, 153 install_dir: pkgconfdir 154) 155 156cc_flags = [] 157 158git_werror = get_option('git_werror') 159if git_werror.enabled() or git_werror.auto() and git 160 cc_flags += [ '-Werror' ] 161endif 162 163cc_flags += [ 164 '-fno-common', 165 '-W', 166 '-Wabsolute-value', 167 '-Waddress', 168 '-Waddress-of-packed-member', 169 '-Waggressive-loop-optimizations', 170 '-Wall', 171 '-Wattribute-warning', 172 '-Wattributes', 173 '-Wbool-compare', 174 '-Wbool-operation', 175 '-Wbuiltin-declaration-mismatch', 176 '-Wbuiltin-macro-redefined', 177 '-Wcannot-profile', 178 '-Wcast-align', 179 '-Wcast-align=strict', 180 '-Wcast-function-type', 181 '-Wchar-subscripts', 182 '-Wclobbered', 183 '-Wcomment', 184 '-Wcomments', 185 '-Wcoverage-mismatch', 186 '-Wcpp', 187 '-Wdangling-else', 188 '-Wdate-time', 189 '-Wdeprecated-declarations', 190 '-Wdesignated-init', 191 '-Wdiscarded-array-qualifiers', 192 '-Wdiscarded-qualifiers', 193 '-Wdiv-by-zero', 194 '-Wduplicated-cond', 195 '-Wduplicate-decl-specifier', 196 '-Wempty-body', 197 '-Wendif-labels', 198 '-Wexpansion-to-defined', 199 '-Wextra', 200 '-Wformat-contains-nul', 201 '-Wformat-extra-args', 202 '-Wformat-nonliteral', 203 '-Wformat-security', 204 '-Wformat-y2k', 205 '-Wformat-zero-length', 206 '-Wframe-address', 207 '-Wfree-nonheap-object', 208 '-Whsa', 209 '-Wif-not-aligned', 210 '-Wignored-attributes', 211 '-Wignored-qualifiers', 212 '-Wimplicit', 213 '-Wimplicit-function-declaration', 214 '-Wimplicit-int', 215 '-Wincompatible-pointer-types', 216 '-Winit-self', 217 '-Winline', 218 '-Wint-conversion', 219 '-Wint-in-bool-context', 220 '-Wint-to-pointer-cast', 221 '-Winvalid-memory-model', 222 '-Winvalid-pch', 223 '-Wlogical-not-parentheses', 224 '-Wlogical-op', 225 '-Wmain', 226 '-Wmaybe-uninitialized', 227 '-Wmemset-elt-size', 228 '-Wmemset-transposed-args', 229 '-Wmisleading-indentation', 230 '-Wmissing-attributes', 231 '-Wmissing-braces', 232 '-Wmissing-declarations', 233 '-Wmissing-field-initializers', 234 '-Wmissing-include-dirs', 235 '-Wmissing-parameter-type', 236 '-Wmissing-profile', 237 '-Wmissing-prototypes', 238 '-Wmultichar', 239 '-Wmultistatement-macros', 240 '-Wnarrowing', 241 '-Wnested-externs', 242 '-Wnonnull', 243 '-Wnonnull-compare', 244 '-Wnull-dereference', 245 '-Wodr', 246 '-Wold-style-declaration', 247 '-Wold-style-definition', 248 '-Wopenmp-simd', 249 '-Woverflow', 250 '-Woverride-init', 251 '-Wpacked-bitfield-compat', 252 '-Wpacked-not-aligned', 253 '-Wparentheses', 254 '-Wpointer-arith', 255 '-Wpointer-compare', 256 '-Wpointer-sign', 257 '-Wpointer-to-int-cast', 258 '-Wpragmas', 259 '-Wpsabi', 260 '-Wrestrict', 261 '-Wreturn-local-addr', 262 '-Wreturn-type', 263 '-Wscalar-storage-order', 264 '-Wsequence-point', 265 '-Wshadow', 266 '-Wshift-count-negative', 267 '-Wshift-count-overflow', 268 '-Wshift-negative-value', 269 '-Wsizeof-array-argument', 270 '-Wsizeof-pointer-div', 271 '-Wsizeof-pointer-memaccess', 272 '-Wstrict-aliasing', 273 '-Wstrict-prototypes', 274 '-Wstringop-truncation', 275 '-Wsuggest-attribute=cold', 276 '-Wsuggest-attribute=const', 277 '-Wsuggest-attribute=format', 278 '-Wsuggest-attribute=noreturn', 279 '-Wsuggest-attribute=pure', 280 '-Wsuggest-final-methods', 281 '-Wsuggest-final-types', 282 '-Wswitch', 283 '-Wswitch-bool', 284 '-Wswitch-unreachable', 285 '-Wsync-nand', 286 '-Wtautological-compare', 287 '-Wtrampolines', 288 '-Wtrigraphs', 289 '-Wtype-limits', 290 '-Wuninitialized', 291 '-Wunknown-pragmas', 292 '-Wunused', 293 '-Wunused-but-set-parameter', 294 '-Wunused-but-set-variable', 295 '-Wunused-function', 296 '-Wunused-label', 297 '-Wunused-local-typedefs', 298 '-Wunused-result', 299 '-Wunused-value', 300 '-Wunused-variable', 301 '-Wvarargs', 302 '-Wvariadic-macros', 303 '-Wvector-operation-performance', 304 '-Wvla', 305 '-Wvolatile-register-var', 306 '-Wwrite-strings', 307] 308 309# gcc --help=warnings outputs 310ptrdiff_max = cc.sizeof('ptrdiff_t', prefix: '#include <stddef.h>') 311size_max = cc.sizeof('size_t', prefix: '#include <stdint.h>') 312# Compute max safe object size by checking ptrdiff_t and size_t sizes. 313# Ideally we would get PTRDIFF_MAX and SIZE_MAX values but it would 314# give us (2147483647L) and we would have to remove the () and the suffix 315# in order to convert it to numbers to be able to pick the smaller one. 316alloc_max = run_command( 317 python3.path(), '-c', 318 'print(min(2**(@0@ * 8 - 1) - 1, 2**(@1@ * 8) - 1))'.format(ptrdiff_max, size_max), 319) 320cc_flags += [ 321 '-Walloc-size-larger-than=@0@'.format(alloc_max.stdout().strip()), 322 '-Warray-bounds=2', 323 '-Wattribute-alias=2', 324 '-Wformat-overflow=2', 325 '-Wformat-truncation=2', 326 '-Wimplicit-fallthrough=5', 327 '-Wnormalized=nfc', 328 '-Wshift-overflow=2', 329 '-Wstringop-overflow=2', 330 '-Wunused-const-variable=2', 331 '-Wvla-larger-then=4031', 332] 333 334cc_flags += [ 335 # So we have -W enabled, and then have to explicitly turn off... 336 '-Wno-sign-compare', 337 338 # We do "bad" function casts all the time for event callbacks 339 '-Wno-cast-function-type', 340 341 # Clang incorrectly complains about dup typedefs win gnu99 mode 342 # so use this Clang-specific arg to keep it quiet 343 '-Wno-typedef-redefinition', 344 345 # We don't use -Wc++-compat so we have to enable it explicitly 346 '-Wjump-misses-init', 347 348 # -Wswitch is enabled but that doesn't report missing enums if a default: 349 # is present 350 '-Wswitch-enum', 351 352 # -Wformat=2 implies -Wformat-nonliteral so we need to manually exclude it 353 '-Wno-format-nonliteral', 354 355 # -Wformat enables this by default, and we should keep it, 356 # but need to rewrite various areas of code first 357 '-Wno-format-truncation', 358 359 # This should be < 256 really. Currently we're down to 4096, 360 # but using 1024 bytes sized buffers (mostly for virStrerror) 361 # stops us from going down further 362 '-Wframe-larger-than=4096', 363 364 # extra special flags 365 '-fexceptions', 366 '-fasynchronous-unwind-tables', 367 368 # Need -fipa-pure-const in order to make -Wsuggest-attribute=pure 369 # fire even without -O. 370 '-fipa-pure-const', 371 372 # We should eventually enable this, but right now there are at 373 # least 75 functions triggering warnings. 374 '-Wno-suggest-attribute=pure', 375 '-Wno-suggest-attribute=const', 376 377 # gtk-doc-scangobj causes failures. We should do a 378 # more targetted workaround for this really. 379 '-Wno-unused-parameter', 380] 381 382# on aarch64 error: -fstack-protector not supported for this target 383if host_machine.cpu_family() != 'aarch64' 384 if host_machine.system() in [ 'linux', 'freebsd', 'windows' ] 385 # we prefer -fstack-protector-strong but fallback to -fstack-protector-all 386 fstack_cflags = cc.first_supported_argument([ 387 '-fstack-protector-strong', 388 '-fstack-protector-all', 389 ]) 390 cc_flags += fstack_cflags 391 392 # When building with mingw using -fstack-protector requires libssp library 393 # which is included by using -fstack-protector with linker. 394 if fstack_cflags.length() == 1 and host_machine.system() == 'windows' 395 add_project_link_arguments(fstack_cflags, language: 'c') 396 endif 397 endif 398endif 399 400# Clang complains about unused static inline functions which are common 401# with G_DEFINE_AUTOPTR_CLEANUP_FUNC. 402w_unused_function_args = ['-Wunused-function', '-Werror'] 403w_unused_function_code = ''' 404 static inline void foo(void) {} 405 406 int main(void) { return 0; } 407''' 408# -Wunused-function is implied by -Wall, we must turn it off explicitly. 409if not cc.compiles(w_unused_function_code, args: w_unused_function_args) 410 cc_flags += ['-Wno-unused-function'] 411endif 412 413cc_flags_disabled = [ 414 # In meson this is specified using 'c_std=gnu99' in project() function. 415 '-std=gnu99', 416 417 # don't care about C++ compiler compat 418 '-Wc++-compat', 419 '-Wabi', 420 '-Wdeprecated', 421 422 # Don't care about ancient C standard compat 423 '-Wtraditional', 424 '-Wtraditional-conversion', 425 426 # Ignore warnings in /usr/include 427 '-Wsystem-headers', 428 429 # Happy for compiler to add struct padding 430 '-Wpadded', 431 432 # GCC very confused with -O2 433 '-Wunreachable-code', 434 435 # Too many to deal with 436 '-Wconversion', 437 '-Wsign-conversion', 438 439 # Need to allow bad cast for execve() 440 '-Wcast-qual', 441 442 # We need to use long long in many places 443 '-Wlong-long', 444 445 # We allow manual list of all enum cases without default 446 '-Wswitch-default', 447 448 # Not a problem since we don't use -fstrict-overflow 449 '-Wstrict-overflow', 450 451 # Not a problem since we don't use -funsafe-loop-optimizations 452 '-Wunsafe-loop-optimizations', 453 454 # gcc 4.4.6 complains this is C++ only; gcc 4.7.0 implies this from -Wall 455 '-Wenum-compare', 456 457 # gcc 5.1 -Wformat-signedness mishandles enums, not ready for prime time 458 '-Wformat-signedness', 459 460 # Several conditionals expand the same on both branches depending on the 461 # particular platform/architecture 462 '-Wduplicated-branches', 463 464 # > This warning does not generally indicate that there is anything wrong 465 # > with your code; it merely indicates that GCC's optimizers are unable 466 # > to handle the code effectively. 467 # Source: https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html 468 '-Wdisabled-optimization', 469 470 # Various valid glib APIs/macros trigger this warning 471 '-Wbad-function-cast', 472 473 # We might fundamentally need some of these disabled forever, but 474 # ideally we'd turn many of them on 475 '-Wfloat-equal', 476 '-Wpacked', 477 '-Wunused-macros', 478 '-Woverlength-strings', 479 '-Wstack-protector', 480 '-Wsuggest-attribute=malloc', 481 482 # g_return_val_if_fail usage violates this often 483 '-Wdeclaration-after-statement', 484 485 # older gtk-doc fails - re-enable this in future 486 '-Wdouble-promotion', 487] 488 489foreach flag : cc_flags_disabled 490 if cc_flags.contains(flag) 491 error('@0@ is disabled but listed in cc_flags'.format(flag)) 492 endif 493endforeach 494 495supported_cc_flags = cc.get_supported_arguments(cc_flags) 496add_project_arguments(supported_cc_flags, language: 'c') 497 498if git 499 authors_helper = join_paths(meson.source_root(), 'build-aux', 'gen-authors.py') 500 authors = run_command(python3.path(), authors_helper, env: runutf8) 501 authors_file = 'AUTHORS.in' 502 503 authors_conf = configuration_data() 504 authors_conf.set('authorslist', authors.stdout()) 505 506 configure_file( 507 input: authors_file, 508 output: '@BASENAME@', 509 configuration: authors_conf, 510 ) 511 512 dist_helper = join_paths(meson.source_root(), 'build-aux', 'dist.py') 513 meson.add_dist_script(python3.path(), dist_helper, meson.build_root(), 'AUTHORS') 514 meson.add_dist_script(python3.path(), dist_helper, meson.build_root(), 'libvirt-glib.spec') 515endif 516 517common_cflags = [ 518 '-DLOCALEDIR="@0@"'.format(localedir), 519 '-DDATADIR="@0@"'.format(datadir), 520 '-DLIBVIRT_GLIB_BUILD', 521] 522 523gnome = import('gnome') 524i18n = import('i18n') 525 526top_include_dir = [include_directories('.')] 527 528check_symfile = join_paths(meson.source_root(), 'build-aux', 'check-symfile.py') 529check_symsorting = join_paths(meson.source_root(), 'build-aux', 'check-symsorting.py') 530 531 532subdir('libvirt-glib') 533subdir('libvirt-gconfig') 534subdir('libvirt-gobject') 535subdir('po') 536subdir('examples') 537subdir('docs') 538if build_tests 539 subdir('tests') 540endif 541subdir('build-aux') 542