Skip to content

Commit d4d6eeb

Browse files
committed
feat: Another tidy pass over natives, pretty close to done
1 parent 6727e35 commit d4d6eeb

File tree

7 files changed

+211
-168
lines changed

7 files changed

+211
-168
lines changed

build.zig

Lines changed: 116 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,69 @@
2121
const std = @import("std");
2222
const cpu_util = @import("src/main/zig/cpuid/cpu_util.zig");
2323
const zanama = @import("zanama");
24-
const TargetCombination = struct {
25-
os: std.Target.Os.Tag,
26-
cpu_arch: std.Target.Cpu.Arch,
27-
baseline_model: *const std.Target.Cpu.Model,
24+
25+
const base_targets = [_]std.Target.Query{
26+
.{ .os_tag = .linux, .cpu_arch = .x86_64, .abi = .gnu, .cpu_model = .{ .explicit = &std.Target.x86.cpu.x86_64 } },
27+
.{ .os_tag = .windows, .cpu_arch = .x86_64, .abi = .gnu, .cpu_model = .{ .explicit = &std.Target.x86.cpu.x86_64 } },
28+
.{ .os_tag = .linux, .cpu_arch = .aarch64, .abi = .gnu, .cpu_model = .{ .explicit = &std.Target.aarch64.cpu.generic } },
29+
.{ .os_tag = .macos, .cpu_arch = .aarch64, .abi = .none, .cpu_model = .{ .explicit = &std.Target.aarch64.cpu.generic } },
30+
.{ .os_tag = .windows, .cpu_arch = .aarch64, .abi = .gnu, .cpu_model = .{ .explicit = &std.Target.aarch64.cpu.generic } },
2831
};
32+
2933
pub fn build(b: *std.Build) void {
30-
const zanama_dep = b.dependency("zanama", .{});
31-
const zb = zanama.Build.init(b, .ReleaseFast, zanama_dep);
34+
const packer = createPackerTask(b);
35+
const targets = getTargets(b);
36+
37+
//JNI stubs
38+
for (targets.baseline) |target| {
39+
const triple = target.query.zigTriple(b.allocator) catch @panic("OOM");
40+
const jni_dep = b.dependency("jni", .{
41+
.target = target,
42+
.optimize = .ReleaseFast,
43+
});
44+
const jni_module = jni_dep.module("JNI");
45+
46+
const libjni_mod = b.createModule(.{
47+
.root_source_file = b.path("src/main/zig/libjni.zig"),
48+
.target = target,
49+
.optimize = .ReleaseFast,
50+
.strip = true,
51+
});
52+
const name = std.mem.concat(b.allocator, u8, &.{ "jni-", triple, "-", target.query.cpu_model.explicit.name }) catch @panic("OOM");
53+
libjni_mod.addImport("jni", jni_module);
54+
const libjni = b.addLibrary(.{
55+
.linkage = .dynamic,
56+
.name = name,
57+
.root_module = libjni_mod,
58+
});
59+
packer.addArg(name);
60+
packer.addFileArg(libjni.getEmittedBin());
61+
}
62+
63+
const zanamaBuilder = ZanamaLibBuilder.init(b, packer);
64+
65+
zanamaBuilder.addZanamaLibs(
66+
"cpuid",
67+
b.createModule(.{
68+
.root_source_file = b.path("src/main/zig/cpuid/lib.zig"),
69+
.optimize = .ReleaseSmall,
70+
.strip = true,
71+
}),
72+
targets.baseline,
73+
);
74+
75+
zanamaBuilder.addZanamaLibs(
76+
"FalseTweaks",
77+
b.createModule(.{
78+
.root_source_file = b.path("src/main/zig/lib.zig"),
79+
.optimize = .ReleaseFast,
80+
.strip = true,
81+
}),
82+
targets.all,
83+
);
84+
}
3285

86+
fn createPackerTask(b: *std.Build) *std.Build.Step.Run {
3387
const packer = b.addExecutable(.{
3488
.name = "packer",
3589
.root_module = b.addModule("packer", .{
@@ -39,98 +93,65 @@ pub fn build(b: *std.Build) void {
3993
});
4094
const run_packer = b.addRunArtifact(packer);
4195
const natives_file = "natives.pak";
42-
const install_step = b.getInstallStep();
43-
install_step.dependOn(&b.addInstallLibFile(run_packer.addOutputFileArg(natives_file), natives_file).step);
44-
const target_combos = [_]TargetCombination{
45-
.{.os = .linux, .cpu_arch = .x86_64, .baseline_model = &std.Target.x86.cpu.x86_64},
46-
.{.os = .windows, .cpu_arch = .x86_64, .baseline_model = &std.Target.x86.cpu.x86_64},
47-
.{.os = .linux, .cpu_arch = .aarch64, .baseline_model = &std.Target.aarch64.cpu.generic}
48-
};
49-
for (target_combos) |combo| {
50-
const baseline_target = b.resolveTargetQuery(.{
51-
.os_tag = combo.os,
52-
.cpu_arch = combo.cpu_arch,
53-
.cpu_model = .{ .explicit = combo.baseline_model },
54-
.abi = .gnu,
55-
});
56-
const baseline_triple = baseline_target.query.zigTriple(b.allocator) catch @panic("OOM");
57-
{
58-
const jni_dep = b.dependency("jni", .{
59-
.target = baseline_target,
60-
.optimize = .ReleaseFast,
61-
});
62-
const jni_module = jni_dep.module("JNI");
96+
const output_natives_file = run_packer.addOutputFileArg(natives_file);
97+
const install_pack = b.addInstallLibFile(output_natives_file, natives_file);
98+
b.getInstallStep().dependOn(&install_pack.step);
99+
return run_packer;
100+
}
63101

64-
const libjni_mod = b.createModule(.{
65-
.root_source_file = b.path("src/main/zig/libjni.zig"),
66-
.target = baseline_target,
67-
.optimize = .ReleaseFast,
68-
.strip = true,
69-
});
70-
const name = std.mem.concat(b.allocator, u8, &.{"jni-", baseline_triple, "-", baseline_target.query.cpu_model.explicit.name}) catch @panic("OOM");
71-
libjni_mod.addImport("jni", jni_module);
72-
const libjni = b.addLibrary(.{
73-
.linkage = .dynamic,
74-
.name = name,
75-
.root_module = libjni_mod,
76-
});
77-
run_packer.addArg(name);
78-
run_packer.addFileArg(libjni.getEmittedBin());
79-
}
80-
{
81-
const libcpuid_mod = b.createModule(.{
82-
.root_source_file = b.path("src/main/zig/cpuid/lib.zig"),
83-
.target = baseline_target,
84-
.optimize = .ReleaseSmall,
85-
.strip = true,
86-
.imports = &.{
87-
.{ .name = "zanama", .module = zanama_dep.module("api") },
88-
}
89-
});
90-
const libs = zb.createZanamaLibsResolved("cpuid", libcpuid_mod, &.{baseline_target});
91-
for (libs.artifacts) |artifact| {
92-
run_packer.addArg(artifact.name);
93-
run_packer.addFileArg(artifact.getEmittedBin());
94-
}
95-
const install_json = b.addInstallFile(libs.json, "cpuid.json");
96-
install_json.step.dependOn(libs.json_step);
97-
install_step.dependOn(&install_json.step);
102+
fn getTargets(b: *std.Build) struct { baseline: []std.Build.ResolvedTarget, all: []std.Build.ResolvedTarget } {
103+
var baseline_targets: [base_targets.len]std.Build.ResolvedTarget = undefined;
104+
var targets = std.ArrayList(std.Build.ResolvedTarget).empty;
105+
defer targets.deinit(b.allocator);
106+
for (base_targets, 0..) |base, combo_index| {
107+
baseline_targets[combo_index] = b.resolveTargetQuery(base);
108+
const supported_models = switch (base.cpu_arch.?) {
109+
.aarch64 => cpu_util.supported_models_aarch64,
110+
.x86_64 => cpu_util.supported_models_x86,
111+
else => @panic(std.mem.concat(b.allocator, u8, &.{ "Unsupported CPU arch ", @tagName(base.cpu_arch.?) }) catch @panic("OOM")),
112+
};
113+
114+
for (supported_models) |model| {
115+
var model_query = base;
116+
model_query.cpu_model = .{ .explicit = model };
117+
targets.append(b.allocator, b.resolveTargetQuery(model_query)) catch @panic("OOM");
98118
}
99-
{
100-
const supported_models = switch (combo.cpu_arch) {
101-
.aarch64 => cpu_util.supported_models_aarch64,
102-
.x86_64 => cpu_util.supported_models_x86,
103-
else => @panic(std.mem.concat(b.allocator, u8, &.{"Unsupported CPU arch ", @tagName(combo.cpu_arch)}) catch @panic("OOM")),
104-
};
105-
const targets = b.allocator.alloc(std.Build.ResolvedTarget, supported_models.len) catch @panic("OOM");
106-
defer b.allocator.free(targets);
107-
108-
for (supported_models, 0..) |model, i| {
109-
targets[i] = b.resolveTargetQuery(.{
110-
.os_tag = combo.os,
111-
.cpu_arch = combo.cpu_arch,
112-
.cpu_model = .{ .explicit = model },
113-
.abi = .gnu,
114-
});
115-
}
116-
const lib_mod = b.createModule(.{
117-
.root_source_file = b.path("src/main/zig/lib.zig"),
118-
.optimize = .ReleaseFast,
119-
.strip = true,
120-
.imports = &.{
121-
.{ .name = "zanama", .module = zanama_dep.module("api") },
122-
}
123-
});
119+
}
120+
return .{
121+
.baseline = b.allocator.dupe(std.Build.ResolvedTarget, &baseline_targets) catch @panic("OOM"),
122+
.all = targets.toOwnedSlice(b.allocator) catch @panic("OOM"),
123+
};
124+
}
125+
126+
const ZanamaLibBuilder = struct {
127+
b: *std.Build,
128+
packer: *std.Build.Step.Run,
129+
zanama_dep: *std.Build.Dependency,
130+
zanama_api: *std.Build.Module,
131+
zb: zanama.Build,
124132

125-
const libs = zb.createZanamaLibsResolved("FalseTweaks", lib_mod, targets);
133+
pub fn init(b: *std.Build, packer: *std.Build.Step.Run) ZanamaLibBuilder {
134+
const zanama_dep = b.dependency("zanama", .{});
135+
const zanama_api = zanama_dep.module("api");
136+
const zb = zanama.Build.init(b, .ReleaseFast, zanama_dep);
137+
return .{
138+
.b = b,
139+
.packer = packer,
140+
.zanama_dep = zanama_dep,
141+
.zanama_api = zanama_api,
142+
.zb = zb,
143+
};
144+
}
126145

127-
for (libs.artifacts) |artifact| {
128-
run_packer.addArg(artifact.name);
129-
run_packer.addFileArg(artifact.getEmittedBin());
130-
}
131-
const install_json = b.addInstallFile(libs.json, "FalseTweaks.json");
132-
install_json.step.dependOn(libs.json_step);
133-
install_step.dependOn(&install_json.step);
146+
fn addZanamaLibs(self: *const ZanamaLibBuilder, name: []const u8, module: *std.Build.Module, targets: []std.Build.ResolvedTarget) void {
147+
module.addImport("zanama", self.zanama_api);
148+
const libs = self.zb.createZanamaLibsResolved(name, module, targets);
149+
for (libs.artifacts) |artifact| {
150+
self.packer.addArg(artifact.name);
151+
self.packer.addFileArg(artifact.getEmittedBin());
134152
}
153+
const install_json = self.b.addInstallFile(libs.json, std.mem.concat(self.b.allocator, u8, &.{name, ".json"}) catch @panic("OOM"));
154+
install_json.step.dependOn(libs.json_step);
155+
self.b.getInstallStep().dependOn(&install_json.step);
135156
}
136-
}
157+
};

src/main/java/com/falsepattern/falsetweaks/modules/natives/NativeLoader.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import lombok.val;
3030
import lombok.var;
3131

32+
import java.io.File;
3233
import java.io.IOException;
3334
import java.nio.file.Files;
3435
import java.nio.file.Path;
@@ -56,6 +57,7 @@ public NativeLoader(Class<?> root) throws UnsupportedPlatformException {
5657
Files.createDirectories(nativesDir);
5758
} catch (IOException ignored) {
5859
}
60+
nativesDir.toFile().deleteOnExit();
5961
val arch = Arch.getCurrent();
6062
val os = OS.getCurrent();
6163
val libc = os.libc();
@@ -74,18 +76,21 @@ public NativeLoader(Class<?> root) throws UnsupportedPlatformException {
7476

7577
public String unpackNative(String libName, String cpu) throws UnsupportedPlatformException {
7678
val libNameSys = currentTriple.toLibName(libName, cpu);
79+
cpu = cpu == null ? currentTriple.arch.baselineModel : cpu;
7780
val libNameArchive = libName + "-" + currentTriple.toName() + "-" + cpu;
7881
val libFile = nativesDir.resolve(libNameSys);
7982
try {
8083
unpacker.unpack(libNameArchive, libFile);
8184
} catch (IOException e) {
8285
throw new UnsupportedPlatformException(e);
8386
}
87+
libFile.toFile().deleteOnExit();
8488
return libNameArchive;
8589
}
8690

8791
public String loadNative(String libName, String cpu) throws UnsupportedPlatformException {
8892
val libNameSys = currentTriple.toLibName(libName, cpu);
93+
cpu = cpu == null ? currentTriple.arch.baselineModel : cpu;
8994
val libNameArchive = libName + "-" + currentTriple.toName() + "-" + cpu;
9095
val libFile = nativesDir.resolve(libNameSys);
9196
try {
@@ -99,6 +104,7 @@ public String loadNative(String libName, String cpu) throws UnsupportedPlatformE
99104
} catch (UnsatisfiedLinkError e) {
100105
throw new UnsupportedPlatformException(e);
101106
}
107+
libFile.toFile().deleteOnExit();
102108
return absolutePath;
103109
}
104110

src/main/java/com/falsepattern/falsetweaks/modules/natives/Natives.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,12 @@
2626
import com.falsepattern.falsetweaks.modules.natives.camera.Clipping;
2727
import lombok.Getter;
2828
import lombok.val;
29+
import org.apache.commons.io.FileUtils;
2930
import stubpackage.com.falsepattern.falsetweaks.modules.natives.panama.Init;
3031

32+
import java.io.IOException;
33+
import java.nio.file.Files;
34+
3135
import static com.falsepattern.falsetweaks.Share.log;
3236

3337
public class Natives {
@@ -51,6 +55,12 @@ public static void load() throws UnsupportedPlatformException {
5155
public static void loadJNI() throws UnsupportedPlatformException {
5256
log.info("Initializing natives (JNI)");
5357
val loader = new NativeLoader(CPUID.class);
58+
try {
59+
FileUtils.deleteDirectory(loader.nativesDir.toFile());
60+
Files.createDirectories(loader.nativesDir);
61+
} catch (IOException e) {
62+
throw new UnsupportedPlatformException(e);
63+
}
5464
log.info("Loading JNI stubs");
5565
loader.loadNative("jni", null);
5666
log.info("Loading CPUID natives");

src/main/java/com/falsepattern/falsetweaks/modules/natives/Unpacker.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ public String[] names() throws IOException {
5858
return result;
5959
}
6060

61-
public boolean unpack(String blobName, Path into) throws IOException {
61+
public void unpack(String blobName, Path into) throws IOException {
6262
@Cleanup val in = data.openStream();
6363
@Cleanup val dIn = new DataInputStream(in);
6464
val count = dIn.readInt();
@@ -74,9 +74,9 @@ public boolean unpack(String blobName, Path into) throws IOException {
7474
}
7575
@Cleanup val output = new BufferedOutputStream(Files.newOutputStream(into));
7676
copy(dIn, output, length);
77-
return true;
77+
return;
7878
}
79-
return false;
79+
throw new IOException("Blob " + blobName + " not found in pak file!");
8080
}
8181

8282
private void copy(InputStream input, OutputStream output, int bytes) throws IOException {

src/main/zig/cpuid/cpu_util.zig

Lines changed: 27 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -34,38 +34,36 @@ pub const max_name_length_current = switch (builtin.cpu.arch) {
3434
};
3535

3636
fn getSupportedModelsX86() []const *const CpuModel {
37-
comptime {
38-
const cpu = std.Target.x86.cpu;
39-
const decls = @typeInfo(cpu).@"struct".decls;
40-
var result: []const *const CpuModel = &[0]*const CpuModel{};
41-
var i = 0;
42-
for (decls) |decl| {
43-
const cpuModel: *const CpuModel = &@field(cpu, decl.name);
44-
if (cpuModel == &cpu.generic) {
45-
continue;
46-
}
47-
var features = cpuModel.features;
48-
features.populateDependencies(&std.Target.x86.all_features);
49-
if (features.isEnabled(@intFromEnum(std.Target.x86.Feature.@"64bit"))) {
50-
result = result ++ &[_]*const CpuModel{cpuModel};
51-
i += 1;
52-
}
53-
}
54-
return result;
55-
}
37+
const cpu = std.Target.x86.cpu;
38+
return &.{
39+
&cpu.x86_64,
40+
&cpu.x86_64_v2,
41+
&cpu.x86_64_v3,
42+
&cpu.x86_64_v4,
43+
};
44+
// comptime {
45+
// const cpu = std.Target.x86.cpu;
46+
// const decls = @typeInfo(cpu).@"struct".decls;
47+
// var result: []const *const CpuModel = &[0]*const CpuModel{};
48+
// var i = 0;
49+
// for (decls) |decl| {
50+
// const cpuModel: *const CpuModel = &@field(cpu, decl.name);
51+
// if (cpuModel == &cpu.generic) {
52+
// continue;
53+
// }
54+
// var features = cpuModel.features;
55+
// features.populateDependencies(&std.Target.x86.all_features);
56+
// if (features.isEnabled(@intFromEnum(std.Target.x86.Feature.@"64bit"))) {
57+
// result = result ++ &[_]*const CpuModel{cpuModel};
58+
// i += 1;
59+
// }
60+
// }
61+
// return result;
62+
// }
5663
}
5764

5865
fn getSupportedModelsAarch64() []const *const CpuModel {
59-
comptime {
60-
const cpu = std.Target.aarch64.cpu;
61-
const decls = @typeInfo(cpu).@"struct".decls;
62-
var result: []const *const CpuModel = &[0]*const CpuModel{};
63-
for (decls) |decl| {
64-
const cpuModel: *const CpuModel = &@field(cpu, decl.name);
65-
result = result ++ &[_]*const CpuModel{cpuModel};
66-
}
67-
return result;
68-
}
66+
return &.{&std.Target.aarch64.cpu.generic};
6967
}
7068

7169
fn maxNameLength(models: []const *const CpuModel) usize {

0 commit comments

Comments
 (0)