tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

meson.build (14544B)


      1 #
      2 # Meson project file for FreeType 2
      3 #
      4 
      5 # Copyright (C) 2020-2025 by
      6 # David Turner, Robert Wilhelm, and Werner Lemberg.
      7 #
      8 # This file is part of the FreeType project, and may only be used, modified,
      9 # and distributed under the terms of the FreeType project license,
     10 # LICENSE.TXT.  By continuing to use, modify, or distribute this file you
     11 # indicate that you have read the license and understand and accept it
     12 # fully.
     13 
     14 #
     15 # Say
     16 #
     17 #   meson configure
     18 #
     19 # to see all configuration options and their default values.  For example,
     20 # to build only a shared version of FreeType, override the default value
     21 # with
     22 #
     23 #   meson setup -Ddefault_library=shared
     24 #
     25 
     26 project('freetype2', 'c',
     27  meson_version: '>= 0.55.0',
     28  version: run_command('builds/meson/extract_freetype_version.py',
     29                       'include/freetype/freetype.h',
     30                       check: true).stdout().strip(),
     31 )
     32 
     33 
     34 # Only meson >= 0.57 can read a file and assign its contents to a
     35 # variable; we thus use an external command to have this functionality
     36 # with older versions, too.
     37 
     38 python_exe = find_program('python3')
     39 
     40 ft2_so_version = run_command(python_exe,
     41  files('builds/meson/extract_libtool_version.py'),
     42  '--soversion',
     43  files('builds/unix/configure.raw'),
     44  check: true).stdout().strip()
     45 
     46 ft2_pkgconfig_version = run_command(python_exe,
     47  files('builds/meson/extract_libtool_version.py'),
     48  files('builds/unix/configure.raw'),
     49  check: true).stdout().strip()
     50 
     51 ft2_includes = include_directories('include')
     52 
     53 freetype_includedir = join_paths(get_option('includedir'), 'freetype2')
     54 
     55 ft2_defines = []
     56 
     57 freetype_aclocaldir = join_paths(get_option('datadir'), 'aclocal')
     58 
     59 
     60 # Generate a custom `ftmodule.h` version based on the content of
     61 # `modules.cfg`.
     62 
     63 ftmodule_h = custom_target('ftmodule.h',
     64  output: 'ftmodule.h',
     65  input: 'modules.cfg',
     66  command: [python_exe, files('builds/meson/parse_modules_cfg.py'),
     67            '--format=ftmodule.h', '@INPUT@', '--output', '@OUTPUT@'],
     68  install: true,
     69  install_dir: join_paths(freetype_includedir, 'freetype/config'),
     70 )
     71 ft2_sources = [ftmodule_h]
     72 ft2_defines += ['-DFT_CONFIG_MODULES_H=<ftmodule.h>']
     73 
     74 
     75 # FreeType 2 modules.
     76 
     77 ft_main_modules = run_command(python_exe,
     78  files('builds/meson/parse_modules_cfg.py'),
     79  '--format=main-modules',
     80  files('modules.cfg'),
     81  check: true).stdout().strip().split()
     82 
     83 ft2_sources += files([
     84  'src/base/ftbase.c',
     85  'src/base/ftinit.c',
     86 ])
     87 
     88 foreach mod: ft_main_modules
     89  source = mod
     90  if mod == 'winfonts'
     91    source = 'winfnt'
     92  elif mod == 'cid'
     93    source = 'type1cid'
     94  endif
     95  ft2_sources += 'src/@0@/@1@.c'.format(mod, source)
     96 endforeach
     97 
     98 # NOTE: The `bzip2` aux module is handled through options.
     99 ft_aux_modules = run_command(python_exe,
    100  files('builds/meson/parse_modules_cfg.py'),
    101  '--format=aux-modules',
    102  files('modules.cfg'),
    103  check: true).stdout().strip().split()
    104 
    105 foreach auxmod: ft_aux_modules
    106  source = auxmod
    107  # Most sources are named `src/<module>/<module>.c`, but there are a few
    108  # exceptions handled here.
    109  if auxmod == 'cache'
    110    source = 'ftcache'
    111  elif auxmod == 'lzw'
    112    source = 'ftlzw'
    113  elif auxmod == 'gzip'
    114    source = 'ftgzip'
    115  elif auxmod == 'bzip2'
    116    # Handled through options instead, see below.
    117    continue
    118  endif
    119  ft2_sources += 'src/@0@/@1@.c'.format(auxmod, source)
    120 endforeach
    121 
    122 
    123 # FreeType 2 base extensions.
    124 # To be configured in `modules.cfg`.
    125 
    126 base_extensions = run_command(python_exe,
    127  files('builds/meson/parse_modules_cfg.py'),
    128  '--format=base-extensions-list',
    129  files('modules.cfg'),
    130  check: true).stdout().split()
    131 
    132 foreach ext: base_extensions
    133  ft2_sources += files('src/base/' + ext)
    134 endforeach
    135 
    136 
    137 # Header files.
    138 
    139 ft2_public_headers = files([
    140  'include/freetype/freetype.h',
    141  'include/freetype/ftadvanc.h',
    142  'include/freetype/ftbbox.h',
    143  'include/freetype/ftbdf.h',
    144  'include/freetype/ftbitmap.h',
    145  'include/freetype/ftbzip2.h',
    146  'include/freetype/ftcache.h',
    147  'include/freetype/ftchapters.h',
    148  'include/freetype/ftcid.h',
    149  'include/freetype/ftcolor.h',
    150  'include/freetype/ftdriver.h',
    151  'include/freetype/fterrdef.h',
    152  'include/freetype/fterrors.h',
    153  'include/freetype/ftfntfmt.h',
    154  'include/freetype/ftgasp.h',
    155  'include/freetype/ftglyph.h',
    156  'include/freetype/ftgxval.h',
    157  'include/freetype/ftgzip.h',
    158  'include/freetype/ftimage.h',
    159  'include/freetype/ftincrem.h',
    160  'include/freetype/ftlcdfil.h',
    161  'include/freetype/ftlist.h',
    162  'include/freetype/ftlogging.h',
    163  'include/freetype/ftlzw.h',
    164  'include/freetype/ftmac.h',
    165  'include/freetype/ftmm.h',
    166  'include/freetype/ftmodapi.h',
    167  'include/freetype/ftmoderr.h',
    168  'include/freetype/ftotval.h',
    169  'include/freetype/ftoutln.h',
    170  'include/freetype/ftparams.h',
    171  'include/freetype/ftpfr.h',
    172  'include/freetype/ftrender.h',
    173  'include/freetype/ftsizes.h',
    174  'include/freetype/ftsnames.h',
    175  'include/freetype/ftstroke.h',
    176  'include/freetype/ftsynth.h',
    177  'include/freetype/ftsystem.h',
    178  'include/freetype/fttrigon.h',
    179  'include/freetype/fttypes.h',
    180  'include/freetype/ftwinfnt.h',
    181  'include/freetype/otsvg.h',
    182  'include/freetype/t1tables.h',
    183  'include/freetype/ttnameid.h',
    184  'include/freetype/tttables.h',
    185  'include/freetype/tttags.h',
    186 ])
    187 
    188 ft2_config_headers = files([
    189  'include/freetype/config/ftconfig.h',
    190  'include/freetype/config/ftheader.h',
    191  'include/freetype/config/ftstdlib.h',
    192  'include/freetype/config/integer-types.h',
    193  'include/freetype/config/mac-support.h',
    194  'include/freetype/config/public-macros.h',
    195 ])
    196 
    197 ft2_defines += ['-DFT2_BUILD_LIBRARY=1']
    198 
    199 
    200 # System support file.
    201 
    202 cc = meson.get_compiler('c')
    203 
    204 # NOTE: msys2 on Windows has `unistd.h` and `fcntl.h` but not `sys/mman.h`!
    205 has_unistd_h = cc.has_header('unistd.h')
    206 has_fcntl_h = cc.has_header('fcntl.h')
    207 has_sys_mman_h = cc.has_header('sys/mman.h')
    208 
    209 mmap_option = get_option('mmap')
    210 
    211 use_unix_ftsystem_c = false
    212 if mmap_option.disabled()
    213  ft2_sources += files(['src/base/ftsystem.c',])
    214 elif host_machine.system() == 'windows'
    215  ft2_sources += files(['builds/windows/ftsystem.c',])
    216 else
    217  if has_unistd_h and has_fcntl_h and has_sys_mman_h
    218    # This version of `ftsystem.c` uses `mmap` to read input font files.
    219    ft2_sources += files(['builds/unix/ftsystem.c',])
    220    use_unix_ftsystem_c = true
    221  elif mmap_option.enabled()
    222    error('mmap was enabled via options but is not available,'
    223          + ' required headers were not found!')
    224  else
    225    ft2_sources += files(['src/base/ftsystem.c',])
    226  endif
    227 endif
    228 
    229 
    230 # Debug support file
    231 #
    232 # NOTE: Some specialized versions exist for other platforms not supported by
    233 # Meson.  Most implementation differences are extremely minor, i.e., in the
    234 # implementation of `FT_Message` and `FT_Panic`, and getting the `FT2_DEBUG`
    235 # value from the environment, when this is supported.  A smaller refactor
    236 # might make these platform-specific files much smaller, and could be moved
    237 # into `ftsystem.c` as well.
    238 
    239 if host_machine.system() == 'windows'
    240  winmod = import('windows')
    241  ft2_sources += [
    242    'builds/windows/ftdebug.c',
    243    winmod.compile_resources('src/base/ftver.rc'),
    244  ]
    245 else
    246  ft2_sources += 'src/base/ftdebug.c'
    247 endif
    248 
    249 
    250 ft2_deps = []
    251 common_ldflags = []
    252 
    253 
    254 # Correct compatibility version for OS x.
    255 #
    256 # OSX sets the compatibility_version (aka libtools version) differently from
    257 # the library name.
    258 
    259 if host_machine.system() == 'darwin'
    260  # maintain compatibility with autotools on macOS
    261  common_ldflags = [
    262    '-compatibility_version', ft2_pkgconfig_version.split('.')[0],
    263    '-current_version', ft2_pkgconfig_version
    264  ]
    265 endif
    266 
    267 
    268 # Generate `ftoption.h` based on available dependencies.
    269 
    270 process_header_command = [python_exe,
    271  files('builds/meson/process_ftoption_h.py'),
    272  '@INPUT@', '--output=@OUTPUT@']
    273 
    274 ftoption_command = process_header_command
    275 
    276 # External GZip support.
    277 zlib_option = get_option('zlib')
    278 
    279 # Backward-compatible aliases.
    280 if zlib_option == 'disabled'
    281  zlib_option = 'none'
    282 elif zlib_option == 'enabled'
    283  zlib_option = 'auto'
    284 endif
    285 
    286 if zlib_option == 'auto'
    287  # First try to find a system installation, otherwise fall back to
    288  # the subproject.
    289  zlib_dep = dependency('zlib',
    290    required: false)
    291  if zlib_dep.found()
    292    zlib_option = 'system'
    293  else
    294    zlib_option = 'external'
    295  endif
    296 endif
    297 
    298 if zlib_option == 'none'
    299  ftoption_command += [ '--disable=FT_CONFIG_OPTION_USE_ZLIB' ]
    300 elif zlib_option == 'internal'
    301  ftoption_command += [ '--enable=FT_CONFIG_OPTION_USE_ZLIB' ]
    302 elif zlib_option == 'external'
    303  ftoption_command += [ '--enable=FT_CONFIG_OPTION_USE_ZLIB' ]
    304  zlib_project = subproject('zlib',
    305    required: true,
    306    default_options: 'default_library=static')
    307  zlib_dep = zlib_project.get_variable('zlib_dep')
    308  ft2_deps += [zlib_dep]
    309 elif zlib_option == 'system'
    310  zlib_dep = dependency('zlib',
    311    required: true)
    312  assert(zlib_dep.found(), 'Could not find system zlib installation!')
    313  ftoption_command += [
    314    '--enable=FT_CONFIG_OPTION_USE_ZLIB',
    315    '--enable=FT_CONFIG_OPTION_SYSTEM_ZLIB',
    316  ]
    317  ft2_deps += [zlib_dep]
    318 else
    319  assert(false, 'Invalid zlib option ' + zlib_option)
    320 endif
    321 
    322 # BZip2 support.
    323 bzip2_dep = dependency(
    324  'bzip2',
    325  required: get_option('bzip2').disabled() ? get_option('bzip2') : false,
    326 )
    327 if not bzip2_dep.found()
    328  bzip2_dep = cc.find_library(
    329    'bz2',
    330    has_headers: ['bzlib.h'],
    331    required: get_option('bzip2'),
    332  )
    333 endif
    334 
    335 if bzip2_dep.found()
    336  ftoption_command += ['--enable=FT_CONFIG_OPTION_USE_BZIP2']
    337  ft2_sources += files(['src/bzip2/ftbzip2.c',])
    338  ft2_deps += [bzip2_dep]
    339 endif
    340 
    341 # PNG support.
    342 libpng_dep = dependency('libpng',
    343  required: get_option('png'),
    344  fallback: 'libpng')
    345 
    346 if libpng_dep.found()
    347  ftoption_command += ['--enable=FT_CONFIG_OPTION_USE_PNG']
    348  ft2_deps += [libpng_dep]
    349 endif
    350 
    351 # HarfBuzz support.
    352 harfbuzz_opt = get_option('harfbuzz')
    353 harfbuzz_dep = disabler()
    354 
    355 if harfbuzz_opt == 'enabled' or harfbuzz_opt == 'auto'
    356  harfbuzz_dep = dependency('harfbuzz',
    357    version: '>= 2.0.0',
    358    required: harfbuzz_opt == 'enabled',
    359    default_options: ['freetype=disabled'])
    360  if harfbuzz_dep.found()
    361    harfbuzz_opt = 'YES'
    362    ftoption_command += ['--enable=FT_CONFIG_OPTION_USE_HARFBUZZ']
    363    ft2_deps += [harfbuzz_dep]
    364  endif
    365 endif
    366 
    367 if not harfbuzz_dep.found() and \
    368   (harfbuzz_opt == 'dynamic' or harfbuzz_opt == 'auto')
    369  # On Windows we don't need libdl, but on other platforms we need it.
    370  if host_machine.system() == 'windows'
    371    harfbuzz_opt = 'dynamic'
    372    ftoption_command += [
    373      '--enable=FT_CONFIG_OPTION_USE_HARFBUZZ',
    374      '--enable=FT_CONFIG_OPTION_USE_HARFBUZZ_DYNAMIC',
    375    ]
    376  else
    377    harfbuzz_dep = meson.get_compiler('c').find_library('dl',
    378      required: harfbuzz_opt == 'dynamic',
    379    )
    380    if harfbuzz_dep.found()
    381      harfbuzz_opt = 'dynamic'
    382      ftoption_command += [
    383        '--enable=FT_CONFIG_OPTION_USE_HARFBUZZ',
    384        '--enable=FT_CONFIG_OPTION_USE_HARFBUZZ_DYNAMIC',
    385      ]
    386      ft2_deps += [harfbuzz_dep]
    387    endif
    388  endif
    389 endif
    390 
    391 if harfbuzz_opt == 'disabled' or harfbuzz_opt == 'auto'
    392  harfbuzz_opt = 'NO'
    393 endif
    394 
    395 # Brotli decompression support.
    396 brotli_dep = dependency('libbrotlidec',
    397  required: get_option('brotli'))
    398 
    399 if brotli_dep.found()
    400  ftoption_command += ['--enable=FT_CONFIG_OPTION_USE_BROTLI']
    401  ft2_deps += [brotli_dep]
    402 endif
    403 
    404 if get_option('error_strings')
    405  ftoption_command += ['--enable=FT_CONFIG_OPTION_ERROR_STRINGS']
    406 endif
    407 
    408 # We can now generate `ftoption.h`.
    409 ftoption_h = custom_target('ftoption.h',
    410  input: 'include/freetype/config/ftoption.h',
    411  output: 'ftoption.h',
    412  command: ftoption_command,
    413  install: true,
    414  install_dir: join_paths(freetype_includedir, 'freetype/config'),
    415 )
    416 ft2_sources += ftoption_h
    417 ft2_defines += ['-DFT_CONFIG_OPTIONS_H=<ftoption.h>']
    418 
    419 if host_machine.system() == 'windows' and \
    420   get_option('default_library') == 'shared'
    421  ft2_defines += ['-DDLL_EXPORT=1']
    422 endif
    423 
    424 
    425 # Generate `ftconfig.h`.
    426 
    427 ftconfig_command = process_header_command
    428 
    429 if has_unistd_h
    430  ftconfig_command += '--enable=HAVE_UNISTD_H'
    431 endif
    432 if has_fcntl_h
    433  ftconfig_command += '--enable=HAVE_FCNTL_H'
    434 endif
    435 
    436 if use_unix_ftsystem_c
    437  ftconfig_h_in = files('builds/unix/ftconfig.h.in')
    438  ftconfig_h = custom_target('ftconfig.h',
    439    input: ftconfig_h_in,
    440    output: 'ftconfig.h',
    441    command: ftconfig_command,
    442    install: true,
    443    install_dir: join_paths(freetype_includedir, 'freetype/config'),
    444  )
    445  ft2_sources += ftconfig_h
    446  ft2_defines += ['-DFT_CONFIG_CONFIG_H=<ftconfig.h>']
    447 endif
    448 
    449 
    450 ft2_lib = library('freetype',
    451  sources: ft2_sources + [ftmodule_h],
    452  c_args: ft2_defines,
    453  gnu_symbol_visibility: 'hidden',
    454  include_directories: ft2_includes,
    455  dependencies: ft2_deps,
    456  install: true,
    457  version: ft2_so_version,
    458  link_args: common_ldflags,
    459 )
    460 
    461 
    462 # To be used by other projects including this one via `subproject`.
    463 
    464 freetype_dep = declare_dependency(
    465  include_directories: ft2_includes,
    466  link_with: ft2_lib,
    467  version: ft2_pkgconfig_version)
    468 
    469 meson.override_dependency('freetype2', freetype_dep)
    470 
    471 
    472 # NOTE: Using both `install_dir` and `subdir` doesn't seem to work
    473 # below, i.e., the `subdir` value seems to be ignored, contrary to
    474 # examples in the Meson documentation.
    475 install_headers('include/ft2build.h',
    476  install_dir: freetype_includedir)
    477 install_headers(ft2_public_headers,
    478  install_dir: join_paths(freetype_includedir, 'freetype'))
    479 install_headers(ft2_config_headers,
    480  install_dir: join_paths(freetype_includedir, 'freetype/config'))
    481 
    482 
    483 install_data('builds/unix/freetype2.m4',
    484  install_dir: freetype_aclocaldir)
    485 
    486 
    487 pkgconfig = import('pkgconfig')
    488 
    489 pkgconfig.generate(ft2_lib,
    490  filebase: 'freetype2',
    491  name: 'FreeType 2',
    492  description: 'A free, high-quality, and portable font engine.',
    493  url: 'https://freetype.org',
    494  subdirs: 'freetype2',
    495  version: ft2_pkgconfig_version,
    496 )
    497 
    498 if get_option('tests').enabled()
    499  subdir('tests')
    500 endif
    501 
    502 
    503 # NOTE: Unlike the old `make refdoc` command, this generates the
    504 # documentation under `$BUILD/docs/` since Meson doesn't support modifying
    505 # the source root directory (which is a good thing).
    506 
    507 gen_docs = custom_target('freetype2 reference documentation',
    508  output: 'docs',
    509  input: ft2_public_headers + ft2_config_headers,
    510  command: [python_exe,
    511    files('builds/meson/generate_reference_docs.py'),
    512    '--version=' + meson.project_version(),
    513    '--input-dir=' + meson.current_source_dir(),
    514    '--output-dir=@OUTPUT@'
    515  ],
    516 )
    517 
    518 
    519 summary({'OS': host_machine.system(),
    520        }, section: 'Operating System')
    521 
    522 summary({'Zlib': zlib_option,
    523         'Bzip2': bzip2_dep.found(),
    524         'Png': libpng_dep.found(),
    525         'HarfBuzz': harfbuzz_opt,
    526         'Brotli': brotli_dep.found(),
    527        }, bool_yn: true, section: 'Used Libraries')
    528 
    529 # EOF