Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ jobs:
- name: Setup Zig for OpenHarmony
uses: openharmony-zig/setup-zig-ohos@v0.1.0
id: setup-zig
with:
tag: '0.16.0'

- name: Build
run: |
Expand Down
13 changes: 8 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,10 @@ We recommend you use ZON(Zig Package Manager) to install it.
.{
.name = "appname",
.version = "0.0.0",
.minimum_zig_version = "0.16.0",
.dependencies = .{
.network = .{
.url = "https://github.com/openharmony-zig/zig-addon/archive/refs/tags/<GIT_TAG>.tar.gz",
.@"zig-napi" = .{
.url = "https://github.com/openharmony-zig/zig-napi/archive/refs/tags/<GIT_TAG>.tar.gz",
.hash = "HASH_GOES_HERE",
},
},
Expand All @@ -43,9 +44,11 @@ pub fn build(b: *std.Build) !void {

const result = try napi_build.nativeAddonBuild(b, .{
.name = "hello",
.root_source_file = b.path("./src/hello.zig"),
.target = target,
.optimize = optimize,
.root_module_options = .{
.root_source_file = b.path("./src/hello.zig"),
.target = target,
.optimize = optimize,
},
});

if (result.arm64) |arm64| {
Expand Down
2 changes: 1 addition & 1 deletion build.zig.zon
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
.{
.name = .zig_napi,
.version = "0.0.1-beta.2",
.minimum_zig_version = "0.15.1",
.minimum_zig_version = "0.16.0",
.dependencies = .{},
.fingerprint = 0x6093bdd26bb0a31f,
.paths = .{
Expand Down
2 changes: 1 addition & 1 deletion examples/basic/build.zig.zon
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
.{
.name = .add,
.version = "0.0.1",
.minimum_zig_version = "0.15.1",
.minimum_zig_version = "0.16.0",
.fingerprint = 0xfd1a73e7f96390fb,
.dependencies = .{ .@"zig-napi" = .{ .path = "../.." } },
.paths = .{ "build.zig", "build.zig.zon", "src" },
Expand Down
12 changes: 10 additions & 2 deletions examples/basic/src/thread_safe_function.zig
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,21 @@ const napi = @import("napi");
const Args = struct { i32, i32 };
const Return = i32;

fn sleepForFiveSeconds() void {
var req = std.c.timespec{
.sec = 5,
.nsec = 0,
};
_ = std.c.nanosleep(&req, null);
}

fn execute_thread_safe_function(tsfn: *napi.ThreadSafeFunction(Args, Return, true, 0)) void {
std.Thread.sleep(5_000_000_000);
sleepForFiveSeconds();
tsfn.Ok(.{ 1, 2 }, .NonBlocking);
}

fn execute_thread_safe_function_with_error(tsfn: *napi.ThreadSafeFunction(Args, Return, true, 0)) void {
std.Thread.sleep(5_000_000_000);
sleepForFiveSeconds();
tsfn.Err(napi.Error.withReason("TSFN Error"), .NonBlocking);
}

Expand Down
2 changes: 1 addition & 1 deletion examples/init/build.zig.zon
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
.{
.name = .add,
.version = "0.0.1",
.minimum_zig_version = "0.14.0",
.minimum_zig_version = "0.16.0",
.fingerprint = 0xfd1a73e7f96390fb,
.dependencies = .{ .@"zig-napi" = .{ .path = "../.." } },
.paths = .{ "build.zig", "build.zig.zon", "src" },
Expand Down
28 changes: 8 additions & 20 deletions src/build/napi-build.zig
Original file line number Diff line number Diff line change
@@ -1,12 +1,7 @@
const std = @import("std");

fn getEnvVarOptional(allocator: std.mem.Allocator, name: []const u8) !?[]const u8 {
return std.process.getEnvVarOwned(allocator, name) catch |err| {
if (err == error.EnvironmentVariableNotFound) {
return null;
}
return err;
};
fn getEnvVarOptional(build: *std.Build, name: []const u8) ?[]const u8 {
return build.graph.environ_map.get(name);
}

pub fn cloneLibraryOptions(build: *std.Build, option: NativeAddonBuildOptionsWithModule, target: std.Build.ResolvedTarget) std.Build.LibraryOptions {
Expand Down Expand Up @@ -49,20 +44,13 @@ pub fn cloneLibraryOptions(build: *std.Build, option: NativeAddonBuildOptionsWit
}

pub fn resolveNdkPath(build: *std.Build) ![]const u8 {
const allocator = build.allocator;

var ndkRoot: ?[]const u8 = null;

const home = try getEnvVarOptional(allocator, "OHOS_NDK_HOME");
if (home) |v| {
ndkRoot = try std.fs.path.join(allocator, &[_][]const u8{ v, "native" });
} else {
const ohos_sdk_native = try getEnvVarOptional(allocator, "ohos_sdk_native");
if (ohos_sdk_native) |v| {
ndkRoot = v;
}
if (getEnvVarOptional(build, "OHOS_NDK_HOME")) |home| {
return build.pathJoin(&.{ home, "native" });
}
if (getEnvVarOptional(build, "ohos_sdk_native")) |native| {
return native;
}
return ndkRoot orelse "";
return "";
}

const targets: []const std.Target.Query = &.{
Expand Down
58 changes: 30 additions & 28 deletions src/build/napi-tsgen.zig
Original file line number Diff line number Diff line change
Expand Up @@ -261,11 +261,13 @@ const ParsedSourceParams = struct {

const SourceResolver = struct {
allocator: std.mem.Allocator,
io: std.Io,
root_source_path: []const u8,

fn init(allocator: std.mem.Allocator, root_source_path: []const u8) SourceResolver {
fn init(allocator: std.mem.Allocator, io: std.Io, root_source_path: []const u8) SourceResolver {
return .{
.allocator = allocator,
.io = io,
.root_source_path = root_source_path,
};
}
Expand Down Expand Up @@ -515,10 +517,10 @@ const SourceResolver = struct {
if (param.len == 0 or std.mem.eql(u8, param, "...")) return;

if (std.mem.startsWith(u8, param, "comptime ")) {
param = std.mem.trimLeft(u8, param["comptime ".len..], " \t");
param = std.mem.trimStart(u8, param["comptime ".len..], " \t");
}
if (std.mem.startsWith(u8, param, "noalias ")) {
param = std.mem.trimLeft(u8, param["noalias ".len..], " \t");
param = std.mem.trimStart(u8, param["noalias ".len..], " \t");
}

const colon = std.mem.indexOfScalar(u8, param, ':') orelse return;
Expand All @@ -538,10 +540,10 @@ const SourceResolver = struct {
if (std.mem.eql(u8, param, "...")) return;

if (std.mem.startsWith(u8, param, "comptime ")) {
param = std.mem.trimLeft(u8, param["comptime ".len..], " \t");
param = std.mem.trimStart(u8, param["comptime ".len..], " \t");
}
if (std.mem.startsWith(u8, param, "noalias ")) {
param = std.mem.trimLeft(u8, param["noalias ".len..], " \t");
param = std.mem.trimStart(u8, param["noalias ".len..], " \t");
}

const colon = std.mem.indexOfScalar(u8, param, ':') orelse return;
Expand All @@ -551,7 +553,7 @@ const SourceResolver = struct {
}

fn readFile(self: *SourceResolver, file_path: []const u8) ![]const u8 {
return try std.fs.cwd().readFileAlloc(file_path, self.allocator, .unlimited);
return try std.Io.Dir.cwd().readFileAlloc(self.io, file_path, self.allocator, .limited(std.math.maxInt(usize)));
}

fn resolveImportPath(self: *SourceResolver, file_path: []const u8, alias: []const u8) !?[]const u8 {
Expand Down Expand Up @@ -608,7 +610,7 @@ fn trimAfterBalancedCall(text: []const u8) ?[]const u8 {
')' => {
depth -= 1;
if (depth == 0) {
return std.mem.trimLeft(u8, text[i + 1 ..], " \t\r\n");
return std.mem.trimStart(u8, text[i + 1 ..], " \t\r\n");
}
},
else => {},
Expand Down Expand Up @@ -640,7 +642,7 @@ fn matchConstAssignment(line: []const u8, symbol: []const u8) ?[]const u8 {
if (!std.mem.eql(u8, lhs, symbol)) return null;

const rhs_full = std.mem.trim(u8, rest[eq_index + 1 ..], " \t");
return std.mem.trimRight(u8, rhs_full, ";");
return std.mem.trimEnd(u8, rhs_full, ";");
}

fn tryMatchConstPrefix(line: []const u8) ?usize {
Expand All @@ -666,7 +668,7 @@ const ObjectSetCall = struct {
fn matchObjectSetCall(line: []const u8, object_name: []const u8) ?ObjectSetCall {
var rest = std.mem.trim(u8, line, " \t\r\n");
if (std.mem.startsWith(u8, rest, "try ")) {
rest = std.mem.trimLeft(u8, rest["try ".len..], " \t");
rest = std.mem.trimStart(u8, rest["try ".len..], " \t");
}

if (!std.mem.startsWith(u8, rest, object_name)) return null;
Expand All @@ -677,9 +679,9 @@ fn matchObjectSetCall(line: []const u8, object_name: []const u8) ?ObjectSetCall
const name_end = std.mem.indexOfScalar(u8, rest, '"') orelse return null;
const name = rest[0..name_end];

rest = std.mem.trimLeft(u8, rest[name_end + 1 ..], " \t");
rest = std.mem.trimStart(u8, rest[name_end + 1 ..], " \t");
if (rest.len == 0 or rest[0] != ',') return null;
rest = std.mem.trimLeft(u8, rest[1..], " \t");
rest = std.mem.trimStart(u8, rest[1..], " \t");

const call_end = std.mem.lastIndexOfScalar(u8, rest, ')') orelse return null;
const value_expr = std.mem.trim(u8, rest[0..call_end], " \t");
Expand Down Expand Up @@ -1361,7 +1363,7 @@ fn isSourceNumericType(type_expr: []const u8) bool {
fn trimConstType(type_expr: []const u8) []const u8 {
const trimmed = std.mem.trim(u8, type_expr, " \t\r\n");
if (std.mem.startsWith(u8, trimmed, "const ")) {
return std.mem.trimLeft(u8, trimmed["const ".len..], " \t");
return std.mem.trimStart(u8, trimmed["const ".len..], " \t");
}
return trimmed;
}
Expand Down Expand Up @@ -1684,8 +1686,8 @@ fn appendHeader(writer: *StringBuilder, header: []const u8) !void {
try append(writer, "\n");
}

fn generate(allocator: std.mem.Allocator, root_source_path: []const u8, header: []const u8) ![]u8 {
var source = SourceResolver.init(allocator, root_source_path);
fn generate(allocator: std.mem.Allocator, io: std.Io, root_source_path: []const u8, header: []const u8) ![]u8 {
var source = SourceResolver.init(allocator, io, root_source_path);
var state = State.init(allocator, &source);
defer state.deinit();

Expand Down Expand Up @@ -1738,21 +1740,21 @@ fn generate(allocator: std.mem.Allocator, root_source_path: []const u8, header:
return try output.toOwnedSlice();
}

pub fn main() !void {
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
defer arena.deinit();
const allocator = arena.allocator();
pub fn main(init: std.process.Init) !void {
const io = init.io;
const allocator = init.arena.allocator();
const args = try init.minimal.args.toSlice(allocator);

var args = try std.process.argsWithAllocator(allocator);
defer args.deinit();
if (args.len < 3) return error.InvalidArgument;

_ = args.next();
const output_path = args.next() orelse return error.InvalidArgument;
const root_source_path = args.next() orelse return error.InvalidArgument;
const header = args.next() orelse "";
const output_path = args[1];
const root_source_path = args[2];
const header = if (args.len > 3) args[3] else "";

const content = try generate(allocator, root_source_path, header);
const file = try std.fs.cwd().createFile(output_path, .{ .truncate = true });
defer file.close();
try file.writeAll(content);
const content = try generate(allocator, io, root_source_path, header);
try std.Io.Dir.cwd().writeFile(io, .{
.sub_path = output_path,
.data = content,
.flags = .{ .truncate = true },
});
}
21 changes: 5 additions & 16 deletions src/napi/util/helper.zig
Original file line number Diff line number Diff line change
Expand Up @@ -185,24 +185,13 @@ pub fn collectFunctionArgs(comptime functions: anytype) type {

const args_len = infos.@"fn".params.len;

var fields: [args_len]std.builtin.Type.StructField = undefined;
var field_types: [args_len]type = undefined;

inline for (0..args_len) |i| {
fields[i] = std.builtin.Type.StructField{
.name = std.fmt.comptimePrint("{d}", .{i}),
.type = infos.@"fn".params[i].type.?,
.default_value_ptr = null,
.is_comptime = false,
.alignment = @alignOf(infos.@"fn".params[i].type.?),
};
}

return @Type(std.builtin.Type{ .@"struct" = std.builtin.Type.Struct{
.layout = .auto,
.fields = &fields,
.decls = &[_]std.builtin.Type.Declaration{},
.is_tuple = true,
} });
field_types[i] = infos.@"fn".params[i].type.?;
}

return std.meta.Tuple(&field_types);
}

pub fn shortTypeName(comptime T: type) []const u8 {
Expand Down
Loading