xref: /aosp_15_r20/external/harfbuzz_ng/src/meson.build (revision 2d1272b857b1f7575e6e246373e1cb218663db8a)
1fs = import('fs')
2
3hb_version_h = configure_file(
4               command: [find_program('gen-hb-version.py'), meson.project_version(), '@OUTPUT@', '@INPUT@'],
5               input: 'hb-version.h.in',
6               output: 'hb-version.h',
7               install: true,
8               install_dir: get_option('includedir') / meson.project_name())
9
10# Base and default-included sources and headers
11hb_base_sources = files(
12  'hb-aat-layout-ankr-table.hh',
13  'hb-aat-layout-bsln-table.hh',
14  'hb-aat-layout-common.hh',
15  'hb-aat-layout-feat-table.hh',
16  'hb-aat-layout-just-table.hh',
17  'hb-aat-layout-kerx-table.hh',
18  'hb-aat-layout-morx-table.hh',
19  'hb-aat-layout-opbd-table.hh',
20  'hb-aat-layout-trak-table.hh',
21  'hb-aat-layout.cc',
22  'hb-aat-layout.hh',
23  'hb-aat-ltag-table.hh',
24  'hb-aat-map.cc',
25  'hb-aat-map.hh',
26  'hb-algs.hh',
27  'hb-array.hh',
28  'hb-atomic.hh',
29  'hb-bimap.hh',
30  'hb-bit-page.hh',
31  'hb-blob.cc',
32  'hb-blob.hh',
33  'hb-buffer-serialize.cc',
34  'hb-buffer-verify.cc',
35  'hb-buffer.cc',
36  'hb-buffer.hh',
37  'hb-cache.hh',
38  'hb-cff-interp-common.hh',
39  'hb-cff-interp-cs-common.hh',
40  'hb-cff-interp-dict-common.hh',
41  'hb-cff1-interp-cs.hh',
42  'hb-cff2-interp-cs.hh',
43  'hb-common.cc',
44  'hb-config.hh',
45  'hb-debug.hh',
46  'hb-dispatch.hh',
47  'hb-draw.cc',
48  'hb-draw.hh',
49  'hb-geometry.hh',
50  'hb-paint.cc',
51  'hb-paint.hh',
52  'hb-paint-extents.cc',
53  'hb-paint-extents.hh',
54  'hb-face.cc',
55  'hb-face.hh',
56  'hb-face-builder.cc',
57  'hb-fallback-shape.cc',
58  'hb-font.cc',
59  'hb-font.hh',
60  'hb-iter.hh',
61  'hb-kern.hh',
62  'hb-limits.hh',
63  'hb-machinery.hh',
64  'hb-map.cc',
65  'hb-map.hh',
66  'hb-meta.hh',
67  'hb-ms-feature-ranges.hh',
68  'hb-multimap.hh',
69  'hb-mutex.hh',
70  'hb-null.hh',
71  'hb-number.cc',
72  'hb-number.hh',
73  'hb-object.hh',
74  'hb-open-file.hh',
75  'hb-open-type.hh',
76  'hb-ot-cff-common.hh',
77  'hb-ot-cff1-std-str.hh',
78  'hb-ot-cff1-table.cc',
79  'hb-ot-cff1-table.hh',
80  'hb-ot-cff2-table.cc',
81  'hb-ot-cff2-table.hh',
82  'hb-ot-cmap-table.hh',
83  'hb-ot-color.cc',
84  'hb-ot-face-table-list.hh',
85  'hb-ot-face.cc',
86  'hb-ot-face.hh',
87  'hb-ot-font.cc',
88  'hb-ot-gasp-table.hh',
89  'hb-ot-glyf-table.hh',
90  'hb-ot-hdmx-table.hh',
91  'hb-ot-head-table.hh',
92  'hb-ot-hhea-table.hh',
93  'hb-ot-hmtx-table.hh',
94  'hb-ot-kern-table.hh',
95  'hb-ot-layout-base-table.hh',
96  'hb-ot-layout-common.hh',
97  'hb-ot-layout-gdef-table.hh',
98  'hb-ot-layout-gpos-table.hh',
99  'hb-ot-layout-gsub-table.hh',
100  'hb-outline.hh',
101  'hb-outline.cc',
102  'OT/Color/CBDT/CBDT.hh',
103  'OT/Color/COLR/COLR.hh',
104  'OT/Color/CPAL/CPAL.hh',
105  'OT/Color/sbix/sbix.hh',
106  'OT/Color/svg/svg.hh',
107  'OT/glyf/glyf.hh',
108  'OT/glyf/glyf-helpers.hh',
109  'OT/glyf/loca.hh',
110  'OT/glyf/path-builder.hh',
111  'OT/glyf/Glyph.hh',
112  'OT/glyf/GlyphHeader.hh',
113  'OT/glyf/SimpleGlyph.hh',
114  'OT/glyf/CompositeGlyph.hh',
115  'OT/glyf/SubsetGlyph.hh',
116  'OT/Layout/types.hh',
117  'OT/Layout/Common/Coverage.hh',
118  'OT/Layout/Common/CoverageFormat1.hh',
119  'OT/Layout/Common/CoverageFormat2.hh',
120  'OT/Layout/Common/RangeRecord.hh',
121  'OT/Layout/GDEF/GDEF.hh',
122  'OT/Layout/GPOS/AnchorFormat1.hh',
123  'OT/Layout/GPOS/AnchorFormat2.hh',
124  'OT/Layout/GPOS/AnchorFormat3.hh',
125  'OT/Layout/GPOS/Anchor.hh',
126  'OT/Layout/GPOS/AnchorMatrix.hh',
127  'OT/Layout/GPOS/ChainContextPos.hh',
128  'OT/Layout/GPOS/Common.hh',
129  'OT/Layout/GPOS/ContextPos.hh',
130  'OT/Layout/GPOS/CursivePosFormat1.hh',
131  'OT/Layout/GPOS/CursivePos.hh',
132  'OT/Layout/GPOS/ExtensionPos.hh',
133  'OT/Layout/GPOS/GPOS.hh',
134  'OT/Layout/GPOS/LigatureArray.hh',
135  'OT/Layout/GPOS/MarkArray.hh',
136  'OT/Layout/GPOS/MarkBasePosFormat1.hh',
137  'OT/Layout/GPOS/MarkBasePos.hh',
138  'OT/Layout/GPOS/MarkLigPosFormat1.hh',
139  'OT/Layout/GPOS/MarkLigPos.hh',
140  'OT/Layout/GPOS/MarkMarkPosFormat1.hh',
141  'OT/Layout/GPOS/MarkMarkPos.hh',
142  'OT/Layout/GPOS/MarkRecord.hh',
143  'OT/Layout/GPOS/PairPosFormat1.hh',
144  'OT/Layout/GPOS/PairPosFormat2.hh',
145  'OT/Layout/GPOS/PairPos.hh',
146  'OT/Layout/GPOS/PairSet.hh',
147  'OT/Layout/GPOS/PairValueRecord.hh',
148  'OT/Layout/GPOS/PosLookup.hh',
149  'OT/Layout/GPOS/PosLookupSubTable.hh',
150  'OT/Layout/GPOS/SinglePosFormat1.hh',
151  'OT/Layout/GPOS/SinglePosFormat2.hh',
152  'OT/Layout/GPOS/SinglePos.hh',
153  'OT/Layout/GPOS/ValueFormat.hh',
154  'OT/Layout/GSUB/AlternateSet.hh',
155  'OT/Layout/GSUB/AlternateSubstFormat1.hh',
156  'OT/Layout/GSUB/AlternateSubst.hh',
157  'OT/Layout/GSUB/ChainContextSubst.hh',
158  'OT/Layout/GSUB/Common.hh',
159  'OT/Layout/GSUB/ContextSubst.hh',
160  'OT/Layout/GSUB/ExtensionSubst.hh',
161  'OT/Layout/GSUB/GSUB.hh',
162  'OT/Layout/GSUB/Ligature.hh',
163  'OT/Layout/GSUB/LigatureSet.hh',
164  'OT/Layout/GSUB/LigatureSubstFormat1.hh',
165  'OT/Layout/GSUB/LigatureSubst.hh',
166  'OT/Layout/GSUB/MultipleSubstFormat1.hh',
167  'OT/Layout/GSUB/MultipleSubst.hh',
168  'OT/Layout/GSUB/ReverseChainSingleSubstFormat1.hh',
169  'OT/Layout/GSUB/ReverseChainSingleSubst.hh',
170  'OT/Layout/GSUB/Sequence.hh',
171  'OT/Layout/GSUB/SingleSubstFormat1.hh',
172  'OT/Layout/GSUB/SingleSubstFormat2.hh',
173  'OT/Layout/GSUB/SingleSubst.hh',
174  'OT/Layout/GSUB/SubstLookup.hh',
175  'OT/Layout/GSUB/SubstLookupSubTable.hh',
176  'OT/name/name.hh',
177  'OT/Var/VARC/coord-setter.hh',
178  'OT/Var/VARC/VARC.cc',
179  'OT/Var/VARC/VARC.hh',
180  'hb-ot-layout-gsubgpos.hh',
181  'hb-ot-layout-jstf-table.hh',
182  'hb-ot-layout.cc',
183  'hb-ot-layout.hh',
184  'hb-ot-map.cc',
185  'hb-ot-map.hh',
186  'hb-ot-math-table.hh',
187  'hb-ot-math.cc',
188  'hb-ot-maxp-table.hh',
189  'hb-ot-meta-table.hh',
190  'hb-ot-meta.cc',
191  'hb-ot-metrics.cc',
192  'hb-ot-metrics.hh',
193  'hb-ot-name-language-static.hh',
194  'hb-ot-name-language.hh',
195  'hb-ot-name-table.hh',
196  'hb-ot-name.cc',
197  'hb-ot-os2-table.hh',
198  'hb-ot-os2-unicode-ranges.hh',
199  'hb-ot-post-macroman.hh',
200  'hb-ot-post-table.hh',
201  'hb-ot-shaper-arabic-fallback.hh',
202  'hb-ot-shaper-arabic-joining-list.hh',
203  'hb-ot-shaper-arabic-pua.hh',
204  'hb-ot-shaper-arabic-table.hh',
205  'hb-ot-shaper-arabic-win1256.hh',
206  'hb-ot-shaper-arabic.cc',
207  'hb-ot-shaper-arabic.hh',
208  'hb-ot-shaper-default.cc',
209  'hb-ot-shaper-hangul.cc',
210  'hb-ot-shaper-hebrew.cc',
211  'hb-ot-shaper-indic-table.cc',
212  'hb-ot-shaper-indic.cc',
213  'hb-ot-shaper-indic.hh',
214  'hb-ot-shaper-khmer.cc',
215  'hb-ot-shaper-myanmar.cc',
216  'hb-ot-shaper-syllabic.cc',
217  'hb-ot-shaper-syllabic.hh',
218  'hb-ot-shaper-thai.cc',
219  'hb-ot-shaper-use-table.hh',
220  'hb-ot-shaper-use.cc',
221  'hb-ot-shaper-vowel-constraints.cc',
222  'hb-ot-shaper-vowel-constraints.hh',
223  'hb-ot-shaper.hh',
224  'hb-ot-shape-fallback.cc',
225  'hb-ot-shape-fallback.hh',
226  'hb-ot-shape-normalize.cc',
227  'hb-ot-shape-normalize.hh',
228  'hb-ot-shape.cc',
229  'hb-ot-shape.hh',
230  'hb-ot-stat-table.hh',
231  'hb-ot-tag-table.hh',
232  'hb-ot-tag.cc',
233  'hb-ot-var-avar-table.hh',
234  'hb-ot-var-common.hh',
235  'hb-ot-var-cvar-table.hh',
236  'hb-ot-var-fvar-table.hh',
237  'hb-ot-var-gvar-table.hh',
238  'hb-ot-var-hvar-table.hh',
239  'hb-ot-var-mvar-table.hh',
240  'hb-ot-var-varc-table.hh',
241  'hb-ot-var.cc',
242  'hb-ot-vorg-table.hh',
243  'hb-pool.hh',
244  'hb-sanitize.hh',
245  'hb-serialize.hh',
246  'hb-set-digest.hh',
247  'hb-set.cc',
248  'hb-set.hh',
249  'hb-shape-plan.cc',
250  'hb-shape-plan.hh',
251  'hb-shape.cc',
252  'hb-shaper-impl.hh',
253  'hb-shaper-list.hh',
254  'hb-shaper.cc',
255  'hb-shaper.hh',
256  'hb-static.cc',
257  'hb-string-array.hh',
258  'hb-style.cc',
259  'hb-ucd-table.hh',
260  'hb-ucd.cc',
261  'hb-unicode-emoji-table.hh',
262  'hb-unicode.cc',
263  'hb-unicode.hh',
264  'hb-utf.hh',
265  'hb-vector.hh',
266  'hb.hh',
267)
268
269hb_base_ragel_generated_sources = files(
270  'hb-buffer-deserialize-json.hh',
271  'hb-buffer-deserialize-text-glyphs.hh',
272  'hb-buffer-deserialize-text-unicode.hh',
273  'hb-number-parser.hh',
274  'hb-ot-shaper-indic-machine.hh',
275  'hb-ot-shaper-khmer-machine.hh',
276  'hb-ot-shaper-myanmar-machine.hh',
277  'hb-ot-shaper-use-machine.hh',
278)
279hb_base_ragel_sources = [
280  'hb-buffer-deserialize-json.rl',
281  'hb-buffer-deserialize-text-glyphs.rl',
282  'hb-buffer-deserialize-text-unicode.rl',
283  'hb-number-parser.rl',
284  'hb-ot-shaper-indic-machine.rl',
285  'hb-ot-shaper-khmer-machine.rl',
286  'hb-ot-shaper-myanmar-machine.rl',
287  'hb-ot-shaper-use-machine.rl',
288]
289
290hb_base_headers = files(
291  'hb-aat-layout.h',
292  'hb-aat.h',
293  'hb-blob.h',
294  'hb-buffer.h',
295  'hb-common.h',
296  'hb-cplusplus.hh',
297  'hb-deprecated.h',
298  'hb-draw.h',
299  'hb-paint.h',
300  'hb-face.h',
301  'hb-font.h',
302  'hb-map.h',
303  'hb-ot-color.h',
304  'hb-ot-deprecated.h',
305  'hb-ot-font.h',
306  'hb-ot-layout.h',
307  'hb-ot-math.h',
308  'hb-ot-meta.h',
309  'hb-ot-metrics.h',
310  'hb-ot-name.h',
311  'hb-ot-shape.h',
312  'hb-ot-var.h',
313  'hb-ot.h',
314  'hb-set.h',
315  'hb-shape-plan.h',
316  'hb-shape.h',
317  'hb-style.h',
318  'hb-unicode.h',
319  'hb.h',
320)
321hb_base_headers += hb_version_h
322
323# Optional Sources and Headers with external deps
324
325hb_ft_sources = files('hb-ft.cc', 'hb-ft-colr.hh')
326hb_ft_headers = files('hb-ft.h')
327
328hb_glib_sources = files('hb-glib.cc')
329hb_glib_headers = files('hb-glib.h')
330
331hb_graphite2_sources = files('hb-graphite2.cc')
332hb_graphite2_headers = files('hb-graphite2.h')
333
334hb_wasm_sources = files(
335  'hb-wasm-api.cc',
336  'hb-wasm-api.hh',
337  'hb-wasm-api-blob.hh',
338  'hb-wasm-api-buffer.hh',
339  'hb-wasm-api-common.hh',
340  'hb-wasm-api-face.hh',
341  'hb-wasm-api-font.hh',
342  'hb-wasm-api-shape.hh',
343  'hb-wasm-shape.cc',
344)
345hb_wasm_headers = files()
346
347# System-dependent sources and headers
348
349hb_coretext_sources = files('hb-coretext-shape.cc', 'hb-coretext-font.cc')
350hb_coretext_headers = files('hb-coretext.h')
351
352hb_directwrite_sources = files('hb-directwrite.cc')
353hb_directwrite_headers = files('hb-directwrite.h')
354
355hb_gdi_sources = files('hb-gdi.cc')
356hb_gdi_headers = files('hb-gdi.h')
357
358hb_uniscribe_sources = files('hb-uniscribe.cc')
359hb_uniscribe_headers = files('hb-uniscribe.h')
360
361# Sources for libharfbuzz-gobject and libharfbuzz-icu
362hb_icu_sources = files('hb-icu.cc')
363hb_icu_headers = files('hb-icu.h')
364
365# Sources for libharfbuzz-subset
366hb_subset_sources = files(
367  'hb-number.cc',
368  'hb-number.hh',
369  'hb-ot-cff1-table.cc',
370  'hb-ot-cff2-table.cc',
371  'hb-static.cc',
372  'hb-subset-accelerator.hh',
373  'hb-subset-cff-common.cc',
374  'hb-subset-cff-common.hh',
375  'hb-subset-cff1.cc',
376  'hb-subset-cff2.cc',
377  'hb-subset-input.cc',
378  'hb-subset-input.hh',
379  'hb-subset-instancer-iup.hh',
380  'hb-subset-instancer-iup.cc',
381  'hb-subset-instancer-solver.hh',
382  'hb-subset-instancer-solver.cc',
383  'hb-subset-plan.cc',
384  'hb-subset-plan.hh',
385  'hb-subset-plan-member-list.hh',
386  'hb-subset-repacker.cc',
387  'graph/gsubgpos-context.cc',
388  'graph/gsubgpos-context.hh',
389  'graph/gsubgpos-graph.hh',
390  'graph/pairpos-graph.hh',
391  'graph/markbasepos-graph.hh',
392  'graph/coverage-graph.hh',
393  'graph/classdef-graph.hh',
394  'graph/split-helpers.hh',
395  'hb-subset.cc',
396  'hb-subset.hh',
397)
398
399hb_subset_headers = files(
400  'hb-subset.h',
401  'hb-subset-repacker.h'
402)
403
404hb_gobject_sources = files(
405  'hb-gobject-structs.cc'
406)
407
408hb_gobject_headers = files(
409  'hb-gobject.h',
410  'hb-gobject-structs.h',
411)
412
413ragel = find_program('ragel', version: '6.10', required: false)
414has_ragel = ragel.found()
415if not has_ragel and get_option('ragel_subproject')
416    ragel = subproject('ragel').get_variable('ragel')
417    has_ragel = true
418endif
419if not has_ragel
420  if not meson.is_subproject()
421    warning('You have to install ragel if you are going to develop HarfBuzz itself')
422  endif
423else
424  ragel_helper = find_program('gen-ragel-artifacts.py')
425  foreach rl : hb_base_ragel_sources
426    hh = rl.split('.')[0] + '.hh'
427    custom_target('@0@'.format(hh),
428      build_by_default: true,
429      input: rl,
430      output: hh,
431      command: [ragel_helper, ragel, '@OUTPUT@', meson.current_source_dir(), '@INPUT@'],
432    )
433  endforeach
434endif
435
436custom_target('harfbuzz.cc',
437  build_by_default: true,
438  output: 'harfbuzz.cc',
439  input: hb_base_sources + hb_glib_sources + hb_ft_sources +
440         hb_graphite2_sources + hb_uniscribe_sources + hb_gdi_sources +
441         hb_directwrite_sources + hb_coretext_sources + hb_wasm_sources,
442  command: [find_program('gen-harfbuzzcc.py'),
443            '@OUTPUT@', meson.current_source_dir(), '@INPUT@'],
444)
445
446incsrc = include_directories('.')
447
448hb_sources = hb_base_sources + hb_base_ragel_generated_sources
449hb_headers = hb_base_headers
450
451harfbuzz_deps = [thread_dep, m_dep] + harfbuzz_extra_deps
452
453if get_option('with_libstdcxx')
454  chosen_linker = 'cpp'
455else
456  # Use a C linker, not C++; Don't link to libstdc++
457  chosen_linker = 'c'
458endif
459libharfbuzz_link_language = chosen_linker
460
461if conf.get('HAVE_FREETYPE', 0) == 1
462  hb_sources += hb_ft_sources
463  hb_headers += hb_ft_headers
464  harfbuzz_deps += [freetype_dep]
465endif
466
467if conf.get('HAVE_GLIB', 0) == 1
468  hb_sources += hb_glib_sources
469  hb_headers += hb_glib_headers
470  harfbuzz_deps += [glib_dep]
471endif
472
473# We set those here to not include the sources below that are of no use to
474# GObject Introspection
475gir_sources = hb_sources + hb_gobject_sources
476gir_headers = hb_headers + hb_gobject_headers
477
478if conf.get('HAVE_GDI', 0) == 1
479  hb_sources += hb_gdi_sources
480  hb_headers += hb_gdi_headers
481  harfbuzz_deps += gdi_uniscribe_deps
482endif
483
484if conf.get('HAVE_GRAPHITE2', 0) == 1
485  hb_sources += hb_graphite2_sources
486  hb_headers += hb_graphite2_headers
487  harfbuzz_deps += [graphite2_dep, graphite_dep]
488endif
489
490if conf.get('HAVE_WASM', 0) == 1
491  hb_sources += hb_wasm_sources
492  hb_headers += hb_wasm_headers
493  harfbuzz_deps += wasm_dep
494  #harfbuzz_deps += llvm_dep
495endif
496
497if conf.get('HAVE_UNISCRIBE', 0) == 1
498  hb_sources += hb_uniscribe_sources
499  hb_headers += hb_uniscribe_headers
500endif
501
502if conf.get('HAVE_DIRECTWRITE', 0) == 1
503  hb_sources += hb_directwrite_sources
504  hb_headers += hb_directwrite_headers
505  # hb-directwrite needs a C++ linker
506  libharfbuzz_link_language = 'cpp'
507endif
508
509if conf.get('HAVE_CORETEXT', 0) == 1
510  hb_sources += hb_coretext_sources
511  hb_headers += hb_coretext_headers
512  harfbuzz_deps += coretext_deps
513endif
514
515have_icu = conf.get('HAVE_ICU', 0) == 1
516have_icu_builtin = conf.get('HAVE_ICU_BUILTIN', 0) == 1
517if have_icu and have_icu_builtin
518  hb_sources += hb_icu_sources
519  hb_headers += hb_icu_headers
520  harfbuzz_deps += [icu_dep]
521endif
522
523features = [
524  'CAIRO',
525  'CORETEXT',
526  'DIRECTWRITE',
527  'FREETYPE',
528  'GDI',
529  'GLIB',
530  'GOBJECT',
531  'GRAPHITE',
532  'ICU',
533  'UNISCRIBE',
534  'WASM',
535]
536
537hb_enabled_features = configuration_data()
538hb_supported_features = configuration_data()
539foreach feature : features
540  key = 'HB_HAS_@0@'.format(feature)
541  hb_enabled_features.set(key, conf.get('HAVE_@0@'.format(feature), false))
542  hb_supported_features.set(key, 1)
543endforeach
544
545# The enabled features. This file is installed.
546hb_features_h = configure_file(input: 'hb-features.h.in',
547                               output: 'hb-features.h',
548                               configuration: hb_enabled_features,
549                               install: true,
550                               install_dir: get_option('includedir') / meson.project_name())
551
552# This file is generated to convince gtk-doc to generate documentation for all
553# HB_HAS_* macros, whether they are enabled for the current build or not.
554# This file should not be installed.
555hb_supported_features_h = configure_file(input: 'hb-features.h.in',
556                               output: 'hb-supported-features.h',
557                               configuration: hb_supported_features,
558                               install: false)
559
560
561# Base and default-included sources and headers
562gen_def = find_program('gen-def.py')
563gen_def_cmd = [gen_def, '@OUTPUT@', '@INPUT@']
564if get_option('experimental_api')
565  gen_def_cmd += '--experimental-api'
566endif
567
568# harfbuzz
569harfbuzz_def = custom_target('harfbuzz.def',
570    command: gen_def_cmd,
571    input: hb_headers,
572    output: 'harfbuzz.def')
573defs_list = [harfbuzz_def]
574
575version = '0.@[email protected]'.format(hb_version_int)
576
577extra_hb_cpp_args = []
578if cpp.get_define('_MSC_FULL_VER') != ''
579  if get_option('default_library') != 'static'
580    extra_hb_cpp_args += '-DHB_DLL_EXPORT'
581  endif
582  hb_so_version = ''
583else
584  hb_so_version = '0'
585endif
586
587if get_option('fuzzer_ldflags') != ''
588  extra_hb_cpp_args += ['-DHB_CUSTOM_MALLOC']
589  hb_sources += 'failing-alloc.c'
590  hb_subset_sources += 'failing-alloc.c'
591  hb_icu_sources += 'failing-alloc.c'
592  hb_gobject_sources += 'failing-alloc.c'
593endif
594
595darwin_versions = [hb_version_int, '@[email protected]'.format(hb_version_int)]
596
597libharfbuzz = library('harfbuzz', hb_sources,
598  include_directories: incconfig,
599  dependencies: harfbuzz_deps,
600  cpp_args: cpp_args + extra_hb_cpp_args,
601  soversion: hb_so_version,
602  version: version,
603  install: true,
604  darwin_versions: darwin_versions,
605  link_language: libharfbuzz_link_language,
606)
607
608libharfbuzz_dep = declare_dependency(
609  link_with: libharfbuzz,
610  include_directories: incsrc,
611  dependencies: harfbuzz_deps)
612meson.override_dependency('harfbuzz', libharfbuzz_dep)
613
614# harfbuzz-subset
615harfbuzz_subset_def = custom_target('harfbuzz-subset.def',
616    command: gen_def_cmd,
617    input: hb_subset_headers,
618    output: 'harfbuzz-subset.def')
619defs_list += [harfbuzz_subset_def]
620
621libharfbuzz_subset = library('harfbuzz-subset', hb_subset_sources,
622  include_directories: incconfig,
623  dependencies: [m_dep],
624  link_with: [libharfbuzz],
625  cpp_args: cpp_args + extra_hb_cpp_args,
626  soversion: hb_so_version,
627  version: version,
628  install: true,
629  darwin_versions: darwin_versions,
630  link_language: chosen_linker,
631)
632
633custom_target('harfbuzz-subset.cc',
634  build_by_default: true,
635  output: 'harfbuzz-subset.cc',
636  input: hb_base_sources + hb_subset_sources,
637  command: [find_program('gen-harfbuzzcc.py'),
638            '@OUTPUT@', meson.current_source_dir(), '@INPUT@'],
639)
640
641libharfbuzz_subset_dep = declare_dependency(
642  link_with: libharfbuzz_subset,
643  include_directories: incsrc,
644  dependencies: [m_dep])
645meson.override_dependency('harfbuzz-subset', libharfbuzz_subset_dep)
646
647libharfbuzz_cairo_dep = null_dep
648if conf.get('HAVE_CAIRO', 0) == 1
649  hb_cairo_sources = [
650    'hb-cairo.cc',
651    'hb-cairo-utils.cc',
652    'hb-static.cc'
653  ]
654
655  hb_cairo_headers = [
656    'hb-cairo.h',
657  ]
658
659  cairo_dep = dependency('cairo')
660
661  libharfbuzz_cairo = library('harfbuzz-cairo', hb_cairo_sources,
662    include_directories: incconfig,
663    dependencies: [m_dep, cairo_dep],
664    link_with: [libharfbuzz],
665     cpp_args: cpp_args + extra_hb_cpp_args,
666    soversion: hb_so_version,
667    version: version,
668    install: true,
669    darwin_versions: darwin_versions,
670    link_language: chosen_linker,
671  )
672
673  install_headers(hb_cairo_headers, subdir: meson.project_name())
674
675  libharfbuzz_cairo_dep = declare_dependency(
676    link_with: libharfbuzz_cairo,
677    include_directories: incsrc,
678    dependencies: [m_dep, cairo_dep])
679  meson.override_dependency('harfbuzz-cairo', libharfbuzz_cairo_dep)
680
681  harfbuzz_cairo_def = custom_target('harfbuzz-cairo.def',
682    command: gen_def_cmd,
683    input: hb_cairo_headers,
684    output: 'harfbuzz-cairo.def')
685  defs_list += [harfbuzz_cairo_def]
686
687  pkgmod.generate(libharfbuzz_cairo,
688    description: 'HarfBuzz cairo support',
689    requires: ['harfbuzz = @0@'.format(meson.project_version())],
690    subdirs: [meson.project_name()],
691    version: meson.project_version(),
692  )
693endif
694
695if get_option('tests').enabled()
696  # TODO: Microsoft LINK gives the following because extern, non dllexport
697  # symbols can only be used when linking against a static library
698  # error LNK2019: unresolved external symbol "unsigned __int64 const * const _hb_NullPool"
699  if cpp.get_define('_MSC_FULL_VER') == ''
700    noinst_programs = {
701      'main': 'main.cc',
702      'test-basics': 'test.cc',
703      'test-buffer-serialize': 'test-buffer-serialize.cc',
704      'test-ot-meta': 'test-ot-meta.cc',
705      'test-ot-name': 'test-ot-name.cc',
706      'test-ot-glyphname': 'test-ot-glyphname.cc',
707      'test-ot-gpos-size-params': 'test-gpos-size-params.cc',
708      'test-ot-gsub-get-alternates': 'test-gsub-get-alternates.cc',
709      'test-ot-gsub-would-substitute': 'test-gsub-would-substitute.cc',
710      'test-use-table': 'test-use-table.cc',
711    }
712    foreach name, source : noinst_programs
713      executable(name, source,
714        include_directories: incconfig,
715        cpp_args: cpp_args + ['-UNDEBUG'],
716        dependencies: libharfbuzz_dep,
717        install: false,
718      )
719    endforeach
720  endif
721
722  compiled_tests = {
723    'test-algs': ['test-algs.cc', 'hb-static.cc'],
724    'test-array': ['test-array.cc'],
725    'test-bimap': ['test-bimap.cc', 'hb-static.cc'],
726    'test-cff': ['test-cff.cc', 'hb-static.cc'],
727    'test-classdef-graph': ['graph/test-classdef-graph.cc', 'hb-static.cc', 'graph/gsubgpos-context.cc'],
728    'test-iter': ['test-iter.cc', 'hb-static.cc'],
729    'test-machinery': ['test-machinery.cc', 'hb-static.cc'],
730    'test-map': ['test-map.cc', 'hb-static.cc'],
731    'test-multimap': ['test-multimap.cc', 'hb-static.cc'],
732    'test-number': ['test-number.cc', 'hb-number.cc'],
733    'test-ot-tag': ['hb-ot-tag.cc'],
734    'test-set': ['test-set.cc', 'hb-static.cc'],
735    'test-serialize': ['test-serialize.cc', 'hb-static.cc'],
736    'test-vector': ['test-vector.cc', 'hb-static.cc'],
737    'test-repacker': ['test-repacker.cc', 'hb-static.cc', 'graph/gsubgpos-context.cc'],
738    'test-instancer-solver': ['test-subset-instancer-solver.cc', 'hb-subset-instancer-solver.cc', 'hb-static.cc'],
739    'test-priority-queue': ['test-priority-queue.cc', 'hb-static.cc'],
740    'test-tuple-varstore': ['test-tuple-varstore.cc', 'hb-subset-instancer-solver.cc', 'hb-subset-instancer-iup.cc', 'hb-static.cc'],
741    'test-item-varstore': ['test-item-varstore.cc', 'hb-subset-instancer-solver.cc', 'hb-subset-instancer-iup.cc', 'hb-static.cc'],
742    'test-unicode-ranges': ['test-unicode-ranges.cc'],
743  }
744  foreach name, source : compiled_tests
745    if cpp.get_define('_MSC_FULL_VER') != '' and source.contains('hb-static.cc')
746      # TODO: Microsoft compilers cannot link tests using hb-static.cc, fix them
747      continue
748    endif
749    test(name, executable(name, source,
750      include_directories: incconfig,
751      cpp_args: cpp_args + ['-DMAIN', '-UNDEBUG'],
752      dependencies: libharfbuzz_dep,
753      install: false,
754    ), suite: ['src'])
755  endforeach
756endif
757
758pkgmod.generate(libharfbuzz,
759  description: 'HarfBuzz text shaping library',
760  subdirs: [meson.project_name()],
761  version: meson.project_version(),
762)
763
764pkgmod.generate(libharfbuzz_subset,
765  description: 'HarfBuzz font subsetter',
766  requires: ['harfbuzz = @0@'.format(meson.project_version())],
767  subdirs: [meson.project_name()],
768  version: meson.project_version(),
769)
770
771libharfbuzz_icu_dep = null_dep
772if have_icu and not have_icu_builtin
773  harfbuzz_icu_def = custom_target('harfbuzz-icu.def',
774    command: gen_def_cmd,
775    input: [hb_icu_headers],
776    output: 'harfbuzz-icu.def')
777  defs_list += [harfbuzz_icu_def]
778
779  libharfbuzz_icu = library('harfbuzz-icu', [hb_icu_sources, hb_icu_headers],
780    include_directories: incconfig,
781    dependencies: icu_dep,
782    link_with: [libharfbuzz],
783    cpp_args: cpp_args + extra_hb_cpp_args,
784    soversion: hb_so_version,
785    version: version,
786    install: true,
787    darwin_versions: darwin_versions,
788    # ICU links to stdc++ anyway so the default linker is good
789    # link_language: chosen_linker,
790  )
791
792  libharfbuzz_icu_dep = declare_dependency(
793    link_with: libharfbuzz_icu,
794    include_directories: incsrc,
795    dependencies: icu_dep)
796  meson.override_dependency('harfbuzz-icu', libharfbuzz_icu_dep)
797
798  pkgmod.generate(libharfbuzz_icu,
799    description: 'HarfBuzz text shaping library ICU integration',
800    requires: ['harfbuzz = @0@'.format(meson.project_version())],
801    subdirs: [meson.project_name()],
802    version: meson.project_version(),
803  )
804
805  install_headers(hb_icu_headers, subdir: meson.project_name())
806endif
807
808have_gobject = conf.get('HAVE_GOBJECT', 0) == 1
809
810# This code (especially PACKAGE_INIT) kept similar to what CMake's own
811# configure_package_config_file() generates, see
812# https://cmake.org/cmake/help/latest/module/CMakePackageConfigHelpers.html#command:configure_package_config_file
813
814cmake_config = configuration_data()
815cmake_config_dir = cmake_package_install_dir / 'harfbuzz'
816
817have_fs_relative_to = meson.version().version_compare('>=1.3.0')
818
819if not have_fs_relative_to
820  relative_to = find_program('relative_to.py')
821endif
822
823if have_fs_relative_to
824  cmake_package_prefix_dir = fs.relative_to(get_option('prefix'), get_option('prefix') / cmake_config_dir)
825else
826  cmake_package_prefix_dir = run_command(relative_to, get_option('prefix'), get_option('prefix') / cmake_config_dir, check: true).stdout().strip()
827endif
828
829cmake_package_prefix_dir = '${CMAKE_CURRENT_LIST_DIR}/@0@'.format(cmake_package_prefix_dir)
830
831# Make all the relevant paths relative to our prefix, so we can later append
832# them onto ${PACKAGE_PREFIX_DIR} to get the correct paths.
833
834cmake_install_includedir = get_option('includedir')
835
836if fs.is_absolute(cmake_install_includedir)
837  if have_fs_relative_to
838    cmake_install_includedir = fs.relative_to(cmake_install_includedir, get_option('prefix'))
839  else
840    cmake_install_includedir = run_command(relative_to, cmake_install_includedir, get_option('prefix'), check: true).stdout().strip()
841  endif
842endif
843
844cmake_install_libdir = get_option('libdir')
845
846if fs.is_absolute(cmake_install_libdir)
847  if have_fs_relative_to
848    cmake_install_libdir = fs.relative_to(cmake_install_libdir, get_option('prefix'))
849  else
850    cmake_install_libdir = run_command(relative_to, cmake_install_libdir, get_option('prefix'), check: true).stdout().strip()
851  endif
852endif
853
854cmake_config.set('PACKAGE_INIT', '''
855get_filename_component(PACKAGE_PREFIX_DIR "@0@" ABSOLUTE)
856
857macro(set_and_check _var _file)
858  set(${_var} "${_file}")
859  if(NOT EXISTS "${_file}")
860    message(FATAL_ERROR "File or directory ${_file} referenced by variable ${_var} does not exist !")
861  endif()
862endmacro()
863
864macro(check_required_components _NAME)
865  foreach(comp ${${_NAME}_FIND_COMPONENTS})
866    if(NOT ${_NAME}_${comp}_FOUND)
867      if(${_NAME}_FIND_REQUIRED_${comp})
868        set(${_NAME}_FOUND FALSE)
869      endif()
870    endif()
871  endforeach()
872endmacro()
873'''.format(cmake_package_prefix_dir))
874
875cmake_config.set('PACKAGE_CMAKE_INSTALL_INCLUDEDIR', '${PACKAGE_PREFIX_DIR}/@0@'.format(cmake_install_includedir))
876cmake_config.set('PACKAGE_CMAKE_INSTALL_LIBDIR', '${PACKAGE_PREFIX_DIR}/@0@'.format(cmake_install_libdir))
877cmake_config.set('PACKAGE_INCLUDE_INSTALL_DIR', '${PACKAGE_PREFIX_DIR}/@0@/@1@'.format(cmake_install_includedir, meson.project_name()))
878cmake_config.set('HB_HAVE_GOBJECT', have_gobject ? 'YES' : 'NO')
879cmake_config.set('HB_LIBRARY_TYPE', get_option('default_library') == 'static' ? 'STATIC' : 'SHARED')
880
881if get_option('default_library') == 'static'
882  cmake_config.set('HB_LIB_PREFIX', '${CMAKE_STATIC_LIBRARY_PREFIX}')
883  cmake_config.set('HB_LIB_SUFFIX', '${CMAKE_STATIC_LIBRARY_SUFFIX}')
884elif host_machine.system() == 'darwin'
885  cmake_config.set('HB_LIB_PREFIX', '${CMAKE_SHARED_LIBRARY_PREFIX}')
886  cmake_config.set('HB_LIB_SUFFIX', '.@0@${CMAKE_SHARED_LIBRARY_SUFFIX}'.format(hb_so_version))
887elif host_machine.system() == 'windows'
888  cmake_config.set('HB_LIB_PREFIX', '${CMAKE_IMPORT_LIBRARY_PREFIX}')
889  cmake_config.set('HB_LIB_SUFFIX', '${CMAKE_IMPORT_LIBRARY_SUFFIX}')
890else
891  cmake_config.set('HB_LIB_PREFIX', '${CMAKE_SHARED_LIBRARY_PREFIX}')
892  cmake_config.set('HB_LIB_SUFFIX', '${CMAKE_SHARED_LIBRARY_SUFFIX}.@0@'.format(version))
893endif
894
895configure_file(input: 'harfbuzz-config.cmake.in',
896  output: 'harfbuzz-config.cmake',
897  configuration: cmake_config,
898  install_dir: cmake_config_dir,
899)
900
901gobject_enums_c = []
902gobject_enums_h = []
903libharfbuzz_gobject_dep = null_dep
904if have_gobject
905  gnome = import('gnome')
906
907  h_templ = configure_file(
908    input: 'hb-gobject-enums.h.tmpl',
909    output: 'hb-gobject-enums-tmp.h.tmpl',
910    copy: true)
911
912  cc_templ = configure_file(
913    input: 'hb-gobject-enums.cc.tmpl',
914    output: 'hb-gobject-enums-tmp.cc.tmpl',
915    copy: true)
916
917  enums = gnome.mkenums('hb-gobject',
918    sources: hb_headers,
919    h_template: h_templ,
920    c_template: cc_templ,
921    identifier_prefix: 'hb_',
922    symbol_prefix: 'hb_gobject',
923  )
924
925  gobject_enums_c = custom_target('hb-gobject-enums.cc',
926    input: enums[0],
927    output: 'hb-gobject-enums.cc',
928    command: [find_program('fix_get_types.py'), '@INPUT@', '@OUTPUT@']
929  )
930
931  gobject_enums_h = custom_target('hb-gobject-enums.h',
932    input: enums[1],
933    output: 'hb-gobject-enums.h',
934    command: [find_program('fix_get_types.py'), '@INPUT@', '@OUTPUT@'],
935    install: true,
936    install_dir: get_option('prefix') / get_option('includedir') / meson.project_name(),
937  )
938
939  hb_gobject_sources += [gobject_enums_c]
940
941  harfbuzz_gobject_def = custom_target('harfbuzz-gobject.def',
942    command: gen_def_cmd,
943    input: [hb_gobject_headers, gobject_enums_h],
944    output: 'harfbuzz-gobject.def')
945  defs_list += [harfbuzz_gobject_def]
946
947  libharfbuzz_gobject = library('harfbuzz-gobject', [hb_gobject_sources, gobject_enums_c, gobject_enums_h],
948    include_directories: incconfig,
949    dependencies: [glib_dep, gobject_dep],
950    link_with: [libharfbuzz],
951    cpp_args: cpp_args + extra_hb_cpp_args,
952    soversion: hb_so_version,
953    version: version,
954    install: true,
955    darwin_versions: darwin_versions,
956    link_language: chosen_linker,
957  )
958
959  gir = find_program('g-ir-scanner', required: get_option('introspection'))
960  build_gir = gir.found() and (not meson.is_cross_build() or get_option('introspection').enabled())
961
962  build_gir = build_gir and get_option('default_library') != 'static'
963  if not build_gir and get_option('introspection').enabled()
964    error('Introspection support is requested but the default library option should be shared or both')
965  endif
966
967  if build_gir
968    conf.set('HAVE_INTROSPECTION', 1)
969    hb_gen_files_gir = gnome.generate_gir([libharfbuzz_gobject, libharfbuzz],
970      sources: [gir_headers, gir_sources, gobject_enums_h],
971      dependencies: libharfbuzz_dep,
972      namespace: 'HarfBuzz',
973      nsversion: '0.0',
974      identifier_prefix: 'hb_',
975      symbol_prefix: ['hb', 'hb_gobject'],
976      includes: ['GObject-2.0', 'freetype2-2.0'],
977      export_packages: ['harfbuzz-gobject', 'harfbuzz'],
978      header: 'hb-gobject.h',
979      install: true,
980      extra_args:  ['--cflags-begin',
981                    '-DHB_NO_SINGLE_HEADER_ERROR',
982                    '-DHAVE_GOBJECT',
983                    '-DHB_EXTERN=',
984                    '--cflags-end'])
985  endif
986
987  libharfbuzz_gobject_dep = declare_dependency(
988    link_with: libharfbuzz_gobject,
989    include_directories: incsrc,
990    sources: build_gir ? hb_gen_files_gir : hb_gobject_sources,
991    dependencies: [glib_dep, gobject_dep])
992  meson.override_dependency('harfbuzz-gobject', libharfbuzz_gobject_dep)
993
994  pkgmod.generate(libharfbuzz_gobject,
995    description: 'HarfBuzz text shaping library GObject integration',
996    requires: ['harfbuzz = @0@'.format(meson.project_version()), 'glib-2.0', 'gobject-2.0'],
997    subdirs: [meson.project_name()],
998    version: meson.project_version(),
999  )
1000
1001  install_headers(hb_gobject_headers, subdir: meson.project_name())
1002else
1003  if get_option('introspection').enabled()
1004    error('introspection requires gobject to be enabled')
1005  endif
1006endif
1007
1008if get_option('tests').enabled()
1009  dist_check_script = [
1010    'check-c-linkage-decls',
1011    'check-externs',
1012    'check-header-guards',
1013    'check-includes',
1014  ]
1015
1016  env = environment()
1017  env.set('srcdir', meson.current_source_dir())
1018  env.set('base_srcdir', meson.source_root())
1019  env.set('builddir', meson.current_build_dir())
1020  env.set('libs', meson.current_build_dir()) # TODO: Merge this with builddir after autotools removal
1021  HBSOURCES = []
1022  foreach f : hb_sources
1023    HBSOURCES += '@0@'.format(f)
1024  endforeach
1025  env.set('HBSOURCES', ' '.join(HBSOURCES))
1026  HBHEADERS = []
1027  foreach f : hb_headers
1028    HBHEADERS += '@0@'.format(f)
1029  endforeach
1030  env.set('HBHEADERS', ' '.join(HBHEADERS))
1031
1032  if cpp.get_argument_syntax() != 'msvc' and not meson.is_cross_build() # ensure the local tools are usable
1033    dist_check_script += ['check-static-inits', 'check-symbols']
1034    if get_option('wasm').disabled() and not get_option('with_libstdcxx')
1035      dist_check_script += ['check-libstdc++']
1036    endif
1037  endif
1038
1039  foreach name : dist_check_script
1040    test(name, find_program(name + '.py'),
1041      env: env,
1042      depends: name == 'check-symbols' ? defs_list : [],
1043      suite: ['src'],
1044    )
1045  endforeach
1046endif
1047
1048install_headers(hb_headers + hb_subset_headers, subdir: meson.project_name())
1049