ffi #jni_main: emit static { System.loadLibrary(...); } in the Java class
Required for Android to resolve the `Java_*` symbols R.3 synthesises:
without `System.loadLibrary(...)` running before the Activity calls its
first native method, JNI lookup fails with UnsatisfiedLinkError.
The lib name comes from the build's `-o` basename — `/tmp/libsxchess.so`
→ `sxchess` — derived in `Compilation.collectJniMainEmissions` and
threaded through new `jni_java_emit.Options.lib_name`. When `-o` is
unset (or doesn't match `lib*.so`), the emitter omits the static init
and the caller must arrange loading another way.
dex confirmation on the slice 2 smoke: `<clinit>` static constructor
appears alongside `<init>` and `sx_onCreate` — the bytecode invokes
`System.loadLibrary("sxjnimain")` matching `/tmp/libsxjnimain.so`.
131 host / 4 cross / zig build test all green.
This commit is contained in:
@@ -47,6 +47,12 @@ pub const Options = struct {
|
||||
/// Activities — `NativeActivity` is the legacy NDK path that
|
||||
/// requires native_app_glue's `ANativeActivity_onCreate`.
|
||||
default_extends: []const u8 = "android.app.Activity",
|
||||
/// `System.loadLibrary(...)` argument for the emitted static init
|
||||
/// block. When set, the emitter inserts `static { System.loadLibrary
|
||||
/// (lib_name); }` so JNI native delegates can resolve at runtime.
|
||||
/// When null, no static init is emitted (caller must arrange .so
|
||||
/// loading some other way — e.g. another class's static init).
|
||||
lib_name: ?[]const u8 = null,
|
||||
};
|
||||
|
||||
/// Emit a `.java` source for the given foreign-class decl. Result is
|
||||
@@ -113,8 +119,14 @@ pub fn emitJavaSource(
|
||||
|
||||
try buf.appendSlice(allocator, " {\n");
|
||||
|
||||
// Two passes: @Override stubs that call super + native delegate,
|
||||
// then the native declarations.
|
||||
if (opts.lib_name) |ln| {
|
||||
try buf.appendSlice(allocator, " static { System.loadLibrary(\"");
|
||||
try buf.appendSlice(allocator, ln);
|
||||
try buf.appendSlice(allocator, "\"); }\n");
|
||||
}
|
||||
|
||||
// Two passes: @Override stubs + native delegate; then the native
|
||||
// declarations.
|
||||
for (fcd.members) |m| switch (m) {
|
||||
.method => |md| {
|
||||
if (md.body == null) continue;
|
||||
|
||||
Reference in New Issue
Block a user