-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathutils.zig
98 lines (76 loc) · 3.89 KB
/
utils.zig
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
const std = @import("std");
const fs = std.fs;
const mem = std.mem;
pub fn collectSources(b: *std.Build, path: std.Build.LazyPath, variable: []const u8) []const []const u8 {
const p = path.getPath(b);
var file = fs.openFileAbsolute(p, .{}) catch |e| std.debug.panic("Failed to open {s}: {s}", .{ p, @errorName(e) });
defer file.close();
const metadata = file.metadata() catch |e| std.debug.panic("Failed to get metadata {s}: {s}", .{ p, @errorName(e) });
const contents = file.readToEndAlloc(b.allocator, metadata.size()) catch |e| std.debug.panic("Failed to read {s}: {s}", .{ p, @errorName(e) });
defer b.allocator.free(contents);
var list = std.ArrayList([]const u8).init(b.allocator);
defer list.deinit();
const needle = b.fmt("{s} = [", .{variable});
if (mem.indexOf(u8, contents, needle)) |i| {
if (mem.indexOf(u8, contents[i..], "]")) |x| {
const block = contents[(i + needle.len + 1)..(i + x)];
if (mem.indexOf(u8, block, "\n") != null) {
var it = mem.splitSequence(u8, block, "\n");
while (it.next()) |line| {
const open_string = mem.indexOf(u8, line, "\"") orelse continue;
const close_string = mem.indexOf(u8, line[open_string..], "\",") orelse continue;
const string_value = line[(open_string + 1)..(close_string + open_string)];
if (mem.eql(u8, fs.path.extension(string_value), ".cc")) {
list.append(b.allocator.dupe(u8, string_value) catch @panic("OOM")) catch @panic("OOM");
}
}
} else {
const open_string = mem.indexOf(u8, block, "\"") orelse @panic("No entry");
const close_string = mem.indexOf(u8, block[(open_string + 1)..], "\"") orelse @panic("No entry");
const string_value = block[(open_string + 1)..(close_string + open_string + 1)];
if (mem.eql(u8, fs.path.extension(string_value), ".cc")) {
list.append(b.allocator.dupe(u8, string_value) catch @panic("OOM")) catch @panic("OOM");
}
}
}
}
return list.toOwnedSlice() catch |e| std.debug.panic("Failed to allocate memory: {s}", .{@errorName(e)});
}
pub const BinToLinkableOptions = struct {
size_symbol: ?[]const u8 = null,
executable: bool = false,
step: ?*std.Build.Step = null,
};
pub fn binToLinkable(
b: *std.Build,
file: std.Build.LazyPath,
symbol_name: []const u8,
target: std.Build.ResolvedTarget,
optimize: std.builtin.OptimizeMode,
options: BinToLinkableOptions,
) *std.Build.Step.Compile {
const name = fs.path.basename(file.getDisplayName());
const wf = b.addWriteFiles();
_ = wf.addCopyFile(file, b.fmt("{s}.bin", .{name}));
if (options.step) |step| wf.step.dependOn(step);
var code = std.ArrayList(u8).init(b.allocator);
defer code.deinit();
code.appendSlice("comptime {\n") catch @panic("OOM");
code.appendSlice(b.fmt(" @export({s}.ptr, .{{\n .name = \"{s}\",\n", .{ symbol_name, symbol_name })) catch @panic("OOM");
if (options.executable) {
code.appendSlice(" .section = \"text\",\n") catch @panic("OOM");
} else {
code.appendSlice(" .section = \"rodata\",\n") catch @panic("OOM");
}
if (options.size_symbol) |size_symbol| {
code.appendSlice(b.fmt(" }});\n @export(&{s}.len, .{{ .name = \"{s}\"", .{ symbol_name, size_symbol })) catch @panic("OOM");
}
code.appendSlice(" });\n}\n\n") catch @panic("OOM");
code.appendSlice(b.fmt("pub const {s} align(32) = @embedFile(\"{s}.bin\");", .{ symbol_name, name })) catch @panic("OOM");
return b.addObject(.{
.name = b.fmt("{s} {s}", .{ name, symbol_name }),
.root_source_file = wf.add(b.fmt("{s}.zig", .{name}), code.items),
.target = target,
.optimize = optimize,
});
}