-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbuild.zig
More file actions
132 lines (115 loc) · 4.88 KB
/
Copy pathbuild.zig
File metadata and controls
132 lines (115 loc) · 4.88 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
const std = @import("std");
const version = @import("build.zig.zon").version;
pub fn build(b: *std.Build) void {
const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{});
const mpv_prefix = b.option([]const u8, "mpv-prefix", "libmpv install prefix (default /usr/local)") orelse "/usr/local";
const mod = b.createModule(.{
.root_source_file = b.path("src/main.zig"),
.target = target,
.optimize = optimize,
.link_libc = true,
});
linkMpv(b, mod, mpv_prefix);
const options = b.addOptions();
options.addOption([]const u8, "version", version);
mod.addOptions("build_options", options);
const exe = b.addExecutable(.{
.name = "hum",
.root_module = mod,
});
b.installArtifact(exe);
const run_cmd = b.addRunArtifact(exe);
run_cmd.step.dependOn(b.getInstallStep());
if (b.args) |args| run_cmd.addArgs(args);
const run_step = b.step("run", "Run hum");
run_step.dependOn(&run_cmd.step);
const test_mod = b.createModule(.{
.root_source_file = b.path("src/tests.zig"),
.target = target,
.optimize = optimize,
.link_libc = true,
});
linkMpv(b, test_mod, mpv_prefix);
test_mod.addOptions("build_options", options);
const unit_tests = b.addTest(.{ .root_module = test_mod });
const run_unit_tests = b.addRunArtifact(unit_tests);
const test_step = b.step("test", "Run unit tests");
test_step.dependOn(&run_unit_tests.step);
addCheckStep(b, mpv_prefix, options);
}
/// `zig build check` type-checks every release target without linking, so a
/// platform-specific break (FreeBSD translate-c, most often) surfaces in seconds
/// on any machine instead of at tag time in a VM.
fn addCheckStep(b: *std.Build, mpv_prefix: []const u8, options: *std.Build.Step.Options) void {
const check = b.step("check", "Type-check all release targets (no link)");
// Zig ships libc headers for every target below, so the ONLY header this
// needs from the host is mpv/client.h. Copy that one file into a generated
// directory rather than putting a system include path on the command line:
// -I /usr/include would feed the host's glibc headers to a macOS or FreeBSD
// cross-compile, which fails on glibc internals.
const header = findMpvHeader(b, mpv_prefix) orelse {
std.log.warn("check: mpv/client.h not found; skipping (pass -Dmpv-prefix)", .{});
return;
};
const shim = b.addWriteFiles();
_ = shim.addCopyFile(.{ .cwd_relative = header }, "mpv/client.h");
const include_dir = shim.getDirectory();
const targets = [_][]const u8{
"x86_64-freebsd",
"x86_64-linux-gnu",
"aarch64-linux-gnu",
"x86_64-macos",
"aarch64-macos",
};
// ReleaseSafe as well as Debug: FreeBSD's __ssp fortify wrappers only appear
// in optimized builds.
const modes = [_]std.builtin.OptimizeMode{ .Debug, .ReleaseSafe };
for (targets) |triple| {
for (modes) |mode| {
const query = std.Build.parseTargetQuery(.{ .arch_os_abi = triple }) catch continue;
const mod = b.createModule(.{
.root_source_file = b.path("src/main.zig"),
.target = b.resolveTargetQuery(query),
.optimize = mode,
.link_libc = true,
});
mod.addIncludePath(include_dir);
mod.addOptions("build_options", options);
const obj = b.addObject(.{
.name = b.fmt("check-{s}-{s}", .{ triple, @tagName(mode) }),
.root_module = mod,
});
check.dependOn(&obj.step);
}
}
}
/// Locate mpv/client.h: the configured prefix, then the usual system locations.
fn findMpvHeader(b: *std.Build, prefix: []const u8) ?[]const u8 {
const dirs = [_][]const u8{
if (prefix.len > 0) b.fmt("{s}/include", .{prefix}) else "",
"/usr/include",
"/usr/local/include",
"/opt/homebrew/include",
};
for (dirs) |dir| {
if (dir.len == 0) continue;
const path = b.fmt("{s}/mpv/client.h", .{dir});
std.Io.Dir.cwd().access(b.graph.io, path, .{}) catch continue;
return path;
}
return null;
}
fn linkMpv(b: *std.Build, mod: *std.Build.Module, prefix: []const u8) void {
if (prefix.len > 0) {
// Explicit prefix wins: skip pkg-config, which resolves to the HOST
// arch's mpv and breaks cross-compiles (e.g. the x86_64 slice of the
// universal macOS build linking the arm libmpv). Empty prefix (Linux)
// still uses pkg-config to find the system libmpv.
mod.addIncludePath(.{ .cwd_relative = b.fmt("{s}/include", .{prefix}) });
mod.addLibraryPath(.{ .cwd_relative = b.fmt("{s}/lib", .{prefix}) });
mod.linkSystemLibrary("mpv", .{ .use_pkg_config = .no });
} else {
mod.linkSystemLibrary("mpv", .{});
}
}