From 920efc0ef72eb4bb5dce02ee9f9adcdd5fdf8f7a Mon Sep 17 00:00:00 2001 From: Mathieu Duponchelle Date: Thu, 17 May 2018 01:28:53 +0200 Subject: [PATCH] Add Meson build definitions Fixes #490 http://mesonbuild.com --- meson-cc-tests/intel-atomic-primitives-test.c | 6 + meson-cc-tests/solaris-atomic-operations.c | 8 + meson.build | 189 ++++++++++++++ src/fix_get_types.py | 15 ++ src/meson.build | 237 ++++++++++++++++++ test/api/meson.build | 51 ++++ test/fuzzing/meson.build | 32 +++ test/meson.build | 4 + test/shaping/meson.build | 110 ++++++++ test/subset/meson.build | 20 ++ util/meson.build | 51 ++++ 11 files changed, 723 insertions(+) create mode 100644 meson-cc-tests/intel-atomic-primitives-test.c create mode 100644 meson-cc-tests/solaris-atomic-operations.c create mode 100644 meson.build create mode 100644 src/fix_get_types.py create mode 100644 src/meson.build create mode 100644 test/api/meson.build create mode 100644 test/fuzzing/meson.build create mode 100644 test/meson.build create mode 100644 test/shaping/meson.build create mode 100644 test/subset/meson.build create mode 100644 util/meson.build diff --git a/meson-cc-tests/intel-atomic-primitives-test.c b/meson-cc-tests/intel-atomic-primitives-test.c new file mode 100644 index 000000000..a5c804091 --- /dev/null +++ b/meson-cc-tests/intel-atomic-primitives-test.c @@ -0,0 +1,6 @@ +void memory_barrier (void) { __sync_synchronize (); } +int atomic_add (int *i) { return __sync_fetch_and_add (i, 1); } +int mutex_trylock (int *m) { return __sync_lock_test_and_set (m, 1); } +void mutex_unlock (int *m) { __sync_lock_release (m); } + +int main(void) { return 0;} diff --git a/meson-cc-tests/solaris-atomic-operations.c b/meson-cc-tests/solaris-atomic-operations.c new file mode 100644 index 000000000..fae0acd87 --- /dev/null +++ b/meson-cc-tests/solaris-atomic-operations.c @@ -0,0 +1,8 @@ +#include +/* This requires Solaris Studio 12.2 or newer: */ +#include +void memory_barrier (void) { __machine_rw_barrier (); } +int atomic_add (volatile unsigned *i) { return atomic_add_int_nv (i, 1); } +void *atomic_ptr_cmpxchg (volatile void **target, void *cmp, void *newval) { return atomic_cas_ptr (target, cmp, newval); } + +int main(void) { return 0; } diff --git a/meson.build b/meson.build new file mode 100644 index 000000000..f1aa94b3a --- /dev/null +++ b/meson.build @@ -0,0 +1,189 @@ +project('harfbuzz', 'c', 'cpp', + version: '1.7.6') + +cpp = meson.get_compiler('cpp') + +python3 = import('python').find_installation('python3') + +check_headers = [ + ['unistd.h'], + ['sys/mman.h'], + ['xlocale.h'], + ['stdbool.h'], +] + +check_funcs = [ + ['atexit'], + ['mprotect'], + ['sysconf'], + ['getpagesize'], + ['mmap'], + ['isatty'], + ['newlocale'], + ['strtod_l'], + ['round'], +] + +check_freetype_funcs = [ + ['FT_Get_Var_Blend_Coordinates'], + ['FT_Set_Var_Blend_Coordinates'], + ['FT_Done_MM_Var'], +] + +check_alignofs = [ + ['struct{char;}', {'conf-name': 'ALIGNOF_STRUCT_CHAR__'}] +] + +freetype_dep = dependency('freetype2', required: false) +glib_dep = dependency('glib-2.0', required: false) +gobject_dep = dependency('gobject-2.0', required: false) +cairo_dep = dependency('cairo', required: false) +cairo_ft_dep = dependency('cairo-ft', required: false) +fontconfig_dep = dependency('fontconfig', required: false) +graphite2_dep = dependency('graphite2', required: false) +icu_dep = dependency('icu-uc', required: false) +m_dep = cpp.find_library('m') + +deps = [m_dep] + +conf = configuration_data() +incbase = include_directories('.') +cpp_args = ['-DHAVE_CONFIG_H'] + +warn_cflags = [ + '-Wno-non-virtual-dtor', +] + +cpp_args += cpp.get_supported_arguments(warn_cflags) + +if glib_dep.found() + conf.set('HAVE_GLIB', 1) + deps += [glib_dep] +endif + +if gobject_dep.found() + conf.set('HAVE_GOBJECT', 1) + deps += [gobject_dep] +endif + +if cairo_dep.found() + conf.set('HAVE_CAIRO', 1) + deps += [cairo_dep] +endif + +if cairo_ft_dep.found() + conf.set('HAVE_CAIRO_FT', 1) + deps += [cairo_ft_dep] +endif + +if graphite2_dep.found() + conf.set('HAVE_GRAPHITE2', 1) + deps += [graphite2_dep] +endif + +if icu_dep.found() + conf.set('HAVE_ICU', 1) + conf.set('HAVE_ICU_BUILTIN', 1) + deps += [icu_dep] +endif + +if freetype_dep.found() + conf.set('HAVE_FREETYPE', 1) + deps += [freetype_dep] + + if freetype_dep.type_name() == 'internal' + foreach func: check_freetype_funcs + name = func[0] + conf.set('HAVE_@0@'.format(name.to_upper()), 1) + endforeach + else + check_funcs += check_freetype_funcs + endif +endif + +if fontconfig_dep.found() + conf.set('HAVE_FONTCONFIG', 1) + deps += [fontconfig_dep] +endif + +if host_machine.system() != 'windows' + thread_dep = dependency('threads', required: false) + + if thread_dep.found() + conf.set('HAVE_PTHREAD', 1) + deps += [thread_dep] + else + check_headers += ['sched.h'] + check_funcs += ['sched_yield', {'link_with': 'rt'}] + endif +endif + +conf.set('HAVE_OT', true) +conf.set('HAVE_FALLBACK', true) +conf.set_quoted('PACKAGE_NAME', 'HarfBuzz') +conf.set_quoted('PACKAGE_VERSION', meson.project_version()) + +foreach check : check_headers + name = check[0] + + if cpp.has_header(name) + conf.set('HAVE_@0@'.format(name.to_upper().underscorify()), 1) + endif +endforeach + +foreach check : check_funcs + name = check[0] + opts = check.length() > 1 ? check[1] : {} + link_withs = opts.get('link_with', []) + extra_deps = [] + found = true + + # First try without linking + + found = cpp.has_function(name) + + if not found and link_withs.length() > 0 + found = true + + foreach link_with : link_withs + dep = cpp.find_library(link_with, required: false) + if dep.found() + extra_deps += dep + else + found = false + endif + endforeach + + if found + found = cpp.has_function(name, dependencies: extra_deps) + endif + endif + + if found + deps += extra_deps + conf.set('HAVE_@0@'.format(name.to_upper()), 1) + endif +endforeach + +foreach check : check_alignofs + type = check[0] + opts = check.length() > 1 ? check[1] : {} + + conf_name = opts.get('conf-name', 'ALIGNOF_@0@'.format(type.to_upper())) + + conf.set(conf_name, cpp.alignment(type)) +endforeach + +if cpp.links(files('meson-cc-tests/intel-atomic-primitives-test.c'), name: 'Intel atomics') + conf.set('HAVE_INTEL_ATOMIC_PRIMITIVES', 1) +endif + +if cpp.links(files('meson-cc-tests/solaris-atomic-operations.c'), name: 'Solaris atomic ops') + conf.set('HAVE_SOLARIS_ATOMIC_OPS', 1) +endif + +subdir('src') +subdir('util') +subdir('test') + +configure_file(output: 'config.h', configuration: conf) diff --git a/src/fix_get_types.py b/src/fix_get_types.py new file mode 100644 index 000000000..f5df60522 --- /dev/null +++ b/src/fix_get_types.py @@ -0,0 +1,15 @@ +import re +import argparse + +if __name__=='__main__': + parser = argparse.ArgumentParser() + parser.add_argument('input') + parser.add_argument('output') + args = parser.parse_args() + + with open(args.input, 'r') as inp: + with open(args.output, 'w') as out: + for l in inp.readlines(): + l = re.sub('_t_get_type', '_get_type', l) + l = re.sub('_T \(', ' (', l) + out.write(l) diff --git a/src/meson.build b/src/meson.build new file mode 100644 index 000000000..0a0577c45 --- /dev/null +++ b/src/meson.build @@ -0,0 +1,237 @@ +hb_base_sources = [ + 'hb-blob.cc', + 'hb-buffer-serialize.cc', + 'hb-buffer.cc', + 'hb-common.cc', + 'hb-face.cc', + 'hb-font.cc', + 'hb-ot-tag.cc', + 'hb-set.cc', + 'hb-shape.cc', + 'hb-shape-plan.cc', + 'hb-shaper.cc', + 'hb-unicode.cc', + 'hb-warning.cc', +] + +hb_base_headers = [ + 'hb.h', + 'hb-blob.h', + 'hb-buffer.h', + 'hb-common.h', + 'hb-deprecated.h', + 'hb-face.h', + 'hb-font.h', + 'hb-set.h', + 'hb-shape.h', + 'hb-shape-plan.h', + 'hb-unicode.h', + 'hb-version.h', +] + +hb_base_ragel_sources = [ + 'hb-buffer-deserialize-json.rl', + 'hb-buffer-deserialize-text.rl', +] + +hb_fallback_sources = [ + 'hb-fallback-shape.cc', +] + +hb_ot_sources = [ + 'hb-aat-layout.cc', + 'hb-ot-font.cc', + 'hb-ot-layout.cc', + 'hb-ot-color.cc', + 'hb-ot-map.cc', + 'hb-ot-math.cc', + 'hb-ot-shape.cc', + 'hb-ot-shape-complex-arabic.cc', + 'hb-ot-shape-complex-default.cc', + 'hb-ot-shape-complex-hangul.cc', + 'hb-ot-shape-complex-hebrew.cc', + 'hb-ot-shape-complex-indic.cc', + 'hb-ot-shape-complex-indic-table.cc', + 'hb-ot-shape-complex-khmer.cc', + 'hb-ot-shape-complex-myanmar.cc', + 'hb-ot-shape-complex-thai.cc', + 'hb-ot-shape-complex-tibetan.cc', + 'hb-ot-shape-complex-use.cc', + 'hb-ot-shape-complex-use-table.cc', + 'hb-ot-shape-normalize.cc', + 'hb-ot-shape-fallback.cc', + 'hb-ot-var.cc', +] + +hb_ot_headers = [ + 'hb-ot.h', + 'hb-ot-font.h', + 'hb-ot-layout.h', + 'hb-ot-math.h', + 'hb-ot-shape.h', + 'hb-ot-tag.h', + 'hb-ot-var.h', +] + +hb_ot_ragel_sources = [ + '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_ft_sources = [ + 'hb-ft.cc', +] + +hb_ft_headers = [ + 'hb-ft.h', +] + +hb_glib_sources = [ + 'hb-glib.cc', +] + +hb_glib_headers = [ + 'hb-glib.h', +] + +hb_graphite2_sources = [ + 'hb-graphite2.cc', +] + +hb_graphite2_headers = [ + 'hb-graphite2.h', +] + +hb_coretext_sources = [ + 'hb-coretext.cc', +] + +hb_directwrite_sources = [ + 'hb-directwrite.cc', +] + +hb_uniscribe_sources = [ + 'hb-uniscribe.cc', +] + +hb_ucdn_sources = [ + 'hb-ucdn.cc', + 'hb-ucdn/ucdn.c', +] + +hb_icu_sources = [ + 'hb-icu.cc', +] + +hb_icu_headers = [ + 'hb-icu.h', +] + +hb_subset_sources = [ + 'hb-subset.cc', + 'hb-subset-glyf.cc', + 'hb-subset-input.cc', + 'hb-subset-plan.cc', +] + +hb_subset_headers = [ + 'hb-subset.h', + 'hb-subset-glyf.hh', + 'hb-subset-plan.hh', + 'hb-subset-private.hh', +] + +hb_gobject_sources = [ + 'hb-gobject-structs.cc' +] + +hb_gobject_headers = [ + 'hb-gobject.h', + 'hb-gobject-structs.h', +] + +conf.set('HAVE_UCDN', 1) + +incucdn = include_directories('hb-ucdn') +incsrc = include_directories('.') + +hb_sources = hb_base_sources + hb_fallback_sources + hb_ot_sources + hb_ucdn_sources +hb_headers = hb_base_headers + hb_ot_headers + hb_ucdn_sources + +if conf.get('HAVE_FREETYPE', 0) == 1 + hb_sources += hb_ft_sources + hb_headers += hb_ft_headers +endif + +if conf.get('HAVE_GRAPHITE2', 0) == 1 + hb_sources += hb_graphite2_sources + hb_headers += hb_graphite2_headers +endif + +if conf.get('HAVE_GLIB', 0) == 1 + hb_sources += hb_glib_sources + hb_headers += hb_glib_headers +endif + +if conf.get('HAVE_ICU', 0) == 1 + hb_sources += hb_icu_sources + hb_headers += hb_icu_headers +endif + +libharfbuzz = library('harfbuzz', hb_sources, + include_directories: [incbase, incucdn], + dependencies: deps, + cpp_args: cpp_args, +) + +libharfbuzz_subset = library('harfbuzz-subset', hb_subset_sources, + include_directories: incbase, + link_with: [libharfbuzz], + cpp_args: cpp_args) + +if conf.get('HAVE_GOBJECT', 0) == 1 + gnome = import('gnome') + + h_templ = configure_file( + input: 'hb-gobject-enums.h.tmpl', + output: 'hb-gobject-enums-tmp.h.tmpl', + configuration: configuration_data(), + format: 'cmake') + + cc_templ = configure_file( + input: 'hb-gobject-enums.cc.tmpl', + output: 'hb-gobject-enums-tmp.cc.tmpl', + configuration: configuration_data(), + format: 'cmake') + + enums = gnome.mkenums('hb-gobject', + sources: hb_headers, + h_template: h_templ, + c_template: cc_templ, + identifier_prefix: 'hb_', + symbol_prefix: 'hb_gobject', + ) + + enum_c = custom_target('hb-gobject-enums.cc', + input: enums[0], + output: 'hb-gobject-enums.cc', + command: [python3, files('fix_get_types.py')[0], '@INPUT@', '@OUTPUT@'] + ) + + enum_h = custom_target('hb-gobject-enums.h', + input: enums[1], + output: 'hb-gobject-enums.h', + command: [python3, files('fix_get_types.py')[0], '@INPUT@', '@OUTPUT@'] + ) + + hb_gobject_sources += [enum_c] + hb_gobject_headers += [enum_h] + + libharfbuzz_gobject = library('harfbuzz-gobject', [hb_gobject_sources, enum_c, enum_h], + include_directories: incbase, + dependencies: deps, + link_with: [libharfbuzz], + cpp_args: cpp_args) +endif diff --git a/test/api/meson.build b/test/api/meson.build new file mode 100644 index 000000000..27ea026fe --- /dev/null +++ b/test/api/meson.build @@ -0,0 +1,51 @@ +tests = [ + ['test-blob.c'], + ['test-buffer.c'], + ['test-common.c'], + ['test-font.c'], + ['test-object.c'], + ['test-set.c'], + ['test-shape.c'], + ['test-subset.c'], + ['test-subset-codepoints.c'], + ['test-subset-cmap.c'], + ['test-subset-glyf.c'], + ['test-subset-hdmx.c'], + ['test-subset-hmtx.c'], + ['test-subset-os2.c'], + ['test-subset-post.c'], + ['test-subset-vmtx.c'], + ['test-unicode.c'], + ['test-version.c'], + ['test-ot-color.c'], + ['test-ot-tag.c'], +] + +if conf.get('HAVE_FREETYPE', 0) == 1 + tests += [['test-ot-math.c']] +endif + +if conf.get('HAVE_GLIB', 0) == 1 + env = environment() + env.set('G_TEST_SRCDIR', meson.current_source_dir()) + env.set('G_TEST_BUILDDIR', meson.current_build_dir()) + + foreach test_data : tests + fname = test_data[0] + opts = test_data.length() > 1 ? test_data[1] : {} + extra_c_args = opts.get('c_args', []) + + + + test_name = fname.split('.')[0].underscorify() + exe = executable(test_name, fname, + cpp_args: cpp_args + extra_c_args, + include_directories: [incbase, incsrc], + dependencies: deps, + link_with: [libharfbuzz, libharfbuzz_subset], + ) + + test(test_name, exe, + env: env) + endforeach +endif diff --git a/test/fuzzing/meson.build b/test/fuzzing/meson.build new file mode 100644 index 000000000..7afa54f2d --- /dev/null +++ b/test/fuzzing/meson.build @@ -0,0 +1,32 @@ +tests = [ + ['hb-shape-fuzzer.cc'], + ['hb-subset-fuzzer.cc'], + ['hb-subset-get-codepoints-fuzzer.cc'], +] + +foreach test_data : tests + fname = test_data[0] + test_name = fname.split('.')[0].underscorify() + + exe = executable(test_name, [fname, 'main.cc'], + cpp_args: cpp_args, + include_directories: [incbase, incsrc], + dependencies: deps, + link_with: [libharfbuzz, libharfbuzz_subset], + ) +endforeach + +test('shape_fuzzer', python3, + args: [ + files('run-shape-fuzzer-tests.py')[0], + join_paths(meson.current_build_dir(), 'hb_shape_fuzzer') + ], + workdir: meson.current_source_dir()) + +test('subset_fuzzer', python3, + args: [ + files('run-subset-fuzzer-tests.py')[0], + join_paths(meson.current_build_dir(), 'hb_subset_fuzzer'), + join_paths(meson.current_build_dir(), 'hb_subset_get_codepoints_fuzzer'), + ], + workdir: meson.current_source_dir()) diff --git a/test/meson.build b/test/meson.build new file mode 100644 index 000000000..c3a2002fd --- /dev/null +++ b/test/meson.build @@ -0,0 +1,4 @@ +subdir('api') +subdir('fuzzing') +subdir('shaping') +subdir('subset') diff --git a/test/shaping/meson.build b/test/shaping/meson.build new file mode 100644 index 000000000..d8854fe9f --- /dev/null +++ b/test/shaping/meson.build @@ -0,0 +1,110 @@ +in_house_tests = [ + ['arabic-fallback-shaping.tests'], + ['arabic-feature-order.tests'], + ['arabic-like-joining.tests'], + ['arabic-mark-order.tests'], + ['arabic-stch.tests'], + ['automatic-fractions.tests'], + ['cluster.tests'], + ['color-fonts.tests'], + ['context-matching.tests'], + ['cursive-positioning.tests'], + ['default-ignorables.tests'], + ['emoji-flag-tags.tests'], + ['fallback-positioning.tests'], + ['fuzzed.tests'], + ['hangul-jamo.tests'], + ['hyphens.tests'], + ['indic-consonant-with-stacker.tests'], + ['indic-decompose.tests'], + ['indic-init.tests'], + ['indic-joiner-candrabindu.tests'], + ['indic-joiners.tests'], + ['indic-old-spec.tests'], + ['indic-pref-blocking.tests'], + ['indic-script-extensions.tests'], + ['indic-special-cases.tests'], + ['indic-syllable.tests'], + ['language-tags.tests'], + ['ligature-id.tests'], + ['mark-attachment.tests'], + ['mark-filtering-sets.tests'], + ['mongolian-variation-selector.tests'], + ['myanmar-syllable.tests'], + ['none-directional.tests'], + ['spaces.tests'], + ['simple.tests'], + ['tibetan-contractions-1.tests'], + ['tibetan-contractions-2.tests'], + ['tibetan-vowels.tests'], + ['use.tests'], + ['use-marchen.tests'], + ['use-syllable.tests'], + ['variations-rvrn.tests'], + ['vertical.tests'], + ['zero-width-marks.tests'], +] + +text_rendering_tests = [ + ['AVAR-1.tests'], + ['CFF-1.tests'], + ['CFF2-1.tests'], + ['CFF-2.tests'], + ['CMAP-1.tests'], + ['CMAP-2.tests'], + ['CVAR-1.tests'], + ['CVAR-2.tests'], + ['GLYF-1.tests'], + ['GPOS-1.tests'], + ['GPOS-2.tests'], + ['GPOS-3.tests'], + ['GPOS-4.tests'], + ['GPOS-5.tests'], + ['GSUB-1.tests'], + ['GSUB-2.tests'], + ['GVAR-1.tests'], + ['GVAR-2.tests'], + ['GVAR-3.tests'], + ['GVAR-4.tests'], + ['GVAR-5.tests'], + ['GVAR-6.tests'], + ['GVAR-7.tests'], + ['GVAR-8.tests'], + ['GVAR-9.tests'], + ['HVAR-1.tests'], + ['HVAR-2.tests'], + ['KERN-1.tests'], + ['KERN-2.tests'], + ['SHBALI-3.tests'], + ['SHKNDA-1.tests'], +] + +foreach test_data : in_house_tests + fname = test_data[0] + + test_name = fname.split('.')[0].underscorify() + + test(test_name, python3, + args: [ + files('run-tests.py')[0], + hb_shape.full_path(), + join_paths(meson.current_source_dir(), 'data/in-house/tests', fname), + ], + workdir: meson.current_source_dir(), + ) +endforeach + +foreach test_data : text_rendering_tests + fname = test_data[0] + + test_name = fname.split('.')[0].underscorify() + + test(test_name, python3, + args: [ + files('run-tests.py')[0], + hb_shape.full_path(), + join_paths(meson.current_source_dir(), 'data/text-rendering-tests/tests', fname), + ], + workdir: meson.current_source_dir(), + ) +endforeach diff --git a/test/subset/meson.build b/test/subset/meson.build new file mode 100644 index 000000000..ae9e7ea25 --- /dev/null +++ b/test/subset/meson.build @@ -0,0 +1,20 @@ +tests = [ + ['basics.tests'], + ['full-font.tests'], + ['japanese.tests'], +] + +foreach test_data : tests + fname = test_data[0] + + test_name = fname.split('.')[0].underscorify() + + test(test_name, python3, + args: [ + files('run-tests.py')[0], + hb_subset.full_path(), + join_paths(meson.current_source_dir(), 'data/tests', fname), + ], + workdir: meson.current_source_dir(), + ) +endforeach diff --git a/util/meson.build b/util/meson.build new file mode 100644 index 000000000..483babb5b --- /dev/null +++ b/util/meson.build @@ -0,0 +1,51 @@ +hb_view_sources = [ + 'hb-view.cc', + 'options.cc', + 'ansi-print.cc', + 'helper-cairo.cc', + 'helper-cairo-ansi.cc', + 'view-cairo.cc', +] + +hb_shape_sources = [ + 'hb-shape.cc', + 'options.cc', +] + +hb_ot_shape_closure_sources = [ + 'hb-ot-shape-closure.cc', + 'options.cc', +] + +hb_subset_cli_sources = [ + 'hb-subset.cc', + 'options.cc', +] + +hb_view = executable('hb-view', hb_view_sources, + cpp_args: cpp_args, + include_directories: [incbase, incsrc], + dependencies: deps, + link_with: [libharfbuzz] +) + +hb_shape = executable('hb-shape', hb_shape_sources, + cpp_args: cpp_args, + include_directories: [incbase, incsrc], + dependencies: deps, + link_with: [libharfbuzz] +) + +hb_subset = executable('hb-subset', hb_subset_cli_sources, + cpp_args: cpp_args, + include_directories: [incbase, incsrc], + dependencies: deps, + link_with: [libharfbuzz, libharfbuzz_subset] +) + +hb_ot_shape_closure = executable('hb-ot-shape-closure', hb_ot_shape_closure_sources, + cpp_args: cpp_args, + include_directories: [incbase, incsrc], + dependencies: deps, + link_with: [libharfbuzz] +)