build: fix flatpak/snap, restore rpath opt, fix local gtk4-layer-shell (#13677)

This fixes regressions in the flatpak/snap builds, and knock-on stuff
that was discovered as as a result:

* Update the Zig versions in the flatpak/snap build configuration files.
* Restore the classic `-Dpatch-rpath` option, and add a new
`-Dpatch-interp` option. This ensures that the snap can still use
`-Dpatch-rpath` correctly.
* There seems to be an issue in Zig when parsing IPv6 addresses that
leads to issues loading `resolv.conf` files; when trying to load a
nameserver that has an IPv6 address with a numeric interface index as
the scoped zone ID, Zig will try to resolve the interface as a name
rather than just use the index. This is coming up in snap builds because
the build process seems to, by default, use the exhaustive
`/run/systemd/resolve/resolv.conf` file, versus the simpler stub
(`stub-resolv.conf`) file. We work around this for the time being by
linking the stub at the end of the Zig part, overwriting the link to the
non-stub file.
* Fixed `gtk4-layer-shell` packaging - the migration to external
translate-c meant that non-system builds of the dependency were not
handing the local `gtk4-layer-shell` headers over for translation. Now,
instead, we've extracted the management of the `gtk4-layer-shell` source
and `wayland-protocols` generation to a locally-cached object so that
the source can be shared by both C translation and the library build in
a way that is not coupled to any particular step.
This commit is contained in:
Mitchell Hashimoto
2026-08-07 07:52:31 -07:00
committed by GitHub
4 changed files with 144 additions and 73 deletions

View File

@@ -333,22 +333,39 @@ pub fn init(b: *std.Build, appVersion: []const u8, libVersion: []const u8) !Conf
// may be fixed in 0.17.0. We may want to revisit this afterwards; although
// I'm not too sure if that helps to clean up rpath, this may just be the
// better option. See https://codeberg.org/ziglang/zig/issues/31760.
if ((target.result.os.tag == .linux) and target.query.isNativeCpu()) {
const in_nix_shell = env.get("IN_NIX_SHELL") != null;
if (b.option(
bool,
"patchelf",
"Patch interpreter and rpath in the built binary (default if IN_NIX_SHELL is set)",
) orelse in_nix_shell) {
var patchelf: PatchElf = .{};
if (b.findProgram(&.{"ld.so"}, &.{})) |ld_so| {
patchelf.interp = std.Io.Dir.realPathFileAbsoluteAlloc(b.graph.io, ld_so, b.allocator) catch null;
} else |_| {}
if (env.get("LD_LIBRARY_PATH")) |ld_library_path| {
patchelf.rpath = if (ld_library_path.len > 0) ld_library_path else null;
}
if (patchelf.interp != null or patchelf.rpath != null) {
config.patchelf = patchelf;
if (b.option(
[]const u8,
"patch-interp",
"Inject the supplied path as the dynamic linker in the built binary. " ++
"Under Nix, this defaults to the dynamic linker found in PATH.",
)) |interp| {
PatchElf.setInterp(&config, interp);
} else patch_interp: {
if (!(target.result.os.tag == .linux) or !target.query.isNativeCpu()) break :patch_interp;
if (env.get("IN_NIX_SHELL") == null) break :patch_interp;
if (b.findProgram(&.{"ld.so"}, &.{})) |ld_so| {
PatchElf.setInterp(
&config,
std.Io.Dir.realPathFileAbsoluteAlloc(b.graph.io, ld_so, b.allocator) catch break :patch_interp,
);
} else |_| {}
}
if (b.option(
[]const u8,
"patch-rpath",
"Inject the supplied colon-delimited search path as the rpath in the built binary. " ++
"This defaults to LD_LIBRARY_PATH if we're in a Nix shell environment.",
)) |rpath| {
PatchElf.setRpath(&config, rpath);
} else patch_rpath: {
if (!(target.result.os.tag == .linux) or !target.query.isNativeCpu()) break :patch_rpath;
if (env.get("IN_NIX_SHELL") == null) break :patch_rpath;
if (env.get("LD_LIBRARY_PATH")) |ld_library_path| {
if (ld_library_path.len > 0) {
PatchElf.setRpath(&config, ld_library_path);
}
}
}
@@ -543,6 +560,24 @@ pub fn init(b: *std.Build, appVersion: []const u8, libVersion: []const u8) !Conf
const PatchElf = struct {
interp: ?[]const u8 = null,
rpath: ?[]const u8 = null,
fn setInterp(config: *Config, interp: []const u8) void {
if (config.patchelf) |*patchelf| {
patchelf.interp = interp;
return;
}
config.patchelf = .{ .interp = interp };
}
fn setRpath(config: *Config, rpath: []const u8) void {
if (config.patchelf) |*patchelf| {
patchelf.rpath = rpath;
return;
}
config.patchelf = .{ .rpath = rpath };
}
};
/// Add a patchelf step for the supplied `artifact`, depending on the supplied