diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 24896659..c665ef6b 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -9,10 +9,11 @@ before_script: - echo '#!/bin/sh' > /usr/sbin/policy-rc.d - echo 'exit 101' >> /usr/sbin/policy-rc.d - chmod +x /usr/sbin/policy-rc.d + - echo 'deb http://deb.debian.org/debian stretch-backports main' >> /etc/apt/sources.list - apt-get update - - apt-get -y --no-install-recommends install build-essential automake autoconf libtool pkg-config libexpat1-dev libffi-dev libxml2-dev doxygen graphviz xmlto xsltproc docbook-xsl + - apt-get -y --no-install-recommends install build-essential automake autoconf libtool pkg-config libexpat1-dev libffi-dev libxml2-dev doxygen graphviz xmlto xsltproc docbook-xsl meson/stretch-backports -build-native: +build-native-autotools: stage: build script: - export BUILD_ID="wayland-$CI_JOB_NAME_$CI_COMMIT_SHA-$CI_JOB_ID" @@ -34,3 +35,21 @@ build-native: - build-*/wayland*/_build/sub/*.log - build-*/*.log - prefix-* + +build-native-meson: + stage: build + script: + - export BUILD_ID="wayland-$CI_JOB_NAME_$CI_COMMIT_SHA-$CI_JOB_ID" + - export PREFIX="$(pwd)/prefix-$BUILD_ID" + - export BUILDDIR="$(pwd)/build-$BUILD_ID" + - mkdir "$BUILDDIR" "$PREFIX" + - cd "$BUILDDIR" + - meson --prefix="$PREFIX" -Dicon_directory=/usr/share/X11/icons .. + - ninja -k0 test + - ninja clean + artifacts: + name: wayland-meson-$CI_COMMIT_SHA-$CI_JOB_ID + when: always + paths: + - build-meson/meson-logs + - prefix-* diff --git a/cursor/meson.build b/cursor/meson.build new file mode 100644 index 00000000..ae85ed9b --- /dev/null +++ b/cursor/meson.build @@ -0,0 +1,27 @@ +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', +) diff --git a/doc/doxygen/.gitignore b/doc/doxygen/.gitignore index a85e6c0d..d68d6fce 100644 --- a/doc/doxygen/.gitignore +++ b/doc/doxygen/.gitignore @@ -1,4 +1,3 @@ doxygen_sqlite3.db html/ wayland.doxygen -xml/ diff --git a/doc/doxygen/gen-doxygen.py b/doc/doxygen/gen-doxygen.py new file mode 100755 index 00000000..1bb07e57 --- /dev/null +++ b/doc/doxygen/gen-doxygen.py @@ -0,0 +1,105 @@ +#!/usr/bin/env python3 + +import argparse +import datetime +import errno +import os +import subprocess +import sys + +# Custom configuration for each documentation format +doxygen_templates = { + 'xml': [ + 'GENERATE_XML=YES\n', + 'XML_OUTPUT={format}/{section}\n', + 'INPUT= {files}\n', + ], + 'html': [ + 'GENERATE_HTML=YES\n', + 'HTML_OUTPUT={format}/{section}\n', + 'PROJECT_NAME=\"Wayland {section} API\"\n', + 'INPUT= {files}\n', + ], + 'man': [ + 'GENERATE_MAN=YES\n', + 'MAN_OUTPUT={format}\n', + 'MAN_SUBDIR=.\n', + 'JAVADOC_AUTOBRIEF=NO\n', + 'INPUT= {files}\n', + ], +} + +def load_doxygen_file(doxyfile): + with open(doxyfile, 'r') as f: + res = f.readlines() + return res + +def get_template(outformat): + for (k,v) in doxygen_templates.items(): + if outformat.startswith(k): + return v + +def gen_doxygen_file(data, outformat, section, files): + for l in get_template(outformat): + data.append(l.format(format=outformat, section=section, files=' '.join(files))) + return data + +parser = argparse.ArgumentParser(description='Generate docs with Doxygen') +parser.add_argument('doxygen_file', + help='The doxygen file to use') +parser.add_argument('files', + help='The list of files to parse', + metavar='FILES', + nargs='+') +parser.add_argument('--builddir', + help='The build directory', + metavar='DIR', + default='.') +parser.add_argument('--section', + help='The section to build', + metavar='NAME', + default='Client') +parser.add_argument('--output-format', + help='The output format: xml, html, man', + metavar='FORMAT', + default='xml') +parser.add_argument('--stamp', + help='Stamp file to output', + metavar='STAMP_FILE', + nargs='?', + type=argparse.FileType('w')) + +args = parser.parse_args() + +# Merge the doxyfile with our custom templates +conf = load_doxygen_file(args.doxygen_file) +conf = gen_doxygen_file(conf, args.output_format, args.section, args.files) + +# Doxygen is not clever enough to create the directories it +# needs beforehand +try: + os.makedirs(os.path.join(args.builddir, args.output_format)) +except OSError as e: + if e.errno != errno.EEXIST: + raise e + +# Run Doxygen with the generated doxyfile +cmd = subprocess.Popen(['doxygen', '-'], stdin=subprocess.PIPE) +cmd.stdin.write(''.join(conf).encode('utf-8')) +cmd.stdin.close() +if cmd.wait() != 0: + sys.exit(1) + +# This is a bit of a hack; Doxygen will generate way more files than we +# want to install, but there's no way to know how many at configuration +# time. Since we want to install only the wl_* man pages anyway, we can +# delete the other files and let Meson install the whole man3 subdirectory +if args.output_format.startswith('man'): + manpath = os.path.join(args.builddir, args.output_format) + for filename in os.listdir(manpath): + full_path = os.path.join(manpath, filename) + if not filename.startswith('wl_'): + os.remove(full_path) + +if args.stamp: + args.stamp.write(str(datetime.datetime.now())) diff --git a/doc/doxygen/meson.build b/doc/doxygen/meson.build new file mode 100644 index 00000000..c39b2826 --- /dev/null +++ b/doc/doxygen/meson.build @@ -0,0 +1,105 @@ +# Here be dragons + +dot_gv = { + 'wayland-architecture': files('dot/wayland-architecture.gv'), + 'x-architecture': files('dot/x-architecture.gv'), +} + +# This is a workaround for Meson's custom_target() directive, which +# currently does not support outputs pointing to a sub-directory +# XXX: try turning these into maps, so they can be indexed with picture name +dot_png = [] +dot_map = [] + +doxygen_conf = configuration_data() +doxygen_conf.set('VERSION', meson.project_version()) +doxygen_conf.set('top_builddir', meson.build_root()) +wayland_doxygen = configure_file( + input: 'wayland.doxygen.in', + output: 'wayland.doxygen', + configuration: doxygen_conf, +) + +shared_files = files([ + '../../src/wayland-util.h', +]) + +client_files = files([ + '../../src/wayland-client.c', + '../../src/wayland-client.h', + '../../src/wayland-client-core.h', +]) + +server_files = files([ + '../../src/event-loop.c', + '../../src/wayland-server.c', + '../../src/wayland-server.h', + '../../src/wayland-server-core.h', + '../../src/wayland-shm.c', +]) + +extra_client_files = [ + 'mainpage.dox', + wayland_client_protocol_h, +] + +extra_server_files = [ + 'mainpage.dox', + wayland_server_protocol_h, +] + +gen_doxygen = find_program('gen-doxygen.py') + +subdir('xml') + +formats = { + 'html': { + 'Client': shared_files + client_files + extra_client_files, + 'Server': shared_files + server_files + extra_server_files, + }, +} + +foreach f_name, sections: formats + foreach s_name, s_files: sections + t_name = '@0@-@1@-doc'.format(f_name, s_name) + + # We do not really need an output file, but Meson + # will complain if one is not set, so we use a + # dummy 'stamp' file + custom_target( + t_name, + command: [ + gen_doxygen, + # XXX pass doxygen path as argument + '--builddir=@OUTDIR@', + '--section=@0@'.format(s_name), + '--output-format=@0@'.format(f_name), + '--stamp=doc/doxygen/@0@.stamp'.format(t_name), + wayland_doxygen, + '@INPUT@', + ], + input: s_files, + output: '@0@.stamp'.format(t_name), + depends: [dot_png, dot_map], + build_by_default: true, + ) + endforeach +endforeach + +man_files = shared_files + server_files + client_files +custom_target( + 'man-pages-3', + command: [ + gen_doxygen, + '--builddir=@OUTDIR@', + '--output-format=man3', + '--stamp=doc/doxygen/man3.stamp', + wayland_doxygen, + '@INPUT@', + ], + input: man_files, + output: 'man3', + build_by_default: true, + install: true, + install_dir: join_paths(get_option('prefix'), get_option('mandir')), +) diff --git a/doc/doxygen/xml/Client/meson.build b/doc/doxygen/xml/Client/meson.build new file mode 100644 index 00000000..849c30da --- /dev/null +++ b/doc/doxygen/xml/Client/meson.build @@ -0,0 +1,18 @@ +tgt = custom_target( + 'xml-Client-doc', + command: [ + gen_doxygen, + # XXX pass doxygen path as argument + '--builddir=@OUTDIR@', + '--section=Client', + '--output-format=xml', + wayland_doxygen, + '@INPUT@', + ], + input: [ shared_files, client_files ], + output: [ 'combine.xslt', 'index.xml' ], + depends: [dot_png, dot_map] +) + +doxygen_Client_combine_xslt = tgt[0] +doxygen_Client_index_xml = tgt[1] diff --git a/doc/doxygen/xml/Server/meson.build b/doc/doxygen/xml/Server/meson.build new file mode 100644 index 00000000..4792c1bc --- /dev/null +++ b/doc/doxygen/xml/Server/meson.build @@ -0,0 +1,18 @@ +tgt = custom_target( + 'xml-Server-doc', + command: [ + gen_doxygen, + # XXX pass doxygen path as argument + '--builddir=@OUTDIR@', + '--section=Server', + '--output-format=xml', + wayland_doxygen, + '@INPUT@', + ], + input: [ shared_files, server_files ], + output: [ 'combine.xslt', 'index.xml' ], + depends: [dot_png, dot_map] +) + +doxygen_Server_combine_xslt = tgt[0] +doxygen_Server_index_xml = tgt[1] diff --git a/doc/doxygen/xml/meson.build b/doc/doxygen/xml/meson.build new file mode 100644 index 00000000..6d55c53a --- /dev/null +++ b/doc/doxygen/xml/meson.build @@ -0,0 +1,22 @@ +# dot_png: list of PNG targets +# dot_map: list of MAP targets +foreach name, infile: dot_gv + dot_png += custom_target( + name + '.png', + command: [ dot, '-Tpng', '-o@OUTPUT@', '@INPUT@' ], + input: infile, + output: name + '.png', + install: true, + install_dir: join_paths(publican_install_prefix, publican_html_dir, 'images') + ) + + dot_map += custom_target( + name + '.map', + command: [ dot, '-Tcmapx_np', '-o@OUTPUT@', '@INPUT@' ], + input: infile, + output: name + '.map', + ) +endforeach + +subdir('Client') +subdir('Server') diff --git a/doc/man/meson.build b/doc/man/meson.build new file mode 100644 index 00000000..0fd4cec7 --- /dev/null +++ b/doc/man/meson.build @@ -0,0 +1,46 @@ +man_pages = [ + { + 'section': '3', + 'xml': 'wl_display_connect.xml', + 'name': 'wl_display_connect', + 'alias': 'wl_display_connect_to_fd', + } +] + +xsltproc_opts = [ + '--nonet', + '--stringparam', 'man.authors.section.enabled', '0', + '--stringparam', 'man.copyright.section.enabled', '0', + '--stringparam', 'funcsynopsis.style', 'ansi', + '--stringparam', 'man.output.quietly', '1', +] + +foreach page: man_pages + section_number = page['section'] + xml_input = page['xml'] + name = page['name'] + alias = page.get('alias', '') + + man_output = name + '.' + section_number + if alias != '' + alias_output = alias + '.' + section_number + else + alias_output = [] + endif + + man_page = custom_target( + name + '-man', + command: [ + xsltproc, + xsltproc_opts, + '-o', '@OUTPUT0@', + manpage_xsl, + '@INPUT@', + ], + input: xml_input, + output: [ man_output, alias_output ], + install: true, + install_dir: join_paths(get_option('prefix'), get_option('mandir'), 'man' + section_number), + build_by_default: true, + ) +endforeach diff --git a/doc/meson.build b/doc/meson.build new file mode 100644 index 00000000..0b46f48c --- /dev/null +++ b/doc/meson.build @@ -0,0 +1,38 @@ +dot = find_program('dot') +doxygen = find_program('doxygen') +xsltproc = find_program('xsltproc') +xmlto = find_program('xmlto') + +cmd = run_command(doxygen, '--version', check: true) +message('doxygen: ' + cmd.stdout().strip()) +vers = cmd.stdout().strip() +if vers.version_compare('< 1.6.0') + error('Doxygen 1.6 or later is required for building documentation, found @0@.'.format(vers)) +endif + +cmd = run_command(dot, '-V', check: true) +message('dot: ' + cmd.stderr().strip()) +vers = cmd.stderr().split('version')[1].strip().split(' ')[0] +if vers.version_compare('< 2.26.0') + error('Dot (Graphviz) 2.26 or later is required for building documentation, found @0@.'.format(vers)) +endif + +manpage_xsl = 'http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl' +cmd = run_command(xsltproc, '--nonet', manpage_xsl) +if cmd.returncode() != 0 + error('The style sheet for man pages providing "@0@" was not found.'.format(manpage_xsl)) +endif + +publican_install_prefix = join_paths( + get_option('prefix'), + get_option('datadir'), + 'doc', + meson.project_name(), + 'Wayland', 'en-US' +) + +publican_html_dir = 'html' + +subdir('doxygen') +subdir('man') +subdir('publican') diff --git a/doc/publican/meson.build b/doc/publican/meson.build new file mode 100644 index 00000000..898ca4fc --- /dev/null +++ b/doc/publican/meson.build @@ -0,0 +1,30 @@ +merge_mapcoords_xsl = files('merge-mapcoords.xsl') + +subdir('sources') + +custom_target( + 'Wayland-docbook-html', + command: [ + xmlto, + '--skip-validation', + '--stringparam', 'chunk.section.depth=0', + '--stringparam', 'toc.section.depth=1', + '--stringparam', 'html.stylesheet=css/default.css', + '-o', '@OUTPUT@', + 'html', + '@INPUT@' + ], + input: publican_processed_main, + output: publican_html_dir, + depend_files: publican_copied_sources, + depends: [ + publican_processed_targets, + ClientAPI_xml, + ServerAPI_xml, + ProtocolSpec_xml, + ProtocolInterfaces_xml + ], + build_by_default: true, + install: true, + install_dir: publican_install_prefix +) diff --git a/doc/publican/sources/meson.build b/doc/publican/sources/meson.build new file mode 100644 index 00000000..52f3a681 --- /dev/null +++ b/doc/publican/sources/meson.build @@ -0,0 +1,113 @@ +ProtocolSpec_xml = custom_target( + 'ProtocolSpec.xml', + command: [ xsltproc, '-o', '@OUTPUT@', files('../protocol-to-docbook.xsl'), '@INPUT@' ], + input: wayland_protocol_xml, + output: 'ProtocolSpec.xml' +) + +ProtocolInterfaces_xml = custom_target( + 'ProtocolInterfaces.xml', + command: [ xsltproc, '-o', '@OUTPUT@', files('../protocol-interfaces-to-docbook.xsl'), '@INPUT@' ], + input: wayland_protocol_xml, + output: 'ProtocolInterfaces.xml' +) + +ClientAPI_combined = custom_target( + 'ClientAPI-combined', + command: [ xsltproc, '-o', '@OUTPUT@', '@INPUT@' ], + input: [ doxygen_Client_combine_xslt, doxygen_Client_index_xml ], + output: 'ClientAPI-combined.xml' +) + +to_publican_xsl = files('../doxygen-to-publican.xsl') + +ClientAPI_xml = custom_target( + 'ClientAPI.xml', + command: [ xsltproc, '-o', '@OUTPUT@', '--stringparam', 'which', 'Client', to_publican_xsl, '@INPUT@' ], + input: ClientAPI_combined, + output: 'ClientAPI.xml' +) + +ServerAPI_combined = custom_target( + 'ServerAPI-combined', + command: [ xsltproc, '-o', '@OUTPUT@', '@INPUT@' ], + input: [ doxygen_Server_combine_xslt, doxygen_Server_index_xml ], + output: 'ServerAPI-combined.xml' +) + +ServerAPI_xml = custom_target( + 'ServerAPI.xml', + command: [ xsltproc, '-o', '@OUTPUT@', '--stringparam', 'which', 'Server', to_publican_xsl, '@INPUT@' ], + input: ServerAPI_combined, + output: 'ServerAPI.xml' +) + + +publican_sources = [ + 'Wayland.ent', + # 'Wayland.xml', # handled specially + 'Book_Info.xml', + 'Author_Group.xml', + 'Foreword.xml', + 'Preface.xml', + 'Revision_History.xml', + 'Protocol.xml', + 'Xwayland.xml', + 'Compositors.xml', + 'Client.xml', + 'Server.xml' +] + +publican_processed_main = configure_file( + input: 'Wayland.xml', + output: 'Wayland.xml', + copy: true +) + +publican_copied_sources = [] +foreach src: publican_sources + publican_copied_sources += configure_file( + input: src, + output: src, + copy: true + ) +endforeach + +publican_processed_sources = [ + 'Architecture.xml', + 'Introduction.xml' +] + +publican_processed_targets = [] +foreach src: publican_processed_sources + publican_processed_targets += custom_target( + src, + command: [ xsltproc, '-o', '@OUTPUT@', '--stringparam', 'basedir', '.', merge_mapcoords_xsl, '@INPUT@' ], + input: src, + output: src + ) +endforeach + +publican_css_sources = files([ + 'css/brand.css', + 'css/common.css', + 'css/default.css', + 'css/epub.css', + 'css/print.css' +]) + +install_data( + publican_css_sources, + install_dir: join_paths(publican_install_prefix, publican_html_dir, 'css') +) + +publican_img_sources = files([ + 'images/icon.svg', + 'images/wayland.png', + 'images/xwayland-architecture.png' +]) + +install_data( + publican_img_sources, + install_dir: join_paths(publican_install_prefix, publican_html_dir, 'images') +) diff --git a/egl/meson.build b/egl/meson.build new file mode 100644 index 00000000..dee9b1dd --- /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) + ] +) + +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 interface', + version: '3' +) diff --git a/meson.build b/meson.build new file mode 100644 index 00000000..be2129cf --- /dev/null +++ b/meson.build @@ -0,0 +1,104 @@ +project( + 'wayland', 'c', 'cpp', + version: '1.17.90', + license: 'MIT', + meson_version: '>= 0.47.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_VERSION', meson.project_version()) + +compiler_flags = [ + '-Wno-unused-parameter', + '-Wstrict-prototypes', + '-Wmissing-prototypes', + '-fvisibility=hidden', +] + +cc = meson.get_compiler('c') +add_project_arguments( + cc.get_supported_arguments(compiler_flags), + language: 'c' +) + +foreach h: [ 'sys/prctl.h' ] + config_h.set('HAVE_' + h.underscorify().to_upper(), cc.has_header(h)) +endforeach + +have_funcs = [ + 'accept4', + 'mkostemp', + 'posix_fallocate', + 'prctl', + 'memfd_create', + 'strndup', +] +foreach f: have_funcs + config_h.set('HAVE_' + f.underscorify().to_upper(), cc.has_function(f)) +endforeach + +if get_option('libraries') + ffi_dep = dependency('libffi') + + decls = [ + { 'header': 'sys/signalfd.h', 'symbol': 'SFD_CLOEXEC' }, + { 'header': 'sys/timerfd.h', 'symbol': 'TFD_CLOEXEC' }, + { 'header': 'time.h', 'symbol': 'CLOCK_MONOTONIC' }, + ] + + foreach d: decls + if not cc.has_header_symbol(d['header'], d['symbol']) + error('@0@ is needed to compile Wayland libraries'.format(d['symbol'])) + endif + endforeach +endif + +scanner_deps = [ dependency('expat') ] + +if get_option('dtd_validation') + scanner_deps += 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') + +wayland_protocol_xml = files('protocol/wayland.xml') + +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 00000000..76314f79 --- /dev/null +++ b/meson_options.txt @@ -0,0 +1,16 @@ +option('libraries', + description: 'Compile Wayland libraries', + type: 'boolean', + value: 'true') +option('documentation', + description: 'Build the documentation (requires Doxygen, dot, xmlto, xsltproc)', + 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 00000000..26e52693 --- /dev/null +++ b/src/meson.build @@ -0,0 +1,228 @@ +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_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('.') +) + +# wayland-scanner + +configure_file( + input: '../protocol/wayland.dtd', + output: 'wayland.dtd.embed', + copy: true +) + +wayland_scanner_sources = [ 'scanner.c', 'dtddata.S' ] +wayland_scanner_includes = [ root_inc, protocol_inc ] + +wayland_scanner = executable( + 'wayland-scanner', + wayland_scanner_sources, + c_args: [ '-include', 'config.h' ], + include_directories: wayland_scanner_includes, + dependencies: [ scanner_deps, wayland_util_dep, ], + install: true +) + +pkgconfig.generate( + name: 'Wayland Scanner', + description: 'Wayland scanner', + version: meson.project_version(), + variables: [ + 'datarootdir=' + join_paths('${prefix}', get_option('datadir')), + 'pkgdatadir=' + join_paths('${datarootdir}', meson.project_name()), + 'bindir=' + join_paths('${prefix}', get_option('bindir')), + 'wayland_scanner=${bindir}/wayland-scanner' + ], + filebase: 'wayland-scanner' +) + +if meson.is_cross_build() + scanner_dep = dependency('wayland-scanner', native: true) + wayland_scanner_for_build = find_program(scanner_dep.get_pkgconfig_variable('wayland_scanner')) +else + wayland_scanner_for_build = wayland_scanner +endif + +if get_option('libraries') + mathlib_dep = cc.find_library('m', required: false) + threads_dep = dependency('threads', required: false) + + 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 = [ + { + 'scanner_args': ['server-header'], + 'output': 'wayland-server-protocol.h', + 'install': true, + }, + { + 'scanner_args': ['server-header', '-c'], + 'output': 'wayland-server-protocol-core.h', + 'install': false, + }, + { + 'scanner_args': ['client-header'], + 'output': 'wayland-client-protocol.h', + 'install': true, + }, + { + 'scanner_args': ['client-header', '-c'], + 'output': 'wayland-client-protocol-core.h', + 'install': false, + }, + ] + + foreach gen: generated_headers + scanner_args = gen['scanner_args'] + output_file = gen['output'] + install_file = gen['install'] + install_dir = join_paths(get_option('prefix'), get_option('includedir')) + target_name = output_file.underscorify() + + target = custom_target( + target_name, + command: [ + wayland_scanner_for_build, scanner_args, + '@INPUT@', '@OUTPUT@' + ], + input: wayland_protocol_xml, + output: output_file, + install: install_file, + install_dir: install_dir + ) + + set_variable(target_name, target) + endforeach + + wayland_protocol_c = custom_target( + 'protocol source', + command: [ + wayland_scanner_for_build, 'public-code', '@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, + threads_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, threads_dep ], + sources: [ + wayland_server_protocol_core_h, + wayland_server_protocol_h + ] + ) + + pkgconfig.generate( + wayland_server, + name: 'Wayland Server', + description: 'Server side implementation of the Wayland protocol', + version: meson.project_version(), + filebase: 'wayland-server', + variables: [ + 'datarootdir=' + join_paths('${prefix}', get_option('datadir')), + 'pkgdatadir=' + join_paths('${datarootdir}', meson.project_name()) + ] + ) + + 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, + threads_dep + ], + include_directories: root_inc, + install: true + ) + + pkgconfig.generate( + wayland_client, + name: 'Wayland Client', + description: 'Wayland client side library', + version: meson.project_version(), + filebase: 'wayland-client', + variables: [ + 'datarootdir=' + join_paths('${prefix}', get_option('datadir')), + 'pkgdatadir=' + join_paths('${datarootdir}', meson.project_name()) + ] + ) + + 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..6daec2ed --- /dev/null +++ b/tests/meson.build @@ -0,0 +1,153 @@ +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_for_build, '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_for_build, 'client-header', '@INPUT@', '@OUTPUT@' ], + input: tests_protocol_xml, + output: 'tests-client-protocol.h' +) + +tests_protocol_c = custom_target( + 'test protocol source', + command: [ wayland_scanner_for_build, 'public-code', '@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', + wayland_server_protocol_core_h, + include_directories: src_inc + ) +) + +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()), + ], +) + +tests = { + 'array-test': [], + 'client-test': [ wayland_server_protocol_h ], + 'display-test': [ + tests_server_protocol_h, + tests_client_protocol_c, + tests_protocol_c, + ], + 'connection-test': [ wayland_server_protocol_h ], + 'event-loop-test': [ wayland_server_protocol_h ], + 'fixed-test': [], + 'interface-test': [ wayland_client_protocol_h ], + 'list-test': [], + 'map-test': [], + 'sanity-test' : [ wayland_server_protocol_h ], + 'socket-test': [ + wayland_client_protocol_h, + wayland_server_protocol_h, + ], + 'queue-test': [ + wayland_client_protocol_h, + wayland_server_protocol_h, + ], + 'signal-test': [ wayland_server_protocol_h ], + 'newsignal-test': [ + # wayland-server.c is needed here to access wl_priv_* functions + files('../src/wayland-server.c'), + wayland_server_protocol_h, + ], + 'resources-test': [ wayland_server_protocol_core_h ], + 'message-test': [ + wayland_client_protocol_h, + wayland_server_protocol_h, + ], + 'compositor-introspection-test': [ + wayland_client_protocol_h, + wayland_server_protocol_h, + ], + 'protocol-logger-test': [ + wayland_server_protocol_core_h, + wayland_client_protocol_core_h, + ], + 'headers-test': [ + 'headers-protocol-test.c', + 'headers-protocol-core-test.c', + wayland_server_protocol_core_h, + wayland_client_protocol_core_h, + ], + 'os-wrappers-test': [], +} + +foreach test_name, test_extra_sources: tests + test_sources = [ test_name + '.c' ] + test_extra_sources + test_deps = [test_runner_dep] + bin = executable(test_name, test_sources, dependencies: test_deps) + test( + test_name, + bin, + env: [ + 'TEST_SRC_DIR=@0@'.format(meson.current_source_dir()), + 'TEST_BUILD_DIR=@0@'.format(meson.current_build_dir()), + ], + ) +endforeach