Commit cae4bd92 authored by Niels De Graef's avatar Niels De Graef

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
parent f4f3adfe
Pipeline #75763 passed with stage
in 9 minutes and 4 seconds
image: fedora:latest
stages:
- build
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
- 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/meson-logs"
- "_build/${CI_JOB_NAME}-report.xml"
#!/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)
#!/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
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,
libebook_dep,
libm_dep,
]
bluez_backend_vala_flags = [
]
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
{
global:
FOLKS_DUMMY_*;
folks_dummy_*;
local:
*;
};
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,
]
# 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,
]
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
pkgconfig.generate(dummy_backendlib,
name: 'Folks dummy support library',
description: 'Dummy support library for the Folks meta-contacts library',
filebase: 'folks-@0@'.format(dummy_backend_name),
requires: [ 'folks', glib_dep, gobject_dep, gee_dep, ],
variables: common_pkgconf_variables,
)
# 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 = [
]
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,
name_prefix: '',
install_dir: folks_backend_dir / dummy_backend_name,
install: true,
)
folks_backends += dummy_backend
{
global:
EDSF_*;
edsf_*;
local:
*;
};
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,
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,
]
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(eds_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
pkgconfig.generate(eds_backendlib,
name: 'Folks e-d-s support library',
description: 'Evolution Data Server support library for the Folks meta-contacts library',
filebase: 'folks-@0@'.format(eds_backend_name),
requires: [ 'folks', glib_dep, gobject_dep, gee_dep, libebook_dep, libedataserver_dep ],
variables: common_pkgconf_variables,
)
# 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 = [
]
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,
name_prefix: '',
install_dir: folks_backend_dir / eds_backend_name,
install: true,
)
folks_backends += eds_backend
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 = [
]
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,
name_prefix: '',
install_dir: folks_backend_dir / keyfile_backend_name,
install: true,
)
folks_backends += keyfile_backend
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,
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,
]
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(libsocialweb_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
pkgconfig.generate(libsocialweb_backendlib,
name: 'Folks libsocialweb support library',
description: 'Libsocialweb support library for the Folks meta-contacts library',
filebase: 'folks-@0@'.format(libsocialweb_backend_name),
requires: [ 'folks', glib_dep, gobject_dep, gee_dep, libsocialweb_dep ],
variables: common_pkgconf_variables,
)
# 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 = [
]
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,
name_prefix: '',
install_dir: folks_backend_dir / dummy_backend_name,
install: true,
)
folks_backends += libsocialweb_backend
# Common dependencies
backend_deps = [
build_conf_dep,
libfolks_dep,
libfolks_internal_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
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 = [
]
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,
name_prefix: '',
install_dir: folks_backend_dir / ofono_backend_name,
install: true,
)
folks_backends += ofono_backend
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,
)