Imported Upstream version 8.2.2
[platform/upstream/harfbuzz.git] / src / meson.build
index c9d3f17..5401e5d 100644 (file)
@@ -1,3 +1,5 @@
+fs = import('fs')
+
 hb_version_h = configure_file(
                command: [find_program('gen-hb-version.py'), meson.project_version(), '@OUTPUT@', '@INPUT@'],
                input: 'hb-version.h.in',
@@ -44,18 +46,25 @@ hb_base_sources = files(
   'hb-dispatch.hh',
   'hb-draw.cc',
   'hb-draw.hh',
+  'hb-paint.cc',
+  'hb-paint.hh',
+  'hb-paint-extents.cc',
+  'hb-paint-extents.hh',
   'hb-face.cc',
   'hb-face.hh',
+  'hb-face-builder.cc',
   'hb-fallback-shape.cc',
   'hb-font.cc',
   'hb-font.hh',
   'hb-iter.hh',
   'hb-kern.hh',
+  'hb-limits.hh',
   'hb-machinery.hh',
   'hb-map.cc',
   'hb-map.hh',
   'hb-meta.hh',
   'hb-ms-feature-ranges.hh',
+  'hb-multimap.hh',
   'hb-mutex.hh',
   'hb-null.hh',
   'hb-number.cc',
@@ -70,11 +79,6 @@ hb_base_sources = files(
   'hb-ot-cff2-table.cc',
   'hb-ot-cff2-table.hh',
   'hb-ot-cmap-table.hh',
-  'hb-ot-color-cbdt-table.hh',
-  'hb-ot-color-colr-table.hh',
-  'hb-ot-color-cpal-table.hh',
-  'hb-ot-color-sbix-table.hh',
-  'hb-ot-color-svg-table.hh',
   'hb-ot-color.cc',
   'hb-ot-face-table-list.hh',
   'hb-ot-face.cc',
@@ -92,6 +96,83 @@ hb_base_sources = files(
   'hb-ot-layout-gdef-table.hh',
   'hb-ot-layout-gpos-table.hh',
   'hb-ot-layout-gsub-table.hh',
+  'hb-outline.hh',
+  'hb-outline.cc',
+  'OT/Color/CBDT/CBDT.hh',
+  'OT/Color/COLR/COLR.hh',
+  'OT/Color/CPAL/CPAL.hh',
+  'OT/Color/sbix/sbix.hh',
+  'OT/Color/svg/svg.hh',
+  'OT/glyf/glyf.hh',
+  'OT/glyf/glyf-helpers.hh',
+  'OT/glyf/loca.hh',
+  'OT/glyf/path-builder.hh',
+  'OT/glyf/Glyph.hh',
+  'OT/glyf/GlyphHeader.hh',
+  'OT/glyf/SimpleGlyph.hh',
+  'OT/glyf/CompositeGlyph.hh',
+  'OT/glyf/SubsetGlyph.hh',
+  'OT/Layout/types.hh',
+  'OT/Layout/Common/Coverage.hh',
+  'OT/Layout/Common/CoverageFormat1.hh',
+  'OT/Layout/Common/CoverageFormat2.hh',
+  'OT/Layout/Common/RangeRecord.hh',
+  'OT/Layout/GDEF/GDEF.hh',
+  'OT/Layout/GPOS/AnchorFormat1.hh',
+  'OT/Layout/GPOS/AnchorFormat2.hh',
+  'OT/Layout/GPOS/AnchorFormat3.hh',
+  'OT/Layout/GPOS/Anchor.hh',
+  'OT/Layout/GPOS/AnchorMatrix.hh',
+  'OT/Layout/GPOS/ChainContextPos.hh',
+  'OT/Layout/GPOS/Common.hh',
+  'OT/Layout/GPOS/ContextPos.hh',
+  'OT/Layout/GPOS/CursivePosFormat1.hh',
+  'OT/Layout/GPOS/CursivePos.hh',
+  'OT/Layout/GPOS/ExtensionPos.hh',
+  'OT/Layout/GPOS/GPOS.hh',
+  'OT/Layout/GPOS/LigatureArray.hh',
+  'OT/Layout/GPOS/MarkArray.hh',
+  'OT/Layout/GPOS/MarkBasePosFormat1.hh',
+  'OT/Layout/GPOS/MarkBasePos.hh',
+  'OT/Layout/GPOS/MarkLigPosFormat1.hh',
+  'OT/Layout/GPOS/MarkLigPos.hh',
+  'OT/Layout/GPOS/MarkMarkPosFormat1.hh',
+  'OT/Layout/GPOS/MarkMarkPos.hh',
+  'OT/Layout/GPOS/MarkRecord.hh',
+  'OT/Layout/GPOS/PairPosFormat1.hh',
+  'OT/Layout/GPOS/PairPosFormat2.hh',
+  'OT/Layout/GPOS/PairPos.hh',
+  'OT/Layout/GPOS/PairSet.hh',
+  'OT/Layout/GPOS/PairValueRecord.hh',
+  'OT/Layout/GPOS/PosLookup.hh',
+  'OT/Layout/GPOS/PosLookupSubTable.hh',
+  'OT/Layout/GPOS/SinglePosFormat1.hh',
+  'OT/Layout/GPOS/SinglePosFormat2.hh',
+  'OT/Layout/GPOS/SinglePos.hh',
+  'OT/Layout/GPOS/ValueFormat.hh',
+  'OT/Layout/GSUB/AlternateSet.hh',
+  'OT/Layout/GSUB/AlternateSubstFormat1.hh',
+  'OT/Layout/GSUB/AlternateSubst.hh',
+  'OT/Layout/GSUB/ChainContextSubst.hh',
+  'OT/Layout/GSUB/Common.hh',
+  'OT/Layout/GSUB/ContextSubst.hh',
+  'OT/Layout/GSUB/ExtensionSubst.hh',
+  'OT/Layout/GSUB/GSUB.hh',
+  'OT/Layout/GSUB/Ligature.hh',
+  'OT/Layout/GSUB/LigatureSet.hh',
+  'OT/Layout/GSUB/LigatureSubstFormat1.hh',
+  'OT/Layout/GSUB/LigatureSubst.hh',
+  'OT/Layout/GSUB/MultipleSubstFormat1.hh',
+  'OT/Layout/GSUB/MultipleSubst.hh',
+  'OT/Layout/GSUB/ReverseChainSingleSubstFormat1.hh',
+  'OT/Layout/GSUB/ReverseChainSingleSubst.hh',
+  'OT/Layout/GSUB/Sequence.hh',
+  'OT/Layout/GSUB/SingleSubstFormat1.hh',
+  'OT/Layout/GSUB/SingleSubstFormat2.hh',
+  'OT/Layout/GSUB/SingleSubst.hh',
+  'OT/Layout/GSUB/SubstLookup.hh',
+  'OT/Layout/GSUB/SubstLookupSubTable.hh',
+  'OT/name/name.hh',
   'hb-ot-layout-gsubgpos.hh',
   'hb-ot-layout-jstf-table.hh',
   'hb-ot-layout.cc',
@@ -113,30 +194,29 @@ hb_base_sources = files(
   'hb-ot-os2-unicode-ranges.hh',
   'hb-ot-post-macroman.hh',
   'hb-ot-post-table.hh',
-  'hb-ot-shape-complex-arabic-fallback.hh',
-  'hb-ot-shape-complex-arabic-joining-list.hh',
-  'hb-ot-shape-complex-arabic-table.hh',
-  'hb-ot-shape-complex-arabic-win1256.hh',
-  'hb-ot-shape-complex-arabic.cc',
-  'hb-ot-shape-complex-arabic.hh',
-  'hb-ot-shape-complex-default.cc',
-  'hb-ot-shape-complex-hangul.cc',
-  'hb-ot-shape-complex-hebrew.cc',
-  'hb-ot-shape-complex-indic-table.cc',
-  'hb-ot-shape-complex-indic.cc',
-  'hb-ot-shape-complex-indic.hh',
-  'hb-ot-shape-complex-khmer.cc',
-  'hb-ot-shape-complex-khmer.hh',
-  'hb-ot-shape-complex-myanmar.cc',
-  'hb-ot-shape-complex-myanmar.hh',
-  'hb-ot-shape-complex-syllabic.cc',
-  'hb-ot-shape-complex-syllabic.hh',
-  'hb-ot-shape-complex-thai.cc',
-  'hb-ot-shape-complex-use-table.hh',
-  'hb-ot-shape-complex-use.cc',
-  'hb-ot-shape-complex-vowel-constraints.cc',
-  'hb-ot-shape-complex-vowel-constraints.hh',
-  'hb-ot-shape-complex.hh',
+  'hb-ot-shaper-arabic-fallback.hh',
+  'hb-ot-shaper-arabic-joining-list.hh',
+  'hb-ot-shaper-arabic-pua.hh',
+  'hb-ot-shaper-arabic-table.hh',
+  'hb-ot-shaper-arabic-win1256.hh',
+  'hb-ot-shaper-arabic.cc',
+  'hb-ot-shaper-arabic.hh',
+  'hb-ot-shaper-default.cc',
+  'hb-ot-shaper-hangul.cc',
+  'hb-ot-shaper-hebrew.cc',
+  'hb-ot-shaper-indic-table.cc',
+  'hb-ot-shaper-indic.cc',
+  'hb-ot-shaper-indic.hh',
+  'hb-ot-shaper-khmer.cc',
+  'hb-ot-shaper-myanmar.cc',
+  'hb-ot-shaper-syllabic.cc',
+  'hb-ot-shaper-syllabic.hh',
+  'hb-ot-shaper-thai.cc',
+  'hb-ot-shaper-use-table.hh',
+  'hb-ot-shaper-use.cc',
+  'hb-ot-shaper-vowel-constraints.cc',
+  'hb-ot-shaper-vowel-constraints.hh',
+  'hb-ot-shaper.hh',
   'hb-ot-shape-fallback.cc',
   'hb-ot-shape-fallback.hh',
   'hb-ot-shape-normalize.cc',
@@ -148,6 +228,7 @@ hb_base_sources = files(
   'hb-ot-tag.cc',
   'hb-ot-var-avar-table.hh',
   'hb-ot-var-common.hh',
+  'hb-ot-var-cvar-table.hh',
   'hb-ot-var-fvar-table.hh',
   'hb-ot-var-gvar-table.hh',
   'hb-ot-var-hvar-table.hh',
@@ -182,21 +263,23 @@ hb_base_sources = files(
 
 hb_base_ragel_generated_sources = files(
   'hb-buffer-deserialize-json.hh',
-  'hb-buffer-deserialize-text.hh',
+  'hb-buffer-deserialize-text-glyphs.hh',
+  'hb-buffer-deserialize-text-unicode.hh',
   'hb-number-parser.hh',
-  'hb-ot-shape-complex-indic-machine.hh',
-  'hb-ot-shape-complex-khmer-machine.hh',
-  'hb-ot-shape-complex-myanmar-machine.hh',
-  'hb-ot-shape-complex-use-machine.hh',
+  'hb-ot-shaper-indic-machine.hh',
+  'hb-ot-shaper-khmer-machine.hh',
+  'hb-ot-shaper-myanmar-machine.hh',
+  'hb-ot-shaper-use-machine.hh',
 )
 hb_base_ragel_sources = [
   'hb-buffer-deserialize-json.rl',
-  'hb-buffer-deserialize-text.rl',
+  'hb-buffer-deserialize-text-glyphs.rl',
+  'hb-buffer-deserialize-text-unicode.rl',
   'hb-number-parser.rl',
-  'hb-ot-shape-complex-indic-machine.rl',
-  'hb-ot-shape-complex-khmer-machine.rl',
-  'hb-ot-shape-complex-myanmar-machine.rl',
-  'hb-ot-shape-complex-use-machine.rl',
+  'hb-ot-shaper-indic-machine.rl',
+  'hb-ot-shaper-khmer-machine.rl',
+  'hb-ot-shaper-myanmar-machine.rl',
+  'hb-ot-shaper-use-machine.rl',
 ]
 
 hb_base_headers = files(
@@ -205,8 +288,10 @@ hb_base_headers = files(
   'hb-blob.h',
   'hb-buffer.h',
   'hb-common.h',
+  'hb-cplusplus.hh',
   'hb-deprecated.h',
   'hb-draw.h',
+  'hb-paint.h',
   'hb-face.h',
   'hb-font.h',
   'hb-map.h',
@@ -232,7 +317,7 @@ hb_base_headers += hb_version_h
 
 # Optional Sources and Headers with external deps
 
-hb_ft_sources = files('hb-ft.cc')
+hb_ft_sources = files('hb-ft.cc', 'hb-ft-colr.hh')
 hb_ft_headers = files('hb-ft.h')
 
 hb_glib_sources = files('hb-glib.cc')
@@ -241,6 +326,19 @@ hb_glib_headers = files('hb-glib.h')
 hb_graphite2_sources = files('hb-graphite2.cc')
 hb_graphite2_headers = files('hb-graphite2.h')
 
+hb_wasm_sources = files(
+  'hb-wasm-api.cc',
+  'hb-wasm-api.hh',
+  'hb-wasm-api-blob.hh',
+  'hb-wasm-api-buffer.hh',
+  'hb-wasm-api-common.hh',
+  'hb-wasm-api-face.hh',
+  'hb-wasm-api-font.hh',
+  'hb-wasm-api-shape.hh',
+  'hb-wasm-shape.cc',
+)
+hb_wasm_headers = files()
+
 # System-dependent sources and headers
 
 hb_coretext_sources = files('hb-coretext.cc')
@@ -266,21 +364,35 @@ hb_subset_sources = files(
   'hb-ot-cff1-table.cc',
   'hb-ot-cff2-table.cc',
   'hb-static.cc',
+  'hb-subset-accelerator.hh',
   'hb-subset-cff-common.cc',
   'hb-subset-cff-common.hh',
   'hb-subset-cff1.cc',
-  'hb-subset-cff1.hh',
   'hb-subset-cff2.cc',
-  'hb-subset-cff2.hh',
   'hb-subset-input.cc',
   'hb-subset-input.hh',
+  'hb-subset-instancer-solver.hh',
+  'hb-subset-instancer-solver.cc',
   'hb-subset-plan.cc',
   'hb-subset-plan.hh',
+  'hb-subset-plan-member-list.hh',
+  'hb-subset-repacker.cc',
+  'graph/gsubgpos-context.cc',
+  'graph/gsubgpos-context.hh',
+  'graph/gsubgpos-graph.hh',
+  'graph/pairpos-graph.hh',
+  'graph/markbasepos-graph.hh',
+  'graph/coverage-graph.hh',
+  'graph/classdef-graph.hh',
+  'graph/split-helpers.hh',
   'hb-subset.cc',
   'hb-subset.hh',
 )
 
-hb_subset_headers = files('hb-subset.h')
+hb_subset_headers = files(
+  'hb-subset.h',
+  'hb-subset-repacker.h'
+)
 
 hb_gobject_sources = files(
   'hb-gobject-structs.cc'
@@ -298,7 +410,9 @@ if not has_ragel and get_option('ragel_subproject')
     has_ragel = true
 endif
 if not has_ragel
-  warning('You have to install ragel if you are going to develop HarfBuzz itself')
+  if not meson.is_subproject()
+    warning('You have to install ragel if you are going to develop HarfBuzz itself')
+  endif
 else
   ragel_helper = find_program('gen-ragel-artifacts.py')
   foreach rl : hb_base_ragel_sources
@@ -317,7 +431,7 @@ custom_target('harfbuzz.cc',
   output: 'harfbuzz.cc',
   input: hb_base_sources + hb_glib_sources + hb_ft_sources +
          hb_graphite2_sources + hb_uniscribe_sources + hb_gdi_sources +
-         hb_directwrite_sources + hb_coretext_sources,
+         hb_directwrite_sources + hb_coretext_sources + hb_wasm_sources,
   command: [find_program('gen-harfbuzzcc.py'),
             '@OUTPUT@', meson.current_source_dir(), '@INPUT@'],
 )
@@ -337,6 +451,17 @@ if conf.get('HAVE_FREETYPE', 0) == 1
   harfbuzz_deps += [freetype_dep]
 endif
 
+if conf.get('HAVE_GLIB', 0) == 1
+  hb_sources += hb_glib_sources
+  hb_headers += hb_glib_headers
+  harfbuzz_deps += [glib_dep]
+endif
+
+# We set those here to not include the sources below that are of no use to
+# GObject Introspection
+gir_sources = hb_sources + hb_gobject_sources
+gir_headers = hb_headers + hb_gobject_headers
+
 if conf.get('HAVE_GDI', 0) == 1
   hb_sources += hb_gdi_sources
   hb_headers += hb_gdi_headers
@@ -349,10 +474,11 @@ if conf.get('HAVE_GRAPHITE2', 0) == 1
   harfbuzz_deps += [graphite2_dep, graphite_dep]
 endif
 
-if conf.get('HAVE_GLIB', 0) == 1
-  hb_sources += hb_glib_sources
-  hb_headers += hb_glib_headers
-  harfbuzz_deps += [glib_dep]
+if conf.get('HAVE_WASM', 0) == 1
+  hb_sources += hb_wasm_sources
+  hb_headers += hb_wasm_headers
+  harfbuzz_deps += wasm_dep
+  #harfbuzz_deps += llvm_dep
 endif
 
 if conf.get('HAVE_UNISCRIBE', 0) == 1
@@ -363,7 +489,6 @@ endif
 if conf.get('HAVE_DIRECTWRITE', 0) == 1
   hb_sources += hb_directwrite_sources
   hb_headers += hb_directwrite_headers
-  harfbuzz_deps += directwrite_dep
   # hb-directwrite needs a C++ linker
   libharfbuzz_link_language = 'cpp'
 endif
@@ -376,23 +501,60 @@ endif
 
 have_icu = conf.get('HAVE_ICU', 0) == 1
 have_icu_builtin = conf.get('HAVE_ICU_BUILTIN', 0) == 1
-
 if have_icu and have_icu_builtin
   hb_sources += hb_icu_sources
   hb_headers += hb_icu_headers
   harfbuzz_deps += [icu_dep]
 endif
 
-# harfbuzz
-gen_def = find_program('gen-def.py')
+features = [
+  'CAIRO',
+  'CORETEXT',
+  'DIRECTWRITE',
+  'FREETYPE',
+  'GDI',
+  'GLIB',
+  'GOBJECT',
+  'GRAPHITE',
+  'ICU',
+  'UNISCRIBE',
+  'WASM',
+]
+
+hb_enabled_features = configuration_data()
+hb_supported_features = configuration_data()
+foreach feature : features
+  key = 'HB_HAS_@0@'.format(feature)
+  hb_enabled_features.set(key, conf.get('HAVE_@0@'.format(feature), false))
+  hb_supported_features.set(key, 1)
+endforeach
+
+# The enabled features. This file is installed.
+hb_features_h = configure_file(input: 'hb-features.h.in',
+                               output: 'hb-features.h',
+                               configuration: hb_enabled_features,
+                               install: true,
+                               install_dir: get_option('includedir') / meson.project_name())
+
+# This file is generated to convince gtk-doc to generate documentation for all
+# HB_HAS_* macros, whether they are enabled for the current build or not.
+# This file should not be installed.
+hb_supported_features_h = configure_file(input: 'hb-features.h.in',
+                               output: 'hb-supported-features.h',
+                               configuration: hb_supported_features,
+                               install: false)
 
-harfbuzz_def_command_args = [gen_def, '@OUTPUT@', '@INPUT@']
+# Base and default-included sources and headers
+
+gen_def = find_program('gen-def.py')
+gen_def_cmd = [gen_def, '@OUTPUT@', '@INPUT@']
 if get_option('experimental_api')
-  harfbuzz_def_command_args += '--experimental-api'
+  gen_def_cmd += '--experimental-api'
 endif
 
+# harfbuzz
 harfbuzz_def = custom_target('harfbuzz.def',
-    command: harfbuzz_def_command_args,
+    command: gen_def_cmd,
     input: hb_headers,
     output: 'harfbuzz.def')
 defs_list = [harfbuzz_def]
@@ -400,7 +562,7 @@ defs_list = [harfbuzz_def]
 version = '0.@0@.0'.format(hb_version_int)
 
 extra_hb_cpp_args = []
-if cpp.get_id() == 'msvc'
+if cpp.get_define('_MSC_FULL_VER') != ''
   if get_option('default_library') != 'static'
     extra_hb_cpp_args += '-DHB_DLL_EXPORT'
   endif
@@ -434,10 +596,11 @@ libharfbuzz_dep = declare_dependency(
   link_with: libharfbuzz,
   include_directories: incsrc,
   dependencies: harfbuzz_deps)
+meson.override_dependency('harfbuzz', libharfbuzz_dep)
 
 # harfbuzz-subset
 harfbuzz_subset_def = custom_target('harfbuzz-subset.def',
-    command: [gen_def, '@OUTPUT@', '@INPUT@'],
+    command: gen_def_cmd,
     input: hb_subset_headers,
     output: 'harfbuzz-subset.def')
 defs_list += [harfbuzz_subset_def]
@@ -454,29 +617,102 @@ libharfbuzz_subset = library('harfbuzz-subset', hb_subset_sources,
   link_language: 'c',
 )
 
+custom_target('harfbuzz-subset.cc',
+  build_by_default: true,
+  output: 'harfbuzz-subset.cc',
+  input: hb_base_sources + hb_subset_sources,
+  command: [find_program('gen-harfbuzzcc.py'),
+            '@OUTPUT@', meson.current_source_dir(), '@INPUT@'],
+)
+
 libharfbuzz_subset_dep = declare_dependency(
   link_with: libharfbuzz_subset,
   include_directories: incsrc,
   dependencies: [m_dep])
+meson.override_dependency('harfbuzz-subset', libharfbuzz_subset_dep)
+
+libharfbuzz_cairo_dep = null_dep
+if conf.get('HAVE_CAIRO', 0) == 1
+  hb_cairo_sources = [
+    'hb-cairo.cc',
+    'hb-cairo-utils.cc',
+    'hb-static.cc'
+  ]
+
+  hb_cairo_headers = [
+    'hb-cairo.h',
+  ]
+
+  cairo_dep = dependency('cairo')
+
+  libharfbuzz_cairo = library('harfbuzz-cairo', hb_cairo_sources,
+    include_directories: incconfig,
+    dependencies: [m_dep, cairo_dep],
+    link_with: [libharfbuzz],
+     cpp_args: cpp_args + extra_hb_cpp_args,
+    soversion: hb_so_version,
+    version: version,
+    install: true,
+    darwin_versions: darwin_versions,
+    link_language: 'c',
+  )
+
+  install_headers(hb_cairo_headers, subdir: meson.project_name())
+
+  libharfbuzz_cairo_dep = declare_dependency(
+    link_with: libharfbuzz_cairo,
+    include_directories: incsrc,
+    dependencies: [m_dep, cairo_dep])
+  meson.override_dependency('harfbuzz-cairo', libharfbuzz_cairo_dep)
+
+  harfbuzz_cairo_def = custom_target('harfbuzz-cairo.def',
+    command: gen_def_cmd,
+    input: hb_cairo_headers,
+    output: 'harfbuzz-cairo.def')
+  defs_list += [harfbuzz_cairo_def]
+
+  pkgmod.generate(libharfbuzz_cairo,
+    description: 'HarfBuzz cairo support',
+    requires: ['harfbuzz = @0@'.format(meson.project_version())],
+    subdirs: [meson.project_name()],
+    version: meson.project_version(),
+  )
+endif
 
 if get_option('tests').enabled()
   # TODO: MSVC gives the following,
   # error LNK2019: unresolved external symbol "unsigned __int64 const * const _hb_NullPool"
-  if cpp.get_id() != 'msvc'
+  if cpp.get_define('_MSC_FULL_VER') == ''
     noinst_programs = {
       'main': 'main.cc',
+      'test-algs': ['test-algs.cc', 'hb-static.cc'],
       'test-basics': 'test.cc',
+      'test-bimap': ['test-bimap.cc', 'hb-static.cc'],
       'test-buffer-serialize': 'test-buffer-serialize.cc',
+      'test-classdef-graph': ['graph/test-classdef-graph.cc', 'hb-static.cc', 'graph/gsubgpos-context.cc'],
+      'test-instancer-solver': ['test-subset-instancer-solver.cc', 'hb-subset-instancer-solver.cc', 'hb-static.cc'],
+      'test-iter': ['test-iter.cc', 'hb-static.cc'],
+      'test-map': ['test-map.cc', 'hb-static.cc'],
+      'test-multimap': ['test-multimap.cc', 'hb-static.cc'],
       'test-ot-meta': 'test-ot-meta.cc',
       'test-ot-name': 'test-ot-name.cc',
       'test-ot-glyphname': 'test-ot-glyphname.cc',
       'test-ot-gpos-size-params': 'test-gpos-size-params.cc',
+      'test-ot-gsub-get-alternates': 'test-gsub-get-alternates.cc',
       'test-ot-gsub-would-substitute': 'test-gsub-would-substitute.cc',
+      'test-priority-queue': ['test-priority-queue.cc', 'hb-static.cc'],
+      'test-repacker': ['test-repacker.cc', 'hb-static.cc', 'graph/gsubgpos-context.cc'],
+      'test-serialize': ['test-serialize.cc', 'hb-static.cc'],
+      'test-set': ['test-set.cc', 'hb-static.cc'],
+      'test-tuple-varstore': ['test-tuple-varstore.cc', 'hb-subset-instancer-solver.cc', 'hb-static.cc'],
+      'test-item-varstore': ['test-item-varstore.cc', 'hb-subset-instancer-solver.cc', 'hb-static.cc'],
+      'test-use-table': 'test-use-table.cc',
+      'test-vector': ['test-vector.cc', 'hb-static.cc'],
     }
     foreach name, source : noinst_programs
       executable(name, source,
         include_directories: incconfig,
-        cpp_args: cpp_args,
+        cpp_args: cpp_args + ['-UNDEBUG'],
         dependencies: libharfbuzz_dep,
         install: false,
       )
@@ -484,23 +720,14 @@ if get_option('tests').enabled()
   endif
 
   compiled_tests = {
-    'test-algs': ['test-algs.cc', 'hb-static.cc'],
     'test-array': ['test-array.cc'],
-    'test-iter': ['test-iter.cc', 'hb-static.cc'],
     'test-machinery': ['test-machinery.cc', 'hb-static.cc'],
-    'test-map': ['test-map.cc', 'hb-static.cc'],
     'test-number': ['test-number.cc', 'hb-number.cc'],
     'test-ot-tag': ['hb-ot-tag.cc'],
-    'test-priority-queue': ['test-priority-queue.cc', 'hb-static.cc'],
-    'test-repacker': ['test-repacker.cc', 'hb-static.cc'],
-    'test-set': ['test-set.cc', 'hb-static.cc'],
-    'test-serialize': ['test-serialize.cc', 'hb-static.cc'],
     'test-unicode-ranges': ['test-unicode-ranges.cc'],
-    'test-vector': ['test-vector.cc', 'hb-static.cc'],
-    'test-bimap': ['test-bimap.cc', 'hb-static.cc'],
   }
   foreach name, source : compiled_tests
-    if cpp.get_id() == 'msvc' and source.contains('hb-static.cc')
+    if cpp.get_argument_syntax() == 'msvc' and source.contains('hb-static.cc')
       # TODO: MSVC doesn't like tests having hb-static.cc, fix them
       continue
     endif
@@ -529,7 +756,7 @@ pkgmod.generate(libharfbuzz_subset,
 libharfbuzz_icu_dep = null_dep
 if have_icu and not have_icu_builtin
   harfbuzz_icu_def = custom_target('harfbuzz-icu.def',
-    command: [gen_def, '@OUTPUT@', '@INPUT@'],
+    command: gen_def_cmd,
     input: [hb_icu_headers],
     output: 'harfbuzz-icu.def')
   defs_list += [harfbuzz_icu_def]
@@ -551,6 +778,7 @@ if have_icu and not have_icu_builtin
     link_with: libharfbuzz_icu,
     include_directories: incsrc,
     dependencies: icu_dep)
+  meson.override_dependency('harfbuzz-icu', libharfbuzz_icu_dep)
 
   pkgmod.generate(libharfbuzz_icu,
     description: 'HarfBuzz text shaping library ICU integration',
@@ -564,17 +792,99 @@ endif
 
 have_gobject = conf.get('HAVE_GOBJECT', 0) == 1
 
+# This code (especially PACKAGE_INIT) kept similar to what CMake's own
+# configure_package_config_file() generates, see
+# https://cmake.org/cmake/help/latest/module/CMakePackageConfigHelpers.html#command:configure_package_config_file
+
 cmake_config = configuration_data()
-cmake_config.set('libdir', '${prefix}/@0@'.format(get_option('libdir')))
-cmake_config.set('includedir', '${prefix}/@0@'.format(get_option('includedir')))
-cmake_config.set('HB_LIBTOOL_VERSION_INFO', hb_libtool_version_info)
-cmake_config.set('have_gobject', '@0@'.format(have_gobject))
+cmake_config_dir = cmake_package_install_dir / 'harfbuzz'
+
+have_fs_relative_to = meson.version().version_compare('>=1.3.0')
+
+if not have_fs_relative_to
+  relative_to = find_program('relative_to.py')
+endif
+
+if have_fs_relative_to
+  cmake_package_prefix_dir = fs.relative_to(get_option('prefix'), get_option('prefix') / cmake_config_dir)
+else
+  cmake_package_prefix_dir = run_command(relative_to, get_option('prefix'), get_option('prefix') / cmake_config_dir, check: true).stdout().strip()
+endif
+
+cmake_package_prefix_dir = '${CMAKE_CURRENT_LIST_DIR}/@0@'.format(cmake_package_prefix_dir)
+
+# Make all the relevant paths relative to our prefix, so we can later append
+# them onto ${PACKAGE_PREFIX_DIR} to get the correct paths.
+
+cmake_install_includedir = get_option('includedir')
+
+if fs.is_absolute(cmake_install_includedir)
+  if have_fs_relative_to
+    cmake_install_includedir = fs.relative_to(cmake_install_includedir, get_option('prefix'))
+  else
+    cmake_install_includedir = run_command(relative_to, cmake_install_includedir, get_option('prefix'), check: true).stdout().strip()
+  endif
+endif
+
+cmake_install_libdir = get_option('libdir')
+
+if fs.is_absolute(cmake_install_libdir)
+  if have_fs_relative_to
+    cmake_install_libdir = fs.relative_to(cmake_install_libdir, get_option('prefix'))
+  else
+    cmake_install_libdir = run_command(relative_to, cmake_install_libdir, get_option('prefix'), check: true).stdout().strip()
+  endif
+endif
+
+cmake_config.set('PACKAGE_INIT', '''
+get_filename_component(PACKAGE_PREFIX_DIR "@0@" ABSOLUTE)
+
+macro(set_and_check _var _file)
+  set(${_var} "${_file}")
+  if(NOT EXISTS "${_file}")
+    message(FATAL_ERROR "File or directory ${_file} referenced by variable ${_var} does not exist !")
+  endif()
+endmacro()
+
+macro(check_required_components _NAME)
+  foreach(comp ${${_NAME}_FIND_COMPONENTS})
+    if(NOT ${_NAME}_${comp}_FOUND)
+      if(${_NAME}_FIND_REQUIRED_${comp})
+        set(${_NAME}_FOUND FALSE)
+      endif()
+    endif()
+  endforeach()
+endmacro()
+'''.format(cmake_package_prefix_dir))
+
+cmake_config.set('PACKAGE_CMAKE_INSTALL_INCLUDEDIR', '${PACKAGE_PREFIX_DIR}/@0@'.format(cmake_install_includedir))
+cmake_config.set('PACKAGE_CMAKE_INSTALL_LIBDIR', '${PACKAGE_PREFIX_DIR}/@0@'.format(cmake_install_libdir))
+cmake_config.set('PACKAGE_INCLUDE_INSTALL_DIR', '${PACKAGE_PREFIX_DIR}/@0@/@1@'.format(cmake_install_includedir, meson.project_name()))
+cmake_config.set('HB_HAVE_GOBJECT', have_gobject ? 'YES' : 'NO')
+cmake_config.set('HB_LIBRARY_TYPE', get_option('default_library') == 'static' ? 'STATIC' : 'SHARED')
+
+if get_option('default_library') == 'static'
+  cmake_config.set('HB_LIB_PREFIX', '${CMAKE_STATIC_LIBRARY_PREFIX}')
+  cmake_config.set('HB_LIB_SUFFIX', '${CMAKE_STATIC_LIBRARY_SUFFIX}')
+elif host_machine.system() == 'darwin'
+  cmake_config.set('HB_LIB_PREFIX', '${CMAKE_SHARED_LIBRARY_PREFIX}')
+  cmake_config.set('HB_LIB_SUFFIX', '.@0@.${CMAKE_SHARED_LIBRARY_SUFFIX}'.format(hb_so_version))
+elif host_machine.system() == 'windows'
+  cmake_config.set('HB_LIB_PREFIX', '${CMAKE_IMPORT_LIBRARY_PREFIX}')
+  cmake_config.set('HB_LIB_SUFFIX', '${CMAKE_IMPORT_LIBRARY_SUFFIX}')
+else
+  cmake_config.set('HB_LIB_PREFIX', '${CMAKE_SHARED_LIBRARY_PREFIX}')
+  cmake_config.set('HB_LIB_SUFFIX', '${CMAKE_SHARED_LIBRARY_SUFFIX}.@0@'.format(version))
+endif
+
 configure_file(input: 'harfbuzz-config.cmake.in',
   output: 'harfbuzz-config.cmake',
   configuration: cmake_config,
-  install_dir: get_option('libdir') / 'cmake' / 'harfbuzz',
+  install_dir: cmake_config_dir,
 )
 
+gobject_enums_c = []
+gobject_enums_h = []
 libharfbuzz_gobject_dep = null_dep
 if have_gobject
   gnome = import('gnome')
@@ -597,13 +907,13 @@ if have_gobject
     symbol_prefix: 'hb_gobject',
   )
 
-  enum_c = custom_target('hb-gobject-enums.cc',
+  gobject_enums_c = custom_target('hb-gobject-enums.cc',
     input: enums[0],
     output: 'hb-gobject-enums.cc',
     command: [find_program('fix_get_types.py'), '@INPUT@', '@OUTPUT@']
   )
 
-  enum_h = custom_target('hb-gobject-enums.h',
+  gobject_enums_h = custom_target('hb-gobject-enums.h',
     input: enums[1],
     output: 'hb-gobject-enums.h',
     command: [find_program('fix_get_types.py'), '@INPUT@', '@OUTPUT@'],
@@ -611,15 +921,15 @@ if have_gobject
     install_dir: get_option('prefix') / get_option('includedir') / meson.project_name(),
   )
 
-  hb_gobject_sources += [enum_c]
+  hb_gobject_sources += [gobject_enums_c]
 
   harfbuzz_gobject_def = custom_target('harfbuzz-gobject.def',
-    command: [gen_def, '@OUTPUT@', '@INPUT@'],
-    input: [hb_gobject_headers, enum_h],
+    command: gen_def_cmd,
+    input: [hb_gobject_headers, gobject_enums_h],
     output: 'harfbuzz-gobject.def')
   defs_list += [harfbuzz_gobject_def]
 
-  libharfbuzz_gobject = library('harfbuzz-gobject', [hb_gobject_sources, enum_c, enum_h],
+  libharfbuzz_gobject = library('harfbuzz-gobject', [hb_gobject_sources, gobject_enums_c, gobject_enums_h],
     include_directories: incconfig,
     dependencies: [glib_dep, gobject_dep],
     link_with: [libharfbuzz],
@@ -641,15 +951,15 @@ if have_gobject
 
   if build_gir
     conf.set('HAVE_INTROSPECTION', 1)
-    hb_gen_files_gir = gnome.generate_gir(libharfbuzz_gobject,
-      sources: [hb_headers, hb_sources, hb_gobject_headers, hb_gobject_sources, enum_h],
+    hb_gen_files_gir = gnome.generate_gir([libharfbuzz_gobject, libharfbuzz],
+      sources: [gir_headers, gir_sources, gobject_enums_h],
       dependencies: libharfbuzz_dep,
       namespace: 'HarfBuzz',
       nsversion: '0.0',
       identifier_prefix: 'hb_',
       symbol_prefix: ['hb', 'hb_gobject'],
-      includes: ['GObject-2.0'],
-      export_packages: ['harfbuzz-gobject'],
+      includes: ['GObject-2.0', 'freetype2-2.0'],
+      export_packages: ['harfbuzz-gobject', 'harfbuzz'],
       header: 'hb-gobject.h',
       install: true,
       extra_args:  ['--cflags-begin',
@@ -664,6 +974,7 @@ if have_gobject
     include_directories: incsrc,
     sources: build_gir ? hb_gen_files_gir : hb_gobject_sources,
     dependencies: [glib_dep, gobject_dep])
+  meson.override_dependency('harfbuzz-gobject', libharfbuzz_gobject_dep)
 
   pkgmod.generate(libharfbuzz_gobject,
     description: 'HarfBuzz text shaping library GObject integration',
@@ -689,6 +1000,7 @@ if get_option('tests').enabled()
 
   env = environment()
   env.set('srcdir', meson.current_source_dir())
+  env.set('base_srcdir', meson.source_root())
   env.set('builddir', meson.current_build_dir())
   env.set('libs', meson.current_build_dir()) # TODO: Merge this with builddir after autotools removal
   HBSOURCES = []
@@ -702,8 +1014,11 @@ if get_option('tests').enabled()
   endforeach
   env.set('HBHEADERS', ' '.join(HBHEADERS))
 
-  if cpp.get_id() != 'msvc' and not meson.is_cross_build() # ensure the local tools are usable
-    dist_check_script += ['check-libstdc++', 'check-static-inits', 'check-symbols']
+  if cpp.get_argument_syntax() != 'msvc' and not meson.is_cross_build() # ensure the local tools are usable
+    dist_check_script += ['check-static-inits', 'check-symbols']
+    if get_option('wasm').disabled()
+      dist_check_script += ['check-libstdc++']
+    endif
   endif
 
   foreach name : dist_check_script