1project('pango', 'c', 'cpp', 2 version: '1.48.11', 3 license: 'LGPLv2.1+', 4 default_options: [ 5 'buildtype=debugoptimized', 6 'warning_level=1', 7 # We only need c99, but glib needs GNU-specific features 8 # https://github.com/mesonbuild/meson/issues/2289 9 'c_std=gnu99', 10 ], 11 meson_version : '>= 0.55.3') 12 13add_project_arguments([ '-D_POSIX_C_SOURCE=200809L', '-D_POSIX_THREAD_SAFE_FUNCTIONS', '-D_GNU_SOURCE', ], language: 'c') 14 15pango_prefix = get_option('prefix') 16pango_libdir = join_paths(pango_prefix, get_option('libdir')) 17pango_sysconfdir = join_paths(pango_prefix, get_option('sysconfdir')) 18pango_includedir = join_paths(pango_prefix, get_option('includedir')) 19pango_datadir = join_paths(pango_prefix, get_option('datadir')) 20pango_libexecdir = join_paths(pango_prefix, get_option('libexecdir')) 21 22version = meson.project_version().split('.') 23pango_major_version = version[0].to_int() 24pango_minor_version = version[1].to_int() 25pango_micro_version = version[2].to_int() 26 27pango_interface_age = pango_minor_version.is_odd() ? 0 : pango_micro_version 28pango_binary_age = pango_minor_version * 100 + pango_micro_version 29 30pango_api_version = '@0@.0'.format(pango_major_version) 31pango_api_name = 'pango-@0@'.format(pango_api_version) 32pango_api_path = join_paths(pango_api_name, 'pango') 33 34pango_conf = configuration_data() 35 36pango_conf.set('PANGO_BINARY_AGE', pango_binary_age) 37pango_conf.set('PANGO_INTERFACE_AGE', pango_interface_age) 38pango_conf.set('PANGO_VERSION_MAJOR', pango_major_version) 39pango_conf.set('PANGO_VERSION_MINOR', pango_minor_version) 40pango_conf.set('PANGO_VERSION_MICRO', pango_micro_version) 41 42# Maintain version scheme with libtool 43pango_soversion = 0 44pango_libversion = '@0@.@1@.@2@'.format(pango_soversion, (pango_binary_age - pango_interface_age), pango_interface_age) 45osx_current = pango_binary_age - pango_interface_age + 1 46pango_osxversion = [osx_current, '@0@.@1@.0'.format(osx_current, pango_interface_age)] 47 48cc = meson.get_compiler('c') 49host_system = host_machine.system() 50 51# Compiler and linker flags 52common_cflags = [] 53common_cppflags = [] 54common_ldflags = [] 55 56# Add more compiler warnings to the default set 57if cc.get_id() == 'msvc' 58 # Compiler options taken from msvc_recommended_pragmas.h 59 # in GLib, based on _Win32_Programming_ by Rector and Newcomer 60 test_cflags = ['-FImsvc_recommended_pragmas.h', '-utf-8'] 61 add_project_arguments(cc.get_supported_arguments(test_cflags), language: 'c') 62 test_c_only_flags = [] 63elif cc.get_id() == 'gcc' or cc.get_id() == 'clang' 64 test_c_only_flags = [ 65 '-Wimplicit-function-declaration', 66 '-Wstrict-prototypes', 67 '-Wmissing-prototypes', 68 '-Wnested-externs', 69 '-Wold-style-definition', 70 '-Wno-int-conversion', 71 '-Wno-discarded-qualifiers', 72 '-Werror=implicit', 73 '-Werror=pointer-to-int-cast', 74 ] 75 76 test_cflags = test_c_only_flags + [ 77 '-fno-strict-aliasing', 78 '-Wpointer-arith', 79 '-Wmissing-declarations', 80 '-Wformat=2', 81 '-Wformat-nonliteral', 82 '-Wformat-security', 83 '-Wunused', 84 '-Wcast-align', 85 '-Wmissing-noreturn', 86 '-Wmissing-format-attribute', 87 '-Wmissing-include-dirs', 88 '-Wlogical-op', 89 '-Wno-uninitialized', 90 '-Wno-shadow', 91 '-Werror=implicit-fallthrough', 92 '-Werror=nonnull', 93 '-Werror=init-self', 94 '-Werror=main', 95 '-Werror=missing-braces', 96 '-Werror=sequence-point', 97 '-Werror=return-type', 98 '-Werror=trigraphs', 99 '-Werror=array-bounds', 100 '-Werror=write-strings', 101 '-Werror=address', 102 '-Werror=int-to-pointer-cast', 103 '-Werror=empty-body', 104 '-Werror=write-strings', 105 '-Werror=unused-but-set-variable', 106 '-Wundef', # FIXME: https://bugzilla.gnome.org/show_bug.cgi?id=792481 107 ] 108 109 if host_system == 'windows' 110 test_cflags += [ '-mms-bitfields' ] 111 else 112 test_cflags += [ '-Werror=redundant-decls' ] 113 endif 114else 115 test_cflags = [] 116 test_c_only_flags = [] 117endif 118 119# Symbol visibility 120if get_option('default_library') != 'static' 121 if host_system == 'windows' 122 pango_conf.set('DLL_EXPORT', true) 123 pango_conf.set('_PANGO_EXTERN', '__declspec(dllexport) extern') 124 if cc.get_id() != 'msvc' 125 test_cflags += ['-fvisibility=hidden'] 126 endif 127 else 128 pango_conf.set('_PANGO_EXTERN', '__attribute__((visibility("default"))) extern') 129 test_cflags += ['-fvisibility=hidden'] 130 endif 131endif 132 133# Check all compiler flags 134common_cflags += cc.get_supported_arguments(test_cflags) 135 136# Isolate the C++ compiler flags 137foreach cflag: common_cflags 138 if not test_c_only_flags.contains(cflag) 139 common_cppflags += [ cflag ] 140 endif 141endforeach 142 143# Linker flags 144if host_machine.system() == 'linux' 145 common_ldflags += cc.get_supported_link_arguments([ '-Wl,-Bsymbolic', '-Wl,-z,relro', '-Wl,-z,now', ]) 146endif 147 148# Functions 149checked_funcs = [ 150 'sysconf', 151 'getpagesize', 152 'flockfile', 153 'strtok_r', 154] 155 156foreach f: checked_funcs 157 if cc.has_function(f) 158 pango_conf.set('HAVE_' + f.underscorify().to_upper(), 1) 159 endif 160endforeach 161 162# Headers 163checked_headers = [ 164 'unistd.h', 165 'sys/mman.h', 166 'dirent.h', 167] 168 169foreach h: checked_headers 170 if cc.has_header(h) 171 pango_conf.set('HAVE_' + h.underscorify().to_upper(), 1) 172 endif 173endforeach 174 175# Use debug/optimization flags to determine whether to enable debug or disable 176# cast checks 177pango_debug_cflags = [] 178if get_option('debug') 179 pango_debug_cflags = [ '-DPANGO_ENABLE_DEBUG' ] 180 message('Enabling various debug infrastructure') 181elif get_option('optimization') in ['2', '3', 's'] 182 pango_debug_cflags = [ '-DG_DISABLE_CAST_CHECKS' ] 183 message('Disabling cast checks') 184 # TODO: We may want a configuration argument to add `G_DISABLE_CHECKS` 185 # and `G_DISABLE_ASSERT` from the build, for specific build environments. 186 # On the other hand, those who need these symbols can inject them in their 187 # build as well. 188endif 189 190# Dependencies 191pango_deps = [] 192 193glib_req_version = '>= 2.62' 194fribidi_req_version = '>= 1.0.6' 195libthai_req_version = '>= 0.1.9' 196harfbuzz_req_version = '>= 2.2.0' 197fontconfig_req_version = '>= 2.11.91' 198xft_req_version = '>= 2.0.0' 199cairo_req_version = '>= 1.12.10' 200 201# libm 202mathlib_dep = cc.find_library('m', required: false) 203pango_deps += mathlib_dep 204 205# gobject 206glib_dep = dependency('glib-2.0', version: glib_req_version, 207 fallback: ['glib', 'libglib_dep']) 208gobject_dep = dependency('gobject-2.0', version: glib_req_version, 209 fallback: ['glib', 'libgobject_dep']) 210gio_dep = dependency('gio-2.0', version: glib_req_version, 211 fallback: ['glib', 'libgio_dep']) 212pango_deps += [glib_dep, gobject_dep, gio_dep] 213 214fribidi_dep = dependency('fribidi', version: fribidi_req_version, 215 fallback: ['fribidi', 'libfribidi_dep'], 216 default_options: ['docs=false']) 217pango_deps += fribidi_dep 218 219thai_dep = dependency('libthai', version: libthai_req_version, required: get_option('libthai')) 220if thai_dep.found() 221 pango_conf.set('HAVE_LIBTHAI', 1) 222 pango_deps += thai_dep 223 224 if cc.has_function('th_brk_find_breaks', dependencies: thai_dep) 225 pango_conf.set('HAVE_TH_BRK_FIND_BREAKS', 1) 226 endif 227endif 228 229# These are for the various .pc files so that things will link 230# properly, depending on whether we have the pkg-config files 231# for those non-GNOME dependencies, or when we find them manually 232# for MSVC builds, as their MSVC build systems do not generate 233# pkg-config files for them 234cairo_pc = '' 235cairo_lib = '' 236harfbuzz_pc='' 237freetype2_pc='' 238fontconfig_pc='' 239harfbuzz_lib='' 240fontconfig_lib='' 241 242harfbuzz_dep = dependency('harfbuzz', version: harfbuzz_req_version, required: false) 243if harfbuzz_dep.found() 244 harfbuzz_pc = 'harfbuzz' 245else 246 if cc.get_id() == 'msvc' and cc.has_header('hb.h') 247 # The CMake build files for HarfBuzz (which is used for MSVC builds) do not 248 # generate pkg-config files, so look for harfbuzz.lib. Ensure that we 249 # we look for HarfBuzz 2.0.0 or later. 250 harfbuzz_lib = cc.find_library('harfbuzz', required: false) 251 if harfbuzz_lib.found() 252 if cc.has_function('hb_ot_tags_from_script_and_language', dependencies: harfbuzz_lib) 253 harfbuzz_dep = harfbuzz_lib 254 endif 255 endif 256 endif 257endif 258 259# Remove when Meson acquires ability to declare deps declaratively, or 260# when finding dependencies via CMake files is fixed. 261if not harfbuzz_dep.found() 262 harfbuzz_dep = dependency('harfbuzz', version: harfbuzz_req_version, 263 fallback: ['harfbuzz', 'libharfbuzz_dep'], 264 default_options: ['coretext=enabled']) 265endif 266 267if not harfbuzz_dep.found() 268 error('harfbuzz not found') 269endif 270 271pango_deps += harfbuzz_dep 272 273# If option is 'auto' or 'enabled' it is not required to find fontconfig on the 274# system because a fallback is done at the end. Override 'disabled' option on 275# platforms that requires it. 276fontconfig_option = get_option('fontconfig') 277fontconfig_required = host_system not in ['windows', 'darwin'] 278if not fontconfig_option.disabled() or fontconfig_required 279 fontconfig_option = false 280endif 281 282fontconfig_dep = dependency('fontconfig', version: fontconfig_req_version, required: fontconfig_option) 283if fontconfig_dep.found() 284 fontconfig_pc = 'fontconfig' 285else 286 if cc.get_id() == 'msvc' and cc.has_header('fontconfig/fontconfig.h') 287 # Look for the Visual Studio-style import library if FontConfig's .pc file cannot be 288 # found on Visual Studio 289 fontconfig_dep = cc.find_library('fontconfig', required: fontconfig_option) 290 if fontconfig_dep.found() 291 fontconfig_lib = '-lfontconfig' 292 endif 293 endif 294endif 295 296# Do the fallback now if fontconfig has not been found on the system. Override 297# user option on platforms that always require fontconfig. 298fontconfig_option = fontconfig_required ? true : get_option('fontconfig') 299if not fontconfig_dep.found() 300 fontconfig_dep = dependency('fontconfig', version: fontconfig_req_version, 301 fallback: ['fontconfig', 'fontconfig_dep'], 302 required: fontconfig_option) 303endif 304 305if fontconfig_dep.found() 306 pango_deps += fontconfig_dep 307 308 if fontconfig_dep.type_name() != 'library' 309 if fontconfig_dep.version().version_compare('>=2.12.92') 310 pango_conf.set('HAVE_FCWEIGHTFROMOPENTYPEDOUBLE', 1) 311 endif 312 elif cc.has_function('FcWeightFromOpenTypeDouble', dependencies: fontconfig_dep) 313 pango_conf.set('HAVE_FCWEIGHTFROMOPENTYPEDOUBLE', 1) 314 endif 315endif 316 317if pango_conf.has('HAVE_FCWEIGHTFROMOPENTYPEDOUBLE') 318 res = 'YES' 319else 320 res = 'NO' 321endif 322message('fontconfig has FcWeightFromOpenTypeDouble: ' + res) 323 324# If option is 'auto' or 'enabled' it is not required to find freetype2 on the 325# system because a fallback is done at the end. Override 'disabled' option on 326# if fontconfig has been found. 327freetype_option = get_option('freetype') 328freetype_required = fontconfig_dep.found() 329if not freetype_option.disabled() or freetype_required 330 freetype_option = false 331endif 332 333# The first version of freetype with a pkg-config file is 2.1.5 334freetype_dep = dependency('freetype2', required: freetype_option) 335 336if freetype_dep.found() 337 freetype2_pc = 'freetype2' 338else 339 if cc.get_id() == 'msvc' and cc.has_header('ft2build.h') 340 foreach ft2_lib: ['freetype', 'freetypemt'] 341 if not freetype_dep.found() 342 freetype_dep = cc.find_library(ft2_lib, required: freetype_option) 343 if freetype_dep.found() 344 freetype2_lib = '-l@0@'.format(ft2_lib) 345 endif 346 endif 347 endforeach 348 endif 349endif 350 351# Do the fallback now if freetype2 has not been found on the system. 352freetype_option = freetype_required ? true : get_option('freetype') 353if not freetype_dep.found() 354 freetype_dep = dependency('freetype2', required: freetype_option, 355 fallback: ['freetype2', 'freetype_dep']) 356endif 357 358# To build pangoft2, we need HarfBuzz, FontConfig and FreeType 359build_pangoft2 = harfbuzz_dep.found() and fontconfig_dep.found() and freetype_dep.found() 360if build_pangoft2 361 pango_conf.set('HAVE_FREETYPE', 1) 362 pango_deps += freetype_dep 363endif 364 365xft_dep = dependency('xft', version: xft_req_version, required: get_option('xft')) 366if xft_dep.found() and fontconfig_dep.found() and freetype_dep.found() 367 pango_conf.set('HAVE_XFT', 1) 368 pango_deps += dependency('xrender', required: false) 369 pango_deps += xft_dep 370endif 371 372if host_system == 'darwin' 373 has_core_text = cc.links('''#include <Carbon/Carbon.h> 374 int main (void) { 375 CTGetCoreTextVersion (); 376 return 0; 377 }''', 378 name: 'CoreText availability', 379 dependencies: dependency('appleframeworks', modules: 'ApplicationServices')) 380 if has_core_text 381 pango_conf.set('HAVE_CORE_TEXT', 1) 382 endif 383 384 pango_deps += dependency('appleframeworks', modules: [ 'CoreFoundation', 'ApplicationServices' ]) 385endif 386 387# If option is 'auto' or 'enabled' it is not required to find cairo on the 388# system because a fallback is done at the end. 389cairo_option = get_option('cairo') 390if not cairo_option.disabled() 391 cairo_option = false 392endif 393 394cairo_found_type = '' 395cairo_dep = dependency('cairo', version: cairo_req_version, required: cairo_option) 396 397if cairo_dep.found() 398 cairo_found_type = cairo_dep.type_name() 399else 400 if cc.get_id() == 'msvc' and cc.has_header('cairo.h') 401 cairo_dep = cc.find_library('cairo', required: cairo_option) 402 cairo_found_type = 'library' 403 endif 404endif 405 406# Remove once Meson gains capability to declare dependencies 407# in a declarative way 408if not cairo_dep.found() 409 cairo_dep = dependency('cairo', version: cairo_req_version, 410 fallback: ['cairo', 'libcairo_dep'], required: get_option('cairo'), 411 default_options: ['freetype=enabled', 'fontconfig=enabled']) 412 cairo_found_type = cairo_dep.type_name() 413endif 414 415pango_font_backends = [] 416pango_cairo_backends = [] 417 418if ['pkgconfig', 'internal'].contains(cairo_found_type) 419 # Check the following Cairo font backends 420 # - dependency 421 # - version 422 # - define 423 # - backend name 424 # Note that Cairo can be built with FreeType but without FontConfig 425 426 cairo_font_backends = [ 427 [ 'cairo-ft', cairo_req_version, 'HAVE_CAIRO_FREETYPE', 'freetype', ], 428 [ 'cairo-win32', cairo_req_version, 'HAVE_CAIRO_WIN32', 'win32', ], 429 [ 'cairo-quartz', cairo_req_version, 'HAVE_CAIRO_QUARTZ', 'quartz', ], 430 ] 431 432 if cairo_found_type == 'internal' 433 cairo_features = subproject('cairo').get_variable('built_features') 434 endif 435 436 foreach b: cairo_font_backends 437 if cairo_found_type == 'pkgconfig' 438 dep = dependency(b[0], version: b[1], required: false) 439 else 440 dep = dependency('', required: false) 441 foreach f: cairo_features 442 if f['name'] == b[0] 443 dep = cairo_dep 444 message('Cairo font backend "@0@" enabled'.format(b)) 445 endif 446 endforeach 447 endif 448 if dep.found() 449 if b[0] == 'cairo-ft' 450 if build_pangoft2 451 pango_conf.set(b[2], 1) 452 pango_font_backends += b[3] 453 endif 454 else 455 pango_conf.set(b[2], 1) 456 pango_font_backends += b[3] 457 endif 458 endif 459 endforeach 460 461 if pango_font_backends.length() == 0 462 error('No Cairo font backends found') 463 endif 464 465 # Check the following Cairo surface backends 466 # - dependency 467 # - version 468 # - define 469 # - backend name 470 cairo_surface_backends = [ 471 [ 'cairo-png', cairo_req_version, 'HAVE_CAIRO_PNG', 'png', ], 472 [ 'cairo-ps', cairo_req_version, 'HAVE_CAIRO_PS', 'ps', ], 473 [ 'cairo-pdf', cairo_req_version, 'HAVE_CAIRO_PDF', 'pdf', ], 474 [ 'cairo-xlib', cairo_req_version, 'HAVE_CAIRO_XLIB', 'xlib', ], 475 ] 476 477 foreach b: cairo_surface_backends 478 if cairo_found_type == 'pkgconfig' 479 dep = dependency(b[0], version: b[1], required: false) 480 else 481 dep = dependency('', required: false) 482 foreach f: cairo_features 483 if f['name'] == b[0] 484 dep = cairo_dep 485 message('Cairo surface backend "@0@" enabled'.format(b)) 486 endif 487 endforeach 488 endif 489 if dep.found() 490 pango_conf.set(b[2], 1) 491 pango_cairo_backends += b[3] 492 endif 493 endforeach 494 495 # This is to set up pangocairo.pc so that things that refer to 496 # it will link correctly 497 cairo_pc = 'cairo' 498elif cairo_found_type == 'library' 499 # Fallback: Look for Cairo items manually 500 # We need to check for headers for some 501 cairo_headers = [ 'win32', 'quartz', 'ps', 'pdf', 'xlib' ] 502 503 foreach header : cairo_headers 504 if cc.has_header('cairo-@0@.h'.format(header)) 505 pango_conf.set('HAVE_CAIRO_@0@'.format(header.underscorify().to_upper()), 1) 506 if header == 'win32' or header == 'quartz' 507 pango_font_backends += header 508 else 509 pango_cairo_backends += header 510 endif 511 endif 512 endforeach 513 514 # Other cairo features that we need to check for symbols 515 # Note that Cairo with FreeType support can be without FontConfig 516 # support, so we must check for FontConfig support in Cairo 517 if cc.links('''#include <cairo-ft.h> 518 int main() { 519 FcPattern *p = NULL; 520 cairo_ft_font_face_create_for_pattern (p); 521 return 0; 522 }''', 523 dependencies: cairo_dep, 524 name : 'Cairo is built with FreeType and FontConfig support') 525 if build_pangoft2 526 pango_conf.set('HAVE_CAIRO_FREETYPE', 1) 527 pango_font_backends += 'freetype' 528 endif 529 endif 530 531 if pango_font_backends.length() == 0 532 error('Cairo found, but no Cairo font backends found') 533 endif 534 535 # Check for Cairo's libpng output surface support 536 if cc.links('''#include <cairo.h> 537 #include <stdio.h> 538 int main() { 539 cairo_surface_t *s = NULL; 540 const char *f = "abc.png"; 541 cairo_surface_write_to_png (s, f); 542 return 0; 543 }''', 544 dependencies: cairo_dep, 545 name : 'Cairo is built with PNG output surface support') 546 pango_conf.set('HAVE_CAIRO_PNG', 1) 547 pango_cairo_backends += 'png' 548 endif 549 550 # This is to set up pangocairo.pc so that things that refer to 551 # it will link correctly, when we don't have pkg-config files for cairo 552 cairo_lib = '-lcairo' 553endif 554 555if cairo_dep.found() 556 pango_conf.set('HAVE_CAIRO', 1) 557 pango_deps += cairo_dep 558 559 pangocairo_requires = '' 560 561 if pango_font_backends.contains('freetype') 562 pangocairo_requires += 'pangoft2 ' 563 endif 564 565 if pango_font_backends.contains('win32') 566 pangocairo_requires += 'pangowin32 ' 567 endif 568endif 569 570# libsysprof-capture support 571libsysprof_capture_dep = dependency('sysprof-capture-4', 572 required: get_option('sysprof'), 573 default_options: [ 574 'enable_examples=false', 575 'enable_gtk=false', 576 'enable_tests=false', 577 'enable_tools=false', 578 'libsysprof=false', 579 'with_sysprofd=none', 580 'help=false', 581 ], 582 fallback: ['sysprof', 'libsysprof_capture_dep'], 583) 584pango_conf.set('HAVE_SYSPROF', libsysprof_capture_dep.found()) 585pango_deps += libsysprof_capture_dep 586 587gidocgen_dep = dependency('gi-docgen', version: '>= 2021.1', 588 required: get_option('gtk_doc')) 589 590gnome = import('gnome') 591pkgconfig = import('pkgconfig') 592 593# Internal configuration header 594configure_file(output: 'config.h', configuration: pango_conf) 595 596root_inc = include_directories('.') 597pango_inc = include_directories('pango') 598 599subdir('pango') 600subdir('utils') 601subdir('examples') 602subdir('tests') 603subdir('tools') 604 605if get_option('gtk_doc') 606 subdir('docs') 607endif 608 609if not meson.is_subproject() 610 meson.add_dist_script('build-aux/meson/dist-docs.py') 611endif 612