@gjsify/gtk-runtime-win32-x64 0.19.0 → 0.21.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +133 -133
- package/gtk/bin/cairo-2.dll +0 -0
- package/gtk/bin/cairo-gobject-2.dll +0 -0
- package/gtk/bin/cairo-script-interpreter-2.dll +0 -0
- package/gtk/bin/epoxy-0.dll +0 -0
- package/gtk/bin/ffi-8.dll +0 -0
- package/gtk/bin/fontconfig-1.dll +0 -0
- package/gtk/bin/freetype-6.dll +0 -0
- package/gtk/bin/fribidi-0.dll +0 -0
- package/gtk/bin/gdk_pixbuf-2.0-0.dll +0 -0
- package/gtk/bin/gio-2.0-0.dll +0 -0
- package/gtk/bin/girepository-1.0-1.dll +0 -0
- package/gtk/bin/girepository-2.0-0.dll +0 -0
- package/gtk/bin/glib-2.0-0.dll +0 -0
- package/gtk/bin/gmodule-2.0-0.dll +0 -0
- package/gtk/bin/gobject-2.0-0.dll +0 -0
- package/gtk/bin/graphene-1.0-0.dll +0 -0
- package/gtk/bin/gtk-4-1.dll +0 -0
- package/gtk/bin/harfbuzz-cairo.dll +0 -0
- package/gtk/bin/harfbuzz-gobject.dll +0 -0
- package/gtk/bin/harfbuzz-gpu.dll +0 -0
- package/gtk/bin/harfbuzz-raster.dll +0 -0
- package/gtk/bin/harfbuzz-subset.dll +0 -0
- package/gtk/bin/harfbuzz-vector.dll +0 -0
- package/gtk/bin/harfbuzz.dll +0 -0
- package/gtk/bin/iconv.dll +0 -0
- package/gtk/bin/intl.dll +0 -0
- package/gtk/bin/jpeg62.dll +0 -0
- package/gtk/bin/libexpat.dll +0 -0
- package/gtk/bin/libpng16.dll +0 -0
- package/gtk/bin/pango-1.0-0.dll +0 -0
- package/gtk/bin/pangocairo-1.0-0.dll +0 -0
- package/gtk/bin/pangoft2-1.0-0.dll +0 -0
- package/gtk/bin/pangowin32-1.0-0.dll +0 -0
- package/gtk/bin/pcre2-8-0.dll +0 -0
- package/gtk/bin/pixman-1-0.dll +0 -0
- package/gtk/bin/tiff.dll +0 -0
- package/gtk/bin/zlib1.dll +0 -0
- package/gtk/girepository-1.0/Adw-1.typelib +0 -0
- package/gtk/girepository-1.0/DBus-1.0.typelib +0 -0
- package/gtk/girepository-1.0/DBusGLib-1.0.typelib +0 -0
- package/gtk/girepository-1.0/GIRepository-2.0.typelib +0 -0
- package/gtk/girepository-1.0/GIRepository-3.0.typelib +0 -0
- package/gtk/girepository-1.0/GL-1.0.typelib +0 -0
- package/gtk/girepository-1.0/GLib-2.0.typelib +0 -0
- package/gtk/girepository-1.0/GLibWin32-2.0.typelib +0 -0
- package/gtk/girepository-1.0/GModule-2.0.typelib +0 -0
- package/gtk/girepository-1.0/GObject-2.0.typelib +0 -0
- package/gtk/girepository-1.0/Gdk-4.0.typelib +0 -0
- package/gtk/girepository-1.0/GdkPixbuf-2.0.typelib +0 -0
- package/gtk/girepository-1.0/GdkPixdata-2.0.typelib +0 -0
- package/gtk/girepository-1.0/GdkWin32-4.0.typelib +0 -0
- package/gtk/girepository-1.0/Gio-2.0.typelib +0 -0
- package/gtk/girepository-1.0/GioWin32-2.0.typelib +0 -0
- package/gtk/girepository-1.0/Graphene-1.0.typelib +0 -0
- package/gtk/girepository-1.0/Gsk-4.0.typelib +0 -0
- package/gtk/girepository-1.0/Gtk-4.0.typelib +0 -0
- package/gtk/girepository-1.0/GtkSource-5.typelib +0 -0
- package/gtk/girepository-1.0/HarfBuzz-0.0.typelib +0 -0
- package/gtk/girepository-1.0/Pango-1.0.typelib +0 -0
- package/gtk/girepository-1.0/PangoCairo-1.0.typelib +0 -0
- package/gtk/girepository-1.0/PangoFT2-1.0.typelib +0 -0
- package/gtk/girepository-1.0/PangoFc-1.0.typelib +0 -0
- package/gtk/girepository-1.0/PangoOT-1.0.typelib +0 -0
- package/gtk/girepository-1.0/Rsvg-2.0.typelib +0 -0
- package/gtk/girepository-1.0/Vulkan-1.0.typelib +0 -0
- package/gtk/girepository-1.0/cairo-1.0.typelib +0 -0
- package/gtk/girepository-1.0/fontconfig-2.0.typelib +0 -0
- package/gtk/girepository-1.0/freetype2-2.0.typelib +0 -0
- package/gtk/girepository-1.0/libxml2-2.0.typelib +0 -0
- package/gtk/girepository-1.0/win32-1.0.typelib +0 -0
- package/gtk/girepository-1.0/xfixes-4.0.typelib +0 -0
- package/gtk/girepository-1.0/xft-2.0.typelib +0 -0
- package/gtk/girepository-1.0/xlib-2.0.typelib +0 -0
- package/gtk/girepository-1.0/xrandr-1.3.typelib +0 -0
- package/gtk/manifest.json +51 -0
- package/index.d.ts +11 -11
- package/index.js +27 -27
- package/package.json +1 -1
- package/scripts/build-gtk-runtime.mjs +472 -446
|
@@ -1,446 +1,472 @@
|
|
|
1
|
-
// SPDX-License-Identifier: MIT
|
|
2
|
-
// Collect a standalone, batteries-included GTK/GObject-Introspection runtime
|
|
3
|
-
// bundle for Windows x64 — so @gjsify/node-gi loads gi:// namespaces with NO
|
|
4
|
-
// gvsbuild/system GTK on the host (the Windows sibling of the darwin-arm64 bundle).
|
|
5
|
-
//
|
|
6
|
-
// node scripts/build-gtk-runtime.mjs [--out <dir>] [--prefix <gvsbuild GTK prefix>] [--windowing]
|
|
7
|
-
//
|
|
8
|
-
// Two closures, one bundle dir:
|
|
9
|
-
// • DEFAULT (display-free) — the loadable DLLs + typelibs the DISPLAY-FREE
|
|
10
|
-
// conformance needs (GLib/GObject/Gio/cairo/Pango/Graphene/Gdk). Unchanged.
|
|
11
|
-
// • --windowing (SUPERSET) — everything above PLUS the runtime data a REAL GTK
|
|
12
|
-
// WINDOW needs on Windows: the gdk-pixbuf loaders + `loaders.cache`, compiled
|
|
13
|
-
// GSettings schemas (`gschemas.compiled`), the Adwaita/hicolor icon themes +
|
|
14
|
-
// `icon-theme.cache`, and the Fontconfig config/cache. The extra image-loader
|
|
15
|
-
// backing DLLs (librsvg/png/…) are walked into `bin/` too. node-gi's loader
|
|
16
|
-
// (gtk-runtime.js) detects the windowing data (the `gschemas.compiled` marker)
|
|
17
|
-
// and wires the env (GSETTINGS_SCHEMA_DIR / GDK_PIXBUF_MODULE_FILE /
|
|
18
|
-
// XDG_DATA_DIRS / FONTCONFIG_*) so the SAME loader serves both — the display-free
|
|
19
|
-
// path is byte-unchanged when the windowing data is absent.
|
|
20
|
-
//
|
|
21
|
-
// Runs ONLY on win32/x64 with a build-time gvsbuild GTK4 stack extracted at
|
|
22
|
-
// --prefix (env GTK_PREFIX, the closure *source*, not shipped — the same tree the
|
|
23
|
-
// node-gi.yml windows jobs cache at C:\gtk-build\gtk\x64\release). gvsbuild bundles
|
|
24
|
-
// the tools this needs (gdk-pixbuf-query-loaders / glib-compile-schemas /
|
|
25
|
-
// gtk4-update-icon-cache / fc-cache) in <prefix>/bin.
|
|
26
|
-
//
|
|
27
|
-
// CRUCIAL DIFFERENCE FROM macOS: there is NO relocation step (no install_name_tool,
|
|
28
|
-
// no @rpath, no codesign). Windows resolves a DLL's imports by SEARCH PATH at
|
|
29
|
-
// LoadLibrary time, so a bundle is "portable" the moment its DLLs sit in one dir —
|
|
30
|
-
// node-gi just prepends <out>/bin to PATH before the addon loads. The runtime DATA
|
|
31
|
-
// (loaders/schemas/icons/fonts) is likewise resolved by env vars set at load time,
|
|
32
|
-
// no baked absolute paths (the caches are rewritten to bundle-relative).
|
|
33
|
-
//
|
|
34
|
-
// Reference: GJS ships no relocation; gvsbuild ships the MSVC-ABI GTK4 stack whose
|
|
35
|
-
// DLLs load into stock (MSVC-ABI) Node.
|
|
36
|
-
import { execFileSync } from 'node:child_process';
|
|
37
|
-
import {
|
|
38
|
-
copyFileSync,
|
|
39
|
-
cpSync,
|
|
40
|
-
existsSync,
|
|
41
|
-
mkdirSync,
|
|
42
|
-
readdirSync,
|
|
43
|
-
rmSync,
|
|
44
|
-
statSync,
|
|
45
|
-
writeFileSync,
|
|
46
|
-
} from 'node:fs';
|
|
47
|
-
import { basename, dirname, join } from 'node:path';
|
|
48
|
-
import { fileURLToPath } from 'node:url';
|
|
49
|
-
|
|
50
|
-
const pkgRoot = dirname(dirname(fileURLToPath(import.meta.url)));
|
|
51
|
-
|
|
52
|
-
// --- args ------------------------------------------------------------------
|
|
53
|
-
function argValue(flag) {
|
|
54
|
-
const i = process.argv.indexOf(flag);
|
|
55
|
-
return i >= 0 && i + 1 < process.argv.length ? process.argv[i + 1] : undefined;
|
|
56
|
-
}
|
|
57
|
-
const OUT = argValue('--out') ?? join(pkgRoot, 'gtk');
|
|
58
|
-
const PREFIX = argValue('--prefix') ?? process.env.GTK_PREFIX;
|
|
59
|
-
// The full-windowing SUPERSET: also collect the runtime data a real GTK window needs.
|
|
60
|
-
const WINDOWING = process.argv.includes('--windowing');
|
|
61
|
-
|
|
62
|
-
if (process.platform !== 'win32' || process.arch !== 'x64') {
|
|
63
|
-
console.error(`build-gtk-runtime: only supported on win32/x64, not ${process.platform}/${process.arch}`);
|
|
64
|
-
process.exit(2);
|
|
65
|
-
}
|
|
66
|
-
if (!PREFIX) {
|
|
67
|
-
console.error('build-gtk-runtime: no GTK prefix — pass --prefix or set GTK_PREFIX (e.g. C:\\gtk-build\\gtk\\x64\\release)');
|
|
68
|
-
process.exit(1);
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
const gtkBin = join(PREFIX, 'bin');
|
|
72
|
-
const gtkTypelibs = join(PREFIX, 'lib', 'girepository-1.0');
|
|
73
|
-
if (!existsSync(gtkBin)) {
|
|
74
|
-
console.error(`build-gtk-runtime: ${gtkBin} not found — extract the gvsbuild GTK4 stack first`);
|
|
75
|
-
process.exit(1);
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
const sh = (bin, args, opts) => execFileSync(bin, args, { encoding: 'utf8', ...opts });
|
|
79
|
-
|
|
80
|
-
// The seed DLLs of the DISPLAY-FREE conformance closure. Liberal, version-agnostic
|
|
81
|
-
// patterns matched against <prefix>/bin (gvsbuild's suffixes drift: glib-2.0-0.dll,
|
|
82
|
-
// girepository-2.0-0.dll, cairo-2.dll, pango-1.0-0.dll, gdk_pixbuf-2.0-0.dll,
|
|
83
|
-
// gtk-4-1.dll, harfbuzz.dll, …). The recursive dumpbin walk pulls every transitive
|
|
84
|
-
// gvsbuild dep (harfbuzz, fribidi, fontconfig, freetype, pixman, png, intl, pcre2,
|
|
85
|
-
// ffi, epoxy, zlib, …). gtk-4 is seeded because it backs the Gdk typelib the
|
|
86
|
-
// conformance's struct-construct loads (Gdk/Graphene) and transitively pulls
|
|
87
|
-
// pango/graphene/gdk-pixbuf/cairo/harfbuzz.
|
|
88
|
-
const SEED_PATTERNS = [
|
|
89
|
-
/^glib-2\.0-.*\.dll$/i,
|
|
90
|
-
/^gobject-2\.0-.*\.dll$/i,
|
|
91
|
-
/^gio-2\.0-.*\.dll$/i,
|
|
92
|
-
/^gmodule-2\.0-.*\.dll$/i,
|
|
93
|
-
/^girepository-[12]\.0-.*\.dll$/i, // girepository-2.0 (merged API) on modern gvsbuild
|
|
94
|
-
/^cairo(-gobject|-script-interpreter)?-?\d*\.dll$/i,
|
|
95
|
-
/^pango(cairo|ft2|win32)?-1\.0-.*\.dll$/i,
|
|
96
|
-
/^graphene-1\.0-.*\.dll$/i,
|
|
97
|
-
/^gdk[-_]pixbuf-2\.0-.*\.dll$/i,
|
|
98
|
-
/^gtk-4-.*\.dll$/i, // provides the Gdk typelib's backing library
|
|
99
|
-
/^harfbuzz.*\.dll$/i,
|
|
100
|
-
];
|
|
101
|
-
|
|
102
|
-
// Extra seeds for the WINDOWING superset: libadwaita (the Adw-1 typelib's backing
|
|
103
|
-
// DLL — a real Adw.Application/ApplicationWindow needs it; the display-free
|
|
104
|
-
// conformance never touches Adwaita, so it is NOT in the base seeds), the GL backing
|
|
105
|
-
// a GSK GL renderer picks (ANGLE libEGL/libGLESv2 + epoxy — the cairo renderer needs
|
|
106
|
-
// none, but a real window may negotiate GL), and librsvg (the SVG gdk-pixbuf loader
|
|
107
|
-
// that renders the Adwaita symbolic icons). Most GL/rsvg deps are pulled transitively
|
|
108
|
-
// by the loaders below; naming them keeps the closure complete even if a loader is
|
|
109
|
-
// missing. (Gdk/Gsk/Gtk are all in gtk-4-*.dll, already a base seed.)
|
|
110
|
-
const WINDOWING_SEED_PATTERNS = [
|
|
111
|
-
/^(lib)?adwaita-1.*\.dll$/i, // gvsbuild leaf: adwaita-1-0.dll (backs the Adw-1 typelib)
|
|
112
|
-
/^
|
|
113
|
-
/^
|
|
114
|
-
/^
|
|
115
|
-
/^
|
|
116
|
-
/^
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
//
|
|
121
|
-
//
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
//
|
|
138
|
-
//
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
'
|
|
151
|
-
'
|
|
152
|
-
'
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
const
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
//
|
|
168
|
-
//
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
if (
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
const
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
//
|
|
214
|
-
//
|
|
215
|
-
|
|
216
|
-
const
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
//
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
//
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
const
|
|
236
|
-
const
|
|
237
|
-
const
|
|
238
|
-
const
|
|
239
|
-
|
|
240
|
-
if (!
|
|
241
|
-
|
|
242
|
-
bundled.
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
//
|
|
250
|
-
//
|
|
251
|
-
//
|
|
252
|
-
//
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
//
|
|
294
|
-
//
|
|
295
|
-
//
|
|
296
|
-
//
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
//
|
|
301
|
-
//
|
|
302
|
-
//
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
const
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
.
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
//
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
//
|
|
338
|
-
//
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
//
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
//
|
|
388
|
-
//
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
}
|
|
407
|
-
|
|
408
|
-
//
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
const
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
const
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
);
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
// Collect a standalone, batteries-included GTK/GObject-Introspection runtime
|
|
3
|
+
// bundle for Windows x64 — so @gjsify/node-gi loads gi:// namespaces with NO
|
|
4
|
+
// gvsbuild/system GTK on the host (the Windows sibling of the darwin-arm64 bundle).
|
|
5
|
+
//
|
|
6
|
+
// node scripts/build-gtk-runtime.mjs [--out <dir>] [--prefix <gvsbuild GTK prefix>] [--windowing]
|
|
7
|
+
//
|
|
8
|
+
// Two closures, one bundle dir:
|
|
9
|
+
// • DEFAULT (display-free) — the loadable DLLs + typelibs the DISPLAY-FREE
|
|
10
|
+
// conformance needs (GLib/GObject/Gio/cairo/Pango/Graphene/Gdk). Unchanged.
|
|
11
|
+
// • --windowing (SUPERSET) — everything above PLUS the runtime data a REAL GTK
|
|
12
|
+
// WINDOW needs on Windows: the gdk-pixbuf loaders + `loaders.cache`, compiled
|
|
13
|
+
// GSettings schemas (`gschemas.compiled`), the Adwaita/hicolor icon themes +
|
|
14
|
+
// `icon-theme.cache`, and the Fontconfig config/cache. The extra image-loader
|
|
15
|
+
// backing DLLs (librsvg/png/…) are walked into `bin/` too. node-gi's loader
|
|
16
|
+
// (gtk-runtime.js) detects the windowing data (the `gschemas.compiled` marker)
|
|
17
|
+
// and wires the env (GSETTINGS_SCHEMA_DIR / GDK_PIXBUF_MODULE_FILE /
|
|
18
|
+
// XDG_DATA_DIRS / FONTCONFIG_*) so the SAME loader serves both — the display-free
|
|
19
|
+
// path is byte-unchanged when the windowing data is absent.
|
|
20
|
+
//
|
|
21
|
+
// Runs ONLY on win32/x64 with a build-time gvsbuild GTK4 stack extracted at
|
|
22
|
+
// --prefix (env GTK_PREFIX, the closure *source*, not shipped — the same tree the
|
|
23
|
+
// node-gi.yml windows jobs cache at C:\gtk-build\gtk\x64\release). gvsbuild bundles
|
|
24
|
+
// the tools this needs (gdk-pixbuf-query-loaders / glib-compile-schemas /
|
|
25
|
+
// gtk4-update-icon-cache / fc-cache) in <prefix>/bin.
|
|
26
|
+
//
|
|
27
|
+
// CRUCIAL DIFFERENCE FROM macOS: there is NO relocation step (no install_name_tool,
|
|
28
|
+
// no @rpath, no codesign). Windows resolves a DLL's imports by SEARCH PATH at
|
|
29
|
+
// LoadLibrary time, so a bundle is "portable" the moment its DLLs sit in one dir —
|
|
30
|
+
// node-gi just prepends <out>/bin to PATH before the addon loads. The runtime DATA
|
|
31
|
+
// (loaders/schemas/icons/fonts) is likewise resolved by env vars set at load time,
|
|
32
|
+
// no baked absolute paths (the caches are rewritten to bundle-relative).
|
|
33
|
+
//
|
|
34
|
+
// Reference: GJS ships no relocation; gvsbuild ships the MSVC-ABI GTK4 stack whose
|
|
35
|
+
// DLLs load into stock (MSVC-ABI) Node.
|
|
36
|
+
import { execFileSync } from 'node:child_process';
|
|
37
|
+
import {
|
|
38
|
+
copyFileSync,
|
|
39
|
+
cpSync,
|
|
40
|
+
existsSync,
|
|
41
|
+
mkdirSync,
|
|
42
|
+
readdirSync,
|
|
43
|
+
rmSync,
|
|
44
|
+
statSync,
|
|
45
|
+
writeFileSync,
|
|
46
|
+
} from 'node:fs';
|
|
47
|
+
import { basename, dirname, join } from 'node:path';
|
|
48
|
+
import { fileURLToPath } from 'node:url';
|
|
49
|
+
|
|
50
|
+
const pkgRoot = dirname(dirname(fileURLToPath(import.meta.url)));
|
|
51
|
+
|
|
52
|
+
// --- args ------------------------------------------------------------------
|
|
53
|
+
function argValue(flag) {
|
|
54
|
+
const i = process.argv.indexOf(flag);
|
|
55
|
+
return i >= 0 && i + 1 < process.argv.length ? process.argv[i + 1] : undefined;
|
|
56
|
+
}
|
|
57
|
+
const OUT = argValue('--out') ?? join(pkgRoot, 'gtk');
|
|
58
|
+
const PREFIX = argValue('--prefix') ?? process.env.GTK_PREFIX;
|
|
59
|
+
// The full-windowing SUPERSET: also collect the runtime data a real GTK window needs.
|
|
60
|
+
const WINDOWING = process.argv.includes('--windowing');
|
|
61
|
+
|
|
62
|
+
if (process.platform !== 'win32' || process.arch !== 'x64') {
|
|
63
|
+
console.error(`build-gtk-runtime: only supported on win32/x64, not ${process.platform}/${process.arch}`);
|
|
64
|
+
process.exit(2);
|
|
65
|
+
}
|
|
66
|
+
if (!PREFIX) {
|
|
67
|
+
console.error('build-gtk-runtime: no GTK prefix — pass --prefix or set GTK_PREFIX (e.g. C:\\gtk-build\\gtk\\x64\\release)');
|
|
68
|
+
process.exit(1);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const gtkBin = join(PREFIX, 'bin');
|
|
72
|
+
const gtkTypelibs = join(PREFIX, 'lib', 'girepository-1.0');
|
|
73
|
+
if (!existsSync(gtkBin)) {
|
|
74
|
+
console.error(`build-gtk-runtime: ${gtkBin} not found — extract the gvsbuild GTK4 stack first`);
|
|
75
|
+
process.exit(1);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const sh = (bin, args, opts) => execFileSync(bin, args, { encoding: 'utf8', ...opts });
|
|
79
|
+
|
|
80
|
+
// The seed DLLs of the DISPLAY-FREE conformance closure. Liberal, version-agnostic
|
|
81
|
+
// patterns matched against <prefix>/bin (gvsbuild's suffixes drift: glib-2.0-0.dll,
|
|
82
|
+
// girepository-2.0-0.dll, cairo-2.dll, pango-1.0-0.dll, gdk_pixbuf-2.0-0.dll,
|
|
83
|
+
// gtk-4-1.dll, harfbuzz.dll, …). The recursive dumpbin walk pulls every transitive
|
|
84
|
+
// gvsbuild dep (harfbuzz, fribidi, fontconfig, freetype, pixman, png, intl, pcre2,
|
|
85
|
+
// ffi, epoxy, zlib, …). gtk-4 is seeded because it backs the Gdk typelib the
|
|
86
|
+
// conformance's struct-construct loads (Gdk/Graphene) and transitively pulls
|
|
87
|
+
// pango/graphene/gdk-pixbuf/cairo/harfbuzz.
|
|
88
|
+
const SEED_PATTERNS = [
|
|
89
|
+
/^glib-2\.0-.*\.dll$/i,
|
|
90
|
+
/^gobject-2\.0-.*\.dll$/i,
|
|
91
|
+
/^gio-2\.0-.*\.dll$/i,
|
|
92
|
+
/^gmodule-2\.0-.*\.dll$/i,
|
|
93
|
+
/^girepository-[12]\.0-.*\.dll$/i, // girepository-2.0 (merged API) on modern gvsbuild
|
|
94
|
+
/^cairo(-gobject|-script-interpreter)?-?\d*\.dll$/i,
|
|
95
|
+
/^pango(cairo|ft2|win32)?-1\.0-.*\.dll$/i,
|
|
96
|
+
/^graphene-1\.0-.*\.dll$/i,
|
|
97
|
+
/^gdk[-_]pixbuf-2\.0-.*\.dll$/i,
|
|
98
|
+
/^gtk-4-.*\.dll$/i, // provides the Gdk typelib's backing library
|
|
99
|
+
/^harfbuzz.*\.dll$/i,
|
|
100
|
+
];
|
|
101
|
+
|
|
102
|
+
// Extra seeds for the WINDOWING superset: libadwaita (the Adw-1 typelib's backing
|
|
103
|
+
// DLL — a real Adw.Application/ApplicationWindow needs it; the display-free
|
|
104
|
+
// conformance never touches Adwaita, so it is NOT in the base seeds), the GL backing
|
|
105
|
+
// a GSK GL renderer picks (ANGLE libEGL/libGLESv2 + epoxy — the cairo renderer needs
|
|
106
|
+
// none, but a real window may negotiate GL), and librsvg (the SVG gdk-pixbuf loader
|
|
107
|
+
// that renders the Adwaita symbolic icons). Most GL/rsvg deps are pulled transitively
|
|
108
|
+
// by the loaders below; naming them keeps the closure complete even if a loader is
|
|
109
|
+
// missing. (Gdk/Gsk/Gtk are all in gtk-4-*.dll, already a base seed.)
|
|
110
|
+
const WINDOWING_SEED_PATTERNS = [
|
|
111
|
+
/^(lib)?adwaita-1.*\.dll$/i, // gvsbuild leaf: adwaita-1-0.dll (backs the Adw-1 typelib)
|
|
112
|
+
/^(lib)?gtksourceview-5.*\.dll$/i, // gvsbuild leaf: gtksourceview-5-0.dll (backs the GtkSource-5 typelib — the Learn6502 editor)
|
|
113
|
+
/^libEGL.*\.dll$/i,
|
|
114
|
+
/^libGLESv2.*\.dll$/i,
|
|
115
|
+
/^epoxy.*\.dll$/i,
|
|
116
|
+
/^rsvg.*\.dll$/i,
|
|
117
|
+
/^libxml2.*\.dll$/i,
|
|
118
|
+
];
|
|
119
|
+
|
|
120
|
+
// Locate an MSVC/gvsbuild tool: env override, then the gvsbuild <prefix>/bin
|
|
121
|
+
// (gvsbuild ships gdk-pixbuf-query-loaders / glib-compile-schemas /
|
|
122
|
+
// gtk4-update-icon-cache / fc-cache there), then PATH. Null when absent.
|
|
123
|
+
function findTool(leaf, envVar) {
|
|
124
|
+
const envd = envVar && process.env[envVar];
|
|
125
|
+
if (envd && existsSync(envd)) return envd;
|
|
126
|
+
const inBin = join(gtkBin, leaf);
|
|
127
|
+
if (existsSync(inBin)) return inBin;
|
|
128
|
+
try {
|
|
129
|
+
const p = sh('where', [leaf.replace(/\.exe$/i, '')]).split(/\r?\n/).map((s) => s.trim()).filter(Boolean)[0];
|
|
130
|
+
if (p && existsSync(p)) return p;
|
|
131
|
+
} catch {
|
|
132
|
+
// not on PATH
|
|
133
|
+
}
|
|
134
|
+
return null;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// Locate dumpbin (MSVC): env override, then PATH (a dev-cmd/vcvars job), then
|
|
138
|
+
// vswhere's -find glob into the VC toolchain. Null when unavailable → the caller
|
|
139
|
+
// falls back to copying the whole bin/ DLL set.
|
|
140
|
+
function findDumpbin() {
|
|
141
|
+
const envd = process.env.DUMPBIN;
|
|
142
|
+
if (envd && existsSync(envd)) return envd;
|
|
143
|
+
try {
|
|
144
|
+
const p = sh('where', ['dumpbin']).split(/\r?\n/).map((s) => s.trim()).filter(Boolean)[0];
|
|
145
|
+
if (p && existsSync(p)) return p;
|
|
146
|
+
} catch {
|
|
147
|
+
// not on PATH
|
|
148
|
+
}
|
|
149
|
+
const vswhere = join(
|
|
150
|
+
process.env['ProgramFiles(x86)'] || 'C:\\Program Files (x86)',
|
|
151
|
+
'Microsoft Visual Studio',
|
|
152
|
+
'Installer',
|
|
153
|
+
'vswhere.exe',
|
|
154
|
+
);
|
|
155
|
+
if (existsSync(vswhere)) {
|
|
156
|
+
try {
|
|
157
|
+
const out = sh(vswhere, ['-latest', '-products', '*', '-find', '**\\Hostx64\\x64\\dumpbin.exe']);
|
|
158
|
+
const p = out.split(/\r?\n/).map((s) => s.trim()).filter(Boolean)[0];
|
|
159
|
+
if (p && existsSync(p)) return p;
|
|
160
|
+
} catch {
|
|
161
|
+
// vswhere present but no match
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
return null;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// Parse `dumpbin /dependents <dll>` into the list of imported DLL leaf names (both
|
|
168
|
+
// normal + delay-load sections; stop at the Summary). Exit-tolerant: dumpbin can
|
|
169
|
+
// print the section then exit non-zero on some inputs — capture the attached stdout.
|
|
170
|
+
function dumpbinDeps(dumpbin, dllPath) {
|
|
171
|
+
let out;
|
|
172
|
+
try {
|
|
173
|
+
out = sh(dumpbin, ['/nologo', '/dependents', dllPath]);
|
|
174
|
+
} catch (error) {
|
|
175
|
+
out = typeof error?.stdout === 'string' ? error.stdout : '';
|
|
176
|
+
}
|
|
177
|
+
const deps = [];
|
|
178
|
+
let inDeps = false;
|
|
179
|
+
for (const raw of out.split(/\r?\n/)) {
|
|
180
|
+
const line = raw.replace(/\s+$/, '');
|
|
181
|
+
if (/following (delay load )?dependencies:/i.test(line)) {
|
|
182
|
+
inDeps = true;
|
|
183
|
+
continue;
|
|
184
|
+
}
|
|
185
|
+
if (/^\s*Summary/i.test(line)) break;
|
|
186
|
+
if (inDeps) {
|
|
187
|
+
const m = line.match(/^\s+([A-Za-z0-9_.+-]+\.dll)\s*$/i);
|
|
188
|
+
if (m) deps.push(m[1]);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
return deps;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
// --- 1. discover the closure ----------------------------------------------
|
|
195
|
+
console.log(`build-gtk-runtime: gvsbuild prefix ${PREFIX}${WINDOWING ? ' (windowing superset)' : ' (display-free)'}`);
|
|
196
|
+
// leaf(lower) -> actual on-disk filename in <prefix>/bin
|
|
197
|
+
const binFiles = new Map();
|
|
198
|
+
for (const f of readdirSync(gtkBin)) {
|
|
199
|
+
if (f.toLowerCase().endsWith('.dll')) binFiles.set(f.toLowerCase(), f);
|
|
200
|
+
}
|
|
201
|
+
if (binFiles.size === 0) {
|
|
202
|
+
console.error(`build-gtk-runtime: no DLLs under ${gtkBin} — is the GTK stack extracted?`);
|
|
203
|
+
process.exit(1);
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
const seedPatterns = WINDOWING ? [...SEED_PATTERNS, ...WINDOWING_SEED_PATTERNS] : SEED_PATTERNS;
|
|
207
|
+
const seeds = [...binFiles.values()].filter((f) => seedPatterns.some((re) => re.test(f)));
|
|
208
|
+
if (seeds.length === 0) {
|
|
209
|
+
console.error('build-gtk-runtime: no seed DLLs matched — check the gvsbuild layout / SEED_PATTERNS');
|
|
210
|
+
process.exit(1);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
// Windowing: the gdk-pixbuf loaders (SVG/PNG/… image decoders GTK dlopen's for
|
|
214
|
+
// icons) live OUTSIDE bin/ — their backing libs (librsvg, …) must still land in
|
|
215
|
+
// bin/, so seed the closure walk with each loader DLL so its dumpbin walk pulls them.
|
|
216
|
+
const gdkPixbufLoaderDir = join(PREFIX, 'lib', 'gdk-pixbuf-2.0', '2.10.0', 'loaders');
|
|
217
|
+
const loaderSeeds = [];
|
|
218
|
+
if (WINDOWING && existsSync(gdkPixbufLoaderDir)) {
|
|
219
|
+
for (const f of readdirSync(gdkPixbufLoaderDir)) {
|
|
220
|
+
if (f.toLowerCase().endsWith('.dll')) loaderSeeds.push(join(gdkPixbufLoaderDir, f));
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
console.log(`build-gtk-runtime: ${seeds.length} seed DLLs${loaderSeeds.length ? ` + ${loaderSeeds.length} pixbuf loaders` : ''}`);
|
|
224
|
+
|
|
225
|
+
const dumpbin = findDumpbin();
|
|
226
|
+
// leaf(lower) -> actual filename (source in <prefix>/bin); '\0loader:'-prefixed keys
|
|
227
|
+
// are walked-but-not-bin-copied loader sentinels.
|
|
228
|
+
const bundled = new Map();
|
|
229
|
+
if (dumpbin) {
|
|
230
|
+
console.log(`build-gtk-runtime: walking the DLL closure with ${dumpbin}`);
|
|
231
|
+
// Seed with bin/ seeds (leaf names) + external loader DLLs (full paths) so THEIR
|
|
232
|
+
// deps are walked into bin/ even though the loaders live outside bin/.
|
|
233
|
+
const queue = [...seeds, ...loaderSeeds];
|
|
234
|
+
while (queue.length) {
|
|
235
|
+
const entry = queue.shift();
|
|
236
|
+
const isPath = entry.includes('\\') || entry.includes('/');
|
|
237
|
+
const leaf = isPath ? basename(entry) : entry;
|
|
238
|
+
const lower = leaf.toLowerCase();
|
|
239
|
+
const src = isPath ? entry : binFiles.get(lower);
|
|
240
|
+
if (!src) continue; // system / non-gvsbuild dep — leave as OS-provided
|
|
241
|
+
if (!isPath) {
|
|
242
|
+
if (bundled.has(lower)) continue;
|
|
243
|
+
bundled.set(lower, src);
|
|
244
|
+
} else if (bundled.has('\0loader:' + lower)) {
|
|
245
|
+
continue;
|
|
246
|
+
} else {
|
|
247
|
+
bundled.set('\0loader:' + lower, null); // walked, not bin-copied (copied below)
|
|
248
|
+
}
|
|
249
|
+
// dumpbin needs the ABSOLUTE path: a bin/ entry's `src` is a bare filename
|
|
250
|
+
// (leaf), so resolve it under <prefix>/bin; a loader entry's `src` is already
|
|
251
|
+
// a full path. Passing the bare leaf made dumpbin find nothing → the closure
|
|
252
|
+
// never grew past the seeds → the transitive DLLs (ffi/intl/pcre2/zlib/…)
|
|
253
|
+
// were dropped and the addon failed to dlopen.
|
|
254
|
+
const walkPath = isPath ? src : join(gtkBin, src);
|
|
255
|
+
for (const dep of dumpbinDeps(dumpbin, walkPath)) {
|
|
256
|
+
const dl = dep.toLowerCase();
|
|
257
|
+
if (!bundled.has(dl) && binFiles.has(dl)) queue.push(dep);
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
} else {
|
|
261
|
+
console.warn(
|
|
262
|
+
'build-gtk-runtime: WARNING — dumpbin not found (no MSVC / vswhere); falling back to copying the FULL bin/*.dll set (a complete but larger superset).',
|
|
263
|
+
);
|
|
264
|
+
for (const [lower, src] of binFiles) bundled.set(lower, src);
|
|
265
|
+
}
|
|
266
|
+
// Real bin/ DLLs only (drop the walked-loader sentinels).
|
|
267
|
+
const binDlls = new Map([...bundled].filter(([k, v]) => v !== null && !k.startsWith('\0loader:')));
|
|
268
|
+
console.log(`build-gtk-runtime: closure = ${binDlls.size} DLLs`);
|
|
269
|
+
|
|
270
|
+
// --- 2. copy DLLs (no relocation — Windows resolves by search path) -------
|
|
271
|
+
const binOut = join(OUT, 'bin');
|
|
272
|
+
rmSync(OUT, { recursive: true, force: true });
|
|
273
|
+
mkdirSync(binOut, { recursive: true });
|
|
274
|
+
for (const src of binDlls.values()) {
|
|
275
|
+
copyFileSync(join(gtkBin, src), join(binOut, src));
|
|
276
|
+
}
|
|
277
|
+
console.log(`build-gtk-runtime: copied ${binDlls.size} DLLs -> ${binOut}`);
|
|
278
|
+
|
|
279
|
+
// --- 3. typelibs -----------------------------------------------------------
|
|
280
|
+
const typelibOut = join(OUT, 'girepository-1.0');
|
|
281
|
+
mkdirSync(typelibOut, { recursive: true });
|
|
282
|
+
let typelibCount = 0;
|
|
283
|
+
if (existsSync(gtkTypelibs)) {
|
|
284
|
+
for (const f of readdirSync(gtkTypelibs)) {
|
|
285
|
+
if (f.endsWith('.typelib')) {
|
|
286
|
+
copyFileSync(join(gtkTypelibs, f), join(typelibOut, f));
|
|
287
|
+
typelibCount++;
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
console.log(`build-gtk-runtime: copied ${typelibCount} typelibs`);
|
|
292
|
+
|
|
293
|
+
// --- 4. WINDOWING data (loaders / schemas / icons / fonts) ----------------
|
|
294
|
+
// Each step is independent + defensive: a missing tree/tool WARNS + continues so a
|
|
295
|
+
// partial gvsbuild layout still produces the DLL+typelib bundle. The DATA marker
|
|
296
|
+
// node-gi keys on is gschemas.compiled; if that step fails the loader treats the
|
|
297
|
+
// bundle as display-free (no windowing env wired).
|
|
298
|
+
const windowing = { pixbufLoaders: 0, schemas: false, iconThemes: [], fontconfig: false, gtksource: false };
|
|
299
|
+
if (WINDOWING) {
|
|
300
|
+
// 4a. gdk-pixbuf loaders + a bundle-relative loaders.cache. The cache maps each
|
|
301
|
+
// decoder DLL to its mime/extensions; gdk-pixbuf resolves the DLL paths in it
|
|
302
|
+
// relative to GDK_PIXBUF_MODULEDIR when set (node-gi sets it), so we rewrite the
|
|
303
|
+
// absolute build paths the query tool emits down to leaf names.
|
|
304
|
+
if (existsSync(gdkPixbufLoaderDir)) {
|
|
305
|
+
const loadersOut = join(OUT, 'lib', 'gdk-pixbuf-2.0', '2.10.0', 'loaders');
|
|
306
|
+
mkdirSync(loadersOut, { recursive: true });
|
|
307
|
+
for (const f of readdirSync(gdkPixbufLoaderDir)) {
|
|
308
|
+
if (f.toLowerCase().endsWith('.dll')) {
|
|
309
|
+
copyFileSync(join(gdkPixbufLoaderDir, f), join(loadersOut, f));
|
|
310
|
+
windowing.pixbufLoaders++;
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
const queryTool = findTool('gdk-pixbuf-query-loaders.exe', 'GDK_PIXBUF_QUERY_LOADERS');
|
|
314
|
+
const cacheOut = join(OUT, 'lib', 'gdk-pixbuf-2.0', '2.10.0', 'loaders.cache');
|
|
315
|
+
if (queryTool && windowing.pixbufLoaders > 0) {
|
|
316
|
+
const loaderPaths = readdirSync(loadersOut)
|
|
317
|
+
.filter((f) => f.toLowerCase().endsWith('.dll'))
|
|
318
|
+
.map((f) => join(loadersOut, f));
|
|
319
|
+
let cache = '';
|
|
320
|
+
try {
|
|
321
|
+
cache = sh(queryTool, loaderPaths);
|
|
322
|
+
} catch (error) {
|
|
323
|
+
cache = typeof error?.stdout === 'string' ? error.stdout : '';
|
|
324
|
+
}
|
|
325
|
+
// A loader header line is a quoted absolute path; strip it to the leaf so
|
|
326
|
+
// GDK_PIXBUF_MODULEDIR resolves it in the consumer's bundle.
|
|
327
|
+
const rel = cache.replace(/^"(.*[\\/])?([^"\\/]+\.dll)"\s*$/gim, '"$2"');
|
|
328
|
+
writeFileSync(cacheOut, rel);
|
|
329
|
+
console.log(`build-gtk-runtime: wrote loaders.cache (${windowing.pixbufLoaders} loaders, bundle-relative)`);
|
|
330
|
+
} else {
|
|
331
|
+
console.warn('build-gtk-runtime: WARNING — gdk-pixbuf-query-loaders not found; loaders.cache NOT generated (SVG/PNG icons may not load)');
|
|
332
|
+
}
|
|
333
|
+
} else {
|
|
334
|
+
console.warn(`build-gtk-runtime: WARNING — ${gdkPixbufLoaderDir} missing; no gdk-pixbuf loaders bundled`);
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
// 4b. Compiled GSettings schemas (GTK/Adwaita read org.gnome.desktop.interface
|
|
338
|
+
// etc. at startup). Copy every schema found (GTK's own + gsettings-desktop-
|
|
339
|
+
// schemas if gvsbuild shipped it) and (re)compile gschemas.compiled.
|
|
340
|
+
const schemasSrc = join(PREFIX, 'share', 'glib-2.0', 'schemas');
|
|
341
|
+
if (existsSync(schemasSrc)) {
|
|
342
|
+
const schemasOut = join(OUT, 'share', 'glib-2.0', 'schemas');
|
|
343
|
+
mkdirSync(schemasOut, { recursive: true });
|
|
344
|
+
for (const f of readdirSync(schemasSrc)) {
|
|
345
|
+
if (f.endsWith('.xml') || f.endsWith('.gschema.override') || f === 'gschemas.compiled') {
|
|
346
|
+
copyFileSync(join(schemasSrc, f), join(schemasOut, f));
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
const compileTool = findTool('glib-compile-schemas.exe', 'GLIB_COMPILE_SCHEMAS');
|
|
350
|
+
if (compileTool) {
|
|
351
|
+
try {
|
|
352
|
+
sh(compileTool, [schemasOut]);
|
|
353
|
+
} catch (error) {
|
|
354
|
+
console.warn(`build-gtk-runtime: WARNING — glib-compile-schemas failed: ${error?.message ?? error}`);
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
windowing.schemas = existsSync(join(schemasOut, 'gschemas.compiled'));
|
|
358
|
+
console.log(`build-gtk-runtime: GSettings schemas ${windowing.schemas ? 'compiled' : 'copied (no gschemas.compiled!)'}`);
|
|
359
|
+
} else {
|
|
360
|
+
console.warn(`build-gtk-runtime: WARNING — ${schemasSrc} missing; GSettings schemas NOT bundled (GTK settings reads will fail)`);
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
// 4c. Icon themes (Adwaita for symbolic icons + hicolor fallback) + caches. The
|
|
364
|
+
// theme is loaded from XDG_DATA_DIRS/icons/<theme>/ (node-gi prepends <bundle>/share).
|
|
365
|
+
const updateIconCache = findTool('gtk4-update-icon-cache.exe', 'GTK4_UPDATE_ICON_CACHE')
|
|
366
|
+
?? findTool('gtk-update-icon-cache.exe', 'GTK_UPDATE_ICON_CACHE');
|
|
367
|
+
for (const theme of ['Adwaita', 'hicolor']) {
|
|
368
|
+
const themeSrc = join(PREFIX, 'share', 'icons', theme);
|
|
369
|
+
if (!existsSync(themeSrc)) continue;
|
|
370
|
+
const themeOut = join(OUT, 'share', 'icons', theme);
|
|
371
|
+
cpSync(themeSrc, themeOut, { recursive: true });
|
|
372
|
+
if (updateIconCache) {
|
|
373
|
+
try {
|
|
374
|
+
sh(updateIconCache, ['-q', '-t', '-f', themeOut]);
|
|
375
|
+
} catch {
|
|
376
|
+
// an existing icon-theme.cache from the copy is a usable fallback
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
windowing.iconThemes.push(theme);
|
|
380
|
+
}
|
|
381
|
+
console.log(
|
|
382
|
+
windowing.iconThemes.length
|
|
383
|
+
? `build-gtk-runtime: icon themes ${windowing.iconThemes.join(', ')}${updateIconCache ? ' (cache refreshed)' : ' (no update-icon-cache tool — copied caches)'}`
|
|
384
|
+
: 'build-gtk-runtime: WARNING — no Adwaita/hicolor icon theme found under share/icons (symbolic icons may be blank)',
|
|
385
|
+
);
|
|
386
|
+
|
|
387
|
+
// 4d. Fontconfig config + cache. GTK4-on-Windows text usually goes through the
|
|
388
|
+
// DirectWrite/pangowin32 backend (no fontconfig), but gvsbuild's pango can be
|
|
389
|
+
// fontconfig-backed; ship etc/fonts + a cache when present so either path works.
|
|
390
|
+
const fontsSrc = join(PREFIX, 'etc', 'fonts');
|
|
391
|
+
if (existsSync(fontsSrc)) {
|
|
392
|
+
const fontsOut = join(OUT, 'etc', 'fonts');
|
|
393
|
+
cpSync(fontsSrc, fontsOut, { recursive: true });
|
|
394
|
+
const fcCache = findTool('fc-cache.exe', 'FC_CACHE');
|
|
395
|
+
if (fcCache) {
|
|
396
|
+
try {
|
|
397
|
+
sh(fcCache, ['-f', fontsOut], { env: { ...process.env, FONTCONFIG_PATH: fontsOut } });
|
|
398
|
+
} catch {
|
|
399
|
+
// best-effort — Pango's win32 backend does not need the cache
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
windowing.fontconfig = true;
|
|
403
|
+
console.log('build-gtk-runtime: fontconfig config bundled');
|
|
404
|
+
} else {
|
|
405
|
+
console.log('build-gtk-runtime: no etc/fonts (pango uses the win32/DirectWrite backend) — skipping fontconfig');
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
// 4e. GtkSource-5 runtime DATA: the syntax-highlighting language definitions
|
|
409
|
+
// (share/gtksourceview-5/language-specs/*.lang) + style schemes
|
|
410
|
+
// (share/gtksourceview-5/styles/*.xml). GtkSource's LanguageManager /
|
|
411
|
+
// StyleSchemeManager load these from XDG_DATA_DIRS/gtksourceview-5 (node-gi
|
|
412
|
+
// prepends <bundle>/share), so without them the Learn6502 editor's GtkSource.View
|
|
413
|
+
// constructs but has no built-in languages/styles. Defensive: WARN + continue if
|
|
414
|
+
// gvsbuild's layout lacks the tree (the DLL + typelib still ship, so GtkSource
|
|
415
|
+
// itself works — only the bundled highlight data is absent).
|
|
416
|
+
const gtksourceSrc = join(PREFIX, 'share', 'gtksourceview-5');
|
|
417
|
+
if (existsSync(gtksourceSrc)) {
|
|
418
|
+
const gtksourceOut = join(OUT, 'share', 'gtksourceview-5');
|
|
419
|
+
let copied = 0;
|
|
420
|
+
for (const sub of ['language-specs', 'styles']) {
|
|
421
|
+
const subSrc = join(gtksourceSrc, sub);
|
|
422
|
+
if (existsSync(subSrc)) {
|
|
423
|
+
cpSync(subSrc, join(gtksourceOut, sub), { recursive: true });
|
|
424
|
+
copied += readdirSync(subSrc).length;
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
windowing.gtksource = copied > 0;
|
|
428
|
+
console.log(`build-gtk-runtime: GtkSource-5 data ${windowing.gtksource ? `bundled (${copied} language-specs/styles files)` : 'directory present but empty'}`);
|
|
429
|
+
} else {
|
|
430
|
+
console.warn(`build-gtk-runtime: WARNING — ${gtksourceSrc} missing; GtkSource-5 language-specs/styles NOT bundled (the editor's built-in highlighting will be unavailable)`);
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
// --- manifest + size -------------------------------------------------------
|
|
435
|
+
function dirSize(dir) {
|
|
436
|
+
if (!existsSync(dir)) return 0;
|
|
437
|
+
let total = 0;
|
|
438
|
+
for (const f of readdirSync(dir, { withFileTypes: true })) {
|
|
439
|
+
const p = join(dir, f.name);
|
|
440
|
+
total += f.isDirectory() ? dirSize(p) : statSync(p).size;
|
|
441
|
+
}
|
|
442
|
+
return total;
|
|
443
|
+
}
|
|
444
|
+
const binBytes = dirSize(binOut);
|
|
445
|
+
const typelibBytes = dirSize(typelibOut);
|
|
446
|
+
const dataBytes = WINDOWING ? dirSize(join(OUT, 'lib')) + dirSize(join(OUT, 'share')) + dirSize(join(OUT, 'etc')) : 0;
|
|
447
|
+
const manifest = {
|
|
448
|
+
platform: 'win32-x64',
|
|
449
|
+
windowing: WINDOWING,
|
|
450
|
+
generatedFrom: PREFIX,
|
|
451
|
+
walkedWith: dumpbin ? 'dumpbin' : 'copy-all-fallback',
|
|
452
|
+
dlls: binDlls.size,
|
|
453
|
+
typelibs: typelibCount,
|
|
454
|
+
binBytes,
|
|
455
|
+
typelibBytes,
|
|
456
|
+
dataBytes,
|
|
457
|
+
totalBytes: binBytes + typelibBytes + dataBytes,
|
|
458
|
+
dllList: [...binDlls.values()].map((f) => basename(f)).sort((a, b) => a.localeCompare(b)),
|
|
459
|
+
...(WINDOWING ? { windowingData: windowing } : {}),
|
|
460
|
+
};
|
|
461
|
+
writeFileSync(join(OUT, 'manifest.json'), JSON.stringify(manifest, null, 2));
|
|
462
|
+
|
|
463
|
+
const mb = (n) => (n / 1024 / 1024).toFixed(1);
|
|
464
|
+
console.log(
|
|
465
|
+
`build-gtk-runtime: DONE -> ${OUT}\n` +
|
|
466
|
+
` DLLs: ${binDlls.size} (${mb(binBytes)} MiB)\n` +
|
|
467
|
+
` typelibs: ${typelibCount} (${mb(typelibBytes)} MiB)\n` +
|
|
468
|
+
(WINDOWING
|
|
469
|
+
? ` data: loaders=${windowing.pixbufLoaders} schemas=${windowing.schemas} icons=[${windowing.iconThemes.join(',')}] fontconfig=${windowing.fontconfig} (${mb(dataBytes)} MiB)\n`
|
|
470
|
+
: '') +
|
|
471
|
+
` total: ${mb(manifest.totalBytes)} MiB`,
|
|
472
|
+
);
|