[cairo-commit] 2 commits - boilerplate/make-cairo-boilerplate-constructors.py boilerplate/make-cairo-boilerplate-constructors.sh boilerplate/meson.build configure.ac meson.build meson-cc-tests/atomic-ops-cxx11.c meson-cc-tests/atomic-ops-gcc-legacy.c meson-cc-tests/ft_has_color.c meson-cc-tests/ipc_rmid_deferred_release.c meson-cc-tests/mkdir-variant-1.c meson-cc-tests/mkdir-variant-2.c meson-cc-tests/pthread.c meson_options.txt src/cairo-compiler-private.h src/meson.build subprojects/expat.wrap subprojects/fontconfig.wrap subprojects/freetype2.wrap subprojects/.gitignore subprojects/glib.wrap subprojects/libffi.wrap subprojects/libpng.wrap subprojects/pixman.wrap subprojects/proxy-libintl.wrap subprojects/zlib.wrap test/bitmap-font.c test/cairo-test.h test/make-cairo-test-constructors.py test/meson.build test/pdiff util/cairo-fdr util/cairo-gobject util/cairo-missing util/cairo-script util/cairo-sphinx util/cairo-trace util/meson.build

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Sun Aug 2 11:27:00 UTC 2020


 boilerplate/make-cairo-boilerplate-constructors.py |   38 
 boilerplate/make-cairo-boilerplate-constructors.sh |    2 
 boilerplate/meson.build                            |   43 
 configure.ac                                       |   11 
 meson-cc-tests/atomic-ops-cxx11.c                  |    3 
 meson-cc-tests/atomic-ops-gcc-legacy.c             |    3 
 meson-cc-tests/ft_has_color.c                      |    7 
 meson-cc-tests/ipc_rmid_deferred_release.c         |   18 
 meson-cc-tests/mkdir-variant-1.c                   |   12 
 meson-cc-tests/mkdir-variant-2.c                   |   12 
 meson-cc-tests/pthread.c                           |   35 
 meson.build                                        |  918 +++++++++++++++++++++
 meson_options.txt                                  |   34 
 src/cairo-compiler-private.h                       |    6 
 src/meson.build                                    |  322 +++++++
 subprojects/.gitignore                             |   10 
 subprojects/expat.wrap                             |   10 
 subprojects/fontconfig.wrap                        |    5 
 subprojects/freetype2.wrap                         |    5 
 subprojects/glib.wrap                              |    5 
 subprojects/libffi.wrap                            |    4 
 subprojects/libpng.wrap                            |   10 
 subprojects/pixman.wrap                            |    5 
 subprojects/proxy-libintl.wrap                     |    4 
 subprojects/zlib.wrap                              |   10 
 test/bitmap-font.c                                 |    6 
 test/cairo-test.h                                  |    2 
 test/make-cairo-test-constructors.py               |   37 
 test/meson.build                                   |  627 ++++++++++++++
 test/pdiff/meson.build                             |   21 
 util/cairo-fdr/meson.build                         |   11 
 util/cairo-gobject/meson.build                     |   25 
 util/cairo-missing/meson.build                     |   11 
 util/cairo-script/meson.build                      |   65 +
 util/cairo-sphinx/meson.build                      |   26 
 util/cairo-trace/meson.build                       |   30 
 util/meson.build                                   |   66 +
 37 files changed, 2457 insertions(+), 2 deletions(-)

New commits:
commit 596a82f2d185b101bd74645492821fe2f9e0daa0
Author: Mathieu Duponchelle <mathieu at centricular.com>
Date:   Mon May 21 20:08:22 2018 +0200

    Add meson build definitions
    
    Co-Authored by:
    Nirbheek Chauhan <nirbheek at centricular.com>
    lb90 <luca.bacci982 at gmail.com>
    Tim-Philipp Müller <tim at centricular.com>

diff --git a/boilerplate/make-cairo-boilerplate-constructors.py b/boilerplate/make-cairo-boilerplate-constructors.py
new file mode 100644
index 000000000..8e02fa500
--- /dev/null
+++ b/boilerplate/make-cairo-boilerplate-constructors.py
@@ -0,0 +1,38 @@
+# IMPORTANT: Keep in sync with make-cairo-boilerplate-constructors.sh
+#            and test/make-cairo-test-constructors.py!
+import argparse
+import sys
+import re
+
+if __name__=='__main__':
+    parser = argparse.ArgumentParser()
+    parser.add_argument('output')
+    parser.add_argument('input', nargs='+')
+    args = parser.parse_args()
+
+    boilerplate_names = []
+
+    match_boilerplate_line = re.compile(r'^CAIRO_BOILERPLATE.*')
+    match_boilerplate_name = re.compile(r'^CAIRO_BOILERPLATE.*\((.*),.*')
+
+    for fname in args.input:
+        with open(fname, 'r') as f:
+            for l in f.readlines():
+                if match_boilerplate_line.match(l):
+                    boilerplate_names.append(match_boilerplate_name.match(l).group(1))
+
+    with open(args.output, 'w') as f:
+        f.write('/* WARNING: Autogenerated file - see %s! */\n\n' % sys.argv[0])
+        f.write('#include "cairo-boilerplate-private.h"\n\n')
+        f.write('void _cairo_boilerplate_register_all (void);\n\n')
+
+        for boilerplate_name in boilerplate_names:
+            f.write('extern void _register_%s (void);\n' % boilerplate_name)
+
+        f.write('\nvoid\n')
+        f.write('_cairo_boilerplate_register_all (void)\n')
+        f.write('{\n')
+
+        for boilerplate_name in boilerplate_names:
+            f.write('    _register_%s ();\n' % boilerplate_name)
+        f.write('}\n')
diff --git a/boilerplate/make-cairo-boilerplate-constructors.sh b/boilerplate/make-cairo-boilerplate-constructors.sh
index 09716ca9e..1503e9970 100644
--- a/boilerplate/make-cairo-boilerplate-constructors.sh
+++ b/boilerplate/make-cairo-boilerplate-constructors.sh
@@ -1,4 +1,6 @@
 #! /bin/sh
+#
+# IMPORTANT: Keep in sync with make-cairo-boilerplate-constructors.py!
 
 if test $# -eq 0; then
     echo "$0: no input files." >&2
diff --git a/boilerplate/meson.build b/boilerplate/meson.build
new file mode 100644
index 000000000..325396d6e
--- /dev/null
+++ b/boilerplate/meson.build
@@ -0,0 +1,43 @@
+cairo_boilerplate_sources = [
+  'cairo-boilerplate-getopt.c',
+  'cairo-boilerplate-system.c',
+  'cairo-boilerplate.c',
+]
+
+cairo_boilerplate_feature_sources = {
+  'cairo-xlib': ['cairo-boilerplate-xlib.c'],
+  'cairo-qt': ['cairo-boilerplate-qt.cpp'],
+  'cairo-quartz': ['cairo-boilerplate-quartz.c'],
+  'cairo-xcb': ['cairo-boilerplate-xcb.c'],
+  'cairo-win32': ['cairo-boilerplate-win32.c', 'cairo-boilerplate-win32-printing.c'],
+  'cairo-drm': ['cairo-boilerplate-drm.c'],
+  'cairo-cogl': ['cairo-boilerplate-cogl.c'],
+  'cairo-directfb': ['cairo-boilerplate-directfb.c'],
+  'cairo-pdf': ['cairo-boilerplate-pdf.c'],
+  'cairo-ps': ['cairo-boilerplate-ps.c'],
+  'cairo-svg': ['cairo-boilerplate-svg.c'],
+  'cairo-vg': ['cairo-boilerplate-vg.c'],
+  'cairo-script': ['cairo-boilerplate-script.c'],
+  # All tests crash with FPE
+  # 'cairo-egl': ['cairo-boilerplate-egl.c'],
+  # cairo-glx: ['cairo-boilerplate-glx.c'],
+  'cairo-wgl': ['cairo-boilerplate-wgl.c'],
+}
+
+foreach feature: built_features
+  source_key = feature.get('source-key', feature.get('name'))
+  cairo_boilerplate_sources += cairo_boilerplate_feature_sources.get(source_key, [])
+endforeach
+
+cairo_boilerplate_constructors = custom_target('cairo-boilerplate-constructors.c',
+  input: files(cairo_boilerplate_sources),
+  output: 'cairo-boilerplate-constructors.c',
+  command: [python3, files('make-cairo-boilerplate-constructors.py')[0], '@OUTPUT@', '@INPUT@'])
+
+libcairoboilerplate = static_library('cairoboilerplate', cairo_boilerplate_sources + [cairo_boilerplate_constructors],
+  c_args: ['-DHAVE_CONFIG_H'],
+  cpp_args: ['-DHAVE_CONFIG_H'],
+  include_directories: [incbase, incsrc],
+  dependencies: deps,
+  link_with: [libcairo],
+)
diff --git a/configure.ac b/configure.ac
index 2d5151ae7..8b2ab18ec 100644
--- a/configure.ac
+++ b/configure.ac
@@ -136,6 +136,7 @@ CAIRO_ENABLE_SURFACE_BACKEND(xlib_xrender, Xlib Xrender, auto, [
   else
     dnl Check for Xrender header files if the Xrender package is not installed:
     xlib_xrender_BASE=cairo-xlib
+    dnl Keep in sync with meson.build!
     xlib_xrender_REQUIRES="xrender >= 0.6"
     PKG_CHECK_MODULES(xlib_xrender, $xlib_xrender_REQUIRES, ,
 		      [xlib_xrender_REQUIRES=""
@@ -162,6 +163,7 @@ CAIRO_ENABLE_SURFACE_BACKEND(xlib_xrender, Xlib Xrender, auto, [
 dnl ===========================================================================
 
 CAIRO_ENABLE_SURFACE_BACKEND(xcb, XCB, auto, [
+  dnl Keep in sync with meson.build!
   xcb_REQUIRES="xcb >= 1.6 xcb-render >= 1.6"
   PKG_CHECK_MODULES(xcb, $xcb_REQUIRES, ,
 		    [use_xcb="no (requires $xcb_REQUIRES https://xcb.freedesktop.org)"])
@@ -190,6 +192,7 @@ CAIRO_ENABLE_FUNCTIONS(xcb_shm, XCB/SHM, auto, [
 dnl ===========================================================================
 
 CAIRO_ENABLE_SURFACE_BACKEND(qt, Qt, no, [
+  dnl Keep in sync with meson.build!
   qt_REQUIRES="QtGui >= 4.4.0"
   PKG_CHECK_MODULES(qt, $qt_REQUIRES, ,
 		    [qt_REQUIRES=""
@@ -279,6 +282,7 @@ CAIRO_ENABLE_SURFACE_BACKEND(beos, BeOS/Zeta, no, [
 dnl ===========================================================================
 
 CAIRO_ENABLE_SURFACE_BACKEND(drm, DRM, no, [
+  dnl Keep in sync with meson.build!
   drm_REQUIRES="libudev >= 136, libdrm >= 2.4"
   PKG_CHECK_MODULES(drm, $drm_REQUIRES, ,
    [use_drm="no (requires $drm_REQUIRES, udev is available from git://git.kernel.org/pub/scm/linux/hotplug/udev.git)"])
@@ -504,6 +508,7 @@ dnl ===========================================================================
 # release number - for information only
 FREETYPE_MIN_RELEASE=2.1.9
 # libtool-specific version - this is what is checked
+# Keep in sync with meson.build!
 FREETYPE_MIN_VERSION=9.7.3
 
 CAIRO_ENABLE_FONT_BACKEND(ft, FreeType, auto, [
@@ -538,6 +543,7 @@ CAIRO_ENABLE_FONT_BACKEND(ft, FreeType, auto, [
   ft_LIBS="$FREETYPE_LIBS"
 ])
 
+# Keep in sync with meson.build!
 FONTCONFIG_MIN_VERSION=2.2.95
 CAIRO_ENABLE_FONT_BACKEND(fc, Fontconfig, auto, [
   use_fc=$use_ft
@@ -587,6 +593,7 @@ CAIRO_ENABLE_SURFACE_BACKEND(ps, PostScript, yes, [
 
 dnl ===========================================================================
 
+# Keep in sync with meson.build!
 SPECTRE_VERSION_REQUIRED=0.2.0
 test_ps=no
 any2ppm_ps=no
@@ -625,6 +632,7 @@ CAIRO_ENABLE_SURFACE_BACKEND(pdf, PDF, yes, [
 dnl ===========================================================================
 
 # poppler-0.17.4 fixes text-pattern and text-transform
+# Keep in sync with meson.build!
 POPPLER_VERSION_REQUIRED=0.17.4
 test_pdf=no
 any2ppm_pdf=no
@@ -656,6 +664,7 @@ CAIRO_ENABLE_SURFACE_BACKEND(svg, SVG, yes, [
   fi
 ])
 
+dnl Keep in sync with meson.build!
 LIBRSVG_VERSION_REQUIRED=2.35.0
 test_svg=no
 any2ppm_svg=no
@@ -685,6 +694,7 @@ CAIRO_ENABLE(test_surfaces, test surfaces, no)
 dnl ===========================================================================
 
 CAIRO_ENABLE_SURFACE_BACKEND(image, image, always, [
+  dnl Keep in sync with meson.build!
   pixman_REQUIRES="pixman-1 >= 0.36.0"
   PKG_CHECK_MODULES(pixman, $pixman_REQUIRES, ,
     [use_image="no (requires $pixman_REQUIRES https://cairographics.org/releases/)"])
@@ -733,6 +743,7 @@ dnl ===========================================================================
 dnl Build gobject integration library
 
 CAIRO_ENABLE_FUNCTIONS(gobject, gobject, auto, [
+  dnl Keep in sync with meson.build!
   gobject_REQUIRES="gobject-2.0 glib-2.0 >= 2.14"
   PKG_CHECK_MODULES(GOBJECT, $gobject_REQUIRES, ,
     [use_gobject="no (requires $gobject_REQUIRES https://download.gnome.org/pub/GNOME/sources/glib/)"])
diff --git a/meson-cc-tests/atomic-ops-cxx11.c b/meson-cc-tests/atomic-ops-cxx11.c
new file mode 100644
index 000000000..aeef0d849
--- /dev/null
+++ b/meson-cc-tests/atomic-ops-cxx11.c
@@ -0,0 +1,3 @@
+int atomic_add(int i) { return __atomic_fetch_add(&i, 1, __ATOMIC_SEQ_CST); }
+int atomic_cmpxchg(int i, int j, int k) { return __atomic_compare_exchange_n(&i, &j, k, 0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); }
+int main(void) { return 0; }
diff --git a/meson-cc-tests/atomic-ops-gcc-legacy.c b/meson-cc-tests/atomic-ops-gcc-legacy.c
new file mode 100644
index 000000000..99331968d
--- /dev/null
+++ b/meson-cc-tests/atomic-ops-gcc-legacy.c
@@ -0,0 +1,3 @@
+int atomic_add(int i) { return __sync_fetch_and_add (&i, 1); }
+int atomic_cmpxchg(int i, int j, int k) { return __sync_val_compare_and_swap (&i, j, k); }
+int main(void) { return 0; }
diff --git a/meson-cc-tests/ft_has_color.c b/meson-cc-tests/ft_has_color.c
new file mode 100644
index 000000000..daeed7f35
--- /dev/null
+++ b/meson-cc-tests/ft_has_color.c
@@ -0,0 +1,7 @@
+#include <ft2build.h>
+#include FT_FREETYPE_H
+
+int main(void) {
+  FT_Long has_color = FT_HAS_COLOR(((FT_Face)NULL));
+  return 0;
+}
diff --git a/meson-cc-tests/ipc_rmid_deferred_release.c b/meson-cc-tests/ipc_rmid_deferred_release.c
new file mode 100644
index 000000000..2c9290d25
--- /dev/null
+++ b/meson-cc-tests/ipc_rmid_deferred_release.c
@@ -0,0 +1,18 @@
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+int main()
+{
+    char *shmaddr;
+    int id = shmget (IPC_PRIVATE, 4, IPC_CREAT | 0600);
+    if (id == -1) return 2;
+    shmaddr = shmat (id, 0, 0);
+    shmctl (id, IPC_RMID, 0);
+    if ((char*) shmat (id, 0, 0) == (char*) -1) {
+  shmdt (shmaddr);
+  return 1;
+    }
+    shmdt (shmaddr);
+    shmdt (shmaddr);
+    return 0;
+}
diff --git a/meson-cc-tests/mkdir-variant-1.c b/meson-cc-tests/mkdir-variant-1.c
new file mode 100644
index 000000000..88910d107
--- /dev/null
+++ b/meson-cc-tests/mkdir-variant-1.c
@@ -0,0 +1,12 @@
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#ifdef HAVE_IO_H
+#include <io.h>
+#endif
+
+int main(int ac, char **av)
+{
+  mkdir("hello.world");
+  return 0;
+}
diff --git a/meson-cc-tests/mkdir-variant-2.c b/meson-cc-tests/mkdir-variant-2.c
new file mode 100644
index 000000000..d0ab7b298
--- /dev/null
+++ b/meson-cc-tests/mkdir-variant-2.c
@@ -0,0 +1,12 @@
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#ifdef HAVE_IO_H
+#include <io.h>
+#endif
+
+int main(int ac, char **av)
+{
+  mkdir("hello.world", 0777);
+  return 0;
+}
diff --git a/meson-cc-tests/pthread.c b/meson-cc-tests/pthread.c
new file mode 100644
index 000000000..035cb3a94
--- /dev/null
+++ b/meson-cc-tests/pthread.c
@@ -0,0 +1,35 @@
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE /* for PTHREAD_MUTEX_INITIALIZER under linux */
+#endif
+#include <pthread.h>
+
+pthread_mutex_t test_mutex_initializer = PTHREAD_MUTEX_INITIALIZER;
+int test_mutex (void)
+{
+	int x = 0;
+	pthread_mutex_t mutex;
+	x |= pthread_mutex_init (&mutex, NULL);
+	x |= pthread_mutex_lock (&mutex);
+	x |= pthread_mutex_unlock (&mutex);
+	x |= pthread_mutex_destroy (&mutex);
+	return 0;
+}
+
+int test_mutex_attr (void)
+{
+	int x = 0;
+	pthread_mutexattr_t attr;
+	pthread_mutex_t mutex;
+	x |= pthread_mutexattr_init (&attr);
+	x |= pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_RECURSIVE);
+	x |= pthread_mutex_init (&mutex, &attr);
+	x |= pthread_mutex_lock (&mutex);
+	x |= pthread_mutex_unlock (&mutex);
+	x |= pthread_mutex_destroy (&mutex);
+	x |= pthread_mutexattr_destroy (&attr);
+	return x;
+}
+
+int main(void) {
+  return 0;
+}
diff --git a/meson.build b/meson.build
new file mode 100644
index 000000000..7054232d1
--- /dev/null
+++ b/meson.build
@@ -0,0 +1,918 @@
+project('cairo', 'c', 'cpp',
+  meson_version: '>= 0.50.0',
+  version: '1.17.3',
+)
+
+cc = meson.get_compiler('c')
+
+# Keep in sync with configure.ac!
+freetype_required_version = '>= 9.7.3'
+fontconfig_required_version = '>= 2.2.95'
+xrender_required_version = '>= 0.6'
+xcb_required_version = '>= 1.6'
+xcb_render_required_version = '>= 1.6'
+qtgui_required_version = '>= 4.4.0'
+libudev_required_version = '>= 136'
+libdrm_required_version = '>= 2.4'
+glib_required_version = '>= 2.14'
+
+if cc.get_id() == 'msvc'
+  # Basic usage in the cairo type system that causes spammy and useless warnings
+  add_project_arguments('/wd4244', '/wd4146',
+                        # Don't warn about double -> float truncation
+                        '/wd4305',
+                        language : 'c')
+endif
+
+pkgmod = import('pkgconfig')
+python3 = import('python').find_installation()
+
+check_sizeofs = [
+  ['void *', {'conf-name': 'SIZEOF_VOID_P'}],
+  ['int'],
+  ['long'],
+  ['long long'],
+  ['size_t'],
+]
+
+check_headers = [
+  ['stdint.h'],
+  ['inttypes.h'],
+  ['sys/int_types.h'],
+  ['fcntl.h'],
+  ['unistd.h'],
+  ['signal.h'],
+  ['sys/stat.h'],
+  ['sys/socket.h'],
+  ['sys/poll.h'],
+  ['sys/un.h'],
+  ['sched.h', {'check-funcs': ['sched_getaffinity']}],
+  ['sys/mman.h', {'check-funcs': ['mmap']}],
+  ['time.h', {'check-funcs': ['clock_gettime']}],
+  ['libgen.h'],
+  ['byteswap.h'],
+  ['signal.h'],
+  ['setjmp.h'],
+  ['fenv.h'],
+  ['sys/wait.h'],
+  ['sys/stat.h'],
+  ['io.h'],
+  ['fenv.h', {'check-funcs': ['feenableexcept', 'fedisableexcept', 'feclearexcept']}],
+  ['xlocale.h'],
+  ['sys/ioctl.h'],
+]
+
+check_types = [
+  ['uint64_t', {'headers': ['stdint.h']}],
+  ['uint128_t', {'headers': ['stdint.h']}],
+  ['__uint128_t']
+]
+
+check_funcs = [
+  'alarm',
+  'ctime_r',
+  'localtime_r',
+  'gmtime_r',
+  'drand48',
+  'flockfile',
+  'funlockfile',
+  'getline',
+  'link',
+  'strndup',
+  'fork',
+  'waitpid',
+  'raise',
+  'newlocale',
+  'strtod_l',
+]
+
+check_thread_flags = [
+  [['-D_REENTRANT'], ['-lpthread']],
+  [['-pthread'], []],
+  [['-D_REENTRANT'], [], {'real': false}],
+]
+
+m_dep = cc.find_library('m', required: false)
+# Used in util
+gtk_dep = dependency('gtk+-2.0', required: get_option('gtk2-utils'))
+
+deps = [m_dep]
+test_deps = []
+internal_deps = []
+extra_link_args = []
+
+conf = configuration_data()
+
+lzo_dep = dependency('lzo2', required: false)
+if lzo_dep.found()
+  deps += [lzo_dep]
+  conf.set('HAVE_LZO', 1)
+endif
+
+dl_dep = cc.find_library('dl', required: false)
+if dl_dep.found() and cc.has_function('dlsym', dependencies: [dl_dep])
+  deps += [dl_dep]
+  conf.set('CAIRO_HAS_DLSYM', 1)
+elif cc.has_function('dlsym')
+  conf.set('CAIRO_HAS_DLSYM', 1)
+elif cc.has_function('dlsym', prefix: '#include <dlfcn.h>')
+  conf.set('CAIRO_HAS_DLSYM', 1)
+endif
+
+feature_conf = configuration_data()
+
+# Array of dictionaries, used to generate per-feature pc files
+# Mandatory keys: name, description
+# Optional keys: requires, libs
+built_features = []
+
+zlib_dep = dependency('zlib',
+  required: get_option('zlib'),
+  fallback : ['zlib', 'zlib_dep'],
+)
+if zlib_dep.found()
+  if zlib_dep.type_name() == 'internal'
+    internal_deps += [zlib_dep]
+  else
+    deps += [zlib_dep]
+  endif
+  conf.set('HAVE_ZLIB', 1)
+endif
+
+png_dep = dependency('libpng',
+  required: get_option('png'),
+  fallback: ['libpng', 'png_dep']
+)
+if png_dep.found()
+  feature_conf.set('CAIRO_HAS_SVG_SURFACE', 1)
+  feature_conf.set('CAIRO_HAS_PNG_FUNCTIONS', 1)
+  built_features += [
+    {
+      'name': 'cairo-png',
+      'description': 'PNG functions',
+      'requires': 'libpng',
+    },
+    {
+      'name': 'cairo-svg',
+      'description': 'SVG surface backend',
+      'requires': 'libpng',
+    }
+  ]
+
+  if png_dep.type_name() == 'internal'
+    internal_deps += [png_dep]
+  else
+    deps += [png_dep]
+  endif
+endif
+
+freetype_dep = dependency('freetype2',
+  required: get_option('freetype'),
+  version: freetype_required_version,
+  fallback: ['freetype2', 'freetype_dep'],
+)
+if freetype_dep.found()
+  feature_conf.set('CAIRO_HAS_FT_FONT', 1)
+  built_features += [{
+    'name': 'cairo-ft',
+    'description': 'Freetype font backend',
+    'requires': 'freetype2 @0@'.format(freetype_required_version)
+  }]
+
+  ft_check_funcs = [
+    'FT_Get_X11_Font_Format',
+    'FT_GlyphSlot_Embolden',
+    'FT_GlyphSlot_Oblique',
+    'FT_Load_Sfnt_Table',
+    'FT_Library_SetLcdFilter',
+    'FT_Get_Var_Design_Coordinates',
+    'FT_Done_MM_Var',
+  ]
+
+  if freetype_dep.type_name() == 'internal'
+    foreach func : ft_check_funcs
+      conf.set('HAVE_ at 0@'.format(func.to_upper()), 1)
+    endforeach
+    internal_deps += [freetype_dep]
+  else
+    if not cc.links(files('meson-cc-tests/ft_has_color.c'), dependencies: freetype_dep, name: 'FT has color')
+      conf.set('FT_HAS_COLOR', '(0)')
+    endif
+    check_funcs += ft_check_funcs
+    deps += [freetype_dep]
+  endif
+endif
+
+fontconfig_dep = dependency('fontconfig',
+  required: get_option('fontconfig'),
+  version: fontconfig_required_version,
+  fallback: ['fontconfig', 'fontconfig_dep'],
+)
+if fontconfig_dep.found()
+  fc_check_funcs = [
+    'FcInit',
+    'FcFini'
+  ]
+
+  if fontconfig_dep.type_name() == 'internal'
+    foreach func : fc_check_funcs
+      conf.set('HAVE_ at 0@'.format(func.to_upper()), 1)
+    endforeach
+    internal_deps += [fontconfig_dep]
+  else
+    check_funcs += fc_check_funcs
+    deps += [fontconfig_dep]
+  endif
+
+  feature_conf.set('CAIRO_HAS_FC_FONT', 1)
+  built_features += [{
+    'name': 'cairo-fc',
+    'description': 'Fontconfig font backend',
+    'requires': 'fontconfig @0@'.format(fontconfig_required_version)
+  }]
+endif
+
+x11_dep = dependency('x11', required: get_option('xlib'))
+xext_dep = dependency('xext', required: get_option('xlib'))
+if x11_dep.found() and xext_dep.found()
+  feature_conf.set('CAIRO_HAS_XLIB_SURFACE', 1)
+  built_features += [{
+    'name': 'cairo-xlib',
+    'description': 'Xlib surface backend',
+    'requires': 'x11 xext',
+  }]
+
+  extra_headers = ['X11/Xlibint.h', 'X11/Xproto.h']
+  check_headers += [
+    ['X11/extensions/XShm.h', {'extra-headers': extra_headers}],
+    ['X11/extensions/shmproto.h', {'extra-headers': extra_headers}],
+    ['X11/extensions/shmstr.h', {'extra-headers': extra_headers}],
+  ]
+  deps += [x11_dep, xext_dep]
+  res = cc.run(files('meson-cc-tests/ipc_rmid_deferred_release.c'),
+    dependencies: [x11_dep, xext_dep],
+    name: 'shmctl IPC_RMID allowes subsequent attaches')
+
+  if res.returncode() == 0
+    conf.set('IPC_RMID_DEFERRED_RELEASE', 1)
+  endif
+endif
+
+if feature_conf.get('CAIRO_HAS_XLIB_SURFACE', 0) == 1
+  xrender_dep = dependency('xrender', required: get_option('xlib'),
+                           version: xrender_required_version)
+
+  if xrender_dep.found()
+    check_funcs += [
+      'XRenderCreateSolidFill',
+      'XRenderCreateLinearGradient',
+      'XRenderCreateRadialGradient',
+      'XRenderCreateConicalGradient',
+    ]
+
+    deps += [xrender_dep]
+
+    built_features += [{
+      'name': 'cairo-xlib-xrender',
+      'description': 'Xlib Xrender surface backend',
+      'requires': 'xrender @0@'.format(xrender_required_version),
+    }]
+    feature_conf.set('CAIRO_HAS_XLIB_XRENDER_SURFACE', 1)
+  endif
+endif
+
+xcb_dep = dependency('xcb', required: get_option('xcb'),
+                     version: xcb_required_version)
+xcb_render_dep = dependency('xcb-render', required: get_option('xcb'),
+                            version: xcb_render_required_version)
+if xcb_dep.found() and xcb_render_dep.found()
+  feature_conf.set('CAIRO_HAS_XCB_SURFACE', 1)
+  built_features += [{
+    'name': 'cairo-xcb',
+    'description': 'XCB surface backend',
+    'requires': 'xcb @0@ xcb-render @1@'.format(xcb_required_version, xcb_render_required_version),
+  }]
+
+  deps += [xcb_dep, xcb_render_dep]
+endif
+
+if feature_conf.get('CAIRO_HAS_XCB_SURFACE', 0) == 1 and feature_conf.get('CAIRO_HAS_XLIB_SURFACE', 0) == 1
+  # FIXME: automagic
+  x11xcb_dep = dependency('x11-xcb', required: false)
+  if x11xcb_dep.found()
+    deps += [x11xcb_dep]
+    feature_conf.set('CAIRO_HAS_XLIB_XCB_FUNCTIONS', 1)
+    built_features += [{
+      'name': 'cairo-xlib-xcb',
+      'description': 'Xlib/XCB functions',
+      'requires': 'x11-xcb',
+    }]
+  endif
+endif
+
+if feature_conf.get('CAIRO_HAS_XCB_SURFACE', 0) == 1
+  xcbshm_dep = dependency('xcb-shm', required: get_option('xcb'))
+  if xcbshm_dep.found()
+    feature_conf.set('CAIRO_HAS_XCB_SHM_FUNCTIONS', 1)
+    deps += [xcbshm_dep]
+    built_features += [{
+      'name': 'cairo-xcb-shm',
+      'description': 'XCB/SHM functions',
+      'requires': 'xcb-shm',
+    }]
+  endif
+endif
+
+# Tests crash and burn
+qtgui_dep = dependency('QtGui', required: get_option('qt'),
+                       version: qtgui_required_version)
+if qtgui_dep.found() and false
+  feature_conf.set('CAIRO_HAS_QT_SURFACE', 1)
+  built_features += [{
+    'name': 'cairo-qt',
+    'description': 'Qt surface backend',
+    'requires': 'QtGui @0@'.format(qtgui_required_version),
+    'libs': qtgui_extra_libs,
+  }]
+
+  deps += [qtgui_dep]
+  qtgui_extra_libs = ['-lstdc++']
+  extra_link_args += qtgui_extra_libs
+endif
+
+# Untested
+if cc.has_header('ApplicationServices/ApplicationServices.h')
+  if cc.has_header('CoreGraphics/CoreGraphics.h')
+    quartz_extra_libs = ['-Xlinker', '-framework', '-Xlinker', 'CoreGraphics']
+  else
+    quartz_extra_libs = ['-Xlinker', '-framework', '-Xlinker', 'ApplicationServices']
+  endif
+
+  extra_link_args += quartz_extra_libs
+
+  feature_conf.set('CAIRO_HAS_QUARTZ_SURFACE', 1)
+  feature_conf.set('CAIRO_HAS_QUARTZ_FONT', 1)
+  feature_conf.set('CAIRO_HAS_QUARTZ_IMAGE_SURFACE', 1)
+
+  built_features += [
+    {
+      'name': 'cairo-quartz',
+      'description': 'Quartz surface backend',
+      'libs': quartz_extra_libs,
+    },
+    {
+      'name': 'cairo-quartz-image',
+      'description': 'Quartz Image surface backend',
+      'libs': quartz_extra_libs,
+    },
+    {
+      'name': 'cairo-quartz-font',
+      'description': 'Quartz font backend',
+      'libs': quartz_extra_libs,
+    },
+  ]
+endif
+
+if host_machine.system() == 'windows'
+  win32_extra_libs = ['gdi32', 'msimg32']
+  foreach libname: win32_extra_libs
+    deps += [cc.find_library(libname)]
+  endforeach
+
+  feature_conf.set('CAIRO_HAS_WIN32_SURFACE', 1)
+  built_features += [{
+    'name': 'cairo-win32',
+    'description': 'Microsoft Windows surface backend',
+    'libs': win32_extra_libs,
+  }]
+endif
+
+if feature_conf.get('CAIRO_HAS_WIN32_SURFACE', 0) == 1
+  feature_conf.set('CAIRO_HAS_WIN32_FONT', 1)
+  built_features += [{
+    'name': 'cairo-win32-font',
+    'description': 'Microsoft Windows font backend',
+    'libs': win32_extra_libs,
+  }]
+endif
+
+# FIXME: Doesn't build since at least 2011
+libudev_dep = dependency('libudev', required: get_option('drm'),
+                         version: libudev_required_version)
+libdrm_dep = dependency('libdrm', required: get_option('drm'),
+                        version: libdrm_required_version)
+if libudev_dep.found() and libdrm_dep.found() and false
+  deps += [libudev_dep, libdrm_dep]
+
+  feature_conf.set('CAIRO_HAS_DRM_SURFACE', 1)
+  built_features += [{
+    'name': 'cairo-drm',
+    'description': 'DRM surface backend',
+    'requires': 'libudev @0@ libdrm @1@'.format(libudev_required_version, libdrm_required_version),
+  }]
+endif
+
+# Not even trying to port gallium as it depends on drm
+
+# Not porting BEOS or OS/2 backends either, meson doesn't support those
+
+# GL / GLESV2 / GLESV3 are mutually exclusive
+gl_backend = get_option('gl-backend')
+use_gl = false
+need_egl_functions = false
+need_wgl_functions = false
+need_glx_functions = false
+
+if gl_backend in ['auto', 'gl']
+  gl_dep = dependency('gl', required: gl_backend == 'gl')
+  if not gl_dep.found()
+    if cc.has_header('GL/gl.h')
+      gl_extra_libs = ['-lGL']
+      gl_requires = ''
+      extra_link_args += gl_extra_libs
+      use_gl = true
+    endif
+  elif cc.has_header('GL/gl.h', dependencies: gl_dep) and cc.has_header('GL/glext.h', dependencies: gl_dep)
+    use_gl = true
+    gl_extra_libs = []
+    gl_requires = 'gl'
+    deps += [gl_dep]
+  endif
+endif
+
+
+if use_gl
+  need_egl_functions = true
+  need_wgl_functions = true
+  need_glx_functions = true
+
+  feature_conf.set('CAIRO_HAS_GL_SURFACE', 1)
+  built_features += [{
+    'name': 'cairo-gl',
+    'description': 'OpenGL surface backend',
+    'requires': gl_requires,
+    'libs': gl_extra_libs,
+  }]
+endif
+
+if feature_conf.get('CAIRO_HAS_GL_SURFACE', 0) == 0 and ['auto', 'glesv2'].contains(gl_backend)
+  use_glesv2 = false
+  glesv2_dep = dependency('glesv2', required: gl_backend == 'glesv2')
+  if not glesv2_dep.found()
+    if cc.has_header('GLES2/gl2.h')
+      use_glesv2 = true
+      glesv2_extra_libs = ['-lGLESv2']
+      glesv2_requires = ''
+      extra_link_args += glesv2_extra_libs
+    endif
+  else
+    glesv2_extra_libs = []
+    glesv2_requires = 'glesv2'
+    use_glesv2 = true
+    deps += [glesv2_dep]
+  endif
+
+  if use_glesv2
+    need_egl_functions = true
+
+    feature_conf.set('CAIRO_HAS_GLESV2_SURFACE', 1)
+    built_features += [{
+      'name': 'cairo-glesv2',
+      'source-key': 'cairo-gl',
+      'description': 'OpenGLESv2 surface backend',
+      'requires': glesv2_requires,
+      'libs': glesv2_extra_libs,
+    }]
+  endif
+endif
+
+if feature_conf.get('CAIRO_HAS_GL_SURFACE', 0) == 0 and feature_conf.get('CAIRO_HAS_GLESV2_SURFACE', 0) == 0 and ['auto', 'glesv3'].contains(gl_backend)
+  use_glesv3 = false
+  # glesv3 is provided via libGLESv2.so (there is no libGLESv3, nor glesv3.pc)
+  glesv3_dep = dependency('glesv2', required: gl_backend == 'glesv3')
+  if cc.has_header('GLES3/gl3.h', dependencies: glesv3_dep)
+    use_glesv3 = true
+    if not glesv3_dep.found()
+      glesv3_extra_libs = ['-lGLESv2']
+      extra_link_args += glesv3_extra_libs
+      glesv3_requires = ''
+    else
+      glesv3_extra_libs = []
+      glesv3_requires = 'glesv2'
+      deps += [glesv3_dep]
+    endif
+  endif
+
+  if use_glesv3
+    need_egl_functions = true
+
+    feature_conf.set('CAIRO_HAS_GLESV3_SURFACE', 1)
+    built_features += [{
+      'name': 'cairo-glesv3',
+      'source-key': 'cairo-gl',
+      'description': 'OpenGLESv3 surface backend',
+      'requires': glesv3_requires,
+      'libs': glesv3_extra_libs,
+    }]
+  endif
+endif
+
+# FIXME: Broken for me, depends on experimental API
+# https://gitlab.freedesktop.org/cairo/cairo/-/issues/410
+cogl_dep = dependency('cogl-2.0-experimental', required: get_option('cogl'))
+if cogl_dep.found() and false
+  deps += [cogl_dep]
+
+  feature_conf.set('CAIRO_HAS_COGL_SURFACE', 1)
+  built_features += [{
+    'name': 'cairo-cogl',
+    'description': 'Cogl surface backend',
+    'requires': 'cogl-2.0-experimental',
+  }]
+endif
+
+# Untested
+directfb_dep = dependency('directfb', required: get_option('directfb'))
+if directfb_dep.found()
+  deps += [directfb_dep]
+
+  feature_conf.set('CAIRO_HAS_DIRECTFB_SURFACE', 1)
+  built_features += [{
+    'name': 'cairo-directfb',
+    'description': 'directfb surface backend',
+    'requires': 'directfb',
+  }]
+endif
+
+# Untested
+openvg_dep = cc.find_library('OpenVG', has_headers: 'VG/openvg.h', required: get_option('openvg'))
+if openvg_dep.found()
+  # can we use the dep here somehow instead?
+  openvg_extra_libs = ['-lOpenVG']
+  extra_link_args += openvg_extra_libs
+  need_egl_functions = true
+  need_glx_functions = true
+
+  feature_conf.set('CAIRO_HAS_VG_SURFACE', 1)
+  built_features += [{
+    'name': 'cairo-vg',
+    'description': 'OpenVG surface backend',
+    'libs': openvg_extra_libs,
+  }]
+endif
+
+if need_egl_functions
+  # FIXME: automagic
+  egl_dep = dependency('egl', required: false)
+  use_egl = false
+  egl_extra_libs = []
+  egl_requires = ''
+
+  if not egl_dep.found()
+    if cc.has_header('EGL/egl.h')
+      egl_extra_deps = []
+      csi_dep = cc.find_library('csi', required: false)
+      if csi_dep.found() and cc.has_function('csi_stream_attachresource', dependencies: [csi_dep])
+        egl_extra_deps = [csi_dep]
+        egl_extra_libs = ['-lcsi']
+      endif
+
+      foreach libname : ['EGL', 'egl13', 'egl12', 'egl11']
+        dep = cc.find_library(libname, required: false)
+        if dep.found() and cc.has_function('eglGetError', dependencies: [dep])
+          deps += [dep] + egl_extra_deps
+          egl_extra_libs += ['-l at 0@'.format(libname)]
+          use_egl = true
+          break
+        endif
+      endforeach
+    endif
+  else
+    use_egl = true
+    egl_requires = 'egl'
+    deps += [egl_dep]
+  endif
+
+  if use_egl
+    feature_conf.set('CAIRO_HAS_EGL_FUNCTIONS', 1)
+    built_features += [{
+      'name': 'cairo-egl',
+      'description': 'EGL functions',
+      'libs': egl_extra_libs,
+      'requires': egl_requires,
+    }]
+  endif
+endif
+
+if need_glx_functions
+  # FIXME: automagic
+  if cc.has_header('GL/glx.h')
+    feature_conf.set('CAIRO_HAS_GLX_FUNCTIONS', 1)
+    built_features += [{
+      'name': 'cairo-glx',
+      'description': 'GLX functions',
+      'libs': ['-lGL'],
+    }]
+  endif
+endif
+
+# Untested
+if need_wgl_functions
+  # FIXME: automagic
+  if cc.has_header('windows.h')
+    feature_conf.set('CAIRO_HAS_WGL_FUNCTIONS', 1)
+    built_features += [{
+      'name': 'cairo-wgl',
+      'description': 'WGL functions',
+    }]
+  endif
+endif
+
+gobject_dep = dependency('gobject-2.0',
+  required: get_option('glib'),
+  fallback: ['glib', 'libgobject_dep']
+)
+glib_dep = dependency('glib-2.0',
+  required: get_option('glib'),
+  version: glib_required_version,
+  fallback: ['glib', 'libglib_dep'],
+)
+if gobject_dep.found() and glib_dep.found()
+  feature_conf.set('CAIRO_HAS_GOBJECT_FUNCTIONS', 1)
+  built_features += [{
+    'name': 'cairo-gobject',
+    'description': 'gobject functions',
+    'requires': 'gobject-2.0 glib-2.0 @0@'.format(glib_required_version),
+    'libs': ['-lcairo-gobject'],
+  }]
+endif
+
+if zlib_dep.found()
+  feature_conf.set('CAIRO_HAS_SCRIPT_SURFACE', 1)
+  built_features += [{
+    'name': 'cairo-script',
+    'description': 'script surface backend',
+    'requires': 'zlib',
+  }]
+endif
+
+if zlib_dep.found()
+  feature_conf.set('CAIRO_HAS_PS_SURFACE', 1)
+  built_features += [{
+    'name': 'cairo-ps',
+    'description': 'PostScript surface backend',
+    'requires': 'zlib',
+  }]
+endif
+
+if zlib_dep.found()
+  feature_conf.set('CAIRO_HAS_PDF_SURFACE', 1)
+  built_features += [{
+    'name': 'cairo-pdf',
+    'description': 'PDF surface backend',
+    'requires': 'zlib',
+  }]
+endif
+
+if zlib_dep.found()
+  feature_conf.set('CAIRO_HAS_INTERPRETER', 1)
+endif
+
+if zlib_dep.found() and png_dep.found()
+  feature_conf.set('CAIRO_HAS_XML_SURFACE', 1)
+  built_features += [{
+    'name': 'cairo-xml',
+    'description': 'XML surface backend',
+    'requires': 'zlib',
+  }]
+endif
+
+# Untested, libiberty.h is in a libiberty subfolder for me
+# FIXME: automagic
+bfd_dep = cc.find_library('bfd', required: false)
+if bfd_dep.found() and cc.has_function('bfd_openr', dependencies: [bfd_dep])
+  if cc.has_header('libiberty.h')
+    conf.set('HAVE_BFD', 1)
+    deps += [bfd_dep]
+  endif
+endif
+
+# Untested, see above
+if conf.get('HAVE_BFD', 0) == 1
+  conf.set('CAIRO_HAS_SYMBOL_LOOKUP', 1)
+endif
+
+if feature_conf.get('CAIRO_HAS_PS_SURFACE', 0) == 1
+  gs = find_program('gs', required: get_option('tests'))
+  libspectre_dep = dependency('libspectre', version: '>= 0.2.0',
+                              required: get_option('spectre'))
+  if gs.found() and libspectre_dep.found()
+    conf.set('CAIRO_CAN_TEST_PS_SURFACE', 1)
+  endif
+
+  if libspectre_dep.found()
+    conf.set('CAIRO_HAS_SPECTRE', 1)
+    deps += [libspectre_dep]
+  endif
+endif
+
+if feature_conf.get('CAIRO_HAS_PDF_SURFACE', 0) == 1
+  poppler_dep = dependency('poppler-glib', version: '>= 0.17.4',
+                           required: get_option('tests'))
+  if poppler_dep.found() and cc.has_function('poppler_page_render', dependencies: [poppler_dep])
+    conf.set('CAIRO_CAN_TEST_PDF_SURFACE', 1)
+    test_deps += [poppler_dep]
+  endif
+endif
+
+if feature_conf.get('CAIRO_HAS_SVG_SURFACE', 0) == 1
+  librsvg_dep = dependency('librsvg-2.0', version: '>= 2.35.0',
+                           required: get_option('tests'))
+  if librsvg_dep.found()
+    conf.set('CAIRO_CAN_TEST_SVG_SURFACE', 1)
+    test_deps += [librsvg_dep]
+  endif
+endif
+
+pixman_dep = dependency('pixman-1',
+  version: '>= 0.36.0',
+  fallback: ['pixman', 'idep_pixman'],
+)
+if pixman_dep.found()
+  feature_conf.set('CAIRO_HAS_IMAGE_SURFACE', 1)
+  conf.set('HAS_PIXMAN_GLYPHS', 1)
+  if pixman_dep.type_name() == 'internal'
+    internal_deps += [pixman_dep]
+  else
+    deps += [pixman_dep]
+  endif
+endif
+
+feature_conf.set('CAIRO_FEATURES_H', true)
+feature_conf.set('CAIRO_HAS_USER_FONT', 1)
+
+feature_conf.set('CAIRO_HAS_MIME_SURFACE', 1)
+feature_conf.set('CAIRO_HAS_RECORDING_SURFACE', 1)
+feature_conf.set('CAIRO_HAS_OBSERVER_SURFACE', 1)
+
+feature_conf.set('CAIRO_HAS_TEE_SURFACE', 1)
+built_features += [{
+  'name': 'cairo-tee',
+  'description': 'Tee surface backend',
+}]
+
+incbase = include_directories('.')
+
+foreach check : check_sizeofs
+  type = check[0]
+  opts = check.length() > 1 ? check[1] : {}
+
+  conf_name = opts.get('conf-name', 'SIZEOF_ at 0@'.format(type.underscorify().to_upper()))
+
+  conf.set(conf_name, cc.sizeof(type))
+endforeach
+
+foreach check : check_headers
+  name = check[0]
+  opts = check.length() > 1 ? check[1] : {}
+  prefix = ''
+
+  foreach header : opts.get('extra-headers', [])
+    prefix += '#include <@0@>\n'.format(header)
+  endforeach
+
+  if cc.has_header(name, prefix: prefix)
+    conf.set('HAVE_ at 0@'.format(name.to_upper().underscorify()), 1)
+    check_funcs += check.length() > 1 ? check[1].get('check-funcs', []) : []
+  endif
+endforeach
+
+foreach check : check_types
+  name = check[0]
+  opts = check.length() > 1 ? check[1] : {}
+  prefix = ''
+
+  foreach header : opts.get('headers', [])
+    prefix += '#include <@0@>\n'.format(header)
+  endforeach
+
+  if cc.has_type(name, prefix: prefix)
+    conf.set('HAVE_ at 0@'.format(name.to_upper()), 1)
+  endif
+endforeach
+
+foreach name : check_funcs
+  if cc.has_function(name, dependencies: deps)
+    conf.set('HAVE_ at 0@'.format(name.to_upper()), 1)
+  endif
+endforeach
+
+pthread_c_args = []
+pthread_link_args = []
+
+foreach thread_flags : check_thread_flags
+  if not conf.has('CAIRO_HAS_PTHREAD')
+    cflags = thread_flags[0]
+    lflags = thread_flags[1]
+    real_pthread = thread_flags.length() > 2 ? thread_flags[2].get('real', true) : true
+
+    if cc.links(files('meson-cc-tests/pthread.c'), args: cflags + lflags, name: 'pthreads')
+      conf.set('CAIRO_HAS_PTHREAD', 1)
+      if real_pthread
+        conf.set('CAIRO_HAS_REAL_PTHREAD', 1)
+      endif
+      pthread_c_args = cflags
+      pthread_link_args = lflags
+    endif
+  endif
+endforeach
+
+extra_link_args += pthread_link_args
+
+if cc.links(files('meson-cc-tests/atomic-ops-cxx11.c'), name: 'Atomic ops: cxx11')
+  conf.set('HAVE_CXX11_ATOMIC_PRIMITIVES', 1)
+elif cc.links(files('meson-cc-tests/atomic-ops-gcc-legacy.c'), name: 'Atomic ops: gcc legacy')
+  conf.set('HAVE_GCC_LEGACY_ATOMICS', 1)
+elif cc.has_header('atomic_ops.h')
+  conf.set('HAVE_LIB_ATOMIC_OPS', 1)
+elif cc.has_header('libkern/OSAtomic.h')
+  conf.set('HAVE_OS_ATOMIC_OPS', 1)
+endif
+
+test_mkdir_c_args = []
+if conf.get('HAVE_SYS_STAT_H', 0) == 1
+  test_mkdir_c_args += ['-DHAVE_SYS_STAT_H']
+endif
+
+if conf.get('HAVE_IO_H', 0) == 1
+  test_mkdir_c_args += ['-DHAVE_IO_H']
+endif
+
+if cc.links(files('meson-cc-tests/mkdir-variant-1.c'), args: test_mkdir_c_args)
+  conf.set('HAVE_MKDIR', 1)
+elif cc.links(files('meson-cc-tests/mkdir-variant-2.c'), args: test_mkdir_c_args)
+  conf.set('HAVE_MKDIR', 2)
+else
+  conf.set('HAVE_MKDIR', 0)
+endif
+
+if not ['x86', 'x86_64'].contains(host_machine.cpu_family())
+  conf.set('ATOMIC_OP_NEEDS_MEMORY_BARRIER', 1)
+endif
+
+have_ld_preload = ['linux', 'freebsd', 'darwin', 'dragonfly'].contains(host_machine.system())
+
+if have_ld_preload and zlib_dep.found() and conf.get('CAIRO_HAS_REAL_PTHREAD', 0) == 1 and conf.get('CAIRO_HAS_DLSYM', 0) == 1
+  conf.set('CAIRO_HAS_TRACE', 1)
+endif
+
+rt_dep = cc.find_library('rt', required: false)
+have_shm = false
+if rt_dep.found() and cc.has_function('shm_open', dependencies: [rt_dep])
+  have_shm = true
+endif
+
+# This to make sure we don't run checks against internal deps
+deps += internal_deps
+
+subdir('src')
+
+incboilerplate = include_directories('boilerplate')
+if feature_conf.get('CAIRO_HAS_PNG_FUNCTIONS', 0) == 1
+  subdir('boilerplate')
+else
+  libcairoboilerplate = []
+endif
+
+subdir('util')
+
+if not get_option('tests').disabled() and feature_conf.get('CAIRO_HAS_PNG_FUNCTIONS', 0) == 1
+  subdir('test')
+endif
+
+configure_file(output: 'config.h', configuration: conf)
+
+foreach feature: built_features
+  fconf = configuration_data()
+  fconf.set('prefix', get_option('prefix'))
+  fconf.set('exec_prefix', '${prefix}')
+  fconf.set('libdir', '${exec_prefix}/@0@'.format(get_option('libdir')))
+  fconf.set('includedir', '${prefix}/@0@'.format(get_option('includedir')))
+  fconf.set('FEATURE_PC', feature['name'])
+  fconf.set('FEATURE_NAME', feature['description'])
+  fconf.set('VERSION', meson.project_version())
+  fconf.set('FEATURE_BASE', meson.project_name())
+  fconf.set('FEATURE_REQUIRES', feature.get('requires', ''))
+  fconf.set('FEATURE_NONPKGCONFIG_LIBS', ' '.join(feature.get('libs', [])))
+  fconf.set('FEATURE_NONPKGCONFIG_EXTRA_LIBS', '')
+  fconf.set('FEATURE_NONPKGCONFIG_CFLAGS', '')
+
+  configure_file(input: 'src/cairo-features.pc.in',
+    output: '@0 at .pc'.format(feature['name']),
+    configuration: fconf,
+    install: true,
+    install_dir: join_paths(get_option('prefix'), get_option('libdir'), 'pkgconfig')
+  )
+endforeach
+
+install_headers('cairo-version.h', subdir: 'cairo')
diff --git a/meson_options.txt b/meson_options.txt
new file mode 100644
index 000000000..6dff33efc
--- /dev/null
+++ b/meson_options.txt
@@ -0,0 +1,34 @@
+# Cairo font backends
+option('fontconfig', type : 'feature', value : 'auto')
+option('freetype', type : 'feature', value : 'auto')
+
+# Cairo surface backends
+option('cogl', type : 'feature', value : 'auto')
+option('directfb', type : 'feature', value : 'auto')
+option('gl-backend', type : 'combo', value : 'auto',
+       # FIXME: https://github.com/mesonbuild/meson/issues/4566
+       choices : ['auto', 'gl', 'glesv2', 'glesv3', 'disabled'])
+option('glesv2', type : 'feature', value : 'auto')
+option('glesv3', type : 'feature', value : 'auto')
+option('drm', type : 'feature', value : 'auto')
+option('openvg', type : 'feature', value : 'auto')
+option('png', type : 'feature', value : 'auto') # png and svg surfaces
+option('qt', type : 'feature', value : 'auto')
+option('xcb', type : 'feature', value : 'auto')
+option('xlib', type : 'feature', value : 'auto')
+option('zlib', type : 'feature', value : 'auto') # script, ps, pdf, xml surfaces
+
+# Tests
+option('tests', type : 'feature', value : 'auto')
+
+# Util deps
+option('gtk2-utils', type : 'feature', value : 'disabled')
+
+# Misc deps
+option('glib', type : 'feature', value : 'auto')
+option('spectre', type : 'feature', value : 'auto')
+
+# FIXME: implement these to avoid automagic
+#option('egl', type : 'feature', value : 'auto')
+#option('glx', type : 'feature', value : 'auto')
+#option('wgl', type : 'feature', value : 'auto')
diff --git a/src/meson.build b/src/meson.build
new file mode 100644
index 000000000..5a3fb92e5
--- /dev/null
+++ b/src/meson.build
@@ -0,0 +1,322 @@
+cairo_sources = [
+  'cairo-analysis-surface.c',
+  'cairo-arc.c',
+  'cairo-array.c',
+  'cairo-atomic.c',
+  'cairo-base64-stream.c',
+  'cairo-base85-stream.c',
+  'cairo-bentley-ottmann-rectangular.c',
+  'cairo-bentley-ottmann-rectilinear.c',
+  'cairo-bentley-ottmann.c',
+  'cairo-botor-scan-converter.c',
+  'cairo-boxes-intersect.c',
+  'cairo-boxes.c',
+  'cairo-cache.c',
+  'cairo-clip-boxes.c',
+  'cairo-clip-polygon.c',
+  'cairo-clip-region.c',
+  'cairo-clip-surface.c',
+  'cairo-clip-tor-scan-converter.c',
+  'cairo-clip.c',
+  'cairo-color.c',
+  'cairo-composite-rectangles.c',
+  'cairo-compositor.c',
+  'cairo-contour.c',
+  'cairo-damage.c',
+  'cairo-debug.c',
+  'cairo-default-context.c',
+  'cairo-device.c',
+  'cairo-error.c',
+  'cairo-fallback-compositor.c',
+  'cairo-fixed.c',
+  'cairo-font-face-twin-data.c',
+  'cairo-font-face-twin.c',
+  'cairo-font-face.c',
+  'cairo-font-options.c',
+  'cairo-freed-pool.c',
+  'cairo-freelist.c',
+  'cairo-gstate.c',
+  'cairo-hash.c',
+  'cairo-hull.c',
+  'cairo-image-compositor.c',
+  'cairo-image-info.c',
+  'cairo-image-source.c',
+  'cairo-image-surface.c',
+  'cairo-line.c',
+  'cairo-lzw.c',
+  'cairo-mask-compositor.c',
+  'cairo-matrix.c',
+  'cairo-mempool.c',
+  'cairo-mesh-pattern-rasterizer.c',
+  'cairo-misc.c',
+  'cairo-mono-scan-converter.c',
+  'cairo-mutex.c',
+  'cairo-no-compositor.c',
+  'cairo-observer.c',
+  'cairo-output-stream.c',
+  'cairo-paginated-surface.c',
+  'cairo-path-bounds.c',
+  'cairo-path-fill.c',
+  'cairo-path-fixed.c',
+  'cairo-path-in-fill.c',
+  'cairo-path-stroke-boxes.c',
+  'cairo-path-stroke-polygon.c',
+  'cairo-path-stroke-traps.c',
+  'cairo-path-stroke-tristrip.c',
+  'cairo-path-stroke.c',
+  'cairo-path.c',
+  'cairo-pattern.c',
+  'cairo-pen.c',
+  'cairo-polygon-intersect.c',
+  'cairo-polygon-reduce.c',
+  'cairo-polygon.c',
+  'cairo-raster-source-pattern.c',
+  'cairo-recording-surface.c',
+  'cairo-rectangle.c',
+  'cairo-rectangular-scan-converter.c',
+  'cairo-region.c',
+  'cairo-rtree.c',
+  'cairo-scaled-font.c',
+  'cairo-shape-mask-compositor.c',
+  'cairo-slope.c',
+  'cairo-spans-compositor.c',
+  'cairo-spans.c',
+  'cairo-spline.c',
+  'cairo-stroke-dash.c',
+  'cairo-stroke-style.c',
+  'cairo-surface-clipper.c',
+  'cairo-surface-fallback.c',
+  'cairo-surface-observer.c',
+  'cairo-surface-offset.c',
+  'cairo-surface-snapshot.c',
+  'cairo-surface-subsurface.c',
+  'cairo-surface-wrapper.c',
+  'cairo-surface.c',
+  'cairo-time.c',
+  'cairo-tor-scan-converter.c',
+  'cairo-tor22-scan-converter.c',
+  'cairo-toy-font-face.c',
+  'cairo-traps-compositor.c',
+  'cairo-traps.c',
+  'cairo-tristrip.c',
+  'cairo-unicode.c',
+  'cairo-user-font.c',
+  'cairo-version.c',
+  'cairo-wideint.c',
+  'cairo.c',
+  'cairo-cff-subset.c',
+  'cairo-scaled-font-subsets.c',
+  'cairo-truetype-subset.c',
+  'cairo-type1-fallback.c',
+  'cairo-type1-glyph-names.c',
+  'cairo-type1-subset.c',
+  'cairo-type3-glyph-surface.c',
+  'cairo-pdf-operators.c',
+  'cairo-pdf-shading.c',
+  'cairo-tag-attributes.c',
+  'cairo-deflate-stream.c',
+]
+
+cairo_headers = [
+  'cairo.h',
+  'cairo-deprecated.h',
+]
+
+cairo_feature_sources = {
+  'cairo-png': [
+    'cairo-png.c',
+  ],
+  'cairo-ft': [
+    'cairo-ft-font.c',
+  ],
+
+  'cairo-xlib': [
+    'cairo-xlib-display.c',
+    'cairo-xlib-core-compositor.c',
+    'cairo-xlib-fallback-compositor.c',
+    'cairo-xlib-render-compositor.c',
+    'cairo-xlib-screen.c',
+    'cairo-xlib-source.c',
+    'cairo-xlib-surface.c',
+    'cairo-xlib-surface-shm.c',
+    'cairo-xlib-visual.c',
+    'cairo-xlib-xcb-surface.c',
+  ],
+  'cairo-xcb': [
+    'cairo-xcb-connection.c',
+    'cairo-xcb-connection-core.c',
+    'cairo-xcb-connection-render.c',
+    'cairo-xcb-connection-shm.c',
+    'cairo-xcb-screen.c',
+    'cairo-xcb-shm.c',
+    'cairo-xcb-surface.c',
+    'cairo-xcb-surface-core.c',
+    'cairo-xcb-surface-render.c',
+    'cairo-xcb-resources.c',
+  ],
+  'cairo-qt': [
+    'cairo-qt-surface.cpp',
+  ],
+  'cairo-quartz': [
+    'cairo-quartz-surface.c',
+  ],
+  'cairo-quartz-image': [
+    'cairo-quartz-image-surface.c',
+  ],
+  'cairo-quartz-font': [
+    'cairo-quartz-font.c',
+  ],
+  'cairo-win32': [
+    'win32/cairo-win32-debug.c',
+    'win32/cairo-win32-device.c',
+    'win32/cairo-win32-gdi-compositor.c',
+    'win32/cairo-win32-system.c',
+    'win32/cairo-win32-surface.c',
+    'win32/cairo-win32-display-surface.c',
+    'win32/cairo-win32-printing-surface.c',
+  ],
+  'cairo-win32-font': [
+    'win32/cairo-win32-font.c',
+  ],
+  'cairo-drm': [
+    'drm/cairo-drm.c',
+    'drm/cairo-drm-bo.c',
+    'drm/cairo-drm-surface.c',
+    'drm/cairo-drm-intel.c',
+    'drm/cairo-drm-intel-debug.c',
+    'drm/cairo-drm-intel-surface.c',
+    'drm/cairo-drm-i915-surface.c',
+    'drm/cairo-drm-i915-glyphs.c',
+    'drm/cairo-drm-i915-shader.c',
+    'drm/cairo-drm-i915-spans.c',
+    'drm/cairo-drm-i965-surface.c',
+    'drm/cairo-drm-i965-glyphs.c',
+    'drm/cairo-drm-i965-shader.c',
+    'drm/cairo-drm-i965-spans.c',
+    'drm/cairo-drm-intel-brw-eu.c',
+    'drm/cairo-drm-intel-brw-eu-emit.c',
+    'drm/cairo-drm-intel-brw-eu-util.c',
+    'drm/cairo-drm-radeon.c',
+    'drm/cairo-drm-radeon-surface.c',
+  ],
+  'cairo-gl': [
+    'cairo-gl-composite.c',
+    'cairo-gl-device.c',
+    'cairo-gl-dispatch.c',
+    'cairo-gl-glyphs.c',
+    'cairo-gl-gradient.c',
+    'cairo-gl-info.c',
+    'cairo-gl-msaa-compositor.c',
+    'cairo-gl-operand.c',
+    'cairo-gl-shaders.c',
+    'cairo-gl-source.c',
+    'cairo-gl-spans-compositor.c',
+    'cairo-gl-surface.c',
+    'cairo-gl-traps-compositor.c',
+  ],
+  'cairo-cogl': [
+    'cairo-cogl-surface.c',
+    'cairo-cogl-gradient.c',
+    'cairo-cogl-context.c',
+    'cairo-cogl-utils.c',
+  ],
+  'cairo-directfb': [
+    'cairo-directfb-surface.c',
+  ],
+  'cairo-vg': [
+    'cairo-vg-surface.c',
+  ],
+  'cairo-script': [
+    'cairo-script-surface.c',
+  ],
+  'cairo-ps': [
+    'cairo-ps-surface.c',
+  ],
+  'cairo-pdf': [
+    'cairo-pdf-surface.c',
+    'cairo-pdf-interchange.c',
+    'cairo-tag-stack.c',
+  ],
+  'cairo-svg': [
+    'cairo-svg-surface.c',
+  ],
+  'cairo-egl': [
+    'cairo-egl-context.c',
+  ],
+  'cairo-glx': [
+    'cairo-glx-context.c',
+  ],
+  'cairo-wgl': [
+    'cairo-wgl-context.c',
+  ],
+  'cairo-xml': [
+    'cairo-xml-surface.c',
+  ],
+  'cairo-tee': [
+    'cairo-tee-surface.c',
+  ],
+}
+
+cairo_feature_headers = {
+  'cairo-ps': ['cairo-ps.h'],
+  'cairo-pdf': ['cairo-pdf.h'],
+  'cairo-svg': ['cairo-svg.h'],
+  'cairo-ft': ['cairo-ft.h'],
+  'cairo-xlib': ['cairo-xlib.h'],
+  'cairo-xlib-xrender': ['cairo-xlib-xrender.h'],
+  'cairo-xcb': ['cairo-xcb.h'],
+  'cairo-qt': ['cairo-qt.h'],
+  'cairo-quartz': ['cairo-quartz.h'],
+  'cairo-quartz-image': ['cairo-quartz-image.h'],
+  'cairo-win32': ['cairo-win32.h'],
+  'cairo-gl': ['cairo-gl.h'],
+  'cairo-directfb': ['cairo-directfb.h'],
+  'cairo-drm': ['cairo-drm.h'],
+  'cairo-script': ['cairo-script.h'],
+  'cairo-tee': ['cairo-tee.h'],
+  'cairo-xml': ['cairo-xml.h'],
+  'cairo-vg': ['cairo-vg.h'],
+  'cairo-cogl': ['cairo-cogl.h'],
+}
+
+cairo_no_warn_c_args = cc.get_supported_arguments([
+  '-Wno-attributes',
+  '-Wno-unused-but-set-variable',
+  '-Wno-missing-field-initializers',
+  '-Wno-unused-parameter',
+  '-Wno-long-long',
+])
+
+foreach feature: built_features
+  source_key = feature.get('source-key', feature.get('name'))
+  cairo_sources += cairo_feature_sources.get(source_key, [])
+  cairo_headers += cairo_feature_headers.get(source_key, [])
+endforeach
+
+incsrc = include_directories('.')
+
+libcairo = library('cairo', cairo_sources,
+  dependencies: deps,
+  c_args: cairo_no_warn_c_args + pthread_c_args + ['-DHAVE_CONFIG_H'],
+  cpp_args: cairo_no_warn_c_args + pthread_c_args + ['-DHAVE_CONFIG_H'],
+  link_args: extra_link_args,
+  soversion: '2',
+  version: '2.' + ''.join(meson.project_version().split('.')) + '.0',
+  install: true,
+  include_directories: incbase,
+)
+
+cairo_headers += [configure_file(output: 'cairo-features.h', configuration: feature_conf)]
+
+libcairo_dep = declare_dependency(link_with: libcairo,
+  include_directories: incbase)
+
+pkgmod.generate(libcairo,
+  description: 'Multi-platform 2D graphics library',
+  subdirs: [meson.project_name()],
+  version: meson.project_version(),
+)
+
+install_headers(cairo_headers, subdir: 'cairo')
+
+libcairo_dep = declare_dependency(link_with: libcairo, include_directories: incsrc)
diff --git a/subprojects/.gitignore b/subprojects/.gitignore
new file mode 100644
index 000000000..e1affbbba
--- /dev/null
+++ b/subprojects/.gitignore
@@ -0,0 +1,10 @@
+/expat-2.2.5
+/freetype2
+/glib
+/fontconfig
+/libffi
+/proxy-libintl
+/zlib
+/packagecache
+/pixman
+/libpng*
diff --git a/subprojects/expat.wrap b/subprojects/expat.wrap
new file mode 100644
index 000000000..0b7c53e54
--- /dev/null
+++ b/subprojects/expat.wrap
@@ -0,0 +1,10 @@
+[wrap-file]
+directory = expat-2.2.5
+
+source_url = https://github.com/libexpat/libexpat/releases/download/R_2_2_5/expat-2.2.5.tar.bz2
+source_filename = expat-2.2.5.tar.bz2
+source_hash = d9dc32efba7e74f788fcc4f212a43216fc37cf5f23f4c2339664d473353aedf6
+
+patch_url = https://wrapdb.mesonbuild.com/v1/projects/expat/2.2.5/4/get_zip
+patch_filename = expat-2.2.5-4-wrap.zip
+patch_hash = 25748839be2bbdd2ff586d1a05aa6fc37aeada75c78416df6e8347a6321abaac
diff --git a/subprojects/fontconfig.wrap b/subprojects/fontconfig.wrap
new file mode 100644
index 000000000..083a49d6a
--- /dev/null
+++ b/subprojects/fontconfig.wrap
@@ -0,0 +1,5 @@
+[wrap-git]
+directory=fontconfig
+url=https://github.com/centricular/fontconfig.git
+push-url=git at github.com:centricular/fontconfig.git
+revision=meson
diff --git a/subprojects/freetype2.wrap b/subprojects/freetype2.wrap
new file mode 100644
index 000000000..3151539c8
--- /dev/null
+++ b/subprojects/freetype2.wrap
@@ -0,0 +1,5 @@
+[wrap-git]
+directory=freetype2
+url=https://github.com/centricular/freetype2.git
+push-url=git at github.com:centricular/freetype2.git
+revision=meson
diff --git a/subprojects/glib.wrap b/subprojects/glib.wrap
new file mode 100644
index 000000000..3964b1c25
--- /dev/null
+++ b/subprojects/glib.wrap
@@ -0,0 +1,5 @@
+[wrap-git]
+directory=glib
+url=https://gitlab.gnome.org/GNOME/glib.git
+push-url=git at gitlab.gnome.org:GNOME/glib.git
+revision=2.64.4
diff --git a/subprojects/libffi.wrap b/subprojects/libffi.wrap
new file mode 100644
index 000000000..6dea9ebed
--- /dev/null
+++ b/subprojects/libffi.wrap
@@ -0,0 +1,4 @@
+[wrap-git]
+directory=libffi
+url=https://gitlab.freedesktop.org/gstreamer/meson-ports/libffi.git
+revision=meson
diff --git a/subprojects/libpng.wrap b/subprojects/libpng.wrap
new file mode 100644
index 000000000..30774eb72
--- /dev/null
+++ b/subprojects/libpng.wrap
@@ -0,0 +1,10 @@
+[wrap-file]
+directory = libpng-1.6.35
+
+source_url = https://github.com/glennrp/libpng/archive/v1.6.35.tar.gz
+source_filename = libpng-1.6.35.tar.gz
+source_hash = 6d59d6a154ccbb772ec11772cb8f8beb0d382b61e7ccc62435bf7311c9f4b210
+
+patch_url = https://wrapdb.mesonbuild.com/v1/projects/libpng/1.6.35/5/get_zip
+patch_filename = libpng-1.6.35-5-wrap.zip
+patch_hash = da42b18e8d75a88615bdbc1c7bbf1f739ae19f63a8e70d96c90bc448326ae6b7
diff --git a/subprojects/pixman.wrap b/subprojects/pixman.wrap
new file mode 100644
index 000000000..71d585829
--- /dev/null
+++ b/subprojects/pixman.wrap
@@ -0,0 +1,5 @@
+[wrap-git]
+directory=pixman
+url=https://gitlab.freedesktop.org/pixman/pixman.git
+push-url=git at gitlab.freedesktop.org:pixman/pixman.git
+revision=master
diff --git a/subprojects/proxy-libintl.wrap b/subprojects/proxy-libintl.wrap
new file mode 100644
index 000000000..b53c8f7c3
--- /dev/null
+++ b/subprojects/proxy-libintl.wrap
@@ -0,0 +1,4 @@
+[wrap-git]
+directory=proxy-libintl
+url=https://github.com/frida/proxy-libintl.git
+revision=0.1
diff --git a/subprojects/zlib.wrap b/subprojects/zlib.wrap
new file mode 100644
index 000000000..ff9ab6680
--- /dev/null
+++ b/subprojects/zlib.wrap
@@ -0,0 +1,10 @@
+[wrap-file]
+directory = zlib-1.2.11
+
+source_url = https://zlib.net/fossils/zlib-1.2.11.tar.gz
+source_filename = zlib-1.2.11.tar.gz
+source_hash = c3e5e9fdd5004dcb542feda5ee4f0ff0744628baf8ed2dd5d66f8ca1197cb1a1
+
+patch_url = https://github.com/mesonbuild/zlib/releases/download/1.2.11-3/zlib.zip
+patch_filename = zlib-1.2.11-3-wrap.zip
+patch_hash = f07dc491ab3d05daf00632a0591e2ae61b470615b5b73bcf9b3f061fff65cff0
diff --git a/test/make-cairo-test-constructors.py b/test/make-cairo-test-constructors.py
new file mode 100644
index 000000000..329763ccd
--- /dev/null
+++ b/test/make-cairo-test-constructors.py
@@ -0,0 +1,37 @@
+# IMPORTANT: Keep in sync with boilerplate/make-cairo-boilerplate-constructors.py!
+import argparse
+import sys
+import re
+
+if __name__=='__main__':
+    parser = argparse.ArgumentParser()
+    parser.add_argument('output')
+    parser.add_argument('input', nargs='+')
+    args = parser.parse_args()
+
+    test_names = []
+
+    match_test_line = re.compile(r'^CAIRO_TEST.*')
+    match_test_name = re.compile(r'^CAIRO_TEST.*\((.*),.*')
+
+    for fname in args.input:
+        with open(fname, 'r') as f:
+            for l in f.readlines():
+                if match_test_line.match(l):
+                    test_names.append(match_test_name.match(l).group(1))
+
+    with open(args.output, 'w') as f:
+        f.write('/* WARNING: Autogenerated file - see %s! */\n\n' % sys.argv[0])
+        f.write('#include "cairo-test-private.h"\n\n')
+        f.write('void _cairo_test_runner_register_tests (void);\n\n')
+
+        for test_name in test_names:
+            f.write('extern void _register_%s (void);\n' % test_name)
+
+        f.write('void\n')
+        f.write('_cairo_test_runner_register_tests (void)\n')
+        f.write('{\n')
+
+        for test_name in test_names:
+            f.write('    _register_%s ();\n' % test_name)
+        f.write('}\n')
diff --git a/test/meson.build b/test/meson.build
new file mode 100644
index 000000000..0e2e23673
--- /dev/null
+++ b/test/meson.build
@@ -0,0 +1,627 @@
+test_sources = [
+  'a1-bug.c',
+  'a1-clip.c',
+  'a1-fill.c',
+  'a1-image-sample.c',
+  'a1-mask.c',
+  'a1-mask-sample.c',
+  'a1-sample.c',
+  'a1-traps-sample.c',
+  'a1-rasterisation.c',
+  'a8-clear.c',
+  'a8-mask.c',
+  'aliasing.c',
+  'alpha-similar.c',
+  'arc-direction.c',
+  'arc-infinite-loop.c',
+  'arc-looping-dash.c',
+  'api-special-cases.c',
+  'big-line.c',
+  'big-empty-box.c',
+  'big-empty-triangle.c',
+  'big-little-box.c',
+  'big-little-triangle.c',
+  'bug-spline.c',
+  'big-trap.c',
+  'bilevel-image.c',
+  'bug-40410.c',
+  'bug-51910.c',
+  'bug-84115.c',
+  'bug-bo-rectangular.c',
+  'bug-bo-collins.c',
+  'bug-bo-ricotz.c',
+  'bug-source-cu.c',
+  'bug-extents.c',
+  'bug-seams.c',
+  'caps.c',
+  'checkerboard.c',
+  'caps-joins.c',
+  'caps-joins-alpha.c',
+  'caps-joins-curve.c',
+  'caps-tails-curve.c',
+  'caps-sub-paths.c',
+  'clear.c',
+  'clear-source.c',
+  'clip-all.c',
+  'clip-complex-bug61592.c',
+  'clip-complex-shape.c',
+  'clip-contexts.c',
+  'clip-disjoint.c',
+  'clip-disjoint-hatching.c',
+  'clip-disjoint-quad.c',
+  'clip-device-offset.c',
+  'clip-double-free.c',
+  'clip-draw-unbounded.c',
+  'clip-empty.c',
+  'clip-empty-group.c',
+  'clip-empty-save.c',
+  'clip-fill.c',
+  'clip-fill-no-op.c',
+  'clip-fill-rule.c',
+  'clip-fill-rule-pixel-aligned.c',
+  'clip-group-shapes.c',
+  'clip-image.c',
+  'clip-intersect.c',
+  'clip-mixed-antialias.c',
+  'clip-nesting.c',
+  'clip-operator.c',
+  'clip-push-group.c',
+  'clip-polygons.c',
+  'clip-rectilinear.c',
+  'clip-shape.c',
+  'clip-stroke.c',
+  'clip-stroke-no-op.c',
+  'clip-text.c',
+  'clip-twice.c',
+  'clip-twice-rectangle.c',
+  'clip-unbounded.c',
+  'clip-zero.c',
+  'clipped-group.c',
+  'clipped-surface.c',
+  'close-path.c',
+  'close-path-current-point.c',
+  'composite-integer-translate-source.c',
+  'composite-integer-translate-over.c',
+  'composite-integer-translate-over-repeat.c',
+  'copy-disjoint.c',
+  'copy-path.c',
+  'coverage.c',
+  'create-for-stream.c',
+  'create-from-broken-png-stream.c',
+  'create-from-png.c',
+  'create-from-png-stream.c',
+  'culled-glyphs.c',
+  'curve-to-as-line-to.c',
+  'dash-caps-joins.c',
+  'dash-curve.c',
+  'dash-infinite-loop.c',
+  'dash-no-dash.c',
+  'dash-offset.c',
+  'dash-offset-negative.c',
+  'dash-scale.c',
+  'dash-state.c',
+  'dash-zero-length.c',
+  'degenerate-arc.c',
+  'degenerate-arcs.c',
+  'degenerate-curve-to.c',
+  'degenerate-dash.c',
+  'degenerate-linear-gradient.c',
+  'degenerate-path.c',
+  'degenerate-pen.c',
+  'degenerate-radial-gradient.c',
+  'degenerate-rel-curve-to.c',
+  'degenerate-solid-dash.c',
+  'drunkard-tails.c',
+  'device-offset.c',
+  'device-offset-fractional.c',
+  'device-offset-positive.c',
+  'device-offset-scale.c',
+  'error-setters.c',
+  'extend-pad.c',
+  'extend-pad-border.c',
+  'extend-pad-similar.c',
+  'extend-reflect.c',
+  'extend-reflect-similar.c',
+  'extend-repeat.c',
+  'extend-repeat-similar.c',
+  'extended-blend.c',
+  'fallback.c',
+  'fill-alpha.c',
+  'fill-alpha-pattern.c',
+  'fill-and-stroke.c',
+  'fill-and-stroke-alpha.c',
+  'fill-and-stroke-alpha-add.c',
+  'fill-degenerate-sort-order.c',
+  'fill-disjoint.c',
+  'fill-empty.c',
+  'fill-image.c',
+  'fill-missed-stop.c',
+  'fill-rule.c',
+  'filter-bilinear-extents.c',
+  'filter-nearest-offset.c',
+  'filter-nearest-transformed.c',
+  'finer-grained-fallbacks.c',
+  'font-face-get-type.c',
+  'font-matrix-translation.c',
+  'font-options.c',
+  #'font-variations.c',
+  'glyph-cache-pressure.c',
+  'get-and-set.c',
+  'get-clip.c',
+  'get-group-target.c',
+  'get-path-extents.c',
+  'gradient-alpha.c',
+  'gradient-constant-alpha.c',
+  'gradient-zero-stops.c',
+  'gradient-zero-stops-mask.c',
+  'group-clip.c',
+  'group-paint.c',
+  'group-state.c',
+  'group-unaligned.c',
+  'half-coverage.c',
+  'halo.c',
+  'hatchings.c',
+  'horizontal-clip.c',
+  'huge-linear.c',
+  'huge-radial.c',
+  'image-surface-source.c',
+  'image-bug-710072.c',
+  'implicit-close.c',
+  'infinite-join.c',
+  'in-fill-empty-trapezoid.c',
+  'in-fill-trapezoid.c',
+  'invalid-matrix.c',
+  'inverse-text.c',
+  'inverted-clip.c',
+  'joins.c',
+  'joins-loop.c',
+  'joins-star.c',
+  'joins-retrace.c',
+  'large-clip.c',
+  'large-font.c',
+  'large-source.c',
+  'large-source-roi.c',
+  'large-twin-antialias-mixed.c',
+  'leaky-dash.c',
+  'leaky-dashed-rectangle.c',
+  'leaky-dashed-stroke.c',
+  'leaky-polygon.c',
+  'line-width.c',
+  'line-width-large-overlap.c',
+  'line-width-overlap.c',
+  'line-width-scale.c',
+  'line-width-tolerance.c',
+  'line-width-zero.c',
+  'linear-gradient.c',
+  'linear-gradient-extend.c',
+  'linear-gradient-large.c',
+  'linear-gradient-one-stop.c',
+  'linear-gradient-reflect.c',
+  'linear-gradient-subset.c',
+  'linear-step-function.c',
+  'linear-uniform.c',
+  'long-dashed-lines.c',
+  'long-lines.c',
+  'map-to-image.c',
+  'mask.c',
+  'mask-alpha.c',
+  'mask-ctm.c',
+  'mask-glyphs.c',
+  'mask-surface-ctm.c',
+  'mask-transformed-image.c',
+  'mask-transformed-similar.c',
+  'mesh-pattern.c',
+  'mesh-pattern-accuracy.c',
+  'mesh-pattern-conical.c',
+  'mesh-pattern-control-points.c',
+  'mesh-pattern-fold.c',
+  'mesh-pattern-overlap.c',
+  'mesh-pattern-transformed.c',
+  'mime-data.c',
+  'mime-surface-api.c',
+  'miter-precision.c',
+  'move-to-show-surface.c',
+  'negative-stride-image.c',
+  'new-sub-path.c',
+  'nil-surface.c',
+  'operator.c',
+  'operator-alpha.c',
+  'operator-alpha-alpha.c',
+  'operator-clear.c',
+  'operator-source.c',
+  'outline-tolerance.c',
+  'over-above-source.c',
+  'over-around-source.c',
+  'over-below-source.c',
+  'over-between-source.c',
+  'overlapping-boxes.c',
+  'overlapping-glyphs.c',
+  'overlapping-dash-caps.c',
+  'paint.c',
+  'paint-clip-fill.c',
+  'paint-repeat.c',
+  'paint-source-alpha.c',
+  'paint-with-alpha.c',
+  'paint-with-alpha-group-clip.c',
+  'partial-clip-text.c',
+  'partial-coverage.c',
+  'pass-through.c',
+  'path-append.c',
+  'path-currentpoint.c',
+  'path-stroke-twice.c',
+  'path-precision.c',
+  'pattern-get-type.c',
+  'pattern-getters.c',
+  'pdf-isolated-group.c',
+  'pixman-downscale.c',
+  'pixman-rotate.c',
+  'png.c',
+  'push-group.c',
+  'push-group-color.c',
+  'push-group-path-offset.c',
+  'radial-gradient.c',
+  'radial-gradient-extend.c',
+  'radial-outer-focus.c',
+  'random-clips.c',
+  'random-intersections-eo.c',
+  'random-intersections-nonzero.c',
+  'random-intersections-curves-eo.c',
+  'random-intersections-curves-nz.c',
+  'raster-source.c',
+  'record.c',
+  'record1414x.c',
+  'record2x.c',
+  'record90.c',
+  'recordflip.c',
+  'record-extend.c',
+  'record-neg-extents.c',
+  'record-mesh.c',
+  'record-replay-extend.c',
+  'recording-ink-extents.c',
+  'recording-surface-pattern.c',
+  'recording-surface-extend.c',
+  'rectangle-rounding-error.c',
+  'rectilinear-fill.c',
+  'rectilinear-grid.c',
+  'rectilinear-miter-limit.c',
+  'rectilinear-dash.c',
+  'rectilinear-dash-scale.c',
+  'rectilinear-stroke.c',
+  'reflected-stroke.c',
+  'rel-path.c',
+  'rgb24-ignore-alpha.c',
+  'rotate-image-surface-paint.c',
+  'rotate-stroke-box.c',
+  'rotated-clip.c',
+  'rounded-rectangle-fill.c',
+  'rounded-rectangle-stroke.c',
+  'sample.c',
+  'scale-down-source-surface-paint.c',
+  'scale-offset-image.c',
+  'scale-offset-similar.c',
+  'scale-source-surface-paint.c',
+  'scaled-font-zero-matrix.c',
+  'stroke-ctm-caps.c',
+  'stroke-clipped.c',
+  'stroke-image.c',
+  'stroke-open-box.c',
+  'select-font-face.c',
+  'select-font-no-show-text.c',
+  'self-copy.c',
+  'self-copy-overlap.c',
+  'self-intersecting.c',
+  'set-source.c',
+  'show-glyphs-advance.c',
+  'show-glyphs-many.c',
+  'show-text-current-point.c',
+  'shape-general-convex.c',
+  'shape-sierpinski.c',
+  'simple.c',
+  'skew-extreme.c',
+  'smask.c',
+  'smask-fill.c',
+  'smask-image-mask.c',
+  'smask-mask.c',
+  'smask-paint.c',
+  'smask-stroke.c',
+  'smask-text.c',
+  'smp-glyph.c',
+  'solid-pattern-cache-stress.c',
+  'source-clip.c',
+  'source-clip-scale.c',
+  'source-surface-scale-paint.c',
+  'spline-decomposition.c',
+  'stride-12-image.c',
+  'stroke-pattern.c',
+  'subsurface.c',
+  'subsurface-image-repeat.c',
+  'subsurface-repeat.c',
+  'subsurface-reflect.c',
+  'subsurface-pad.c',
+  'subsurface-modify-child.c',
+  'subsurface-modify-parent.c',
+  'subsurface-outside-target.c',
+  'subsurface-scale.c',
+  'subsurface-similar-repeat.c',
+  'surface-finish-twice.c',
+  'surface-pattern.c',
+  'surface-pattern-big-scale-down.c',
+  'surface-pattern-operator.c',
+  'surface-pattern-scale-down.c',
+  'surface-pattern-scale-down-extend.c',
+  'surface-pattern-scale-up.c',
+  'text-antialias.c',
+  'text-antialias-subpixel.c',
+  'text-cache-crash.c',
+  'text-glyph-range.c',
+  'text-pattern.c',
+  'text-rotate.c',
+  'text-transform.c',
+  'text-unhinted-metrics.c',
+  'text-zero-len.c',
+  'thin-lines.c',
+  'tighten-bounds.c',
+  'tiger.c',
+  'toy-font-face.c',
+  'transforms.c',
+  'translate-show-surface.c',
+  'trap-clip.c',
+  'twin.c',
+  'twin-antialias-gray.c',
+  'twin-antialias-mixed.c',
+  'twin-antialias-none.c',
+  'twin-antialias-subpixel.c',
+  'unaligned-box.c',
+  'unantialiased-shapes.c',
+  'unbounded-operator.c',
+  'unclosed-strokes.c',
+  'user-data.c',
+  'user-font.c',
+  'user-font-mask.c',
+  'user-font-proxy.c',
+  'user-font-rescale.c',
+  'world-map.c',
+  'white-in-noop.c',
+  'xcb-huge-image-shm.c',
+  'xcb-huge-subimage.c',
+  'xcb-stress-cache.c',
+  'xcb-snapshot-assert.c',
+  'xcomposite-projection.c',
+  'xlib-expose-event.c',
+  'zero-alpha.c',
+  'zero-mask.c',
+]
+
+test_pthread_sources = [
+  'pthread-same-source.c',
+  'pthread-show-text.c',
+  'pthread-similar.c',
+]
+
+test_ft_font_sources = [
+  'bitmap-font.c',
+  'ft-font-create-for-ft-face.c',
+  'ft-show-glyphs-positioning.c',
+  'ft-show-glyphs-table.c',
+  'ft-text-vertical-layout-type1.c',
+  'ft-text-vertical-layout-type3.c',
+  'ft-text-antialias-none.c',
+]
+
+test_gl_sources = [
+  'gl-device-release.c',
+  'gl-oversized-surface.c',
+  'gl-surface-source.c',
+]
+
+test_egl_sources = [
+  'egl-oversized-surface.c',
+  'egl-surface-source.c',
+]
+
+test_quartz_sources = [
+  'quartz-surface-source.c',
+]
+
+test_pdf_sources = [
+  'pdf-features.c',
+  'pdf-mime-data.c',
+  'pdf-surface-source.c',
+  'pdf-tagged-text.c',
+]
+
+test_ps_sources = [
+  'ps-eps.c',
+  'ps-features.c',
+  'ps-surface-source.c',
+]
+
+test_svg_sources = [
+  'svg-surface.c',
+  'svg-clip.c',
+  'svg-surface-source.c',
+]
+
+test_xcb_sources = [
+  'xcb-surface-source.c',
+]
+
+test_xlib_sources = [
+  'xlib-surface.c',
+  'xlib-surface-source.c',
+]
+
+test_xlib_xrender_sources = [
+  'get-xrender-format.c',
+]
+
+test_multi_page_sources = [
+  'multi-page.c',
+  'mime-unique-id.c',
+]
+
+test_fallback_resolution_sources = [
+  'fallback-resolution.c',
+]
+
+cairo_test_suite_sources = [
+  'buffer-diff.c',
+  'cairo-test.c',
+  'cairo-test-runner.c',
+]
+
+cairo_test_trace_sources = [
+  'cairo-test-trace.c',
+  'buffer-diff.c',
+]
+
+imagediff_sources = [
+  'imagediff.c',
+  'buffer-diff.c',
+]
+
+png_flatten_sources = [
+  'png-flatten.c',
+]
+
+pdf2png_sources = [
+  'pdf2png.c',
+]
+
+svg2png_sources = [
+  'svg2png.c',
+]
+
+ps2png_sources = [
+  'ps2png.c',
+]
+
+build_any2ppm = false
+has_multipage_surfaces = false
+add_fallback_resolution = false
+
+if conf.get('HAVE_REAL_PTHREAD', 0) == 1
+  test_sources += test_pthread_sources
+endif
+
+if feature_conf.get('CAIRO_HAS_FT_FONT', 0) == 1 and feature_conf.get('CAIRO_HAS_FC_FONT', 0) == 1
+  test_sources += test_ft_font_sources
+endif
+
+if feature_conf.get('CAIRO_HAS_QUARTZ_SURFACE', 0) == 1
+  test_sources += test_quartz_sources
+endif
+
+if feature_conf.get('CAIRO_HAS_PDF_SURFACE', 0) == 1
+  test_sources += test_pdf_sources
+  has_multipage_surfaces = true
+  add_fallback_resolution = true
+  build_any2ppm = true
+endif
+
+if feature_conf.get('CAIRO_HAS_PS_SURFACE', 0) == 1
+  test_sources += test_ps_sources
+  has_multipage_surfaces = true
+  add_fallback_resolution = true
+  build_any2ppm = true
+endif
+
+if feature_conf.get('CAIRO_HAS_SVG_SURFACE', 0) == 1
+  test_sources += test_svg_sources
+  build_any2ppm = true
+  add_fallback_resolution = true
+endif
+
+if feature_conf.get('CAIRO_HAS_XCB_SURFACE', 0) == 1
+  test_sources += test_xcb_sources
+endif
+
+if feature_conf.get('CAIRO_HAS_XLIB_SURFACE', 0) == 1
+  test_sources += test_xlib_sources
+endif
+
+if feature_conf.get('CAIRO_HAS_XLIB_XRENDER_SURFACE', 0) == 1
+  test_sources += test_xlib_xrender_sources
+endif
+
+if feature_conf.get('CAIRO_HAS_EGL_FUNCTIONS', 0) == 1
+  test_sources += test_egl_sources
+endif
+
+if has_multipage_surfaces
+  test_sources += test_multi_page_sources
+endif
+
+if add_fallback_resolution
+  test_sources += test_fallback_resolution_sources
+endif
+
+if feature_conf.get('CAIRO_HAS_SCRIPT_SURFACE', 0) == 1
+  build_any2ppm = true
+endif
+
+cairo_test_constructors = custom_target('cairo-test-constructors.c',
+  input: files(test_sources),
+  output: 'cairo-test-constructors.c',
+  command: [python3, files('make-cairo-test-constructors.py')[0], '@OUTPUT@', '@INPUT@'])
+
+incpdiff = include_directories('pdiff')
+
+test_depends = []
+
+subdir('pdiff')
+
+if conf.get('CAIRO_CAN_TEST_PDF_SURFACE', 0) == 1
+  exe = executable('pdf2png', pdf2png_sources,
+    dependencies: deps + test_deps,
+  )
+endif
+
+if conf.get('CAIRO_CAN_TEST_SVG_SURFACE', 0) == 1
+  exe = executable('svg2png', svg2png_sources,
+    dependencies: deps + test_deps,
+  )
+endif
+
+if conf.get('CAIRO_HAS_SPECTRE', 0) == 1
+  exe = executable('ps2png', ps2png_sources,
+    dependencies: deps + test_deps,
+  )
+endif
+
+if build_any2ppm
+  any2ppm_exe = executable('any2ppm', 'any2ppm.c',
+    c_args: ['-DHAVE_CONFIG_H'],
+    include_directories: [incbase, incsrc, inccairoscript],
+    link_with: [libcairo, libcairoscript],
+    dependencies: deps + test_deps,
+  )
+  test_depends += [any2ppm_exe]
+endif
+
+if have_shm
+  cairo_test_trace_exe = executable('cairo-test-trace', cairo_test_trace_sources,
+  include_directories: [incbase, incsrc, incboilerplate, incpdiff, inccairoscript, inccairomissing],
+  c_args: ['-DHAVE_CONFIG_H'] + pthread_c_args,
+  link_with: [libcairo, libcairoboilerplate, libpdiff, libcairoscript, libcairomissing],
+  link_args: extra_link_args,
+  dependencies: deps + test_deps + [rt_dep])
+endif
+
+exe = executable('cairo-test-suite', [cairo_test_suite_sources, test_sources, cairo_test_constructors],
+  include_directories: [incbase, incsrc, incboilerplate, incpdiff],
+  c_args: ['-DHAVE_CONFIG_H'],
+  link_with: [libcairo, libcairoboilerplate, libpdiff],
+  link_args: extra_link_args,
+  dependencies: deps + test_deps,
+)
+
+env = environment()
+
+env.set('srcdir', meson.current_source_dir())
+
+test('cairo', exe,
+  timeout: 60 * 60,
+  env: env,
+  workdir: meson.current_build_dir(),
+  depends: test_depends)
diff --git a/test/pdiff/meson.build b/test/pdiff/meson.build
new file mode 100644
index 000000000..6400b95c2
--- /dev/null
+++ b/test/pdiff/meson.build
@@ -0,0 +1,21 @@
+libpdiff_sources = [
+  'lpyramid.c',
+  'pdiff.c',
+]
+
+perceptualdiff_sources = [
+  'args.c',
+  'perceptualdiff.c',
+]
+
+libpdiff = static_library('pdiff', libpdiff_sources,
+  c_args: ['-DHAVE_CONFIG_H'],
+  include_directories: [incbase, incsrc],
+  dependencies: deps,
+  link_with: [libcairo],
+)
+
+perceptualdiff = executable('perceptualdiff', perceptualdiff_sources,
+  c_args: ['-DHAVE_CONFIG_H'],
+  include_directories: [incbase, incsrc],
+  link_with: [libpdiff])
diff --git a/util/cairo-fdr/meson.build b/util/cairo-fdr/meson.build
new file mode 100644
index 000000000..3cb66c678
--- /dev/null
+++ b/util/cairo-fdr/meson.build
@@ -0,0 +1,11 @@
+cairo_fdr_sources = [
+  'fdr.c',
+]
+
+libcairofdr = library('cairo-fdr', cairo_fdr_sources,
+  include_directories: [incbase, incsrc],
+  c_args: ['-DHAVE_CONFIG_H'],
+  dependencies: deps,
+  install: true,
+  install_dir: join_paths(get_option('prefix'), get_option('libdir'), 'cairo'),
+)
diff --git a/util/cairo-gobject/meson.build b/util/cairo-gobject/meson.build
new file mode 100644
index 000000000..895ba03d7
--- /dev/null
+++ b/util/cairo-gobject/meson.build
@@ -0,0 +1,25 @@
+cairo_gobject_sources = [
+  'cairo-gobject-enums.c',
+  'cairo-gobject-structs.c',
+]
+
+cairo_gobject_headers = [
+  'cairo-gobject.h',
+]
+
+libcairogobject = library('cairo-gobject', cairo_gobject_sources,
+  c_args: ['-DHAVE_CONFIG_H'],
+  include_directories: [incbase, incsrc],
+  dependencies: [glib_dep, gobject_dep],
+  link_with: [libcairo],
+  soversion: '2',
+  version: '2.' + ''.join(meson.project_version().split('.')) + '.0',
+  install: true,
+)
+
+incgobject = include_directories('.')
+
+libcairogobject_dep = declare_dependency(link_with: libcairogobject,
+  include_directories: [incbase, incgobject])
+
+install_headers(cairo_gobject_headers, subdir: 'cairo')
diff --git a/util/cairo-missing/meson.build b/util/cairo-missing/meson.build
new file mode 100644
index 000000000..db328fb1c
--- /dev/null
+++ b/util/cairo-missing/meson.build
@@ -0,0 +1,11 @@
+cairo_missing_sources = [
+  'strndup.c',
+  'getline.c',
+]
+
+inccairomissing = include_directories('.')
+
+libcairomissing = static_library('cairo-missing', cairo_missing_sources,
+  c_args: ['-DHAVE_CONFIG_H'],
+  include_directories: [incbase, incsrc],
+)
diff --git a/util/cairo-script/meson.build b/util/cairo-script/meson.build
new file mode 100644
index 000000000..f1be1f193
--- /dev/null
+++ b/util/cairo-script/meson.build
@@ -0,0 +1,65 @@
+cairoscript_interpreter_sources = [
+  'cairo-script-file.c',
+  'cairo-script-hash.c',
+  'cairo-script-interpreter.c',
+  'cairo-script-objects.c',
+  'cairo-script-operators.c',
+  'cairo-script-scanner.c',
+  'cairo-script-stack.c',
+]
+
+cairoscript_interpreter_headers = [
+  'cairo-script-interpreter.h',
+]
+
+csi_replay_sources = [
+  'csi-replay.c',
+]
+
+csi_exec_sources = [
+  'csi-exec.c',
+]
+
+csi_trace_sources = [
+  'csi-trace.c',
+]
+
+libcairoscript = library('cairo-script', cairoscript_interpreter_sources,
+  c_args: ['-DHAVE_CONFIG_H'],
+  include_directories: [incbase, incsrc],
+  dependencies: deps,
+  link_with: [libcairo],
+  soversion: '2',
+  version: '2.' + ''.join(meson.project_version().split('.')) + '.0',
+  install: true,
+)
+
+inccairoscript = include_directories('.')
+
+libcairoscript_dep = declare_dependency(link_with: libcairoscript,
+  include_directories: [incbase, inccairoscript])
+
+csi_replay_exe = executable('csi-replay', csi_replay_sources,
+  c_args: ['-DHAVE_CONFIG_H'],
+  include_directories: [incbase, incsrc],
+  link_with: [libcairo, libcairoscript],
+  dependencies: deps,
+)
+
+csi_exec_exe = executable('csi-exec', csi_exec_sources,
+  c_args: ['-DHAVE_CONFIG_H'],
+  include_directories: [incbase, incsrc],
+  link_with: [libcairo, libcairoscript],
+  dependencies: deps,
+)
+
+if feature_conf.get('CAIRO_HAS_SCRIPT_SURFACE', 0) == 1 and conf.get('HAVE_LIBGEN_H', 0) == 1
+  csi_trace_exe = executable('csi-trace', csi_trace_sources,
+    c_args: ['-DHAVE_CONFIG_H'],
+    include_directories: [incbase, incsrc],
+    link_with: [libcairo, libcairoscript],
+    dependencies: deps,
+  )
+endif
+
+install_headers(cairoscript_interpreter_headers, subdir: 'cairo')
diff --git a/util/cairo-sphinx/meson.build b/util/cairo-sphinx/meson.build
new file mode 100644
index 000000000..cf560aefd
--- /dev/null
+++ b/util/cairo-sphinx/meson.build
@@ -0,0 +1,26 @@
+libcairo_sphinx_sources = [
+  'fdr.c',
+]
+
+cairo_sphinx_sources = [
+  'sphinx.c',
+]
+
+libcairosphinx = library('cairo-sphinx', libcairo_sphinx_sources,
+  include_directories: [incbase, incsrc],
+  c_args: ['-DHAVE_CONFIG_H'],
+  dependencies: deps,
+  install: true,
+  install_dir: join_paths(get_option('prefix'), get_option('libdir'), 'cairo'),
+)
+
+libdir = join_paths(get_option('prefix'), get_option('libdir'))
+
+cairosphinx_exe = executable('cairo-sphinx', cairo_sphinx_sources,
+  include_directories: [incbase, incsrc, inccairoscript, incboilerplate],
+  c_args: ['-DHAVE_CONFIG_H', '-DLIBDIR="@0@"'.format(libdir)] + pthread_c_args,
+  dependencies: deps + [glib_dep, rt_dep],
+  link_with: [libcairo, libcairosphinx, libcairoscript, libcairoboilerplate],
+  link_args: extra_link_args,
+  install: true,
+)
diff --git a/util/cairo-trace/meson.build b/util/cairo-trace/meson.build
new file mode 100644
index 000000000..20f2b87d6
--- /dev/null
+++ b/util/cairo-trace/meson.build
@@ -0,0 +1,30 @@
+cairo_trace_sources = [
+  'trace.c',
+]
+
+shared_lib_ext = libcairo.full_path().split('.')[-1]
+
+libcairotrace = library('cairo-trace', cairo_trace_sources,
+  include_directories: [incbase, incsrc],
+  dependencies: deps,
+  link_args: extra_link_args,
+  c_args: ['-DSHARED_LIB_EXT="@0@"'.format(shared_lib_ext), '-DHAVE_CONFIG_H'] + pthread_c_args,
+  install: true,
+  install_dir: join_paths(get_option('prefix'), get_option('libdir'), 'cairo'),
+)
+
+trace_conf = configuration_data()
+trace_conf.set('prefix', get_option('prefix'))
+trace_conf.set('exec_prefix', get_option('prefix'))
+trace_conf.set('libdir', get_option('prefix') / get_option('libdir'))
+trace_conf.set('CAIRO_VERSION_MAJOR', meson.project_version().split('.')[0])
+trace_conf.set('CAIRO_VERSION_MINOR', meson.project_version().split('.')[1])
+trace_conf.set('CAIRO_VERSION_MICRO', meson.project_version().split('.')[2])
+trace_conf.set('SHLIB_EXT', shared_lib_ext)
+
+configure_file(input: 'cairo-trace.in',
+  output: 'cairo-trace',
+  configuration: trace_conf,
+  install: true,
+  install_dir: join_paths(get_option('prefix'), get_option('bindir')),
+)
diff --git a/util/meson.build b/util/meson.build
new file mode 100644
index 000000000..3f16d7c78
--- /dev/null
+++ b/util/meson.build
@@ -0,0 +1,66 @@
+subdir('cairo-missing')
+
+cairo_utils = []
+
+if feature_conf.get('CAIRO_HAS_GOBJECT_FUNCTIONS', 0) == 1
+  subdir('cairo-gobject')
+endif
+
+if feature_conf.get('CAIRO_HAS_INTERPRETER', 0) == 1
+  subdir('cairo-script')
+endif
+
+if conf.get('CAIRO_HAS_TRACE', 0) == 1
+  subdir('cairo-trace')
+
+  if (conf.get('CAIRO_HAS_DLSYM', 0) == 1 and
+      feature_conf.get('CAIRO_HAS_SCRIPT_SURFACE', 0) == 1 and
+      feature_conf.get('CAIRO_HAS_TEE_SURFACE', 0) == 1)
+    subdir('cairo-fdr')
+  endif
+endif
+
+if (glib_dep.found() and
+    png_dep.found() and
+    host_machine.system() != 'windows' and
+    conf.get('CAIRO_HAS_DLSYM', 0) == 1 and
+    feature_conf.get('CAIRO_HAS_SCRIPT_SURFACE', 0) == 1 and
+    feature_conf.get('CAIRO_HAS_TEE_SURFACE', 0) == 1)
+  subdir('cairo-sphinx')
+endif
+
+if gtk_dep.found()
+  cairo_utils += [
+    ['show-contour.c', {'deps': [gtk_dep]}],
+    ['show-traps.c', {'deps': [gtk_dep]}],
+    ['show-edges.c', {'deps': [gtk_dep]}],
+    ['show-polygon.c', {'deps': [gtk_dep]}],
+    ['show-events.c', {'deps': [gtk_dep]}],
+    ['font-view.c', {'deps': [gtk_dep]}],
+  ]
+endif
+
+if feature_conf.get('CAIRO_HAS_INTERPRETER', 0) == 1
+  expat_dep = dependency('expat', fallback: ['expat', 'expat_dep'])
+  cairo_utils += [
+    ['trace-to-xml.c', {'deps': [expat_dep]}],
+    ['xml-to-trace.c', {'deps': [expat_dep]}],
+  ]
+endif
+
+foreach util : cairo_utils
+  exe_name = util[0].split('.')[0]
+  util_deps = util.get(1, {}).get('deps', [])
+  executable(exe_name, util[0],
+    include_directories: [incbase, incsrc, inccairoscript],
+    dependencies: deps + util_deps,
+    link_with: [libcairo, libcairoscript],
+  )
+endforeach
+
+# This is useless and doesn't build on Windows
+if host_machine.system() != 'windows'
+  libmallocstats = library('malloc-stats', 'malloc-stats.c')
+endif
+
+# backtrace-symbols does not build
commit a75f8df95761bf88b54c326c5312117ea5073010
Author: Mathieu Duponchelle <mathieu at centricular.com>
Date:   Thu May 31 16:07:57 2018 -0700

    Fix build on Windows with recent versions of MSVC
    
    - vsnprintf and snprintf are available since vs2015
    - define ISREG if not provided
    - guard unistd.h include with HAVE_UNISTD_H
    - isnan() is available after vs2010

diff --git a/src/cairo-compiler-private.h b/src/cairo-compiler-private.h
index d982c101d..4562bea66 100644
--- a/src/cairo-compiler-private.h
+++ b/src/cairo-compiler-private.h
@@ -201,10 +201,12 @@
 #define hypot _hypot
 #define pclose _pclose
 #define popen _popen
-#define snprintf _snprintf
 #define strdup _strdup
 #define unlink _unlink
-#define vsnprintf _vsnprintf
+#if _MSC_VER < 1900
+  #define vsnprintf _vsnprintf
+  #define snprintf _snprintf
+#endif
 #endif
 
 #ifdef _MSC_VER
diff --git a/test/bitmap-font.c b/test/bitmap-font.c
index 525bafb2a..f9d753954 100644
--- a/test/bitmap-font.c
+++ b/test/bitmap-font.c
@@ -27,7 +27,9 @@
 
 #include <sys/types.h>
 #include <sys/stat.h>
+#ifdef HAVE_UNISTD_H
 #include <unistd.h>
+#endif
 
 #include <cairo-ft.h>
 #include <fontconfig/fontconfig.h>
@@ -73,6 +75,10 @@ check_font_extents (const cairo_test_context_t *ctx, cairo_t *cr, const char *co
     return CAIRO_TEST_SUCCESS;
 }
 
+#if !defined(S_ISREG) && defined(S_IFMT) && defined(S_IFREG)
+#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
+#endif
+
 static cairo_test_status_t
 draw (cairo_t *cr, int width, int height)
 {
diff --git a/test/cairo-test.h b/test/cairo-test.h
index 767c1ddf5..6d423ba01 100644
--- a/test/cairo-test.h
+++ b/test/cairo-test.h
@@ -58,7 +58,9 @@ typedef unsigned __int64 uint64_t;
 #define _USE_MATH_DEFINES
 
 #include <float.h>
+#if _MSC_VER <= 1600
 #define isnan(x) _isnan(x)
+#endif
 
 #endif
 


More information about the cairo-commit mailing list