[PATCH 2/4] Add Meson build to Wayland

Emmanuele Bassi ebassi at gmail.com
Mon Apr 23 13:29:16 UTC 2018


From: Emmanuele Bassi <ebassi at gnome.org>

Meson is a next generation build system, simpler than Autotools and,
more importantly, faster and more portable. While the latter
consideration is of lesser importance for Wayland, being easier to
understand and faster are pretty much key reasons to switch.

This is mostly a mechanical port of Wayland to the Meson build system.

The goal is to maintain feature parity of the Meson build with the
Autotools build, until such time when we can drop the latter.
---
 cursor/meson.build |  30 +++++++
 doc/meson.build    |   5 ++
 egl/meson.build    |  43 ++++++++++
 meson.build        | 106 +++++++++++++++++++++++
 meson_options.txt  |  20 +++++
 src/meson.build    | 203 +++++++++++++++++++++++++++++++++++++++++++++
 tests/meson.build  | 134 ++++++++++++++++++++++++++++++
 7 files changed, 541 insertions(+)
 create mode 100644 cursor/meson.build
 create mode 100644 doc/meson.build
 create mode 100644 egl/meson.build
 create mode 100644 meson.build
 create mode 100644 meson_options.txt
 create mode 100644 src/meson.build
 create mode 100644 tests/meson.build

diff --git a/cursor/meson.build b/cursor/meson.build
new file mode 100644
index 0000000..c8ed1aa
--- /dev/null
+++ b/cursor/meson.build
@@ -0,0 +1,30 @@
+icondir = get_option('icon_directory')
+if icondir == ''
+  icondir = join_paths(get_option('prefix'), get_option('datadir'), 'icons')
+endif
+
+wayland_cursor = library(
+  'wayland-cursor',
+  sources: [
+    'wayland-cursor.c',
+    'os-compatibility.c',
+    'xcursor.c',
+  ],
+  version: '0.0.0',
+  dependencies: [ wayland_client_dep ],
+  c_args: [
+    '-DICONDIR="@0@"'.format(icondir),
+  ],
+  install: true,
+)
+
+install_headers('wayland-cursor.h')
+
+pkgconfig.generate(
+  name: 'Wayland Cursor',
+  description: 'Wayland cursor helper library',
+  version: meson.project_version(),
+  libraries: wayland_cursor,
+  filebase: 'wayland-cursor',
+  install_dir: join_paths(get_option('prefix'), get_option('libdir'), 'pkgconfig'),
+)
diff --git a/doc/meson.build b/doc/meson.build
new file mode 100644
index 0000000..8c743fe
--- /dev/null
+++ b/doc/meson.build
@@ -0,0 +1,5 @@
+xsltproc = find_program('xsltproc', required: false)
+doxygen = find_program('doxygen')
+xmlto = find_program('xmlto')
+dot = find_program('dot')
+
diff --git a/egl/meson.build b/egl/meson.build
new file mode 100644
index 0000000..db5da86
--- /dev/null
+++ b/egl/meson.build
@@ -0,0 +1,43 @@
+wayland_egl = library(
+  'wayland-egl',
+  sources: [
+    'wayland-egl.c',
+  ],
+  version: '1.0.0',
+  install: true,
+)
+
+executable('wayland-egl-abi-check', 'wayland-egl-abi-check.c')
+
+nm_path = find_program('nm').path()
+
+test(
+  'wayland-egl symbols check',
+  find_program('wayland-egl-symbols-check'),
+  env: [
+    'WAYLAND_EGL_LIB=@0@'.format(wayland_egl.full_path()),
+    'NM=@0@'.format(nm_path),
+  ],
+)
+
+install_headers([
+  'wayland-egl.h',
+  'wayland-egl-core.h',
+  'wayland-egl-backend.h',
+])
+
+pkgconfig.generate(
+  name: 'wayland-egl',
+  description: 'Frontend wayland-egl library',
+  version: '18.1.0',
+  requires: 'wayland-client',
+  libraries: wayland_egl,
+  install_dir: join_paths(get_option('prefix'), get_option('libdir'), 'pkgconfig'),
+)
+
+pkgconfig.generate(
+  name: 'wayland-egl-backend',
+  description: 'Backend wayland-egl library',
+  version: '3',
+  install_dir: join_paths(get_option('prefix'), get_option('libdir'), 'pkgconfig'),
+)
diff --git a/meson.build b/meson.build
new file mode 100644
index 0000000..b37dad2
--- /dev/null
+++ b/meson.build
@@ -0,0 +1,106 @@
+project('wayland', 'c', 'cpp',
+  version: '1.15.90',
+  license: 'MIT',
+  meson_version: '>= 0.45.0',
+  default_options: [
+    'warning_level=2',
+    'buildtype=debugoptimized',
+  ])
+
+config_h = configuration_data()
+config_h.set_quoted('PACKAGE', meson.project_name())
+config_h.set_quoted('PACKAGE_NAME', meson.project_name())
+config_h.set_quoted('PACKAGE_VERSION', meson.project_version())
+config_h.set_quoted('VERSION', meson.project_version())
+config_h.set_quoted('PACKAGE_URL', 'http://wayland.freedesktop.org')
+config_h.set_quoted('PACKAGE_BUGREPORT', 'https://bugs.freedesktop.org/enter_bug.cgi?product=Wayland&component=@0@&version=@1@'.format(meson.project_name(), meson.project_version()))
+
+cc = meson.get_compiler('c')
+
+compiler_flags = cc.get_supported_arguments([
+  '-Wno-unused-parameter',
+  '-Wstrict-prototypes',
+  '-Wmissing-prototypes',
+  '-fvisibility=hidden',
+])
+
+add_project_arguments(compiler_flags, language: 'c')
+
+foreach h: [ 'sys/prctl.h', 'dlfcn.h', 'memory.h', 'sys/stat.h', 'unistd.h', ]
+  config_h.set('HAVE_' + h.underscorify().to_upper(), cc.has_header(h))
+endforeach
+
+foreach f: [ 'accept4', 'mkostemp', 'posix_fallocate', 'prctl', ]
+  config_h.set('HAVE_' + f.underscorify().to_upper(), cc.has_function(f))
+endforeach
+
+if get_option('libraries')
+  ffi_dep = dependency('libffi')
+
+  decls = [
+    [ 'sys/signalfd.h', 'SFD_CLOEXEC' ],
+    [ 'sys/timerfd.h', 'TFD_CLOEXEC' ],
+    [ 'time.h', 'CLOCK_MONOTONIC' ],
+  ]
+
+  foreach d: decls
+    if not cc.has_header_symbol(d[0], d[1])
+      error('@0@ is needed to compile wayland libraries'.format(d[1]))
+    endif
+  endforeach
+
+  config_h.set('HAVE_EXECINFO_H', cc.has_header('execinfo.h'))
+endif
+
+expat_dep = dependency('expat', required: false)
+if not expat_dep.found()
+  if not cc.has_header('expat.h')
+    error('Cannot find expat.h header. Please install expat')
+  endif
+
+  expat_dep = cc.find_library('expat')
+  if not cc.has_function('XML_ParserCreate', dependencies: expat_dep)
+    error('Cannot find expat library. Please install expat')
+  endif
+endif
+
+if get_option('dtd_validation')
+  libxml2_dep = dependency('libxml-2.0')
+  config_h.set('HAVE_LIBXML', 1)
+endif
+
+configure_file(
+  output: 'config.h',
+  configuration: config_h,
+)
+
+add_project_arguments([ '-DHAVE_CONFIG_H' ], language: 'c')
+
+pkgconfig = import('pkgconfig')
+
+root_inc = include_directories('.')
+protocol_inc = include_directories('protocol')
+src_inc = include_directories('src')
+
+subdir('src')
+
+if get_option('libraries')
+  subdir('cursor')
+  subdir('egl')
+  subdir('tests')
+endif
+
+if get_option('documentation')
+  subdir('doc')
+endif
+
+install_data([
+  'wayland-scanner.mk',
+  'protocol/wayland.xml',
+  'protocol/wayland.dtd',
+])
+
+install_data(
+  [ 'wayland-scanner.m4' ],
+  install_dir: join_paths(get_option('prefix'), get_option('datadir'), 'aclocal'),
+)
diff --git a/meson_options.txt b/meson_options.txt
new file mode 100644
index 0000000..78e9f9f
--- /dev/null
+++ b/meson_options.txt
@@ -0,0 +1,20 @@
+option('libraries',
+  description: 'Compile Wayland libraries',
+  type: 'boolean',
+  value: 'true')
+option('host_scanner',
+  description: 'Use wayland-scanner from PATH during build',
+  type: 'boolean',
+  value: 'false')
+option('documentation',
+  description: 'Build the documentation (requires Doxygen)',
+  type: 'boolean',
+  value: 'true')
+option('dtd_validation',
+  description: 'Validate the protocol DTD (requires libxml2)',
+  type: 'boolean',
+  value: 'true')
+option('icon_directory',
+  description: 'Location used to look for cursors (defaults to ${datadir}/icons if unset)',
+  type: 'string',
+  value: '')
diff --git a/src/meson.build b/src/meson.build
new file mode 100644
index 0000000..376ba9a
--- /dev/null
+++ b/src/meson.build
@@ -0,0 +1,203 @@
+wayland_version = meson.project_version().split('.')
+wayland_version_h = configuration_data()
+wayland_version_h.set('WAYLAND_VERSION', meson.project_version())
+wayland_version_h.set('WAYLAND_VERSION_MAJOR', wayland_version[0].to_int())
+wayland_version_h.set('WAYLAND_VERSION_MINOR', wayland_version[1].to_int())
+wayland_version_h.set('WAYLAND_VERSION_MICRO', wayland_version[2].to_int())
+configure_file(
+  input: 'wayland-version.h.in',
+  output: 'wayland-version.h',
+  configuration: wayland_version_h,
+  install: true,
+  install_dir: join_paths(get_option('prefix'), get_option('includedir')),
+)
+
+wayland_util = static_library(
+  'wayland-util',
+  sources: 'wayland-util.c',
+)
+
+wayland_util_dep = declare_dependency(
+  link_with: wayland_util,
+  include_directories: include_directories('.'),
+)
+
+if get_option('host_scanner')
+  wayland_scanner = find_program('wayland-scanner')
+  wayland_scanner_code_arg = 'code'
+else
+  configure_file(
+    input: '../protocol/wayland.dtd',
+    output: 'wayland.dtd.embed',
+    configuration: configuration_data(),
+  )
+
+  wayland_scanner = executable(
+    'wayland-scanner',
+    'scanner.c',
+    'dtddata.S',
+    include_directories: [ root_inc, protocol_inc ],
+    dependencies: [ expat_dep, libxml2_dep, wayland_util_dep, ],
+    install: true,
+  )
+  wayland_scanner_code_arg = 'public-code'
+
+  pkgconfig.generate(
+    name: 'Wayland Scanner',
+    description: 'Wayland scanner',
+    version: meson.project_version(),
+    variables: [
+      'bindir=${prefix}/@0@'.format(get_option('bindir')),
+      'datarootdir=${prefix}/@0@'.format(get_option('datadir')),
+      'pkgdatadir=${prefix}/@0@/@1@'.format(get_option('datadir'), meson.project_name()),
+      'wayland_scanner=${bindir}/wayland-scanner',
+    ],
+    filebase: 'wayland-scanner',
+    install_dir: join_paths(get_option('prefix'), get_option('libdir'), 'pkgconfig'),
+  )
+endif
+
+if get_option('libraries')
+  mathlib_dep = cc.find_library('m', required: false)
+  rt_dep = dependency('threads', required: false)
+
+  wayland_protocol_xml = files('../protocol/wayland.xml')
+
+  wayland_private = static_library(
+    'wayland-private',
+    sources: [
+      'connection.c',
+      'wayland-os.c',
+    ],
+    dependencies: [ ffi_dep, ],
+  )
+
+  wayland_private_dep = declare_dependency(
+    link_with: wayland_private,
+    include_directories: include_directories('.'),
+  )
+
+  generated_headers = [
+    [ 'server header', ['server-header'], 'wayland-server-protocol.h', true, ],
+    [ 'core server header', ['server-header', '-c'], 'wayland-server-protocol-core.h', false, ],
+    [ 'client header', ['client-header'], 'wayland-client-protocol.h', true, ],
+    [ 'core client header', ['client-header', '-c'], 'wayland-client-protocol-core.h', false, ],
+  ]
+
+  foreach gen: generated_headers
+    target_name = gen[0]
+    scanner_args = gen[1]
+    output_file = gen[2]
+    install_file = gen[3]
+    install_dir = join_paths(get_option('prefix'), get_option('includedir'))
+    var_name = output_file.underscorify()
+
+    target = custom_target(
+      target_name,
+      command: [
+        wayland_scanner, scanner_args, '@INPUT@', '@OUTPUT@',
+      ],
+      input: wayland_protocol_xml,
+      output: output_file,
+      install: install_file,
+      install_dir: install_dir,
+    )
+
+    set_variable(var_name, target)
+  endforeach
+
+  wayland_protocol_c = custom_target('protocol source',
+    command: [
+      wayland_scanner, wayland_scanner_code_arg, '@INPUT@', '@OUTPUT@',
+    ],
+    input: wayland_protocol_xml,
+    output: 'wayland-protocol.c',
+  )
+
+  wayland_server = library(
+    'wayland-server',
+    sources: [
+      get_variable('wayland_server_protocol_core_h'),
+      get_variable('wayland_server_protocol_h'),
+      wayland_protocol_c,
+      'wayland-server.c',
+      'wayland-shm.c',
+      'event-loop.c',
+    ],
+    version: '0.1.0',
+    dependencies: [
+      ffi_dep,
+      wayland_private_dep,
+      wayland_util_dep,
+      mathlib_dep,
+      rt_dep,
+    ],
+    include_directories: root_inc,
+    install: true,
+  )
+
+  wayland_server_dep = declare_dependency(
+    link_with: wayland_server,
+    include_directories: [ root_inc, include_directories('.') ],
+    dependencies: [ ffi_dep, mathlib_dep, rt_dep, ],
+    sources: [
+      get_variable('wayland_server_protocol_core_h'),
+      get_variable('wayland_server_protocol_h'),
+    ],
+  )
+
+  pkgconfig.generate(
+    name: 'Wayland Server',
+    description: 'Server side implementation of the Wayland protocol',
+    version: meson.project_version(),
+    libraries: wayland_server,
+    filebase: 'wayland-server',
+    install_dir: join_paths(get_option('prefix'), get_option('libdir'), 'pkgconfig'),
+  )
+
+  wayland_client = library(
+    'wayland-client',
+    sources: [
+      get_variable('wayland_client_protocol_core_h'),
+      get_variable('wayland_client_protocol_h'),
+      wayland_protocol_c,
+      'wayland-client.c',
+    ],
+    version: '0.3.0',
+    dependencies: [
+      ffi_dep,
+      wayland_private_dep,
+      wayland_util_dep,
+      mathlib_dep,
+      rt_dep,
+    ],
+    include_directories: root_inc,
+    install: true,
+  )
+
+  pkgconfig.generate(
+    name: 'Wayland Client',
+    description: 'Wayland client side library',
+    version: meson.project_version(),
+    libraries: wayland_client,
+    filebase: 'wayland-client',
+    install_dir: join_paths(get_option('prefix'), get_option('libdir'), 'pkgconfig'),
+  )
+
+  wayland_client_dep = declare_dependency(
+    link_with: wayland_client,
+    include_directories: [ root_inc, include_directories('.') ],
+    sources: [
+      get_variable('wayland_client_protocol_core_h'),
+      get_variable('wayland_client_protocol_h'),
+    ],
+  )
+
+  install_headers([
+    'wayland-util.h',
+    'wayland-server.h',
+    'wayland-server-core.h',
+    'wayland-client.h',
+    'wayland-client-core.h',
+  ])
+endif
diff --git a/tests/meson.build b/tests/meson.build
new file mode 100644
index 0000000..5bf723a
--- /dev/null
+++ b/tests/meson.build
@@ -0,0 +1,134 @@
+test_runner = static_library(
+  'test-runner',
+  sources: [
+    'test-runner.c',
+    'test-helpers.c',
+    'test-compositor.c',
+  ],
+  include_directories: [ root_inc, src_inc ],
+  dependencies: [
+    cc.find_library('dl', required: false),
+    dependency('threads'),
+    ffi_dep,
+    wayland_util_dep,
+    wayland_private_dep,
+    wayland_client_dep,
+    wayland_server_dep,
+  ],
+)
+
+test_runner_dep = declare_dependency(
+  link_with: test_runner,
+  include_directories: [ src_inc ],
+  dependencies: [
+    dependency('threads'),
+    cc.find_library('dl', required: false),
+  ],
+)
+
+tests_protocol_xml = files('../protocol/tests.xml')
+
+tests_server_protocol_h = custom_target(
+  'test server protocol header',
+  command: [ wayland_scanner, 'server-header', '@INPUT@', '@OUTPUT@' ],
+  input: tests_protocol_xml,
+  output: 'tests-server-protocol.h',
+)
+
+tests_client_protocol_c = custom_target(
+  'test client protocol header',
+  command: [ wayland_scanner, 'client-header', '@INPUT@', '@OUTPUT@' ],
+  input: tests_protocol_xml,
+  output: 'tests-client-protocol.h',
+)
+
+tests_protocol_c = custom_target(
+  'test protocol source',
+  command: [ wayland_scanner, wayland_scanner_code_arg, '@INPUT@', '@OUTPUT@' ],
+  input: tests_protocol_xml,
+  output: 'tests-protocol.c',
+)
+
+benchmark(
+  'fixed-benchmark',
+  executable(
+    'fixed-benchmark',
+    'fixed-benchmark.c',
+    dependencies: test_runner_dep,
+  ),
+)
+
+executable(
+  'exec-fd-leak-checker',
+  'exec-fd-leak-checker.c',
+  dependencies: test_runner_dep,
+)
+
+test(
+  'cpp-compile-test',
+  executable('cpp-compile-test', 'cpp-compile-test.cpp'),
+)
+
+sed_path = find_program('sed').path()
+
+test(
+  'scanner-test',
+  find_program('scanner-test.sh'),
+  env: [
+    'TEST_DATA_DIR=@0@/data'.format(meson.current_source_dir()),
+    'TEST_OUTPUT_DIR=@0@/output'.format(meson.current_build_dir()),
+    'SED=@0@'.format(sed_path),
+    'WAYLAND_SCANNER=@0@'.format(wayland_scanner.full_path()),
+  ],
+)
+
+# test name, extra sources, extra dependencies
+tests = [
+  [ 'array-test' ],
+  [ 'client-test' ],
+  [ 'display-test', [
+      tests_server_protocol_h,
+      tests_client_protocol_c,
+      tests_protocol_c,
+    ],
+  ],
+  [ 'connection-test' ],
+  [ 'event-loop-test' ],
+  [ 'fixed-test' ],
+  [ 'interface-test' ],
+  [ 'list-test' ],
+  [ 'map-test' ],
+  [ 'sanity-test' ],
+  [ 'socket-test' ],
+  [ 'queue-test' ],
+  [ 'signal-test' ],
+  [ 'newsignal-test', [
+      files('../src/wayland-server.c'),
+    ],
+  ],
+  [ 'resources-test' ],
+  [ 'message-test' ],
+  [ 'compositor-introspection-test' ],
+  [ 'protocol-logger-test' ],
+  [ 'headers-test', [
+      'headers-protocol-test.c',
+      'headers-protocol-core-test.c',
+      get_variable('wayland_server_protocol_core_h'),
+      get_variable('wayland_client_protocol_core_h'),
+    ],
+  ],
+  [ 'os-wrappers-test' ],
+]
+
+foreach t: tests
+  t_name = t.get(0)
+  t_sources = [ t_name + '.c' ] + t.get(1, [])
+  t_deps = [test_runner_dep] + t.get(2, [])
+  bin = executable(t_name, t_sources, dependencies: t_deps)
+  test(t_name, bin,
+    env: [
+      'TEST_SRC_DIR=@0@'.format(meson.current_source_dir()),
+      'TEST_BUILD_DIR=@0@'.format(meson.current_build_dir()),
+    ],
+  )
+endforeach
-- 
2.17.0



More information about the wayland-devel mailing list