modules/wayland: Add unstable_wayland module

pull/10038/head
Mark Bolhuis 3 years ago committed by Xavier Claessens
parent fcca265035
commit 5a4177523e
  1. 1
      CODEOWNERS
  2. 2
      ci/ciimage/arch/install.sh
  3. 2
      ci/ciimage/fedora/install.sh
  4. 64
      docs/markdown/Wayland-module.md
  5. 1
      docs/markdown/_Sidebar.md
  6. 4
      docs/markdown/snippets/wayland-module.md
  7. 1
      docs/sitemap.txt
  8. 1
      docs/theme/extra/templates/navbar_links.html
  9. 6
      mesonbuild/modules/__init__.py
  10. 120
      mesonbuild/modules/unstable_wayland.py
  11. 10
      run_project_tests.py
  12. 9
      test cases/wayland/1 client/main.c
  13. 16
      test cases/wayland/1 client/meson.build
  14. 9
      test cases/wayland/2 server/main.c
  15. 16
      test cases/wayland/2 server/meson.build
  16. 9
      test cases/wayland/3 local/main.c
  17. 11
      test cases/wayland/3 local/meson.build
  18. 6
      test cases/wayland/3 local/test.xml

@ -3,6 +3,7 @@
/mesonbuild/modules/cmake.py @mensinda
/mesonbuild/modules/unstable_external_project.py @xclaesse
/mesonbuild/modules/unstable_rust.py @dcbaker
/mesonbuild/modules/unstable_wayland.py @markbolhuis
/mesonbuild/ast/ @mensinda
/mesonbuild/cmake/ @mensinda
/mesonbuild/compilers/ @dcbaker

@ -14,7 +14,7 @@ pkgs=(
itstool gtk3 java-environment=8 gtk-doc llvm clang sdl2 graphviz
doxygen vulkan-validation-layers openssh mercurial gtk-sharp-2 qt5-tools
libwmf valgrind cmake netcdf-fortran openmpi nasm gnustep-base gettext
python-lxml hotdoc rust-bindgen qt6-base qt6-tools
python-lxml hotdoc rust-bindgen qt6-base qt6-tools wayland wayland-protocols
# cuda
)

@ -15,7 +15,7 @@ pkgs=(
doxygen vulkan-devel vulkan-validation-layers-devel openssh mercurial gtk-sharp2-devel libpcap-devel gpgme-devel
qt5-qtbase-devel qt5-qttools-devel qt5-linguist qt5-qtbase-private-devel
libwmf-devel valgrind cmake openmpi-devel nasm gnustep-base-devel gettext-devel ncurses-devel
libxml2-devel libxslt-devel libyaml-devel glib2-devel json-glib-devel libgcrypt-devel
libxml2-devel libxslt-devel libyaml-devel glib2-devel json-glib-devel libgcrypt-devel wayland-devel wayland-protocols-devel
)
# Sys update

@ -0,0 +1,64 @@
# Unstable Wayland Module
This module is available since version 0.62.0.
This module provides helper functions to find wayland protocol
xmls and to generate .c and .h files using wayland-scanner
**Note**: this module is unstable. It is only provided as a technology
preview. Its API may change in arbitrary ways between releases or it
might be removed from Meson altogether.
## Quick Usage
```meson
project('hello-wayland', 'c')
wl_dep = dependency('wayland-client')
wl_mod = import('unstable-wayland')
xml = wl_mod.find_protocol('xdg-shell')
xdg_shell = wl_mod.scan_xml(xml)
executable('hw', 'main.c', xdg_shell, dependencies : wl_dep)
```
## Methods
### find_protocol
```meson
xml = wl_mod.find_protocol(
'xdg-decoration',
state : 'unstable',
version : 1,
)
```
This function requires one positional argument: the protocol base name.
- `state` Optional arg that specifies the current state of the protocol.
Either stable, staging, or unstable.
The default is stable.
- `version` The backwards incompatible version number.
Required for staging or unstable. An error is raised for stable.
### scan_xml
```meson
generated = wl_mod.scan_xml(
'my-protocol.xml',
side : 'client',
scope : 'private',
)
```
This function accepts one or more arguments of either string or file type.
- `side` Optional arg that specifies if client or server side code is generated.
The default is client side.
- `scope` Optional arg that specifies the scope of the generated code.
Either public or private.
The default is private.
## Links
- [Official Wayland Documentation](https://wayland.freedesktop.org/docs/html/)
- [Wayland GitLab](https://gitlab.freedesktop.org/wayland)
- [Wayland Book](https://wayland-book.com/)

@ -13,3 +13,4 @@
* [i18n](i18n-module.md)
* [pkgconfig](Pkgconfig-module.md)
* [rust](Rust-module.md)
* [wayland](Wayland-module.md)

@ -0,0 +1,4 @@
## New unstable wayland module
This module can search for protocol xml files from the wayland-protocols
package, and generate .c and .h files using wayland-scanner.

@ -58,6 +58,7 @@ index.md
SourceSet-module.md
Windows-module.md
i18n-module.md
Wayland-module.md
Java.md
Vala.md
D.md

@ -26,6 +26,7 @@
("Rust-module.html","Rust"), \
("Simd-module.html","Simd"), \
("SourceSet-module.html","SourceSet"), \
("Wayland-module.html","Wayland"), \
("Windows-module.html","Windows")]:
<li>
<a href="@tup[0]">@tup[1]</a>

@ -80,8 +80,10 @@ class ModuleState:
def find_program(self, prog: T.Union[str, T.List[str]], required: bool = True,
version_func: T.Optional[T.Callable[['ExternalProgram'], str]] = None,
wanted: T.Optional[str] = None, silent: bool = False) -> 'ExternalProgram':
return self._interpreter.find_program_impl(prog, required=required, version_func=version_func, wanted=wanted, silent=silent)
wanted: T.Optional[str] = None, silent: bool = False,
for_machine: MachineChoice = MachineChoice.HOST) -> 'ExternalProgram':
return self._interpreter.find_program_impl(prog, required=required, version_func=version_func,
wanted=wanted, silent=silent, for_machine=for_machine)
def test(self, args: T.Tuple[str, T.Union[build.Executable, build.Jar, 'ExternalProgram', mesonlib.File]],
workdir: T.Optional[str] = None,

@ -0,0 +1,120 @@
# Copyright 2022 Mark Bolhuis <mark@bolhuis.dev>
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import os
from . import ExtensionModule, ModuleReturnValue
from ..build import CustomTarget
from ..interpreter.type_checking import NoneType, in_set_validator
from ..interpreterbase import FeatureNew, typed_pos_args, typed_kwargs, KwargInfo
from ..mesonlib import File, MesonException, MachineChoice
class WaylandModule(ExtensionModule):
@FeatureNew('wayland module', '0.62.0')
def __init__(self, interpreter):
super().__init__(interpreter)
self.protocols_dep = None
self.pkgdatadir = None
self.scanner_bin = None
self.methods.update({
'scan_xml': self.scan_xml,
'find_protocol': self.find_protocol,
})
@typed_pos_args('wayland.scan_xml', varargs=(str, File), min_varargs=1)
@typed_kwargs(
'wayland.scan_xml',
KwargInfo('side', str, default='client', validator=in_set_validator({'client', 'server'})),
KwargInfo('scope', str, default='private', validator=in_set_validator({'private', 'public'})),
)
def scan_xml(self, state, args, kwargs):
if self.scanner_bin is None:
self.scanner_bin = state.find_program('wayland-scanner', for_machine=MachineChoice.BUILD)
scope = kwargs['scope']
side = kwargs['side']
xml_files = self.interpreter.source_strings_to_files(args[0])
targets = []
for xml_file in xml_files:
name = os.path.splitext(os.path.basename(xml_file.fname))[0]
code = CustomTarget(
f'{name}-protocol',
state.subdir,
state.subproject,
[self.scanner_bin, f'{scope}-code', '@INPUT@', '@OUTPUT@'],
[xml_file],
[f'{name}-protocol.c'],
backend=state.backend,
)
targets.append(code)
header = CustomTarget(
f'{name}-{side}-protocol',
state.subdir,
state.subproject,
[self.scanner_bin, f'{side}-header', '@INPUT@', '@OUTPUT@'],
[xml_file],
[f'{name}-{side}-protocol.h'],
backend=state.backend,
)
targets.append(header)
return ModuleReturnValue(targets, targets)
@typed_pos_args('wayland.find_protocol', str)
@typed_kwargs(
'wayland.find_protocol',
KwargInfo('state', str, default='stable', validator=in_set_validator({'stable', 'staging', 'unstable'})),
KwargInfo('version', (int, NoneType)),
)
def find_protocol(self, state, args, kwargs):
base_name = args[0]
xml_state = kwargs['state']
version = kwargs['version']
if xml_state != 'stable' and version is None:
raise MesonException(f'{xml_state} protocols require a version number.')
if xml_state == 'stable' and version is not None:
raise MesonException('stable protocols do not require a version number.')
if self.protocols_dep is None:
self.protocols_dep = self.interpreter.func_dependency(state.current_node, ['wayland-protocols'], {})
if self.pkgdatadir is None:
self.pkgdatadir = self.protocols_dep.get_variable(pkgconfig='pkgdatadir', internal='pkgdatadir')
if xml_state == 'stable':
xml_name = f'{base_name}.xml'
elif xml_state == 'staging':
xml_name = f'{base_name}-v{version}.xml'
else:
xml_name = f'{base_name}-unstable-v{version}.xml'
path = os.path.join(self.pkgdatadir, xml_state, base_name, xml_name)
if not os.path.exists(path):
raise MesonException(f'The file {path} does not exist.')
return File.from_absolute_file(path)
def initialize(interpreter):
return WaylandModule(interpreter)

@ -84,7 +84,7 @@ if T.TYPE_CHECKING:
ALL_TESTS = ['cmake', 'common', 'native', 'warning-meson', 'failing-meson', 'failing-build', 'failing-test',
'keyval', 'platform-osx', 'platform-windows', 'platform-linux',
'java', 'C#', 'vala', 'cython', 'rust', 'd', 'objective c', 'objective c++',
'fortran', 'swift', 'cuda', 'python3', 'python', 'fpga', 'frameworks', 'nasm', 'wasm',
'fortran', 'swift', 'cuda', 'python3', 'python', 'fpga', 'frameworks', 'nasm', 'wasm', 'wayland'
]
@ -1033,6 +1033,13 @@ def should_skip_rust(backend: Backend) -> bool:
return True
return False
def should_skip_wayland() -> bool:
if mesonlib.is_windows() or mesonlib.is_osx():
return True
if not shutil.which('wayland-scanner'):
return True
return False
def detect_tests_to_run(only: T.Dict[str, T.List[str]], use_tmp: bool) -> T.List[T.Tuple[str, T.List[TestDef], bool]]:
"""
Parameters
@ -1089,6 +1096,7 @@ def detect_tests_to_run(only: T.Dict[str, T.List[str]], use_tmp: bool) -> T.List
TestCategory('frameworks', 'frameworks'),
TestCategory('nasm', 'nasm'),
TestCategory('wasm', 'wasm', shutil.which('emcc') is None or backend is not Backend.ninja),
TestCategory('wayland', 'wayland', should_skip_wayland()),
]
categories = [t.category for t in all_tests]

@ -0,0 +1,9 @@
#include "xdg-shell-client-protocol.h"
int main() {
#ifdef XDG_SHELL_CLIENT_PROTOCOL_H
return 0;
#else
return 1;
#endif
}

@ -0,0 +1,16 @@
project('wayland-test-client', 'c')
wl_protocols_dep = dependency('wayland-protocols', required : false)
if not wl_protocols_dep.found()
error('MESON_SKIP_TEST: wayland-protocols not installed')
endif
wl_dep = dependency('wayland-client')
wl_mod = import('unstable-wayland')
xdg_shell_xml = wl_mod.find_protocol('xdg-shell')
xdg_shell = wl_mod.scan_xml(xdg_shell_xml)
exe = executable('client', 'main.c', xdg_shell, dependencies : wl_dep)
test('client', exe)

@ -0,0 +1,9 @@
#include "xdg-shell-server-protocol.h"
int main() {
#ifdef XDG_SHELL_SERVER_PROTOCOL_H
return 0;
#else
return 1;
#endif
}

@ -0,0 +1,16 @@
project('wayland-test-server', 'c')
wl_protocols_dep = dependency('wayland-protocols', required : false)
if not wl_protocols_dep.found()
error('MESON_SKIP_TEST: wayland-protocols not installed')
endif
wl_dep = dependency('wayland-server')
wl_mod = import('unstable-wayland')
xdg_shell_xml = wl_mod.find_protocol('xdg-shell')
xdg_shell = wl_mod.scan_xml(xdg_shell_xml, side : 'server')
exe = executable('server', 'main.c', xdg_shell, dependencies : wl_dep)
test('client', exe)

@ -0,0 +1,9 @@
#include "test-client-protocol.h"
int main() {
#ifdef TEST_CLIENT_PROTOCOL_H
return 0;
#else
return 1;
#endif
}

@ -0,0 +1,11 @@
project('wayland-test-local', 'c')
wl_dep = dependency('wayland-client')
wl_mod = import('unstable-wayland')
xmls = files('test.xml')
gen = wl_mod.scan_xml(xmls)
exe = executable('local', 'main.c', gen, dependencies : wl_dep)
test('local', exe)

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<protocol name="test">
<interface name="ext_test" version="1">
<request name="destroy" type="destructor"/>
</interface>
</protocol>
Loading…
Cancel
Save