[gegl/wip/pippin/meson] Added meson files



commit d71e17ce6a0da40a0df4ae8fbcd73fc7759b9127
Author: Félix Piédallu <felix piedallu me>
Date:   Thu Nov 30 17:31:54 2017 +0100

    Added meson files

 bin/lua/meson.build                                |  33 ++
 bin/meson.build                                    |  50 +++
 docs/meson.build                                   | 201 ++++++++++
 examples/meson.build                               |  52 +++
 gegl.pc.in                                         |  12 -
 gegl/buffer/meson.build                            |  61 +++
 gegl/graph/meson.build                             |  15 +
 gegl/meson.build                                   | 121 ++++++
 gegl/module/meson.build                            |   5 +
 gegl/opencl/meson.build                            |  27 ++
 gegl/operation/meson.build                         |  47 +++
 gegl/process/meson.build                           |  11 +
 gegl/property-types/meson.build                    |  15 +
 libs/npd/meson.build                               |  39 ++
 libs/rgbe/meson.build                              |  11 +
 meson.build                                        | 408 +++++++++++++++++++++
 meson_options.txt                                  |  36 ++
 meson_todo.md                                      |   6 +
 opencl/cltostring.py                               |  20 +-
 opencl/meson.build                                 |  61 +++
 operations/common-cxx/meson.build                  |  34 ++
 operations/common-gpl3+/meson.build                |  80 ++++
 operations/common/meson.build                      | 143 ++++++++
 operations/core/meson.build                        |  39 ++
 operations/external/gif-load.c                     |   7 +-
 operations/external/meson.build                    | 123 +++++++
 operations/generated/meson.build                   |  56 +++
 operations/json/meson.build                        |   3 +
 operations/meson.build                             |  13 +
 operations/seamless-clone/meson.build              |  26 ++
 operations/transform/meson.build                   |  31 ++
 operations/workshop/external/meson.build           |  80 ++++
 operations/workshop/generated/meson.build          |  27 ++
 operations/workshop/meson.build                    |  45 +++
 perf/meson.build                                   |  42 +++
 po/meson.build                                     |   1 +
 seamless-clone/gegl-sc.pc.in                       |  11 -
 seamless-clone/meson.build                         |  55 +++
 subprojects/libnsgif/meson.build                   |  16 +
 subprojects/poly2tri-c/meson.build                 |  31 ++
 .../poly2tri-c/poly2tri-c/p2t/common/meson.build   |   5 +
 subprojects/poly2tri-c/poly2tri-c/p2t/meson.build  |  10 +
 .../poly2tri-c/poly2tri-c/p2t/sweep/meson.build    |   7 +
 .../poly2tri-c/poly2tri-c/refine/meson.build       |  25 ++
 .../poly2tri-c/poly2tri-c/render/meson.build       |   6 +
 tests/buffer/buffer-test-wrapper.c                 | 370 +++++++++++++++++++
 tests/buffer/buffer-test.c.in                      | 363 ++++++++++++++++++
 tests/buffer/buffer-tests-run.sh                   |  11 +
 tests/buffer/meson.build                           | 105 ++++++
 tests/compositions/meson.build                     |  94 +++++
 tests/ff-load-save/meson.build                     |  11 +
 tests/ff-load-save/tests_ff_load_save.sh           |  38 ++
 tests/meson.build                                  |   8 +
 tests/mipmap/meson.build                           |  22 ++
 tests/opencl/meson.build                           |  43 +++
 tests/opencl/opencl_test.sh                        |  13 +
 tests/python/meson.build                           |  24 ++
 tests/simple/meson.build                           |  59 +++
 tests/xml/meson.build                              |  33 ++
 tools/meson.build                                  |  80 ++++
 60 files changed, 3387 insertions(+), 34 deletions(-)
---
diff --git a/bin/lua/meson.build b/bin/lua/meson.build
new file mode 100644
index 000000000..61ffcd710
--- /dev/null
+++ b/bin/lua/meson.build
@@ -0,0 +1,33 @@
+lua_files = files(
+  'cairo_h.lua',
+  'cairo.lua',
+  'gegl_box-blur.lua',
+  'gegl_c2g.lua',
+  'gegl_crop.lua',
+  'gegl_edge-neon.lua',
+  'gegl_fill-path.lua',
+  'gegl_gaussian-blur.lua',
+  'gegl_linear-gradient.lua',
+  'gegl_median-blur.lua',
+  'gegl_radial-gradient.lua',
+  'gegl_rectangle.lua',
+  'gegl_rotate.lua',
+  'gegl_snn-mean.lua',
+  'gegl_stress.lua',
+  'gegl_translate.lua',
+  'gegl_unsharp-mask.lua',
+  'gegl_vector-stroke.lua',
+  'init.lua',
+  'mime.lua',
+  'mrg.lua',
+  'mrl.lua',
+  'preferences.lua',
+  'viewer.lua',
+)
+
+if lua.found()
+  install_data(
+    lua_files,
+    install_dir: get_option('datadir') /  api_name / 'lua'
+  )
+endif
diff --git a/bin/meson.build b/bin/meson.build
new file mode 100644
index 000000000..9d6ffe963
--- /dev/null
+++ b/bin/meson.build
@@ -0,0 +1,50 @@
+subdir('lua')
+
+gegl_sources = files(
+  'gegl-options.c',
+  'gegl-path-smooth.c',
+  'gegl.c',
+)
+
+gegl_deps = [
+  babl,
+  glib,
+  gobject,
+  math,
+]
+
+if libpng.found()
+  gegl_deps += [ libpng, ]
+endif
+
+if mrg.found() and gexiv2.found()
+  gegl_sources += files(
+    'argvs.c',
+    'mrg-gegl.c',
+    'ui-collection.c',
+    'ui-core.c',
+    'ui-viewer.c',
+  )
+
+  gegl_sources += custom_target('argvs-commands.inc',
+    input : gegl_sources,
+    output: 'argvs-commands.inc',
+    command: [ argvs_extract, '@INPUT@' ],
+    capture: true,
+  )
+
+  gegl_deps += [ mrg, gexiv2, sdl1, ]
+endif
+
+if libspiro.found()
+  gegl_sources += files('gegl-path-spiro.c')
+  gegl_deps += [ libspiro, ]
+endif
+
+gegl_bin = executable('gegl',
+  gegl_sources,
+  include_directories: [ rootInclude, geglInclude, ],
+  dependencies: gegl_deps,
+  link_with: gegl_lib,
+  install: true,
+)
diff --git a/docs/meson.build b/docs/meson.build
new file mode 100644
index 000000000..2557c2282
--- /dev/null
+++ b/docs/meson.build
@@ -0,0 +1,201 @@
+doc_config = configuration_data()
+doc_config.set('top_srcdir', meson.source_root())
+
+html_files = []
+gtkdoc_files = []
+
+#######################################
+# Enscript files
+
+if enscript.found()
+  enscript_inputs = [
+    [ 'gegl',              'gegl-plugin.h' ],
+    [ 'gegl',              'gegl.h' ],
+    [ 'gegl/operation',    'gegl-operation-area-filter.h' ],
+    [ 'gegl/operation',    'gegl-operation-composer.h' ],
+    [ 'gegl/operation',    'gegl-operation-filter.h' ],
+    [ 'gegl/operation',    'gegl-operation-meta.h' ],
+    [ 'gegl/operation',    'gegl-operation-point-composer.h' ],
+    [ 'gegl/operation',    'gegl-operation-point-filter.h' ],
+    [ 'gegl/operation',    'gegl-operation-point-render.h' ],
+    [ 'gegl/operation',    'gegl-operation-sink.h' ],
+    [ 'gegl/operation',    'gegl-operation-source.h' ],
+    [ 'gegl/operation',    'gegl-operation-temporal.h' ],
+    [ 'gegl/operation',    'gegl-operation.h' ],
+    [ 'operations/common', 'brightness-contrast.c' ],
+  ]
+
+  enscript_files = []
+  foreach input : enscript_inputs
+    input_file = meson.source_root() / input[0] / input[1]
+    output_file = input[1] + '.html'
+
+    enscript_files += custom_target(output_file,
+      input : input_file,
+      output: output_file,
+      command: [
+        enscript, '-q',
+        '--highlight',
+        '--color',
+        '--language', 'html',
+        '--output', '@OUTPUT@',
+        '@INPUT@',
+      ],
+      install: true,
+      install_dir: gnome.gtkdoc_html_dir('gegl')
+    )
+  endforeach
+
+
+
+
+  html_files += enscript_files
+  # gtkdoc_files += enscript_files
+endif
+
+#######################################
+# HTML files
+
+html_files += custom_target('class-hierarchy.html',
+  input : [ ],
+  output: [ 'class-hierarchy.html' ],
+  command: [ find_program('env'),
+    'GEGL_SWAP=RAM',
+    'GEGL_PATH='+ meson.build_root() / 'operations',
+    introspect,
+  ],
+  capture: true,
+)
+
+if asciidoc.found()
+  txt_files = files(
+    'abyss_policy.txt',
+    'build.txt',
+    'commandline.txt',
+    'contribute.txt',
+    'development.txt',
+    'editor.txt',
+    'environment.txt',
+    'features.txt',
+    'gegl-chain.txt',
+    'glossary.txt',
+    'journal.txt',
+    'NEWS.txt',
+    'operation-api.txt',
+    'source-overview.txt',
+  )
+  txt_files += [
+    configure_file(
+      input : 'copyright.txt.in',
+      output: 'copyright.txt',
+      configuration: doc_config,
+    ),
+    configure_file(
+      input : 'hello-world.txt.in',
+      output: 'hello-world.txt',
+      configuration: doc_config,
+    ),
+    configure_file(
+      input : 'index.txt.in',
+      output: 'index.txt',
+      configuration: doc_config,
+    ),
+  ]
+
+  asciidoc_gen = generator(asciidoc,
+    arguments: [
+      '--unsafe',
+      '-o', '@OUTPUT@',
+      '-a', 'stylesheet=@0@'.format(meson.current_source_dir() / 'gegl.css'),
+      '-a', 'quirks!',
+      '@INPUT@'
+    ],
+    output: '@BASENAME@.html',
+  )
+
+  html_files += asciidoc_gen.process(txt_files)
+endif
+
+
+if ruby.found()
+  inheritance_dot = custom_target('inheritance.dot',
+    output: 'inheritance.dot',
+    command: [ gobj2dot, meson.source_root() ],
+    capture: true,
+    build_always_stale: true,
+  )
+  html_files += custom_target('inheritance.png',
+    input :  inheritance_dot,
+    output: 'inheritance.png',
+    command: [ graphviz, '-Tpng', '@INPUT@', '-o', '@OUTPUT@' ],
+  )
+endif
+
+
+#######################################
+# GTK Doc files
+
+gtkdoc_files += files(
+  'gegl.css',
+)
+
+gtkdoc_images = files(
+  'images' / 'standard-input.png',
+  'images' / 'standard-panorama.png',
+  'images' / 'standard-aux.png',
+)
+
+
+install_data(gtkdoc_files,
+  install_dir: gnome.gtkdoc_html_dir('gegl')
+)
+install_data(gtkdoc_images,
+  install_dir: gnome.gtkdoc_html_dir('gegl') / 'images'
+)
+
+
+# doc_operations_examples_dir = join_paths(
+#   meson.current_build_dir(), 'operations', 'images'
+# )
+# exclusion_pattern = '|'.join([
+#   'box-blur', 'box-percentile', 'buffer-cache', 'buffer-source',
+#   'clone', 'convert-format',
+#   'disc-percentile', 'dropshadow',
+#   'exp-combine', 'exr-load',
+#   'hstack',
+#   'image-compare', 'integral-image', 'introspect',
+#   'jpg-load',
+#   'kuwahara',
+#   'layer', 'line-profile', 'load',
+#   'magick-load', 'mandelbrot', 'matting-global',
+#   'nop',
+#   'open-buffer',
+#   'pixbuf', 'png-load',
+#   'remap',
+#   'snn-percentile', 'stretch-contrast', 'svg-load',
+#   'v4l2',
+#   'warp',
+# ])
+
+# doc_operations_examples = run_target('doc_examples',
+#   command: [ bash, '-c',
+#     ' '.join([
+#     'echo', 'Generating example images',
+#     '&&',
+#     'mkdir', '-p', doc_operations_examples_dir,
+#     '&&',
+#     'BABL_TOLERANCE=0.0',
+#     'GEGL_SWAP=RAM',
+#     'GEGL_PATH=' + join_paths(meson.source_root(), 'operations'),
+#     gegl_tester.full_path(),
+#     '--all', '-o',  doc_operations_examples_dir,
+#     '-d', join_paths(meson.current_source_dir(), 'images'),
+#     '-e', '"' + exclusion_pattern + '"',
+#     '&&',
+#     'cd', join_paths(meson.current_build_dir(), 'operations'),
+#     '&&',
+#     'GEGL_PATH=' + join_paths(meson.build_root(), 'operations'),
+#     operations_html.full_path(),
+#     ])
+#   ],
+# )
diff --git a/examples/meson.build b/examples/meson.build
new file mode 100644
index 000000000..f76ae95c8
--- /dev/null
+++ b/examples/meson.build
@@ -0,0 +1,52 @@
+
+examples = [
+  { 'name': '2geglbuffer', },
+  { 'name': 'frame-counter', },
+  { 'name': 'gegl-convert', },
+  { 'name': 'gegl-slicer', },
+  { 'name': 'geglbuffer-add-image', },
+  { 'name': 'geglbuffer-clock', },
+  { 'name': 'hello-world', },
+  { 'name': 'video-invert', },
+]
+
+if sdl1.found()
+  examples += {
+    'name': 'sdl-draw',
+    'deps': [ sdl1, math, ]
+  }
+endif
+if gexiv2.found()
+  examples += {
+    'name': 'gegl-video',
+    'deps': [ gexiv2, ]
+  }
+endif
+
+
+foreach example : examples
+  example_name = example.get('name')
+  example_srcs = example.get('srcs', example_name + '.c')
+  example_deps = example.get('deps', [])
+
+  exe = executable(example_name,
+    example_srcs,
+    include_directories: [ geglInclude, ],
+    dependencies: [
+      babl,
+      glib,
+      gobject,
+      example_deps,
+    ],
+    link_with: [ gegl_lib, ],
+    install: false,
+  )
+
+  # Fore use as tests for ff-load-save
+  if example_name == 'gegl-video'
+    gegl_video_example = exe
+  endif
+  if example_name == 'frame-counter'
+    frame_counter_example = exe
+  endif
+endforeach
diff --git a/gegl/buffer/meson.build b/gegl/buffer/meson.build
new file mode 100644
index 000000000..e997d71eb
--- /dev/null
+++ b/gegl/buffer/meson.build
@@ -0,0 +1,61 @@
+gegl_sources += files(
+  'gegl-algorithms.c',
+  'gegl-buffer-access.c',
+  'gegl-buffer-config.c',
+  'gegl-buffer-enums.c',
+  'gegl-buffer-iterator.c',
+  'gegl-buffer-iterator2.c',
+  'gegl-buffer-linear.c',
+  'gegl-buffer-load.c',
+  'gegl-buffer-matrix2.c',
+  'gegl-buffer-save.c',
+  'gegl-buffer-swap.c',
+  'gegl-buffer.c',
+  'gegl-compression-nop.c',
+  'gegl-compression-rle.c',
+  'gegl-compression-zlib.c',
+  'gegl-compression.c',
+  'gegl-memory.c',
+  'gegl-rectangle.c',
+  'gegl-sampler-cubic.c',
+  'gegl-sampler-linear.c',
+  'gegl-sampler-lohalo.c',
+  'gegl-sampler-nearest.c',
+  'gegl-sampler-nohalo.c',
+  'gegl-sampler.c',
+  'gegl-scratch.c',
+  'gegl-tile-alloc.c',
+  'gegl-tile-backend-buffer.c',
+  'gegl-tile-backend-file-async.c',
+  'gegl-tile-backend-ram.c',
+  'gegl-tile-backend-swap.c',
+  'gegl-tile-backend.c',
+  'gegl-tile-handler-cache.c',
+  'gegl-tile-handler-chain.c',
+  'gegl-tile-handler-empty.c',
+  'gegl-tile-handler-log.c',
+  'gegl-tile-handler-zoom.c',
+  'gegl-tile-handler.c',
+  'gegl-tile-source.c',
+  'gegl-tile-storage.c',
+  'gegl-tile.c',
+)
+
+gegl_introspectable_headers += files(
+  'gegl-buffer-backend.h',
+  'gegl-buffer-enums.h',
+  'gegl-buffer-iterator.h',
+  'gegl-buffer-matrix2.h',
+  'gegl-buffer-swap.h',
+  'gegl-buffer.h',
+  'gegl-memory.h',
+  'gegl-rectangle.h',
+  'gegl-scratch.h',
+  'gegl-tile-backend.h',
+  'gegl-tile-handler.h',
+  'gegl-tile-source.h',
+)
+
+gegl_headers += files(
+  'gegl-tile.h',
+)
diff --git a/gegl/graph/meson.build b/gegl/graph/meson.build
new file mode 100644
index 000000000..9e9ef120f
--- /dev/null
+++ b/gegl/graph/meson.build
@@ -0,0 +1,15 @@
+gegl_sources += files(
+  'gegl-cache.c',
+  'gegl-callback-visitor.c',
+  'gegl-connection.c',
+  'gegl-node-output-visitable.c',
+  'gegl-node.c',
+  'gegl-pad.c',
+  'gegl-region-generic.c',
+  'gegl-visitable.c',
+  'gegl-visitor.c',
+)
+
+gegl_introspectable_headers += files(
+  'gegl-node.h',
+)
diff --git a/gegl/meson.build b/gegl/meson.build
new file mode 100644
index 000000000..ce906c597
--- /dev/null
+++ b/gegl/meson.build
@@ -0,0 +1,121 @@
+
+geglInclude = include_directories(
+  '.',
+  'buffer',
+  'graph',
+  'module',
+  'opencl',
+  'operation',
+  'process',
+  'property-types',
+)
+
+gegl_cflags = [
+  '-DLIBDIR="@0@"'.format(get_option('prefix') / get_option('libdir')),
+  '-DG_LOG_DOMAIN="@0@"'.format('GEGL'),
+  '-DGEGL_LOCALEDIR="@0@"'.format(get_option('localedir')),
+]
+
+gegl_introspectable_headers = files(
+  'gegl.h',
+  'gegl-apply.h',
+  'gegl-enums.h',
+  'gegl-init.h',
+  'gegl-lookup.h',
+  'gegl-matrix.h',
+  'gegl-operations-util.h',
+  'gegl-parallel.h',
+  'gegl-random.h',
+  'gegl-types.h',
+  'gegl-utils.h',
+  'gegl-version.h',
+)
+
+gegl_headers = files(
+  'gegl-cpuaccel.h',
+  'gegl-debug.h',
+  'gegl-op.h',
+  'gegl-plugin.h',
+)
+
+gegl_sources = files(
+  'gegl-apply.c',
+  'gegl-config.c',
+  'gegl-cpuaccel.c',
+  'gegl-dot-visitor.c',
+  'gegl-dot.c',
+  'gegl-enums.c',
+  'gegl-gio.c',
+  'gegl-init.c',
+  'gegl-instrument.c',
+  'gegl-introspection-support.c',
+  'gegl-lookup.c',
+  'gegl-matrix.c',
+  'gegl-parallel.c',
+  'gegl-random.c',
+  'gegl-serialize.c',
+  'gegl-stats.c',
+  'gegl-utils.c',
+  'gegl-xml.c',
+)
+
+subdir('buffer')
+subdir('graph')
+subdir('module')
+subdir('opencl')
+subdir('operation')
+subdir('process')
+subdir('property-types')
+
+gegl_headers += gegl_introspectable_headers
+
+install_headers(gegl_headers,
+  subdir: api_name
+)
+
+gegl_lib = library(api_name,
+  gegl_sources,
+  include_directories: [ rootInclude, geglInclude, ],
+  dependencies: [
+    babl,
+    glib,
+    gio,
+    math,
+    gmodule,
+  ],
+  c_args: [ gegl_cflags, ],
+  install: true,
+  version: so_version,
+)
+
+
+introspection_sources = gegl_introspectable_headers + files(
+  'gegl-introspection-support.h',
+  'opencl' / 'gegl-cl-introspection-support.h',
+)
+
+
+if get_option('introspection')
+  gegl_gir = gnome.generate_gir(gegl_lib,
+    sources: introspection_sources,
+    nsversion: api_version,
+    namespace: 'Gegl',
+    identifier_prefix: 'Gegl',
+    symbol_prefix: 'gegl',
+    header: 'gegl.h',
+    includes: [ 'GLib-2.0', 'GObject-2.0', ],
+    include_directories: [
+      rootInclude,
+      geglInclude,
+    ],
+    install: true,
+  )
+
+  if vapigen.found()
+     gnome.generate_vapi(api_name,
+       metadata_dirs: '.',
+       sources: gegl_gir[0],
+       install: true,
+     )
+  endif
+endif
diff --git a/gegl/module/meson.build b/gegl/module/meson.build
new file mode 100644
index 000000000..cff16af9c
--- /dev/null
+++ b/gegl/module/meson.build
@@ -0,0 +1,5 @@
+gegl_sources += files(
+  'gegldatafiles.c',
+  'geglmodule.c',
+  'geglmoduledb.c',
+)
diff --git a/gegl/opencl/meson.build b/gegl/opencl/meson.build
new file mode 100644
index 000000000..778c463f9
--- /dev/null
+++ b/gegl/opencl/meson.build
@@ -0,0 +1,27 @@
+gegl_sources += files(
+  'gegl-buffer-cl-cache.c',
+  'gegl-buffer-cl-iterator.c',
+  'gegl-cl-color.c',
+  'gegl-cl-init.c',
+  'gegl-cl-random.c',
+  'gegl-cl.c',
+)
+
+gegl_opencl_headers = files(
+  'cl_d3d10.h',
+  'cl_ext.h',
+  'cl_gl_ext.h',
+  'cl_gl.h',
+  'cl_platform.h',
+  'cl.h',
+  'gegl-cl-color.h',
+  'gegl-cl-init.h',
+  'gegl-cl-random.h',
+  'gegl-cl-types.h',
+  'gegl-cl.h',
+  'opencl.h',
+)
+
+install_headers(gegl_opencl_headers,
+  subdir: api_name / 'opencl'
+)
diff --git a/gegl/operation/meson.build b/gegl/operation/meson.build
new file mode 100644
index 000000000..6a3aa4eac
--- /dev/null
+++ b/gegl/operation/meson.build
@@ -0,0 +1,47 @@
+gegl_sources += files(
+  'gegl-extension-handler.c',
+  'gegl-operation-area-filter.c',
+  'gegl-operation-composer.c',
+  'gegl-operation-composer3.c',
+  'gegl-operation-context-private.h',
+  'gegl-operation-context.c',
+  'gegl-operation-filter.c',
+  'gegl-operation-handlers-private.h',
+  'gegl-operation-handlers.c',
+  'gegl-operation-meta-json.c',
+  'gegl-operation-meta.c',
+  'gegl-operation-point-composer.c',
+  'gegl-operation-point-composer3.c',
+  'gegl-operation-point-filter.c',
+  'gegl-operation-point-render.c',
+  'gegl-operation-property-keys.c',
+  'gegl-operation-sink.c',
+  'gegl-operation-source.c',
+  'gegl-operation-temporal.c',
+  'gegl-operation.c',
+  'gegl-operations.c',
+)
+gegl_operation_headers = files(
+  'gegl-extension-handler.h',
+  'gegl-operation-area-filter.h',
+  'gegl-operation-composer.h',
+  'gegl-operation-composer3.h',
+  'gegl-operation-context.h',
+  'gegl-operation-filter.h',
+  'gegl-operation-handlers.h',
+  'gegl-operation-meta-json.h',
+  'gegl-operation-meta.h',
+  'gegl-operation-point-composer.h',
+  'gegl-operation-point-composer3.h',
+  'gegl-operation-point-filter.h',
+  'gegl-operation-point-render.h',
+  'gegl-operation-property-keys.h',
+  'gegl-operation-sink.h',
+  'gegl-operation-source.h',
+  'gegl-operation-temporal.h',
+  'gegl-operation.h',
+)
+
+install_headers(gegl_operation_headers,
+  subdir: api_name / 'operation',
+)
diff --git a/gegl/process/meson.build b/gegl/process/meson.build
new file mode 100644
index 000000000..be1416bb0
--- /dev/null
+++ b/gegl/process/meson.build
@@ -0,0 +1,11 @@
+gegl_sources += files(
+  'gegl-eval-manager.c',
+  'gegl-graph-traversal-debug.c',
+  'gegl-graph-traversal.c',
+  'gegl-processor.c',
+)
+
+gegl_introspectable_headers += files(
+  'gegl-graph-debug.h',
+  'gegl-processor.h',
+)
diff --git a/gegl/property-types/meson.build b/gegl/property-types/meson.build
new file mode 100644
index 000000000..73e7ab377
--- /dev/null
+++ b/gegl/property-types/meson.build
@@ -0,0 +1,15 @@
+gegl_sources += files(
+  'gegl-audio-fragment.c',
+  'gegl-color.c',
+  'gegl-curve.c',
+  'gegl-paramspecs.c',
+  'gegl-path.c',
+)
+
+gegl_introspectable_headers += files(
+  'gegl-audio-fragment.h',
+  'gegl-color.h',
+  'gegl-curve.h',
+  'gegl-paramspecs.h',
+  'gegl-path.h',
+)
diff --git a/libs/npd/meson.build b/libs/npd/meson.build
new file mode 100644
index 000000000..6baf9c942
--- /dev/null
+++ b/libs/npd/meson.build
@@ -0,0 +1,39 @@
+gegl_npd_sources = files(
+  'deformation.c',
+  'graphics.c',
+  'lattice_cut.c',
+  'npd_common.c',
+  'npd_debug.c',
+  'npd_gegl.c',
+  'npd_math.c',
+)
+
+gegl_npd_headers = files(
+  'deformation.h',
+  'graphics.h',
+  'lattice_cut.h',
+  'npd_common.h',
+  'npd_debug.h',
+  'npd_gegl.h',
+  'npd_math.h',
+  'npd.h',
+)
+
+gegl_npd_lib = library(meson.project_name() + '-npd-' + api_version,
+  gegl_npd_sources,
+  dependencies: [ glib, babl, math, ],
+  include_directories: geglInclude,
+  link_with: [
+    gegl_lib,
+  ],
+  install: true,
+)
+
+libnpd = declare_dependency(
+  include_directories: include_directories('..'),
+  link_with: gegl_npd_lib,
+)
+
+install_headers(gegl_npd_headers,
+  subdir: api_name / 'npd',
+)
diff --git a/libs/rgbe/meson.build b/libs/rgbe/meson.build
new file mode 100644
index 000000000..f7cfd5eba
--- /dev/null
+++ b/libs/rgbe/meson.build
@@ -0,0 +1,11 @@
+
+rgbe_lib = static_library('rgbe',
+  'rgbe.c',
+  dependencies: glib,
+  include_directories: rootInclude,
+)
+
+librgbe = declare_dependency(
+  include_directories: include_directories('..'),
+  link_with: rgbe_lib,
+)
diff --git a/meson.build b/meson.build
new file mode 100644
index 000000000..cb8274d27
--- /dev/null
+++ b/meson.build
@@ -0,0 +1,408 @@
+project('gegl',
+  'c', 'cpp',
+  license: 'GPL3+',
+  version: '0.4.17',
+  meson_version: '>=0.50.0',
+  default_options: [
+    'c_std=gnu11',
+    'cpp_std=gnu++14',
+  ],
+)
+
+# Making releases on the stable branch:
+#   micro_version += 1;
+#   interface_age += 1;
+#   binary_age += 1;
+# if any functions have been added,
+#    set interface_age to 0.
+# if backwards compatibility has been broken,
+#    set binary_age _and_ interface_age to 0.
+
+pkgconfig = import('pkgconfig')
+i18n      = import('i18n')
+gnome     = import('gnome')
+python    = import('python3').find_python()
+
+cc  = meson.get_compiler('c')
+config= configuration_data()
+
+################################################################################
+# Project infos
+
+version = meson.project_version()
+array_version = version.split('.')
+major_version = array_version[0].to_int()
+minor_version = array_version[1].to_int()
+micro_version = array_version[2].to_int()
+
+api_version = '@0@.@1@'.format(major_version, minor_version)
+api_name    = meson.project_name() + '-' + api_version
+gettext_package = api_name
+
+stability_version_number = (major_version != 0 ? minor_version : micro_version)
+stable = (stability_version_number % 2 == 0)
+
+config.set        ('GEGL_MAJOR_VERSION',  '@0@'.format(major_version))
+config.set        ('GEGL_MINOR_VERSION',  '@0@'.format(minor_version))
+config.set        ('GEGL_MICRO_VERSION',  '@0@'.format(micro_version))
+config.set        ('GEGL_UNSTABLE',       not stable)
+
+config.set_quoted ('GEGL_LIBRARY',        '@0@'.format(api_name))
+config.set_quoted ('GETTEXT_PACKAGE',     '@0@'.format(gettext_package))
+
+# Libtool versionning
+interface_age = 1
+
+binary_age = 100 * minor_version + micro_version
+lt_current = binary_age - interface_age
+so_version  = '@0@.@1@.@2@'.format(0, lt_current, interface_age)
+
+################################################################################
+# Host system detection
+
+host_os = host_machine.system()
+os_win32  = host_os.contains('mingw') or host_os.contains('windows')
+os_android= host_os.contains('android')
+os_osx    = host_os.contains('darwin')
+
+if os_osx and cc.get_id() != 'clang'
+  error('You should use Clang on OSx.')
+endif
+
+
+host_cpu = host_machine.cpu()
+if   host_cpu.startswith('i') and host_cpu.endswith('86')
+  have_x86 = true
+  config.set10('ARCH_X86',    true)
+elif host_cpu == 'x86_64'
+  have_x86 = true
+  config.set10('ARCH_X86',    true)
+  config.set10('ARCH_X86_64', true)
+elif host_cpu == 'ppc' or host_cpu == 'powerpc'
+  have_ppc = true
+  config.set10('ARCH_PPC',    true)
+elif host_cpu == 'ppc64' or host_cpu == 'powerpc64'
+  have_ppc = true
+  config.set10('ARCH_PPC',    true)
+  config.set10('ARCH_PPC64',  true)
+else
+  error('Unknown host architecture')
+endif
+
+# Should be filled with c_arguments, is checked before use.
+c_arguments = [
+  '-DHAVE_CONFIG_H',
+]
+
+################################################################################
+# Extra warnings
+
+c_arguments += [
+  '-Winit-self',
+  '-Wmissing-declarations',
+  '-Wmissing-prototypes',
+  '-Wold-style-definition',
+  '-Wpointer-arith',
+  '-Wno-deprecated-declarations',
+]
+
+################################################################################
+# Check for compiler CPU extensions
+
+c_arguments += [
+  '-mfpmath=sse',
+]
+
+optionnal_arguments = [
+  'mmx',
+  'sse',
+  'sse2',
+  'sse4.1',
+  'f16c',
+]
+
+foreach arg : optionnal_arguments
+  if get_option('enable-@0@'.format(arg.underscorify()))
+    c_arguments += '-m@0@'.format(arg)
+  endif
+endforeach
+
+add_project_arguments(cc.get_supported_arguments(c_arguments), language: 'c')
+
+################################################################################
+# Utilities
+
+bash        = find_program('bash')
+
+asciidoc    = find_program('asciidoc',      required: false)
+enscript    = find_program('enscript',      required: false)
+perl        = find_program('perl5', 'perl', required: false)
+python2     = find_program('python2',       required: false)
+rsvg_convert= find_program('rsvg-convert',  required: false)
+ruby        = find_program('ruby',          required: false)
+w3m         = find_program('w3m',           required: false)
+
+graphviz    = find_program('dot',           required: get_option('graphviz'))
+
+################################################################################
+# Required Dependencies
+
+config.set('HAVE_UNISTD_H',   cc.has_header('unistd.h'))
+config.set('HAVE_EXECINFO_H', cc.has_header('execinfo.h'))
+config.set('HAVE_FSYNC',      cc.has_function('fsync'))
+
+math    = cc.find_library('m', required: false)
+thread  = dependency('threads')
+
+babl      = dependency('babl',        version: '>=0.1.66')
+glib      = dependency('glib-2.0',    version: '>=2.44.0')
+gobject   = dependency('gobject-2.0', version: '>=2.44.0')
+gmodule   = dependency('gmodule-2.0', version: '>=2.44.0')
+gthread   = dependency('gthread-2.0', version: '>=2.44.0')
+gio_os    = os_win32 ? 'gio-windows-2.0' : 'gio-unix-2.0'
+gio       = [
+            dependency('gio-2.0',     version: '>=2.44.0'),
+            dependency(gio_os,        version: '>=2.44.0'),
+]
+json_glib = dependency('json-glib-1.0', version: '>=1.2.6')
+
+# Required libraries eventually provided in subprojects/ subdir
+
+poly2tri_c= dependency('poly2tri-c',  version: '>=0.0.0',
+  fallback: [ 'poly2tri-c', 'poly2tri_c' ],
+  required: false,
+)
+
+libnsgif = dependency('libnsgif',
+  fallback: [ 'libnsgif', 'libnsgif' ],
+)
+
+################################################################################
+# Optionnal Dependencies
+
+gdk_pixbuf= dependency('gdk-pixbuf-2.0', version:'>=2.32.0',
+  required: get_option('gdk-pixbuf')
+)
+pango     = dependency('pango',       version: '>=1.38.0',
+  required: get_option('pango')
+)
+pangocairo= dependency('pangocairo',  version: '>=1.38.0',
+  required: get_option('pangocairo')
+)
+cairo     = dependency('cairo',       version: '>=1.12.2',
+  required: get_option('cairo')
+)
+exiv2     = dependency('exiv2',       version: '>=0.25',
+  required: get_option('exiv2')
+)
+gexiv2    = dependency('gexiv2',      version: '>=0.0.0',
+  required: get_option('gexiv2')
+)
+config.set('HAVE_GEXIV2', gexiv2.found())
+
+jasper    = dependency('jasper',      version: '>=1.900.1',
+  required: get_option('jasper')
+)
+lcms      = dependency('lcms2',       version: '>=2.8',
+  required: get_option('lcms')
+)
+lensfun   = dependency('lensfun',     version: '>=0.2.5',
+  required: get_option('lensfun')
+)
+libjpeg   = dependency('libjpeg',     version: '>=1.0.0',
+  required: get_option('libjpeg')
+)
+libpng    = dependency('libpng',      version: '>=1.6.0',
+  required: get_option('libpng')
+)
+libraw    = dependency('libraw',      version: '>=0.15.4',
+  required: get_option('libraw')
+)
+librsvg   = dependency('librsvg-2.0', version: '>=2.40.6',
+  required: get_option('librsvg')
+)
+libspiro  = dependency('libspiro',    version: '>=0.5.0',
+  required: get_option('libspiro')
+)
+libtiff   = dependency('libtiff-4',   version: '>=4.0.0',
+  required: get_option('libtiff')
+)
+libv4l1   = dependency('libv4l1',     version: '>=1.0.1',
+  required: get_option('libv4l')
+)
+libv4l2   = dependency('libv4l2',     version: '>=1.0.1',
+  required: get_option('libv4l2')
+)
+lua       = dependency('lua',         version: '>=5.1.0',
+  required: get_option('lua')
+)
+mrg       = dependency('mrg',         version: '>=0.0.0',
+  required: get_option('mrg')
+)
+config.set('HAVE_MRG', mrg.found())
+
+openexr   = dependency('OpenEXR',     version: '>=1.6.1',
+  required: get_option('openexr')
+)
+sdl1      = dependency('sdl',         version: '>=1.2.0',
+  required: get_option('sdl1')
+)
+
+vapigen   = dependency('vapigen',     version:'>=0.20.0',
+  required: get_option('vapigen')
+)
+libwebp   = dependency('libwebp',     version:'>=0.5.0',
+  required: get_option('webp')
+)
+
+pygobject3  = dependency('pygobject-3.0', version: '>=3.2.0',
+  required: get_option('pygobject')
+)
+gobj_introsp = dependency('gobject-introspection-1.0', version: '>=1.32.0',
+  required: get_option('pygobject')
+)
+pygobject_found = pygobject3.found() and gobj_introsp.found()
+
+libavcodec  = dependency('libavcodec',   version: '>=55.69.100',
+  required: get_option('libav')
+)
+libavformat = dependency('libavformat',  version: '>=55.48.100',
+  required: get_option('libav')
+)
+libavutil   = dependency('libavutil',    version: '>=55.92.100',
+  required: get_option('libav')
+)
+libswscale  = dependency('libswscale',   version: '>=2.6.100',
+  required: get_option('libav')
+)
+avlibs_found = (
+  libavcodec.found() and
+  libavformat.found() and
+  libavutil.found() and
+  libswscale.found()
+)
+avlibs = avlibs_found ? [ libavcodec, libavformat, libavutil, libswscale ] : []
+
+libumfpack = cc.find_library('umfpack', required: get_option('umfpack'))
+if libumfpack.found()
+  have_umfpack = cc.has_header('umfpack.h')
+  have_ss_umfpack = cc.has_header_symbol(
+    'suitesparse/umfpack.h',
+    'umfpack_dl_solve'
+  )
+
+  if not (have_umfpack or have_ss_umfpack)
+    if get_option('umfpack').auto()
+      libumfpack = dependency('', required: false)
+    else
+      error('UmfPack library found but not headers.')
+    endif
+  endif
+  config.set('HAVE_UMFPACK_H', have_umfpack)
+  config.set('HAVE_SUITESPARSE_UMFPACK_H', have_ss_umfpack)
+endif
+
+################################################################################
+# Subdirs
+
+configure_file(
+  output: 'config.h',
+  configuration: config
+)
+
+rootInclude = include_directories('.')
+
+argvs_extract = find_program('tools/argvs_extract.sh')
+
+subdir('libs/rgbe')
+subdir('opencl')
+subdir('gegl')
+subdir('libs/npd')
+subdir('seamless-clone')
+subdir('bin')
+subdir('tools')
+subdir('operations')
+subdir('examples')
+subdir('tests')
+subdir('perf')
+subdir('po')
+if get_option('docs')
+  subdir('docs')
+endif
+
+if w3m.found()
+  custom_target('README',
+    input : 'docs/index.html',
+    output: 'README',
+    command: [ w3m, '-cols', '72', '-dump', '@INPUT@' ],
+    capture: true,
+  )
+  custom_target('NEWS',
+    input : 'docs/NEWS.html',
+    output: 'NEWS',
+    command: [ w3m, '-cols', '72', '-dump', '@INPUT@' ],
+    capture: true,
+  )
+endif
+
+pkgconfig.generate(filebase: 'gegl-' + api_version,
+  name: 'GEGL',
+  description: 'Generic Graphics Library',
+  version: meson.project_version(),
+  variables: 'pluginsdir=' + '${prefix}' / get_option('libdir') / api_name,
+  requires: [
+    gobject,
+    gmodule,
+    gio,
+    json_glib,
+
+    babl,
+  ],
+  libraries: gegl_lib,
+  subdirs: api_name,
+)
+
+
+message('\n'.join(['',
+'Building GEGL with prefix=@0@'.format(get_option('prefix')),
+'',
+'Optional features:',
+'  GEGL docs:       @0@'.format(get_option('docs')),
+'  Build workshop:  @0@'.format(get_option('workshop')),
+'  Build website:   @0@'.format(asciidoc.found()),
+'  SIMD:            sse:@0@ mmx:@1@ sse2:@2@'.format(
+  get_option('enable-sse'),
+  get_option('enable-mmx'),
+  get_option('enable-sse2')
+),
+'  Vala support:    @0@'.format(vapigen.found()),
+'',
+'Optional dependencies:',
+'  asciidoc:        @0@'.format(asciidoc.found()),
+'  enscript:        @0@'.format(enscript.found()),
+'  mrg:             @0@'.format(mrg.found()),
+'  Ruby:            @0@'.format(ruby.found()),
+'  Lua:             @0@'.format(lua.found()),
+'  Cairo:           @0@'.format(cairo.found()),
+'  Pango:           @0@'.format(pango.found()),
+'  pangocairo:      @0@'.format(pangocairo.found()),
+'  GDKPixbuf:       @0@'.format(gdk_pixbuf.found()),
+'  JPEG:            @0@'.format(libjpeg.found()),
+'  PNG:             @0@'.format(libpng.found()),
+'  OpenEXR:         @0@'.format(openexr.found()),
+'  rsvg:            @0@'.format(librsvg.found()),
+'  SDL:             @0@'.format(sdl1.found()),
+'  libraw:          @0@'.format(libraw.found()),
+'  Jasper:          @0@'.format(jasper.found()),
+'  graphviz:        @0@'.format(graphviz.found()),
+'  av libs:         @0@'.format(avlibs_found),
+'  V4L:             @0@'.format(libv4l1.found()),
+'  V4L2:            @0@'.format(libv4l2.found()),
+'  spiro:           @0@'.format(libspiro.found()),
+'  EXIV:            @0@'.format(exiv2.found()),
+'  gexiv2:          @0@'.format(gexiv2.found()),
+'  umfpack:         @0@'.format(libumfpack.found()),
+'  TIFF             @0@'.format(libtiff.found()),
+'  webp:            @0@'.format(libwebp.found()),
+'  poly2tri-c:      @0@ (@1@)'.format(poly2tri_c.found(),poly2tri_c.type_name()),
+'']))
diff --git a/meson_options.txt b/meson_options.txt
new file mode 100644
index 000000000..62c949e6d
--- /dev/null
+++ b/meson_options.txt
@@ -0,0 +1,36 @@
+option('enable-mmx',    type: 'boolean', value: true, description: 'enable MMX support')
+option('enable-sse',    type: 'boolean', value: true, description: 'enable SSE support')
+option('enable-sse2',   type: 'boolean', value: true, description: 'enable SSE2 support')
+option('enable-sse4_1', type: 'boolean', value: true, description: 'enable SSE4.1 support')
+option('enable-f16c',   type: 'boolean', value: true, description: 'enable hardware half-float support')
+option('docs',          type: 'boolean', value: 'true')
+option('workshop',      type: 'boolean', value: 'true')
+option('introspection', type: 'boolean', value: 'false')
+
+option('exiv2',         type: 'feature', value: 'auto')
+option('gdk-pixbuf',    type: 'feature', value: 'auto')
+option('gexiv2',        type: 'feature', value: 'auto')
+option('graphviz',      type: 'feature', value: 'auto')
+option('jasper',        type: 'feature', value: 'auto')
+option('lcms',          type: 'feature', value: 'auto')
+option('lensfun',       type: 'feature', value: 'auto')
+option('libav',         type: 'feature', value: 'auto')
+option('libjpeg',       type: 'feature', value: 'auto')
+option('libpng',        type: 'feature', value: 'auto')
+option('libraw',        type: 'feature', value: 'auto')
+option('librsvg',       type: 'feature', value: 'auto')
+option('libspiro',      type: 'feature', value: 'auto')
+option('libtiff',       type: 'feature', value: 'auto')
+option('libv4l',        type: 'feature', value: 'auto')
+option('libv4l2',       type: 'feature', value: 'auto')
+option('lua',           type: 'feature', value: 'auto')
+option('mrg',           type: 'feature', value: 'auto')
+option('openexr',       type: 'feature', value: 'auto')
+option('cairo',         type: 'feature', value: 'auto')
+option('pango',         type: 'feature', value: 'auto')
+option('pangocairo',    type: 'feature', value: 'auto')
+option('pygobject',     type: 'feature', value: 'auto')
+option('sdl1',          type: 'feature', value: 'auto')
+option('umfpack',       type: 'feature', value: 'auto')
+option('vapigen',       type: 'feature', value: 'auto')
+option('webp',          type: 'feature', value: 'auto')
diff --git a/meson_todo.md b/meson_todo.md
new file mode 100644
index 000000000..c95f836b5
--- /dev/null
+++ b/meson_todo.md
@@ -0,0 +1,6 @@
+
+* Fix CFlags
+* Final configure message
+* Generate changelog from script
+* docs -> Wut ??
+* gcut -> Issue \ replaced with / in meson
diff --git a/opencl/cltostring.py b/opencl/cltostring.py
index bf8f46e43..f2831c644 100755
--- a/opencl/cltostring.py
+++ b/opencl/cltostring.py
@@ -4,10 +4,6 @@ from __future__ import print_function
 import os
 import sys
 
-if len(sys.argv) != 2:
-  print("Usage: %s file.cl" % sys.argv[0])
-  sys.exit(1)
-
 # Search for lines that look like #include "blah.h" and replace them
 # with the contents of blah.h.
 def do_includes (source):
@@ -37,8 +33,18 @@ def escape_string(s):
   return result
 
 
-infile  = open(sys.argv[1], "r")
-outfile = open(sys.argv[1] + ".h", "w")
+if len(sys.argv) == 2:
+  infile  = open(sys.argv[1], "r")
+  outfile = open(sys.argv[1] + '.h',  "w")
+
+elif len(sys.argv) == 3:
+  infile  = open(sys.argv[1], "r")
+  outfile = open(sys.argv[2], "w")
+
+else:
+  print("Usage: %s input [output]" % sys.argv[0])
+  sys.exit(1)
+
 
 cl_source = infile.read()
 cl_source = do_includes(cl_source)
@@ -55,4 +61,4 @@ for line in cl_source.rstrip().split("\n"):
   line = '"%-78s\\n"\n' % line
   outfile.write(line)
 outfile.write(";\n")
-outfile.close()
\ No newline at end of file
+outfile.close()
diff --git a/opencl/meson.build b/opencl/meson.build
new file mode 100644
index 000000000..6c5bee0a2
--- /dev/null
+++ b/opencl/meson.build
@@ -0,0 +1,61 @@
+
+opencl_sources = [
+  'alien-map.cl',
+  'bilateral-filter-fast.cl',
+  'bilateral-filter.cl',
+  'box-blur.cl',
+  'box-max.cl',
+  'box-min.cl',
+  'brightness-contrast.cl',
+  'c2g.cl',
+  'checkerboard.cl',
+  'color-exchange.cl',
+  'color-temperature.cl',
+  'color-to-alpha.cl',
+  'colors-8bit-lut.cl',
+  'colors.cl',
+  'contrast-curve.cl',
+  'diffraction-patterns.cl',
+  'edge-laplace.cl',
+  'edge-sobel.cl',
+  'gaussian-blur-selective.cl',
+  'gblur-1d.cl',
+  'hue-chroma.cl',
+  'invert-linear.cl',
+  'levels.cl',
+  'mono-mixer.cl',
+  'motion-blur-circular.cl',
+  'motion-blur-linear.cl',
+  'noise-cell.cl',
+  'noise-hsv.cl',
+  'noise-hurl.cl',
+  'noise-reduction.cl',
+  'noise-simplex.cl',
+  'oilify.cl',
+  'opacity.cl',
+  'pixelize.cl',
+  'posterize.cl',
+  'random.cl',
+  'red-eye-removal.cl',
+  'shadows-highlights-correction.cl',
+  'snn-mean.cl',
+  'stretch-contrast.cl',
+  'svg-src-over.cl',
+  'texturize-canvas.cl',
+  'threshold.cl',
+  'value-invert.cl',
+  'video-degradation.cl',
+  'vignette.cl',
+  'weighted-blend.cl',
+]
+
+cltostring = find_program('cltostring.py')
+
+opencl_headers = files()
+foreach source : opencl_sources
+  opencl_headers += custom_target(source + '.h',
+    input : source,
+    output: source +'.h',
+    command: [ cltostring, '@INPUT@', '@OUTPUT@' ],
+  )
+endforeach
diff --git a/operations/common-cxx/meson.build b/operations/common-cxx/meson.build
new file mode 100644
index 000000000..27c3817ed
--- /dev/null
+++ b/operations/common-cxx/meson.build
@@ -0,0 +1,34 @@
+
+gegl_common_cxx_sources = files(
+  'distance-transform.cc',
+  'warp.cc',
+)
+
+gegl_common_cxx_sources += custom_target('module_common_gpl3.c',
+  input : [ gegl_common_cxx_sources ],
+  output: [ 'module_common_gpl3.c' ],
+  command: [
+    gen_loader,
+    '@INPUT@',
+  ],
+  capture: true
+)
+
+gegl_common_cxx = shared_library('gegl-common-cxx',
+  [ gegl_common_cxx_sources, opencl_headers, ],
+  include_directories: [ rootInclude, geglInclude, ],
+  dependencies: [
+    babl,
+    glib,
+    json_glib,
+    math,
+  ],
+  link_with: [
+    gegl_lib,
+  ],
+  c_args: [   '-DGEGL_OP_BUNDLE', ],
+  cpp_args: [ '-DGEGL_OP_BUNDLE', ],
+  name_prefix: '',
+  install: true,
+  install_dir: get_option('libdir') / api_name,
+)
diff --git a/operations/common-gpl3+/meson.build b/operations/common-gpl3+/meson.build
new file mode 100644
index 000000000..7e059b486
--- /dev/null
+++ b/operations/common-gpl3+/meson.build
@@ -0,0 +1,80 @@
+gegl_common_sources = files(
+  'antialias.c',
+  'apply-lens.c',
+  'bump-map.c',
+  'cartoon.c',
+  'channel-mixer.c',
+  'color-exchange.c',
+  'color-to-alpha.c',
+  'cubism.c',
+  'deinterlace.c',
+  'diffraction-patterns.c',
+  'displace.c',
+  'edge-laplace.c',
+  'edge.c',
+  'emboss.c',
+  'engrave.c',
+  'fractal-explorer.c',
+  'fractal-trace.c',
+  'gaussian-blur-selective.c',
+  'illusion.c',
+  'lens-distortion.c',
+  'lens-flare.c',
+  'maze.c',
+  'mosaic.c',
+  'motion-blur-circular.c',
+  'motion-blur-zoom.c',
+  'noise-slur.c',
+  'noise-solid.c',
+  'oilify.c',
+  'photocopy.c',
+  'plasma.c',
+  'polar-coordinates.c',
+  'red-eye-removal.c',
+  'ripple.c',
+  'shadows-highlights-correction.c',
+  'shadows-highlights.c',
+  'shift.c',
+  'sinus.c',
+  'softglow.c',
+  'spiral.c',
+  'supernova.c',
+  'texturize-canvas.c',
+  'tile-glass.c',
+  'tile-paper.c',
+  'value-propagate.c',
+  'video-degradation.c',
+  'waves.c',
+  'whirl-pinch.c',
+  'wind.c',
+)
+
+gegl_common_sources += custom_target('module_common_gpl3.c',
+  input : [ gegl_common_sources ],
+  output: [ 'module_common_gpl3.c' ],
+  command: [
+    gen_loader,
+    '@INPUT@',
+  ],
+  capture: true
+)
+
+gegl_common = shared_library('gegl-common-gpl3',
+  [ gegl_common_sources, opencl_headers, ],
+  include_directories: [ rootInclude, geglInclude, ],
+  dependencies: [
+    babl,
+    glib,
+    json_glib,
+    math,
+  ],
+  link_with: [
+    gegl_lib,
+  ],
+  c_args: [
+    '-DGEGL_OP_BUNDLE',
+  ],
+  name_prefix: '',
+  install: true,
+  install_dir: get_option('libdir') / api_name,
+)
diff --git a/operations/common/meson.build b/operations/common/meson.build
new file mode 100644
index 000000000..c18af464b
--- /dev/null
+++ b/operations/common/meson.build
@@ -0,0 +1,143 @@
+gegl_common_sources = files(
+  'absolute.c',
+  'alien-map.c',
+  'bilateral-filter.c',
+  'box-blur.c',
+  'brightness-contrast.c',
+  'buffer-sink.c',
+  'buffer-source.c',
+  'c2g.c',
+  'checkerboard.c',
+  'color-enhance.c',
+  'color-overlay.c',
+  'color-rotate.c',
+  'color-temperature.c',
+  'color-warp.c',
+  'color.c',
+  'component-extract.c',
+  'contrast-curve.c',
+  'convolution-matrix.c',
+  'copy-buffer.c',
+  'difference-of-gaussians.c',
+  'display.c',
+  'dither.c',
+  'domain-transform.c',
+  'dropshadow.c',
+  'edge-neon.c',
+  'edge-sobel.c',
+  'exp-combine.c',
+  'exposure.c',
+  'fattal02.c',
+  'gaussian-blur.c',
+  'gblur-1d.c',
+  'gegl-buffer-load-op.c',
+  'gegl-buffer-save-op.c',
+  'gegl.c',
+  'grey.c',
+  'grid.c',
+  'high-pass.c',
+  'hue-chroma.c',
+  'icc-save.c',
+  'image-compare.c',
+  'image-gradient.c',
+  'introspect.c',
+  'invert-gamma.c',
+  'invert-linear.c',
+  'layer.c',
+  'levels.c',
+  'linear-gradient.c',
+  'little-planet.c',
+  'long-shadow.c',
+  'magick-load.c',
+  'mantiuk06.c',
+  'map-absolute.c',
+  'map-relative.c',
+  'matting-global.c',
+  'mblur.c',
+  'mean-curvature-blur.c',
+  'median-blur.c',
+  'mirrors.c',
+  'mix.c',
+  'mono-mixer.c',
+  'motion-blur-linear.c',
+  'newsprint.c',
+  'noise-cell.c',
+  'noise-cie-lch.c',
+  'noise-hsv.c',
+  'noise-hurl.c',
+  'noise-perlin.c',
+  'noise-pick.c',
+  'noise-reduction.c',
+  'noise-rgb.c',
+  'noise-simplex.c',
+  'noise-spread.c',
+  'opacity.c',
+  'open-buffer.c',
+  'over.c',
+  'panorama-projection.c',
+  'pixelize.c',
+  'posterize.c',
+  'radial-gradient.c',
+  'rectangle.c',
+  'recursive-transform.c',
+  'reinhard05.c',
+  'remap.c',
+  'rgb-clip.c',
+  'saturation.c',
+  'save.c',
+  'sepia.c',
+  'slic.c',
+  'snn-mean.c',
+  'spherize.c',
+  'stress.c',
+  'stretch-contrast-hsv.c',
+  'stretch-contrast.c',
+  'svg-huerotate.c',
+  'svg-luminancetoalpha.c',
+  'svg-matrix.c',
+  'svg-saturate.c',
+  'threshold.c',
+  'tile-seamless.c',
+  'tile.c',
+  'unpremultiply.c',
+  'unsharp-mask.c',
+  'value-invert.c',
+  'vignette.c',
+  'waterpixels.c',
+  'watershed-transform.c',
+  'wavelet-blur-1d.c',
+  'wavelet-blur.c',
+  'weighted-blend.c',
+  'write-buffer.c',
+)
+
+gegl_common_sources += custom_target('module_common.c',
+  input : [ gegl_common_sources ],
+  output: [ 'module_common.c' ],
+  command: [
+    gen_loader,
+    '@INPUT@',
+  ],
+  capture: true
+)
+
+gegl_common = shared_library('gegl-common',
+  gegl_common_sources,
+  opencl_headers,
+  include_directories: [ rootInclude, geglInclude, ],
+  dependencies: [
+    babl,
+    glib,
+    json_glib,
+    math,
+  ],
+  link_with: [
+    gegl_lib,
+  ],
+  c_args: [
+    '-DGEGL_OP_BUNDLE',
+  ],
+  name_prefix: '',
+  install: true,
+  install_dir: get_option('libdir') / api_name,
+)
diff --git a/operations/core/meson.build b/operations/core/meson.build
new file mode 100644
index 000000000..ceac1fe88
--- /dev/null
+++ b/operations/core/meson.build
@@ -0,0 +1,39 @@
+
+gegl_core_sources = files(
+  'cache.c',
+  'cast-format.c',
+  'clone.c',
+  'convert-format.c',
+  'crop.c',
+  'json.c',
+  'load.c',
+  'nop.c',
+)
+
+gegl_core_sources += custom_target('module_core.c',
+  input : gegl_core_sources,
+  output: 'module_core.c',
+  command: [ gen_loader, '@INPUT@', ],
+  capture: true
+)
+
+gegl_core = shared_library('gegl-core',
+  gegl_core_sources,
+  include_directories: [ rootInclude, geglInclude, ],
+  dependencies: [
+    babl,
+    glib,
+    gmodule,
+    json_glib,
+    math,
+  ],
+  link_with: [
+    gegl_lib,
+  ],
+  c_args: [
+    '-DGEGL_OP_BUNDLE',
+  ],
+  name_prefix: '',
+  install: true,
+  install_dir: get_option('libdir') / api_name,
+)
diff --git a/operations/external/gif-load.c b/operations/external/gif-load.c
index 9f314eb95..8f312d935 100644
--- a/operations/external/gif-load.c
+++ b/operations/external/gif-load.c
@@ -49,10 +49,9 @@ property_int (frame_delay, _("frame-delay"), 100)
 #include <gegl-op.h>
 #include <gegl-gio-private.h>
 
-/* since libnsgif is nice and simple we directly embed it in the .so  */
-#include "libs/libnsgif/libnsgif.h"
-#include "libs/libnsgif/libnsgif.c"
-#include "libs/libnsgif/lzw.c"
+#include <assert.h>
+
+#include "libnsgif.h"
 
 #define IO_BUFFER_SIZE 4096
 
diff --git a/operations/external/meson.build b/operations/external/meson.build
new file mode 100644
index 000000000..4e54bc6ef
--- /dev/null
+++ b/operations/external/meson.build
@@ -0,0 +1,123 @@
+
+operations = [
+  { 'name': 'ppm-load' },
+  { 'name': 'ppm-save' },
+  { 'name': 'npy-save' },
+  { 'name': 'rgbe-load', 'deps': librgbe },
+  { 'name': 'rgbe-save', 'deps': librgbe },
+  { 'name': 'gif-load',  'deps': libnsgif },
+]
+
+
+if pangocairo.found()
+  operations += { 'name': 'text', 'deps': pangocairo }
+endif
+
+if cairo.found()
+  operations += [
+    { 'name': 'path',           'deps': cairo },
+    { 'name': 'vector-fill',    'deps': cairo },
+    { 'name': 'vector-stroke',  'deps': cairo },
+    { 'name': 'npd',            'deps': [ cairo, libnpd ] },
+  ]
+endif
+
+if libpng.found()
+  operations += [
+    { 'name': 'png-load', 'deps': libpng },
+    { 'name': 'png-save', 'deps': libpng },
+  ]
+endif
+
+if libjpeg.found()
+  operations += [
+    { 'name': 'jpg-load', 'deps': libjpeg },
+    { 'name': 'jpg-save', 'deps': libjpeg },
+  ]
+endif
+
+if cairo.found() and librsvg.found()
+  operations += [
+    { 'name': 'svg-load', 'deps': [ librsvg, cairo ], },
+  ]
+endif
+
+if gdk_pixbuf.found()
+  operations += [
+    { 'name': 'pixbuf-load',  'srcs': 'pixbuf.c',      'deps': gdk_pixbuf },
+    { 'name': 'pixbuf-save',  'srcs': 'save-pixbuf.c', 'deps': gdk_pixbuf },
+  ]
+endif
+
+if openexr.found()
+  operations += [
+    { 'name': 'exr-load',   'srcs': 'exr-load.cpp', 'deps': openexr },
+    { 'name': 'exr-save',   'srcs': 'exr-save.cc',  'deps': openexr },
+  ]
+endif
+
+if sdl1.found()
+  operations += { 'name': 'sdl-display', 'deps': sdl1 }
+endif
+
+if libraw.found()
+  operations += { 'name': 'raw-load', 'deps': libraw }
+endif
+
+if libv4l1.found()
+  operations += { 'name': 'v4l', 'deps': [ libv4l1, thread ], }
+endif
+
+if jasper.found()
+  operations += { 'name': 'jp2-load', 'deps': jasper }
+endif
+
+if avlibs_found
+  operations += [
+    { 'name': 'ff-load', 'deps': avlibs },
+    { 'name': 'ff-save', 'deps': avlibs },
+  ]
+endif
+
+if libumfpack.found()
+  operations += {
+    'name': 'matting-levin',
+    'srcs': [ 'matting-levin.c', 'matting-levin-cblas.c', ],
+    'deps': libumfpack
+  }
+endif
+
+if lcms.found()
+  operations += { 'name': 'lcms-from-profile', 'deps': lcms }
+endif
+
+if libtiff.found()
+  operations += [
+    { 'name': 'tiff-load', 'deps': libtiff },
+    { 'name': 'tiff-save', 'deps': libtiff },
+  ]
+endif
+
+if libwebp.found()
+  operations += [
+    { 'name': 'webp-load', 'deps': libwebp },
+    { 'name': 'webp-save', 'deps': libwebp },
+  ]
+endif
+
+
+foreach operation : operations
+  libname = operation.get('name')
+  libsrcs = operation.get('srcs', libname + '.c')
+  libdeps = operation.get('deps', [])
+
+  shared_library(libname,
+    libsrcs,
+    dependencies: [ babl, gio, glib, gobject, math, libdeps, ],
+    include_directories: [ rootInclude, geglInclude, ],
+    link_with: [ gegl_lib, ],
+    name_prefix: '',
+    install: true,
+    install_dir: get_option('libdir') / api_name,
+  )
+endforeach
diff --git a/operations/generated/meson.build b/operations/generated/meson.build
new file mode 100644
index 000000000..2a654656c
--- /dev/null
+++ b/operations/generated/meson.build
@@ -0,0 +1,56 @@
+gegl_generated_sources = files(
+  'add.c',
+  'clear.c',
+  'color-burn.c',
+  'color-dodge.c',
+  'darken.c',
+  'difference.c',
+  'divide.c',
+  'dst-atop.c',
+  'dst-in.c',
+  'dst-out.c',
+  'dst-over.c',
+  'dst.c',
+  'exclusion.c',
+  'gamma.c',
+  'hard-light.c',
+  'lighten.c',
+  'multiply.c',
+  'overlay.c',
+  'plus.c',
+  'screen.c',
+  'soft-light.c',
+  'src-atop.c',
+  'src-in.c',
+  'src-out.c',
+  'src.c',
+  'subtract.c',
+  'xor.c',
+)
+
+gegl_generated_sources += custom_target('module_generated_gpl3.c',
+  input : gegl_generated_sources,
+  output: 'module_generated_gpl3.c',
+  command: [ gen_loader, '@INPUT@', ],
+  capture: true
+)
+
+gegl_generated = shared_library('gegl-generated',
+  gegl_generated_sources,
+  include_directories: [ rootInclude, geglInclude, ],
+  dependencies: [
+    babl,
+    glib,
+    json_glib,
+    math,
+  ],
+  link_with: [
+    gegl_lib,
+  ],
+  c_args: [
+    '-DGEGL_OP_BUNDLE',
+  ],
+  name_prefix: '',
+  install: true,
+  install_dir: get_option('libdir') / api_name,
+)
diff --git a/operations/json/meson.build b/operations/json/meson.build
new file mode 100644
index 000000000..1d861ecca
--- /dev/null
+++ b/operations/json/meson.build
@@ -0,0 +1,3 @@
+install_data('grey2.json',
+  install_dir: get_option('libdir') / api_name,
+)
diff --git a/operations/meson.build b/operations/meson.build
new file mode 100644
index 000000000..e2fec07d9
--- /dev/null
+++ b/operations/meson.build
@@ -0,0 +1,13 @@
+subdir('common-gpl3+')
+subdir('common-cxx')
+subdir('common')
+subdir('core')
+subdir('external')
+subdir('generated')
+subdir('json')
+subdir('seamless-clone')
+subdir('transform')
+
+if get_option('workshop')
+  subdir('workshop')
+endif
diff --git a/operations/seamless-clone/meson.build b/operations/seamless-clone/meson.build
new file mode 100644
index 000000000..27ee947f7
--- /dev/null
+++ b/operations/seamless-clone/meson.build
@@ -0,0 +1,26 @@
+
+seamless_clone_libs = [
+  'seamless-clone',
+  'seamless-clone-compose',
+]
+
+foreach lib : seamless_clone_libs
+  shared_library(lib,
+    files(lib + '.c'),
+    include_directories: [ rootInclude, geglInclude, seamlessInclude, ],
+    dependencies: [
+      babl,
+      glib,
+      json_glib,
+      poly2tri_c,
+      math,
+    ],
+    link_with: [
+      gegl_lib,
+      seamlessclone_lib,
+    ],
+    name_prefix: '',
+    install: true,
+    install_dir: get_option('libdir') / api_name,
+  )
+endforeach
diff --git a/operations/transform/meson.build b/operations/transform/meson.build
new file mode 100644
index 000000000..4e0fc2a2d
--- /dev/null
+++ b/operations/transform/meson.build
@@ -0,0 +1,31 @@
+gegl_transformops_sources = files(
+  'module.c',
+  'reflect.c',
+  'rotate-on-center.c',
+  'rotate.c',
+  'scale-ratio.c',
+  'scale-size-keepaspect.c',
+  'scale-size.c',
+  'scale.c',
+  'shear.c',
+  'transform-core.c',
+  'transform.c',
+  'translate.c',
+)
+
+gegl_transformops = shared_library('transformops',
+  gegl_transformops_sources,
+  include_directories: [ rootInclude, geglInclude, ],
+  dependencies: [
+    babl,
+    glib,
+    json_glib,
+    math,
+  ],
+  link_with: [
+    gegl_lib,
+  ],
+  name_prefix: '',
+  install: true,
+  install_dir: get_option('libdir') / api_name,
+)
diff --git a/operations/workshop/external/meson.build b/operations/workshop/external/meson.build
new file mode 100644
index 000000000..94e8322db
--- /dev/null
+++ b/operations/workshop/external/meson.build
@@ -0,0 +1,80 @@
+
+if lua.found()
+  shared_library('gluas',
+    'gluas.c',
+    include_directories: [ rootInclude, geglInclude, seamlessInclude, ],
+    dependencies: [
+      babl,
+      glib,
+      gobject,
+      lua,
+      math,
+    ],
+    link_with: [
+      gegl_lib,
+    ],
+    name_prefix: '',
+    install: true,
+    install_dir: get_option('libdir') / api_name,
+  )
+endif
+
+if lensfun.found()
+  shared_library('lens-correct',
+    'lens-correct.c',
+    include_directories: [ rootInclude, geglInclude, seamlessInclude, ],
+    dependencies: [
+      babl,
+      glib,
+      gobject,
+      lensfun,
+      math,
+    ],
+    link_with: [
+      gegl_lib,
+    ],
+    name_prefix: '',
+    install: true,
+    install_dir: get_option('libdir') / api_name,
+  )
+endif
+
+if cairo.found()
+  shared_library('line-profile',
+    'line-profile.c',
+    include_directories: [ rootInclude, geglInclude, seamlessInclude, ],
+    dependencies: [
+      babl,
+      cairo,
+      glib,
+      gobject,
+      math,
+    ],
+    link_with: [
+      gegl_lib,
+    ],
+    name_prefix: '',
+    install: true,
+    install_dir: get_option('libdir') / api_name,
+  )
+endif
+
+if libv4l2.found()
+  shared_library('v4l2',
+    'v4l2.c',
+    include_directories: [ rootInclude, geglInclude, seamlessInclude, ],
+    dependencies: [
+      babl,
+      glib,
+      gobject,
+      libv4l2,
+      math,
+    ],
+    link_with: [
+      gegl_lib,
+    ],
+    name_prefix: '',
+    install: true,
+    install_dir: get_option('libdir') / api_name,
+  )
+endif
diff --git a/operations/workshop/generated/meson.build b/operations/workshop/generated/meson.build
new file mode 100644
index 000000000..fd463db54
--- /dev/null
+++ b/operations/workshop/generated/meson.build
@@ -0,0 +1,27 @@
+
+libraries = [
+  'average',
+  'blend-reflect',
+  'negation',
+  'soft-burn',
+  'soft-dodge',
+  'subtractive',
+]
+
+foreach lib : libraries
+  shared_library(lib,
+    lib + '.c',
+    include_directories: [ rootInclude, geglInclude, seamlessInclude, ],
+    dependencies: [
+      babl,
+      glib,
+      gobject,
+    ],
+    link_with: [
+      gegl_lib,
+    ],
+    name_prefix: '',
+    install: true,
+    install_dir: get_option('libdir') / api_name,
+  )
+endforeach
diff --git a/operations/workshop/meson.build b/operations/workshop/meson.build
new file mode 100644
index 000000000..688d62fe0
--- /dev/null
+++ b/operations/workshop/meson.build
@@ -0,0 +1,45 @@
+subdir('external')
+subdir('generated')
+
+libraries = [
+  { 'name': 'aces-rrt', },
+  { 'name': 'alpha-inpaint', },
+  { 'name': 'bilateral-filter-fast', },
+  { 'name': 'boxblur-1d', },
+  { 'name': 'boxblur', },
+  { 'name': 'connected-components', },
+  { 'name': 'demosaic-bimedian', },
+  { 'name': 'demosaic-simple', },
+  { 'name': 'ditto', },
+  { 'name': 'gcr', },
+  { 'name': 'gradient-map', },
+  { 'name': 'hstack', },
+  { 'name': 'integral-image', },
+  { 'name': 'rawbayer-load', },
+  { 'name': 'segment-kmeans', },
+  { 'name': 'selective-hue-saturation', },
+  { 'name': 'voronoi-diagram', 'srcs': 'voronoi-diagram.cc', },
+]
+
+foreach lib : libraries
+  libname = lib.get('name')
+  libsrcs = lib.get('srcs', libname + '.c')
+  shared_library(libname,
+    libsrcs,
+    opencl_headers,
+    include_directories: [ rootInclude, geglInclude, seamlessInclude, ],
+    dependencies: [
+      babl,
+      glib,
+      gobject,
+      math,
+    ],
+    link_with: [
+      gegl_lib,
+      seamlessclone_lib,
+    ],
+    name_prefix: '',
+    install: true,
+    install_dir: get_option('libdir') / api_name,
+  )
+endforeach
diff --git a/perf/meson.build b/perf/meson.build
new file mode 100644
index 000000000..290038c01
--- /dev/null
+++ b/perf/meson.build
@@ -0,0 +1,42 @@
+
+perf_tests = [
+  'bcontrast-4x',
+  'bcontrast-minichunk',
+  'bcontrast',
+  'blur',
+  'gegl-buffer-access',
+  'init',
+  'rotate',
+  'samplers',
+  'saturation',
+  'scale',
+  'translate',
+  'unsharpmask',
+]
+
+foreach testname : perf_tests
+  perf_test_exe = executable(testname,
+    'test-' + testname + '.c',
+    include_directories: [ rootInclude, geglInclude, ],
+    dependencies: [
+      babl,
+      glib,
+      gobject,
+    ],
+    link_with: [ gegl_lib, ],
+    c_args: [
+      '-DG_DISABLE_SINGLE_INCLUDES',
+      '-DGLIB_DISABLE_DEPRECATION_WARNINGS',
+      '-DCLUTTER_DISABLE_DEPRECATION_WARNINGS',
+      '-DTESTS_DATA_DIR="@0@"'.format( meson.source_root() / 'tests' / 'data'),
+    ],
+    install: false,
+  )
+
+  benchmark('Perf Test ' + testname, perf_test_exe,
+    env: [
+      'GEGL_PATH=' + meson.build_root() / 'operations',
+      'GEGL_USE_OPENCL=no',
+    ],
+  )
+endforeach
diff --git a/po/meson.build b/po/meson.build
new file mode 100644
index 000000000..d2a005f83
--- /dev/null
+++ b/po/meson.build
@@ -0,0 +1 @@
+i18n.gettext(gettext_package)
diff --git a/seamless-clone/meson.build b/seamless-clone/meson.build
new file mode 100644
index 000000000..d67e279a9
--- /dev/null
+++ b/seamless-clone/meson.build
@@ -0,0 +1,55 @@
+
+seamlessInclude = include_directories('.')
+
+seamlessclone_sources = [
+  'sc-context.c',
+  'sc-outline.c',
+  'sc-sample.c',
+]
+
+seamlessclone_headers = [
+  'sc-common.h',
+  'sc-context.h',
+  'sc-outline.h',
+  'sc-sample.h',
+]
+
+seamlessclone_lib = library('gegl-sc-' + api_version,
+  seamlessclone_sources,
+  include_directories: [ rootInclude, geglInclude, ],
+  dependencies: [
+    babl,
+    glib,
+    gobject,
+    poly2tri_c,
+  ],
+  link_with: [
+    gegl_lib,
+  ],
+  install: true,
+)
+
+install_headers(
+  seamlessclone_headers,
+  subdir: api_name / 'sc'
+)
+
+
+pkgconfig.generate(
+  filebase: 'gegl-sc-' + api_version,
+  name: 'GEGL Seamless Cloning',
+  description: 'Seamless Cloning Library Based on GEGL',
+  version: meson.project_version(),
+  requires: [
+    gobject,
+    gmodule,
+    gio,
+    json_glib,
+
+    babl,
+    poly2tri_c.type_name() == 'internal' ? [] : poly2tri_c,
+    'gegl-' + api_version,
+  ],
+  libraries: seamlessclone_lib,
+  subdirs: api_name / 'sc',
+)
diff --git a/subprojects/libnsgif/meson.build b/subprojects/libnsgif/meson.build
new file mode 100644
index 000000000..273d4ca26
--- /dev/null
+++ b/subprojects/libnsgif/meson.build
@@ -0,0 +1,16 @@
+project('libnsgif',
+  'c',
+  meson_version: '>=0.0.0',
+)
+
+
+libnsgif_lib = static_library('nsgif',
+  'libnsgif.c',
+  'lzw.c',
+)
+
+
+libnsgif = declare_dependency(
+  link_with: libnsgif_lib,
+  include_directories: '.'
+)
diff --git a/subprojects/poly2tri-c/meson.build b/subprojects/poly2tri-c/meson.build
new file mode 100644
index 000000000..280275235
--- /dev/null
+++ b/subprojects/poly2tri-c/meson.build
@@ -0,0 +1,31 @@
+project('poly2tri-c', 'c',
+  license: 'GPL3+',
+  version: '0.1.0',
+  meson_version: '>=0.40.0',
+  default_options: [
+    'sysconfdir=/etc',
+    'localstatedir=/var',
+    'sharedstatedir=/var/lib'
+  ],
+)
+
+glib = dependency('glib-2.0')
+math = meson.get_compiler('c').find_library('m')
+
+rootInclude = include_directories('.')
+
+subdir('poly2tri-c/p2t')
+subdir('poly2tri-c/refine')
+subdir('poly2tri-c/render')
+
+
+libpoly2tri_c = static_library('poly2tri-c',
+  link_with: [ libp2tc, libp2tc_refine, libp2tc_render, ],
+)
+
+
+poly2tri_c = declare_dependency(
+  include_directories: [ rootInclude, ],
+  link_with: [ libpoly2tri_c, ],
+  version: meson.project_version(),
+)
diff --git a/subprojects/poly2tri-c/poly2tri-c/p2t/common/meson.build 
b/subprojects/poly2tri-c/poly2tri-c/p2t/common/meson.build
new file mode 100644
index 000000000..e6cd6c93e
--- /dev/null
+++ b/subprojects/poly2tri-c/poly2tri-c/p2t/common/meson.build
@@ -0,0 +1,5 @@
+
+libp2tc_common_sources = files(
+  'shapes.c',
+  'utils.c'
+)
diff --git a/subprojects/poly2tri-c/poly2tri-c/p2t/meson.build 
b/subprojects/poly2tri-c/poly2tri-c/p2t/meson.build
new file mode 100644
index 000000000..38a68369b
--- /dev/null
+++ b/subprojects/poly2tri-c/poly2tri-c/p2t/meson.build
@@ -0,0 +1,10 @@
+
+subdir('common')
+subdir('sweep')
+
+libp2tc = static_library('p2tc',
+  libp2tc_common_sources,
+  libp2tc_sweep_sources,
+  dependencies: [ glib, math, ],
+  include_directories: [ rootInclude, ],
+)
diff --git a/subprojects/poly2tri-c/poly2tri-c/p2t/sweep/meson.build 
b/subprojects/poly2tri-c/poly2tri-c/p2t/sweep/meson.build
new file mode 100644
index 000000000..0d75c372b
--- /dev/null
+++ b/subprojects/poly2tri-c/poly2tri-c/p2t/sweep/meson.build
@@ -0,0 +1,7 @@
+
+libp2tc_sweep_sources = files(
+    'advancing_front.c',
+    'cdt.c',
+    'sweep_context.c',
+    'sweep.c',
+)
diff --git a/subprojects/poly2tri-c/poly2tri-c/refine/meson.build 
b/subprojects/poly2tri-c/poly2tri-c/refine/meson.build
new file mode 100644
index 000000000..70add0c2b
--- /dev/null
+++ b/subprojects/poly2tri-c/poly2tri-c/refine/meson.build
@@ -0,0 +1,25 @@
+
+libp2tc_refine = static_library('p2tc_refine',
+  'bounded-line.c',
+  'cdt-flipfix.c',
+  'cdt.c',
+  'circle.c',
+  'cluster.c',
+  'delaunay-terminator.c',
+  'edge.c',
+  'line.c',
+  'mesh-action.c',
+  'mesh.c',
+  'point.c',
+  'pslg.c',
+  'refiner.c',
+  'rmath.c',
+  'triangle.c',
+  'utils.c',
+  'vector2.c',
+  'vedge.c',
+  'visibility.c',
+  'vtriangle.c',
+  dependencies: [ glib, ],
+  include_directories: [ rootInclude, ],
+)
diff --git a/subprojects/poly2tri-c/poly2tri-c/render/meson.build 
b/subprojects/poly2tri-c/poly2tri-c/render/meson.build
new file mode 100644
index 000000000..ffe06a84c
--- /dev/null
+++ b/subprojects/poly2tri-c/poly2tri-c/render/meson.build
@@ -0,0 +1,6 @@
+
+libp2tc_render = static_library('p2tc_render',
+  [ 'mesh-render.c', 'svg-plot.c' ],
+  dependencies: [ glib, ],
+  include_directories: [ rootInclude, ],
+)
diff --git a/tests/buffer/buffer-test-wrapper.c b/tests/buffer/buffer-test-wrapper.c
new file mode 100644
index 000000000..4a904a801
--- /dev/null
+++ b/tests/buffer/buffer-test-wrapper.c
@@ -0,0 +1,370 @@
+
+#include "config.h"
+#include <gegl.h>
+#include <gegl-buffer.h>
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <glib.h>
+#include <glib/gstdio.h>
+
+/* This file consists of a testing suite for the GeglBuffer API. For every
+ * function matching the regexp ^static.*(' in the file a test is performed and
+ * the output is stored in in a file with the name of the function.
+ *
+ * The makefile contains shell scripting that provides knowledge of how much
+ * passes the reference suite, testing should occur over a range of different
+ * tile sizes to make sure the behavior is consistent.
+ */
+
+#include "gegl/buffer/gegl-buffer-iterator.h"
+
+
+
+/* helper macros for the output, issue a test_start() after your defined
+ * variables and the first logic, use print as your printf and print_buffer to
+ * dump a GeglBuffer's contents to the log, issue test_end for the final
+ * rendering.
+ */
+
+#define test_start()              GString *gstring=g_string_new("");\
+                                  print (("Test: %s\n", TEST_NAME))
+#define print(args)              G_STMT_START {                \
+       gchar *_fmt = g_strdup_printf args;                     \
+       g_string_append (gstring, _fmt);                        \
+       g_free (_fmt);                                          \
+                                 } G_STMT_END
+#define print_buffer(buffer)      print_buffer_internal (gstring, buffer)
+#define print_linear_buffer_u8(w,h,b)  print_linear_buffer_internal_u8 (gstring,w,h,b)
+#define print_linear_buffer_float(w,h,b)  print_linear_buffer_internal_float (gstring,w,h,b)
+#define test_end()                return g_string_free (gstring, FALSE)
+
+
+static void print_buffer_internal (GString    *gstring,
+                                   GeglBuffer *buffer);
+static void
+print_linear_buffer_internal_float (GString    *gstring,
+                                    gint        width,
+                                    gint        height,
+                                    gfloat     *buf);
+static void
+print_linear_buffer_internal_u8    (GString    *gstring,
+                                    gint        width,
+                                    gint        height,
+                                    guchar     *buf);
+
+static void checkerboard          (GeglBuffer *buffer,
+                                   gint        cellsize,
+                                   gfloat      val1,
+                                   gfloat      val2);
+
+static void fill                  (GeglBuffer *buffer,
+                                   gfloat      value);
+
+static void vgrad                 (GeglBuffer *buffer);
+static void hgrad                 (GeglBuffer *buffer);
+
+static void rectangle             (GeglBuffer *buffer,
+                                   gint        x,
+                                   gint        y,
+                                   gint        width,
+                                   gint        height,
+                                   gfloat      value);
+
+static void fill_rect (GeglBuffer          *buffer,
+                       const GeglRectangle *roi,
+                       gfloat               value
+                       );
+
+
+
+/***********************************************************************/
+/**************************************************************************/
+
+static void
+print_linear_buffer_internal_float (GString    *gstring,
+                                    gint        width,
+                                    gint        height,
+                                    gfloat     *buf)
+{
+  gchar *scale[]={" ", "░", "▒", "▓", "█", "█"};
+  gint x,y;
+  print (("▛"));
+  for (x=0;x<width;x++)
+    print (("▀"));
+  print (("▜\n"));
+  for (y=0;y<height;y++)
+    {
+      print (("▌"));
+      for (x=0;x<width;x++)
+        {
+          gint val = floor ( buf[y*width+x] * 4 + 0.5);
+          if (val>4)
+            val=4;
+          if (val<0)
+            val=0;
+          print (("%s", scale[val]));
+        }
+      print (("▐\n"));
+    }
+  print (("▙"));
+  for (x=0;x<width;x++)
+    print (("▄"));
+  print (("▟\n"));
+}
+
+static void
+print_linear_buffer_internal_u8 (GString    *gstring,
+                                 gint        width,
+                                 gint        height,
+                                 guchar     *buf)
+{
+  gchar *scale[]={" ", "░", "▒", "▓", "█"};
+  gint x,y;
+  print (("▛"));
+  for (x=0;x<width;x++)
+    print (("▀"));
+  print (("▜\n"));
+  for (y=0;y<height;y++)
+    {
+      print (("▌"));
+      for (x=0;x<width;x++)
+        print (("%s", scale[ (gint)floor ( buf[y*width+x]/256.0 * 4 + 0.5)]));
+      print (("▐\n"));
+    }
+  print (("▙"));
+  for (x=0;x<width;x++)
+    print (("▄"));
+  print (("▟\n"));
+}
+
+
+static void
+print_buffer_internal (GString    *gstring,
+                       GeglBuffer *buffer)
+{
+  gfloat *buf;
+  gint width, height, x0, y0;
+  g_object_get (buffer, "x", &x0,
+                        "y", &y0,
+                        "width", &width,
+                        "height", &height,
+                        NULL);
+  buf = g_malloc (width*height*sizeof(gfloat));
+  gegl_buffer_get (buffer, NULL, 1.0, babl_format ("Y float"), buf, 0,
+                   GEGL_ABYSS_NONE);
+  print_linear_buffer_internal_float (gstring, width, height, buf);
+  g_free (buf);
+}
+
+static void
+fill (GeglBuffer *buffer,
+      gfloat      value)
+{
+  gfloat *buf;
+  gint x,y;
+  gint i;
+  gint width, height, x0, y0;
+  g_object_get (buffer, "x", &x0,
+                        "y", &y0,
+                        "width", &width,
+                        "height", &height,
+                        NULL);
+  buf = g_malloc (width*height*sizeof(gfloat));
+  gegl_buffer_get (buffer, NULL, 1.0, babl_format ("Y float"), buf, 0,
+                   GEGL_ABYSS_NONE);
+
+  i=0;
+  for (y=0;y<height;y++)
+    {
+      for (x=0;x<width;x++)
+        {
+          buf[i++]=value;
+        }
+    }
+  gegl_buffer_set (buffer, NULL, 0, babl_format ("Y float"), buf, GEGL_AUTO_ROWSTRIDE);
+  g_free (buf);
+}
+
+static void checkerboard          (GeglBuffer *buffer,
+                                   gint        cellsize,
+                                   gfloat      val1,
+                                   gfloat      val2)
+{
+  gfloat *buf;
+  gint x,y;
+  gint i;
+  gint width, height, x0, y0;
+  g_object_get (buffer, "x", &x0,
+                        "y", &y0,
+                        "width", &width,
+                        "height", &height,
+                        NULL);
+  buf = g_malloc (width*height*sizeof(gfloat));
+  gegl_buffer_get (buffer, NULL, 1.0, babl_format ("Y float"), buf, 0,
+                   GEGL_ABYSS_NONE);
+
+  i=0;
+  for (y=0;y<height;y++)
+    {
+      for (x=0;x<width;x++)
+        {
+          gfloat val=val1;
+          if ( (x/cellsize) % 2)
+            {
+              if ( (y/cellsize) % 2)
+                {
+                  val=val2;
+                }
+            }
+          else
+            {
+              if ( (y/cellsize) % 2 == 0)
+                {
+                  val=val2;
+                }
+            }
+          buf[i++]= val;
+        }
+    }
+
+  gegl_buffer_set (buffer, NULL, 0, babl_format ("Y float"), buf, GEGL_AUTO_ROWSTRIDE);
+
+  g_free (buf);
+}
+
+static void vgrad (GeglBuffer *buffer)
+{
+  gfloat *buf;
+  gint x,y;
+  gint i;
+  gint width, height, x0, y0;
+  g_object_get (buffer, "x", &x0,
+                        "y", &y0,
+                        "width", &width,
+                        "height", &height,
+                        NULL);
+  buf = g_malloc (width*height*sizeof(gfloat));
+  gegl_buffer_get (buffer, NULL, 1.0, babl_format ("Y float"), buf, 0,
+                   GEGL_ABYSS_NONE);
+
+  i=0;
+  for (y=0;y<height;y++)
+    {
+      for (x=0;x<width;x++)
+        {
+          buf[i++]= (1.0*y)/height;
+        }
+    }
+  gegl_buffer_set (buffer, NULL, 0, babl_format ("Y float"), buf, GEGL_AUTO_ROWSTRIDE);
+  g_free (buf);
+}
+
+static void hgrad (GeglBuffer *buffer)
+{
+  gfloat *buf;
+  gint x,y;
+  gint i;
+  gint width, height, x0, y0;
+  g_object_get (buffer, "x", &x0,
+                        "y", &y0,
+                        "width", &width,
+                        "height", &height,
+                        NULL);
+  buf = g_malloc (width*height*sizeof(gfloat));
+  gegl_buffer_get (buffer, NULL, 1.0, babl_format ("Y float"), buf, 0,
+                   GEGL_ABYSS_NONE);
+
+  i=0;
+  for (y=0;y<height;y++)
+    {
+      for (x=0;x<width;x++)
+        {
+          buf[i++]= (1.0*x)/width;
+        }
+    }
+  gegl_buffer_set (buffer, NULL, 0, babl_format ("Y float"), buf, GEGL_AUTO_ROWSTRIDE);
+  g_free (buf);
+}
+
+static void fill_rect (GeglBuffer          *buffer,
+                       const GeglRectangle *roi,
+                       gfloat               value
+                       )
+{
+  GeglBufferIterator *gi;
+  gi = gegl_buffer_iterator_new (buffer, roi, 0, NULL,
+                                 GEGL_ACCESS_WRITE, GEGL_ABYSS_NONE, 1);
+  while (gegl_buffer_iterator_next (gi))
+    {
+      gfloat *buf = gi->items[0].data;
+      gint    i;
+      for (i=0; i<gi->length; i++)
+        {
+          buf[i]=value;
+        }
+    }
+}
+
+void rectangle (GeglBuffer *buffer,
+                gint        x,
+                gint        y,
+                gint        width,
+                gint        height,
+                gfloat      value)
+{
+  GeglBuffer *sub_buf;
+  GeglRectangle rect={x,y,width,height};
+
+  sub_buf = gegl_buffer_create_sub_buffer (buffer, &rect);
+  fill (sub_buf, value);
+  g_object_unref (sub_buf);
+}
+
+
+
+gchar* test_name = TEST_NAME;
+
+#define TEST() gchar * test_function (void)
+TEST();
+#include TEST_INCLUDE
+
+gint main (gint argc, gchar **argv)
+{
+  gint i;
+  gegl_init (&argc, &argv);
+
+  for (i=0; i < 1; i++)
+    {
+      gchar *ret;
+
+      if (argc > 1)
+        {
+          /* handle any extra commandline options as a list of tests to
+           * run and output to standard output
+           */
+          gint j;
+          for (j=1;j<argc;j++)
+            {
+              if (g_str_equal (argv[j], test_name))
+                {
+                  ret=test_function();
+                  printf ("%s", ret);
+                  g_free (ret);
+                }
+            }
+        }
+      else
+        {
+          gchar output_file[1024];
+          printf ("%s ", test_name);
+          ret=test_function();
+          sprintf (output_file, "output/%s.buf", test_name);
+          g_file_set_contents (output_file, ret, -1, NULL);
+          g_free (ret);
+        }
+    }
+
+  gegl_exit ();
+  return 0;
+}
diff --git a/tests/buffer/buffer-test.c.in b/tests/buffer/buffer-test.c.in
new file mode 100644
index 000000000..2a27f69cd
--- /dev/null
+++ b/tests/buffer/buffer-test.c.in
@@ -0,0 +1,363 @@
+#include "config.h"
+#include <gegl.h>
+#include <gegl-buffer.h>
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <glib.h>
+#include <glib/gstdio.h>
+
+/* This file consists of a testing suite for the GeglBuffer API. For every
+ * function matching the regexp ^static.*(' in the file a test is performed and
+ * the output is stored in in a file with the name of the function.
+ *
+ * The makefile contains shell scripting that provides knowledge of how much
+ * passes the reference suite, testing should occur over a range of different
+ * tile sizes to make sure the behavior is consistent.
+ */
+
+#include "gegl/buffer/gegl-buffer-iterator.h"
+
+
+
+/* helper macros for the output, issue a test_start() after your defined
+ * variables and the first logic, use print as your printf and print_buffer to
+ * dump a GeglBuffer's contents to the log, issue test_end for the final
+ * rendering.
+ */
+
+#define test_start()              GString *gstring=g_string_new("");\
+                                  print (("Test: %s\n", G_STRINGIFY (TESTNAME)))
+#define print(args)              G_STMT_START {                \
+       gchar *_fmt = g_strdup_printf args;                     \
+       g_string_append (gstring, _fmt);                        \
+       g_free (_fmt);                                          \
+                                 } G_STMT_END
+#define print_buffer(buffer)      print_buffer_internal (gstring, buffer)
+#define print_linear_buffer_u8(w,h,b)  print_linear_buffer_internal_u8 (gstring,w,h,b)
+#define print_linear_buffer_float(w,h,b)  print_linear_buffer_internal_float (gstring,w,h,b)
+#define test_end()                return g_string_free (gstring, FALSE)
+
+
+static void print_buffer_internal (GString    *gstring,
+                                   GeglBuffer *buffer);
+static void
+print_linear_buffer_internal_float (GString    *gstring,
+                                    gint        width,
+                                    gint        height,
+                                    gfloat     *buf);
+static void
+print_linear_buffer_internal_u8    (GString    *gstring,
+                                    gint        width,
+                                    gint        height,
+                                    guchar     *buf);
+
+static void checkerboard          (GeglBuffer *buffer,
+                                   gint        cellsize,
+                                   gfloat      val1,
+                                   gfloat      val2);
+
+static void fill                  (GeglBuffer *buffer,
+                                   gfloat      value);
+
+static void vgrad                 (GeglBuffer *buffer);
+static void hgrad                 (GeglBuffer *buffer);
+
+static void rectangle             (GeglBuffer *buffer,
+                                   gint        x,
+                                   gint        y,
+                                   gint        width,
+                                   gint        height,
+                                   gfloat      value);
+
+static void fill_rect (GeglBuffer          *buffer,
+                       const GeglRectangle *roi,
+                       gfloat               value
+                       );
+
+
+
+/***********************************************************************/
+/**************************************************************************/
+
+static void
+print_linear_buffer_internal_float (GString    *gstring,
+                                    gint        width,
+                                    gint        height,
+                                    gfloat     *buf)
+{
+  gchar *scale[]={" ", "░", "▒", "▓", "█", "█"};
+  gint x,y;
+  print (("▛"));
+  for (x=0;x<width;x++)
+    print (("▀"));
+  print (("▜\n"));
+  for (y=0;y<height;y++)
+    {
+      print (("▌"));
+      for (x=0;x<width;x++)
+        {
+          gint val = floor ( buf[y*width+x] * 4 + 0.5);
+          if (val>4)
+            val=4;
+          if (val<0)
+            val=0;
+          print (("%s", scale[val]));
+        }
+      print (("▐\n"));
+    }
+  print (("▙"));
+  for (x=0;x<width;x++)
+    print (("▄"));
+  print (("▟\n"));
+}
+
+static void
+print_linear_buffer_internal_u8 (GString    *gstring,
+                                 gint        width,
+                                 gint        height,
+                                 guchar     *buf)
+{
+  gchar *scale[]={" ", "░", "▒", "▓", "█"};
+  gint x,y;
+  print (("▛"));
+  for (x=0;x<width;x++)
+    print (("▀"));
+  print (("▜\n"));
+  for (y=0;y<height;y++)
+    {
+      print (("▌"));
+      for (x=0;x<width;x++)
+        print (("%s", scale[ (gint)floor ( buf[y*width+x]/256.0 * 4 + 0.5)]));
+      print (("▐\n"));
+    }
+  print (("▙"));
+  for (x=0;x<width;x++)
+    print (("▄"));
+  print (("▟\n"));
+}
+
+
+static void
+print_buffer_internal (GString    *gstring,
+                       GeglBuffer *buffer)
+{
+  gfloat *buf;
+  gint width, height, x0, y0;
+  g_object_get (buffer, "x", &x0,
+                        "y", &y0,
+                        "width", &width,
+                        "height", &height,
+                        NULL);
+  buf = g_malloc (width*height*sizeof(gfloat));
+  gegl_buffer_get (buffer, NULL, 1.0, babl_format ("Y float"), buf, 0,
+                   GEGL_ABYSS_NONE);
+  print_linear_buffer_internal_float (gstring, width, height, buf);
+  g_free (buf);
+}
+
+static void
+fill (GeglBuffer *buffer,
+      gfloat      value)
+{
+  gfloat *buf;
+  gint x,y;
+  gint i;
+  gint width, height, x0, y0;
+  g_object_get (buffer, "x", &x0,
+                        "y", &y0,
+                        "width", &width,
+                        "height", &height,
+                        NULL);
+  buf = g_malloc (width*height*sizeof(gfloat));
+  gegl_buffer_get (buffer, NULL, 1.0, babl_format ("Y float"), buf, 0,
+                   GEGL_ABYSS_NONE);
+
+  i=0;
+  for (y=0;y<height;y++)
+    {
+      for (x=0;x<width;x++)
+        {
+          buf[i++]=value;
+        }
+    }
+  gegl_buffer_set (buffer, NULL, 0, babl_format ("Y float"), buf, GEGL_AUTO_ROWSTRIDE);
+  g_free (buf);
+}
+
+static void checkerboard          (GeglBuffer *buffer,
+                                   gint        cellsize,
+                                   gfloat      val1,
+                                   gfloat      val2)
+{
+  gfloat *buf;
+  gint x,y;
+  gint i;
+  gint width, height, x0, y0;
+  g_object_get (buffer, "x", &x0,
+                        "y", &y0,
+                        "width", &width,
+                        "height", &height,
+                        NULL);
+  buf = g_malloc (width*height*sizeof(gfloat));
+  gegl_buffer_get (buffer, NULL, 1.0, babl_format ("Y float"), buf, 0,
+                   GEGL_ABYSS_NONE);
+
+  i=0;
+  for (y=0;y<height;y++)
+    {
+      for (x=0;x<width;x++)
+        {
+          gfloat val=val1;
+          if ( (x/cellsize) % 2)
+            {
+              if ( (y/cellsize) % 2)
+                {
+                  val=val2;
+                }
+            }
+          else
+            {
+              if ( (y/cellsize) % 2 == 0)
+                {
+                  val=val2;
+                }
+            }
+          buf[i++]= val;
+        }
+    }
+
+  gegl_buffer_set (buffer, NULL, 0, babl_format ("Y float"), buf, GEGL_AUTO_ROWSTRIDE);
+
+  g_free (buf);
+}
+
+static void vgrad (GeglBuffer *buffer)
+{
+  gfloat *buf;
+  gint x,y;
+  gint i;
+  gint width, height, x0, y0;
+  g_object_get (buffer, "x", &x0,
+                        "y", &y0,
+                        "width", &width,
+                        "height", &height,
+                        NULL);
+  buf = g_malloc (width*height*sizeof(gfloat));
+  gegl_buffer_get (buffer, NULL, 1.0, babl_format ("Y float"), buf, 0,
+                   GEGL_ABYSS_NONE);
+
+  i=0;
+  for (y=0;y<height;y++)
+    {
+      for (x=0;x<width;x++)
+        {
+          buf[i++]= (1.0*y)/height;
+        }
+    }
+  gegl_buffer_set (buffer, NULL, 0, babl_format ("Y float"), buf, GEGL_AUTO_ROWSTRIDE);
+  g_free (buf);
+}
+
+static void hgrad (GeglBuffer *buffer)
+{
+  gfloat *buf;
+  gint x,y;
+  gint i;
+  gint width, height, x0, y0;
+  g_object_get (buffer, "x", &x0,
+                        "y", &y0,
+                        "width", &width,
+                        "height", &height,
+                        NULL);
+  buf = g_malloc (width*height*sizeof(gfloat));
+  gegl_buffer_get (buffer, NULL, 1.0, babl_format ("Y float"), buf, 0,
+                   GEGL_ABYSS_NONE);
+
+  i=0;
+  for (y=0;y<height;y++)
+    {
+      for (x=0;x<width;x++)
+        {
+          buf[i++]= (1.0*x)/width;
+        }
+    }
+  gegl_buffer_set (buffer, NULL, 0, babl_format ("Y float"), buf, GEGL_AUTO_ROWSTRIDE);
+  g_free (buf);
+}
+
+static void fill_rect (GeglBuffer          *buffer,
+                       const GeglRectangle *roi,
+                       gfloat               value
+                       )
+{
+  GeglBufferIterator *gi;
+  gi = gegl_buffer_iterator_new (buffer, roi, 0, NULL,
+                                 GEGL_ACCESS_WRITE, GEGL_ABYSS_NONE);
+  while (gegl_buffer_iterator_next (gi))
+    {
+      gfloat *buf = gi->data[0];
+      gint    i;
+      for (i=0; i<gi->length; i++)
+        {
+          buf[i]=value;
+        }
+    }
+}
+
+void rectangle (GeglBuffer *buffer,
+                gint        x,
+                gint        y,
+                gint        width,
+                gint        height,
+                gfloat      value)
+{
+  GeglBuffer *sub_buf;
+  GeglRectangle rect={x,y,width,height};
+
+  sub_buf = gegl_buffer_create_sub_buffer (buffer, &rect);
+  fill (sub_buf, value);
+  g_object_unref (sub_buf);
+}
+
+#define TEST_NAME @TEST_NAME@
+#define TESTNAME @TESTNAME@
+#define TEST() static gchar* the_test(void)
+@TEST_INCLUDE@
+
+
+gint main (gint argc, gchar **argv)
+{
+  gint i;
+  gegl_init (&argc, &argv);
+
+  gchar *ret;
+
+  if (argc > 1)
+  {
+    // handle any extra commandline options as a list of tests to
+    // run and output to standard output
+    gint j;
+    for (j=1;j<argc;j++)
+      {
+        if (g_str_equal (argv[j], TEST_NAME))
+          {
+            ret=the_test();
+            printf ("%s", ret);
+            g_free (ret);
+          }
+      }
+  }
+  else
+  {
+    gchar output_file[1024];
+    printf ("%s ", TEST_NAME);
+    ret=the_test();
+    sprintf (output_file, "output/%s.buf", TEST_NAME);
+    g_file_set_contents (output_file, ret, -1, NULL);
+    g_free (ret);
+  }
+
+  gegl_exit ();
+  return 0;
+}
diff --git a/tests/buffer/buffer-tests-run.sh b/tests/buffer/buffer-tests-run.sh
new file mode 100644
index 000000000..e82fbd072
--- /dev/null
+++ b/tests/buffer/buffer-tests-run.sh
@@ -0,0 +1,11 @@
+#!/bin/bash -e
+
+mkdir -p output
+
+test_name=$1
+test_exe=$2
+${test_exe}
+
+LC_ALL=C diff \
+    "${REFERENCE_DIR}/${test_name}.buf" \
+              "output/${test_name}.buf"
diff --git a/tests/buffer/meson.build b/tests/buffer/meson.build
new file mode 100644
index 000000000..81160e08a
--- /dev/null
+++ b/tests/buffer/meson.build
@@ -0,0 +1,105 @@
+
+buffer_tests_list = [
+  'blank',
+  'buffer_copy',
+  'buffer_copy_abyss',
+  'buffer_copy_lower_left',
+  'buffer_copy_lower_right',
+  'buffer_copy_self',
+  'buffer_copy_upper_left',
+  'buffer_copy_upper_right',
+  'buffer_dup_copy1',
+  'buffer_dup_copy2',
+  'buffer_dup_delete1',
+  'buffer_dup_delete2',
+  'buffer_dup_write1',
+  'buffer_dup_write2',
+  'buffer_dup_write3',
+  'buffer_dup_write4',
+  'buffer_iterator1',
+  'buffer_iterator1sub',
+  'buffer_iterator2',
+  'buffer_iterator2sub',
+  'buffer_iterator3',
+  'buffer_iterator3sub',
+  'buffer_iterator4',
+  'buffer_iterator4sub',
+  'buffer_linear_copy',
+  'buffer_linear_iter',
+  'buffer_linear_iter2',
+  'buffer_multcopy',
+  'buffer_set_pattern',
+  'buffer_shift_diagonal',
+  'buffer_shift_horizontal',
+  'buffer_shift_vertical',
+  'checks',
+  'disabled_abyss',
+  'dup_linear_from_data',
+  'get_abyss_black',
+  'get_abyss_clamp',
+  'get_abyss_empty_buffer',
+  'get_abyss_loop',
+  'get_abyss_none',
+  'get_abyss_white',
+  'get_buffer_scaled',
+  'get_buffer_scaled2',
+  'get_shifted',
+  'gray',
+  'grow_extent',
+  'linear_from_data',
+  'linear_from_data_rows',
+  'linear_modify',
+  'linear_new',
+  'linear_proxy_modify',
+  'linear_shift',
+  'mipmap_iterator',
+  'mipmap_iterator2',
+  'mipmap_sampler',
+  'mipmap_set',
+  'mipmap_set2',
+  'rect',
+  'sample',
+  'save_small_roi',
+  'sub_rect_fills_and_gets',
+  'sub_sub_fill',
+  'sub_sub_fill2',
+  'vertical_gradient',
+]
+
+
+buffer_test_run_script = find_program('buffer-tests-run.sh')
+
+foreach test_name : buffer_tests_list
+
+  test_exe = executable(test_name,
+    'buffer-test-wrapper.c',
+    include_directories: [ rootInclude, geglInclude, ],
+    link_with: [
+      gegl_lib,
+    ],
+    dependencies: [
+      babl,
+      glib,
+      gobject,
+      math,
+    ],
+    c_args: [
+      '-Wno-unused-function',
+      '-DTEST_NAME="@0@"'.format(test_name),
+      '-DTEST_INCLUDE="@0@"'.format('tests' / test_name + '.c'),
+    ],
+  )
+
+  test(test_name,
+  buffer_test_run_script,
+    args: [ test_name, test_exe.full_path(), ],
+    env: [
+      'GEGL_PATH=' + meson.build_root() / 'operations',
+      'GEGL_SWAP=RAM',
+      'REFERENCE_DIR=' + meson.source_root() / 'tests' / 'buffer' / 'reference',
+    ],
+    workdir: meson.current_build_dir(),
+    suite: 'buffers',
+  )
+
+endforeach
diff --git a/tests/compositions/meson.build b/tests/compositions/meson.build
new file mode 100644
index 000000000..bc00a98b1
--- /dev/null
+++ b/tests/compositions/meson.build
@@ -0,0 +1,94 @@
+compositions_tests = files(
+  'affine-with-negative.xml',
+  'alien-map.xml',
+  'apply-lens.xml',
+  'apply-lens3.xml',
+  'bump-map.xml',
+  'checkerboard.xml',
+  'clones.xml',
+  'color-enhance.xml',
+  'color-exchange.xml',
+  'color-to-alpha.xml',
+  'colors.xml',
+  'composite-transform.xml',
+  'contrast-curve.xml',
+  'convolve1.xml',
+  'convolve2.xml',
+  'edge.xml',
+  'fattal02.xml',
+  'gamma.xml',
+  'gegl.xml',
+  'grey-json.xml',
+  'hdr-color.xml',
+  'illusion.xml',
+  'image-compare.xml',
+  'lens-flare.xml',
+  'mantiuk06.xml',
+  'noise-cell.xml',
+  'noise-hurl.xml',
+  'noise-simplex.xml',
+  'noise-solid.xml',
+  'posterize.xml',
+  'rectangles.xml',
+  'red-eye-removal.xml',
+  'reflect.xml',
+  'reflect2.xml',
+  'reinhard05.xml',
+  'rgb-params.xml',
+  'rotate-on-center.xml',
+  'rotate.xml',
+  'scale-size-keepaspect.xml',
+  'simple-scale.xml',
+  'sinus.xml',
+  'stretch-contrast.xml',
+  'supernova.xml',
+  'transform.xml',
+  'weighted-blend.xml',
+)
+#run-matting-global.xml.sh
+#run-matting-global-big.xml.sh
+
+compositions_tests_without_opencl = files(
+  'color-reduction.xml',
+  'jpg-load-datauri.xml',
+  'pnm-ascii-load.xml',
+  'pnm-raw-load.xml',
+  'rgbe-load.xml',
+  'rgbe-save.xml',
+  'shift.xml',
+  'stretch-contrast-hsv.xml',
+  'tiff-load.xml',
+  'tile.xml',
+)
+
+
+if jasper.found()
+  compositions_tests_without_opencl += 'jp2-load.xml'
+endif
+if libumfpack.found()
+ # compositions_tests += 'matting-levin.xml'
+endif
+
+run_compositions = find_program('run-compositions.py')
+test('compositions_with_opencl',
+  run_compositions,
+  args: [
+    '--build-dir='+ meson.build_root(),
+    '--src-dir='  + meson.source_root(),
+    '--xml-dir='  + meson.current_source_dir(),
+    compositions_tests,
+  ],
+  timeout: 120,
+  suite: 'compositions',
+)
+test('compositions_without_opencl',
+  run_compositions,
+  args: [
+    '--build-dir='+ meson.build_root(),
+    '--src-dir='  + meson.source_root(),
+    '--xml-dir='  + meson.current_source_dir(),
+    '--without-opencl',
+    compositions_tests_without_opencl,
+  ],
+  suite: 'compositions',
+)
diff --git a/tests/ff-load-save/meson.build b/tests/ff-load-save/meson.build
new file mode 100644
index 000000000..64589de56
--- /dev/null
+++ b/tests/ff-load-save/meson.build
@@ -0,0 +1,11 @@
+if gexiv2.found()
+
+  test('ff-load-save',
+    find_program('tests_ff_load_save.sh'),
+    env: [ 'MESON_BUILD_ROOT=' + meson.build_root() ],
+    workdir: meson.current_build_dir(),
+    suite: 'ff-load-save',
+    protocol: 'tap',
+  )
+
+endif
diff --git a/tests/ff-load-save/tests_ff_load_save.sh b/tests/ff-load-save/tests_ff_load_save.sh
new file mode 100755
index 000000000..64efea912
--- /dev/null
+++ b/tests/ff-load-save/tests_ff_load_save.sh
@@ -0,0 +1,38 @@
+#!/usr/bin/env bash
+
+export GEGL_PATH="${MESON_BUILD_ROOT}/operations"
+
+FrameCounter="${MESON_BUILD_ROOT}/examples/frame-counter"
+GeglVideo="${MESON_BUILD_ROOT}/examples/gegl-video"
+
+testcount=0
+
+test() {
+  ((testcount++))
+  if "$@" 1> /dev/null; then
+    echo "ok ${testcount}"
+  else
+    echo "not ok ${testcount} - $@"
+  fi
+}
+endtests() {
+  echo "1..${testcount}"
+}
+
+# Videos
+
+test "${FrameCounter}" --video-codec mpeg4 --video-bit-rate 128            mpeg4-128kb.avi
+test "${FrameCounter}" --video-codec mpeg4 --video-bit-rate 512            mpeg4-512kb.avi
+test "${FrameCounter}" --video-codec mpeg4 --video-bit-rate 512            512kb.mp4
+test "${FrameCounter}" --video-codec mpeg4 --video-bit-rate 128            128kb.mp4
+test "${FrameCounter}" --video-codec mpeg4 --video-bit-rate 128 --fps 12   128kb-12fps.mp4
+test "${FrameCounter}" --video-codec mpeg4 --video-bit-rate 128 --fps 100  128kb-100fps.mp4
+test "${FrameCounter}"                     --video-bit-rate 512 --fps 28   512kb-28fps.ogv
+
+# Images
+
+for a in *.avi *.mp4 *.ogv ; do
+  test "${GeglVideo}" $a -s 74 -e 74 -of $a-
+done
+
+endtests
diff --git a/tests/meson.build b/tests/meson.build
new file mode 100644
index 000000000..b9a7923a2
--- /dev/null
+++ b/tests/meson.build
@@ -0,0 +1,8 @@
+subdir('buffer')
+subdir('compositions')
+subdir('ff-load-save')
+subdir('mipmap')
+subdir('opencl')
+subdir('python')
+subdir('simple')
+subdir('xml')
diff --git a/tests/mipmap/meson.build b/tests/mipmap/meson.build
new file mode 100644
index 000000000..82e4096eb
--- /dev/null
+++ b/tests/mipmap/meson.build
@@ -0,0 +1,22 @@
+
+testnames = [
+  'invert-crop',
+  'invert',
+  'rotate-crop',
+  'rotate',
+  'unsharp-crop',
+  'unsharp',
+]
+
+foreach testname : testnames
+  test(testname.underscorify(),
+    find_program(testname + '.sh'),
+    env: [
+      'ABS_TOP_BUILDDIR=' + meson.build_root(),
+      'ABS_TOP_SRCDIR='   + meson.source_root(),
+      'GEGL_SWAP=RAM',
+      'GEGL_PATH=' + meson.build_root() / 'operations',
+    ],
+    suite: 'mipmap',
+  )
+endforeach
diff --git a/tests/opencl/meson.build b/tests/opencl/meson.build
new file mode 100644
index 000000000..7fd9f21a4
--- /dev/null
+++ b/tests/opencl/meson.build
@@ -0,0 +1,43 @@
+
+test_list = [
+  'bilateral-filter',
+  'box-blur',
+  'brightness-contrast',
+  'color-temperature',
+  'edge-sobel',
+  'gaussian-blur',
+  'invert-linear',
+  'levels',
+  'mono-mixer',
+  'motion-blur',
+  'noise-reduction',
+  'oilify',
+  'opacity',
+  'pixelize',
+  'snn-mean',
+  'svg-src-over',
+  'threshold',
+  'value-invert',
+  'vignette',
+]
+
+opencl_test = find_program('opencl_test.sh')
+foreach test_name: test_list
+  xml_file = meson.current_source_dir() / test_name + '.xml'
+  out_dir  = meson.current_build_dir()
+  out_name = test_name + '.png'
+
+  test(test_name,
+    opencl_test,
+    env: [
+      'ABS_BUILDDIR='+ out_dir,
+      'GEGL_BIN='+ gegl_bin.full_path(),
+      'GEGL_IMGCMP_BIN='+ gegl_imgcmp.full_path(),
+      'XML_FILE='+ xml_file,
+      'OUT_FILE='+ out_name,
+      'GEGL_SWAP=RAM',
+      'GEGL_PATH='+ meson.build_root() / 'operations',
+    ],
+    suite: 'opencl',
+  )
+endforeach
diff --git a/tests/opencl/opencl_test.sh b/tests/opencl/opencl_test.sh
new file mode 100644
index 000000000..724e58128
--- /dev/null
+++ b/tests/opencl/opencl_test.sh
@@ -0,0 +1,13 @@
+#!/bin/bash -e
+outdir_normal="${ABS_BUILDDIR}/output"
+outdir_opencl="${ABS_BUILDDIR}/output_cl"
+
+mkdir -p "${outdir_normal}"
+mkdir -p "${outdir_opencl}"
+
+GEGL_USE_OPENCL=no  "${GEGL_BIN}" "${XML_FILE}" -o "${outdir_normal}/${OUT_FILE}"
+GEGL_USE_OPENCL=yes "${GEGL_BIN}" "${XML_FILE}" -o "${outdir_opencl}/${OUT_FILE}"
+
+"${GEGL_IMGCMP_BIN}" \
+    "${outdir_normal}/${OUT_FILE}" \
+    "${outdir_opencl}/${OUT_FILE}"
diff --git a/tests/python/meson.build b/tests/python/meson.build
new file mode 100644
index 000000000..45f840213
--- /dev/null
+++ b/tests/python/meson.build
@@ -0,0 +1,24 @@
+
+testnames = [
+  'gegl-buffer',
+  'gegl-color',
+  'gegl-format',
+  'gegl-node',
+  'gegl',
+]
+
+if python.found() and pygobject_found
+  foreach testname : testnames
+    testfile = 'test-' + testname + '.py'
+    test(testname,
+      find_program(testfile),
+      env: [
+        'LD_LIBRARY_PATH=' + meson.build_root() / 'gegl' + ':$LD_LIBRARY_PATH',
+        'GI_TYPELIB_PATH=' + meson.build_root() / 'gegl' + ':$GI_TYPELIB_PATH',
+        'GEGL_PATH='+ meson.build_root() / 'operations',
+        'GEGL_SWAP=RAM',
+      ],
+      suite: 'python',
+    )
+  endforeach
+endif
diff --git a/tests/simple/meson.build b/tests/simple/meson.build
new file mode 100644
index 000000000..66a752632
--- /dev/null
+++ b/tests/simple/meson.build
@@ -0,0 +1,59 @@
+testnames = [
+  'backend-file',
+  'buffer-cast',
+  'buffer-changes',
+  'buffer-extract',
+  'buffer-hot-tile',
+  'buffer-sharing',
+  'buffer-tile-voiding',
+  'change-processor-rect',
+  'color-op',
+  'convert-format',
+  'empty-tile',
+  'format-sensing',
+  'gegl-color',
+  'gegl-rectangle',
+  'gegl-tile',
+  'image-compare',
+  'license-check',
+  'misc',
+  'node-connections',
+  'node-exponential',
+  'node-passthrough',
+  'node-properties',
+  'object-forked',
+  'opencl-colors',
+  'path',
+  'proxynop-processing',
+  'scaled-blit',
+  'serialize',
+  'svg-abyss',
+]
+
+foreach testname : testnames
+
+  test_exe = executable(testname,
+    'test-' + testname + '.c',
+    include_directories: [ rootInclude, geglInclude, ],
+    dependencies: [
+      babl,
+      glib,
+      gobject,
+    ],
+    link_with: [
+      gegl_lib,
+    ],
+    install: false,
+  )
+  test(testname,
+    test_exe,
+    env: [
+      'ABS_TOP_BUILDDIR=' + meson.build_root(),
+      'ABS_TOP_SRCDIR='   + meson.source_root(),
+      'GEGL_SWAP=RAM',
+      'GEGL_PATH='+ meson.build_root() / 'operations',
+    ],
+    suite: 'simple',
+  )
+
+endforeach
diff --git a/tests/xml/meson.build b/tests/xml/meson.build
new file mode 100644
index 000000000..d5e15e5ea
--- /dev/null
+++ b/tests/xml/meson.build
@@ -0,0 +1,33 @@
+
+xml_test_names = [
+  'test-load',
+  'test-roundtrip',
+  'test-save',
+]
+
+
+foreach xml_test_name : xml_test_names
+  xml_test = executable(xml_test_name,
+    xml_test_name + '.c',
+    include_directories: [ rootInclude, geglInclude, ],
+    dependencies: [
+      babl,
+      glib,
+      gobject,
+    ],
+    link_with: [
+      gegl_lib,
+    ]
+  )
+  test(xml_test_name.underscorify(),
+    xml_test,
+    env: [
+      'ABS_TOP_BUILDDIR=' + meson.build_root(),
+      'ABS_TOP_SRCDIR='   + meson.source_root(),
+      'GEGL_SWAP=RAM',
+      'GEGL_PATH=' + meson.build_root() / 'operations',
+    ],
+    suite: 'xml',
+  )
+
+endforeach
diff --git a/tools/meson.build b/tools/meson.build
new file mode 100644
index 000000000..74fd37fcd
--- /dev/null
+++ b/tools/meson.build
@@ -0,0 +1,80 @@
+
+tools_deps = [
+  babl,
+  glib,
+  gobject,
+]
+
+tools_c_args = [
+  '-DTOP_SRCDIR="' + meson.source_root() + '"',
+]
+
+detect_opencl = executable(
+  'detect_opencl',
+  'detect_opencl.c',
+  include_directories: [ rootInclude, geglInclude, ],
+  dependencies: [ tools_deps, ],
+  link_with: [ gegl_lib, ],
+  c_args: [ tools_c_args ],
+  install: false,
+)
+gegl_imgcmp = executable(
+  'gegl-imgcmp',
+  'gegl-imgcmp.c',
+  include_directories: [ rootInclude, geglInclude, ],
+  dependencies: [ tools_deps, ],
+  link_with: [ gegl_lib, ],
+  c_args: [ tools_c_args ],
+  install: true,
+)
+gegl_tester = executable(
+  'gegl-tester',
+  'gegl-tester.c',
+  include_directories: [ rootInclude, geglInclude, ],
+  dependencies: [ tools_deps, ],
+  link_with: [ gegl_lib, ],
+  c_args: [ tools_c_args ],
+  install: false,
+)
+introspect = executable(
+  'introspect',
+  'introspect.c',
+  include_directories: [ rootInclude, geglInclude, ],
+  dependencies: [ tools_deps, ],
+  link_with: [ gegl_lib, ],
+  c_args: [ tools_c_args ],
+  install: false,
+)
+operation_reference = executable(
+  'operation_reference',
+  'operation_reference.c',
+  include_directories: [ rootInclude, geglInclude, ],
+  dependencies: [ tools_deps, ],
+  link_with: [ gegl_lib, ],
+  c_args: [ tools_c_args ],
+  install: false,
+)
+operations_html = executable(
+  'operations_html',
+  'operations_html.c',
+  include_directories: [ rootInclude, geglInclude, ],
+  dependencies: [ tools_deps, ],
+  link_with: [ gegl_lib, ],
+  c_args: [ tools_c_args ],
+  install: false,
+)
+
+if gexiv2.found()
+  exp_combine = executable(
+    'exp_combine',
+    'exp_combine.cpp',
+    include_directories: [ rootInclude, geglInclude, ],
+    dependencies: [ tools_deps, gexiv2, ],
+    link_with: [ gegl_lib, ],
+    c_args: [ tools_c_args ],
+    install: false,
+  )
+endif
+
+gen_loader = find_program('gen-loader.sh')
+gobj2dot   = find_program('gobj2dot.rb')


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]