Edit

kc3-lang/freetype/meson.build

Branch :

  • Show log

    Commit

  • Author : Werner Lemberg
    Date : 2021-08-02 12:55:28
    Hash : 09195a82
    Message : * meson.build: Fix zlib support. This commit synchronizes zlib support with both autotools and cmake: If no external zlib is found (or intentionally disabled on the command line), use the internal zlib by undefining `FT_CONFIG_OPTION_SYSTEM_ZLIB` without modifying `FT_CONFIG_OPTION_USE_ZLIB`. Also improve summary output. Problem reported by Moazin.

  • meson.build
  • #
    # Meson project file for FreeType 2
    #
    
    # Copyright (C) 2020-2021 by
    # David Turner, Robert Wilhelm, and Werner Lemberg.
    #
    # This file is part of the FreeType project, and may only be used, modified,
    # and distributed under the terms of the FreeType project license,
    # LICENSE.TXT.  By continuing to use, modify, or distribute this file you
    # indicate that you have read the license and understand and accept it
    # fully.
    
    #
    # Say
    #
    #   meson configure
    #
    # to see all configuration options and their default values.  For example,
    # to build only a shared version of FreeType, override the default value
    # with
    #
    #   meson setup -Ddefault_library=shared
    #
    
    project('freetype2', 'c',
      meson_version: '>= 0.55.0',
      default_options: ['default_library=both'],
      version: run_command('builds/meson/extract_freetype_version.py',
                           'include/freetype/freetype.h').stdout().strip(),
    )
    
    
    # Only meson >= 0.57 can read a file and assign its contents to a
    # variable; we thus use an external command to have this functionality
    # with older versions, too.
    
    python = import('python')
    python_exe = python.find_installation(required: true)
    
    ft2_so_version = run_command(python_exe,
      files('builds/meson/extract_libtool_version.py'),
      '--soversion',
      files('builds/unix/configure.raw')).stdout().strip()
    
    ft2_pkgconfig_version = run_command(python_exe,
      files('builds/meson/extract_libtool_version.py'),
      files('builds/unix/configure.raw')).stdout().strip()
    
    ft2_includes = include_directories('include')
    
    freetype_includedir = join_paths(get_option('includedir'), 'freetype2')
    
    # Generate a custom `ftmodule.h` version based on the content of
    # `modules.cfg`.
    
    ftmodule_h = custom_target('ftmodule.h',
      output: 'ftmodule.h',
      input: 'modules.cfg',
      command: [python_exe, files('builds/meson/parse_modules_cfg.py'),
                '--format=ftmodule.h', '@INPUT@', '--output', '@OUTPUT@'],
      install: true,
      install_dir: join_paths(freetype_includedir, 'freetype/config'),
    )
    ft2_sources = [ftmodule_h]
    
    
    # FreeType 2 modules.
    
    ft_main_modules = run_command(python_exe,
      files('builds/meson/parse_modules_cfg.py'),
      '--format=main-modules',
      files('modules.cfg')).stdout().strip().split()
    
    ft2_sources += files([
      'src/base/ftbase.c',
      'src/base/ftinit.c',
    ])
    
    foreach mod: ft_main_modules
      source = mod
      if mod == 'winfonts'
        source = 'winfnt'
      elif mod == 'cid'
        source = 'type1cid'
      endif
      ft2_sources += 'src/@0@/@1@.c'.format(mod, source)
    endforeach
    
    # NOTE: The `bzip2` aux module is handled through options.
    ft_aux_modules = run_command(python_exe,
      files('builds/meson/parse_modules_cfg.py'),
      '--format=aux-modules',
      files('modules.cfg')).stdout().strip().split()
    
    foreach auxmod: ft_aux_modules
      source = auxmod
      # Most sources are named `src/<module>/<module>.c`, but there are a few
      # exceptions handled here.
      if auxmod == 'cache'
        source = 'ftcache'
      elif auxmod == 'lzw'
        source = 'ftlzw'
      elif auxmod == 'gzip'
        source = 'ftgzip'
      elif auxmod == 'bzip2'
        # Handled through options instead, see below.
        continue
      endif
      ft2_sources += 'src/@0@/@1@.c'.format(auxmod, source)
    endforeach
    
    
    # FreeType 2 base extensions.
    # To be configured in `modules.cfg`.
    
    base_extensions = run_command(python_exe,
      files('builds/meson/parse_modules_cfg.py'),
      '--format=base-extensions-list',
      files('modules.cfg')).stdout().split()
    
    foreach ext: base_extensions
      ft2_sources += files('src/base/' + ext)
    endforeach
    
    
    # Header files.
    
    ft2_public_headers = files([
      'include/freetype/freetype.h',
      'include/freetype/ftadvanc.h',
      'include/freetype/ftbbox.h',
      'include/freetype/ftbdf.h',
      'include/freetype/ftbitmap.h',
      'include/freetype/ftbzip2.h',
      'include/freetype/ftcache.h',
      'include/freetype/ftchapters.h',
      'include/freetype/ftcid.h',
      'include/freetype/ftcolor.h',
      'include/freetype/ftdriver.h',
      'include/freetype/fterrdef.h',
      'include/freetype/fterrors.h',
      'include/freetype/ftfntfmt.h',
      'include/freetype/ftgasp.h',
      'include/freetype/ftglyph.h',
      'include/freetype/ftgxval.h',
      'include/freetype/ftgzip.h',
      'include/freetype/ftimage.h',
      'include/freetype/ftincrem.h',
      'include/freetype/ftlcdfil.h',
      'include/freetype/ftlist.h',
      'include/freetype/ftlzw.h',
      'include/freetype/ftmac.h',
      'include/freetype/ftmm.h',
      'include/freetype/ftmodapi.h',
      'include/freetype/ftmoderr.h',
      'include/freetype/ftotval.h',
      'include/freetype/ftoutln.h',
      'include/freetype/ftparams.h',
      'include/freetype/ftpfr.h',
      'include/freetype/ftrender.h',
      'include/freetype/ftsizes.h',
      'include/freetype/ftsnames.h',
      'include/freetype/ftstroke.h',
      'include/freetype/ftsynth.h',
      'include/freetype/ftsystem.h',
      'include/freetype/fttrigon.h',
      'include/freetype/fttypes.h',
      'include/freetype/ftwinfnt.h',
      'include/freetype/t1tables.h',
      'include/freetype/ttnameid.h',
      'include/freetype/tttables.h',
      'include/freetype/tttags.h',
    ])
    
    ft2_config_headers = files([
      'include/freetype/config/ftconfig.h',
      'include/freetype/config/ftheader.h',
      'include/freetype/config/ftstdlib.h',
      'include/freetype/config/integer-types.h',
      'include/freetype/config/mac-support.h',
      'include/freetype/config/public-macros.h',
    ])
    
    ft2_defines = ['-DFT2_BUILD_LIBRARY=1']
    
    
    # System support file.
    
    cc = meson.get_compiler('c')
    
    # NOTE: msys2 on Windows has `unistd.h` and `fcntl.h` but not `sys/mman.h`!
    has_unistd_h = cc.has_header('unistd.h')
    has_fcntl_h = cc.has_header('fcntl.h')
    has_sys_mman_h = cc.has_header('sys/mman.h')
    
    mmap_option = get_option('mmap')
    
    use_unix_ftsystem_c = false
    if mmap_option.disabled()
      ft2_sources += files(['src/base/ftsystem.c',])
    elif host_machine.system() == 'windows'
      ft2_sources += files(['builds/windows/ftsystem.c',])
    else
      if has_unistd_h and has_fcntl_h and has_sys_mman_h
        # This version of `ftsystem.c` uses `mmap` to read input font files.
        ft2_sources += files(['builds/unix/ftsystem.c',])
        use_unix_ftsystem_c = true
      elif mmap_option.enabled()
        error('mmap was enabled via options but is not available,'
              + ' required headers were not found!')
      else
        ft2_sources += files(['src/base/ftsystem.c',])
      endif
    endif
    
    
    # Debug support file
    #
    # NOTE: Some specialized versions exist for other platforms not supported by
    # Meson.  Most implementation differences are extremely minor, i.e., in the
    # implementation of `FT_Message` and `FT_Panic`, and getting the `FT2_DEBUG`
    # value from the environment, when this is supported.  A smaller refactor
    # might make these platform-specific files much smaller, and could be moved
    # into `ftsystem.c` as well.
    #
    if host_machine.system() == 'windows'
      winmod = import('windows')
      ft2_sources += [
        'builds/windows/ftdebug.c',
        winmod.compile_resources('src/base/ftver.rc'),
      ]
    else
      ft2_sources += 'src/base/ftdebug.c'
    endif
    
    ft2_deps = []
    
    
    # Generate `ftoption.h` based on available dependencies.
    
    process_header_command = [python_exe,
      files('builds/meson/process_ftoption_h.py'),
      '@INPUT@', '--output=@OUTPUT@']
    ftoption_command = process_header_command
    
    
    # external GZip support
    zlib_dep = dependency('zlib',
      required: get_option('zlib'),
      fallback: 'zlib')
    
    if zlib_dep.found()
      ftoption_command += ['--enable=FT_CONFIG_OPTION_SYSTEM_ZLIB']
      ft2_deps += [zlib_dep]
    else
      ftoption_command += ['--disable=FT_CONFIG_OPTION_SYSTEM_ZLIB']
    endif
    
    # BZip2 support
    bzip2_dep = cc.find_library('bz2',
      required: get_option('bzip2'))
    
    if bzip2_dep.found()
      ftoption_command += ['--enable=FT_CONFIG_OPTION_USE_BZIP2']
      ft2_sources += files(['src/bzip2/ftbzip2.c',])
      ft2_deps += [bzip2_dep]
    endif
    
    # PNG support
    libpng_dep = dependency('libpng',
      required: get_option('png'),
      fallback: 'libpng')
    
    if libpng_dep.found()
      ftoption_command += ['--enable=FT_CONFIG_OPTION_USE_PNG']
      ft2_deps += [libpng_dep]
    endif
    
    # Harfbuzz support
    harfbuzz_dep = dependency('harfbuzz',
      version: '>= 2.0.0',
      required: get_option('harfbuzz'))
    
    if harfbuzz_dep.found()
      ftoption_command += ['--enable=FT_CONFIG_OPTION_USE_HARFBUZZ']
      ft2_deps += [harfbuzz_dep]
    endif
    
    # Brotli decompression support
    brotli_dep = dependency('libbrotlidec',
      required: get_option('brotli'))
    
    if brotli_dep.found()
      ftoption_command += ['--enable=FT_CONFIG_OPTION_USE_BROTLI']
      ft2_deps += [brotli_dep]
    endif
    
    # We can now generate `ftoption.h`.
    ftoption_h = custom_target('ftoption.h',
      input: 'include/freetype/config/ftoption.h',
      output: 'ftoption.h',
      command: ftoption_command,
      install: true,
      install_dir: join_paths(freetype_includedir, 'freetype/config'),
    )
    ft2_sources += ftoption_h
    ft2_defines += ['-DFT_CONFIG_OPTIONS_H=<ftoption.h>']
    
    if host_machine.system() == 'windows'
      ft2_defines += ['-DDLL_EXPORT=1']
    endif
    
    
    # Generate `ftconfig.h`.
    
    ftconfig_command = process_header_command
    if has_unistd_h
      ftconfig_command += '--enable=HAVE_UNISTD_H'
    endif
    if has_fcntl_h
      ftconfig_command += '--enable=HAVE_FCNTL_H'
    endif
    
    if use_unix_ftsystem_c
      ftconfig_h_in = files('builds/unix/ftconfig.h.in')
      ftconfig_h = custom_target('ftconfig.h',
        input: ftconfig_h_in,
        output: 'ftconfig.h',
        command: ftconfig_command,
        install: true,
        install_dir: join_paths(freetype_includedir, 'freetype/config'),
      )
      ft2_sources += ftconfig_h
      ft2_defines += ['-DFT_CONFIG_CONFIG_H=<ftconfig.h>']
    endif
    
    
    ft2_lib = library('freetype',
      sources: ft2_sources + [ftmodule_h],
      c_args: ft2_defines,
      gnu_symbol_visibility: 'hidden',
      include_directories: ft2_includes,
      dependencies: ft2_deps,
      install: true,
      version: ft2_so_version,
    )
    
    
    # To be used by other projects including this one through `subproject`.
    freetype_dep = declare_dependency(
      include_directories: ft2_includes,
      link_with: ft2_lib,
      version: ft2_pkgconfig_version)
    
    meson.override_dependency('freetype2', freetype_dep)
    
    
    # NOTE: Using both `install_dir` and `subdir` doesn't seem to work below,
    # i.e., the subdir value seems to be ignored, contrary to examples in the
    # Meson documentation.
    install_headers('include/ft2build.h',
      install_dir: freetype_includedir)
    install_headers(ft2_public_headers,
      install_dir: join_paths(freetype_includedir, 'freetype'))
    install_headers(ft2_config_headers,
      install_dir: join_paths(freetype_includedir, 'freetype/config'))
    
    
    pkgconfig = import('pkgconfig')
    
    pkgconfig.generate(ft2_lib,
      filebase: 'freetype2',
      name: 'FreeType 2',
      description: 'A free, high-quality, and portable font engine.',
      url: 'https://freetype.org',
      subdirs: 'freetype2',
      version: ft2_pkgconfig_version,
    )
    
    if get_option('tests').enabled()
      subdir('tests')
    endif
    
    # NOTE: Unlike the old `make refdoc` command, this generates the
    # documentation under `$BUILD/docs/` since Meson doesn't support modifying
    # the source root directory (which is a good thing).
    gen_docs = custom_target('freetype2 reference documentation',
      output: 'docs',
      input: ft2_public_headers + ft2_config_headers,
      command: [python_exe,
        files('builds/meson/generate_reference_docs.py'),
        '--version=' + meson.project_version(),
        '--input-dir=' + meson.source_root(),
        '--output-dir=@OUTPUT@'
      ],
    )
    
    
    summary({'OS': host_machine.system(),
            }, section: 'Operating System')
    
    summary({'Zlib': zlib_dep.found() ? 'external' : 'internal',
             'Bzip2': bzip2_dep.found() ? 'yes' : 'no',
             'Png': libpng_dep.found() ? 'yes' : 'no',
             'Harfbuzz': harfbuzz_dep.found() ? 'yes' : 'no',
             'Brotli': brotli_dep.found() ? 'yes' : 'no',
            }, section: 'Used Libraries')
    
    # EOF