AtlatestRepositorycore-channel
core-channel / tree / src / core / packageswayland.sgl
1
;;; The Wayland display protocol: the client library, the code generator, and2
;;; the protocol definitions.3
;;;4
;;; WHAT DOES AND DOES NOT HAVE TO MATCH THE USER'S COMPOSITOR, because it is5
;;; the first question anyone asks about a store-built Wayland client and the6
;;; answer is not obvious:7
;;;8
;;; Wayland is a WIRE PROTOCOL over a Unix socket, not a shared-library ABI.9
;;; A client links libwayland-client, a compositor links libwayland-server,10
;;; and the two never link against each other or share an address space. So11
;;; a statically linked musl client built from this channel talks to a12
;;; glibc compositor from any distribution, at any library version, without13
;;; difficulty. What must line up is the PROTOCOL VERSIONS a client binds14
;;; against those the compositor advertises -- and `wayland-protocols` below15
;;; is a BUILD-TIME source of XML for code generation, not something the16
;;; compositor needs to have.17
;;;18
;;; The same reasoning covers libxkbcommon: a Wayland compositor sends its19
;;; keymap to clients as TEXT over a file descriptor, and each client compiles20
;;; it with its own copy of the library. That is why nothing here needs21
;;; `xkeyboard-config` -- a Wayland client never reads the keymap database.22
(define-library (core packages wayland)23
(import (sigil core)24
(core build-environments)25
(core packages ffi)26
(core packages xml)27
(core packages build-tools)28
(core packages python)29
(sigil env package)30
(sigil build external))31
(export wayland wayland-protocols)32
(begin33
;; THE CHANNEL'S FIRST MESON PACKAGE.34
;;35
;; There is no `meson` phase kind and none is needed: `run` executes an36
;; authored argv under `set -eu`, so the three steps are three phases.37
;; Separate phases rather than one script because a failure then names38
;; which step failed without anyone reading a log.39
;;40
;; `--buildtype=plain` is the load-bearing flag. Meson's other build41
;; types inject their own optimisation and debug flags, which would sit42
;; alongside the builder's `@compiler.flags` response file with no defined43
;; precedence. `plain` tells meson to add nothing and use CFLAGS,44
;; CPPFLAGS and LDFLAGS from the environment -- which is exactly the45
;; channel's model, and is what every distribution uses for the same46
;; reason.47
;;48
;; DESTDIR is passed to `meson install` through the environment rather49
;; than as `--destdir`, so the same idiom works on any meson old enough to50
;; predate that flag. `$d` is derived from the phase's cwd rather than51
;; hardcoded: a run phase cannot interpolate the staged install root, but52
;; it always runs in `<build-root>/source` and the staged root is always53
;; `<build-root>/install-root`.54
(define wayland55
(package56
name: "wayland"57
version: "1.24.0"58
source: (external-source59
location: "https://gitlab.freedesktop.org/wayland/wayland/-/releases/1.24.0/downloads/wayland-1.24.0.tar.xz"60
sha256: "82892487a01ad67b334eca83b54317a7c86a03a89cfadacfef5211f11a5d0536")61
buildenv: core-buildenv62
;; libffi is a genuine runtime dependency: libwayland dispatches every63
;; protocol message through `ffi_call`, in the client as well as the64
;; server. expat is needed by wayland-scanner, which parses protocol65
;; XML -- and although the scanner is a build-time tool for consumers,66
;; it is a linked artifact OF THIS package, so expat is a dependency67
;; and not a build input.68
dependencies: (list libffi expat)69
build-inputs: (list meson samurai python)70
phases: (list71
(external-phase72
kind: 'run73
args: (list "sh" "-c"74
(string-append75
"set -eu\n"76
"meson setup build"77
" --prefix=${out}"78
" --buildtype=plain"79
" --default-library=static"80
;; `-Dprefer_static=true` HERE TOO, although81
;; nothing needs it TODAY. wayland builds82
;; `wayland-scanner`, an executable that links83
;; expat, and it links only because `expat.pc`84
;; happens to carry no `Requires.private:` -- so85
;; the default, non-static pkg-config query is86
;; sufficient by coincidence rather than by87
;; construction. The moment expat grows one, or88
;; the scanner gains a dependency that has one,89
;; this package reproduces the `undefined symbol`90
;; link failure that fontconfig's91
;; `Requires.private: expat` produced in foot.92
" -Dprefer_static=true"93
;; documentation wants doxygen, xmlto and94
;; xsltproc; dtd_validation wants libxml2. Both95
;; are probes on what happens to be visible, and96
;; neither produces anything foot consumes.97
" -Ddocumentation=false"98
" -Dtests=false"99
" -Ddtd_validation=false\n"100
"echo WAYLAND-CONFIGURED\n")))101
(external-phase102
kind: 'run103
args: (list "sh" "-c"104
(string-append105
"set -eu\n"106
"meson compile -C build\n"107
"echo WAYLAND-COMPILED\n")))108
(external-phase109
kind: 'run110
args: (list "sh" "-c"111
(string-append112
"set -eu\n"113
"d=\"$(dirname \"$PWD\")/install-root\"\n"114
"DESTDIR=\"$d\" meson install -C build --no-rebuild\n"115
;; Assert the three things consumers resolve by116
;; name. foot asks for wayland-client and117
;; wayland-cursor through pkg-config and then118
;; reads `wayland_scanner` out of the119
;; wayland-scanner `.pc` to find the generator.120
"test -f \"$d${out}/lib/pkgconfig/wayland-client.pc\"\n"121
"test -f \"$d${out}/lib/pkgconfig/wayland-cursor.pc\"\n"122
"test -f \"$d${out}/lib/pkgconfig/wayland-scanner.pc\"\n"123
"test -x \"$d${out}/bin/wayland-scanner\"\n"124
"echo WAYLAND-INSTALLED\n"))))))126
;; wayland-protocols is DATA -- XML files and one `.pc` -- so it is127
;; installed by hand for the same reason tllist is: running meson to copy128
;; a directory tree would add three build inputs to a package that129
;; compiles nothing.130
;;131
;; TWO THINGS HERE ARE NOT COSMETIC.132
;;133
;; 1. THE `.pc` GOES IN `lib/pkgconfig`, WHERE UPSTREAM PUTS IT IN134
;; `share/pkgconfig`. `dependency-pkgconfig` in (sigil build external)135
;; composes PKG_CONFIG_PATH as exactly `<dep>/lib/pkgconfig` for each136
;; dependency and nothing else. An arch-independent `.pc` in137
;; `share/pkgconfig` -- which is the correct place for one, and where138
;; upstream's meson puts it -- WOULD BE INVISIBLE TO EVERY CONSUMER IN139
;; THIS CHANNEL. A package cannot fix that by declaring a search path140
;; either: `PKG_CONFIG_PATH` is builder-owned, and a `search-paths:`141
;; export naming a builder variable is refused outright.142
;;143
;; 2. `pkgdatadir` MUST BE DEFINED IN THE `.pc`, because foot does not144
;; merely link against this -- it reads the variable back out145
;; (`wayland_protocols.get_variable('pkgdatadir')`, meson.build:169) and146
;; then joins protocol paths onto it. Upstream's template writes it as147
;; `${pc_sysrootdir}${datarootdir}/@PACKAGE@`; that spelling cannot be148
;; used here because sigil interpolates `${...}` in a phase argument149
;; before any consumer sees it. An absolute path is equivalent for150
;; every use in this channel.151
(define wayland-protocols152
(package153
name: "wayland-protocols"154
version: "1.45"155
source: (external-source156
location: "https://gitlab.freedesktop.org/wayland/wayland-protocols/-/releases/1.45/downloads/wayland-protocols-1.45.tar.xz"157
sha256: "4d2b2a9e3e099d017dc8107bf1c334d27bb87d9e4aff19a0c8d856d17cd41ef0")158
buildenv: core-buildenv159
phases: (list160
(external-phase161
kind: 'run162
args: (list "sh" "-c"163
(string-append164
"set -eu\n"165
"d=\"$(dirname \"$PWD\")/install-root\"\n"166
"p=\"$d${out}/share/wayland-protocols\"\n"167
"mkdir -p \"$p\" \"$d${out}/lib/pkgconfig\"\n"168
"cp -a stable unstable staging \"$p/\"\n"169
"cat > \"$d${out}/lib/pkgconfig/wayland-protocols.pc\" <<'PC'\n"170
"prefix=${out}\n"171
"datarootdir=${out}/share\n"172
"pkgdatadir=${out}/share/wayland-protocols\n"173
"\n"174
"Name: Wayland Protocols\n"175
"Description: Wayland protocol files\n"176
"Version: 1.45\n"177
"PC\n"178
;; foot names these three files explicitly, so179
;; assert them rather than the directory: a180
;; reorganised tarball would otherwise fail three181
;; packages later inside wayland-scanner.182
"test -f \"$p/stable/xdg-shell/xdg-shell.xml\"\n"183
"test -f \"$p/unstable/xdg-decoration/xdg-decoration-unstable-v1.xml\"\n"184
"test -f \"$p/unstable/xdg-output/xdg-output-unstable-v1.xml\"\n"185
;; And prove the variable foot reads back is186
;; actually readable, by the tool that will read187
;; it.188
;; A BARE `pkg-config --variable=` CALL IS NOT A189
;; GATE. pkg-config exits 0 and prints an empty190
;; line when the requested variable is UNDEFINED,191
;; so deleting the `pkgdatadir=` line from the192
;; heredoc above would leave this green -- and193
;; foot's `get_variable('pkgdatadir')` would then194
;; fail three packages later, inside195
;; wayland-scanner, which is exactly the distance196
;; these assertions exist to close. Require the197
;; value to be non-empty AND to name a real198
;; directory.199
"v=$(PKG_CONFIG_PATH=\"$d${out}/lib/pkgconfig\" pkg-config --variable=pkgdatadir wayland-protocols)\n"200
"echo \"WAYLAND-PROTOCOLS-PKGDATADIR=[$v]\"\n"201
"test -n \"$v\"\n"202
;; AND THE VALUE MUST NAME A REAL DIRECTORY --203
;; but the STAGED one. `$v` is an absolute204
;; `/sigil/store/<item>/...` path, which is where205
;; the directory will live once this output is in206
;; the store and bound into a consumer's sandbox.207
;; It does not exist yet DURING this build; the208
;; files are under `$d` until the realizer moves209
;; them. So the staged equivalent is `$d$v`.210
;;211
;; The first version of this check tested `$v`212
;; directly and failed the build immediately --213
;; which is the right direction for a new gate to214
;; be wrong in, and worth leaving a note about:215
;; a path emitted by pkg-config is a CONSUMER-time216
;; path, and a build-time assertion about it has217
;; to add the staging offset.218
"test -d \"$d$v\"\n"219
"echo WAYLAND-PROTOCOLS-INSTALLED\n"))))))))