Move all gradle files into folder app

Decouple java and native projects
This commit is contained in:
topjohnwu
2025-05-13 16:25:01 -07:00
committed by John Wu
parent 5dd7a7d804
commit 5a762f0a8e
24 changed files with 54 additions and 52 deletions

View File

@@ -6,10 +6,7 @@ on:
paths: paths:
- "app/**" - "app/**"
- "native/**" - "native/**"
- "buildSrc/**"
- "build.py" - "build.py"
- "gradle.properties"
- "gradle/libs.versions.toml"
- ".github/workflows/build.yml" - ".github/workflows/build.yml"
pull_request: pull_request:
branches: [master] branches: [master]
@@ -39,7 +36,7 @@ jobs:
run: ./build.py -v all run: ./build.py -v all
- name: Stop gradle daemon - name: Stop gradle daemon
run: ./gradlew --stop run: ./app/gradlew --stop
- name: Upload build artifact - name: Upload build artifact
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
@@ -75,7 +72,7 @@ jobs:
run: python build.py -v -c .github/ci.prop all run: python build.py -v -c .github/ci.prop all
- name: Stop gradle daemon - name: Stop gradle daemon
run: ./gradlew --stop run: ./app/gradlew --stop
avd-test: avd-test:
name: Test API ${{ matrix.version }} (x86_64) name: Test API ${{ matrix.version }} (x86_64)

8
.gitignore vendored
View File

@@ -5,16 +5,10 @@ out
*.log *.log
/config.prop /config.prop
/notes.md /notes.md
/app/dict.txt
# Built binaries # Built binaries
native/out native/out
# Android Studio / Gradle # Android Studio
*.iml *.iml
.gradle
.idea .idea
.kotlin
/local.properties
/build
/captures

7
app/.gitignore vendored Normal file
View File

@@ -0,0 +1,7 @@
/dict.txt
# Gradle
.gradle
.kotlin
/local.properties
/build

View File

@@ -35,7 +35,7 @@ android {
} }
dependencies { dependencies {
implementation(project(":app:core")) implementation(project(":core"))
coreLibraryDesugaring(libs.jdk.libs) coreLibraryDesugaring(libs.jdk.libs)
implementation(libs.indeterminate.checkbox) implementation(libs.indeterminate.checkbox)

View File

@@ -1,5 +1,11 @@
tasks.register("clean") { plugins {
id("MagiskPlugin")
}
tasks.register("clean", Delete::class) {
delete(rootProject.layout.buildDirectory)
subprojects.forEach { subprojects.forEach {
dependsOn(":app:${it.name}:clean") dependsOn(":${it.name}:clean")
} }
} }

View File

@@ -14,7 +14,7 @@ private val defaultAbis = setOf("armeabi-v7a", "x86", "arm64-v8a", "x86_64")
object Config { object Config {
operator fun get(key: String): String? { operator fun get(key: String): String? {
val v = props[key] as? String ?: return null val v = props[key] as? String ?: return null
return if (v.isBlank()) null else v return v.ifBlank { null }
} }
fun contains(key: String) = get(key) != null fun contains(key: String) = get(key) != null
@@ -28,19 +28,21 @@ object Config {
} }
} }
val Project.baseDir: File get() = rootProject.file("..")
class MagiskPlugin : Plugin<Project> { class MagiskPlugin : Plugin<Project> {
override fun apply(project: Project) = project.applyPlugin() override fun apply(project: Project) = project.applyPlugin()
private fun Project.applyPlugin() { private fun Project.applyPlugin() {
initRandom(rootProject.file("app/dict.txt")) initRandom(rootProject.file("dict.txt"))
props.clear() props.clear()
rootProject.file("gradle.properties").inputStream().use { props.load(it) } rootProject.file("gradle.properties").inputStream().use { props.load(it) }
val configPath: String? by this val configPath: String? by this
val config = configPath?.let { File(it) } ?: rootProject.file("config.prop") val config = configPath?.let { File(it) } ?: File(baseDir, "config.prop")
if (config.exists()) if (config.exists())
config.inputStream().use { props.load(it) } config.inputStream().use { props.load(it) }
val repo = FileRepository(rootProject.file(".git")) val repo = FileRepository(File(baseDir, ".git"))
val refId = repo.refDatabase.exactRef("HEAD").objectId val refId = repo.refDatabase.exactRef("HEAD").objectId
commitHash = repo.newObjectReader().abbreviate(refId, 8).name() commitHash = repo.newObjectReader().abbreviate(refId, 8).name()
} }

View File

@@ -151,7 +151,7 @@ fun Project.setupCoreLib() {
into("src/main/jniLibs") into("src/main/jniLibs")
for (abi in abiList) { for (abi in abiList) {
into(abi) { into(abi) {
from(rootProject.file("native/out/$abi")) { from(File(baseDir, "native/out/$abi")) {
include("magiskboot", "magiskinit", "magiskpolicy", "magisk", "libinit-ld.so") include("magiskboot", "magiskinit", "magiskpolicy", "magisk", "libinit-ld.so")
rename { if (it.endsWith(".so")) it else "lib$it.so" } rename { if (it.endsWith(".so")) it else "lib$it.so" }
} }
@@ -173,10 +173,10 @@ fun Project.setupCoreLib() {
val syncResources by tasks.registering(Sync::class) { val syncResources by tasks.registering(Sync::class) {
into("src/main/resources/META-INF/com/google/android") into("src/main/resources/META-INF/com/google/android")
from(rootProject.file("scripts/update_binary.sh")) { from(File(baseDir, "scripts/update_binary.sh")) {
rename { "update-binary" } rename { "update-binary" }
} }
from(rootProject.file("scripts/flash_script.sh")) { from(File(baseDir, "scripts/flash_script.sh")) {
rename { "updater-script" } rename { "updater-script" }
} }
} }
@@ -187,7 +187,7 @@ fun Project.setupCoreLib() {
tasks.getByPath("merge${variantCapped}JniLibFolders").dependsOn(downloadBusybox) tasks.getByPath("merge${variantCapped}JniLibFolders").dependsOn(downloadBusybox)
processJavaResourcesProvider.configure { dependsOn(syncResources) } processJavaResourcesProvider.configure { dependsOn(syncResources) }
val stubTask = tasks.getByPath(":app:stub:comment$variantCapped") val stubTask = tasks.getByPath(":stub:comment$variantCapped")
val stubApk = stubTask.outputs.files.asFileTree.filter { val stubApk = stubTask.outputs.files.asFileTree.filter {
it.name.endsWith(".apk") it.name.endsWith(".apk")
} }
@@ -197,14 +197,14 @@ fun Project.setupCoreLib() {
inputs.property("version", Config.version) inputs.property("version", Config.version)
inputs.property("versionCode", Config.versionCode) inputs.property("versionCode", Config.versionCode)
into("src/${this@all.name}/assets") into("src/${this@all.name}/assets")
from(rootProject.file("scripts")) { from(File(baseDir, "scripts")) {
include("util_functions.sh", "boot_patch.sh", "addon.d.sh", include("util_functions.sh", "boot_patch.sh", "addon.d.sh",
"app_functions.sh", "uninstaller.sh", "module_installer.sh") "app_functions.sh", "uninstaller.sh", "module_installer.sh")
} }
from(rootProject.file("tools/bootctl")) from(File(baseDir, "tools/bootctl"))
into("chromeos") { into("chromeos") {
from(rootProject.file("tools/futility")) from(File(baseDir, "tools/futility"))
from(rootProject.file("tools/keys")) { from(File(baseDir, "tools/keys")) {
include("kernel_data_key.vbprivk", "kernel.keyblock") include("kernel_data_key.vbprivk", "kernel.keyblock")
} }
} }
@@ -294,7 +294,7 @@ fun Project.setupAppCommon() {
signingConfigs { signingConfigs {
create("config") { create("config") {
Config["keyStore"]?.also { Config["keyStore"]?.also {
storeFile = rootProject.file(it) storeFile = File(baseDir, it)
storePassword = Config["keyStorePass"] storePassword = Config["keyStorePass"]
keyAlias = Config["keyAlias"] keyAlias = Config["keyAlias"]
keyPassword = Config["keyPass"] keyPassword = Config["keyPass"]

View File

@@ -29,7 +29,7 @@ android {
} }
dependencies { dependencies {
api(project(":app:shared")) api(project(":shared"))
api(libs.timber) api(libs.timber)
api(libs.markwon.core) api(libs.markwon.core)

View File

@@ -31,4 +31,3 @@ android.nonFinalResIds=false
# Magisk # Magisk
magisk.stubVersion=40 magisk.stubVersion=40
magisk.versionCode=28104 magisk.versionCode=28104
magisk.ondkVersion=r29.1

View File

View File

View File

@@ -8,4 +8,4 @@ dependencyResolutionManagement {
} }
} }
rootProject.name = "Magisk" rootProject.name = "Magisk"
include(":app:apk", ":app:core", ":app:shared", ":app:stub", ":app:test", ":native") include(":apk", ":core", ":shared", ":stub", ":test")

View File

@@ -41,5 +41,5 @@ android {
setupStubApk() setupStubApk()
dependencies { dependencies {
implementation(project(":app:shared")) implementation(project(":shared"))
} }

View File

@@ -1,7 +0,0 @@
plugins {
id("MagiskPlugin")
}
tasks.register("clean", Delete::class) {
delete(rootProject.layout.buildDirectory)
}

View File

@@ -71,6 +71,7 @@ default_archs = {"armeabi-v7a", "x86", "arm64-v8a", "x86_64"}
default_targets = {"magisk", "magiskinit", "magiskboot", "magiskpolicy"} default_targets = {"magisk", "magiskinit", "magiskboot", "magiskpolicy"}
support_targets = default_targets | {"resetprop"} support_targets = default_targets | {"resetprop"}
rust_targets = {"magisk", "magiskinit", "magiskboot", "magiskpolicy"} rust_targets = {"magisk", "magiskinit", "magiskboot", "magiskpolicy"}
ondk_version = "r29.1"
# Global vars # Global vars
config = {} config = {}
@@ -318,7 +319,7 @@ def build_native():
# Verify NDK install # Verify NDK install
try: try:
with open(Path(ndk_path, "ONDK_VERSION"), "r") as ondk_ver: with open(Path(ndk_path, "ONDK_VERSION"), "r") as ondk_ver:
assert ondk_ver.read().strip(" \t\r\n") == config["ondkVersion"] assert ondk_ver.read().strip(" \t\r\n") == ondk_version
except: except:
error('Unmatched NDK. Please install/upgrade NDK with "build.py ndk"') error('Unmatched NDK. Please install/upgrade NDK with "build.py ndk"')
@@ -383,16 +384,19 @@ def find_jdk():
def build_apk(module: str): def build_apk(module: str):
ensure_paths() ensure_paths()
env = find_jdk() env = find_jdk()
props = args.config.resolve()
os.chdir("app")
build_type = "Release" if args.release else "Debug" build_type = "Release" if args.release else "Debug"
proc = execv( proc = execv(
[ [
gradlew, gradlew,
f"{module}:assemble{build_type}", f"{module}:assemble{build_type}",
f"-PconfigPath={args.config.resolve()}", f"-PconfigPath={props}",
], ],
env=env, env=env,
) )
os.chdir("..")
if proc.returncode != 0: if proc.returncode != 0:
error(f"Build {module} failed!") error(f"Build {module} failed!")
@@ -401,7 +405,7 @@ def build_apk(module: str):
paths = module.split(":") paths = module.split(":")
apk = f"{paths[-1]}-{build_type}.apk" apk = f"{paths[-1]}-{build_type}.apk"
source = Path(*paths, "build", "outputs", "apk", build_type, apk) source = Path("app", *paths, "build", "outputs", "apk", build_type, apk)
target = config["outdir"] / apk target = config["outdir"] / apk
mv(source, target) mv(source, target)
return target return target
@@ -409,7 +413,7 @@ def build_apk(module: str):
def build_app(): def build_app():
header("* Building the Magisk app") header("* Building the Magisk app")
apk = build_apk(":app:apk") apk = build_apk(":apk")
build_type = "release" if args.release else "debug" build_type = "release" if args.release else "debug"
@@ -428,7 +432,7 @@ def build_app():
def build_stub(): def build_stub():
header("* Building the stub app") header("* Building the stub app")
apk = build_apk(":app:stub") apk = build_apk(":stub")
header(f"Output: {apk}") header(f"Output: {apk}")
@@ -439,7 +443,7 @@ def build_test():
args.release = True args.release = True
try: try:
header("* Building the test app") header("* Building the test app")
source = build_apk(":app:test") source = build_apk(":test")
target = source.parent / "test.apk" target = source.parent / "test.apk"
mv(source, target) mv(source, target)
header(f"Output: {target}") header(f"Output: {target}")
@@ -548,10 +552,9 @@ def cargo_cli():
def setup_ndk(): def setup_ndk():
ensure_paths() ensure_paths()
ndk_ver = config["ondkVersion"] url = f"https://github.com/topjohnwu/ondk/releases/download/{ondk_version}/ondk-{ondk_version}-{os_name}.tar.xz"
url = f"https://github.com/topjohnwu/ondk/releases/download/{ndk_ver}/ondk-{ndk_ver}-{os_name}.tar.xz"
ndk_archive = url.split("/")[-1] ndk_archive = url.split("/")[-1]
ondk_path = Path(ndk_root, f"ondk-{ndk_ver}") ondk_path = Path(ndk_root, f"ondk-{ondk_version}")
header(f"* Downloading and extracting {ndk_archive}") header(f"* Downloading and extracting {ndk_archive}")
rm_rf(ondk_path) rm_rf(ondk_path)
@@ -699,7 +702,7 @@ def ensure_paths():
ndk_path / "toolchains" / "llvm" / "prebuilt" / f"{os_name}-x86_64" / "bin" ndk_path / "toolchains" / "llvm" / "prebuilt" / f"{os_name}-x86_64" / "bin"
) )
adb_path = sdk_path / "platform-tools" / "adb" adb_path = sdk_path / "platform-tools" / "adb"
gradlew = Path.cwd() / "gradlew" gradlew = Path.cwd() / "app" / "gradlew"
# We allow using several functionality with only ADB # We allow using several functionality with only ADB
@@ -750,8 +753,9 @@ def load_config():
if args.config.exists(): if args.config.exists():
config.update(parse_props(args.config)) config.update(parse_props(args.config))
if Path("gradle.properties").exists(): gradle_props = Path("app", "gradle.properties")
for key, value in parse_props("gradle.properties").items(): if gradle_props.exists():
for key, value in parse_props(gradle_props).items():
if key.startswith("magisk."): if key.startswith("magisk."):
config[key[7:]] = value config[key[7:]] = value

View File

@@ -11,7 +11,7 @@ CONFIG=config.prop
NOTES=notes.md NOTES=notes.md
# These are constants, do not modify # These are constants, do not modify
GCONFIG=gradle.properties GCONFIG=app/gradle.properties
README=README.MD README=README.MD
BUILDCMD="./build.py -c $CONFIG" BUILDCMD="./build.py -c $CONFIG"
CWD=$(pwd) CWD=$(pwd)