-
Notifications
You must be signed in to change notification settings - Fork 1
/
zbind.zig
110 lines (94 loc) · 3.77 KB
/
zbind.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
const std = @import("std");
const builtin = @import("builtin");
pub const ResolvedTarget = @typeInfo(@TypeOf(std.Build.standardTargetOptions)).Fn.return_type.?;
pub const BuilderPath = if(!@hasField(std.Build, "path") and !@hasDecl(std.Build, "path")) std.Build.LazyPath else @typeInfo(@TypeOf(std.Build.path)).Fn.return_type.?;
fn builder_path(builder: *std.Build, path: []const u8) BuilderPath {
return if(!@hasField(std.Build, "path") and !@hasDecl(std.Build, "path")) .{ .path = path } else builder.path(path);
}
pub fn init(comptime API: type) void {
if(builtin.cpu.arch == .wasm32) {
const zbind = @import("lib/zbind-wasm.zig");
// Support linking with libc.
@export(struct {
pub fn main(_: c_int, _: *anyopaque) callconv(.C) c_int {
return 0;
}
}.main, .{ .name = "main" });
@export(struct {
pub fn init(base: [*c]u8) callconv(.C) u32 {
return zbind.init(API, base);
}
}.init, .{ .name = "init" });
} else {
const zbind = @import("lib/zbind-napi.zig");
@export(struct {
pub fn register(env: zbind.Env, exports: zbind.Value) callconv(.C) zbind.Value {
return zbind.init(env, exports, API);
}
}.register, .{ .name = "napi_register_module_v1" });
}
}
pub fn build(
config: struct { //
builder: *std.Build,
root: ?[]const u8 = null,
main: []const u8,
target: ?ResolvedTarget = null,
optimize: ?std.builtin.OptimizeMode = null,
npm: ?[]const u8 = null,
out: []const u8
}
) !*std.Build.Step.Compile {
const builder = config.builder;
const root = config.root orelse builder.build_root.path orelse ".";
const name = std.fs.path.basename(config.out);
const target: ResolvedTarget = config.target orelse builder.standardTargetOptions(.{});
const optimize: std.builtin.OptimizeMode = config.optimize orelse builder.standardOptimizeOption(.{});
const zbind = builder.createModule(if(@hasField(std.Build.Module, "root_source_file")) .{
.root_source_file = .{ //
.cwd_relative = @src().file
},
.imports = &.{}
} else .{
.source_file = .{ //
.path = @src().file
},
.dependencies = &.{}
});
const arch = (if(@hasField(@TypeOf(target), "cpu_arch")) target else target.query).cpu_arch;
const use_executable = (arch == .wasm32) and builtin.zig_version.order(std.SemanticVersion.parse("0.12.0") catch unreachable) != .lt;
const options = .{ //
.name = name,
.root_source_file = builder_path(builder, config.main),
.target = target,
.optimize = optimize,
.single_threaded = true
};
const lib = if(use_executable) builder.addExecutable(options) else builder.addSharedLibrary(options);
if(arch == .wasm32) {
lib.export_memory = true;
lib.export_table = true;
(if(@hasField(@TypeOf(lib.*), "export_symbol_names")) lib else lib.root_module).export_symbol_names = &.{"init"};
} else {
if((if(@hasDecl(@TypeOf(target), "isDarwin")) target else target.result).isDarwin()) lib.linker_allow_shlib_undefined = true;
const include_path = try std.fs.path.resolve(builder.allocator, if(config.npm) |npm| &.{
root, //
npm,
"node-api-headers/include"
} else &.{
std.fs.path.dirname(@src().file) orelse ".", //
"../node-api-headers/include"
});
(if(@hasDecl(@TypeOf(zbind.*), "addIncludePath")) zbind else lib).addIncludePath(.{ .cwd_relative = include_path });
}
if(@hasDecl(@TypeOf(lib.*), "addModule")) lib.addModule("zbind", zbind) else lib.root_module.addImport("zbind", zbind);
builder.getInstallStep().dependOn(&builder.addInstallArtifact(lib, .{
.dest_dir = .{
.override = .{ //
.custom = try std.fs.path.relative(builder.allocator, builder.install_prefix, try std.fs.path.resolve(builder.allocator, &.{ root, std.fs.path.dirname(config.out) orelse "." }))
}
},
.dest_sub_path = try std.fmt.allocPrint(builder.allocator, "{s}{s}", .{ name, if(arch == .wasm32) ".wasm" else ".node" })
}).step);
return lib;
}