[gcr/wip/nielsdg/meson] Support Meson build system



commit 7d8b0d844208a9d61ac89bf19b8b9242e5ec2917
Author: Niels De Graef <nielsdegraef gmail com>
Date:   Sun Dec 30 00:40:17 2018 +0100

    Support Meson build system

 .gitlab-ci.yml                   |  23 ++++
 .gitlab-ci/meson-junit-report.py | 109 +++++++++++++++
 .gitlab-ci/run-tests.sh          |  15 +++
 docs/meson.build                 |   2 +
 docs/reference/gck/meson.build   |  36 +++++
 docs/reference/gcr/meson.build   |  76 +++++++++++
 egg/meson.build                  |  73 ++++++++++
 gck/libgck.map                   |   7 +
 gck/meson.build                  | 203 ++++++++++++++++++++++++++++
 gck/test-gck-crypto.c            |   4 +
 gck/test-gck-enumerator.c        |   4 +
 gck/test-gck-module.c            |  13 ++
 gck/test-gck-modules.c           |   4 +
 gck/test-gck-object.c            |   4 +
 gck/test-gck-session.c           |   4 +
 gck/test-gck-slot.c              |   4 +
 gcr/libgcr-base.map              |   8 ++
 gcr/meson.build                  | 283 +++++++++++++++++++++++++++++++++++++++
 gcr/test-ssh-askpass.c           |   4 +
 meson.build                      |  96 +++++++++++++
 meson_options.txt                |  20 +++
 meson_post_install.py            |  15 +++
 po/meson.build                   |   3 +
 schema/meson.build               |  13 ++
 ui/icons/meson.build             |  33 +++++
 ui/libgcr-ui.map                 |   8 ++
 ui/meson.build                   | 265 ++++++++++++++++++++++++++++++++++++
 27 files changed, 1329 insertions(+)
---
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 18825f0..e3c446c 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -5,6 +5,29 @@ stages:
 variables:
   DEPENDENCIES: dbus-x11 diffutils gcc gtk-doc make openssh python redhat-rpm-config
 
+fedora:meson:
+  image: fedora:latest
+  stage: build
+  before_script:
+    - dnf install -y 'dnf-command(builddep)'
+    - dnf builddep -y gcr
+    - dnf install -y $DEPENDENCIES meson ninja-build
+    - dbus-uuidgen --ensure
+  script:
+    - meson _build
+    - ninja -C _build
+    - eval `dbus-launch --sh-syntax`
+    - bash +x ./.gitlab-ci/run-tests.sh
+  artifacts:
+    reports:
+      junit: "_build/${CI_JOB_NAME}-report.xml"
+    name: "gcr-${CI_JOB_NAME}-${CI_COMMIT_REF_NAME}"
+    when: always
+    paths:
+      - "_build/config.h"
+      - "_build/meson-logs"
+      - "_build/${CI_JOB_NAME}-report.xml"
+
 fedora:Werror:
   image: fedora:latest
   stage: build
diff --git a/.gitlab-ci/meson-junit-report.py b/.gitlab-ci/meson-junit-report.py
new file mode 100755
index 0000000..248ef6e
--- /dev/null
+++ b/.gitlab-ci/meson-junit-report.py
@@ -0,0 +1,109 @@
+#!/usr/bin/env python3
+
+# Turns a Meson testlog.json file into a JUnit XML report
+#
+# Copyright 2019  GNOME Foundation
+#
+# SPDX-License-Identifier: LGPL-2.1-or-later
+#
+# Original author: Emmanuele Bassi
+
+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 0000000..f6b7dba
--- /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=gcr \
+        --job-id "${CI_JOB_NAME}" \
+        --output "_build/${CI_JOB_NAME}-report.xml" \
+        _build/meson-logs/testlog.json
+
+exit $exit_code
diff --git a/docs/meson.build b/docs/meson.build
new file mode 100644
index 0000000..f353516
--- /dev/null
+++ b/docs/meson.build
@@ -0,0 +1,2 @@
+subdir('reference/gck')
+subdir('reference/gcr')
diff --git a/docs/reference/gck/meson.build b/docs/reference/gck/meson.build
new file mode 100644
index 0000000..67918b7
--- /dev/null
+++ b/docs/reference/gck/meson.build
@@ -0,0 +1,36 @@
+version_xml = configure_file(
+  input: 'version.xml.in',
+  output: 'version.xml',
+  configuration: { 'VERSION': gck_version },
+)
+
+gck_docs_ignore_headers = [
+  'gck-private.h',
+  'test-suite.h',
+  'gck-mock.h',
+  'gck-test.h',
+  'pkcs11-trust-assertions.h',
+  'pkcs11.h',
+  'pkcs11n.h',
+  'pkcs11x.h',
+  'pkcs11i.h',
+]
+
+gnome.gtkdoc('gck',
+  main_sgml: 'gck-docs.sgml',
+  content_files: files(
+    'gck-pkcs11-links.xml',
+  ),
+  src_dir: [
+    include_directories('../../../gck'),
+  ],
+  ignore_headers: gck_docs_ignore_headers,
+  dependencies: gck_dep,
+  gobject_typesfile: 'gck.types',
+  scan_args: [
+    '--rebuild-types',
+    '--deprecated-guards=GCK_DISABLE_DEPRECATED',
+  ],
+  install: true,
+)
+
diff --git a/docs/reference/gcr/meson.build b/docs/reference/gcr/meson.build
new file mode 100644
index 0000000..0b1528e
--- /dev/null
+++ b/docs/reference/gcr/meson.build
@@ -0,0 +1,76 @@
+version_xml = configure_file(
+  input: 'version.xml.in',
+  output: 'version.xml',
+  configuration: { 'VERSION': gcr_version },
+)
+
+gcr_docs_images = [
+       'images/certificate-widget.png',
+       'images/combo-selector.png',
+       'images/import-button.png',
+       'images/list-selector.png',
+       'images/key-widget.png',
+       'images/tree-selector.png',
+       'images/viewer-widget.png',
+]
+
+gcr_docs_ignore_headers = [
+  'console-interaction.h',
+  'eggimagemenuitem.h',
+  'gcr-callback-output-stream.h',
+  'gcr-certificate-exporter.h',
+  'gcr-certificate-basics-widget.h',
+  'gcr-certificate-details-widget.h',
+  'gcr-certificate-request-renderer.h',
+  'gcr-dbus-constants.h',
+  'gcr-dbus-generated.h',
+  'gcr-deprecated.h',
+  'gcr-deprecated-base.h',
+  'gcr-display-scrolled.h',
+  'gcr-display-view.h',
+  'gcr-failure-renderer.h',
+  'gcr-gnupg-importer.h',
+  'gcr-gnupg-renderer.h',
+  'gcr-icons.h',
+  'gcr-import-dialog.h',
+  'gcr-internal.h',
+  'gcr-live-search.h',
+  'gcr-marshal.h',
+  'gcr-menu-button.h',
+  'gcr-oids.h',
+  'gcr-openpgp.h',
+  'gcr-pkcs11-importer.h',
+  'gcr-pkcs11-import-interaction.h',
+  'gcr-pkcs11-import-dialog.h',
+  'gcr-pkcs11-renderer.h',
+  'gcr-record.h',
+  'gcr-single-collection.h',
+  'gcr-unlock-renderer.h',
+  'gcr-viewer-window.h',
+  'gcr-xxx.h',
+  'gcr-zzz.h',
+]
+
+gnome.gtkdoc('gcr',
+  main_sgml: 'gcr-docs.sgml',
+  content_files: files(
+    'gcr-visual-index.xml',
+  ),
+  src_dir: [
+    include_directories('../../../gcr'),
+    include_directories('../../../ui'),
+  ],
+  ignore_headers: gcr_docs_ignore_headers,
+  dependencies: [ gcr_base_dep, gcr_ui_dep ],
+  gobject_typesfile: 'gcr.types',
+  html_assets: gcr_docs_images,
+  scan_args: [
+    '--rebuild-types',
+    '--deprecated-guards=GCR_DISABLE_DEPRECATED',
+  ],
+  install: true,
+)
+
+install_data(gcr_docs_images,
+  install_dir: gnome.gtkdoc_html_dir('gcr'),
+)
diff --git a/egg/meson.build b/egg/meson.build
new file mode 100644
index 0000000..937543d
--- /dev/null
+++ b/egg/meson.build
@@ -0,0 +1,73 @@
+libegg_sources = [
+  'egg-armor.c',
+  'egg-asn1x.c',
+  'egg-asn1-defs.c',
+  'egg-buffer.c',
+  'egg-dh.c',
+  'egg-dn.c',
+  'egg-decimal.c',
+  'egg-hex.c',
+  'egg-hkdf.c',
+  'egg-libgcrypt.c',
+  'egg-oid.c',
+  'egg-padding.c',
+  'egg-openssl.c',
+  'egg-secure-memory.c',
+  'egg-symkey.c',
+  'egg-testing.c',
+  'egg-timegm.c',
+]
+
+libegg_deps = [
+  glib_deps,
+  libgcrypt_dep,
+]
+
+libegg = static_library('egg',
+  libegg_sources,
+  dependencies: libegg_deps,
+  include_directories: config_h_dir,
+)
+
+libegg_dep = declare_dependency(
+  link_with: libegg,
+  dependencies: libegg_deps,
+)
+
+# Tests
+egg_test_lib = static_library('egg-test',
+  sources: [ 'egg-testing.c', 'mock-interaction.c' ],
+  dependencies: glib_deps,
+  include_directories: config_h_dir,
+)
+
+egg_test_names = [
+  'asn1',
+  'asn1x',
+  'dn',
+  'decimal',
+  'hex',
+  'hkdf',
+  'oid',
+  'secmem',
+  'padding',
+  'symkey',
+  'armor',
+  'openssl',
+  'dh',
+]
+
+foreach _test : egg_test_names
+  _test_name = 'egg-'+_test
+
+  egg_test_bin = executable(_test_name,
+    'test-@0@.c'.format(_test),
+       link_with: egg_test_lib,
+       dependencies: libegg_dep,
+    include_directories: config_h_dir,
+  )
+
+  test(_test, egg_test_bin,
+    suite: 'egg',
+  )
+endforeach
diff --git a/gck/libgck.map b/gck/libgck.map
new file mode 100644
index 0000000..b71b7e4
--- /dev/null
+++ b/gck/libgck.map
@@ -0,0 +1,7 @@
+{
+global:
+  gck_*;
+  SECMEM_*;
+local:
+  *;
+};
diff --git a/gck/meson.build b/gck/meson.build
new file mode 100644
index 0000000..2804ea6
--- /dev/null
+++ b/gck/meson.build
@@ -0,0 +1,203 @@
+gck_headers_install_dir = 'gck-@0@'.format(gck_major_version) / 'gck'
+
+gck_sources_public = [
+  'gck-attributes.c',
+  'gck-dump.c',
+  'gck-enumerator.c',
+  'gck-misc.c',
+  'gck-module.c',
+  'gck-modules.c',
+  'gck-object.c',
+  'gck-object-cache.c',
+  'gck-password.c',
+  'gck-session.c',
+  'gck-slot.c',
+  'gck-uri.c',
+]
+
+gck_sources_private = [
+  'gck-call.c',
+  'gck-interaction.c',
+]
+
+gck_headers = [
+  'gck.h',
+]
+
+# Generated sources
+gck_version_conf = configuration_data()
+gck_version_conf.set_quoted('GCR_MAJOR', gck_major_version)
+gck_version_conf.set_quoted('GCR_MINOR', gck_minor_version)
+gck_version_conf.set_quoted('GCR_MICRO', gck_micro_version)
+gck_version_h = configure_file(input: 'gck-version.h.in',
+  output: 'gck-version.h',
+  configuration: gck_version_conf,
+)
+
+gck_enums_gen = gnome.mkenums_simple('gck-enum-types',
+  sources: gck_headers,
+  install_header: true,
+  install_dir: get_option('includedir') / gck_headers_install_dir,
+)
+
+gck_marshal_gen = gnome.genmarshal('gck-marshal',
+  sources: 'gck-marshal.list',
+  prefix: '_gck_marshal',
+)
+
+gck_sources = [
+  gck_sources_public,
+  gck_sources_private,
+  gck_enums_gen,
+  gck_marshal_gen,
+]
+
+gck_exported_headers = [
+  gck_headers,
+  gck_version_h,
+  'gck-deprecated.h',
+  'pkcs11.h',
+  'pkcs11n.h',
+  'pkcs11x.h',
+]
+
+install_headers(gck_exported_headers,
+  subdir: gck_headers_install_dir,
+)
+
+gck_deps = [
+  glib_deps,
+  p11kit_dep,
+  libegg_dep,
+]
+
+gck_cflags = [
+  '-DG_LOG_DOMAIN="@0@"'.format('Gck'),
+  '-DGCK_API_SUBJECT_TO_CHANGE',
+  '-DP11_KIT_API_SUBJECT_TO_CHANGE',
+  '-DPKCS11_REGISTRY_DIR="@0@"'.format(get_option('prefix') / get_option('libdir') / 'pkcs11'),
+]
+
+gck_linkflags = [
+  '-Wl,--version-script,@0@/libgck.map'.format(meson.current_source_dir())
+]
+
+gck_lib = library('gck-@0@'.format(gck_major_version),
+  gck_sources,
+  dependencies: gck_deps,
+  c_args: gck_cflags,
+  link_args: gck_linkflags,
+  include_directories: config_h_dir,
+  version: gck_soversion,
+  install: true,
+)
+
+gck_dep = declare_dependency(
+  link_with: gck_lib,
+  include_directories: include_directories('..'),
+  sources: gck_enums_gen[1], # Make sure gck-enum-types.h can be included
+)
+
+# We create an extra version of GCK which exposes internal functions
+# (for testing purposes)
+gck_testable_lib = library('gck-testable',
+  gck_sources,
+  dependencies: gck_deps,
+  c_args: gck_cflags,
+  include_directories: config_h_dir,
+)
+
+gck_testable_dep = declare_dependency(
+  link_with: gck_testable_lib,
+  include_directories: include_directories('..'),
+  sources: gck_enums_gen[1], # Make sure gck-enum-types.h can be included
+)
+
+# GObject introspection (GIR) file
+gck_gir_sources = [
+  gck_sources_public,
+  gck_headers,
+  gck_enums_gen[1],
+]
+
+if get_option('introspection')
+  gck_gir = gnome.generate_gir(gck_lib,
+    sources: gck_gir_sources,
+    namespace: 'Gck',
+    nsversion: gck_major_version,
+    packages: gck_deps,
+    export_packages: 'gck-@0@'.format(gck_major_version),
+    includes: [ 'GObject-2.0', 'Gio-2.0' ],
+    extra_args: [
+      '-DGCK_COMPILATION',
+      '-DGCK_API_SUBJECT_TO_CHANGE',
+      '--c-include=gck/gck.h'.format(meson.current_source_dir()),
+    ],
+    install: true,
+  )
+
+  gck_vapi = gnome.generate_vapi('gck-@0@'.format(gck_major_version),
+    sources: gck_gir[0],
+    packages: [ 'glib-2.0', 'gio-2.0' ],
+    install: true,
+  )
+
+  install_data('pkcs11.vapi',
+    install_dir: get_option('datadir') / 'vala' / 'vapi',
+  )
+endif
+
+# pkg-config file
+pkgconfig.generate(gck_lib,
+  description: 'GObject bindings for PKCS#11',
+  subdirs: 'gck-@0@'.format(gck_major_version),
+)
+
+# tests
+gck_test_lib = library('gck-test',
+  sources: [ 'gck-mock.c', 'gck-test.c' ],
+  dependencies: [ gck_deps, gck_testable_dep ],
+  c_args: gck_cflags,
+  include_directories: config_h_dir,
+)
+
+gck_mock_test_lib = shared_library('mock-test-module',
+  sources: 'mock-test-module.c',
+  link_with: gck_test_lib,
+  dependencies: [ gck_deps, gck_dep ],
+  c_args: gck_cflags,
+  include_directories: config_h_dir,
+)
+
+gck_test_names = [
+  'attributes',
+  'module',
+  'slot',
+  'session',
+  'object',
+  'crypto',
+  'uri',
+  'enumerator',
+  'modules',
+]
+
+gck_test_cflags = [
+  '-D_GCK_TEST_MODULE_PATH="@0@"'.format(gck_mock_test_lib.full_path()),
+]
+
+foreach _test : gck_test_names
+  _test_name = 'test-gck-'+_test
+
+  gck_test_bin = executable(_test_name,
+    '@0@.c'.format(_test_name),
+    link_with: [ gck_test_lib, egg_test_lib ],
+    dependencies: [ gck_deps, gck_testable_dep ],
+    c_args: gck_cflags + gck_test_cflags,
+    include_directories: config_h_dir,
+  )
+
+  test(_test, gck_test_bin,
+    suite: 'gck',
+    depends: gck_mock_test_lib,
+  )
+endforeach
diff --git a/gck/test-gck-crypto.c b/gck/test-gck-crypto.c
index 0cb3e2b..8092272 100644
--- a/gck/test-gck-crypto.c
+++ b/gck/test-gck-crypto.c
@@ -56,7 +56,11 @@ setup (Test *test, gconstpointer unused)
        GckSlot *slot;
 
        /* Successful load */
+#ifdef _GCK_TEST_MODULE_PATH
+       test->module = gck_module_initialize (_GCK_TEST_MODULE_PATH, NULL, &err);
+#else
        test->module = gck_module_initialize (BUILDDIR "/.libs/libmock-test-module.so", NULL, &err);
+#endif
        g_assert_no_error (err);
        g_assert (GCK_IS_MODULE (test->module));
        g_object_add_weak_pointer (G_OBJECT (test->module), (gpointer *)&test->module);
diff --git a/gck/test-gck-enumerator.c b/gck/test-gck-enumerator.c
index 13ea19f..f3b2ec8 100644
--- a/gck/test-gck-enumerator.c
+++ b/gck/test-gck-enumerator.c
@@ -48,7 +48,11 @@ setup (Test *test, gconstpointer unused)
        GError *err = NULL;
 
        /* Successful load */
+#ifdef _GCK_TEST_MODULE_PATH
+       test->module = gck_module_initialize (_GCK_TEST_MODULE_PATH, NULL, &err);
+#else
        test->module = gck_module_initialize (BUILDDIR "/.libs/libmock-test-module.so", NULL, &err);
+#endif
        g_assert_no_error (err);
        g_assert (GCK_IS_MODULE (test->module));
        g_object_add_weak_pointer (G_OBJECT (test->module), (gpointer *)&test->module);
diff --git a/gck/test-gck-module.c b/gck/test-gck-module.c
index 1b33355..6544d59 100644
--- a/gck/test-gck-module.c
+++ b/gck/test-gck-module.c
@@ -41,7 +41,11 @@ setup (Test *test, gconstpointer unused)
        GError *err = NULL;
 
        /* Successful load */
+#ifdef _GCK_TEST_MODULE_PATH
+       test->module = gck_module_initialize (_GCK_TEST_MODULE_PATH, NULL, &err);
+#else
        test->module = gck_module_initialize (BUILDDIR "/.libs/libmock-test-module.so", NULL, &err);
+#endif
        g_assert_no_error (err);
        g_assert (test->module);
        g_object_add_weak_pointer (G_OBJECT (test->module), (gpointer *)&test->module);
@@ -70,8 +74,13 @@ test_initialize_async (void)
        GError *error = NULL;
 
        /* Shouldn't be able to load modules */
+#ifdef _GCK_TEST_MODULE_PATH
+       gck_module_initialize_async (_GCK_TEST_MODULE_PATH,
+                                    NULL, fetch_async_result, &result);
+#else
        gck_module_initialize_async (BUILDDIR "/.libs/libmock-test-module.so",
                                     NULL, fetch_async_result, &result);
+#endif
 
        egg_test_wait_until (500);
        g_assert (result != NULL);
@@ -138,7 +147,11 @@ test_module_props (Test *test, gconstpointer unused)
 
        g_object_get (test->module, "path", &path, NULL);
        g_assert (path != NULL && "no module-path");
+#ifdef _GCK_TEST_MODULE_PATH
+       g_assert (strcmp (_GCK_TEST_MODULE_PATH, path) == 0 && "module path wrong");
+#else
        g_assert (strcmp (BUILDDIR "/.libs/libmock-test-module.so", path) == 0 && "module path wrong");
+#endif
        g_free (path);
 }
 
diff --git a/gck/test-gck-modules.c b/gck/test-gck-modules.c
index 015c571..6527db1 100644
--- a/gck/test-gck-modules.c
+++ b/gck/test-gck-modules.c
@@ -47,7 +47,11 @@ setup (Test *test, gconstpointer unused)
        GError *err = NULL;
 
        /* Successful load */
+#ifdef _GCK_TEST_MODULE_PATH
+       module = gck_module_initialize (_GCK_TEST_MODULE_PATH, NULL, &err);
+#else
        module = gck_module_initialize (BUILDDIR "/.libs/libmock-test-module.so", NULL, &err);
+#endif
        g_assert_no_error (err);
        g_assert (GCK_IS_MODULE (module));
 
diff --git a/gck/test-gck-object.c b/gck/test-gck-object.c
index 3f782eb..08464b1 100644
--- a/gck/test-gck-object.c
+++ b/gck/test-gck-object.c
@@ -49,7 +49,11 @@ setup (Test *test, gconstpointer unused)
        GList *slots;
 
        /* Successful load */
+#ifdef _GCK_TEST_MODULE_PATH
+       test->module = gck_module_initialize (_GCK_TEST_MODULE_PATH, NULL, &err);
+#else
        test->module = gck_module_initialize (BUILDDIR "/.libs/libmock-test-module.so", NULL, &err);
+#endif
        g_assert_no_error (err);
        g_assert (GCK_IS_MODULE (test->module));
 
diff --git a/gck/test-gck-session.c b/gck/test-gck-session.c
index 6cd4c97..9b2778b 100644
--- a/gck/test-gck-session.c
+++ b/gck/test-gck-session.c
@@ -48,7 +48,11 @@ setup (Test *test, gconstpointer unused)
        GList *slots;
 
        /* Successful load */
+#ifdef _GCK_TEST_MODULE_PATH
+       test->module = gck_module_initialize (_GCK_TEST_MODULE_PATH, NULL, &err);
+#else
        test->module = gck_module_initialize (BUILDDIR "/.libs/libmock-test-module.so", NULL, &err);
+#endif
        g_assert_no_error (err);
        g_assert (GCK_IS_MODULE (test->module));
        g_object_add_weak_pointer (G_OBJECT (test->module), (gpointer *)&test->module);
diff --git a/gck/test-gck-slot.c b/gck/test-gck-slot.c
index b8bcecf..8466159 100644
--- a/gck/test-gck-slot.c
+++ b/gck/test-gck-slot.c
@@ -42,7 +42,11 @@ setup (Test *test, gconstpointer unused)
        GList *slots;
 
        /* Successful load */
+#ifdef _GCK_TEST_MODULE_PATH
+       test->module = gck_module_initialize (_GCK_TEST_MODULE_PATH, NULL, &err);
+#else
        test->module = gck_module_initialize (BUILDDIR "/.libs/libmock-test-module.so", NULL, &err);
+#endif
        g_assert_no_error (err);
        g_assert (GCK_IS_MODULE (test->module));
 
diff --git a/gcr/libgcr-base.map b/gcr/libgcr-base.map
new file mode 100644
index 0000000..4a16138
--- /dev/null
+++ b/gcr/libgcr-base.map
@@ -0,0 +1,8 @@
+{
+global:
+  gcr_*;
+  _gcr_*;
+  SECMEM_*;
+local:
+  *;
+};
diff --git a/gcr/meson.build b/gcr/meson.build
new file mode 100644
index 0000000..629d125
--- /dev/null
+++ b/gcr/meson.build
@@ -0,0 +1,283 @@
+gcr_headers_install_dir = 'gcr-@0@'.format(gcr_major_version) / 'gcr'
+
+gcr_public_sources = [
+  'gcr-certificate.c',
+  'gcr-certificate-chain.c',
+  'gcr-certificate-request.c',
+  'gcr-collection.c',
+  'gcr-comparable.c',
+  'gcr-filter-collection.c',
+  'gcr-fingerprint.c',
+  'gcr-icons.c',
+  'gcr-importer.c',
+  'gcr-import-interaction.c',
+  'gcr-library.c',
+  'gcr-mock-prompter.c',
+  'gcr-parser.c',
+  'gcr-pkcs11-certificate.c',
+  'gcr-prompt.c',
+  'gcr-secret-exchange.c',
+  'gcr-secure-memory.c',
+  'gcr-simple-certificate.c',
+  'gcr-simple-collection.c',
+  'gcr-ssh-askpass.c',
+  'gcr-system-prompt.c',
+  'gcr-system-prompter.c',
+  'gcr-trust.c',
+  'gcr-union-collection.c',
+]
+
+gcr_private_sources = [
+  'gcr-callback-output-stream.c',
+  'gcr-certificate-extensions.c',
+  'gcr-column.c',
+  'gcr-gnupg-collection.c',
+  'gcr-gnupg-importer.c',
+  'gcr-gnupg-key.c',
+  'gcr-gnupg-process.c',
+  'gcr-gnupg-records.c',
+  'gcr-gnupg-util.c',
+  'gcr-key-mechanisms.c',
+  'gcr-memory-icon.c',
+  'gcr-openpgp.c',
+  'gcr-openssh.c',
+  'gcr-pkcs11-importer.c',
+  'gcr-record.c',
+  'gcr-single-collection.c',
+  'gcr-subject-public-key.c',
+  'gcr-util.c',
+]
+
+gcr_headers = [
+  'gcr-base.h',
+  'gcr-certificate.h',
+  'gcr-certificate-chain.h',
+  'gcr-certificate-request.h',
+  'gcr-collection.h',
+  'gcr-column.h',
+  'gcr-comparable.h',
+  'gcr-deprecated-base.h',
+  'gcr-fingerprint.h',
+  'gcr-filter-collection.h',
+  'gcr-icons.h',
+  'gcr-importer.h',
+  'gcr-import-interaction.h',
+  'gcr-library.h',
+  'gcr-mock-prompter.h',
+  'gcr-parser.h',
+  'gcr-pkcs11-certificate.h',
+  'gcr-prompt.h',
+  'gcr-secret-exchange.h',
+  'gcr-secure-memory.h',
+  'gcr-simple-certificate.h',
+  'gcr-simple-collection.h',
+  'gcr-ssh-askpass.h',
+  'gcr-system-prompt.h',
+  'gcr-system-prompter.h',
+  'gcr-trust.h',
+  'gcr-types.h',
+  'gcr-union-collection.h',
+  'gcr-unlock-options.h',
+]
+
+# Generated sources
+gcr_version_conf = configuration_data()
+gcr_version_conf.set('GCR_MAJOR', gcr_major_version)
+gcr_version_conf.set('GCR_MINOR', gcr_minor_version)
+gcr_version_conf.set('GCR_MICRO', gcr_micro_version)
+gcr_version_h = configure_file(input: 'gcr-version.h.in',
+  output: 'gcr-version.h',
+  configuration: gcr_version_conf,
+)
+
+gcr_enums_gen = gnome.mkenums_simple('gcr-enum-types-base',
+  sources: gcr_headers + [ gcr_version_h ],
+  install_header: true,
+  install_dir: get_option('includedir') / gcr_headers_install_dir,
+)
+
+gcr_marshal_gen = gnome.genmarshal('gcr-marshal',
+  sources: 'gcr-marshal.list',
+  prefix: '_gcr_marshal',
+)
+
+gcr_dbus_gen = gnome.gdbus_codegen('gcr-dbus-generated',
+  sources: 'org.gnome.keyring.Prompter.xml',
+  interface_prefix: 'org.gnome.keyring.internal.',
+  namespace: '_GcrDbus',
+)
+
+gcr_oids = custom_target('gcr-oids',
+  output: [
+    'gcr-oids.c',
+    'gcr-oids.h',
+  ],
+  input: 'gcr-oids.list',
+  command: [ find_program('gcr-mkoids'),
+    '-p', 'GCR',
+    '-c', '@OUTPUT0@',
+    '-h', '@OUTPUT1@',
+    '@INPUT@',
+  ]
+)
+
+gcr_sources = [
+  gcr_private_sources,
+  gcr_public_sources,
+  gcr_enums_gen,
+  gcr_marshal_gen,
+  gcr_dbus_gen,
+  gcr_oids,
+]
+
+gcr_deps = [
+  glib_deps,
+  p11kit_dep,
+  libegg_dep,
+  gck_dep,
+]
+
+gcr_cflags = [
+ '-DG_LOG_DOMAIN="Gcr"',
+ '-DGCR_COMPILATION',
+ '-DGCR_API_SUBJECT_TO_CHANGE',
+ '-DGCK_API_SUBJECT_TO_CHANGE',
+ '-DP11_KIT_API_SUBJECT_TO_CHANGE',
+]
+
+gcr_base_linkflags = [
+  '-Wl,--version-script,@0@/libgcr-base.map'.format(meson.current_source_dir())
+]
+
+gcr_base_lib = library('gcr-base-@0@'.format(gcr_major_version),
+  gcr_sources,
+  dependencies: gcr_deps,
+  c_args: gcr_cflags,
+  link_args: gcr_base_linkflags,
+  include_directories: config_h_dir,
+  version: gcr_soversion,
+  install: true,
+)
+
+install_headers(
+  [ gcr_headers, gcr_version_h ],
+  subdir: gcr_headers_install_dir,
+)
+
+if get_option('gtk')
+  install_headers('gcr.h',
+    subdir: gcr_headers_install_dir,
+  )
+endif
+
+gcr_base_dep = declare_dependency(
+  link_with: gcr_base_lib,
+  include_directories: include_directories('..'),
+  sources: gcr_enums_gen[1], # Make sure gcr-enum-types-base.h can be included
+)
+
+if get_option('introspection')
+  gcr_gir = gnome.generate_gir(gcr_base_lib,
+    sources: [ gcr_public_sources, gcr_headers ],
+    namespace: 'Gcr',
+    nsversion: gcr_major_version,
+    packages: gcr_deps,
+    export_packages: 'gcr-base-@0@'.format(gcr_major_version),
+    includes: [
+      'GObject-2.0',
+      'Gio-2.0',
+      'Gck-@0@'.format(gck_major_version),
+    ],
+    extra_args: [
+      '-DGCR_COMPILATION',
+      '-DGCR_API_SUBJECT_TO_CHANGE',
+      '--c-include=gcr/gcr-base.h'.format(meson.current_source_dir()),
+    ],
+    install: true,
+  )
+
+  gcr_vapi = gnome.generate_vapi('gcr-@0@'.format(gcr_major_version),
+    sources: gcr_gir[0],
+    packages: [ 'glib-2.0', 'gio-2.0' ],
+    install: true,
+  )
+endif
+
+# pkg-config file
+pkgconfig.generate(gcr_base_lib,
+  description: 'GObject and GUI library for high level crypto parsing and display',
+)
+
+# gcr-ssh-askpass binary
+gcr_ssh_askpass = executable('gcr-ssh-askpass',
+  'gcr-ssh-askpass.c',
+  dependencies: [ glib_deps, libegg_dep ],
+  c_args: [
+    '-DGCR_SSH_ASKPASS_TOOL',
+    '-DGCR_COMPILATION',
+  ],
+  include_directories: config_h_dir,
+  install: true,
+  install_dir: get_option('libexecdir'),
+)
+
+# Services
+gcr_service_files = [
+  'org.gnome.keyring.SystemPrompter.service',
+  'org.gnome.keyring.PrivatePrompter.service',
+]
+
+foreach service_file : gcr_service_files
+  configure_file(
+    output: service_file,
+    input: service_file + '.in',
+    configuration: {
+      'libexecdir': gcr_prefix / get_option('libexecdir'),
+    },
+    install_dir: get_option('datadir') / 'dbus-1' / 'services',
+  )
+endforeach
+
+# Tests
+gcr_test_names = [
+  'util',
+  'filter-collection',
+  'secret-exchange',
+  'simple-certificate',
+  'certificate',
+  'certificate-chain',
+  'subject-public-key',
+  'fingerprint',
+  'pkcs11-certificate',
+  'openpgp',
+  'openssh',
+  'secure-memory',
+  'trust',
+  'parser',
+  'record',
+  'memory-icon',
+  'gnupg-key',
+  'gnupg-collection',
+  'gnupg-process',
+  'system-prompt',
+  'ssh-askpass',
+]
+
+gcr_test_cflags = [
+  '-D_GCR_TEST_SSH_ASKPASS_PATH="@0@"'.format(gcr_ssh_askpass.full_path()),
+]
+
+foreach _test : gcr_test_names
+  test_bin = executable('test-'+_test,
+    'test-@0@.c'.format(_test),
+    dependencies: [ gcr_deps, gcr_base_dep ],
+    link_with: [ gck_test_lib, egg_test_lib ],
+    c_args: [ gcr_cflags, gcr_test_cflags ],
+    include_directories: config_h_dir,
+  )
+
+  test(_test, test_bin,
+    suite: 'gcr',
+    depends: gcr_ssh_askpass,
+  )
+endforeach
diff --git a/gcr/test-ssh-askpass.c b/gcr/test-ssh-askpass.c
index a6a4965..786ae25 100644
--- a/gcr/test-ssh-askpass.c
+++ b/gcr/test-ssh-askpass.c
@@ -163,7 +163,11 @@ main (int argc, char **argv)
        g_test_init (&argc, &argv, NULL);
        g_set_prgname ("test-ssh-askpass");
 
+#ifdef _GCR_TEST_SSH_ASKPASS_PATH
+       gcr_ssh_askpass_executable = _GCR_TEST_SSH_ASKPASS_PATH;
+#else
        gcr_ssh_askpass_executable = BUILDDIR "/gcr-ssh-askpass";
+#endif
 
        g_test_add ("/gcr/ssh-askpass/ssh-keygen", Test, "booo", setup, test_ssh_keygen, teardown);
        g_test_add ("/gcr/ssh-askpass/cancelled", Test, NULL, setup, test_cancelled, teardown);
diff --git a/meson.build b/meson.build
new file mode 100644
index 0000000..5d1faeb
--- /dev/null
+++ b/meson.build
@@ -0,0 +1,96 @@
+project('gcr', 'c',
+  version: '3.34.0',
+  meson_version: '>= 0.49',
+  license: 'GPL2+',
+)
+
+gnome = import('gnome')
+i18n = import('i18n')
+pkgconfig = import('pkgconfig')
+
+# Versioning
+gcr_version = meson.project_version()
+gcr_soversion = '1.0.0'
+gcr_major_version = gcr_version.split('.')[0]
+gcr_minor_version = gcr_version.split('.')[1]
+gcr_micro_version = gcr_version.split('.')[2]
+
+gck_version = '1.0.0'
+gck_soversion = '0.0.0'
+gck_major_version = gck_version.split('.')[0]
+gck_minor_version = gck_version.split('.')[1]
+gck_micro_version = gck_version.split('.')[2]
+
+# Some variables
+cc = meson.get_compiler('c')
+buildtype = get_option('buildtype')
+
+gcr_prefix = get_option('prefix')
+libexecbindir = gcr_prefix / get_option('libexecdir') / meson.project_name()
+podir = meson.current_source_dir() / 'po'
+
+# Dependencies
+min_glib_version = '2.38'
+glib_deps = [
+  dependency('glib-2.0', version: '>=' + min_glib_version),
+  dependency('gmodule-no-export-2.0', version: '>=' + min_glib_version),
+  dependency('gthread-2.0', version: '>=' + min_glib_version),
+  dependency('gobject-2.0', version: '>=' + min_glib_version),
+  dependency('gio-2.0', version: '>=' + min_glib_version),
+  dependency('gio-unix-2.0',version: '>=' + min_glib_version),
+]
+gpg_bin = find_program('gpg2', 'gpg')
+libgcrypt_dep = dependency('libgcrypt', version: '>= 1')
+p11kit_dep = dependency('p11-kit-1', version: '>+ 0.19.0')
+p11_system_config_modules = p11kit_dep.get_pkgconfig_variable('p11_system_config_modules')
+if p11_system_config_modules == 'Could not find location for pkcs11 module config'
+  error('Could not find location for pkcs11 module config')
+endif
+
+if get_option('gtk')
+  gtk_min_version = '3.12'
+  gtk_dep = dependency('gtk+-3.0', version: '>=' + gtk_min_version)
+  gtk_x11_dep = dependency('gtk+-x11-3.0', version: '>=' + gtk_min_version)
+endif
+
+# configuration
+conf = configuration_data()
+conf.set_quoted('VERSION', meson.project_version())
+conf.set_quoted('PACKAGE', meson.project_name())
+conf.set_quoted('PACKAGE_NAME', meson.project_name())
+conf.set_quoted('PACKAGE_VERSION', meson.project_version())
+conf.set_quoted('PACKAGE_STRING', '@0@ @1@'.format(meson.project_name(), meson.project_version()))
+conf.set_quoted('SRCDIR', meson.source_root())
+conf.set_quoted('BUILDDIR', meson.build_root())
+conf.set_quoted('LIBEXECDIR', libexecbindir)
+conf.set_quoted('LOCALEDIR', gcr_prefix / get_option('localedir'))
+conf.set_quoted('GETTEXT_PACKAGE', meson.project_name())
+conf.set('WITH_DEBUG', buildtype.contains('debug'))
+conf.set10('_DEBUG', buildtype.contains('debug'))
+conf.set10('HAVE_CONFIG_H', true)
+conf.set('HAVE_GETTEXT', true)
+conf.set('HAVE_TIMEGM', cc.has_function('timegm'))
+conf.set('HAVE_MLOCK', cc.has_function('mlock'))
+conf.set_quoted('GPG_EXECUTABLE', gpg_bin.path())
+conf.set_quoted('LIBGCRYPT_VERSION', libgcrypt_dep.version())
+config_file = configure_file(
+  output: 'config.h',
+  configuration: conf,
+)
+config_h_dir = include_directories('.')
+
+# Post-install scripts
+meson.add_install_script('meson_post_install.py')
+
+# subdirs
+subdir('po')
+subdir('egg')
+subdir('gck')
+subdir('gcr')
+subdir('schema')
+if get_option('gtk')
+  subdir('ui')
+endif
+if get_option('docs')
+  subdir('docs')
+endif
diff --git a/meson_options.txt b/meson_options.txt
new file mode 100644
index 0000000..1032cf8
--- /dev/null
+++ b/meson_options.txt
@@ -0,0 +1,20 @@
+option('update-mime-database',
+  type: 'boolean',
+  value: true,
+  description: 'Whether to run update-mime-database (disabling can be useful for packagers)',
+)
+option('introspection',
+  type: 'boolean',
+  value: true,
+  description: 'Build GObject Introspection (GIR) files',
+)
+option('gtk',
+  type: 'boolean',
+  value: true,
+  description: 'Build code that uses GTK+',
+)
+option('docs',
+  type: 'boolean',
+  value: true,
+  description: 'Build the reference documentation (requires gtk-doc)',
+)
diff --git a/meson_post_install.py b/meson_post_install.py
new file mode 100755
index 0000000..bf320a9
--- /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 0000000..f904cde
--- /dev/null
+++ b/po/meson.build
@@ -0,0 +1,3 @@
+i18n.gettext(meson.project_name(),
+  preset: 'glib'
+)
diff --git a/schema/meson.build b/schema/meson.build
new file mode 100644
index 0000000..81572a3
--- /dev/null
+++ b/schema/meson.build
@@ -0,0 +1,13 @@
+compiled_schemas = gnome.compile_schemas()
+install_data('org.gnome.crypto.pgp.gschema.xml',
+  install_dir: gcr_prefix / get_option('datadir') / 'glib-2.0' / 'schemas',
+)
+
+# GConf files (legacy)
+gconf_convert_files = [
+  'org.gnome.crypto.pgp.convert',
+  'org.gnome.crypto.pgp_keyservers.convert',
+]
+install_data(gconf_convert_files,
+  install_dir: get_option('datadir') / 'GConf' / 'gsettings',
+)
diff --git a/ui/icons/meson.build b/ui/icons/meson.build
new file mode 100644
index 0000000..fe7953b
--- /dev/null
+++ b/ui/icons/meson.build
@@ -0,0 +1,33 @@
+large_icons = [
+  'gcr-gnupg',
+  'gcr-password',
+  'gcr-smart-card',
+]
+
+small_icons = [
+  'gcr-gnupg',
+  'gcr-key',
+  'gcr-key-pair',
+  'gcr-password',
+  'gcr-smart-card',
+]
+
+foreach size : [ 16, 22, 24, 32, 48 ]
+  size_str = '@0@x@0@'.format(size)
+
+  foreach icon : small_icons
+    install_data(size_str / icon + '.png',
+      install_dir: get_option('datadir') / 'icons' / 'hicolor' / size_str / 'apps',
+    )
+  endforeach
+endforeach
+
+foreach size : [ 256 ]
+  size_str = '@0@x@0@'.format(size)
+
+  foreach icon : large_icons
+    install_data(size_str / icon + '.png',
+      install_dir: get_option('datadir') / 'icons' / 'hicolor' / size_str / 'apps',
+    )
+  endforeach
+endforeach
diff --git a/ui/libgcr-ui.map b/ui/libgcr-ui.map
new file mode 100644
index 0000000..4a16138
--- /dev/null
+++ b/ui/libgcr-ui.map
@@ -0,0 +1,8 @@
+{
+global:
+  gcr_*;
+  _gcr_*;
+  SECMEM_*;
+local:
+  *;
+};
diff --git a/ui/meson.build b/ui/meson.build
new file mode 100644
index 0000000..d4490a9
--- /dev/null
+++ b/ui/meson.build
@@ -0,0 +1,265 @@
+subdir('icons')
+
+gcr_ui_headers_install_dir = 'gcr-@0@'.format(gcr_major_version) / 'ui'
+
+gcr_ui_public_sources = [
+  'gcr-certificate-renderer.c',
+  'gcr-certificate-widget.c',
+  'gcr-collection-model.c',
+  'gcr-combo-selector.c',
+  'gcr-failure-renderer.c',
+  'gcr-key-renderer.c',
+  'gcr-key-widget.c',
+  'gcr-import-button.c',
+  'gcr-list-selector.c',
+  'gcr-prompt-dialog.c',
+  'gcr-renderer.c',
+  'gcr-secure-entry-buffer.c',
+  'gcr-tree-selector.c',
+  'gcr-unlock-options-widget.c',
+  'gcr-viewer.c',
+  'gcr-viewer-widget.c',
+]
+
+gcr_ui_private_sources = [
+  'eggimagemenuitem.c',
+  'gcr-certificate-basics-widget.c',
+  'gcr-certificate-details-widget.c',
+  'gcr-certificate-exporter.c',
+  'gcr-certificate-request-renderer.c',
+  'gcr-dialog-util.c',
+  'gcr-display-scrolled.c',
+  'gcr-display-view.c',
+  'gcr-gnupg-renderer.c',
+  'gcr-live-search.c',
+  'gcr-pkcs11-import-dialog.c',
+  'gcr-pkcs11-import-interaction.c',
+  'gcr-unlock-renderer.c',
+  'gcr-viewer-window.c',
+]
+
+gcr_ui_headers = [
+  'gcr-ui.h',
+  'gcr-certificate-renderer.h',
+  'gcr-certificate-widget.h',
+  'gcr-collection-model.h',
+  'gcr-combo-selector.h',
+  'gcr-deprecated.h',
+  'gcr-failure-renderer.h',
+  'gcr-key-renderer.h',
+  'gcr-key-widget.h',
+  'gcr-import-button.h',
+  'gcr-list-selector.h',
+  'gcr-prompt-dialog.h',
+  'gcr-renderer.h',
+  'gcr-secure-entry-buffer.h',
+  'gcr-tree-selector.h',
+  'gcr-unlock-options-widget.h',
+  'gcr-viewer.h',
+  'gcr-viewer-widget.h',
+]
+
+# Generated sources
+gcr_ui_enums_gen = gnome.mkenums_simple('gcr-enum-types',
+  sources: gcr_ui_headers,
+  install_header: true,
+  install_dir: get_option('includedir') / gcr_ui_headers_install_dir,
+)
+
+gcr_ui_sources = [
+  gcr_ui_private_sources,
+  gcr_ui_public_sources,
+  gcr_ui_enums_gen,
+]
+
+gcr_ui_deps = [
+  glib_deps,
+  p11kit_dep,
+  libegg_dep,
+  gck_dep,
+  gcr_base_dep,
+  gtk_dep,
+  gtk_x11_dep,
+]
+
+gcr_ui_cflags = [
+ '-DG_LOG_DOMAIN="Gcr"',
+ '-DGCR_COMPILATION',
+ '-DGCR_API_SUBJECT_TO_CHANGE',
+ '-DGCK_API_SUBJECT_TO_CHANGE',
+ '-DP11_KIT_API_SUBJECT_TO_CHANGE',
+]
+
+gcr_ui_linkflags = [
+  '-Wl,--version-script,@0@/libgcr-ui.map'.format(meson.current_source_dir())
+]
+
+# gcr-XX is just the same as gcr-ui-XX
+gcr_ui_basename = 'gcr-ui-@0@'.format(gcr_major_version)
+gcr_basename = 'gcr-@0@'.format(gcr_major_version)
+
+gcr_ui_lib = library(gcr_ui_basename,
+  gcr_ui_sources,
+  dependencies: gcr_ui_deps,
+  c_args: gcr_ui_cflags,
+  link_args: gcr_ui_linkflags,
+  include_directories: config_h_dir,
+  version: gcr_soversion,
+  install: true,
+)
+
+pkgconfig.generate(gcr_ui_lib,
+  description: 'GObject and GUI library for high level crypto parsing and display',
+)
+pkgconfig.generate(gcr_ui_lib,
+  filebase: gcr_basename,
+  name: gcr_basename,
+  description: 'GObject and GUI library for high level crypto parsing and display',
+)
+
+
+# Create a libgcr-X.so file that links to libgcr-ui-X.so file
+meson.add_install_script('sh', '-c',
+  'ln -s -f @0@.so @1@.so'.format(
+    get_option('prefix') / get_option('libdir') / ('lib' + gcr_ui_basename),
+    get_option('prefix') / get_option('libdir') / ('lib' + gcr_basename))
+)
+
+install_headers(gcr_ui_headers,
+  subdir: gcr_ui_headers_install_dir,
+)
+
+gcr_ui_dep = declare_dependency(
+  link_with: gcr_ui_lib,
+  include_directories: include_directories('..'),
+  sources: gcr_ui_enums_gen[1], # Make sure gcr-enum-types.h can be included
+)
+
+if get_option('introspection')
+  gcr_ui_gir = gnome.generate_gir(gcr_ui_lib,
+    sources: gcr_ui_headers,
+    namespace: 'GcrUi',
+    nsversion: gcr_major_version,
+    export_packages: 'gcr-ui-@0@'.format(gcr_major_version),
+    identifier_prefix: 'Gcr',
+    symbol_prefix: 'gcr',
+    packages: gcr_ui_deps,
+    includes: [
+      'GObject-2.0',
+      'Gio-2.0',
+      'Gtk-3.0',
+      'Gck-@0@'.format(gck_major_version),
+      'Gcr-@0@'.format(gcr_major_version),
+    ],
+    extra_args: [
+      '-DGCR_COMPILATION',
+      '-DGCR_API_SUBJECT_TO_CHANGE',
+      '--c-include=ui/gcr-ui.h'.format(meson.current_source_dir()),
+    ],
+    install: true,
+  )
+
+  gcr_ui_vapi = gnome.generate_vapi('gcr-ui-@0@'.format(gcr_major_version),
+    sources: gcr_ui_gir[0],
+    packages: [
+      'glib-2.0',
+      'gio-2.0',
+      'gck-@0@'.format(gck_major_version),
+      'gcr-@0@'.format(gcr_major_version),
+      'gtk+-3.0'
+    ],
+    vapi_dirs: [
+      meson.build_root() / 'gck',
+      meson.build_root() / 'gcr',
+    ],
+    install: true,
+  )
+endif
+
+# gcr-viewer
+gcr_viewer = executable('gcr-viewer',
+  'gcr-viewer-tool.c',
+  dependencies: [ gcr_ui_dep, gcr_ui_deps ],
+  c_args: gcr_ui_cflags,
+  include_directories: config_h_dir,
+  install: true,
+)
+
+gcr_viewer_desktop_in = configure_file(
+  input: 'gcr-viewer.desktop.in.in',
+  output: 'gcr-viewer.desktop.in',
+  configuration: {
+    'bindir': gcr_prefix / get_option('bindir'),
+  },
+)
+
+i18n.merge_file(
+  input: gcr_viewer_desktop_in,
+  output: 'gcr-viewer.desktop',
+  type: 'desktop',
+  po_dir: podir,
+  install: true,
+  install_dir: get_option('datadir') / 'applications',
+)
+
+# gcr-prompter
+gcr_prompter = executable('gcr-prompter',
+  'gcr-prompter-tool.c',
+  dependencies: [ gcr_ui_dep, gcr_ui_deps ],
+  c_args: gcr_ui_cflags,
+  include_directories: config_h_dir,
+  install: true,
+  install_dir: get_option('libexecdir'),
+)
+
+gcr_prompter_desktop_in = configure_file(
+  input: 'gcr-prompter.desktop.in.in',
+  output: 'gcr-prompter.desktop.in',
+  configuration: {
+    'libexecdir': gcr_prefix / get_option('libexecdir'),
+  },
+)
+
+i18n.merge_file(
+  input: gcr_prompter_desktop_in,
+  output: 'gcr-prompter.desktop',
+  type: 'desktop',
+  po_dir: podir,
+  install: true,
+  install_dir: get_option('datadir') / 'applications',
+)
+
+# Register new mime types
+install_data('gcr-crypto-types.xml',
+  install_dir: get_option('datadir') / 'mime' / 'packages',
+)
+if get_option('update-mime-database')
+  find_program('update-mime-database')
+  meson.add_install_script('update-mime-database',
+    get_option('prefix') / get_option('datadir') / 'mime',
+  )
+endif
+
+# Manual UI testing programs
+gcr_ui_manual_tests = [
+  'frob-certificate',
+  'frob-combo-selector',
+  'frob-gnupg-selector',
+  'frob-import-button',
+  'frob-key',
+  'frob-tree-selector',
+  'frob-prompt',
+  'frob-request',
+  'frob-system-prompt',
+  'frob-unlock',
+  'frob-unlock-options',
+]
+
+foreach _test : gcr_ui_manual_tests
+  test_bin = executable('test-'+_test,
+    '@0@.c'.format(_test),
+    dependencies: [ gcr_ui_deps, gcr_ui_dep ],
+    c_args: gcr_cflags,
+    include_directories: config_h_dir,
+  )
+endforeach



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