2c40559609
[meson] Fix dependency lookup and generate `ftconfig.h`. - zlib: If not found on the system, meson can build it as a subproject. We thus never use the (outdated) zlib support that comes with FreeType. Doing so has the additional advantage that the zlib code can be shared with other projects like GLib if both are subprojects of an application. - harfbuzz: Build as a subproject if not found on the system. - 'QUESTION: What if the compiler doesn't support `-D` but uses `/D` instead as on Windows?' Answer: Meson translate arguments for us. - visibility: Replace self-made code with meson-specific solution. * meson.build (ft2_defines): Rewrite logic to set and handle it. (process_header_command): New variable, previously called `ftoption_command`. (ftoption_command, ftconfig_command): New variables. (zlib_option): Removed. (zlib_dep): New variable. (ft2_deps): Updated. (harfbuzz_dep): Updated. (ftconfig_h_in, ftconfig_h): New variables. (ft2_sources): Updated. (ft2_lib): Updated, handle visibility. (summary): Updted. * meson_options.txt (zlib): Updated.
386 lines
11 KiB
Meson
386 lines
11 KiB
Meson
#
|
|
# 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.
|
|
|
|
|
|
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(),
|
|
)
|
|
|
|
#
|
|
# Rules to compile the FreeType 2 library itself
|
|
#
|
|
|
|
|
|
# Apparently meson doesn't provide a read_file() function, so instead
|
|
# running an external command is required.
|
|
|
|
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')
|
|
|
|
|
|
# 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: 'include/freetype2/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 `gzip` and `bzip2` aux modules are 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' or auxmod == 'bzip2'
|
|
# Handled through options instead, see below.
|
|
continue
|
|
endif
|
|
ft2_sources += 'src/@0@/@1@.c'.format(auxmod, source)
|
|
endforeach
|
|
|
|
|
|
# FreeType 2 base extensions.
|
|
# Normally configured through `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/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')
|
|
if mmap_option.auto()
|
|
use_mmap = has_unistd_h and has_fcntl_h and has_sys_mman_h
|
|
else
|
|
use_mmap = mmap_option.enabled()
|
|
endif
|
|
if use_mmap
|
|
# This version of ftsystem.c uses mmap() to read input font files.
|
|
ft2_sources += files(['builds/unix/ftsystem.c',])
|
|
elif host_machine.system() == 'windows'
|
|
ft2_sources += files(['builds/windows/ftsystem.c',])
|
|
else
|
|
ft2_sources += files(['src/base/ftsystem.c',])
|
|
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
|
|
|
|
|
|
# GZip support
|
|
zlib_dep = dependency('zlib', required: get_option('zlib'),
|
|
fallback: ['zlib', 'zlib_dep'])
|
|
if zlib_dep.found()
|
|
ftoption_command += [
|
|
'--enable=FT_CONFIG_OPTION_USE_ZLIB',
|
|
'--enable=FT_CONFIG_OPTION_SYSTEM_ZLIB',
|
|
]
|
|
ft2_sources += files(['src/gzip/ftgzip.c',])
|
|
ft2_deps += [zlib_dep]
|
|
else
|
|
ftoption_command += ['--disable=FT_CONFIG_OPTION_USE_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'))
|
|
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'),
|
|
fallback: ['harfbuzz', 'libharfbuzz_dep'],
|
|
default_options : ['freetype=disabled',
|
|
'fontconfig=disabled'])
|
|
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: 'include/freetype2/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 host_machine.system() in ['linux', 'darwin', 'cygwin']
|
|
ftconfig_h_in = files('builds/unix/ftconfig.h.in')
|
|
else
|
|
ftconfig_h_in = files('include/freetype/config/ftconfig.h')
|
|
endif
|
|
|
|
ftconfig_h = custom_target('ftconfig.h',
|
|
input: ftconfig_h_in,
|
|
output: 'ftconfig.h',
|
|
command: ftconfig_command,
|
|
install: true,
|
|
install_dir: 'include/freetype2/freetype/config',
|
|
)
|
|
ft2_sources += ftconfig_h
|
|
ft2_defines += ['-DFT_CONFIG_CONFIG_H=<ftconfig.h>']
|
|
|
|
|
|
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().
|
|
freetype2_dep = declare_dependency(
|
|
include_directories: ft2_includes,
|
|
link_with: ft2_lib,
|
|
version: ft2_pkgconfig_version)
|
|
meson.override_dependency('freetype2', freetype2_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: 'include/freetype2')
|
|
install_headers(ft2_public_headers,
|
|
install_dir: 'include/freetype2/freetype')
|
|
install_headers(ft2_config_headers,
|
|
install_dir: 'include/freetype2/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,
|
|
)
|
|
|
|
|
|
# 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(),
|
|
'Zlib': zlib_dep.found() ? 'yes' : 'no',
|
|
'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: 'Configuration Options Summary:')
|
|
|
|
# EOF
|