AtlatestRepositorycore-channel

core-channel / tree / src / core / packagesviewer.sgl

1;;; Image viewing.
2;;;
3;;; PROVENANCE: THE SAME SCOPED EXCEPTION AS `core/luajit`, AND FOR THE SAME
4;;; REASON. swayimg publishes NO release assets -- only GitHub's
5;;; auto-generated source archive, which is what every distribution pins. A
6;;; synthetic archive whose bytes can be regenerated does not belong on the
7;;; critical path of a chain intended to SHIP.
8;;;
9;;; This is not that. `core/swayimg` and `core/luajit` exist as a DISCOVERY
10;;; EXERCISE whose product is knowledge about what this packaging model can
11;;; host -- where the blind spots are -- rather than a published dependency.
12;;; Two auto-generated archives are acceptable for that purpose and would not
13;;; be acceptable for a shipped chain. NEITHER PACKAGE SHOULD BE PUBLISHED OR
14;;; SIGNED ON THIS PROVENANCE WITHOUT REVISITING THE QUESTION.
15;;;
16;;; AND A CONCRETE DEMONSTRATION OF WHY, MET WHILE WRITING THIS PACKAGE.
17;;; The first build refused:
18;;;
19;;; REFUSING source sha256 mismatch; expected 64ae8713... actual f84fec72...
20;;;
21;;; That was my error -- I hashed one URL and pinned another -- but the reason
22;;; the two hashes differ is the point. GitHub serves the SAME TAG from two
23;;; endpoints and they are not the same artifact:
24;;;
25;;; api.github.com/repos/OWNER/REPO/tarball/TAG -> artemsen-swayimg-682fecf/
26;;; codeload.github.com/OWNER/REPO/tar.gz/TAG -> swayimg-5.5/
27;;;
28;;; Identical CONTENT once the prefix is stripped -- verified by extracting
29;;; both and diffing -- but a different embedded top-level directory name, so
30;;; different bytes and different hashes. Each endpoint is individually
31;;; stable (the api one was fetched twice and matched), so this is not
32;;; regeneration. It is that THERE IS NO SINGLE CANONICAL BYTE STREAM for a
33;;; tag that ships no release artifact.
34;;;
35;;; A real dist tarball has one answer to "what are the bytes". This has two,
36;;; and nothing upstream declares which is meant. That is the argument
37;;; against synthetic archives stated more precisely than "they can change".
38;;;
39;;; WHAT IT COST, which is the interesting number: ONE new library, and that
40;;; one is LuaJIT. Every other dependency swayimg has -- libxkbcommon,
41;;; fontconfig, freetype, wayland, wayland-protocols, libpng -- already existed
42;;; because foot needed them. The Wayland half of this channel turns out to be
43;;; reusable rather than foot-shaped, which is the same thing `core/grim`
44;;; demonstrated and is worth more than either program.
45(define-library (core packages viewer)
46 (import (sigil core)
47 (core build-environments)
48 (core packages compression)
49 (core packages xml)
50 (core packages ffi)
51 (core packages graphics)
52 (core packages fonts)
53 (core packages wayland)
54 (core packages input)
55 (core packages luajit)
56 (core packages build-tools)
57 (core packages python)
58 (sigil env package)
59 (sigil build external))
60 (export swayimg)
61 (begin
62 ;; LUAJIT IS NOT OPTIONAL, and it is LuaJIT rather than Lua.
63 ;; meson.build:38 is `dependency('luajit')` under a comment reading
64 ;; `# mandatory dependencies`, with no `required:` kwarg and no
65 ;; corresponding entry in meson.options. An earlier estimate of this
66 ;; package's cost read `dependency(get_option('liblua'))` from upstream
67 ;; MASTER and concluded plain Lua would do; the RELEASE hardcodes luajit.
68 ;; Read the version you are packaging, not the branch.
69 ;;
70 ;; expat, zlib, libffi and freetype are declared although swayimg names
71 ;; none of them: they are reached through the `Requires:` and
72 ;; `Requires.private:` chains of fontconfig.pc, freetype2.pc, libpng.pc and
73 ;; wayland-client.pc, and this channel composes PKG_CONFIG_PATH from DIRECT
74 ;; dependencies only. The union was printed from the store before writing
75 ;; this line rather than discovered one build failure at a time.
76 ;; [[topics/core-channel-pkgconfig-is-not-transitive]]
77 (define swayimg
78 (package
79 name: "swayimg"
80 version: "5.5"
81 source: (external-source
82 location: "https://codeload.github.com/artemsen/swayimg/tar.gz/v5.5"
83 sha256: "f84fec722cd0b4cfd86d0a8a820b15a95bbdb1d2cfcded7f67446a7a0c1d1c09")
84 buildenv: core-buildenv
85 dependencies: (list libxkbcommon fontconfig freetype wayland
86 wayland-protocols libpng luajit
87 expat zlib libffi)
88 ;; SWAYIMG IS A C++ PROJECT, AND I MISSED THAT WHEN SCOPING IT.
89 ;;
90 ;; `meson.build:3` is `project('swayimg', 'c', 'cpp', ...)` with
91 ;; `cpp_std=c++20` and roughly thirty `.cpp` sources. My scoping pass
92 ;; enumerated every `dependency()` call carefully and never read the
93 ;; `project()` line, so the estimate said "one new package, LuaJIT" when
94 ;; the truth is one new package AND a C++ toolchain requirement. The
95 ;; libraries were right; the LANGUAGE was not looked at.
96 ;;
97 ;; The failure is loud and names itself, at least:
98 ;;
99 ;; meson.build:3:0: ERROR: Unknown compiler(s):
100 ;; [['c++'], ['g++'], ['clang++'], ['nvc++'], ['pgc++'], ...]
101 ;;
102 ;; meson probes for a C++ compiler BY NAME and the toolchain ships
103 ;; none, so it falls through every candidate. `CXX` is not
104 ;; builder-owned -- the refusal list is derived from what the builder
105 ;; emits and it emits no C++ assignment -- so a package may declare
106 ;; one, and meson honours `CXX` for the cpp language. This is the same
107 ;; mechanism `core/gperf` uses and the second package in the channel to
108 ;; need it. The explicit `-target` is required by the zig guard.
109 env: (list (cons "CXX" "zig c++ -target x86_64-linux-musl"))
110 build-inputs: (list meson samurai python)
111 phases: (list
112 (external-phase
113 kind: 'run
114 args: (list "sh" "-c"
115 (string-append
116 "set -eu\n"
117 "meson setup build"
118 " --prefix=${out}"
119 " --buildtype=plain"
120 " --default-library=static"
121 ;; fontconfig.pc carries `Requires.private: expat`,
122 ;; and swayimg links an executable, so the static
123 ;; pkg-config query is required or the link fails
124 ;; on XML_* symbols. Same lesson as foot.
125 " -Dprefer_static=true"
126 ;; PNG only. Every other decoder is a feature
127 ;; option defaulting to `auto`, which would make
128 ;; the output depend on what happened to be
129 ;; visible -- the thing this channel exists to
130 ;; prevent. Turning them off explicitly is what
131 ;; makes the result a function of the declared
132 ;; inputs.
133 " -Dpng=enabled"
134 " -Dexr=disabled -Dgif=disabled -Dheif=disabled"
135 " -Davif=disabled -Djpeg=disabled -Djp2=disabled"
136 " -Djxl=disabled -Dsvg=disabled -Dtiff=disabled"
137 " -Dsixel=disabled -Draw=disabled -Dwebp=disabled"
138 " -Dexif=disabled"
139 ;; Wayland yes, DRM no: the DRM backend wants
140 ;; libdrm and a console, and the acceptance case
141 ;; is a Wayland compositor.
142 " -Dwayland=enabled -Ddrm=disabled"
143 ;; Completions want bash-completion and zsh; the
144 ;; man page wants scdoc. None is packaged and
145 ;; none is read by anything here.
146 " -Dbash=disabled -Dzsh=disabled"
147 " -Dman=false -Ddoc=false -Ddesktop=false"
148 " -Dluameta=false"
149 ;; The version option exists because swayimg
150 ;; otherwise derives it from `git`, which is not
151 ;; in the seed and would leave it at 0.0.0.
152 " -Dversion=5.5\n"
153 "echo SWAYIMG-CONFIGURED\n")))
154 (external-phase
155 kind: 'run
156 args: (list "sh" "-c"
157 (string-append
158 "set -eu\n"
159 "meson compile -C build\n"
160 "echo SWAYIMG-COMPILED\n")))
161 (external-phase
162 kind: 'run
163 args: (list "sh" "-c"
164 (string-append
165 "set -eu\n"
166 "d=\"$(dirname \"$PWD\")/install-root\"\n"
167 "DESTDIR=\"$d\" meson install -C build --no-rebuild\n"
168 "test -x \"$d${out}/bin/swayimg\"\n"
169 ;; ASSERT PNG SUPPORT IS ACTUALLY IN, not merely
170 ;; requested. `-Dpng=enabled` makes meson FAIL if
171 ;; libpng is missing, so this is belt-and-braces
172 ;; rather than the only guard -- but a viewer that
173 ;; installs and cannot decode the one format it
174 ;; was built for is exactly the silent
175 ;; feature-loss this channel keeps finding, and
176 ;; the binary is the only thing that can answer it.
177 "\"$d${out}/bin/swayimg\" --version\n"
178 "echo SWAYIMG-INSTALLED\n"))))))))