[folks/wip/nielsdg/meson] Add support for the Meson build system



commit e620d53fedb0a59e931131ad463bb83b1fc699e9
Author: Niels De Graef <nielsdegraef gmail com>
Date:   Fri Aug 25 15:41:05 2017 +0200

    Add support for the Meson build system
    
    See the [Meson website] for a full reference. To build, test and/or
    install the folks library, you essentially need the following commands:
    
    ```
    $ meson build
    $ ninja -C build
    $ meson test -C build
    $ ninja -C build install
    ```
    
    Note that there is no one-on-one mapping sometimes from the autotools build to
    the meson build definitions, so here's a non-comprehensive list of changes:
    
    * Vala support is now mandatory.
    * Since meson doesn't have libtool's `export-symbols-regex`, we need to
    write our own little linker script to make sure we're not accidentally
    exporting symbols we shouldn't be exposing (such as
    _libfolks-internal_'s functions).
    * Meson has [built-in support for lcov], see the online reference for more info.
    * Meson also has built-in support for Valgrind by adding the `--wrap=valgrind`
    option.
    * There is no wildcard support in Meson (for good reasons), so instead
    we need to re-use the definitions found in the backend library's
    meson.build files to have the correct source files for the valadoc
    modules.
    
    [Meson website]: http://mesonbuild.com/
    [built-in support for lcov]: http://mesonbuild.com/Unit-tests.html#coverage

 .gitlab-ci.yml                                   |  43 ++--
 .gitlab-ci/meson-junit-report.py                 | 101 ++++++++++
 .gitlab-ci/run-tests.sh                          |  15 ++
 backends/bluez/meson.build                       |  47 +++++
 backends/dummy/lib/folks-dummy.map               |   7 +
 backends/dummy/lib/meson.build                   |  76 +++++++
 backends/dummy/meson.build                       |  38 ++++
 backends/eds/lib/folks-eds.map                   |   7 +
 backends/eds/lib/meson.build                     |  79 ++++++++
 backends/eds/meson.build                         |  41 ++++
 backends/key-file/meson.build                    |  36 ++++
 backends/libsocialweb/lib/folks-libsocialweb.map |   6 +
 backends/libsocialweb/lib/meson.build            |  77 +++++++
 backends/libsocialweb/meson.build                |  40 ++++
 backends/meson.build                             |  41 ++++
 backends/ofono/meson.build                       |  39 ++++
 backends/telepathy/lib/folks-telepathy.map       |   6 +
 backends/telepathy/lib/meson.build               | 160 +++++++++++++++
 backends/telepathy/meson.build                   |  41 ++++
 backends/tracker/lib/folks-tracker.map           |   7 +
 backends/tracker/lib/meson.build                 |  77 +++++++
 backends/tracker/meson.build                     |  40 ++++
 docs/devhelp/meson.build                         |  24 +++
 docs/gtkdoc/meson.build                          |  25 +++
 docs/meson.build                                 |  49 +++++
 folks/meson.build                                | 146 ++++++++++++++
 meson.build                                      | 243 +++++++++++++++++++++++
 meson_options.txt                                |  15 ++
 meson_post_install.py                            |  15 ++
 po/meson.build                                   |   3 +
 tests/bluez/meson.build                          |  50 +++++
 tests/data/meson.build                           |   5 +
 tests/dummy/meson.build                          |  44 ++++
 tests/eds/meson.build                            | 107 ++++++++++
 tests/folks/meson.build                          |  41 ++++
 tests/key-file/meson.build                       |  48 +++++
 tests/lib/bluez/meson.build                      |  15 ++
 tests/lib/dummy/meson.build                      |  20 ++
 tests/lib/eds/meson.build                        |  21 ++
 tests/lib/key-file/meson.build                   |  15 ++
 tests/lib/libsocialweb/meson.build               |  15 ++
 tests/lib/meson.build                            |  74 +++++++
 tests/lib/telepathy/contactlist/meson.build      |  72 +++++++
 tests/lib/telepathy/meson.build                  |  27 +++
 tests/lib/test-case.vala                         |   6 +-
 tests/lib/tracker/meson.build                    |  26 +++
 tests/libsocialweb/meson.build                   |  42 ++++
 tests/meson.build                                |  53 +++++
 tests/telepathy/meson.build                      |  57 ++++++
 tests/template.test.in                           |   3 +
 tests/tools/meson.build                          |   2 +
 tests/tracker/meson.build                        |  99 +++++++++
 tools/inspect/meson.build                        |  42 ++++
 tools/meson.build                                |  37 ++++
 54 files changed, 2442 insertions(+), 23 deletions(-)
---
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index b2399336..45eb5af6 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -1,33 +1,34 @@
+image: fedora:latest
+
 stages:
   - build
+  - test
 
-fedora-latest:
-  image: fedora:latest
+build-folks:
   stage: build
   except:
     - tags
-  variables:
-    V: "1"
-    MAKEFLAGS: "-j8"
   before_script:
-    - dnf update -y && dnf -y install dnf-plugins-core redhat-rpm-config
-    - dnf -y builddep folks
+    - dnf update -y --nogpgcheck
+    - dnf -y install dnf-plugins-core redhat-rpm-config meson ninja-build --nogpgcheck
+    - dnf -y builddep folks --nogpgcheck
   script:
-    # Configure
-    - ./autogen.sh
-    # Build
-    - make
-    # Run tests
-    # FIXME: Tests temporarily disabled because they don’t pass on CI
-    # See https://gitlab.gnome.org/GNOME/folks/issues/3
-    - make check || true
+    - meson _build
+    - ninja -C _build
   artifacts:
+    paths:
+      - "_build/config.h"
+      - "_build/meson-logs"
+
+test-folks:
+  stage: test
+  script:
+    - bash +x ./.gitlab-ci/run-tests.sh
+  allow_failure: true # FIXME: Remove when https://gitlab.gnome.org/GNOME/folks/issues/3 is fixed
+  artifacts:
+    reports:
+      junit: "_build/${CI_JOB_NAME}-report.xml"
     name: "folks-${CI_JOB_NAME}-${CI_COMMIT_REF_NAME}"
     when: always
     paths:
-      - "_build/config.h"
-      - "_build/*.log"
-      - "_build/*/*.log"
-      - "_build/*/*/*.log"
-      - "_build/*/*/*/*.log"
-      - "_build/*/*/*/*/*.log"
+      - "_build/${CI_JOB_NAME}-report.xml"
diff --git a/.gitlab-ci/meson-junit-report.py b/.gitlab-ci/meson-junit-report.py
new file mode 100755
index 00000000..ea492824
--- /dev/null
+++ b/.gitlab-ci/meson-junit-report.py
@@ -0,0 +1,101 @@
+#!/usr/bin/env python3
+
+import argparse
+import datetime
+import json
+import os
+import sys
+import xml.etree.ElementTree as ET
+
+aparser = argparse.ArgumentParser(description='Turns a Meson test log into a JUnit report')
+aparser.add_argument('--project-name', metavar='NAME',
+                     help='The project name',
+                     default='unknown')
+aparser.add_argument('--job-id', metavar='ID',
+                     help='The job ID for the report',
+                     default='Unknown')
+aparser.add_argument('--branch', metavar='NAME',
+                     help='Branch of the project being tested',
+                     default='master')
+aparser.add_argument('--output', metavar='FILE',
+                     help='The output file, stdout by default',
+                     type=argparse.FileType('w', encoding='UTF-8'),
+                     default=sys.stdout)
+aparser.add_argument('infile', metavar='FILE',
+                     help='The input testlog.json, stdin by default',
+                     type=argparse.FileType('r', encoding='UTF-8'),
+                     default=sys.stdin)
+
+args = aparser.parse_args()
+
+outfile = args.output
+
+testsuites = ET.Element('testsuites')
+testsuites.set('id', '{}/{}'.format(args.job_id, args.branch))
+testsuites.set('package', args.project_name)
+testsuites.set('timestamp', datetime.datetime.utcnow().isoformat(timespec='minutes'))
+
+suites = {}
+for line in args.infile:
+    data = json.loads(line)
+    (full_suite, unit_name) = data['name'].split(' / ')
+    (project_name, suite_name) = full_suite.split(':')
+
+    duration = data['duration']
+    return_code = data['returncode']
+    log = data['stdout']
+
+    unit = {
+        'suite': suite_name,
+        'name': unit_name,
+        'duration': duration,
+        'returncode': return_code,
+        'stdout': log,
+    }
+
+    units = suites.setdefault(suite_name, [])
+    units.append(unit)
+
+for name, units in suites.items():
+    print('Processing suite {} (units: {})'.format(name, len(units)))
+
+    def if_failed(unit):
+        if unit['returncode'] != 0:
+            return True
+        return False
+
+    def if_succeded(unit):
+        if unit['returncode'] == 0:
+            return True
+        return False
+
+    successes = list(filter(if_succeded, units))
+    failures = list(filter(if_failed, units))
+    print(' - {}: {} pass, {} fail'.format(name, len(successes), len(failures)))
+
+    testsuite = ET.SubElement(testsuites, 'testsuite')
+    testsuite.set('name', '{}/{}'.format(args.project_name, name))
+    testsuite.set('tests', str(len(units)))
+    testsuite.set('errors', str(len(failures)))
+    testsuite.set('failures', str(len(failures)))
+
+    for unit in successes:
+        testcase = ET.SubElement(testsuite, 'testcase')
+        testcase.set('classname', '{}/{}'.format(args.project_name, unit['suite']))
+        testcase.set('name', unit['name'])
+        testcase.set('time', str(unit['duration']))
+
+    for unit in failures:
+        testcase = ET.SubElement(testsuite, 'testcase')
+        testcase.set('classname', '{}/{}'.format(args.project_name, unit['suite']))
+        testcase.set('name', unit['name'])
+        testcase.set('time', str(unit['duration']))
+
+        failure = ET.SubElement(testcase, 'failure')
+        failure.set('classname', '{}/{}'.format(args.project_name, unit['suite']))
+        failure.set('name', unit['name'])
+        failure.set('type', 'error')
+        failure.text = unit['stdout']
+
+output = ET.tostring(testsuites, encoding='unicode')
+outfile.write(output)
diff --git a/.gitlab-ci/run-tests.sh b/.gitlab-ci/run-tests.sh
new file mode 100755
index 00000000..64d3863a
--- /dev/null
+++ b/.gitlab-ci/run-tests.sh
@@ -0,0 +1,15 @@
+#!/bin/bash
+
+set +e
+
+meson test -C _build
+
+exit_code=$?
+
+python3 .gitlab-ci/meson-junit-report.py \
+        --project-name=folks \
+        --job-id "${CI_JOB_NAME}" \
+        --output "_build/${CI_JOB_NAME}-report.xml" \
+        _build/meson-logs/testlog.json
+
+exit $exit_code
diff --git a/backends/bluez/meson.build b/backends/bluez/meson.build
new file mode 100644
index 00000000..7691cc4d
--- /dev/null
+++ b/backends/bluez/meson.build
@@ -0,0 +1,47 @@
+bluez_backend_name = 'bluez'
+
+# NOTE: we don't export a backend library here.
+
+bluez_backend_sources = [
+  'bluez-backend-factory.vala',
+  'bluez-backend.vala',
+  'bluez-persona-store.vala',
+  'bluez-persona.vala',
+  'org-bluez-obex-client.vala',
+  'org-bluez.vala',
+]
+
+bluez_backend_deps = [
+  backend_deps,
+  libfolks_internal_dep,
+  libebook_dep,
+  libm_dep,
+]
+
+bluez_backend_vala_flags = [
+  '--pkg', 'folks-generics',
+  '--pkg', 'build-conf',
+]
+
+bluez_backend_c_flags = [
+  '-include', 'config.h',
+  '-DBACKEND_NAME="@0@"'.format(bluez_backend_name),
+  '-DG_LOG_DOMAIN="@0@"'.format(bluez_backend_name),
+]
+
+bluez_backend = shared_library(bluez_backend_name,
+  bluez_backend_sources,
+  dependencies: bluez_backend_deps,
+  vala_args: bluez_backend_vala_flags,
+  c_args: bluez_backend_c_flags,
+  name_prefix: '',
+  install_dir: folks_backend_dir / bluez_backend_name,
+  install: true,
+)
+
+bluez_backend_dep = declare_dependency(
+  link_with: bluez_backend,
+  include_directories: include_directories('.'),
+)
+
+folks_backends += bluez_backend
diff --git a/backends/dummy/lib/folks-dummy.map b/backends/dummy/lib/folks-dummy.map
new file mode 100644
index 00000000..a3d859a4
--- /dev/null
+++ b/backends/dummy/lib/folks-dummy.map
@@ -0,0 +1,7 @@
+{
+global:
+  FOLKS_DUMMY_*;
+  folks_dummy_*;
+local:
+  *;
+};
diff --git a/backends/dummy/lib/meson.build b/backends/dummy/lib/meson.build
new file mode 100644
index 00000000..b5e5257b
--- /dev/null
+++ b/backends/dummy/lib/meson.build
@@ -0,0 +1,76 @@
+dummy_backendlib_gir_name = 'FolksDummy-@0@'.format(folks_api_version)
+
+dummy_backendlib_sources = files(
+  'dummy-backend.vala',
+  'dummy-full-persona.vala',
+  'dummy-persona-store.vala',
+  'dummy-persona.vala',
+)
+
+dummy_backendlib_deps = [
+  backend_deps,
+  libfolks_internal_dep,
+]
+
+# FIXME: we need to set these manually for the valadoc target as long as meson
+# doesn't have native support (https://github.com/mesonbuild/meson/issues/894)
+dummy_backendlib_doc_deps = [
+  '--pkg', 'folks',
+]
+
+dummy_backendlib_vala_flags = [
+  common_backendlib_vala_flags,
+  '--pkg', 'folks-generics',
+  '--pkg', 'build-conf',
+]
+
+dummy_backendlib_c_flags = [
+  '-include', 'config.h',
+  '-DBACKEND_NAME="@0@"'.format(dummy_backend_name),
+  '-DG_LOG_DOMAIN="@0@"'.format(dummy_backend_name),
+]
+
+dummy_backendlib_link_flags = [
+  '-Wl,--version-script,@0@/folks-@1@.map'.format(meson.current_source_dir(), dummy_backend_name),
+]
+
+dummy_backendlib = shared_library('folks-@0@'.format(dummy_backend_name),
+  dummy_backendlib_sources,
+  dependencies: dummy_backendlib_deps,
+  vala_args: dummy_backendlib_vala_flags,
+  c_args: dummy_backendlib_c_flags,
+  link_args: dummy_backendlib_link_flags,
+  version: folks_dummy_lib_version,
+  vala_header: 'folks/folks-@0@.h'.format(dummy_backend_name),
+  vala_gir: dummy_backendlib_gir_name + '.gir',
+  install: true,
+  install_dir: [ true, folks_headers_install_dir, true, true ],
+)
+
+# FIXME: This comes straight from the Meson docs on how to create/install a
+# typelib file for your Vala shared library. However, as mentioned in
+# https://github.com/mesonbuild/meson/issues/4481, this is not ideal.
+custom_target(dummy_backendlib_gir_name + '.typelib',
+  command: [ g_ir_compiler,
+    '--includedir', libfolks_gir_include_dir,
+    '--output', '@OUTPUT@',
+    meson.current_build_dir() / (dummy_backendlib_gir_name + '.gir')
+  ],
+  output: dummy_backendlib_gir_name + '.typelib',
+  depends: dummy_backendlib,
+  install: true,
+  install_dir: folks_typelibdir,
+)
+
+dummy_backendlib_dep = declare_dependency(
+  link_with: dummy_backendlib,
+  include_directories: include_directories('.'),
+)
+
+# Pkg-config file
+configure_file(
+  input: 'folks-dummy.pc.in',
+  output: 'folks-dummy.pc',
+  configuration: pkg_conf,
+  install_dir: pkg_install_dir,
+)
diff --git a/backends/dummy/meson.build b/backends/dummy/meson.build
new file mode 100644
index 00000000..a5a9b55c
--- /dev/null
+++ b/backends/dummy/meson.build
@@ -0,0 +1,38 @@
+# The dummy backend
+dummy_backend_name = 'dummy'
+
+# Backend library
+subdir('lib')
+
+dummy_backend_sources = [
+  'dummy-backend-factory.vala',
+]
+
+dummy_backend_deps = [
+  backend_deps,
+  dummy_backendlib_dep,
+]
+
+dummy_backend_vala_flags = [
+  '--pkg', 'folks-generics',
+  '--pkg', 'build-conf',
+]
+
+dummy_backend_c_flags = [
+  '-include', 'config.h',
+  '-DBACKEND_NAME="@0@"'.format(dummy_backend_name),
+  '-DG_LOG_DOMAIN="@0@"'.format(dummy_backend_name),
+]
+
+dummy_backend = shared_library(dummy_backend_name,
+  dummy_backend_sources,
+  dependencies: dummy_backend_deps,
+  vala_args: dummy_backend_vala_flags,
+  c_args: dummy_backend_c_flags,
+  link_with: libfolks_internal,
+  name_prefix: '',
+  install_dir: folks_backend_dir / dummy_backend_name,
+  install: true,
+)
+
+folks_backends += dummy_backend
diff --git a/backends/eds/lib/folks-eds.map b/backends/eds/lib/folks-eds.map
new file mode 100644
index 00000000..b9955888
--- /dev/null
+++ b/backends/eds/lib/folks-eds.map
@@ -0,0 +1,7 @@
+{
+global:
+  EDSF_*;
+  edsf_*;
+local:
+  *;
+};
diff --git a/backends/eds/lib/meson.build b/backends/eds/lib/meson.build
new file mode 100644
index 00000000..7c292f4f
--- /dev/null
+++ b/backends/eds/lib/meson.build
@@ -0,0 +1,79 @@
+eds_backendlib_gir_name = 'FolksEds-@0@'.format(folks_api_version)
+
+eds_backendlib_sources = files(
+  'edsf-persona-store.vala',
+  'edsf-persona.vala',
+)
+
+eds_backendlib_deps = [
+  backend_deps,
+  libfolks_internal_dep,
+  libebook_dep,
+  libebook_contacts_dep,
+  libedataserver_dep,
+  libxml_dep,
+]
+
+# FIXME: we need to set these manually for the valadoc target as long as meson
+# doesn't have native support (https://github.com/mesonbuild/meson/issues/894)
+eds_backendlib_doc_deps = [
+  '--pkg', 'folks',
+  '--pkg', 'libebook-1.2',
+]
+
+eds_backendlib_vala_flags = [
+  common_backendlib_vala_flags,
+  '--pkg', 'folks-generics',
+  '--pkg', 'build-conf',
+]
+
+eds_backendlib_c_flags = [
+  '-include', 'config.h',
+  '-DBACKEND_NAME="@0@"'.format(eds_backend_name),
+  '-DG_LOG_DOMAIN="@0@"'.format(eds_backend_name),
+]
+
+eds_backendlib_link_flags = [
+  '-Wl,--version-script,@0@/folks-@1@.map'.format(meson.current_source_dir(), eds_backend_name),
+]
+
+eds_backendlib = shared_library('folks-@0@'.format(eds_backend_name),
+  eds_backendlib_sources,
+  dependencies: eds_backendlib_deps,
+  vala_args: eds_backendlib_vala_flags,
+  c_args: eds_backendlib_c_flags,
+  link_args: eds_backendlib_link_flags,
+  version: folks_eds_lib_version,
+  vala_header: 'folks/folks-@0@.h'.format(dummy_backend_name),
+  vala_gir: eds_backendlib_gir_name + '.gir',
+  install: true,
+  install_dir: [ true, folks_headers_install_dir, true, true ],
+)
+
+# FIXME: This comes straight from the Meson docs on how to create/install a
+# typelib file for your Vala shared library. However, as mentioned in
+# https://github.com/mesonbuild/meson/issues/4481, this is not ideal.
+custom_target(eds_backendlib_gir_name + '.typelib',
+  command: [ g_ir_compiler,
+    '--includedir', libfolks_gir_include_dir,
+    '--output', '@OUTPUT@',
+    meson.current_build_dir() / (eds_backendlib_gir_name + '.gir')
+  ],
+  output: eds_backendlib_gir_name + '.typelib',
+  depends: eds_backendlib,
+  install: true,
+  install_dir: folks_typelibdir,
+)
+
+eds_backendlib_dep = declare_dependency(
+  link_with: eds_backendlib,
+  include_directories: include_directories('.'),
+)
+
+# Pkg-config file
+configure_file(
+  input: 'folks-eds.pc.in',
+  output: 'folks-eds.pc',
+  configuration: pkg_conf,
+  install_dir: pkg_install_dir,
+)
diff --git a/backends/eds/meson.build b/backends/eds/meson.build
new file mode 100644
index 00000000..21142fa6
--- /dev/null
+++ b/backends/eds/meson.build
@@ -0,0 +1,41 @@
+# Evolution-Data-Server (E-D-S) backend
+eds_backend_name = 'eds'
+
+# Backend library
+subdir('lib')
+
+eds_backend_sources = [
+  'eds-backend-factory.vala',
+  'eds-backend.vala',
+]
+
+eds_backend_deps = [
+  backend_deps,
+  libebook_dep,
+  libedataserver_dep,
+  eds_backendlib_dep,
+]
+
+eds_backend_vala_flags = [
+  '--pkg', 'folks-generics',
+  '--pkg', 'build-conf',
+]
+
+eds_backend_c_flags = [
+  '-include', 'config.h',
+  '-DBACKEND_NAME="@0@"'.format(eds_backend_name),
+  '-DG_LOG_DOMAIN="@0@"'.format(eds_backend_name),
+]
+
+eds_backend = library('eds',
+  eds_backend_sources,
+  dependencies: eds_backend_deps,
+  vala_args: eds_backend_vala_flags,
+  c_args: eds_backend_c_flags,
+  link_with: libfolks_internal,
+  name_prefix: '',
+  install_dir: folks_backend_dir / eds_backend_name,
+  install: true,
+)
+
+folks_backends += eds_backend
diff --git a/backends/key-file/meson.build b/backends/key-file/meson.build
new file mode 100644
index 00000000..cad7fc7d
--- /dev/null
+++ b/backends/key-file/meson.build
@@ -0,0 +1,36 @@
+keyfile_backend_name = 'key-file'
+
+keyfile_backend_sources = [
+  'kf-backend-factory.vala',
+  'kf-backend.vala',
+  'kf-persona-store.vala',
+  'kf-persona.vala',
+]
+
+keyfile_backend_deps = [
+  backend_deps,
+]
+
+keyfile_backend_vala_flags = [
+  '--pkg', 'folks-generics',
+  '--pkg', 'build-conf',
+]
+
+keyfile_backend_c_flags = [
+  '-include', 'config.h',
+  '-DBACKEND_NAME="@0@"'.format(keyfile_backend_name),
+  '-DG_LOG_DOMAIN="@0@"'.format(keyfile_backend_name),
+]
+
+keyfile_backend = shared_library(keyfile_backend_name,
+  keyfile_backend_sources,
+  dependencies: keyfile_backend_deps,
+  vala_args: keyfile_backend_vala_flags,
+  c_args: keyfile_backend_c_flags,
+  link_with: libfolks_internal,
+  name_prefix: '',
+  install_dir: folks_backend_dir / keyfile_backend_name,
+  install: true,
+)
+
+folks_backends += keyfile_backend
diff --git a/backends/libsocialweb/lib/folks-libsocialweb.map 
b/backends/libsocialweb/lib/folks-libsocialweb.map
new file mode 100644
index 00000000..293fafc8
--- /dev/null
+++ b/backends/libsocialweb/lib/folks-libsocialweb.map
@@ -0,0 +1,6 @@
+{
+global:
+  swf_*;
+local:
+  *;
+};
diff --git a/backends/libsocialweb/lib/meson.build b/backends/libsocialweb/lib/meson.build
new file mode 100644
index 00000000..ad87c3d7
--- /dev/null
+++ b/backends/libsocialweb/lib/meson.build
@@ -0,0 +1,77 @@
+libsocialweb_backendlib_gir_name = 'FolksLibsocialweb-@0@'.format(folks_api_version)
+
+libsocialweb_backendlib_sources = files(
+  'swf-persona-store.vala',
+  'swf-persona.vala',
+)
+
+libsocialweb_backendlib_deps = [
+  backend_deps,
+  libfolks_internal_dep,
+  libsocialweb_dep,
+]
+
+# FIXME: we need to set these manually for the valadoc target as long as meson
+# doesn't have native support (https://github.com/mesonbuild/meson/issues/894)
+libsocialweb_backendlib_doc_deps = [
+  '--pkg', 'libsocialweb-client',
+  '--pkg', 'folks',
+]
+
+libsocialweb_backendlib_vala_flags = [
+  common_backendlib_vala_flags,
+  '--pkg', 'folks-generics',
+  '--pkg', 'build-conf',
+]
+
+libsocialweb_backendlib_c_flags = [
+  '-include', 'config.h',
+  '-DBACKEND_NAME="@0@"'.format(libsocialweb_backend_name),
+  '-DG_LOG_DOMAIN="@0@"'.format(libsocialweb_backend_name),
+]
+
+libsocialweb_backendlib_link_flags = [
+  '-Wl,--version-script,@0@/folks-@1@.map'.format(meson.current_source_dir(), libsocialweb_backend_name),
+]
+
+libsocialweb_backendlib = shared_library('folks-@0@'.format(libsocialweb_backend_name),
+  libsocialweb_backendlib_sources,
+  dependencies: libsocialweb_backendlib_deps,
+  vala_args: libsocialweb_backendlib_vala_flags,
+  c_args: libsocialweb_backendlib_c_flags,
+  link_args: libsocialweb_backendlib_link_flags,
+  version: folks_libsocialweb_lib_version,
+  vala_gir: libsocialweb_backendlib_gir_name + '.gir',
+  vala_header: 'folks/folks-@0@.h'.format(dummy_backend_name),
+  install: true,
+  install_dir: [ true, folks_headers_install_dir, true, true ],
+)
+
+# FIXME: This comes straight from the Meson docs on how to create/install a
+# typelib file for your Vala shared library. However, as mentioned in
+# https://github.com/mesonbuild/meson/issues/4481, this is not ideal.
+custom_target(libsocialweb_backendlib_gir_name + '.typelib',
+  command: [ g_ir_compiler,
+    '--includedir', libfolks_gir_include_dir,
+    '--output', '@OUTPUT@',
+    meson.current_build_dir() / (libsocialweb_backendlib_gir_name + '.gir')
+  ],
+  output: libsocialweb_backendlib_gir_name + '.typelib',
+  depends: libsocialweb_backendlib,
+  install: true,
+  install_dir: folks_typelibdir,
+)
+
+libsocialweb_backendlib_dep = declare_dependency(
+  link_with: libsocialweb_backendlib,
+  include_directories: include_directories('.'),
+  dependencies: libsocialweb_dep,
+)
+
+# Pkg-config file
+configure_file(
+  input: 'folks-libsocialweb.pc.in',
+  output: 'folks-libsocialweb.pc',
+  configuration: pkg_conf,
+  install_dir: pkg_install_dir,
+)
diff --git a/backends/libsocialweb/meson.build b/backends/libsocialweb/meson.build
new file mode 100644
index 00000000..c04027f8
--- /dev/null
+++ b/backends/libsocialweb/meson.build
@@ -0,0 +1,40 @@
+# libsocialweb backend
+libsocialweb_backend_name = 'libsocialweb'
+
+# Backend library
+subdir('lib')
+
+libsocialweb_backend_sources = [
+  'sw-backend-factory.vala',
+  'sw-backend.vala',
+]
+
+libsocialweb_backend_deps = [
+  backend_deps,
+  libsocialweb_backendlib_dep,
+  libsocialweb_dep,
+]
+
+libsocialweb_backend_vala_flags = [
+  '--pkg', 'folks-generics',
+  '--pkg', 'build-conf',
+]
+
+libsocialweb_backend_c_flags = [
+  '-include', 'config.h',
+  '-DBACKEND_NAME="@0@"'.format(libsocialweb_backend_name),
+  '-DG_LOG_DOMAIN="@0@"'.format(libsocialweb_backend_name),
+]
+
+libsocialweb_backend = shared_library(libsocialweb_backend_name,
+  libsocialweb_backend_sources,
+  dependencies: libsocialweb_backend_deps,
+  vala_args: libsocialweb_backend_vala_flags,
+  c_args: libsocialweb_backend_c_flags,
+  link_with: libfolks_internal,
+  name_prefix: '',
+  install_dir: folks_backend_dir / dummy_backend_name,
+  install: true,
+)
+
+folks_backends += libsocialweb_backend
diff --git a/backends/meson.build b/backends/meson.build
new file mode 100644
index 00000000..ef5938ce
--- /dev/null
+++ b/backends/meson.build
@@ -0,0 +1,41 @@
+# Common dependencies
+backend_deps = [
+  libfolks_dep,
+  gobject_dep,
+  gee_dep,
+  gio_dep,
+]
+
+# Common flags
+common_backendlib_vala_flags = [
+  # make sure the VAPIs expose the right include path
+  '--includedir', meson.project_name(),
+]
+
+# A subdirectory for each type of backend
+subdir('dummy')
+subdir('key-file')
+
+if telepathy_backend_enabled
+  subdir('telepathy')
+endif
+
+if libsocialweb_backend_enabled
+  subdir('libsocialweb')
+endif
+
+if tracker_backend_enabled
+  subdir('tracker')
+endif
+
+if eds_backend_enabled
+  subdir('eds')
+endif
+
+if ofono_backend_enabled
+  subdir('ofono')
+endif
+
+if bluez_backend_enabled
+  subdir('bluez')
+endif
diff --git a/backends/ofono/meson.build b/backends/ofono/meson.build
new file mode 100644
index 00000000..ccff86bc
--- /dev/null
+++ b/backends/ofono/meson.build
@@ -0,0 +1,39 @@
+ofono_backend_name = 'ofono'
+
+ofono_backend_sources = [
+  'ofono-backend-factory.vala',
+  'ofono-backend.vala',
+  'ofono-persona-store.vala',
+  'ofono-persona.vala',
+  'org-ofono.vala',
+]
+
+ofono_backend_deps = [
+  backend_deps,
+  libebook_dep,
+  libedataserver_dep,
+]
+
+ofono_backend_vala_flags = [
+  '--pkg', 'folks-generics',
+  '--pkg', 'build-conf',
+]
+
+ofono_backend_c_flags = [
+  '-include', 'config.h',
+  '-DBACKEND_NAME="@0@"'.format(ofono_backend_name),
+  '-DG_LOG_DOMAIN="@0@"'.format(ofono_backend_name),
+]
+
+ofono_backend = shared_library(ofono_backend_name,
+  ofono_backend_sources,
+  dependencies: ofono_backend_deps,
+  vala_args: ofono_backend_vala_flags,
+  c_args: ofono_backend_c_flags,
+  link_with: libfolks_internal,
+  name_prefix: '',
+  install_dir: folks_backend_dir / ofono_backend_name,
+  install: true,
+)
+
+folks_backends += ofono_backend
diff --git a/backends/telepathy/lib/folks-telepathy.map b/backends/telepathy/lib/folks-telepathy.map
new file mode 100644
index 00000000..d4084018
--- /dev/null
+++ b/backends/telepathy/lib/folks-telepathy.map
@@ -0,0 +1,6 @@
+{
+global:
+  tpf_*;
+local:
+  *;
+};
diff --git a/backends/telepathy/lib/meson.build b/backends/telepathy/lib/meson.build
new file mode 100644
index 00000000..10b302c0
--- /dev/null
+++ b/backends/telepathy/lib/meson.build
@@ -0,0 +1,160 @@
+telepathy_backendlib_gir_name = 'FolksTelepathy-@0@'.format(folks_api_version)
+
+# Low-level library
+tp_lowlevel_sources = [
+  'tp-lowlevel.c',
+]
+
+tp_lowlevel_deps = [
+  gio_dep,
+  gobject_dep,
+  telepathy_glib_dep,
+]
+
+tp_lowlevel = static_library('tp-lowlevel',
+  sources: tp_lowlevel_sources,
+  dependencies: tp_lowlevel_deps,
+)
+
+tp_lowlevel_gir = gnome.generate_gir(tp_lowlevel,
+  sources: [ 'tp-lowlevel.h' ],
+  includes: [ 'GObject-2.0', 'TelepathyGLib-0.12' ],
+  namespace: 'TpLowlevel',
+  nsversion: folks_api_version,
+  identifier_prefix: 'FolksTpLowlevel',
+  extra_args: [
+    '--c-include=tp-lowlevel.h',
+  ],
+)
+
+tp_lowlevel_vapi = gnome.generate_vapi('tp-lowlevel',
+  sources: tp_lowlevel_gir.get(0),
+  packages: [ 'gio-2.0', 'telepathy-glib' ],
+)
+
+tp_lowlevel_dep = declare_dependency(
+  dependencies: tp_lowlevel_vapi,
+  link_with: tp_lowlevel,
+)
+
+# TP zeitgeist helper library
+tp_zeitgeist_deps = [
+  gee_dep,
+  libfolks_dep,
+  telepathy_glib_dep,
+]
+
+if zeitgeist_enabled
+  tp_zeitgeist_lib = static_library('tp-zeitgeist',
+    'tp-zeitgeist.vala',
+    dependencies: [ tp_zeitgeist_deps, zeitgeist_dep ],
+  )
+
+  tp_zeitgeist_dep = declare_dependency(
+    link_with: tp_zeitgeist_lib,
+    dependencies: [ tp_zeitgeist_deps, zeitgeist_dep ],
+  )
+else
+  tp_zeitgeist_dummy_lib = static_library('tp-zeitgeist-dummy',
+    'tp-zeitgeist-dummy.vala',
+    dependencies: tp_zeitgeist_deps,
+  )
+
+  tp_zeitgeist_dummy_dep = declare_dependency(
+    link_with: tp_zeitgeist_dummy_lib,
+    dependencies: tp_zeitgeist_deps,
+  )
+endif
+
+# Actual backend library
+telepathy_backendlib_sources = files(
+  'tpf-logger.vala',
+  'tpf-persona-store-cache.vala',
+  'tpf-persona-store.vala',
+  'tpf-persona.vala',
+)
+
+telepathy_backendlib_deps = [
+  backend_deps,
+  libfolks_internal_dep,
+  telepathy_glib_dep,
+  tp_lowlevel_dep,
+]
+
+# FIXME: we need to set these manually for the valadoc target as long as meson
+# doesn't have native support (https://github.com/mesonbuild/meson/issues/894)
+telepathy_backendlib_doc_deps = [
+  '--pkg', 'folks',
+  '--pkg', 'tp-lowlevel', '--vapidir', meson.current_build_dir(),
+  '--pkg', 'telepathy-glib',
+]
+
+if zeitgeist_enabled
+  telepathy_backendlib_deps += tp_zeitgeist_dep
+  telepathy_backendlib_doc_deps += [
+    '--pkg', 'tp-zeitgeist',
+  ]
+else
+  telepathy_backendlib_deps += tp_zeitgeist_dummy_dep
+  telepathy_backendlib_doc_deps += [
+    '--pkg', 'tp-zeitgeist-dummy',
+  ]
+endif
+
+telepathy_backendlib_vala_flags = [
+  common_backendlib_vala_flags,
+  '--pkg', 'folks-generics',
+  '--pkg', 'build-conf',
+]
+
+telepathy_backendlib_c_flags = [
+  '-include', 'config.h',
+  '-DBACKEND_NAME="@0@"'.format(telepathy_backend_name),
+  '-DG_LOG_DOMAIN="@0@"'.format(telepathy_backend_name),
+]
+
+telepathy_backendlib_link_flags = [
+  '-Wl,--version-script,@0@/folks-@1@.map'.format(meson.current_source_dir(), telepathy_backend_name),
+]
+
+telepathy_backendlib = shared_library('folks-@0@'.format(telepathy_backend_name),
+  telepathy_backendlib_sources,
+  dependencies: telepathy_backendlib_deps,
+  vala_args: telepathy_backendlib_vala_flags,
+  c_args: telepathy_backendlib_c_flags,
+  link_args: telepathy_backendlib_link_flags,
+  version: folks_telepathy_lib_version,
+  vala_header: 'folks/folks-@0@.h'.format(dummy_backend_name),
+  vala_gir: telepathy_backendlib_gir_name + '.gir',
+  install: true,
+  install_dir: [ true, folks_headers_install_dir, true, true ],
+)
+
+# FIXME: This comes straight from the Meson docs on how to create/install a
+# typelib file for your Vala shared library. However, as mentioned in
+# https://github.com/mesonbuild/meson/issues/4481, this is not ideal.
+custom_target(telepathy_backendlib_gir_name + '.typelib',
+  command: [ g_ir_compiler,
+    '--includedir', libfolks_gir_include_dir,
+    '--output', '@OUTPUT@',
+    meson.current_build_dir() / (telepathy_backendlib_gir_name + '.gir')
+  ],
+  output: telepathy_backendlib_gir_name + '.typelib',
+  depends: telepathy_backendlib,
+  install: true,
+  install_dir: folks_typelibdir,
+)
+
+telepathy_backendlib_dep = declare_dependency(
+  link_with: telepathy_backendlib,
+  include_directories: include_directories('.'),
+  dependencies: telepathy_backendlib_deps,
+)
+
+# Pkg-config file
+configure_file(
+  input: 'folks-telepathy.pc.in',
+  output: 'folks-telepathy.pc',
+  configuration: pkg_conf,
+  install_dir: pkg_install_dir,
+)
diff --git a/backends/telepathy/meson.build b/backends/telepathy/meson.build
new file mode 100644
index 00000000..8405ef32
--- /dev/null
+++ b/backends/telepathy/meson.build
@@ -0,0 +1,41 @@
+# Telepathy backend
+telepathy_backend_name = 'telepathy'
+
+# Backend library
+subdir('lib')
+
+telepathy_backend_sources = [
+  'tp-backend-factory.vala',
+  'tp-backend.vala',
+]
+
+telepathy_backend_deps = [
+  backend_deps,
+  telepathy_glib_dep,
+  tp_lowlevel_vapi,
+  telepathy_backendlib_dep,
+]
+
+telepathy_backend_vala_flags = [
+  '--pkg', 'folks-generics',
+  '--pkg', 'build-conf',
+]
+
+telepathy_backend_c_flags = [
+  '-include', 'config.h',
+  '-DBACKEND_NAME="@0@"'.format(telepathy_backend_name),
+  '-DG_LOG_DOMAIN="@0@"'.format(telepathy_backend_name),
+]
+
+telepathy_backend = shared_library(telepathy_backend_name,
+  telepathy_backend_sources,
+  dependencies: telepathy_backend_deps,
+  vala_args: telepathy_backend_vala_flags,
+  c_args: telepathy_backend_c_flags,
+  link_with: libfolks_internal,
+  name_prefix: '',
+  install_dir: folks_backend_dir / telepathy_backend_name,
+  install: true,
+)
+
+folks_backends += telepathy_backend
diff --git a/backends/tracker/lib/folks-tracker.map b/backends/tracker/lib/folks-tracker.map
new file mode 100644
index 00000000..2e20a0f0
--- /dev/null
+++ b/backends/tracker/lib/folks-tracker.map
@@ -0,0 +1,7 @@
+{
+global:
+  TRF_*;
+  trf_*;
+local:
+  *;
+};
diff --git a/backends/tracker/lib/meson.build b/backends/tracker/lib/meson.build
new file mode 100644
index 00000000..1b24c533
--- /dev/null
+++ b/backends/tracker/lib/meson.build
@@ -0,0 +1,77 @@
+tracker_backendlib_gir_name = 'FolksTracker-@0@'.format(folks_api_version)
+
+tracker_backendlib_sources = files(
+  'trf-persona-store.vala',
+  'trf-persona.vala',
+  'trf-util.vala',
+)
+
+tracker_backendlib_deps = [
+  backend_deps,
+  libfolks_internal_dep,
+  tracker_sparql_dep,
+]
+
+# FIXME: we need to set these manually for the valadoc target as long as meson
+# doesn't have native support (https://github.com/mesonbuild/meson/issues/894)
+tracker_backendlib_doc_deps = [
+  '--pkg', tracker_sparql_dep.name(),
+  '--pkg', 'folks',
+]
+
+tracker_backendlib_vala_flags = [
+  common_backendlib_vala_flags,
+  '--pkg', 'folks-generics',
+  '--pkg', 'build-conf',
+]
+
+tracker_backendlib_c_flags = [
+  '-include', 'config.h',
+  '-DBACKEND_NAME="@0@"'.format(tracker_backend_name),
+  '-DG_LOG_DOMAIN="@0@"'.format(tracker_backend_name),
+]
+
+tracker_backendlib_link_flags = [
+  '-Wl,--version-script,@0@/folks-@1@.map'.format(meson.current_source_dir(), tracker_backend_name),
+]
+
+tracker_backendlib = shared_library('folks-@0@'.format(tracker_backend_name),
+  tracker_backendlib_sources,
+  dependencies: tracker_backendlib_deps,
+  vala_args: tracker_backendlib_vala_flags,
+  c_args: tracker_backendlib_c_flags,
+  link_args: tracker_backendlib_link_flags,
+  version: folks_tracker_lib_version,
+  vala_header: 'folks/folks-@0@.h'.format(dummy_backend_name),
+  vala_gir: tracker_backendlib_gir_name + '.gir',
+  install: true,
+  install_dir: [ true, folks_headers_install_dir, true, true ],
+)
+
+# FIXME: This comes straight from the Meson docs on how to create/install a
+# typelib file for your Vala shared library. However, as mentioned in
+# https://github.com/mesonbuild/meson/issues/4481, this is not ideal.
+custom_target(tracker_backendlib_gir_name + ' typelib',
+  command: [ g_ir_compiler,
+    '--output', '@OUTPUT@',
+    meson.current_build_dir() / (tracker_backendlib_gir_name + '.gir')
+  ],
+  output: tracker_backendlib_gir_name + '.typelib',
+  depends: tracker_backendlib,
+  install: true,
+  install_dir: folks_typelibdir,
+)
+
+tracker_backendlib_dep = declare_dependency(
+  link_with: tracker_backendlib,
+  include_directories: include_directories('.'),
+  dependencies: tracker_sparql_dep,
+)
+
+# Pkg-config file
+configure_file(
+  input: 'folks-tracker.pc.in',
+  output: 'folks-tracker.pc',
+  configuration: pkg_conf,
+  install_dir: pkg_install_dir,
+)
diff --git a/backends/tracker/meson.build b/backends/tracker/meson.build
new file mode 100644
index 00000000..8a93eac9
--- /dev/null
+++ b/backends/tracker/meson.build
@@ -0,0 +1,40 @@
+# The tracker backend
+tracker_backend_name = 'tracker'
+
+# Backend library
+subdir('lib')
+
+tracker_backend_sources = [
+  'tr-backend-factory.vala',
+  'tr-backend.vala',
+]
+
+tracker_backend_deps = [
+  backend_deps,
+  tracker_sparql_dep,
+  tracker_backendlib_dep,
+]
+
+tracker_backend_vala_flags = [
+  '--pkg', 'folks-generics',
+  '--pkg', 'build-conf',
+]
+
+tracker_backend_c_flags = [
+  '-include', 'config.h',
+  '-DBACKEND_NAME="@0@"'.format(tracker_backend_name),
+  '-DG_LOG_DOMAIN="@0@"'.format(tracker_backend_name),
+]
+
+tracker_backend = shared_library(tracker_backend_name,
+  tracker_backend_sources,
+  dependencies: tracker_backend_deps,
+  vala_args: tracker_backend_vala_flags,
+  c_args: tracker_backend_c_flags,
+  link_with: libfolks_internal,
+  name_prefix: '',
+  install_dir: folks_backend_dir / tracker_backend_name,
+  install: true,
+)
+
+folks_backends += tracker_backend
diff --git a/docs/devhelp/meson.build b/docs/devhelp/meson.build
new file mode 100644
index 00000000..b1afd64e
--- /dev/null
+++ b/docs/devhelp/meson.build
@@ -0,0 +1,24 @@
+# Build the devhelp documentation for libfolks and each backend library
+foreach doc_target : valadoc_targets
+  doc_name = doc_target[0]
+  doc_source_files = doc_target[1]
+  doc_library = doc_target[2]
+  doc_deps = doc_target[3]
+
+  doc_valadoc = custom_target(doc_name + '-valadoc',
+    input: doc_source_files,
+    output: doc_name,
+    command: [ valadoc,
+      '-o', meson.current_build_dir() / doc_name,
+      docs_common_valadoc_flags,
+      docs_common_valadoc_deps,
+      doc_deps,
+      '--doclet=devhelp',
+      '--wiki=@0@'.format(meson.current_source_dir() / '..' / 'wiki'),
+      '@INPUT@',
+    ],
+    depends: doc_library,
+    install: true,
+    install_dir: get_option('datadir') / 'devhelp' / 'references',
+  )
+endforeach
diff --git a/docs/gtkdoc/meson.build b/docs/gtkdoc/meson.build
new file mode 100644
index 00000000..a57aee2d
--- /dev/null
+++ b/docs/gtkdoc/meson.build
@@ -0,0 +1,25 @@
+# Build the gtkdoc documentation for libfolks and each backend library
+foreach doc_target : valadoc_targets
+  doc_name = doc_target[0]
+  doc_source_files = doc_target[1]
+  doc_library = doc_target[2]
+  doc_deps = doc_target[3]
+
+  doc_gtkdoc = custom_target(doc_name + '-gtkdoc',
+    input: doc_source_files,
+    output: doc_name,
+    command: [ valadoc,
+      '-X', '-l', '-X', libfolks_lib.full_path(),
+      '-X', '-l', '-X', doc_library.full_path(),
+      '-o', meson.current_build_dir() / doc_name,
+      docs_common_valadoc_flags,
+      docs_common_valadoc_deps,
+      doc_deps,
+      '--doclet=gtkdoc',
+      '@INPUT@',
+     ],
+    depends: doc_library,
+    install: true,
+    install_dir: get_option('datadir') / 'gtk-doc' / 'html',
+  )
+endforeach
diff --git a/docs/meson.build b/docs/meson.build
new file mode 100644
index 00000000..2971d74d
--- /dev/null
+++ b/docs/meson.build
@@ -0,0 +1,49 @@
+# Specify some common flags
+docs_common_valadoc_flags = [
+  '--force',
+  '--package-version', meson.project_version(),
+  '--no-protected',
+  '-X', meson.build_root() / 'folks' / 'folks.h',
+]
+
+docs_common_valadoc_deps = [
+  '--pkg', 'gmodule-2.0',
+  '--pkg', 'glib-2.0',
+  '--pkg', 'gio-2.0',
+  '--pkg', 'gee-0.8',
+  '--vapidir', meson.build_root() / 'folks',
+  '--pkg', 'folks-internal',
+  '--vapidir', meson.source_root() / 'folks',
+  '--pkg', 'folks-generics',
+  '--pkg', 'build-conf',
+]
+
+# The modules we should build for
+valadoc_targets = [
+  [ 'folks',       libfolks_sources,         libfolks_lib,     []                        ],
+  [ 'folks-dummy', dummy_backendlib_sources, dummy_backendlib, dummy_backendlib_doc_deps ],
+]
+
+if eds_backend_enabled
+  valadoc_targets += [[ 'folks-eds', eds_backendlib_sources, eds_backendlib, eds_backendlib_doc_deps ]]
+endif
+
+if libsocialweb_backend_enabled
+  valadoc_targets += [[ 'folks-libsocialweb', libsocialweb_backendlib_sources, libsocialweb_backendlib, 
libsocialweb_backendlib_doc_deps ]]
+endif
+
+if telepathy_backend_enabled
+  valadoc_targets += [[ 'folks-telepathy', telepathy_backendlib_sources, telepathy_backendlib, 
telepathy_backendlib_doc_deps ]]
+endif
+
+if tracker_backend_enabled
+  valadoc_targets += [[ 'folks-tracker', tracker_backendlib_sources, tracker_backendlib, 
tracker_backendlib_doc_deps ]]
+endif
+
+# First, the devhelp modules
+subdir('devhelp')
+
+# Second, the gtk-doc module
+# FIXME: for some reason, this is broken due to the gtkdoc module not finding
+# the folks header
+# subdir('gtkdoc')
diff --git a/folks/meson.build b/folks/meson.build
new file mode 100644
index 00000000..130f6dd8
--- /dev/null
+++ b/folks/meson.build
@@ -0,0 +1,146 @@
+# Internal library
+libfolks_internal_sources = [
+  'internal.vala',
+  'small-set.c',
+]
+
+libfolks_internal_deps = [
+  gobject_dep,
+  gio_dep,
+  gee_dep,
+  posix_dep,
+]
+
+libfolks_internal = static_library('folks-internal',
+  libfolks_internal_sources,
+  include_directories: include_directories('..'),
+  dependencies: libfolks_internal_deps,
+)
+
+libfolks_internal_dep = declare_dependency(
+  link_with: libfolks_internal,
+)
+
+# Core library
+libfolks_gir_name = 'Folks-@0@'.format(folks_api_version)
+
+libfolks_sources = files(
+  'abstract-field-details.vala',
+  'alias-details.vala',
+  'anti-linkable.vala',
+  'avatar-cache.vala',
+  'avatar-details.vala',
+  'backend-store.vala',
+  'backend.vala',
+  'birthday-details.vala',
+  'debug.vala',
+  'email-details.vala',
+  'extended-info.vala',
+  'favourite-details.vala',
+  'folks-namespace.vala',
+  'gender-details.vala',
+  'group-details.vala',
+  'im-details.vala',
+  'individual-aggregator.vala',
+  'individual.vala',
+  'interaction-details.vala',
+  'local-id-details.vala',
+  'location-details.vala',
+  'name-details.vala',
+  'note-details.vala',
+  'object-cache.vala',
+  'persona-store.vala',
+  'persona.vala',
+  'phone-details.vala',
+  'postal-address-details.vala',
+  'potential-match.vala',
+  'presence-details.vala',
+  'query.vala',
+  'role-details.vala',
+  'search-view.vala',
+  'simple-query.vala',
+  'types.vala',
+  'url-details.vala',
+  'utils.vala',
+  'web-service-details.vala',
+)
+
+libfolks_deps = [
+  gobject_dep,
+  gmodule_dep,
+  gio_dep,
+  gee_dep,
+]
+
+libfolks_vala_flags = [
+  '--pkg', 'folks-generics',
+  '--pkg', 'build-conf',
+  '--includedir', meson.project_name(),
+]
+
+libfolks_c_flags = [
+  '-include', 'config.h',
+  '-DG_LOG_DOMAIN="folks"',
+]
+
+libfolks_lib = shared_library('folks',
+  libfolks_sources,
+  dependencies: libfolks_deps,
+  include_directories: config_h_dir,
+  link_with: libfolks_internal,
+  vala_args: libfolks_vala_flags,
+  c_args: libfolks_c_flags,
+  vala_header: 'folks/folks.h',
+  vala_gir: libfolks_gir_name + '.gir',
+  version: folks_lib_version,
+  install: true,
+  install_dir: [ true, folks_headers_install_dir, true, true ],
+)
+
+# FIXME: This comes straight from the Meson docs on how to create/install a
+# typelib file for your Vala shared library. However, as mentioned in
+# https://github.com/mesonbuild/meson/issues/4481, this is not ideal.
+custom_target(libfolks_gir_name + '.typelib',
+  command: [ g_ir_compiler,
+    '--output', '@OUTPUT@',
+    meson.current_build_dir() / (libfolks_gir_name + '.gir')
+  ],
+  output: libfolks_gir_name + '.typelib',
+  depends: libfolks_lib,
+  install: true,
+  install_dir: folks_typelibdir,
+)
+libfolks_gir_include_dir = meson.current_build_dir()
+
+libfolks_dep = declare_dependency(
+  link_with: libfolks_lib,
+  dependencies: libfolks_deps,
+  include_directories: include_directories('.', '..')
+)
+
+# GSettings
+gsettings_conf = configuration_data()
+gsettings_conf.set('GETTEXT_PACKAGE', meson.project_name())
+gschema_file = configure_file(
+  input: 'org.freedesktop.folks.gschema.xml.in',
+  output: 'org.freedesktop.folks.gschema.xml',
+  configuration: gsettings_conf,
+)
+install_data(gschema_file,
+  install_dir: get_option('datadir') / 'glib-2.0' / 'schemas',
+)
+
+# Pkg-config file
+pkgconfig.generate(libfolks_lib,
+  name: 'Folks',
+  description: 'The Folks meta-contacts library',
+  filebase: 'folks',
+  requires: [ glib_dep, gobject_dep, gee_dep, ],
+  variables: [
+    'exec_prefix=${prefix}',
+    'bindir=${prefix}' / get_option('bindir'),
+    'datarootdir=${prefix}' / get_option('datadir'),
+    'datadir=${datarootdir}',
+    'vapidir=${datarootdir}/vala/vapi',
+  ],
+)
diff --git a/meson.build b/meson.build
new file mode 100644
index 00000000..2d615a72
--- /dev/null
+++ b/meson.build
@@ -0,0 +1,243 @@
+project('folks', [ 'vala', 'c' ],
+  version: '0.11.5.0',
+  license: 'LGPL2.1+',
+  meson_version: '>= 0.49',
+)
+
+gnome = import('gnome')
+i18n = import('i18n')
+pkgconfig = import('pkgconfig')
+
+# Versions
+#-------------------------------------------------
+
+# Core library API version (potentially used for parallel installation)
+folks_api_version = '0.6'
+
+# Core library version. When updating this, don't forget to bump the backend
+# library versions too, below.
+#
+# The major version number is additionally used as libfolks' module API version
+# number: a given libfolks.so will only load modules which were compiled
+# against a core with the same major version as itself. This allows the API
+# which is exposed to the modules to be changed.
+folks_lib_version = '25.18.4'
+
+# Each of the backend libraries (e.g. libfolks-eds.so; *not* the loadable
+# modules, eds.so) has its own version. These should be incremented when the
+# core folks_lib_version is incremented (as all the backend libraries are
+# binary-dependent on libfolks.so), but should also be incremented when
+# incompatible changes are made in the backend library APIs themselves.
+folks_eds_lib_version = '25.18.4'
+folks_libsocialweb_lib_version = '25.18.4'
+folks_telepathy_lib_version = '25.18.4'
+folks_tracker_lib_version = '25.18.4'
+folks_dummy_lib_version = '25.18.4'
+
+# The module version is used to set the shared object versions
+_version_split = folks_lib_version.split('.')
+folks_module_version = _version_split[0].to_int() + _version_split[1].to_int()
+
+# Some useful directories
+#-------------------------------------------------
+folks_prefix = get_option('prefix')
+folks_typelibdir = folks_prefix / get_option('libdir') / 'girepository-1.0'
+folks_libexecdir = folks_prefix / get_option('libexecdir')
+pkg_install_dir = get_option('libdir') / 'pkgconfig'
+folks_headers_install_dir = get_option('includedir') / meson.project_name()
+installed_tests_dir = folks_libexecdir / 'installed-tests' / meson.project_name()
+installed_tests_meta_dir = get_option('datadir') / 'installed-tests' / meson.project_name()
+
+folks_backend_dir = get_option('libdir') / 'folks' / '@0@'.format(folks_module_version) / 'backends'
+
+# Options (see meson_options.txt for more info)
+#-------------------------------------------------
+bluez_backend_enabled = get_option('bluez_backend')
+docs_enabled = get_option('docs')
+eds_backend_enabled = get_option('eds_backend')
+installed_tests_enabled = get_option('installed_tests')
+libsocialweb_backend_enabled = get_option('libsocialweb_backend')
+ofono_backend_enabled = get_option('ofono_backend')
+telepathy_backend_enabled = get_option('telepathy_backend')
+tracker_backend_enabled = get_option('tracker_backend')
+zeitgeist_enabled = get_option('zeitgeist')
+import_tool_enabled = get_option('import_tool')
+inspect_tool_enabled = get_option('inspect_tool')
+
+# Dependencies
+#-------------------------------------------------
+min_glib_version = '2.40'    # Note, we use this for --target-glib as well, so don't add a micro version
+min_eds_version = '3.13.90'
+
+valac = meson.get_compiler('vala')
+cc = meson.get_compiler('c')
+
+dbus_glib_dep = dependency('dbus-glib-1') # FIXME: get rid of this when our dependencies stop using dbus-1 
(GNOME#696177)
+gee_dep = dependency('gee-0.8')
+gio_dep = dependency('gio-2.0')
+glib_dep = dependency('glib-2.0', version: '>=' + min_glib_version)
+gmodule_dep = dependency('gmodule-2.0')
+gobject_dep = dependency('gobject-2.0', version: '>=' + min_glib_version)
+libm_dep = cc.find_library('m')
+posix_dep = valac.find_library('posix')
+g_ir_compiler = find_program('g-ir-compiler')
+
+valadoc = find_program('valadoc', required: docs_enabled)
+
+if telepathy_backend_enabled
+  telepathy_glib_dep = dependency('telepathy-glib', version: '>= 0.19.9')
+
+  if zeitgeist_enabled
+    zeitgeist_dep = dependency('zeitgeist-2.0', version: '>= 0.9.14')
+  endif
+endif
+
+if tracker_backend_enabled
+  tracker_sparql_accepted_versions = [ '0.16', '0.18', '1.0', '2.0' ]
+  foreach version : tracker_sparql_accepted_versions
+    tracker_sparql_dep = dependency('tracker-sparql-@0@'.format(version),
+      version: '>= 0.15.2',
+      required: false,
+    )
+    if tracker_sparql_dep.found()
+      tracker_sparql_version = version
+      break
+    endif
+  endforeach
+
+  if not tracker_sparql_dep.found()
+    error('Tracker backend enabld, but couldn\'t find tracker-sparql package')
+  endif
+endif
+
+if eds_backend_enabled
+  libebook_dep = dependency('libebook-1.2', version: '>=' + min_eds_version)
+  libebook_contacts_dep = dependency('libebook-contacts-1.2', version: '>=' + min_eds_version)
+  libedataserver_dep = dependency('libedataserver-1.2', version: '>=' + min_eds_version)
+  libxml_dep = dependency('libxml-2.0')
+endif
+
+if ofono_backend_enabled
+  libebook_dep = dependency('libebook-1.2', version: '>=' + min_eds_version)
+endif
+
+if bluez_backend_enabled
+  libebook_dep = dependency('libebook-1.2', version: '>=' + min_eds_version)
+  # Needed for the BlueZ tests
+  pymod = import('python')
+  py_installation = pymod.find_installation('python3')
+  python_dbusmock = py_installation.dependency('dbusmock')
+endif
+
+if libsocialweb_backend_enabled
+  libsocialweb_dep = dependency('libsocialweb-client', version: '>= 0.25.20')
+endif
+
+if import_tool_enabled
+  libxml_dep = dependency('libxml-2.0')
+endif
+
+if inspect_tool_enabled
+  readline_dep = declare_dependency(
+    dependencies: [
+      cc.find_library('readline'),
+      valac.find_library('readline'),
+    ]
+  )
+endif
+
+# Configuration
+#-------------------------------------------------
+conf = configuration_data()
+conf.set_quoted('GETTEXT_PACKAGE', meson.project_name())
+conf.set_quoted('LOCALE_DIR', folks_prefix / get_option('localedir'))
+conf.set_quoted('PACKAGE_NAME', meson.project_name())
+conf.set_quoted('PACKAGE_STRING', meson.project_name())
+conf.set_quoted('PACKAGE_VERSION', meson.project_version())
+conf.set_quoted('ABS_TOP_SRCDIR', meson.source_root())
+conf.set_quoted('ABS_TOP_BUILDDIR', meson.build_root())
+conf.set_quoted('INSTALLED_TESTS_DIR', installed_tests_dir)
+conf.set_quoted('INSTALLED_TESTS_META_DIR', folks_prefix / installed_tests_meta_dir)
+conf.set_quoted('BACKEND_DIR', folks_prefix / folks_backend_dir)
+conf.set10('HAVE_BLUEZ', bluez_backend_enabled)
+conf.set10('HAVE_EDS', eds_backend_enabled)
+conf.set10('HAVE_LIBSOCIALWEB', libsocialweb_backend_enabled)
+conf.set10('HAVE_OFONO', ofono_backend_enabled)
+conf.set10('HAVE_TELEPATHY', telepathy_backend_enabled)
+conf.set10('HAVE_TRACKER', tracker_backend_enabled)
+if tracker_backend_enabled
+  conf.set_quoted('TRACKER_SPARQL_MAJOR', tracker_sparql_version)
+endif
+configure_file(output: 'config.h', configuration: conf)
+config_h_dir = include_directories('.')
+
+# Vala args
+add_project_arguments([
+    # Make sure the targets find the build-conf VAPI
+    '--vapidir', meson.source_root() / 'folks',
+    # within the libfolks tree, select inline code paths
+    '-D', 'FOLKS_COMPILATION',
+    # Set the target GLib to the minimal version we require as a dependency
+    '--target-glib', min_glib_version,
+  ],
+  language: 'vala'
+)
+
+# Configuration for pc.in files
+pkg_conf = configuration_data()
+pkg_conf.set('prefix', get_option('prefix'))
+pkg_conf.set('exec_prefix', '${prefix}')
+pkg_conf.set('libdir', '${prefix}/@0@'.format(get_option('libdir')))
+pkg_conf.set('bindir', '${prefix}/@0@'.format(get_option('bindir')))
+pkg_conf.set('includedir', '${prefix}/@0@'.format(get_option('includedir')))
+pkg_conf.set('datarootdir', '${prefix}/@0@'.format(get_option('datadir')))
+pkg_conf.set('datadir', '${datarootdir}')
+pkg_conf.set('VERSION', meson.project_version())
+if tracker_backend_enabled
+  pkg_conf.set('TRACKER_SPARQL_MAJOR', tracker_sparql_version)
+endif
+common_pkgconf_variables = [
+  'exec_prefix=${prefix}',
+  'bindir=${prefix}' / get_option('bindir'),
+  'datarootdir=${prefix}' / get_option('datadir'),
+  'datadir=${datarootdir}',
+  'vapidir=${datarootdir}' / 'vala' / 'vapi',
+]
+
+# Post-install scripts
+#-------------------------------------------------
+meson.add_install_script('meson_post_install.py')
+
+
+# Subdirectories
+#-------------------------------------------------
+
+# The core library
+subdir('folks')
+
+# The backends
+
+# This will be filed with the backends' build targets (_not_ the libraries)
+folks_backends = []
+
+subdir('backends')
+
+folks_backend_paths = [] # Add the backend's paths
+foreach backend : folks_backends
+  folks_backend_paths += backend.full_path()
+endforeach
+# Use this variable for FOLKS_BACKEND_PATH in an uninstalled environment
+folks_backend_path_uninstalled = ':'.join(folks_backend_paths)
+
+# Helper executables
+subdir('tools')
+
+# Translations
+subdir('po')
+
+# Tests
+subdir('tests')
+
+if docs_enabled
+  subdir('docs')
+endif
diff --git a/meson_options.txt b/meson_options.txt
new file mode 100644
index 00000000..8d16534b
--- /dev/null
+++ b/meson_options.txt
@@ -0,0 +1,15 @@
+# Backends
+option('bluez_backend', type: 'boolean', value: true, description: 'build the Bluez backend')
+option('eds_backend', type: 'boolean', value: true, description: 'build the E-D-S backend')
+option('libsocialweb_backend', type: 'boolean', value: false, description: 'build the libsocialweb backend')
+option('ofono_backend', type: 'boolean', value: true, description: 'build the oFono backend')
+option('telepathy_backend', type: 'boolean', value: true, description: 'build the Telepathy backend')
+option('tracker_backend', type: 'boolean', value: false, description: 'build the Tracker backend')
+option('zeitgeist', type: 'boolean', value: false, description: 'build Zeitgeist support in the Telepathy 
backend')
+# Tools
+option('import_tool', type: 'boolean', value: true, description: 'Enable building the meta-contact import 
tool')
+option('inspect_tool', type: 'boolean', value: true, description: 'Enable building the data inspection tool')
+# Test options
+option('installed_tests', type: 'boolean', value: false, description: 'Install test programs')
+# Docs
+option('docs', type: 'boolean', value: false, description: 'Enable documentation generation')
diff --git a/meson_post_install.py b/meson_post_install.py
new file mode 100644
index 00000000..bf320a9d
--- /dev/null
+++ b/meson_post_install.py
@@ -0,0 +1,15 @@
+#!/usr/bin/env python3
+
+import os
+import subprocess
+
+install_prefix = os.environ['MESON_INSTALL_PREFIX']
+icondir = os.path.join(install_prefix, 'share', 'icons', 'hicolor')
+schemadir = os.path.join(install_prefix, 'share', 'glib-2.0', 'schemas')
+
+if not os.environ.get('DESTDIR'):
+  print('Update icon cache...')
+  subprocess.call(['gtk-update-icon-cache', '-f', '-t', icondir])
+
+  print('Compiling gsettings schemas...')
+  subprocess.call(['glib-compile-schemas', schemadir])
diff --git a/po/meson.build b/po/meson.build
new file mode 100644
index 00000000..5fdd891b
--- /dev/null
+++ b/po/meson.build
@@ -0,0 +1,3 @@
+i18n.gettext(meson.project_name(),
+  preset: 'glib',
+)
diff --git a/tests/bluez/meson.build b/tests/bluez/meson.build
new file mode 100644
index 00000000..46d795b2
--- /dev/null
+++ b/tests/bluez/meson.build
@@ -0,0 +1,50 @@
+# in order from least to most complex
+bluez_tests = [
+  'device-properties',
+  'individual-retrieval',
+  'vcard-parsing',
+]
+
+bluez_tests_deps = [
+  common_test_deps,
+  libebook_dep,
+  libedataserver_dep,
+  libbluez_test_dep,
+  bluez_backend_dep,
+]
+
+bluez_tests_vala_flags = [
+  common_test_vala_flags,
+  '--pkg', 'folks-generics',
+]
+
+foreach _test: bluez_tests
+  test_install_dir = installed_tests_dir / bluez_backend_name
+
+  test_executable = executable('bluez-'+_test,
+    '@0@.vala'.format(_test),
+    dependencies: bluez_tests_deps,
+    vala_args: bluez_tests_vala_flags,
+    link_with: libfolks_internal,
+    install: installed_tests_enabled,
+    install_dir: test_install_dir,
+  )
+
+  test(_test, test_executable,
+    suite: 'BluezBackend',
+    env: common_test_environment,
+  )
+
+  if installed_tests_enabled
+    configure_file(
+      input: installed_test_template_in,
+      output: _test + '.test',
+      configuration: {
+        'libexecdir': folks_libexecdir,
+        'installed_tests_dir': test_install_dir,
+        'program': _test,
+      },
+      install_dir: installed_tests_meta_dir / bluez_backend_name
+    )
+  endif
+endforeach
diff --git a/tests/data/meson.build b/tests/data/meson.build
new file mode 100644
index 00000000..58c0f743
--- /dev/null
+++ b/tests/data/meson.build
@@ -0,0 +1,5 @@
+if installed_tests_enabled
+  install_data('avatar-01.jpg',
+    install_dir: installed_tests_dir / 'data',
+  )
+endif
diff --git a/tests/dummy/meson.build b/tests/dummy/meson.build
new file mode 100644
index 00000000..29478140
--- /dev/null
+++ b/tests/dummy/meson.build
@@ -0,0 +1,44 @@
+# in order from least to most complex
+dummy_tests = [
+  'individual-retrieval',
+  'add-persona',
+  'linkable-properties',
+  'search-view',
+]
+
+dummy_tests_deps = [
+  common_test_deps,
+  dummy_test_lib_dep,
+  dummy_backendlib_dep,
+]
+
+
+foreach _test: dummy_tests
+  test_install_dir = installed_tests_dir / dummy_backend_name
+
+  test_executable = executable('dummy-'+_test,
+    '@0@.vala'.format(_test),
+    dependencies: dummy_tests_deps,
+    vala_args: common_test_vala_flags,
+    install: installed_tests_enabled,
+    install_dir: test_install_dir,
+  )
+
+  test(_test, test_executable,
+    suite: 'DummyBackend',
+    env: common_test_environment,
+  )
+
+  if installed_tests_enabled
+    configure_file(
+      input: installed_test_template_in,
+      output: _test + '.test',
+      configuration: {
+        'libexecdir': folks_libexecdir,
+        'installed_tests_dir': test_install_dir,
+        'program': _test,
+      },
+      install_dir: installed_tests_meta_dir / dummy_backend_name
+    )
+  endif
+endforeach
diff --git a/tests/eds/meson.build b/tests/eds/meson.build
new file mode 100644
index 00000000..9ef5c2c1
--- /dev/null
+++ b/tests/eds/meson.build
@@ -0,0 +1,107 @@
+eds_tests_deps = [
+  common_test_deps,
+  posix_dep,
+  libebook_dep,
+  libedataserver_dep,
+  libxml_dep,
+  libeds_test_dep,
+  eds_backendlib_dep,
+]
+
+eds_tests_vala_flags = [
+  common_test_vala_flags,
+]
+
+
+# First we make the test helpers
+helpers = [
+  'helper-create-many-contacts',
+  'helper-delete-contacts',
+  'helper-prepare-aggregator',
+]
+
+foreach helper: helpers
+  executable(helper,
+    '@0@.vala'.format(helper),
+    dependencies: eds_tests_deps,
+    vala_args: eds_tests_vala_flags,
+  )
+endforeach
+
+# in order from least to most complex
+eds_tests = [
+  'persona-store-tests',
+  'individual-retrieval',
+  'phone-details',
+  'email-details',
+  'name-details',
+  'removing-contacts',
+  'updating-phones',
+  'updating-contacts',
+  'avatar-details',
+  'add-persona',
+  'im-details',
+  'postal-address-details',
+  'remove-persona',
+  'set-emails',
+  'set-im-addresses',
+  'link-personas',
+  'add-contacts-stress-test',
+  'set-properties',
+  'set-properties-race',
+  'linkable-properties',
+  'link-personas-diff-stores',
+  'store-removed',
+  'anti-linking',
+  'enable-disable-stores',
+  'extended-info',
+]
+
+eds_benchmarks = [
+  'perf',
+]
+
+foreach _test: eds_tests
+  test_install_dir = installed_tests_dir / eds_backend_name
+
+  test_executable = executable('eds-'+_test,
+    '@0@.vala'.format(_test),
+    dependencies: eds_tests_deps,
+    vala_args: eds_tests_vala_flags,
+    install: installed_tests_enabled,
+    install_dir: test_install_dir,
+  )
+
+  test(_test, test_executable,
+    suite: 'EDSBackend',
+    is_parallel: false, # FIXME: https://gitlab.gnome.org/GNOME/folks/issues/69
+    env: common_test_environment,
+  )
+
+  if installed_tests_enabled
+    configure_file(
+      input: installed_test_template_in,
+      output: _test + '.test',
+      configuration: {
+        'libexecdir': folks_libexecdir,
+        'installed_tests_dir': test_install_dir,
+        'program': _test,
+      },
+      install_dir: installed_tests_meta_dir / eds_backend_name
+    )
+  endif
+endforeach
+
+foreach _benchmark: eds_benchmarks
+
+  benchmark_executable = executable('eds-'+_benchmark,
+    '@0@.vala'.format(_benchmark),
+    dependencies: eds_tests_deps,
+    vala_args: eds_tests_vala_flags,
+  )
+
+  benchmark(_benchmark, benchmark_executable,
+    suite: 'EDSBackend',
+    env: common_test_environment,
+  )
+endforeach
diff --git a/tests/folks/meson.build b/tests/folks/meson.build
new file mode 100644
index 00000000..0f6fe8f5
--- /dev/null
+++ b/tests/folks/meson.build
@@ -0,0 +1,41 @@
+# in order from least to most complex
+_folks_tests = [
+  'small-set',
+  'abstract-field-details',
+  'async-locking',
+  'utils',
+  'primary-store-changes',
+  'backend-loading',
+  'aggregation',
+  'standalone-individuals',
+  'avatar-cache',
+  'object-cache',
+  'phone-field-details',
+  'name-details',
+  'init',
+]
+
+_folks_tests_deps = [
+  common_test_deps,
+  dummy_test_lib_dep,
+  telepathy_test_lib_dep,
+]
+
+_folks_tests_vala_flags = [
+  common_test_vala_flags,
+  '--pkg', 'folks-generics',
+]
+
+
+foreach _test: _folks_tests
+  test_executable = executable('_folks-'+_test,
+    '@0@.vala'.format(_test),
+    dependencies: _folks_tests_deps,
+    vala_args: _folks_tests_vala_flags,
+  )
+
+  test(_test, test_executable,
+    suite: 'folks',
+    env: common_test_environment,
+  )
+endforeach
diff --git a/tests/key-file/meson.build b/tests/key-file/meson.build
new file mode 100644
index 00000000..931590ca
--- /dev/null
+++ b/tests/key-file/meson.build
@@ -0,0 +1,48 @@
+# in order from least to most complex
+keyfile_tests = [
+  'individual-retrieval',
+]
+
+keyfile_tests_deps = [
+  gobject_dep,
+  gio_dep,
+  gee_dep,
+  libfolks_dep,
+  libfolks_test_dep,
+  libkeyfile_test_dep,
+  folks_test_dbus,
+]
+
+keyfile_tests_vala_flags = [
+  '--debug',
+]
+
+foreach _test: keyfile_tests
+  test_install_dir = installed_tests_dir / keyfile_backend_name
+
+  test_executable = executable('keyfile-'+_test,
+    '@0@.vala'.format(_test),
+    dependencies: keyfile_tests_deps,
+    vala_args: keyfile_tests_vala_flags,
+    install: installed_tests_enabled,
+    install_dir: test_install_dir,
+  )
+
+  test(_test, test_executable,
+    suite: 'KeyfileBackend',
+    env: common_test_environment,
+  )
+
+  if installed_tests_enabled
+    configure_file(
+      input: installed_test_template_in,
+      output: _test + '.test',
+      configuration: {
+        'libexecdir': folks_libexecdir,
+        'installed_tests_dir': test_install_dir,
+        'program': _test,
+      },
+      install_dir: installed_tests_meta_dir / keyfile_backend_name
+    )
+  endif
+endforeach
diff --git a/tests/lib/bluez/meson.build b/tests/lib/bluez/meson.build
new file mode 100644
index 00000000..3b23a185
--- /dev/null
+++ b/tests/lib/bluez/meson.build
@@ -0,0 +1,15 @@
+libbluez_test_sources = [
+  'test-case.vala',
+  'backend.vala',
+]
+
+libbluez_test = library('bluez-test',
+  libbluez_test_sources,
+  dependencies: common_test_lib_deps,
+  vala_args: common_test_lib_flags,
+)
+
+libbluez_test_dep = declare_dependency(
+  link_with: libbluez_test,
+  include_directories: include_directories('.'),
+)
diff --git a/tests/lib/dummy/meson.build b/tests/lib/dummy/meson.build
new file mode 100644
index 00000000..3e689b73
--- /dev/null
+++ b/tests/lib/dummy/meson.build
@@ -0,0 +1,20 @@
+dummy_test_lib_sources = [
+  'test-case.vala',
+]
+
+dummy_test_lib_deps = [
+  common_test_lib_deps,
+  dummy_backendlib_dep,
+]
+
+dummy_test_lib = library('dummy-test',
+  dummy_test_lib_sources,
+  dependencies: dummy_test_lib_deps,
+  vala_args: common_test_lib_flags,
+)
+
+dummy_test_lib_dep = declare_dependency(
+  link_with: dummy_test_lib,
+  include_directories: include_directories('.'),
+  dependencies: dummy_backendlib_dep,
+)
diff --git a/tests/lib/eds/meson.build b/tests/lib/eds/meson.build
new file mode 100644
index 00000000..b31803d2
--- /dev/null
+++ b/tests/lib/eds/meson.build
@@ -0,0 +1,21 @@
+libeds_test_sources = [
+  'backend.vala',
+  'test-case.vala',
+]
+
+libeds_test_deps = [
+  common_test_lib_deps,
+  libebook_dep,
+  eds_backendlib_dep,
+]
+
+libeds_test = library('eds-test',
+  libeds_test_sources,
+  dependencies: libeds_test_deps,
+  vala_args: common_test_lib_flags,
+)
+
+libeds_test_dep = declare_dependency(
+  link_with: libeds_test,
+  include_directories: include_directories('.'),
+)
diff --git a/tests/lib/key-file/meson.build b/tests/lib/key-file/meson.build
new file mode 100644
index 00000000..740b50d8
--- /dev/null
+++ b/tests/lib/key-file/meson.build
@@ -0,0 +1,15 @@
+libkeyfile_test_sources = [
+  'backend.vala',
+  'test-case.vala',
+]
+
+libkeyfile_test = library('keyfile-test',
+  libkeyfile_test_sources,
+  dependencies: common_test_lib_deps,
+  vala_args: common_test_lib_flags,
+)
+
+libkeyfile_test_dep = declare_dependency(
+  link_with: libkeyfile_test,
+  include_directories: include_directories('.'),
+)
diff --git a/tests/lib/libsocialweb/meson.build b/tests/lib/libsocialweb/meson.build
new file mode 100644
index 00000000..796a3966
--- /dev/null
+++ b/tests/lib/libsocialweb/meson.build
@@ -0,0 +1,15 @@
+libsocialweb_test_lib_sources = [
+  'test-case.vala',
+  'backend.vala',
+]
+
+libsocialweb_test_lib = library('libsocialweb-test-lib',
+  libsocialweb_test_lib_sources,
+  dependencies: common_test_lib_deps,
+  vala_args: common_test_lib_flags,
+)
+
+libsocialweb_test_lib_dep = declare_dependency(
+  link_with: libsocialweb_test_lib,
+  include_directories: include_directories('.'),
+)
diff --git a/tests/lib/meson.build b/tests/lib/meson.build
new file mode 100644
index 00000000..37e87c63
--- /dev/null
+++ b/tests/lib/meson.build
@@ -0,0 +1,74 @@
+# The library that is used by the test libraries
+libfolks_test_sources = [
+  'disconnection-queue.vala',
+  'gtestdbus.c',
+  'haze-remove-directory.c',
+  'org-freedesktop-dbus-mock.vala',
+  'test-case-helper.c',
+  'test-case.vala',
+  'test-utils.vala',
+]
+
+libfolks_test_deps = [
+  gobject_dep,
+  gio_dep,
+  gee_dep,
+  dbus_glib_dep,
+  libfolks_dep,
+  folks_test_dbus,
+  posix_dep,
+]
+
+libfolks_test_vala_flags = [
+  '--debug',
+  '--pkg', 'build-conf',
+  '-h', 'folks-test-internal.h',
+]
+
+libfolks_test = library('folks-test',
+  libfolks_test_sources,
+  dependencies: libfolks_test_deps,
+  vala_args: libfolks_test_vala_flags,
+)
+
+libfolks_test_dep = declare_dependency(
+  link_with: libfolks_test,
+  include_directories: include_directories('.'),
+)
+
+# Common variables
+common_test_lib_deps = [
+  gobject_dep,
+  libfolks_dep,
+  libfolks_test_dep,
+  folks_test_dbus,
+]
+
+common_test_lib_flags = [
+  '--debug',
+]
+
+# Subdirs
+subdir('dummy')
+subdir('key-file')
+
+if bluez_backend_enabled
+  subdir('bluez')
+endif
+
+if telepathy_backend_enabled
+  subdir('telepathy/contactlist')
+  subdir('telepathy')
+endif
+
+if libsocialweb_backend_enabled
+  subdir('libsocialweb')
+endif
+
+if eds_backend_enabled
+  subdir('eds')
+endif
+
+if tracker_backend_enabled
+  subdir('tracker')
+endif
diff --git a/tests/lib/telepathy/contactlist/meson.build b/tests/lib/telepathy/contactlist/meson.build
new file mode 100644
index 00000000..00e02669
--- /dev/null
+++ b/tests/lib/telepathy/contactlist/meson.build
@@ -0,0 +1,72 @@
+# Taken from telepathy-glib. The only change is to remove the option to install
+# the data files.
+#
+# PLEASE DO NOT MODIFY THIS CONNECTION MANAGER. Either subclass it,
+# copy-and-modify (moving it to a better namespace), or make changes in the
+# copy in telepathy-glib first.
+
+telepathy_test_contactlist_sources = [
+  'backend.c',
+  'contact-list-manager.c',
+  'contacts-conn.c',
+  'room-list-chan.c',
+  'simple-account-manager.c',
+  'simple-account.c',
+  'simple-conn.c',
+  'textchan-null.c',
+  'util.c',
+]
+
+ telepathy_test_contactlist_headers = [ # Needed for GIR
+  'backend.h',
+  'contact-list-manager.h',
+  'contacts-conn.h',
+  'debug.h',
+  'room-list-chan.h',
+  'simple-account-manager.h',
+  'simple-account.h',
+  'simple-conn.h',
+  'textchan-null.h',
+  'util.h',
+]
+
+telepathy_test_contactlist_manager = custom_target('tp_test_contact_list.manager',
+  output: 'param-spec-struct.h',
+  input: 'manager-file.py',
+  command: [ test_tools_manager_file_script,
+    '@INPUT@',
+    meson.current_build_dir(),
+  ],
+)
+
+telepathy_test_contactlist_deps = [
+  glib_dep,
+  gio_dep,
+  gobject_dep,
+  telepathy_glib_dep,
+  dbus_glib_dep,
+]
+
+telepathy_test_contactlist_lib = static_library('tp-test-contactlist',
+  [ telepathy_test_contactlist_sources, telepathy_test_contactlist_manager ],
+  dependencies: telepathy_test_contactlist_deps,
+  include_directories: config_h_dir,
+)
+
+telepathy_test_contactlist_gir = gnome.generate_gir(telepathy_test_contactlist_lib,
+  sources: [ telepathy_test_contactlist_sources, telepathy_test_contactlist_headers ],
+  includes: [ 'GObject-2.0', 'TelepathyGLib-0.12' ],
+  nsversion: folks_api_version,
+  namespace: 'TpTests',
+  header: 'tp-test-contactlist.h',
+)
+
+telepathy_test_contactlist_vapi = gnome.generate_vapi('tp-test-contactlist',
+  sources: telepathy_test_contactlist_gir.get(0),
+  packages: [ 'gio-2.0', 'telepathy-glib' ],
+)
+
+telepathy_test_contactlist_dep = declare_dependency(
+  link_with: telepathy_test_contactlist_lib,
+  dependencies: telepathy_test_contactlist_vapi,
+)
diff --git a/tests/lib/telepathy/meson.build b/tests/lib/telepathy/meson.build
new file mode 100644
index 00000000..285267ee
--- /dev/null
+++ b/tests/lib/telepathy/meson.build
@@ -0,0 +1,27 @@
+telepathy_test_lib_sources = [
+  'test-case.vala',
+]
+
+telepathy_test_lib_deps = [
+  common_test_lib_deps,
+  telepathy_test_contactlist_dep,
+  telepathy_backendlib_dep,
+  libkeyfile_test_dep,
+]
+
+telepathy_test_lib = library('telepathy-test',
+  telepathy_test_lib_sources,
+  dependencies: telepathy_test_lib_deps,
+  vala_args: common_test_lib_flags,
+)
+
+telepathy_test_lib_dep = declare_dependency(
+  link_with: telepathy_test_lib,
+  include_directories: include_directories('.'),
+  dependencies: [
+    telepathy_backendlib_dep,
+    # Exposed by the VAPI
+    libkeyfile_test_dep,
+    telepathy_test_contactlist_dep,
+  ],
+)
diff --git a/tests/lib/test-case.vala b/tests/lib/test-case.vala
index 3b60e988..2dc58daa 100644
--- a/tests/lib/test-case.vala
+++ b/tests/lib/test-case.vala
@@ -65,8 +65,10 @@ public abstract class Folks.TestCase : Object
       this._transient_dir = this.create_transient_dir ();
       this.private_bus_up ();
 
-      if (Environment.get_variable ("FOLKS_TESTS_INSTALLED") == null)
+      /* if (Environment.get_variable ("FOLKS_TESTS_INSTALLED") == null) */
+      if (false)
         {
+            /* XXX fix this (no .libs) */
           string[] locations = {
               Folks.BuildConf.ABS_TOP_BUILDDIR + "/backends/key-file/.libs/key-file.so",
               Folks.BuildConf.ABS_TOP_BUILDDIR + "/backends/dummy/.libs/dummy.so",
@@ -91,7 +93,7 @@ public abstract class Folks.TestCase : Object
             locations += Folks.BuildConf.ABS_TOP_BUILDDIR + "/backends/bluez/.libs/bluez.so";
 
           Environment.set_variable ("FOLKS_BACKEND_PATH",
-              string.joinv (":", locations), true);
+              string.joinv (":", locations), false);
         }
 
       /* By default, no backend is allowed. Subclasses must override. */
diff --git a/tests/lib/tracker/meson.build b/tests/lib/tracker/meson.build
new file mode 100644
index 00000000..4a1bcc11
--- /dev/null
+++ b/tests/lib/tracker/meson.build
@@ -0,0 +1,26 @@
+tracker_test_lib_sources = [
+  'test-case.vala',
+  'backend.vala',
+]
+
+tracker_test_lib_deps = [
+  common_test_lib_deps,
+  tracker_backendlib_dep,
+]
+
+tracker_test_lib_vala_flags = [
+  common_test_lib_flags,
+  '--pkg', 'build-conf',
+]
+
+tracker_test_lib = library('tracker-test-lib',
+  tracker_test_lib_sources,
+  dependencies: tracker_test_lib_deps,
+  vala_args: tracker_test_lib_vala_flags,
+)
+
+tracker_test_lib_dep = declare_dependency(
+  link_with: tracker_test_lib,
+  include_directories: include_directories('.'),
+  dependencies: tracker_sparql_dep,
+)
diff --git a/tests/libsocialweb/meson.build b/tests/libsocialweb/meson.build
new file mode 100644
index 00000000..48326cca
--- /dev/null
+++ b/tests/libsocialweb/meson.build
@@ -0,0 +1,42 @@
+# in order from least to most complex
+libsocialweb_tests = [
+  'dummy-lsw',
+  'aggregation',
+]
+
+libsocialweb_tests_deps = [
+  common_test_deps,
+  libsocialweb_test_lib_dep,
+  libsocialweb_backendlib_dep,
+]
+
+
+foreach _test: libsocialweb_tests
+  test_install_dir = installed_tests_dir / libsocialweb_backend_name
+
+  test_executable = executable('libsocialweb-'+_test,
+    '@0@.vala'.format(_test),
+    dependencies: libsocialweb_tests_deps,
+    vala_args: common_test_vala_flags,
+    install: installed_tests_enabled,
+    install_dir: test_install_dir,
+  )
+
+  test(_test, test_executable,
+    suite: 'libsocialweb',
+    env: common_test_environment,
+  )
+
+  if installed_tests_enabled
+    configure_file(
+      input: installed_test_template_in,
+      output: _test + '.test',
+      configuration: {
+        'libexecdir': folks_libexecdir,
+        'installed_tests_dir': test_install_dir,
+        'program': _test,
+      },
+      install_dir: installed_tests_meta_dir / folks_libsocialweb_backend_name
+    )
+  endif
+endforeach
diff --git a/tests/meson.build b/tests/meson.build
new file mode 100644
index 00000000..229007ac
--- /dev/null
+++ b/tests/meson.build
@@ -0,0 +1,53 @@
+# A VAPI for common dbus tests
+folks_test_dbus = valac.find_library('folks-test-dbus',
+  dirs: meson.current_source_dir() / 'lib',
+)
+
+# Test template for installed tests
+installed_test_template_in = files('template.test.in')
+
+# Test data & helpers
+subdir('data')
+subdir('tools')
+
+# Libraries for the tests
+subdir('lib')
+
+# Common variables
+common_test_deps = [
+  libfolks_dep,
+  libfolks_test_dep,
+  folks_test_dbus,
+]
+
+common_test_vala_flags = [
+  '--debug',
+]
+
+common_test_environment = environment()
+common_test_environment.append('FOLKS_BACKEND_PATH', folks_backend_path_uninstalled)
+
+# The tests, grouped in a directory per backend
+subdir('dummy')
+subdir('key-file')
+
+if bluez_backend_enabled
+  subdir('bluez')
+endif
+
+if telepathy_backend_enabled
+  subdir('telepathy')
+  subdir('folks')
+endif
+
+if libsocialweb_backend_enabled
+  subdir('libsocialweb')
+endif
+
+if eds_backend_enabled
+  subdir('eds')
+endif
+
+if tracker_backend_enabled
+  subdir('tracker')
+endif
diff --git a/tests/telepathy/meson.build b/tests/telepathy/meson.build
new file mode 100644
index 00000000..37445126
--- /dev/null
+++ b/tests/telepathy/meson.build
@@ -0,0 +1,57 @@
+# Fake Telepathy backend. For use with client programs such as tests
+fake_tp_backend = executable('fake-tp-backend',
+  'fake-tp-backend.vala',
+  dependencies: [
+    libfolks_dep,
+    libfolks_test_dep,
+    telepathy_test_lib_dep,
+    folks_test_dbus,
+  ],
+)
+
+# in order from least to most complex
+telepathy_tests = [
+  'persona-store-capabilities',
+  'individual-retrieval',
+  'individual-properties',
+  'init',
+]
+
+telepathy_tests_deps = [
+  common_test_deps,
+  telepathy_test_lib_dep,
+]
+
+telepathy_tests_vala_flags = [
+  '--debug',
+]
+
+foreach _test: telepathy_tests
+  test_install_dir = installed_tests_dir / telepathy_backend_name
+
+  test_executable = executable('telepathy-'+_test,
+    '@0@.vala'.format(_test),
+    dependencies: telepathy_tests_deps,
+    vala_args: telepathy_tests_vala_flags,
+    install: installed_tests_enabled,
+    install_dir: test_install_dir,
+  )
+
+  test(_test, test_executable,
+    suite: 'Telepathy',
+    env: common_test_environment,
+  )
+
+  if installed_tests_enabled
+    configure_file(
+      input: installed_test_template_in,
+      output: _test + '.test',
+      configuration: {
+        'libexecdir': folks_libexecdir,
+        'installed_tests_dir': test_install_dir,
+        'program': _test,
+      },
+      install_dir: installed_tests_meta_dir / telepathy_backend_name
+    )
+  endif
+endforeach
diff --git a/tests/template.test.in b/tests/template.test.in
new file mode 100644
index 00000000..28421b81
--- /dev/null
+++ b/tests/template.test.in
@@ -0,0 +1,3 @@
+[Test]
+Type=session
+Exec=env G_ENABLE_DIAGNOSTIC=0 FOLKS_TESTS_INSTALLED=1 G_MESSAGES_DEBUG= 
FOLKS_TEST_EDS_LIBEXECDIR=@libexecdir@ FOLKS_TEST_TRACKER_LIBEXECDIR=@libexecdir@ 
@installed_tests_dir@/@program@
diff --git a/tests/tools/meson.build b/tests/tools/meson.build
new file mode 100644
index 00000000..babbe5f6
--- /dev/null
+++ b/tests/tools/meson.build
@@ -0,0 +1,2 @@
+# Used for telepathy test lib (contactlist)
+test_tools_manager_file_script = find_program('manager-file.py')
diff --git a/tests/tracker/meson.build b/tests/tracker/meson.build
new file mode 100644
index 00000000..10f7984e
--- /dev/null
+++ b/tests/tracker/meson.build
@@ -0,0 +1,99 @@
+# in order from least to most complex
+tracker_tests = [
+  'individual-retrieval',
+  'name-details-interface',
+  'avatar-details-interface',
+  'im-details-interface',
+  'phone-details-interface',
+  'email-details-interface',
+  'url-details-interface',
+  'favourite-details-interface',
+  'fullname-updates',
+  'add-contact',
+  'default-contact',
+  'remove-contact',
+  'nickname-updates',
+  'family-name-updates',
+  'given-name-updates',
+  'additional-names-updates',
+  'prefix-name-updates',
+  'suffix-name-updates',
+  'website-updates',
+  'favourite-updates',
+  'emails-updates',
+  'phones-updates',
+  'imaddresses-updates',
+  'role-details-interface',
+  'birthday-details-interface',
+  'birthday-updates',
+  'note-details-interface',
+  'gender-details-interface',
+  'postal-address-details-interface',
+  'avatar-updates',
+  'add-persona',
+  'remove-persona',
+  'set-nickname',
+  'set-favourite',
+  'set-phones',
+  'set-emails',
+  'set-avatar',
+  'set-structured-name',
+  'set-full-name',
+  'set-urls',
+  'set-im-addresses',
+  'set-postal-addresses',
+  'set-roles',
+  'set-notes',
+  'set-birthday',
+  'set-gender',
+  'link-personas',
+  'duplicated-emails',
+  'duplicated-phones',
+  'link-personas-via-local-ids',
+  'match-im-addresses',
+  'match-email-addresses',
+  'match-known-emails',
+  'match-phone-number',
+  'match-name',
+  'match-all',
+  'set-duplicate-email',
+  'set-null-avatar',
+]
+
+tracker_tests_deps = [
+  common_test_deps,
+  tracker_test_lib_dep,
+  tracker_backendlib_dep,
+]
+
+
+foreach _test: tracker_tests
+  test_install_dir = installed_tests_dir / tracker_backend_name
+
+  test_executable = executable('tracker-'+_test,
+    '@0@.vala'.format(_test),
+    dependencies: tracker_tests_deps,
+    vala_args: common_test_vala_flags,
+    install: installed_tests_enabled,
+    install_dir: test_install_dir,
+  )
+
+  test(_test, test_executable,
+    suite: 'TrackerBackend',
+    is_parallel: false, # FIXME: https://bugzilla.gnome.org/show_bug.cgi?id=709120
+    env: common_test_environment,
+  )
+
+  if installed_tests_enabled
+    configure_file(
+      input: installed_test_template_in,
+      output: _test + '.test',
+      configuration: {
+        'libexecdir': folks_libexecdir,
+        'installed_tests_dir': test_install_dir,
+        'program': _test,
+      },
+      install_dir: installed_tests_meta_dir / tracker_backend_name
+    )
+  endif
+endforeach
diff --git a/tools/inspect/meson.build b/tools/inspect/meson.build
new file mode 100644
index 00000000..71b641f7
--- /dev/null
+++ b/tools/inspect/meson.build
@@ -0,0 +1,42 @@
+folks_inspect_sources = [
+  'command-backends.vala',
+  'command-debug.vala',
+  'command-help.vala',
+  'command-individuals.vala',
+  'command-linking.vala',
+  'command-persona-stores.vala',
+  'command-personas.vala',
+  'command-quit.vala',
+  'command-search.vala',
+  'command-set.vala',
+  'command-signals.vala',
+  'inspect.vala',
+  'signal-manager.vala',
+  'utils.vala',
+]
+
+folks_inspect_deps = [
+  gobject_dep,
+  libfolks_dep,
+  posix_dep,
+  readline_dep,
+  gio_dep,
+  gee_dep,
+]
+
+folks_inspect_vala_flags = [
+  '--pkg', 'build-conf',
+]
+
+folks_inspect_c_flags = [
+  '-include', 'config.h',
+]
+
+folks_inspect = executable('folks-inspect',
+  folks_inspect_sources,
+  dependencies: folks_inspect_deps,
+  vala_args: folks_inspect_vala_flags,
+  c_args: folks_inspect_c_flags,
+  include_directories: config_h_dir,
+  install: true,
+)
diff --git a/tools/meson.build b/tools/meson.build
new file mode 100644
index 00000000..e5f9a023
--- /dev/null
+++ b/tools/meson.build
@@ -0,0 +1,37 @@
+# folks-inspect
+if inspect_tool_enabled
+  subdir('inspect')
+endif
+
+# folks-import
+if import_tool_enabled
+  folks_import_sources = [
+    'import.vala',
+    'import-pidgin.vala',
+  ]
+
+  folks_import_deps = [
+    gee_dep,
+    gobject_dep,
+    glib_dep,
+    libfolks_dep,
+    libxml_dep,
+  ]
+
+  folks_import_vala_flags = [
+    '--pkg', 'build-conf',
+  ]
+
+  folks_import_c_flags = [
+    '-include', 'config.h',
+  ]
+
+  folks_import = executable('folks-import',
+    folks_import_sources,
+    dependencies: folks_import_deps,
+    vala_args: folks_import_vala_flags,
+    c_args: folks_import_c_flags,
+    include_directories: config_h_dir,
+    install: true,
+  )
+endif


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