[Spice-devel] [PATCH spice-server 1/3] Add support for building with meson

Eduardo Lima (Etrunko) etrunko at redhat.com
Fri Apr 27 19:25:38 UTC 2018


Signed-off-by: Eduardo Lima (Etrunko) <etrunko at redhat.com>
---
 Makefile.am                   |   3 +
 docs/Makefile.am              |   1 +
 docs/manual/Makefile.am       |   1 +
 docs/manual/meson.build       |  18 ++++
 docs/meson.build              |  14 +++
 meson.build                   | 166 +++++++++++++++++++++++++++++++++
 meson_options.txt             |  39 ++++++++
 server/Makefile.am            |   1 +
 server/meson.build            | 207 ++++++++++++++++++++++++++++++++++++++++++
 server/tests/Makefile.am      |   1 +
 server/tests/meson.build      |  93 +++++++++++++++++++
 subprojects/spice-common.wrap |   4 +
 tools/Makefile.am             |   4 +
 tools/meson.build             |   4 +
 14 files changed, 556 insertions(+)
 create mode 100644 docs/manual/meson.build
 create mode 100644 docs/meson.build
 create mode 100644 meson.build
 create mode 100644 meson_options.txt
 create mode 100644 server/meson.build
 create mode 100644 server/tests/meson.build
 create mode 100644 subprojects/spice-common.wrap
 create mode 100644 tools/meson.build

diff --git a/Makefile.am b/Makefile.am
index 9a073a12..0104f22d 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -17,6 +17,9 @@ DISTCHECK_CONFIGURE_FLAGS =			\
 	$(NULL)
 
 EXTRA_DIST =					\
+	meson.build				\
+	meson_options.txt			\
+	subprojects/spice-common.wrap		\
 	build-aux/git-version-gen		\
 	.version				\
 	$(NULL)
diff --git a/docs/Makefile.am b/docs/Makefile.am
index 45667a60..aa4298fd 100644
--- a/docs/Makefile.am
+++ b/docs/Makefile.am
@@ -2,6 +2,7 @@ NULL =
 ASCIIDOC_FLAGS = -a icons -a toc
 
 EXTRA_DIST =					\
+	meson.build				\
 	spice_style.html			\
 	spice_style.txt				\
 	spice_threading_model.html		\
diff --git a/docs/manual/Makefile.am b/docs/manual/Makefile.am
index 24a11fe0..bffccfd3 100644
--- a/docs/manual/Makefile.am
+++ b/docs/manual/Makefile.am
@@ -3,6 +3,7 @@ SUFFIXES = .html
 ASCIIDOC_FLAGS = -a icons -a toc
 
 EXTRA_DIST =					\
+	meson.build				\
 	images/icons/important.png		\
 	images/icons/note.png			\
 	manual.html				\
diff --git a/docs/manual/meson.build b/docs/manual/meson.build
new file mode 100644
index 00000000..4218b546
--- /dev/null
+++ b/docs/manual/meson.build
@@ -0,0 +1,18 @@
+txt = files('manual.txt')
+
+if asciidoc.found()
+  custom_target('manual.html',
+                input : txt,
+                output : 'manual.html',
+                build_by_default : true,
+                command : [asciidoc, '-n', asciidoc_args, '-o', '@OUTPUT@', '@INPUT@'])
+endif
+
+a2x = find_program('a2x', required : false)
+if a2x.found()
+  custom_target('manual.chunked',
+                input : txt,
+                output : 'manual.chunked',
+                build_by_default : true,
+                command : [a2x, '-f', 'chunked', '-D', meson.current_build_dir(), asciidoc_args, '@INPUT@'])
+endif
diff --git a/docs/meson.build b/docs/meson.build
new file mode 100644
index 00000000..82864bb8
--- /dev/null
+++ b/docs/meson.build
@@ -0,0 +1,14 @@
+if get_option('manual')
+  asciidoc = find_program('asciidoc', required : false)
+  if asciidoc.found()
+    asciidoc_args = ['-a', 'data-uri', '-a', 'icons', '-a', 'toc']
+    foreach doc : ['style', 'threading_model']
+      custom_target('spice_ at 0@.html'.format(doc),
+                    input : 'spice_ at 0@.txt'.format(doc),
+                    output : 'spice_ at 0@.html'.format(doc),
+                    build_by_default: true,
+                    command : [asciidoc, '-n', asciidoc_args, '-o', '@OUTPUT@', '@INPUT@'])
+    endforeach
+  endif
+  subdir('manual')
+endif
diff --git a/meson.build b/meson.build
new file mode 100644
index 00000000..8481418e
--- /dev/null
+++ b/meson.build
@@ -0,0 +1,166 @@
+#
+# project definition
+#
+# TODO: double check meson.project_version()
+# Ideally we would use the output of git-version-gen as input for meson, because
+# we can not check the result of the command before declaring project().
+#
+project('spice', 'c',
+         version : run_command('build-aux/git-version-gen', '.tarball-version').stdout().strip(),
+         license : 'LGPLv2.1',
+         meson_version : '>= 0.45.0')
+
+#
+# global C defines
+#
+spice_server_global_cflags = [#'-std=c99', # fails compiling spice-common/bitops.h
+                              '-fvisibility=hidden',
+                              '-DSPICE_SERVER_INTERNAL',
+                              '-DG_LOG_DOMAIN="Spice"',
+                              '-DHAVE_CONFIG_H',
+                              #'-Werror',
+                              '-Wall',
+                              '-Wextra',
+                              '-Wno-sign-compare',
+                              '-Wno-unused-parameter']
+
+foreach arg : spice_server_global_cflags
+  add_project_arguments(arg, language : 'c')
+endforeach
+
+# other global vars
+compiler = meson.get_compiler('c')
+spice_server_config_data = configuration_data()
+spice_protocol_min_version='0.12.14'
+spice_server_include = [include_directories('.')]
+spice_server_deps = []
+spice_server_link_args = []
+spice_server_requires = ''
+
+#
+# Spice common subproject
+#
+spice_common_options = ['protocol-version=@0@'.format(spice_protocol_min_version),
+                        'generate-code=server']
+
+spice_common = subproject('spice-common', default_options : spice_common_options)
+spice_server_config_data.merge_from(spice_common.get_variable('spice_common_config_data'))
+spice_server_deps += spice_common.get_variable('spice_common_server_dep')
+
+#
+# check for system headers
+#
+headers = ['sys/time.h',
+           'execinfo.h',
+           'linux/sockios.h',
+           'pthread_np.h']
+
+foreach header : headers
+  if compiler.has_header(header)
+    spice_server_config_data.set('HAVE_ at 0@'.format(header.underscorify().to_upper()), '1')
+  endif
+endforeach
+
+# TCP_KEEPIDLE definition in netinet/tcp.h
+if compiler.has_header_symbol('netinet/tcp.h', 'TCP_KEEPIDLE')
+  spice_server_config_data.set('HAVE_TCP_KEEPIDLE', '1')
+endif
+
+#
+# check for mandatory dependencies
+#
+foreach dep : ['libjpeg', 'zlib']
+  spice_server_deps += dependency(dep)
+endforeach
+
+foreach dep : ['librt', 'libm']
+  spice_server_deps += compiler.find_library(dep)
+endforeach
+
+#
+# Non-mandatory/optional dependencies
+#
+
+# gstreamer
+spice_server_has_gstreamer = false
+spice_server_gst_version = get_option('gstreamer')
+if spice_server_gst_version != 'no'
+  gst_deps = ['gstreamer', 'gstreamer-base', 'gstreamer-app', 'gstreamer-video']
+  foreach dep : gst_deps
+    dep = '@0 at -@1@'.format(dep, spice_server_gst_version)
+    spice_server_deps += dependency(dep)
+  endforeach
+  spice_server_deps += dependency('orc-0.4')
+
+  gst_def = 'HAVE_GSTREAMER'
+  if spice_server_gst_version == '1.0'
+    gst_def = 'HAVE_GSTREAMER_1_0'
+  endif
+
+  spice_server_config_data.set(gst_def, '1')
+  spice_server_has_gstreamer = true
+endif
+
+# lz4
+spice_server_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_server_deps += lz4_dep
+  spice_server_config_data.set('USE_LZ4', '1')
+  spice_server_has_lz4 = true
+endif
+
+# sasl
+spice_server_has_sasl = false
+if get_option('sasl')
+  spice_server_deps += dependency('libsasl2')
+  spice_server_config_data.set('HAVE_SASL', '1')
+  spice_server_has_sasl = true
+endif
+
+# checks for smartcard are done in spice_common
+spice_server_has_smartcard = false
+if get_option('smartcard')
+  if not spice_common.get_variable('spice_common_has_smartcard')
+    error('Building with smartcard support but dependency not found')
+  else
+    spice_server_has_smartcard = true
+  endif
+endif
+
+#
+# Subdirectories
+#
+subdir('server')
+subdir('tools')
+subdir('docs')
+
+#
+# write config.h
+#
+spice_server_config_data.set_quoted('VERSION', meson.project_version())
+spice_server_config_data.set('SPICE_USE_SAFER_CONTAINEROF', '1')
+
+if get_option('statistics')
+  spice_server_config_data.set('RED_STATISTICS', '1')
+endif
+
+configure_file(output : 'config.h',
+               install : false,
+               configuration : spice_server_config_data)
+
+#
+# write spice-server.pc
+#
+pkgconfig = import('pkgconfig')
+pkgconfig.generate(name : 'spice-server',
+    version : meson.project_version(),
+    description : 'SPICE server library',
+    subdirs : ['spice-server'],
+    libraries : spice_server_lib,
+    requires : ['spice-protocol >= @0@'.format(spice_protocol_min_version)],
+    variables : ['exec_prefix=${prefix}'])
diff --git a/meson_options.txt b/meson_options.txt
new file mode 100644
index 00000000..d82e3b87
--- /dev/null
+++ b/meson_options.txt
@@ -0,0 +1,39 @@
+option('gstreamer',
+    type : 'combo',
+    choices : ['1.0', '0.10', 'no'],
+    description : 'Enable gstreamer support (default=1.0)')
+
+option('lz4',
+    type : 'boolean',
+    value : true,
+    description: 'Enable lz4 compression support (default=true)')
+
+option('sasl',
+    type : 'boolean',
+    value : true,
+    description : 'Use cyrus SASL authentication (default=true)')
+
+option('smartcard',
+    type : 'boolean',
+    value : true,
+    description : 'Enable smartcard support (default=true)')
+
+option('alignment-checks',
+    type : 'boolean',
+    value : false,
+    description : 'Enable runtime checks for cast alignment (default=false)')
+
+option('extra-checks',
+    type : 'boolean',
+    value: false,
+    description : 'Enable extra checks on code (default=false)')
+
+option('statistics',
+    type : 'boolean',
+    value: false,
+    description : 'Build SPICE with statistic code enabled (default=false)')
+
+option('manual',
+    type : 'boolean',
+    value : true,
+    description : 'Build SPICE manual (default=true)')
diff --git a/server/Makefile.am b/server/Makefile.am
index 2fee378f..de11cbc3 100644
--- a/server/Makefile.am
+++ b/server/Makefile.am
@@ -213,6 +213,7 @@ spice-server-enums.h: spice-server.h spice-server-enums.h.tmpl
 	$(AM_V_GEN)glib-mkenums --template $(srcdir)/spice-server-enums.h.tmpl $< > $@
 
 EXTRA_DIST =					\
+	meson.build				\
 	spice-bitmap-utils.tmpl.c		\
 	cache-item.tmpl.c			\
 	glz-encode-match.tmpl.c			\
diff --git a/server/meson.build b/server/meson.build
new file mode 100644
index 00000000..485a4f28
--- /dev/null
+++ b/server/meson.build
@@ -0,0 +1,207 @@
+spice_server_include += [include_directories('.')]
+
+#
+# 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].to_int()
+if not version_info[3].contains('git')
+  micro += 1
+endif
+micro = '@0@'.format(micro)
+cmd = run_command('printf', ['"0x%02x%02x%02x"', major, minor, micro])
+version_data = configuration_data()
+version_data.set('SPICE_SERVER_VERSION', cmd.stdout().strip())
+spice_version_h = configure_file(input : 'spice-version.h.in',
+                                 output : 'spice-version.h',
+                                 configuration : version_data)
+
+#
+# libspice-server.so
+#
+spice_server_headers = [
+  spice_version_h,
+  'spice-audio.h',
+  'spice-char.h',
+  'spice-core.h',
+  'spice-experimental.h',
+  'spice-input.h',
+  'spice-migration.h',
+  'spice-qxl.h',
+  'spice-server.h',
+  'spice-replay.h',
+  'spice.h',
+]
+
+install_headers(spice_server_headers, subdir : 'spice-server')
+
+# generate enums
+gnome = import('gnome')
+spice_server_enums = gnome.mkenums_simple('spice-server-enums',
+                                          sources : 'spice-server.h')
+
+spice_server_sources = [
+  spice_server_headers,
+  spice_server_enums,
+  'agent-msg-filter.c',
+  'agent-msg-filter.h',
+  'cache-item.h',
+  'char-device.c',
+  'char-device.h',
+  'common-graphics-channel.c',
+  'common-graphics-channel.h',
+  'cursor-channel.c',
+  'cursor-channel-client.c',
+  'cursor-channel-client.h',
+  'cursor-channel.h',
+  'dcc.c',
+  'dcc.h',
+  'dcc-private.h',
+  'dcc-send.c',
+  'demarshallers.h',
+  'dispatcher.c',
+  'dispatcher.h',
+  'display-channel.c',
+  'display-channel.h',
+  'display-channel-private.h',
+  'display-limits.h',
+  'event-loop.c',
+  'glib-compat.h',
+  'glz-encoder.c',
+  'glz-encoder-dict.c',
+  'glz-encoder-dict.h',
+  'glz-encoder.h',
+  'glz-encoder-priv.h',
+  'image-cache.c',
+  'image-cache.h',
+  'image-encoders.c',
+  'image-encoders.h',
+  'inputs-channel.c',
+  'inputs-channel-client.c',
+  'inputs-channel-client.h',
+  'inputs-channel.h',
+  'jpeg-encoder.c',
+  'jpeg-encoder.h',
+  'main-channel.c',
+  'main-channel-client.c',
+  'main-channel-client.h',
+  'main-channel.h',
+  'main-dispatcher.c',
+  'main-dispatcher.h',
+  'memslot.c',
+  'memslot.h',
+  'migration-protocol.h',
+  'mjpeg-encoder.c',
+  'net-utils.c',
+  'net-utils.h',
+  'pixmap-cache.c',
+  'pixmap-cache.h',
+  'red-channel.c',
+  'red-channel-capabilities.c',
+  'red-channel-capabilities.h',
+  'red-channel-client.c',
+  'red-channel-client.h',
+  'red-channel.h',
+  'red-client.c',
+  'red-client.h',
+  'red-common.h',
+  'red-parse-qxl.c',
+  'red-parse-qxl.h',
+  'red-pipe-item.c',
+  'red-pipe-item.h',
+  'red-qxl.c',
+  'red-qxl.h',
+  'red-record-qxl.c',
+  'red-record-qxl.h',
+  'red-replay-qxl.c',
+  'reds.c',
+  'reds.h',
+  'reds-private.h',
+  'red-stream.c',
+  'red-stream.h',
+  'red-worker.c',
+  'red-worker.h',
+  'sound.c',
+  'sound.h',
+  'spice-bitmap-utils.c',
+  'spice-bitmap-utils.h',
+  'spicevmc.c',
+  'stat-file.c',
+  'stat-file.h',
+  'stat.h',
+  'stream-channel.c',
+  'stream-channel.h',
+  'red-stream-device.c',
+  'red-stream-device.h',
+  'sw-canvas.c',
+  'tree.c',
+  'tree.h',
+  'utils.c',
+  'utils.h',
+  'video-encoder.h',
+  'video-stream.c',
+  'video-stream.h',
+  'zlib-encoder.c',
+  'zlib-encoder.h',
+]
+
+if spice_server_has_lz4 == true
+  spice_server_sources += ['lz4-encoder.c',
+                           'lz4-encoder.h']
+endif
+
+if spice_server_has_smartcard == true
+  spice_server_sources += ['smartcard.c',
+                           'smartcard.h',
+                           'smartcard-channel-client.c',
+                           'smartcard-channel-client.h']
+endif
+
+if spice_server_has_gstreamer == true
+  spice_server_sources += ['gstreamer-encoder.c']
+endif
+
+#
+# custom link_args
+#
+# TODO: Instead of relying on the output of ld, this should be handled
+#       automatically. For compiler args, there is get_supported_arguments(),
+#       but nothing for linker args currently.
+#       https://github.com/mesonbuild/meson/issues/3335
+ld_cmd = run_command('ld', '--help').stdout().strip()
+
+# Check for how to avoid indirect lib deps (--no-copy-dt-needed-entries)
+# from virt-linker-no-indirect
+if ld_cmd.contains('--no-copy-dt-needed-entries')
+  spice_server_link_args += '-Wl,--no-copy-dt-needed-entries'
+endif
+
+# Check for how to force completely read-only GOT table (relro)
+# from virt-link-relro.m4
+if ld_cmd.contains('-z relro')
+  spice_server_link_args += ['-Wl,-z', '-Wl,relro']
+endif
+
+if ld_cmd.contains('-z now')
+  spice_server_link_args += ['-Wl,-z', '-Wl,now']
+endif
+
+# version-script
+# TODO: Also should be done automatically, https://github.com/mesonbuild/meson/issues/3047
+spice_server_syms = files('spice-server.syms')
+if ld_cmd.contains('--version-script')
+  spice_server_syms_path = join_paths(meson.current_source_dir(), 'spice-server.syms')
+  spice_server_link_args += '-Wl,--version-script=@0@'.format(spice_server_syms_path)
+endif
+
+spice_server_lib = library('spice-server', spice_server_sources,
+                           version : '1.12.4',
+                           install : true,
+                           include_directories : spice_server_include,
+                           link_args : spice_server_link_args,
+                           link_depends : spice_server_syms,
+                           dependencies : spice_server_deps)
+
+subdir('tests')
diff --git a/server/tests/Makefile.am b/server/tests/Makefile.am
index ffeb8fc0..ea7074bf 100644
--- a/server/tests/Makefile.am
+++ b/server/tests/Makefile.am
@@ -4,6 +4,7 @@ NULL =
 VALGRIND_SUPPRESSIONS_FILES = $(srcdir)/valgrind/glib.supp
 EXTRA_DIST =				\
 	$(VALGRIND_SUPPRESSIONS_FILES)	\
+	meson.build			\
 	pki/ca-cert.pem			\
 	pki/server-cert.pem		\
 	pki/server-key.pem		\
diff --git a/server/tests/meson.build b/server/tests/meson.build
new file mode 100644
index 00000000..5013ae2f
--- /dev/null
+++ b/server/tests/meson.build
@@ -0,0 +1,93 @@
+test_lib_include = [spice_server_include, include_directories('.')]
+test_lib_deps = [spice_server_deps, dependency('gio-unix-2.0')]
+test_objs = spice_server_lib.extract_all_objects()
+
+test_lib_sources = [
+  'basic-event-loop.c',
+  'basic-event-loop.h',
+  'test-display-base.c',
+  'test-display-base.h',
+  'test-glib-compat.c',
+  'test-glib-compat.h',
+]
+
+##### https://github.com/mesonbuild/meson/issues/3279
+if meson.version().version_compare('< 0.46')
+  test_lib_sources += spice_server_enums
+endif
+#####
+
+test_libs = []
+test_libs += static_library('testlib', test_lib_sources,
+                            link_with: spice_server_lib,
+                            include_directories : test_lib_include,
+                            dependencies : test_lib_deps,
+                            install : false)
+
+stat_test_libs = [['1', '0', '0'], ['2', '0', '1'], ['3', '1', '0'], ['4', '1', '1']]
+foreach t : stat_test_libs
+  test_libs += static_library('testlib_stat at 0@'.format(t[0]), 'stat-test.c',
+                              c_args :  ['-DTEST_NAME=stat_test at 0@'.format(t[0]),
+                                         '-DTEST_COMPRESS_STAT=@0@'.format(t[1]),
+                                         '-DTEST_RED_WORKER_STAT=@0@'.format(t[2])],
+                              include_directories : test_lib_include,
+                              dependencies : test_lib_deps,
+                              install : false)
+endforeach
+
+tests = [
+  ['test-codecs-parsing', true],
+  ['test-options', true],
+  ['test-stat', true],
+  ['test-stream', true],
+  ['test-agent-msg-filter', true],
+  ['test-loop', true],
+  ['test-qxl-parsing', true],
+  ['test-stat-file', true],
+  ['test-leaks', true],
+  ['test-vdagent', true],
+  ['test-fail-on-null-core-interface', true],
+  ['test-empty-success', true],
+  ['test-channel', true],
+  ['test-stream-device', true],
+  ['test-listen', true],
+  ['test-display-no-ssl', false],
+  ['test-display-streaming', false],
+  ['test-playback', false],
+  ['test-display-resolution-changes', false],
+  ['test-two-servers', false],
+  ['test-display-width-stride', false],
+]
+
+if spice_server_has_sasl
+  tests += [['test-sasl', true],]
+endif
+
+if spice_server_has_gstreamer
+  tests += [['test-gst', false],]
+  if get_option('extra-checks')
+    test('video-encoders', files('video-encoders'))
+  endif
+endif
+
+foreach t : tests
+  exe = executable(t[0],
+                   sources : '@0 at .c'.format(t[0]),
+                   link_with : test_libs,
+                   include_directories : test_lib_include,
+                   c_args : ['-DSPICE_TOP_SRCDIR="@0@"'.format(meson.source_root())],
+                   dependencies : test_lib_deps,
+                   objects : test_objs,
+                   install : false)
+
+  if t[1]
+    test(t[0], exe)
+  endif
+endforeach
+
+executable('spice-server-replay',
+           sources : ['replay.c', join_paths('..', 'event-loop.c'), 'basic-event-loop.c', 'basic-event-loop.h'],
+           link_with : spice_server_lib,
+           include_directories : test_lib_include,
+           dependencies : test_lib_deps,
+           install : false)
diff --git a/subprojects/spice-common.wrap b/subprojects/spice-common.wrap
new file mode 100644
index 00000000..6117c631
--- /dev/null
+++ b/subprojects/spice-common.wrap
@@ -0,0 +1,4 @@
+[wrap-git]
+directory=spice-common
+url=https://gitlab.com/etrunko/spice-common.git
+revision=meson
diff --git a/tools/Makefile.am b/tools/Makefile.am
index 03980c5e..cfb0a213 100644
--- a/tools/Makefile.am
+++ b/tools/Makefile.am
@@ -17,3 +17,7 @@ noinst_PROGRAMS = \
 reds_stat_SOURCES = \
 	reds_stat.c \
 	$(NULL)
+
+EXTRA_DIST = \
+	meson.build \
+	$(NULL)
diff --git a/tools/meson.build b/tools/meson.build
new file mode 100644
index 00000000..1d78340b
--- /dev/null
+++ b/tools/meson.build
@@ -0,0 +1,4 @@
+executable('reds_stat', 'reds_stat.c',
+           install : false,
+           include_directories : spice_server_include,
+           dependencies : spice_server_deps)
-- 
2.14.3



More information about the Spice-devel mailing list