all: instrument library loading

This commit is contained in:
Tristan Crawford 2024-12-31 17:21:47 -05:00 committed by Emi Gutekanst
parent c56d596ea9
commit 41ddd2249f
10 changed files with 41 additions and 16 deletions

View file

@ -274,7 +274,7 @@ const LibXkbCommon = struct {
pub fn load() !LibXkbCommon {
var lib: LibXkbCommon = undefined;
lib.handle = std.DynLib.open("libxkbcommon.so.0") catch return error.LibraryNotFound;
lib.handle = try mach.dynLibOpen("libxkbcommon.so.0");
inline for (@typeInfo(LibXkbCommon).@"struct".fields[1..]) |field| {
const name = std.fmt.comptimePrint("{s}\x00", .{field.name});
const name_z: [:0]const u8 = @ptrCast(name[0 .. name.len - 1]);
@ -327,7 +327,7 @@ const LibWaylandClient = struct {
pub fn load() !LibWaylandClient {
var lib: LibWaylandClient = undefined;
lib.handle = std.DynLib.open("libwayland-client.so.0") catch return error.LibraryNotFound;
lib.handle = try mach.dynLibOpen("libwayland-client.so.0");
inline for (@typeInfo(LibWaylandClient).@"struct".fields[1..]) |field| {
const name = std.fmt.comptimePrint("{s}\x00", .{field.name});
const name_z: [:0]const u8 = @ptrCast(name[0 .. name.len - 1]);

View file

@ -439,7 +439,7 @@ const LibX11 = struct {
XFree: *const @TypeOf(c.XFree),
pub fn load() !LibX11 {
var lib: LibX11 = undefined;
lib.handle = std.DynLib.open("libX11.so.6") catch return error.LibraryNotFound;
lib.handle = try mach.dynLibOpen("libX11.so.6");
inline for (@typeInfo(LibX11).@"struct".fields[1..]) |field| {
const name = std.fmt.comptimePrint("{s}\x00", .{field.name});
const name_z: [:0]const u8 = @ptrCast(name[0 .. name.len - 1]);
@ -459,7 +459,7 @@ const LibXCursor = struct {
XcursorLibraryLoadImage: *const @TypeOf(c.XcursorLibraryLoadImage),
pub fn load() !LibXCursor {
var lib: LibXCursor = undefined;
lib.handle = std.DynLib.open("libXcursor.so.1") catch return error.LibraryNotFound;
lib.handle = try mach.dynLibOpen("libXcursor.so.1");
inline for (@typeInfo(LibXCursor).@"struct".fields[1..]) |field| {
const name = std.fmt.comptimePrint("{s}\x00", .{field.name});
const name_z: [:0]const u8 = @ptrCast(name[0 .. name.len - 1]);
@ -475,7 +475,7 @@ const LibXRR = struct {
XRRConfigCurrentRate: *const @TypeOf(c.XRRConfigCurrentRate),
pub fn load() !LibXRR {
var lib: LibXRR = undefined;
lib.handle = std.DynLib.open("libXrandr.so.1") catch return error.LibraryNotFound;
lib.handle = try mach.dynLibOpen("libXrandr.so.1");
inline for (@typeInfo(LibXRR).@"struct".fields[1..]) |field| {
const name = std.fmt.comptimePrint("{s}\x00", .{field.name});
const name_z: [:0]const u8 = @ptrCast(name[0 .. name.len - 1]);
@ -506,7 +506,7 @@ const LibGL = struct {
glXSwapBuffers: *const fn (*c.Display, Drawable) callconv(.C) bool,
pub fn load() !LibGL {
var lib: LibGL = undefined;
lib.handle = std.DynLib.open("libGL.so.1") catch return error.LibraryNotFound;
lib.handle = try mach.dynLibOpen("libGL.so.1");
inline for (@typeInfo(LibGL).@"struct".fields[1..]) |field| {
const name = std.fmt.comptimePrint("{s}\x00", .{field.name});
const name_z: [:0]const u8 = @ptrCast(name[0 .. name.len - 1]);
@ -538,7 +538,7 @@ const LibXkbCommon = struct {
pub fn load() !LibXkbCommon {
var lib: LibXkbCommon = undefined;
lib.handle = std.DynLib.open("libxkbcommon.so.0") catch return error.LibraryNotFound;
lib.handle = try mach.dynLibOpen("libxkbcommon.so.0");
inline for (@typeInfo(LibXkbCommon).@"struct".fields[1..]) |field| {
const name = std.fmt.comptimePrint("{s}\x00", .{field.name});
const name_z: [:0]const u8 = @ptrCast(name[0 .. name.len - 1]);

View file

@ -1,5 +1,6 @@
const std = @import("std");
const builtin = @import("builtin");
const mach = @import("main.zig");
const log = std.log.scoped(.gamemode);
@ -100,9 +101,9 @@ const linux_impl = struct {
pub fn tryInit() LoadError!void {
if (state == .init) return;
var dl = std.DynLib.open("libgamemode.so.0") catch |e| switch (e) {
var dl = mach.dynLibOpen("libgamemode.so.0") catch |e| switch (e) {
// backwards-compatibility for old gamemode versions
error.FileNotFound => try std.DynLib.open("libgamemode.so"),
error.LibraryNotFound => try mach.dynLibOpen("libgamemode.so"),
else => return e,
};
errdefer dl.close();
@ -128,7 +129,7 @@ const linux_impl = struct {
.failed => return false,
.uninit => {
tryInit() catch |e| {
if (e != error.FileNotFound) {
if (e != error.LibraryNotFound) {
log.warn("Loading gamemode: '{}'. Disabling libgamemode support.", .{e});
}
state = .failed;

View file

@ -4,6 +4,8 @@ const build_options = @import("build-options");
const builtin = @import("builtin");
const std = @import("std");
const log = std.log.scoped(.mach);
pub const is_debug = builtin.mode == .Debug;
// Core
@ -35,6 +37,20 @@ pub fn schedule(v: anytype) @TypeOf(v) {
return v;
}
// Instrumented function to load system libraries and print nicer error
// messages.
pub inline fn dynLibOpen(libName: []const u8) !std.DynLib {
return std.DynLib.open(libName) catch |err| {
switch (err) {
error.FileNotFound => {
log.err("Missing system library: '{s}'!", .{libName});
return error.LibraryNotFound;
},
else => return err,
}
};
}
test {
// TODO: refactor code so we can use this here:
// std.testing.refAllDeclsRecursive(@This());

View file

@ -3,6 +3,8 @@ const c = @cImport(@cInclude("alsa/asoundlib.h"));
const main = @import("main.zig");
const backends = @import("backends.zig");
const util = @import("util.zig");
const mach = @import("../main.zig");
const inotify_event = std.os.linux.inotify_event;
const is_little = @import("builtin").cpu.arch.endian() == .little;
@ -69,7 +71,7 @@ const Lib = struct {
snd_mixer_selem_has_capture_channel: *const fn (?*c.snd_mixer_elem_t, c.snd_mixer_selem_channel_id_t) callconv(.C) c_int,
pub fn load() !void {
lib.handle = std.DynLib.open("libasound.so") catch return error.LibraryNotFound;
lib.handle = try mach.dynLibOpen("libasound.so");
inline for (@typeInfo(Lib).@"struct".fields[1..]) |field| {
const name = std.fmt.comptimePrint("{s}\x00", .{field.name});
const name_z: [:0]const u8 = @ptrCast(name[0 .. name.len - 1]);

View file

@ -3,6 +3,7 @@ const c = @cImport(@cInclude("jack/jack.h"));
const main = @import("main.zig");
const backends = @import("backends.zig");
const util = @import("util.zig");
const mach = @import("../main.zig");
var lib: Lib = undefined;
const Lib = struct {
@ -33,7 +34,7 @@ const Lib = struct {
jack_port_type_size: *const fn () c_int,
pub fn load() !void {
lib.handle = std.DynLib.open("libjack.so") catch return error.LibraryNotFound;
lib.handle = try mach.dynLibOpen("libjack.so");
inline for (@typeInfo(Lib).@"struct".fields[1..]) |field| {
const name = std.fmt.comptimePrint("{s}\x00", .{field.name});
const name_z: [:0]const u8 = @ptrCast(name[0 .. name.len - 1]);

View file

@ -6,6 +6,7 @@ const c = @cImport({
const main = @import("main.zig");
const backends = @import("backends.zig");
const util = @import("util.zig");
const mach = @import("../main.zig");
const default_sample_rate = 44_100; // Hz
@ -33,7 +34,7 @@ const Lib = struct {
pw_stream_get_state: *const fn (?*c.pw_stream, [*c][*c]const u8) callconv(.C) c.pw_stream_state,
pub fn load() !void {
lib.handle = std.DynLib.open("libpipewire-0.3.so") catch return error.LibraryNotFound;
lib.handle = try mach.dynLibOpen("libpipewire-0.3.so");
inline for (@typeInfo(Lib).@"struct".fields[1..]) |field| {
const name = std.fmt.comptimePrint("{s}\x00", .{field.name});
const name_z: [:0]const u8 = @ptrCast(name[0 .. name.len - 1]);

View file

@ -3,6 +3,8 @@ const c = @cImport(@cInclude("pulse/pulseaudio.h"));
const main = @import("main.zig");
const backends = @import("backends.zig");
const util = @import("util.zig");
const mach = @import("../main.zig");
const is_little = @import("builtin").cpu.arch.endian() == .little;
const default_sample_rate = 44_100; // Hz
@ -61,7 +63,7 @@ const Lib = struct {
pa_stream_get_sample_spec: *const fn (s: ?*c.pa_stream) [*c]const c.pa_sample_spec,
pub fn load() !void {
lib.handle = std.DynLib.open("libpulse.so") catch return error.LibraryNotFound;
lib.handle = try mach.dynLibOpen("libpulse.so");
inline for (@typeInfo(Lib).@"struct".fields[1..]) |field| {
const name = std.fmt.comptimePrint("{s}\x00", .{field.name});
const name_z: [:0]const u8 = @ptrCast(name[0 .. name.len - 1]);

View file

@ -1,5 +1,6 @@
const std = @import("std");
const c = @import("c.zig");
const mach = @import("../../main.zig");
var libgl: std.DynLib = undefined;
@ -16,7 +17,7 @@ fn getProcAddress(name_ptr: [*:0]const u8) c.PROC {
}
pub fn init() !void {
libgl = try std.DynLib.open("opengl32.dll");
libgl = try mach.dynLibOpen("opengl32.dll");
}
pub fn deinit() void {

View file

@ -7,6 +7,7 @@ const shader = @import("shader.zig");
const utils = @import("utils.zig");
const conv = @import("vulkan/conv.zig");
const proc = @import("vulkan/proc.zig");
const mach = @import("../main.zig");
const log = std.log.scoped(.vulkan);
const api_version = vk.makeApiVersion(0, 1, 1, 0);
@ -28,7 +29,7 @@ pub fn init(alloc: std.mem.Allocator, options: InitOptions) !void {
if (options.baseLoader) |baseLoader| {
vkb = try proc.loadBase(baseLoader);
} else {
libvulkan = try std.DynLib.open(switch (builtin.target.os.tag) {
libvulkan = try mach.dynLibOpen(switch (builtin.target.os.tag) {
.windows => "vulkan-1.dll",
.linux => "libvulkan.so.1",
.macos => "libvulkan.1.dylib",