Skip to content

Commit 8aa5f90

Browse files
committed
Update JNI submodule reference and enhance plugin native library handling. Modify README.md for clarity on submodule usage and CI integration. Adjust build.gradle.kts to enable native library obfuscation and improve task synchronization for different OS architectures.
1 parent bac29f1 commit 8aa5f90

18 files changed

Lines changed: 126 additions & 36 deletions

File tree

.gitmodules

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# JNI native library (private repo). To init: git submodule update --init --recursive
2-
# If the repo URL is not accessible, place the JNI library at stringcare-jni/ (copy from ../stringcare-jni-android-library) or ensure library/CMakeLists.txt path is correct.
2+
# If the repo URL is not accessible, place the JNI library at stringcare-jni/ (copy from ../stringcare-android-c) or ensure library/CMakeLists.txt path is correct.
33
[submodule "stringcare-jni"]
44
path = stringcare-jni
5-
url = [email protected]:vypdev/stringcare-jni-android-library.git
5+
url = [email protected]:vypdev/stringcare-android-c.git

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,9 @@ For **Groovy** use `buildscript` / `apply plugin: 'dev.vyp.stringcare.plugin'` a
7777

7878
#### [Resource Tips](https://github.com/StringCare/AndroidLibrary/wiki/Resource-Tips)
7979

80-
**Build / CI:** This project uses the JNI native library as a Git submodule (`stringcare-jni`). Clone with submodules: `git clone --recurse-submodules ...` or run `git submodule update --init --recursive` after clone. CI workflows must use `checkout` with `submodules: true`.
80+
**Build / CI:** This project uses the JNI native library as a Git submodule (`stringcare-jni`, e.g. stringcare-android-c). Clone with submodules: `git clone --recurse-submodules ...` or run `git submodule update --init --recursive` after clone. CI workflows must use `checkout` with `submodules: true`.
81+
82+
**Plugin host natives:** After building prebuilts in the submodule (`stringcare-jni/dist/{macos,linux,windows}/`), copy them into the plugin with **`./gradlew :plugin:syncPluginNativeLibraries`**. macOS ships a universal `libsignKey.dylib`; Linux and Windows ship x64 and arm64 variants (`*.so` / `*.dll`).
8183

8284
**Publishing (release workflow):** See [CONTRIBUTING.md](CONTRIBUTING.md) for required secrets: `NEXUS_USERNAME`, `NEXUS_PASSWORD`, `GPG_KEY_ID`, `GPG_PASSPHRASE`, `PAT`. When dispatching the release workflow, set **Publish Maven** to `true` to run the publish job (publishes both `dev.vyp.stringcare:library` and `dev.vyp.stringcare:plugin`).
8385

app/build.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ plugins {
66

77
stringcare {
88
debug = false
9-
skip = true // Set to false when running on x86_64 or when arm64 dylib is available; plugin JNI is x86_64 only
9+
skip = false // Obfuscation runs when native lib is available (x86_64 or arm64); otherwise tasks skip automatically
1010
assetsFiles = mutableListOf("*.json")
1111
stringFiles = mutableListOf("strings.xml")
1212
srcFolders = mutableListOf("src/main")

docs/architecture.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ The **plugin** module:
2323

2424
- Implements the Gradle plugin entry point **`StringCarePlugin`** (implements `Plugin<Project>`), creates the **`stringcare`** extension (`StringCareExtension`) and registers tasks.
2525
- Uses the **AGP 8.7 Variant API**: it does **not** use `BuildListener`. It uses `project.plugins.withId("com.android.application")` and then `project.extensions.getByType(AndroidComponentsExtension::class.java)` and **`onVariants`** to register per-variant tasks (e.g. `stringcareBeforeMergeResourcesDebug`, `stringcareAfterMergeResourcesDebug`, and the same for Assets). Each variant gets before/after merge tasks for resources and for assets; the “before” tasks obfuscate, the “after” tasks restore originals from backup.
26-
- Contains **JNI** (dll/dylib) in `src/main/kotlin/.../internal/jni` for development (e.g. signing/fingerprint on the host). These are packaged via `processResources` and are separate from the library’s native code (stringcare-jni).
26+
- Contains **JNI** (`.dylib`, `.dll`, `.so`) in `src/main/kotlin/.../internal/jni` for the **host** (Gradle on macOS, Windows, or Linux). Prebuilts are built in **stringcare-jni** under `dist/{macos,linux,windows}/` and copied with `:plugin:syncPluginNativeLibraries`. macOS uses a universal `libsignKey.dylib`; Linux and Windows ship x64 and arm64 binaries. Packaged via `processResources`; separate from the app’s **sc-native-lib** in the library module.
2727

2828
## Flow
2929

docs/build-and-ci.md

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,17 @@ To run instrumented tests (requires an emulator or device):
3636
- **app** — Demo Android application; applies the StringCare plugin and depends on the library.
3737
- **library** — Android library (AAR) that provides the runtime API (`SC`, `SCTextView`, etc.) and loads the native library from **stringcare-jni** via CMake.
3838
- **plugin** — Gradle plugin (JVM); included as a **composite build** via `includeBuild("plugin")` in the root `settings.gradle.kts`, not as `include(":plugin")`. So the plugin is built from the `plugin/` directory and applied to the app by ID `dev.vyp.stringcare.plugin`.
39-
- **stringcare-jni** — Git submodule containing the native C++ code used by the library (and optionally by the plugin for signing/fingerprint). The library’s `CMakeLists.txt` points to `../stringcare-jni/lib` for the native source.
39+
- **stringcare-jni** — Git submodule containing the native C++ code used by the library and the **plugin host** prebuilts. The library’s `CMakeLists.txt` points to `../stringcare-jni/lib` for the Android JNI source. Plugin host binaries are produced under **`stringcare-jni/dist/`** (`macos/`, `linux/`, `windows/`).
40+
41+
### Syncing plugin host natives into the plugin JAR
42+
43+
After building natives in the submodule (see that repo’s build output), run from the stringcare-android root:
44+
45+
```bash
46+
./gradlew :plugin:syncPluginNativeLibraries
47+
```
48+
49+
This copies `dist/macos/*.dylib`, `dist/linux/*.so`, and `dist/windows/*.dll` into `plugin/src/main/kotlin/dev/vyp/stringcare/plugin/internal/jni/` so they are packaged with the plugin.
4050

4151
## CI
4252

docs/troubleshooting.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,4 +60,4 @@ See [Build and CI](build-and-ci.md).
6060

6161
- The **library** requires **minSdk 21** and a valid NDK/CMake setup. The **stringcare-jni** submodule must be present (see “Submodule not loaded” above).
6262
- **ABI filters:** The library builds for the default ABIs (e.g. armeabi-v7a, arm64-v8a, x86, x86_64). If you restrict ABIs in your app, ensure the library is compatible.
63-
- The **plugin** ships JNI (dylib/dll) for development (e.g. fingerprint on the host). These are for the plugin’s own use (e.g. signing report); on some environments (e.g. non-x86_64 or when the host library is missing) you may need to set **`skip = true`** in the `stringcare` block to skip obfuscation and still build. See [Build and CI](build-and-ci.md) and [Configuration](configuration.md).
63+
- The **plugin** ships JNI for the **host** (Gradle runs on macOS, Windows, or Linux). Prebuilts are produced in **stringcare-jni** (stringcare-android-c): `dist/macos/libsignKey.dylib` (universal x86_64+arm64), `dist/linux/libsignKey.so` / `libsignKey-arm64.so`, `dist/windows/libsignKey.dll` / `libsignKey-arm64.dll`. After building there, sync into this repo with **`./gradlew :plugin:syncPluginNativeLibraries`** (requires submodule at `stringcare-jni/`). If the native library for your OS/arch is missing, set **`skip = true`** in the `stringcare` block or run the sync task. See [Build and CI](build-and-ci.md) and [Configuration](configuration.md).

library/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ project("stringcare-native" CXX)
88
if(EXISTS "${CMAKE_SOURCE_DIR}/../stringcare-jni/lib/sc-native-lib.cpp")
99
set(JNI_SOURCE_DIR "${CMAKE_SOURCE_DIR}/../stringcare-jni/lib")
1010
else()
11-
set(JNI_SOURCE_DIR "${CMAKE_SOURCE_DIR}/../../stringcare-jni-android-library/lib")
11+
set(JNI_SOURCE_DIR "${CMAKE_SOURCE_DIR}/../../stringcare-android-c/lib")
1212
endif()
1313

1414
add_library(sc-native-lib SHARED

plugin/build.gradle.kts

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,27 @@ if (project.hasProperty("signing.gnupg.keyName")) {
9797
tasks.processResources {
9898
duplicatesStrategy = DuplicatesStrategy.INCLUDE
9999
from("src/main/kotlin/dev/vyp/stringcare/plugin/internal/jni") {
100-
include("*.dylib", "*.dll")
100+
include("*.dylib", "*.dll", "*.so")
101+
}
102+
}
103+
104+
/**
105+
* Copy prebuilt plugin natives from the stringcare-jni submodule (stringcare-android-c dist/).
106+
* Run after building natives there: ./gradlew :plugin:syncPluginNativeLibraries
107+
*/
108+
tasks.register<Copy>("syncPluginNativeLibraries") {
109+
val dist = rootProject.layout.projectDirectory.dir("stringcare-jni/dist")
110+
val jni = layout.projectDirectory.dir("src/main/kotlin/dev/vyp/stringcare/plugin/internal/jni")
111+
from(dist.dir("macos")) { include("*.dylib") }
112+
from(dist.dir("linux")) { include("*.so") }
113+
from(dist.dir("windows")) { include("*.dll") }
114+
into(jni)
115+
doFirst {
116+
if (!dist.asFile.exists()) {
117+
throw GradleException(
118+
"stringcare-jni/dist not found. Init submodule: git submodule update --init --recursive " +
119+
"then build natives in stringcare-android-c (see that repo's docs)."
120+
)
121+
}
101122
}
102123
}

plugin/src/main/kotlin/dev/vyp/stringcare/plugin/internal/Execution.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ private fun execute(runtime: Runtime, command: String): ExecutionResult {
2323
process.outputString()
2424
)
2525
}
26-
Os.OSX -> {
26+
Os.OSX, Os.LINUX -> {
2727
ExecutionResult(
2828
command,
2929
runtime.exec(

plugin/src/main/kotlin/dev/vyp/stringcare/plugin/internal/Extensions.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ fun String.normalizePath(): String {
5151
.replace("\\\\", "/")
5252
.replace("//", "/")
5353
return when (getOs()) {
54-
Os.OSX -> unixPath
54+
Os.OSX, Os.LINUX -> unixPath
5555
Os.WINDOWS -> unixPath.replace("/", "\\")
5656
}
5757
}

0 commit comments

Comments
 (0)