[Spice-devel] [PATCH spice-gtk v3 1/2] Add support for building with meson/ninja

Eduardo Lima (Etrunko) etrunko at redhat.com
Fri Aug 10 18:17:29 UTC 2018


On 10/08/18 12:38, Victor Toso wrote:
> On Mon, Aug 06, 2018 at 03:23:13PM -0300, Eduardo Lima (Etrunko) wrote:
>> In a comparison with current autotools build system, meson/ninja
>> provides a huge improvement in build speed, while keeping the same
>> functionalities currently available and being considered more user
>> friendly.
>>
>> The new system coexists within the same repository with the current one,
>> so we can do more extensive testing of its functionality before deciding
>> if the old system can be removed, or for some reason, has to stay for
>> good.
>>
>> - Meson: https://mesonbuild.com
>>
>>   This is the equivalent of autogen/configure step in autotools. It
>>   generates the files that will be used by ninja to actually build the
>>   source code.
>>
>>   The project has received lots of traction recently, with many GNOME
>>   projects willing to move to this new build system. The following wiki
>>   page has more details of the status of the many projects being ported:
>>
>>     https://wiki.gnome.org/Initiatives/GnomeGoals/MesonPorting
>>
>>   Meson has a python-like syntax, easy to read, and the documentation
>>   on the project is very complete, with a dedicated page on how to port
>>   from autotools, explaining how most common use cases can be
>>   implemented using meson.
>>
>>     http://mesonbuild.com/Porting-from-autotools.html
>>
>>   Other important sources of information:
>>
>>     http://mesonbuild.com/howtox.html
>>     http://mesonbuild.com/Syntax.html
>>     http://mesonbuild.com/Reference-manual.html
>>
>> - Ninja: https://ninja-build.org
>>
>>   Ninja is the equivalent of make in an autotools setup, which actually
>>   builds the source code. It has being used by large and complex
>>   projects such as Google Chrome, Android and LLVM. There is not much to
>>   say about ninja (other than it is much faster than make) because we
>>   won't interact directly with it as much, as meson does the middle man
>>   job here. The reasoning for creating ninja in the first place is
>>   explained on the following post:
>>
>>     http://neugierig.org/software/chromium/notes/2011/02/ninja.html
>>
>>   Also its manual provides more in-depth information about the design
>>   principles:
>>
>>     https://ninja-build.org/manual.html
>>
>> - Basic workflow:
>>
>>   Meson package is available for most if not all distros, so, taking
>>   Fedora as an example, we only need to run:
>>
>>     # dnf -y install meson ninja-build.
>>
>>   With Meson, building in-tree is not possible at all, so we need to
>>   pass a directory as argument to meson where we want the build to be
>>   done. This has the advantage of creating builds with different options
>>   under the same parent directory, e.g.:
>>
>>     $ meson ./build --prefix=/usr
>>     $ meson ./build-extra -Dextra-checks=true -Dalignment-checks=true
>>
>>   After configuration is done, we call ninja to actually do the build.
>>
>>     $ ninja -C ./build
>>     $ ninja -C ./build install
>>
>>   Ninja defaults to parallel builds, and this can be changed with the -j
>>   flag.
>>
>>     $ ninja -j 10 -C ./build
>>
>> - Hacking:
>>
>>   * meson.build: Mandatory for the project root and usually found under
>>                  each directory you want something to be built.
>>
>>   * meson_options.txt: Options that can interfere with the result of the
>>                        build.
>>
>> Signed-off-by: Eduardo Lima (Etrunko) <etrunko at redhat.com>
>> ---
>>  Makefile.am                        |   4 +
>>  build-aux/meson/check-spice-common |   5 +
>>  data/Makefile.am                   |   1 +
>>  data/meson.build                   |   4 +
>>  doc/Makefile.am                    |   2 +
>>  doc/meson.build                    |   1 +
>>  doc/reference/Makefile.am          |   2 +
>>  doc/reference/meson.build          |  51 +++++
>>  man/Makefile.am                    |   1 +
>>  man/meson.build                    |  11 +
>>  meson.build                        | 446 +++++++++++++++++++++++++++++++++++++
>>  meson_options.txt                  | 102 +++++++++
>>  po/meson.build                     |   3 +
>>  src/Makefile.am                    |   1 +
>>  src/meson.build                    | 357 +++++++++++++++++++++++++++++
>>  subprojects/spice-common           |   2 +-
>>  tests/Makefile.am                  |   2 +
>>  tests/meson.build                  |  30 +++
>>  tools/Makefile.am                  |   2 +
>>  tools/meson.build                  |  32 +++
>>  vapi/Makefile.am                   |   1 +
>>  vapi/meson.build                   |  13 ++
>>  22 files changed, 1072 insertions(+), 1 deletion(-)
>>  create mode 100755 build-aux/meson/check-spice-common
>>  create mode 100644 data/meson.build
>>  create mode 100644 doc/meson.build
>>  create mode 100644 doc/reference/meson.build
>>  create mode 100644 man/meson.build
>>  create mode 100644 meson.build
>>  create mode 100644 meson_options.txt
>>  create mode 100644 po/meson.build
>>  create mode 100644 src/meson.build
>>  create mode 100644 tests/meson.build
>>  create mode 100644 tools/meson.build
>>  create mode 100644 vapi/meson.build
>>
>> diff --git a/Makefile.am b/Makefile.am
>> index 875c25c..e9dfbe4 100644
>> --- a/Makefile.am
>> +++ b/Makefile.am
>> @@ -25,7 +25,11 @@ endif
>>  DISTCLEANFILES = $(pkgconfig_DATA)
>>  
>>  EXTRA_DIST =					\
>> +	meson.build				\
>> +	meson_options.txt			\
>> +	po/meson.build				\
>>  	build-aux/git-version-gen		\
>> +	build-aux/meson/check-spice-common	\
>>  	gtk-doc.make				\
>>  	.version				\
>>  	$(NULL)
>> diff --git a/build-aux/meson/check-spice-common b/build-aux/meson/check-spice-common
>> new file mode 100755
>> index 0000000..a0d03a6
>> --- /dev/null
>> +++ b/build-aux/meson/check-spice-common
>> @@ -0,0 +1,5 @@
>> +#!/bin/sh
>> +set -e
>> +if git ls-files --error-unmatch ${MESON_SOURCE_ROOT}/subprojects/spice-common > /dev/null 2>&1; then
>> +    git --git-dir="${MESON_SOURCE_ROOT}/.git" submodule update --init --recursive
>> +fi
>> diff --git a/data/Makefile.am b/data/Makefile.am
>> index 59e90f9..457079e 100644
>> --- a/data/Makefile.am
>> +++ b/data/Makefile.am
>> @@ -1,6 +1,7 @@
>>  NULL=
>>  
>>  EXTRA_DIST =						\
>> +	meson.build					\
>>  	org.spice-space.lowlevelusbaccess.policy	\
>>  	$(NULL)
>>  
>> diff --git a/data/meson.build b/data/meson.build
>> new file mode 100644
>> index 0000000..ba549eb
>> --- /dev/null
>> +++ b/data/meson.build
>> @@ -0,0 +1,4 @@
>> +if spice_gtk_has_polkit
>> +  install_data('org.spice-space.lowlevelusbaccess.policy',
>> +               install_dir : spice_gtk_policy_dir)
>> +endif
>> diff --git a/doc/Makefile.am b/doc/Makefile.am
>> index 034926c..870cd26 100644
>> --- a/doc/Makefile.am
>> +++ b/doc/Makefile.am
>> @@ -1,3 +1,5 @@
>>  SUBDIRS = reference
>>  
>> +EXTRA_DIST = meson.build
>> +
>>  -include $(top_srcdir)/git.mk
>> diff --git a/doc/meson.build b/doc/meson.build
>> new file mode 100644
>> index 0000000..ead14c4
>> --- /dev/null
>> +++ b/doc/meson.build
>> @@ -0,0 +1 @@
>> +subdir('reference')
>> diff --git a/doc/reference/Makefile.am b/doc/reference/Makefile.am
>> index 9fda456..0cc26c9 100644
>> --- a/doc/reference/Makefile.am
>> +++ b/doc/reference/Makefile.am
>> @@ -66,6 +66,8 @@ GTKDOC_LIBS = $(top_builddir)/src/libspice-client-glib-2.0.la $(top_builddir)/sr
>>  
>>  include $(top_srcdir)/gtk-doc.make
>>  
>> +EXTRA_DIST += meson.build
>> +
>>  # Comment this out if you want 'make check' to test you doc status
>>  # and run some sanity checks
>>  if ENABLE_GTK_DOC
>> diff --git a/doc/reference/meson.build b/doc/reference/meson.build
>> new file mode 100644
>> index 0000000..7ac703f
>> --- /dev/null
>> +++ b/doc/reference/meson.build
>> @@ -0,0 +1,51 @@
>> +ignore_headers = [
>> +  'bio-gio.h',
>> +  'channel-display-priv.h',
>> +  'channel-usbredir-priv.h',
>> +  'client_sw_canvas.h',
>> +  'continuation.h',
>> +  'coroutine.h',
>> +  'decode.h',
>> +  'desktop-integration.h',
>> +  'display',
>> +  'gio-coroutine.h',
>> +  'giopipe.h',
>> +  'smartcard-manager-priv.h',
>> +  'spice-audio-priv.h',
>> +  'spice-channel-cache.h',
>> +  'spice-channel-priv.h',
>> +  'spice-cmdline.h',
>> +  'spice-common.h',
>> +  'spice-file-transfer-task-priv.h',
>> +  'spice-grabsequence-priv.h',
>> +  'spice-gstaudio.h',
>> +  'spice-gtk-session-priv.h',
>> +  'spice-marshal.h',
>> +  'spice-pulse.h',
>> +  'spice-session-priv.h',
>> +  'spice-uri-priv.h',
>> +  'spice-util-priv.h',
>> +  'spice-widget-priv.h',
>> +  'spicy-connect.h',
>> +  'usb-acl-helper.h',
>> +  'usb-device-manager-priv.h',
>> +  'usbdk_api.h',
>> +  'usbutil.h',
>> +  'vmcstream.h',
>> +  'vncdisplaykeymap.h',
>> +  'win-usb-dev.h',
>> +]
>> +
>> +spice_gtk_doc_dep = declare_dependency(include_directories: spice_gtk_include,
>> +                                       link_args : spice_gtk_link_args,
>> +                                       link_with : [spice_client_gtk_lib, spice_client_glib_lib])
>> +
>> +gnome.gtkdoc('spice-gtk',
>> +             content_files : ['spice-gtk-overrides.txt', 'spice-gtk-overrides.txt'],
>> +             dependencies : spice_gtk_doc_dep,
>> +             main_xml : 'spice-gtk-docs.xml',
>> +             gobject_typesfile : files('spice-gtk.types'),
>> +             ignore_headers : ignore_headers,
>> +             install : true,
>> +             scan_args : ['--deprecated-guards="SPICE_DISABLE_DEPRECATED"', '--ignore-decorators="G_GNUC_INTERNAL"'],
>> +             src_dir : join_paths(meson.source_root(), 'src'))
>> diff --git a/man/Makefile.am b/man/Makefile.am
>> index a8f7e3f..7d5341b 100644
>> --- a/man/Makefile.am
>> +++ b/man/Makefile.am
>> @@ -5,6 +5,7 @@ dist_man_MANS =					\
>>  	$(NULL)
>>  
>>  EXTRA_DIST =					\
>> +	meson.build				\
>>  	spice-client.pod			\
>>  	$(NULL)
>>  
>> diff --git a/man/meson.build b/man/meson.build
>> new file mode 100644
>> index 0000000..de07ba4
>> --- /dev/null
>> +++ b/man/meson.build
>> @@ -0,0 +1,11 @@
>> +pod2man = find_program('pod2man')
>> +
>> +if pod2man.found()
>> +  custom_target('spice-client.1',
>> +            output : 'spice-client.1',
>> +            input : 'spice-client.pod',
>> +            install : true,
>> +            install_dir : join_paths(spice_gtk_datadir, 'man', 'man1'),
>> +            build_by_default : true,
>> +            command : [pod2man, '-c', 'Spice-GTK Documentation', '@INPUT@', '@OUTPUT@'])
>> +endif
>> diff --git a/meson.build b/meson.build
>> new file mode 100644
>> index 0000000..51f83d8
>> --- /dev/null
>> +++ b/meson.build
>> @@ -0,0 +1,446 @@
>> +#
>> +# project definition
>> +#
>> +project('spice-gtk', 'c',
>> +         version : run_command('build-aux/git-version-gen', '${MESON_SOURCE_ROOT}/.tarball-version').stdout().strip(),
>> +         license : 'LGPLv2.1',
>> +         meson_version : '>= 0.47.0')
>> +
>> +# double check meson.project_version()
>> +# we can not use 'check' keyword in run_command() for git-version-gen above
>> +# https://github.com/mesonbuild/meson/issues/3944
>> +version = run_command('build-aux/git-version-gen', '${MESON_SOURCE_ROOT}/.tarball-version', check : true).stdout().strip()
>> +if meson.project_version() != version
>> +  error('Wrong project version')
>> +endif
>> +
>> +message('Updating submodules')
>> +run_command('build-aux/meson/check-spice-common', check : true)
>> +
>> +#
>> +# global C defines
>> +#
>> +spice_gtk_prefix = get_option('prefix')
>> +spice_gtk_bindir = join_paths(spice_gtk_prefix, get_option('bindir'))
>> +spice_gtk_datadir = join_paths(spice_gtk_prefix, get_option('datadir'))
>> +spice_gtk_localedir = join_paths(spice_gtk_datadir, 'locale')
>> +spice_gtk_includedir = join_paths(spice_gtk_prefix, get_option('includedir'))
>> +spice_gtk_global_cflags = ['-DHAVE_CONFIG_H',
>> +                           '-DSPICE_COMPILATION',
>> +                           '-DG_LOG_DOMAIN="GSpice"',
>> +                           #'-Werror',
>> +                           '-Wall',
>> +                           '-Wextra',
>> +                           '-Wno-sign-compare',
>> +                           '-Wno-unused-parameter']
>> +
>> +# other global vars
>> +compiler = meson.get_compiler('c')
>> +spice_gtk_config_data = configuration_data()
>> +spice_protocol_min_version='0.12.13'
>> +spice_gtk_include = [include_directories('.')]
>> +spice_gtk_libs = []
>> +spice_gtk_deps = []
>> +spice_gtk_link_args = []
>> +spice_gtk_host_system = host_machine.system()
>> +
>> +#
>> +# Spice common subproject
>> +#
>> +spice_common = subproject('spice-common', default_options : ['generate-code=client'])
>> +spice_gtk_config_data.merge_from(spice_common.get_variable('spice_common_config_data'))
>> +spice_gtk_deps += spice_common.get_variable('spice_common_client_dep')
>> +
>> +#
>> +# check for system headers
>> +#
>> +headers = ['termios.h',
>> +           'X11/XKBlib.h']
>> +
>> +foreach header : headers
>> +  if compiler.has_header(header)
>> +    spice_gtk_config_data.set('HAVE_ at 0@'.format(header.underscorify().to_upper()), '1')
>> +  endif
>> +endforeach
>> +
>> +spice_gtk_has_egl = compiler.has_header('epoxy/egl.h')
>> +if spice_gtk_has_egl
>> +    spice_gtk_config_data.set('HAVE_EPOXY_EGL_H', '1')
>> +    spice_gtk_config_data.set('HAVE_EGL', '1') # FIXME: Use single define?
>> +endif
>> +
>> +#
>> +# check for system functions
>> +#
>> +foreach func : ['clearenv', 'strtok_r']
>> +  if compiler.has_function(func)
>> +    spice_gtk_config_data.set('HAVE_ at 0@'.format(func.underscorify().to_upper()), '1')
>> +  endif
>> +endforeach
>> +
>> +#
>> +# check for mandatory dependencies
>> +#
>> +spice_protocol_version='0.12.15'
>> +
>> +glib_version = '2.46'
>> +glib_version_info = '>= @0@'.format(glib_version)
>> +pixman_version = '>= 0.17.7'
>> +
>> +deps = {'spice-protocol' : '>= @0@'.format(spice_protocol_version),
>> +        'glib-2.0'       : glib_version_info,
>> +        'gio-2.0'        : glib_version_info,
>> +        'gobject-2.0'    : glib_version_info,
>> +        'pixman-1'       : pixman_version,
>> +        'openssl'        : '>= 1.0.0'}
>> +
>> +foreach dep, version : deps
>> +  spice_gtk_deps += dependency(dep, version : version)
>> +endforeach
>> +
>> +# TODO: specify minimum version for cairo, jpeg and zlib?
>> +deps = ['cairo', 'libjpeg', 'zlib']
>> +if spice_gtk_host_system == 'windows'
>> +  deps += 'gio-windows-2.0'
>> +else
>> +  deps += 'gio-unix-2.0'
>> +endif
>> +
>> +foreach dep : deps
>> +  spice_gtk_deps += dependency(dep)
>> +endforeach
>> +
>> +deps = ['librt', 'libm']
>> +if spice_gtk_host_system == 'windows'
>> +  deps += ['libws2_32', 'libgdi32']
>> +endif
>> +
>> +foreach dep : deps
>> +  spice_gtk_deps += compiler.find_library(dep)
>> +endforeach
>> +
>> +#
>> +# Non-mandatory/optional dependencies
>> +#
>> +optional_deps = {'celt051' : '>= 0.5.1.1',
>> +                 'opus'    : '>= 0.9.14'}
>> +foreach dep, version : optional_deps
>> +  d = dependency(dep, required : get_option(dep), version : version)
>> +  if d.found()
>> +    spice_gtk_deps += d
>> +    spice_gtk_config_data.set('HAVE_ at 0@'.format(dep.underscorify().to_upper()), '1')
>> +  endif
>> +endforeach
>> +
>> +# gtk
>> +spice_gtk_has_gtk = false
>> +gtk_version_required = '3.22'
>> +if get_option('gtk')
>> +  spice_gtk_deps += dependency('gtk+-3.0', version : '>= @0@'.format(gtk_version_required))
>> +  spice_gtk_deps += dependency('x11')
>> +  if spice_gtk_host_system != 'windows'
>> +    spice_gtk_deps += dependency('epoxy')
>> +  endif
>> +  spice_gtk_has_gtk = true
>> +endif
>> +
>> +# webdav
>> +spice_gtk_has_phodav = false
>> +if get_option('webdav')
>> +  spice_gtk_deps += dependency('libphodav-2.0')
>> +  spice_gtk_deps += dependency('libsoup-2.4', version : '>= 2.49.91')
>> +  spice_gtk_config_data.set('USE_PHODAV', '1')
>> +  spice_gtk_has_phodav = true
>> +endif
>> +
>> +# pulse
>> +spice_gtk_has_pulse = false
>> +if get_option('pulse')
>> +  deps = ['libpulse', 'libpulse-mainloop-glib']
>> +  foreach dep : deps
>> +    spice_gtk_deps += dependency(dep)
>> +  endforeach
>> +  spice_gtk_config_data.set('HAVE_PULSE', '1')
>> +  spice_gtk_has_pulse = true
>> +endif
>> +
>> +# gstaudio
>> +gst_base_deps = ['gstreamer-1.0', 'gstreamer-base-1.0', 'gstreamer-app-1.0']
>> +spice_gtk_has_gstaudio = false
>> +if get_option('gstaudio')
>> +  deps = gst_base_deps + ['gstreamer-audio-1.0']
>> +  foreach dep : deps
>> +    spice_gtk_deps += dependency(dep)
>> +  endforeach
>> +  spice_gtk_config_data.set('HAVE_GSTAUDIO', '1')
>> +  spice_gtk_has_gstaudio = true
>> +endif
>> +
>> +# gstvideo
>> +spice_gtk_has_gstvideo = false
>> +if get_option('gstvideo')
>> +  deps = ['gstreamer-video-1.0']
>> +  if not spice_gtk_has_gstaudio
>> +    deps += gst_base_deps
>> +  endif
>> +  foreach dep : deps
>> +    spice_gtk_deps += dependency(dep)
>> +  endforeach
>> +  spice_gtk_config_data.set('HAVE_GSTVIDEO', '1')
>> +  spice_gtk_has_gstvideo = true
>> +endif
>> +
>> +# builtin-mjpeg
>> +spice_gtk_has_builtin_mjpeg = false
>> +if get_option('builtin-mjpeg')
>> +  spice_gtk_config_data.set('HAVE_BUILTIN_MJPEG', '1')
>> +  spice_gtk_has_builtin_mjpeg = true
>> +endif
>> +
>> +if not spice_gtk_has_gstvideo and not spice_gtk_has_builtin_mjpeg
>> +  warning('No builtin MJPEG or GStreamer decoder, video will not be streamed')
>> +endif
>> +
>> +# usbredir
>> +spice_gtk_has_usbredir = false
>> +if get_option('usbredir')
>> +  usb_dep = dependency('libusbredirparser-0.5', required : false)
>> +  if not usb_dep.found()
>> +    usb_dep = dependency('libusbredirparser', version : '>= 0.4')
>> +  endif
>> +  spice_gtk_deps += usb_dep
>> +
>> +  deps = {'libusbredirhost' : '>= 0.4.2',
>> +          'libusb-1.0' : '>= 1.0.9'}
>> +
>> +  foreach dep, version : deps
>> +    usb_dep = dependency(dep, version : version)
>> +    spice_gtk_deps += usb_dep
>> +  endforeach
>> +
>> +  if spice_gtk_host_system != 'windows'
>> +    if usb_dep.version().version_compare('>= 1.0.16')
>> +      spice_gtk_config_data.set('USE_LIBUSB_HOTPLUG', '1')
>> +    else
>> +      spice_gtk_deps += dependency('gudev-1.0')
>> +      spice_gtk_config_data.set('USE_GUDEV', '1')
>> +    endif
>> +  endif
>> +
>> +  spice_gtk_config_data.set('USE_USBREDIR', '1')
>> +  spice_gtk_has_usbredir = true
>> +endif
>> +
>> +# polkit
>> +spice_gtk_has_polkit = false
>> +if get_option('polkit')
>> +  polkit_dep = dependency('polkit-gobject-1', version : '>= 0.96')# ,required : false)
>> +  if polkit_dep.found()
>> +    spice_gtk_policy_dir = polkit_dep.get_pkgconfig_variable('policydir')
>> +    foreach func : ['polkit_authority_get_sync', 'polkit_authorization_result_get_dismissed']
>> +      if compiler.has_function(func, dependencies : polkit_dep)
>> +        spice_gtk_config_data.set('HAVE_ at 0@'.format(func.to_upper()), '1')
>> +      endif
>> +    endforeach
>> +
>> +    if not compiler.has_function('acl_get_file')
>> +      acl_dep = compiler.find_library('acl')
>> +      if not compiler.has_function('acl_get_file', dependencies : acl_dep)
>> +        error('PolicyKit support requested, but some required packages are not available')
>> +      endif
>> +      spice_gtk_deps += acl_dep
>> +    endif
>> +  endif
>> +
>> +  spice_gtk_deps += polkit_dep
>> +  spice_gtk_config_data.set('USE_POLKIT', '1')
>> +  spice_gtk_has_polkit = true
>> +endif
>> +
>> +if spice_gtk_has_usbredir and not spice_gtk_has_polkit
>> +  warning('Building with usbredir support, but *not* building the usb acl helper')
>> +endif
>> +
>> +# pie
>> +spice_gtk_has_pie = false
>> +if get_option('pie')
>> +  spice_gtk_has_pie = true
>> +endif
>> +
>> +# usb-acl-helper-dir
>> +spice_gtk_usb_acl_helper_dir = get_option('usb-acl-helper-dir')
>> +if spice_gtk_usb_acl_helper_dir.strip() == ''
>> +  spice_gtk_usb_acl_helper_dir = spice_gtk_bindir
>> +endif
>> +spice_gtk_config_data.set_quoted('ACL_HELPER_PATH', spice_gtk_usb_acl_helper_dir)
>> +
>> +# usb-ids-path
>> +spice_gtk_usb_ids_path = get_option('usb-ids-path')
>> +if spice_gtk_usb_ids_path.strip() == ''
>> +  usbutils = dependency('usbutils', required : false)
>> +  if usbutils.found()
>> +    spice_gtk_usb_ids_path = usbutils.get_pkgconfig_variable('usbids')
>> +  endif
>> +endif
>> +
>> +if spice_gtk_usb_ids_path.strip() != ''
>> +  spice_gtk_config_data.set('WITH_USBIDS', '1')
>> +  spice_gtk_config_data.set_quoted('USB_IDS', spice_gtk_usb_ids_path)
>> +endif
>> +
>> +# coroutine
>> +spice_gtk_coroutine = get_option('coroutine')
>> +if spice_gtk_coroutine == 'ucontext'
>> +  if compiler.has_function('makecontext') and compiler.has_function('swapcontext') and compiler.has_function('getcontext')
>> +    spice_gtk_config_data.set('WITH_UCONTEXT', '1')
>> +    if spice_gtk_host_system == 'darwin'
>> +      spice_gtk_config_data.set('_XOPEN_SOURCE', '1')
>> +    endif
>> +  else
>> +    spice_gtk_coroutine = 'gthread'
>> +  endif
>> +endif
>> +
>> +if spice_gtk_coroutine == 'gthread'
>> +  spice_gtk_config_data.set('WITH_GTHREAD', '1')
>> +endif
>> +
>> +if spice_gtk_coroutine == 'winfiber'
>> +  spice_gtk_config_data.set('WITH_WINFIBER', '1')
>> +endif
>> +
>> +# introspection
>> +spice_gtk_has_introspection = false
>> +if get_option('introspection')
>> +  spice_gtk_deps += dependency('gobject-introspection-1.0', version : '>= 0.94')
>> +  spice_gtk_has_introspection = true
>> +endif
>> +
>> +# vala (depends on introspection)
>> +spice_gtk_has_vala = false
>> +if spice_gtk_has_introspection and get_option('vapi')
>> +  vapigen_dep = dependency('vapigen')
>> +  vapidir = vapigen_dep.get_pkgconfig_variable('vapidir')
>> +  vapigen = dependency('vapigen').get_pkgconfig_variable('vapigen')
>> +  spice_gtk_has_vala = true
>> +endif
>> +
>> +# dbus
>> +if get_option('dbus')
>> +  spice_gtk_config_data.set('USE_GDBUS', '1')
>> +else
>> +  warning('No D-Bus support, desktop integration and USB redirection may not work properly')
>> +endif
>> +
>> +# lz4
>> +spice_gtk_has_lz4 = false
>> +if get_option('lz4')
>> +  lz4_dep = dependency('liblz4', required : false, version : '>= 129')
>> +  if not lz4_dep.found()
>> +    lz4_dep = dependency('liblz4', version : '>= 1.7.3')
>> +  endif
>> +
>> +  spice_gtk_deps += lz4_dep
>> +  spice_gtk_config_data.set('USE_LZ4', '1')
>> +  spice_gtk_has_lz4 = true
>> +endif
>> +
>> +# sasl
>> +spice_gtk_has_sasl = false
>> +if get_option('sasl')
>> +  spice_gtk_deps += dependency('libsasl2')
>> +  spice_gtk_config_data.set('HAVE_SASL', '1')
>> +  spice_gtk_has_sasl = true
>> +endif
>> +
>> +# smartcard check
>> +spice_gtk_has_smartcard = false
>> +if get_option('smartcard')
>> +  smartcard_dep = dependency('libcacard', required : false, version : '>= 2.5.1')
>> +  if smartcard_dep.found()
>> +    spice_gtk_deps += smartcard_dep
>> +    spice_gtk_config_data.set('USE_SMARTCARD', '1')
>> +  else
>> +    smartcard012_dep = dependency('libcacard', required : false, version : '>= 0.1.2')
>> +    if smartcard012_dep.found()
>> +      spice_gtk_deps += smartcard012_dep
>> +      spice_gtk_config_data.set('USE_SMARTCARD_012', '1')
>> +    endif
>> +  endif
>> +
>> +  spice_gtk_has_smartcard = smartcard_dep.found() or smartcard012_dep.found()
>> +  if not spice_gtk_has_smartcard
>> +    error('Building with smartcard support but dependency not found')
>> +  endif
>> +endif
>> +
>> +#
>> +# global C defines
>> +#
>> +glib_major_minor = glib_version.split('.')
>> +glib_encoded_version = 'GLIB_VERSION_ at 0@_ at 1@'.format(glib_major_minor[0], glib_major_minor[1])
>> +spice_gtk_global_cflags += ['-DGLIB_VERSION_MIN_REQUIRED=@0@'.format(glib_encoded_version),
>> +                            '-DGLIB_VERSION_MAX_ALLOWED=@0@'.format(glib_encoded_version)]
>> +
>> +if spice_gtk_has_gtk
>> +  gtk_major_minor = gtk_version_required.split('.')
>> +  gtk_encoded_version='GDK_VERSION_ at 0@_ at 1@'.format(gtk_major_minor[0], gtk_major_minor[1])
>> +  spice_gtk_global_cflags += ['-DGDK_VERSION_MIN_REQUIRED=@0@'.format(gtk_encoded_version),
>> +                              '-DGDK_VERSION_MAX_ALLOWED=@0@'.format(gtk_encoded_version)]
>> +endif
>> +
>> +foreach arg : spice_gtk_global_cflags
>> +  add_project_arguments(arg, language : 'c')
>> +endforeach
>> +
>> +#
>> +# Subdirectories
>> +#
>> +subdir('src')
>> +subdir('tools')
>> +subdir('tests')
>> +subdir('doc')
>> +subdir('data')
>> +subdir('man')
>> +subdir('po')
>> +subdir('vapi')
>> +
>> +#
>> +# write config.h
>> +#
>> +proj_version = meson.project_version()
>> +proj_name = meson.project_name()
>> +config_data = {'VERSION' : proj_version,
>> +               'PACKAGE_VERSION' : proj_version,
>> +               'GETTEXT_PACKAGE' : proj_name,
>> +               'LOCALE_DIR' : spice_gtk_localedir,
>> +               'PACKAGE_STRING' : '@0@ @1@'.format(proj_name, proj_version),
>> +               'PACKAGE_BUGREPORT' : 'spice-devel at lists.freedesktop.org'}
>> +foreach key, value : config_data
>> +  spice_gtk_config_data.set_quoted(key, value)
>> +endforeach
>> +
>> +configure_file(output : 'config.h',
>> +               install : false,
>> +               configuration : spice_gtk_config_data)
>> +
>> +#
>> +# write spice-client-glib.pc
>> +#
>> +pkgconfig = import('pkgconfig')
>> +pkgconfig.generate(spice_client_glib_lib,
>> +                   description : 'SPICE Client GLib 2.0 library',
>> +                   subdirs : 'spice-client-glib-2.0',
>> +                   requires : 'spice-protocol >= @0@'.format(spice_protocol_min_version),
>> +                   variables : 'exec_prefix=${prefix}')
>> +
>> +#
>> +# write spice-client-gtk.pc
>> +#
>> +if spice_gtk_has_gtk
>> +  pkgconfig.generate(spice_client_gtk_lib,
>> +                     description : 'SPICE Client Gtk 3.0 library',
>> +                     subdirs : 'spice-client-gtk-3.0',
>> +                     requires : 'spice-client-glib-2.0 gtk+3.0 >= @0@'.format(gtk_version_required),
>> +                     variables : 'exec_prefix=${prefix}')
>> +endif
>> diff --git a/meson_options.txt b/meson_options.txt
>> new file mode 100644
>> index 0000000..c09d440
>> --- /dev/null
>> +++ b/meson_options.txt
>> @@ -0,0 +1,102 @@
>> +option('gtk',
>> +    type : 'boolean',
>> +    value : true,
>> +    description: 'Enable gtk+')
>> +
>> +option('webdav',
>> +    type : 'boolean',
>> +    value : true,
>> +    description: 'Enable webdav support')
>> +
>> +option('pulse',
>> +    type : 'boolean',
>> +    value : true,
>> +    description: 'Enable the PulseAudio backend')
>> +
>> +option('gstaudio',
>> +    type : 'boolean',
>> +    value : true,
>> +    description : 'Enable the GStreamer 1.0 audio backend')
>> +
>> +option('gstvideo',
>> +    type : 'boolean',
>> +    value : true,
>> +    description : 'Enable GStreamer video support')
>> +
>> +option('builtin-mjpeg',
>> +    type : 'boolean',
>> +    value : true,
>> +    description : 'Enable the builtin mjpeg video decoder')
>> +
>> +option('usbredir',
>> +    type : 'boolean',
>> +    value : true,
>> +    description : 'Enable usbredir support')
>> +
>> +option('polkit',
>> +    type : 'boolean',
>> +    value : true,
>> +    description : 'Enable PolicyKit support for the USB acl helper')
>> +
>> +option('pie',
>> +    type : 'boolean',
>> +    value : true,
>> +    description : 'Enable position-independent-executable support for the USB acl helper')
>> +
>> +option('usb-acl-helper-dir',
>> +    type : 'string',
>> +    value : '',
>> +    description : 'Directory where the USB ACL helper binary should be installed')
>> +
>> +option('usb-ids-path',
>> +    type : 'string',
>> +    value : '',
>> +    description : 'Specify the path to usb.ids')
>> +
>> +option('coroutine',
>> +    type : 'combo',
>> +    choices : ['ucontext', 'gthread', 'winfiber'],
>> +    description : 'Use ucontext or GThread for coroutines')
>> +
>> +option('introspection',
>> +    type : 'boolean',
>> +    value : true,
>> +    description: 'Check for GObject instrospection requirements')
>> +
>> +option('vapi',
>> +    type : 'boolean',
>> +    value : true,
>> +    description: 'Check for vala requirements')
>> +
>> +option('dbus',
>> +    type : 'boolean',
>> +    value : true,
>> +    description: 'Enable dbus support for desktop integration (disabling automount)')
>> +
>> +option('alignment-checks',
>> +    type : 'boolean',
>> +    value : false,
>> +    description : 'Enable runtime checks for cast alignment')
>> +
>> +option('lz4',
>> +    type : 'boolean',
>> +    value : true,
>> +    description: 'Enable lz4 compression support')
>> +
>> +option('sasl',
>> +    type : 'boolean',
>> +    value : true,
>> +    description : 'Use cyrus SASL authentication')
>> +
>> +option('celt051',
>> +    type : 'feature',
>> +    description: 'Enable celt051 audio codec')
>> +
>> +option('opus',
>> +    type : 'feature',
>> +    description: 'Enable Opus audio codec')
>> +
>> +option('smartcard',
>> +    type : 'boolean',
>> +    value : true,
>> +    description : 'Enable smartcard support')
>> diff --git a/po/meson.build b/po/meson.build
>> new file mode 100644
>> index 0000000..60c27a7
>> --- /dev/null
>> +++ b/po/meson.build
>> @@ -0,0 +1,3 @@
>> +i18n = import('i18n')
>> +i18n.gettext(meson.project_name(),
>> +             args : '--directory=@0@'.format(meson.source_root()))
>> diff --git a/src/Makefile.am b/src/Makefile.am
>> index afad922..68dc5d9 100644
>> --- a/src/Makefile.am
>> +++ b/src/Makefile.am
>> @@ -25,6 +25,7 @@ CLEANFILES = $(GLIBGENS) $(KEYMAPS)
>>  BUILT_SOURCES = $(GLIBGENS) $(KEYMAPS)
>>  
>>  EXTRA_DIST =					\
>> +	meson.build				\
>>  	decode-glz-tmpl.c			\
>>  	$(KEYMAPS)				\
>>  	$(KEYMAP_CSV)				\
>> diff --git a/src/meson.build b/src/meson.build
>> new file mode 100644
>> index 0000000..92f5d78
>> --- /dev/null
>> +++ b/src/meson.build
>> @@ -0,0 +1,357 @@
>> +spice_gtk_include += [include_directories('.')]
>> +
>> +#
>> +# Source files for spice-client-glib
>> +#
>> +
>> +# generate spice-version.h
>> +version_info = meson.project_version().split('.')
>> +major = '@0@'.format(version_info[0])
>> +minor = '@0@'.format(version_info[1])
>> +micro = version_info[2].split('-')[0]
>> +if micro == ''
>> +  micro = '0'
>> +endif
>> +version_data = configuration_data()
>> +version_data.set('SPICE_GTK_MAJOR_VERSION', major)
>> +version_data.set('SPICE_GTK_MINOR_VERSION', minor)
>> +version_data.set('SPICE_GTK_MICRO_VERSION', micro)
>> +spice_version_h = configure_file(input : 'spice-version.h.in',
>> +                                 output : 'spice-version.h',
>> +                                 configuration : version_data)
>> +
>> +spice_client_glib_headers = [
>> +  spice_version_h,
>> +  'channel-cursor.h',
>> +  'channel-display.h',
>> +  'channel-inputs.h',
>> +  'channel-main.h',
>> +  'channel-playback.h',
>> +  'channel-port.h',
>> +  'channel-record.h',
>> +  'channel-smartcard.h',
>> +  'channel-usbredir.h',
>> +  'channel-webdav.h',
>> +  'smartcard-manager.h',
>> +  'spice-audio.h',
>> +  'spice-channel.h',
>> +  'spice-client.h',
>> +  'spice-file-transfer-task.h',
>> +  'spice-option.h',
>> +  'spice-session.h',
>> +  'spice-types.h',
>> +  'spice-uri.h',
>> +  'spice-util.h',
>> +  'usb-device-manager.h',
>> +]
>> +
>> +install_headers(spice_client_glib_headers, subdir : 'spice-client-glib-2.0')
>> +
>> +# generate spice-marshal.[ch]
>> +gnome = import('gnome')
>> +spice_marshals = gnome.genmarshal('spice-marshal', sources : 'spice-marshal.txt')
>> +
>> +# generate spice-glib-enums.[ch]
>> +spice_client_glib_enums = gnome.mkenums_simple('spice-glib-enums',
>> +                                               sources : ['spice-channel.h', 'channel-inputs.h', 'spice-session.h'],
>> +                                               install_header : true,
>> +                                               install_dir : join_paths(spice_gtk_includedir, 'spice-client-glib-2.0'))
>> +
>> +spice_client_glib_introspection_sources = [
>> +  spice_client_glib_headers,
>> +  spice_client_glib_enums,
>> +  'channel-cursor.c',
>> +  'channel-display.c',
>> +  'channel-inputs.c',
>> +  'channel-main.c',
>> +  'channel-playback.c',
>> +  'channel-port.c',
>> +  'channel-record.c',
>> +  'channel-smartcard.c',
>> +  'channel-usbredir.c',
>> +  'channel-webdav.c',
>> +  'smartcard-manager.c',
>> +  'spice-audio.c',
>> +  'spice-channel.c',
>> +  'spice-client.c',
>> +  'spice-option.c',
>> +  'spice-session.c',
>> +  'spice-util.c',
>> +  'usb-device-manager.c',
>> +]
>> +
>> +spice_client_glib_sources = [
>> +  spice_marshals,
>> +  spice_client_glib_introspection_sources,
>> +  'bio-gio.c',
>> +  'bio-gio.h',
>> +  'channel-base.c',
>> +  'channel-display-priv.h',
>> +  'channel-playback-priv.h',
>> +  'channel-usbredir-priv.h',
>> +  'client_sw_canvas.c',
>> +  'client_sw_canvas.h',
>> +  'coroutine.h',
>> +  'decode-glz.c',
>> +  'decode.h',
>> +  'decode-jpeg.c',
>> +  'decode-zlib.c',
>> +  'gio-coroutine.c',
>> +  'gio-coroutine.h',
>> +  'smartcard-manager-priv.h',
>> +  'spice-audio-priv.h',
>> +  'spice-channel-cache.h',
>> +  'spice-channel-priv.h',
>> +  'spice-common.h',
>> +  'spice-file-transfer-task.c',
>> +  'spice-file-transfer-task-priv.h',
>> +  'spice-glib-main.c',
>> +  'spice-option.h',
>> +  'spice-session-priv.h',
>> +  'spice-uri.c',
>> +  'spice-uri-priv.h',
>> +  'spice-util-priv.h',
>> +  'usb-device-manager-priv.h',
>> +  'usbutil.c',
>> +  'usbutil.h',
>> +  'vmcstream.c',
>> +  'vmcstream.h',
>> +]
>> +
>> +if spice_gtk_has_builtin_mjpeg
>> +  spice_client_glib_sources += 'channel-display-mjpeg.c'
>> +endif
>> +
>> +if spice_gtk_has_gstaudio
>> +  spice_client_glib_sources += ['spice-gstaudio.c',
>> +                                'spice-gstaudio.h']
>> +endif
>> +
>> +if spice_gtk_has_gstvideo
>> +  spice_client_glib_sources += 'channel-display-gst.c'
>> +endif
>> +
>> +if spice_gtk_has_polkit
>> +  spice_client_glib_sources += ['usb-acl-helper.c',
>> +                                'usb-acl-helper.h']
>> +endif
>> +
>> +if spice_gtk_has_phodav
>> +  spice_client_glib_sources += ['giopipe.c',
>> +                                'giopipe.h']
>> +endif
>> +
>> +if spice_gtk_has_pulse
>> +  spice_client_glib_sources += ['spice-pulse.c',
>> +                                'spice-pulse.h']
>> +endif
>> +
>> +if spice_gtk_coroutine == 'gthread'
>> +  spice_client_glib_sources += 'coroutine_gthread.c'
>> +elif spice_gtk_coroutine == 'ucontext'
>> +  spice_client_glib_sources += ['continuation.c',
>> +                                'continuation.h',
>> +                                'coroutine_ucontext.c']
>> +elif spice_gtk_coroutine == 'winfiber'
>> +  spice_client_glib_sources += 'coroutine_winfibers.c'
>> +endif
>> +
>> +if spice_gtk_has_usbredir and spice_gtk_host_system == 'windows'
>> +  spice_client_glib_sources += ['usbdk_api.c',
>> +                                'usbdk_api.h',
>> +                                'win-usb-dev.c',
>> +                                'win-usb-dev.h']
>> +endif
>> +
>> +#
>> +# libspice-client-glib-2.0.so
>> +#
>> +
>> +# custom link_args
>> +
>> +# version-script
>> +spice_client_glib_syms = files('map-file')
>> +spice_client_glib_syms_path = join_paths(meson.current_source_dir(), 'map-file')
>> +spice_gtk_version_script = '-Wl,--version-script=@0@'.format(spice_client_glib_syms_path)
>> +spice_gtk_has_version_script = compiler.has_link_argument(spice_gtk_version_script)
>> +if not spice_gtk_has_version_script
>> +  spice_client_glib_syms = files('spice-glib-sym-file')
>> +  spice_client_glib_syms_path = join_paths(meson.current_source_dir(), 'spice-glib-sym-file')
>> +  spice_gtk_version_script = ['-export-symbols', spice_client_glib_syms_path]
>> +endif
>> +
>> +spice_client_glib_lib = library('spice-client-glib-2.0', spice_client_glib_sources,
>> +                                version : '8.6.0',
>> +                                install : true,
>> +                                include_directories : spice_gtk_include,
>> +                                link_args : spice_gtk_link_args + [spice_gtk_version_script],
>> +                                link_depends : spice_client_glib_syms,
>> +                                link_with : spice_gtk_libs,
>> +                                dependencies : spice_gtk_deps)
>> +
>> +spice_client_glib_dep = declare_dependency(sources : [spice_marshals[1], spice_client_glib_enums[1]],
>> +                                           link_with : spice_client_glib_lib,
>> +                                           include_directories : spice_gtk_include,
>> +                                           link_args : spice_gtk_link_args,
>> +                                           dependencies : spice_gtk_deps)
>> +
>> +#
>> +# SpiceClientGLib-2.0.gir
>> +#
>> +spice_client_glib_introspection_dep = declare_dependency(include_directories: spice_gtk_include,
>> +                                                         link_args : spice_gtk_link_args,
>> +                                                         link_with : spice_client_glib_lib)
>> +
>> +spice_client_glib_gir = gnome.generate_gir(spice_client_glib_lib,
>> +                                           build_by_default : spice_gtk_has_introspection,
>> +                                           dependencies : spice_client_glib_introspection_dep,
>> +                                           export_packages : 'spice-client-glib-2.0',
>> +                                           extra_args : ['--accept-unprefixed'],
>> +                                           header : 'spice-client.h',
>> +                                           includes : ['GObject-2.0', 'Gio-2.0'],
>> +                                           identifier_prefix : 'Spice',
>> +                                           symbol_prefix : 'spice',
>> +                                           install : spice_gtk_has_introspection,
>> +                                           namespace : 'SpiceClientGLib',
>> +                                           nsversion : '2.0',
>> +                                           sources : spice_client_glib_introspection_sources)
>> +
>> +#
>> +# spice-client-glib-usb-acl-helper
>> +#
>> +if spice_gtk_has_polkit
>> +  usb_acl_helper_c_args = []
>> +  usb_acl_helper_link_args = spice_gtk_link_args
>> +
>> +  if spice_gtk_has_pie
>> +    usb_acl_helper_c_args += compiler.get_supported_arguments(['-fPIE'])
>> +    usb_acl_helper_link_args += compiler.get_supported_link_arguments(['-pie', '-Wl,-z,relro', '-Wl,-z,now'])
>> +  endif
>> +  executable('spice-client-glib-usb-acl-helper',
>> +             'spice-client-glib-usb-acl-helper.c',
>> +             include_directories : spice_gtk_include,
>> +             install : true,
>> +             install_dir : spice_gtk_usb_acl_helper_dir,
>> +             install_mode : ['rwsr-xr-x', 'root', 'root'],
>> +             c_args : usb_acl_helper_c_args,
>> +             link_args : usb_acl_helper_link_args,
>> +             dependencies : spice_gtk_deps)
>> +endif
>> +
>> +
>> +if spice_gtk_has_gtk
>> +  #
>> +  # Source files for spice-client-gtk
>> +  #
>> +
>> +  spice_client_gtk_headers = [
>> +    'spice-client-gtk.h',
>> +    'spice-grabsequence.h',
>> +    'spice-gtk-session.h',
>> +    'spice-widget.h',
>> +    'usb-device-widget.h',
>> +  ]
>> +
>> +  install_headers(spice_client_gtk_headers, subdir : 'spice-client-gtk-3.0')
>> +
>> +  # generate spice-widget-enums.[ch]
>> +  spice_widget_enums = gnome.mkenums_simple('spice-widget-enums',
>> +                                            sources : 'spice-widget.h',
>> +                                            install_header : true,
>> +                                            install_dir : join_paths(spice_gtk_includedir, 'spice-client-gtk-3.0'))
>> +
>> +  spice_client_gtk_introspection_sources = [
>> +    spice_client_gtk_headers,
>> +    spice_widget_enums,
>> +    'spice-grabsequence.c',
>> +    'spice-gtk-session.c',
>> +    'spice-widget.c',
>> +    'usb-device-widget.c',
>> +  ]
>> +
>> +  spice_client_gtk_sources = [
>> +    spice_marshals,
>> +    spice_client_gtk_introspection_sources,
>> +    'desktop-integration.c',
>> +    'desktop-integration.h',
>> +    'spice-file-transfer-task.h',
>> +    'spice-grabsequence.h',
>> +    'spice-grabsequence-priv.h',
>> +    'spice-gtk-session-priv.h',
>> +    'spice-util.c',
>> +    'spice-util-priv.h',
>> +    'spice-widget-cairo.c',
>> +    'spice-widget-priv.h',
>> +    'vncdisplaykeymap.c',
>> +    'vncdisplaykeymap.h',
>> +  ]
>> +
>> +  if spice_gtk_has_egl
>> +    spice_client_gtk_sources += 'spice-widget-egl.c'
>> +  endif
>> +
>> +  # keymaps
>> +  python = import('python3').find_python()
>> +  keymapgen = files('./keycodemapdb/tools/keymap-gen')
>> +  keymapcsv = files('./keycodemapdb/data/keymaps.csv')
>> +  keymaps = ['xorgevdev',
>> +             'xorgkbd',
>> +             'xorgxquartz',
>> +             'xorgxwin',
>> +             'osx',
>> +             'win32',
>> +             'x11']
> 
> This part seems tricky, hit a few build issues that fade away
> when I use -j1
> 
> [97/142] Compiling C object 'src/src@@spice-client-gtk-3.0 at sha/vncdisplaykeymap.c.o'.
> FAILED: src/src@@spice-client-gtk-3.0 at sha/vncdisplaykeymap.c.o
> cc -Isrc/src@@spice-client-gtk-3.0 at sha -Isrc -I../src -I. -I../ -Isubprojects/spice-common -I../subprojects/spice-common -Isubprojects/spice-common/common -I/home/toso/dev/include/spice-1 -I/home/toso/dev/include/glib-2.0 -I/home/toso/dev/lib/glib-2.0/include -I/usr/include/pixman-1 -I/usr/include/opus -I/home/toso/dev/include/cacard -I/usr/include/nss3 -I/usr/include/nspr4 -I/home/toso/dev/include/cairo -I/usr/include/freetype2 -I/usr/include/libpng16 -I/usr/include/uuid -I/usr/include/libdrm -I/home/toso/dev/include/gio-unix-2.0 -I/home/toso/dev/include/gtk-3.0 -I/home/toso/dev/include/pango-1.0 -I/home/toso/dev/include/fribidi -I/home/toso/dev/include/harfbuzz -I/home/toso/dev/include/gdk-pixbuf-2.0 -I/home/toso/dev/include/atk-1.0 -I/home/toso/dev/include/at-spi2-atk/2.0 -I/home/toso/dev/include/at-spi-2.0 -I/usr/include/dbus-1.0 -I/usr/lib64/dbus-1.0/include -I/home/toso/dev/include/libphodav-2.0 -I/home/toso/dev/include/libsoup-2.4 -I/usr/include/libxml2
> -I/home/toso/dev/include/gstreamer-1.0 -I/usr/include/orc-0.4 -I/home/toso/dev/include/libusb-1.0 -I/usr/include/polkit-1 -I/home/toso/dev/include/gobject-introspection-1.0 -fdiagnostics-color=always -pipe -D_FILE_OFFSET_BITS=64 -Wall -Winvalid-pch -O0 -g -DHAVE_CONFIG_H -DSPICE_COMPILATION '-DG_LOG_DOMAIN="GSpice"' -Wall -Wextra -Wno-sign-compare -Wno-unused-parameter -DGLIB_VERSION_MIN_REQUIRED=GLIB_VERSION_2_46 -DGLIB_VERSION_MAX_ALLOWED=GLIB_VERSION_2_46 -DGDK_VERSION_MIN_REQUIRED=GDK_VERSION_3_22 -DGDK_VERSION_MAX_ALLOWED=GDK_VERSION_3_22 -fPIC -pthread -D_REENTRANT  -MD -MQ 'src/src@@spice-client-gtk-3.0 at sha/vncdisplaykeymap.c.o' -MF 'src/src@@spice-client-gtk-3.0 at sha/vncdisplaykeymap.c.o.d' -o 'src/src@@spice-client-gtk-3.0 at sha/vncdisplaykeymap.c.o' -c ../src/vncdisplaykeymap.c
> ../src/vncdisplaykeymap.c:103:10: fatal error: vncdisplaykeymap_x112xtkbd.c: No such file or directory
>  #include "vncdisplaykeymap_x112xtkbd.c"
>            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> 
> Sorry that I took too long to test it more.
> 

Thank you, this looks like a real problem, that I have never bumped
into. Parellel builds are failing for you because there is no explicit
dependency between the generated keymap files and vncdisplaykeymap.c.

I have a fix for that, but it requires renaming extension of the
generated files to .h, instead of using .c. The reason is that with
meson, if you do something like

declare_dependency(sources : 'foo.c')

Then meson understands this file as being a source code and will then
compile it, and the build still fails.

src/vncdisplaykeymap_xorgevdev2xtkbd.c:7:7: error: unknown type name
‘guint16’
 const guint16 keymap_xorgevdev2xtkbd[533] = {
       ^~~~~~~

Documentation is very explicit about that as well, in

http://mesonbuild.com/Wrap-best-practices-and-tips.html#declare-generated-headers-explicitly

and

http://mesonbuild.com/Wrap-best-practices-and-tips.html#avoid-exposing-compilable-source-files-in-declare_dependency


> Cheers,
> Victor
> 
>> +
>> +  foreach keymap : keymaps
>> +    varname = 'keymap_ at 0@2xtkbd'.format(keymap)
>> +    target = 'vncdisplay at 0@.c'.format(varname)
>> +    cmd = [python, keymapgen, '--lang', 'glib2', '--varname', varname, 'code-map', keymapcsv, keymap, 'xtkbd']
>> +    custom_target(target,
>> +                  output : target,
>> +                  capture : true,
>> +                  build_by_default: true,
>> +                  command : cmd)
>> +  endforeach
>> +
>> +  #
>> +  # libspice-client-gtk.so
>> +  #
>> +  spice_client_gtk_syms = spice_client_glib_syms
>> +  if not spice_gtk_has_version_script
>> +    spice_client_gtk_syms = files('spice-gtk-sym-file')
>> +    spice_client_gtk_syms_path = join_paths(meson.current_source_dir(), 'spice-gtk-sym-file')
>> +    spice_gtk_version_script = ['-export-symbols', spice_client_gtk_syms_path]
>> +  endif
>> +
>> +  spice_client_gtk_lib = library('spice-client-gtk-3.0', spice_client_gtk_sources,
>> +                                 version : '5.0.0',
>> +                                 install : true,
>> +                                 link_args : spice_gtk_link_args + [spice_gtk_version_script],
>> +                                 link_depends : spice_client_gtk_syms,
>> +                                 dependencies : spice_client_glib_dep)
>> +
>> +  spice_client_gtk_dep = declare_dependency(sources : spice_widget_enums[1],
>> +                                            link_with : spice_client_gtk_lib,
>> +                                            dependencies : spice_client_glib_dep)
>> +
>> +  #
>> +  # SpiceClientGtk-3.0.gir
>> +  #
>> +  spice_client_gtk_introspection_dep = declare_dependency(include_directories: spice_gtk_include,
>> +                                                           link_args : spice_gtk_link_args,
>> +                                                           link_with : [spice_client_gtk_lib, spice_client_glib_lib])
>> +
>> +  spice_client_gtk_gir = gnome.generate_gir(spice_client_gtk_lib,
>> +                                            build_by_default : spice_gtk_has_introspection,
>> +                                            dependencies : spice_client_gtk_introspection_dep,
>> +                                            export_packages : 'spice-client-gtk-3.0',
>> +                                            extra_args : ['--accept-unprefixed'],
>> +                                            header : 'spice-widget.h',
>> +                                            includes : ['GObject-2.0', 'Gtk-3.0', 'SpiceClientGLib-2.0'],
>> +                                            identifier_prefix : 'Spice',
>> +                                            symbol_prefix : 'spice',
>> +                                            install : spice_gtk_has_introspection,
>> +                                            namespace : 'SpiceClientGtk',
>> +                                            nsversion : '3.0',
>> +                                            sources : spice_client_gtk_introspection_sources)
>> +endif
>> diff --git a/subprojects/spice-common b/subprojects/spice-common
>> index f82a6c5..5dd0c2f 160000
>> --- a/subprojects/spice-common
>> +++ b/subprojects/spice-common
>> @@ -1 +1 @@
>> -Subproject commit f82a6c5349a9a71485910bd3a57fe588c49d74f8
>> +Subproject commit 5dd0c2f70a871f397b6550bde1eda91e9d4a8ad4
>> diff --git a/tests/Makefile.am b/tests/Makefile.am
>> index 3a0188d..bfa43a3 100644
>> --- a/tests/Makefile.am
>> +++ b/tests/Makefile.am
>> @@ -1,5 +1,7 @@
>>  NULL =
>>  
>> +EXTRA_DIST = meson.build
>> +
>>  noinst_PROGRAMS =
>>  TESTS = test-coroutine				\
>>  	test-util				\
>> diff --git a/tests/meson.build b/tests/meson.build
>> new file mode 100644
>> index 0000000..6c80776
>> --- /dev/null
>> +++ b/tests/meson.build
>> @@ -0,0 +1,30 @@
>> +tests_sources = [
>> +    'util.c',
>> +    'coroutine.c',
>> +    'session.c',
>> +    'uri.c',
>> +    'file-transfer.c',
>> +]
>> +
>> +if spice_gtk_has_phodav
>> +  tests_sources += 'pipe.c'
>> +endif
>> +
>> +if spice_gtk_has_polkit
>> +  tests_sources += [
>> +    'usb-acl-helper.c',
>> +    'mock-acl-helper.c',
>> +  ]
>> +endif
>> +
>> +foreach src : tests_sources
>> +  name = 'test- at 0@'.format(src).split('.')[0]
>> +  exe = executable(name,
>> +                   sources : src,
>> +                   c_args : '-DTESTDIR="@0@"'.format(meson.current_build_dir()),
>> +                   objects : spice_client_glib_lib.extract_all_objects(),
>> +                   dependencies : spice_client_glib_dep)
>> +  if not name.contains('mock-acl-helper')
>> +    test(name, exe)
>> +  endif
>> +endforeach
>> diff --git a/tools/Makefile.am b/tools/Makefile.am
>> index 1e3deed..18786ae 100644
>> --- a/tools/Makefile.am
>> +++ b/tools/Makefile.am
>> @@ -1,5 +1,7 @@
>>  bin_PROGRAMS = spicy-stats spicy-screenshot
>>  
>> +EXTRA_DIST = meson.build
>> +
>>  TOOLS_CPPFLAGS =			\
>>  	-DSPICE_COMPILATION		\
>>  	-I$(top_builddir)/src		\
>> diff --git a/tools/meson.build b/tools/meson.build
>> new file mode 100644
>> index 0000000..33e53c2
>> --- /dev/null
>> +++ b/tools/meson.build
>> @@ -0,0 +1,32 @@
>> +spice_cmdline_sources = [
>> +  'spice-cmdline.c',
>> +  'spice-cmdline.h',
>> +]
>> +
>> +#
>> +# spicy-stats and spicy-screenshot
>> +#
>> +foreach exe : ['spicy-stats', 'spicy-screenshot']
>> +  executable(exe,
>> +             sources : spice_cmdline_sources + ['@0 at .c'.format(exe)],
>> +             c_args : '-Wno-deprecated-declarations',
>> +             install : true,
>> +             dependencies : spice_client_glib_dep)
>> +endforeach
>> +
>> +#
>> +# spicy
>> +#
>> +if spice_gtk_has_gtk
>> +  spicy_sources = [
>> +    'spicy.c',
>> +    'spicy-connect.c',
>> +    'spicy-connect.h',
>> +  ]
>> +
>> +  executable('spicy',
>> +             sources : spicy_sources + spice_cmdline_sources,
>> +             c_args : '-Wno-deprecated-declarations',
>> +             install : true,
>> +             dependencies : spice_client_gtk_dep)
>> +endif
>> diff --git a/vapi/Makefile.am b/vapi/Makefile.am
>> index aaab848..494ad83 100644
>> --- a/vapi/Makefile.am
>> +++ b/vapi/Makefile.am
>> @@ -15,6 +15,7 @@ dist_vapi_DATA += spice-client-gtk-3.0.deps
>>  endif
>>  
>>  EXTRA_DIST =						\
>> +	meson.build					\
>>  	spice-client-gtk-3.0.deps			\
>>  	SpiceClientGLib-2.0.metadata			\
>>  	$(NULL)
>> diff --git a/vapi/meson.build b/vapi/meson.build
>> new file mode 100644
>> index 0000000..4737715
>> --- /dev/null
>> +++ b/vapi/meson.build
>> @@ -0,0 +1,13 @@
>> +if spice_gtk_has_vala
>> +  gnome.generate_vapi('spice-client-glib-2.0',
>> +                      install : true,
>> +                      packages : 'gio-2.0',
>> +                      sources : spice_client_glib_gir[0])
>> +  if spice_gtk_has_gtk
>> +    gnome.generate_vapi('spice-client-gtk-3.0',
>> +                        install : true,
>> +                        packages : ['gtk+-3.0', 'spice-client-glib-2.0'],
>> +                        vapi_dirs : meson.current_build_dir(),
>> +                        sources : spice_client_gtk_gir[0])
>> +  endif
>> +endif
>> -- 
>> 2.14.4
>>
>> _______________________________________________
>> Spice-devel mailing list
>> Spice-devel at lists.freedesktop.org
>> https://lists.freedesktop.org/mailman/listinfo/spice-devel


-- 
Eduardo de Barros Lima (Etrunko)
Software Engineer - RedHat
etrunko at redhat.com


More information about the Spice-devel mailing list