[v4,3/5] Add Meson build to Wayland

Submitted by Pekka Paalanen on Aug. 29, 2018, 11:33 a.m.

Details

Message ID 20180829143350.3b5bd4b5@eldfell
State Not Applicable
Headers show
Series "Series without cover letter" ( rev: 2 ) in Wayland

Not browsing as part of any series.

Commit Message

Pekka Paalanen Aug. 29, 2018, 11:33 a.m.
On Tue, 28 Aug 2018 23:19:17 +0100
Daniel Stone <daniels@collabora.com> wrote:

> From: Emmanuele Bassi <ebassi@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.
> 
> [daniels: Changed to bump version, use GitLab issues URL, remove header
>           checks not used in any code, remove pre-pkg-config Expat
> 	  support, added missing include paths to wayland-egl and
> 	  cpp-compile-test, added GitLab CI.
> 	  Bumped version, removed unnecessary pkg-config paths.]
> 
> Reviewed-by: Daniel Stone <daniels@collabora.com>
> Acked-by: Emre Ucan <eucan@de.adit-jv.com>
> Acked-by: Peter Hutterer <peter.hutterer@who-t.net>
> ---
>  .gitlab-ci.yml     |  24 +++++-
>  cursor/meson.build |  29 +++++++
>  doc/meson.build    |   5 ++
>  egl/meson.build    |  43 ++++++++++
>  meson.build        |  94 +++++++++++++++++++++
>  meson_options.txt  |  20 +++++
>  src/meson.build    | 200 +++++++++++++++++++++++++++++++++++++++++++++
>  tests/meson.build  | 180 ++++++++++++++++++++++++++++++++++++++++
>  8 files changed, 593 insertions(+), 2 deletions(-)
>  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

Hi Daniel,

I see that the doc stuff comes as follow-up. This all looks quite good,
but I had a bunch of comments below.


> diff --git a/egl/meson.build b/egl/meson.build
> new file mode 100644
> index 00000000..5ae9805e
> --- /dev/null
> +++ b/egl/meson.build
> @@ -0,0 +1,43 @@
> +wayland_egl = library(
> +  'wayland-egl',
> +  sources: [
> +    'wayland-egl.c',
> +    wayland_client_protocol_h,
> +  ],
> +  include_directories: src_inc,
> +  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),
> +  ],
> +)

Oddly enough, autotools build does run wayland-egl-abi-check during
'make check'. It comes via the variable built_test_programs. It is
explicitly assigned to check_PROGRAMS which are not run by default, so
that probably confused.

The Meson build does not run it, but I think it should.


> +
> +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,
> +)
> +
> +pkgconfig.generate(
> +  name: 'wayland-egl-backend',
> +  description: 'Backend wayland-egl library',

This should be "interface", not "library", to match autotools build.

> +  version: '3',
> +)
> diff --git a/meson.build b/meson.build
> new file mode 100644
> index 00000000..6d90625a
> --- /dev/null
> +++ b/meson.build


> +
> +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
> +endif
> +
> +expat_dep = dependency('expat', required: false)

If the scanner gets built, how will we get a nice dependency failure
for expat?

Or, if we do get that failure already, then...

> +
> +if get_option('dtd_validation')
> +  libxml2_dep = dependency('libxml-2.0')

...there is no way to build without libxml too, if dtd_validation
is disabled, because src/meson.build has:

+    dependencies: [ expat_dep, libxml2_dep, wayland_util_dep, ],


> +  config_h.set('HAVE_LIBXML', 1)
> +endif
> +


> diff --git a/src/meson.build b/src/meson.build
> new file mode 100644
> index 00000000..388ccebe
> --- /dev/null
> +++ b/src/meson.build

> +
> +  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',
> +  )
> +endif
> +
> +if get_option('libraries')
> +  mathlib_dep = cc.find_library('m', required: false)

Why not required?

> +  rt_dep = dependency('threads', required: false)

Why not required?
Does this not confuse -lrt with -pthread?

-lrt was added to ensure clock_gettime() is resolved.

> +
> +  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: [
> +      wayland_server_protocol_core_h,
> +      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, ],

Are these dependencies here actually needed?
Those libs are already linked to wayland_server, why should the user
link to those as well, or have I misunderstood how this works in Meson?

ffi, math or rt are not present in the public API or ABI of
libwayland-server as far as I recall.

> +    sources: [
> +      wayland_server_protocol_core_h,
> +      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',
> +  )
> +
> +  wayland_client = library(
> +    'wayland-client',
> +    sources: [
> +      wayland_client_protocol_core_h,
> +      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',
> +  )

Comparing autotools and meson produced files:


Could missing exec_prefix, datarootdir, and pkgdatadir cause problems?

The addition of Requires.private and Libs.private are harmless I think,
they are only used if we installed static libraries, right?

Don't mind the lib vs. lib64 difference, autotools installed into lib
and I just renamed it to lib64 to diff.


> +
> +  wayland_client_dep = declare_dependency(
> +    link_with: wayland_client,
> +    include_directories: [ root_inc, include_directories('.') ],
> +    sources: [
> +      wayland_client_protocol_core_h,
> +      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 00000000..4c737aed
> --- /dev/null
> +++ b/tests/meson.build

> +
> +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()),

Could be

'TEST_OUTPUT_DIR=' + join_paths(meson.current_build_dir(), 'output')

but I don't care about portability that much.

> +  ],
> +)
> +
> +# test name, extra sources, extra dependencies
> +tests = [


Thanks,
pq

Patch hide | download patch | download mbox

--- wayland-autotools/lib64/pkgconfig/wayland-client.pc	2018-08-29 14:03:40.625422118 +0300
+++ wayland-meson/lib64/pkgconfig/wayland-client.pc	2018-08-29 14:07:01.478089180 +0300
@@ -1,12 +1,11 @@ 
 prefix=/home/pq/install/wayland
-exec_prefix=${prefix}
-datarootdir=${prefix}/share
-pkgdatadir=${datarootdir}/wayland
-libdir=${exec_prefix}/lib
+libdir=${prefix}/lib64
 includedir=${prefix}/include
 
 Name: Wayland Client
 Description: Wayland client side library
 Version: 1.16.90
-Cflags: -I${includedir}
+Requires.private: libffi
 Libs: -L${libdir} -lwayland-client
+Libs.private: -L${libdir} -lwayland-private -lwayland-util -lm -pthread
+Cflags: -I${includedir}