diff --git a/priv/templates/mob.new/android/app/src/main/AndroidManifest.xml.eex b/priv/templates/mob.new/android/app/src/main/AndroidManifest.xml.eex
index 0cbdbfa..b84c4ee 100644
--- a/priv/templates/mob.new/android/app/src/main/AndroidManifest.xml.eex
+++ b/priv/templates/mob.new/android/app/src/main/AndroidManifest.xml.eex
@@ -54,6 +54,21 @@
+
+
+
.so.
+ // Plugin Kotlin files are handled separately by Gradle (copied into
+ // the project's java tree by mob_dev).
+ if (project_plugin_sources.len > 0) {
+ var plug_it = std.mem.splitScalar(u8, project_plugin_sources, ',');
+ while (plug_it.next()) |pair| {
+ if (pair.len == 0) continue;
+ var colon_it = std.mem.splitScalar(u8, pair, ':');
+ const name = colon_it.next() orelse continue;
+ const path = colon_it.next() orelse continue;
+ const obj = addCObject(b, .{
+ .name = name,
+ .source = path,
+ .target = target,
+ .optimize = optimize,
+ .c_flags = c_flags,
+ .otp_dir = otp_dir,
+ .erts_vsn = erts_vsn,
+ .mob_dir = mob_dir,
+ });
+ const install = b.addInstallFile(obj, b.fmt("{s}/{s}.o", .{ abi, name }));
+ c_objects_step.dependOn(&install.step);
+ obj_paths.append(b.allocator, obj) catch @panic("OOM");
+ }
+ }
+
// Link: zig cc -shared, mirroring CMake's prior target_link_libraries
// (--gc-sections + --whole-archive bracket around the OTP/crypto static
// libs + plain libcrypto.a + Android system libs). Returns the cp