[gcr/wip/nielsdg/meson: 9/9] WIP: Support Meson build system



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

    WIP: Support Meson build system

 .gitlab-ci.yml                   |  22 ++++
 .gitlab-ci/meson-junit-report.py | 109 +++++++++++++++++
 .gitlab-ci/run-tests.sh          |  15 +++
 egg/meson.build                  |  73 ++++++++++++
 gck/meson.build                  | 172 +++++++++++++++++++++++++++
 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/meson.build                  | 251 +++++++++++++++++++++++++++++++++++++++
 gcr/test-ssh-askpass.c           |   4 +
 meson.build                      |  97 +++++++++++++++
 meson_options.txt                |  10 ++
 meson_post_install.py            |  15 +++
 po/meson.build                   |   3 +
 schema/meson.build               |   4 +
 ui/meson.build                   | 124 +++++++++++++++++++
 20 files changed, 936 insertions(+)
---
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 4893870..f35bb02 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -5,6 +5,28 @@ stages:
 variables:
   DEPENDENCIES: dbus-x11 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
+    - 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/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/meson.build b/gck/meson.build
new file mode 100644
index 0000000..4a67216
--- /dev/null
+++ b/gck/meson.build
@@ -0,0 +1,172 @@
+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_exported_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_exported_headers,
+)
+
+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_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(libdir / 'pkcs11'),
+]
+
+gck_lib = library('gck-@0@'.format(gck_major_version),
+  gck_sources,
+  dependencies: gck_deps,
+  c_args: gck_cflags,
+  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
+)
+
+# GObject intospection file
+gck_gir_sources = [
+  gck_sources_public,
+  gck_exported_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,
+  )
+endif
+
+# tests
+gck_test_lib = library('gck-testable',
+  sources: [ 'gck-mock.c', 'gck-test.c' ],
+  dependencies: [ gck_deps, gck_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_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
+
+# pkg-config file
+gck_pc_config = configuration_data()
+gck_pc_config.set('prefix', gcr_prefix)
+gck_pc_config.set('exec_prefix', '${prefix}')
+gck_pc_config.set('libdir', join_paths('${exec_prefix}/lib'))
+gck_pc_config.set('includedir', join_paths('${prefix}/include'))
+gck_pc_config.set('datarootdir', join_paths('${prefix}/share'))
+gck_pc_config.set('datadir', join_paths('${datarootdir}'))
+gck_pc_config.set('sysconfdir', join_paths('${prefix}/etc'))
+gck_pc_config.set('GCK_MAJOR', gck_major_version)
+gck_pc_config.set('VERSION', gcr_version)
+configure_file(input: 'gck.pc.in',
+  output: 'gck.pc',
+  configuration: gck_pc_config,
+)
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/meson.build b/gcr/meson.build
new file mode 100644
index 0000000..cc33603
--- /dev/null
+++ b/gcr/meson.build
@@ -0,0 +1,251 @@
+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 ],
+)
+
+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_lib = library('gcr-@0@'.format(gcr_major_version),
+  gcr_sources,
+  dependencies: gcr_deps,
+  c_args: gcr_cflags,
+  include_directories: config_h_dir,
+  version: gcr_soversion,
+)
+
+gcr_dep = declare_dependency(
+  link_with: gcr_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_lib,
+    sources: gcr_public_sources,
+    namespace: 'Gcr',
+    nsversion: gcr_major_version,
+    packages: gcr_deps,
+    export_packages: 'gcr-@0@'.format(gcr_major_version),
+    includes: [ 'GObject-2.0', 'Gio-2.0' ],
+    extra_args: [
+      '-DGCR_COMPILATION',
+      '-DGCR_API_SUBJECT_TO_CHANGE',
+      '--c-include=gcr/gcr.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
+
+# 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,
+)
+
+# 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_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..ede2ea2
--- /dev/null
+++ b/meson.build
@@ -0,0 +1,97 @@
+project('gcr', 'c',
+  version: '3.28.0',
+  meson_version: '>= 0.49',
+  license: 'GPL2+',
+)
+
+gnome = import('gnome')
+i18n = import('i18n')
+
+# 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]
+
+# Options
+gtk_enabled = get_option('gtk')
+
+# Some variables
+cc = meson.get_compiler('c')
+buildtype = get_option('buildtype')
+
+gcr_prefix = get_option('prefix')
+datadir = gcr_prefix / get_option('datadir')
+bindir = gcr_prefix / get_option('bindir')
+libdir = gcr_prefix / get_option('libdir')
+libexecbindir = gcr_prefix / get_option('libexecdir') / meson.project_name()
+pkgdatadir = datadir / meson.project_name()
+
+# 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 gtk_enabled
+  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('PKGDATADIR', pkgdatadir)
+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.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 gtk_enabled
+  subdir('ui')
+endif
diff --git a/meson_options.txt b/meson_options.txt
new file mode 100644
index 0000000..92f8ac1
--- /dev/null
+++ b/meson_options.txt
@@ -0,0 +1,10 @@
+option('introspection',
+  type: 'boolean',
+  value: true,
+  description: 'Build GObject Introspection (GIR) files',
+)
+option('gtk',
+  type: 'boolean',
+  value: true,
+  description: 'Build code that uses GTK+',
+)
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..4fd22d8
--- /dev/null
+++ b/schema/meson.build
@@ -0,0 +1,4 @@
+compiled_schemas = gnome.compile_schemas()
+install_data('org.gnome.crypto.pgp.gschema.xml',
+  install_dir: gcr_prefix / get_option('datadir') / 'glib-2.0' / 'schemas',
+)
diff --git a/ui/meson.build b/ui/meson.build
new file mode 100644
index 0000000..8623011
--- /dev/null
+++ b/ui/meson.build
@@ -0,0 +1,124 @@
+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-basics-widget.h',
+  'gcr-certificate-details-widget.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,
+)
+
+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_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_lib = library('gcr-ui',
+  gcr_ui_sources,
+  dependencies: gcr_ui_deps,
+  c_args: gcr_ui_cflags,
+  include_directories: config_h_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
+)
+
+# 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]