-
-
Notifications
You must be signed in to change notification settings - Fork 151
/
Copy pathbuild-v0.10.zig
144 lines (132 loc) · 5.48 KB
/
build-v0.10.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
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
133
134
135
136
137
138
139
140
141
142
143
144
// SPDX-License-Identifier: Apache-2.0
//! DEPRECATED build helpers for using modules/packages distributed via NPM
//! Intended for use with https://thi.ng/wasm-api and support packages
//!
//! This version of the script is only compatible with:
//! Zig v0.10.1 or older
//!
//! Use other build.zig files in this same directory for newer Zig versions
const std = @import("std");
/// Definition for a (usually hybrid) Zig package which will be distributed via NPM
pub const Pkg = struct {
/// Package ID used for @import
id: []const u8,
/// Package sub path (appended to base path)
path: []const u8,
/// Package dependencies aka other package IDs.
/// All of them must already have been registered
deps: ?[]const []const u8 = null,
};
pub const PkgOpts = struct {
/// Base path to common node_modules directory under which
/// all to be imported packages are located
base: []const u8 = "node_modules",
/// Additional WASM API support packages.
/// We don't need to specify core wasmapi, only custom/extra ones
/// `wasm-api` and `wasm-api-bindgen` are also auto-added
/// as dependency for each of these...
packages: ?[]const Pkg = null,
};
/// Dependency graph for WASM API packages
/// Expands & resolves the more compact/convenient/human friendly format of PkgOpts
/// into the data structures used by Zig's build system
/// Provides a `addAllTo()` function to add all declared packages to a build step
pub const PkgGraph = struct {
arena: std.heap.ArenaAllocator,
basePath: []const u8,
packages: std.StringArrayHashMap(std.build.Pkg),
const Self = @This();
pub fn init(opts: PkgOpts) Self {
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
var self = Self{
.arena = arena,
.basePath = opts.base,
.packages = std.StringArrayHashMap(std.build.Pkg).init(arena.allocator()),
};
const api = "wasm-api";
self.packages.put(api, .{
.name = api,
.source = .{ .path = self.modulePath("@thi.ng/wasm-api/zig/lib.zig") },
}) catch unreachable;
const apiTypes = "wasm-api-bindgen";
self.packages.put(apiTypes, .{
.name = apiTypes,
.source = .{ .path = self.modulePath("@thi.ng/wasm-api-bindgen/zig/lib.zig") },
}) catch unreachable;
if (opts.packages) |pkgs| {
for (pkgs) |pkg| {
self.register(pkg.id, pkg.path, pkg.deps);
}
}
return self;
}
pub fn deinit(self: *const Self) void {
self.arena.deinit();
}
/// Registers a single package and its deps (also injects core wasm-api deps)
pub fn register(
self: *Self,
name: []const u8,
path: []const u8,
dependencies: ?[]const []const u8,
) void {
var pkg = std.build.Pkg{
.name = name,
.source = .{ .path = self.modulePath(path) },
};
const num = if (dependencies) |deps| deps.len else 0;
var dpkgs = self.arena.allocator().alloc(std.build.Pkg, num + 2) catch unreachable;
dpkgs[0] = if (self.packages.get("wasm-api")) |p| p else unreachable;
dpkgs[1] = if (self.packages.get("wasm-api-bindgen")) |p| p else unreachable;
if (dependencies) |deps| {
var i: usize = 0;
while (i < deps.len) : (i += 1) {
if (self.packages.get(deps[i])) |p| {
dpkgs[i + 1] = p;
} else @panic("unknown dependency");
}
}
pkg.dependencies = dpkgs;
self.packages.put(name, pkg) catch unreachable;
}
/// Adds all registered packages to the given build step
pub fn addAllTo(self: *const Self, step: *std.build.LibExeObjStep) void {
for (self.packages.values()) |pkg| step.addPackage(pkg);
}
fn modulePath(self: *Self, path: []const u8) []const u8 {
return std.fs.path.join(self.arena.allocator(), &.{ self.basePath, path }) catch unreachable;
}
};
/// Config options
pub const WasmLibOpts = struct {
/// Relative path to base directory for WASM API packages
base: []const u8 = "node_modules",
/// Relative path to root source file
root: []const u8 = "zig/main.zig",
/// Relative path to output directory
out: []const u8 = "src",
/// Package definitions for additional WASM API modules
packages: ?[]const Pkg = null,
/// Build mode override (else allows config via CLI args)
mode: ?std.builtin.Mode = null,
/// Additional WASM target features, e.g. `.simd128` to enable SIMD
features: ?[]const std.Target.wasm.Feature = null,
};
/// Creates and returns a build step to build a dynamic WASM library, configured
/// with given options and package declarations. The given package specs will be inserted
pub fn wasmLib(b: *std.build.Builder, opts: WasmLibOpts) *std.build.LibExeObjStep {
const lib = b.addSharedLibrary("main", opts.root, .unversioned);
lib.setTarget(.{
.cpu_arch = .wasm32,
.os_tag = .freestanding,
.cpu_features_add = if (opts.features) |features| std.Target.wasm.featureSet(features) else std.Target.Cpu.Feature.Set.empty,
});
const mode = if (opts.mode) |m| m else b.standardReleaseOptions();
lib.setBuildMode(mode);
if (mode == .ReleaseSmall or mode == .ReleaseFast) lib.strip = true;
const pkgs = PkgGraph.init(.{ .base = opts.base, .packages = opts.packages });
defer pkgs.deinit();
pkgs.addAllTo(lib);
lib.setOutputDir(opts.out);
return lib;
}