diff --git a/build-logic/ide/src/main/java/FDroidConfig.kt b/build-logic/ide/src/main/java/FDroidConfig.kt
index 1b29165a65..58f116da41 100644
--- a/build-logic/ide/src/main/java/FDroidConfig.kt
+++ b/build-logic/ide/src/main/java/FDroidConfig.kt
@@ -1,6 +1,3 @@
-import org.gradle.api.Project
-import java.io.File
-
/*
* This file is part of AndroidIDE.
*
@@ -18,6 +15,9 @@ import java.io.File
* along with AndroidIDE. If not, see .
*/
+import org.gradle.api.Project
+import java.io.File
+
/**
* @author Akash Yadav
*/
@@ -28,6 +28,10 @@ object FDroidConfig {
var isFDroidBuild: Boolean = false
private set
+ get() = hasRead && field
+
+ var fDroidBuildArch: String? = null
+ private set
var fDroidVersionName: String? = null
private set
@@ -35,9 +39,14 @@ object FDroidConfig {
var fDroidVersionCode: Int? = null
private set
+ var fDroidAapt2File: String? = null
+ private set
+
const val PROP_FDROID_BUILD = "ide.build.fdroid"
+ const val PROP_FDROID_BUILD_ARCH = "ide.build.fdroid.arch"
const val PROP_FDROID_BUILD_VERSION = "ide.build.fdroid.version"
const val PROP_FDROID_BUILD_VERCODE = "ide.build.fdroid.vercode"
+ const val PROP_FDROID_AAPT2FILE = "ide.build.fdroid.aapt2File"
fun load(project: Project) {
val propsFile = File(project.rootDir, "fdroid.properties")
@@ -56,7 +65,9 @@ object FDroidConfig {
hasRead = true
isFDroidBuild = properties.getProperty(PROP_FDROID_BUILD, null).toBoolean()
+ fDroidBuildArch = properties.getProperty(PROP_FDROID_BUILD_ARCH, null)
fDroidVersionName = properties.getProperty(PROP_FDROID_BUILD_VERSION, null)
fDroidVersionCode = properties.getProperty(PROP_FDROID_BUILD_VERCODE, null)?.toInt()
+ fDroidAapt2File = properties.getProperty(PROP_FDROID_AAPT2FILE, null)
}
}
\ No newline at end of file
diff --git a/build-logic/ide/src/main/java/com/itsaky/androidide/plugins/AndroidIDEAssetsPlugin.kt b/build-logic/ide/src/main/java/com/itsaky/androidide/plugins/AndroidIDEAssetsPlugin.kt
index 5dd1bb2f3e..4777f5aa62 100644
--- a/build-logic/ide/src/main/java/com/itsaky/androidide/plugins/AndroidIDEAssetsPlugin.kt
+++ b/build-logic/ide/src/main/java/com/itsaky/androidide/plugins/AndroidIDEAssetsPlugin.kt
@@ -18,9 +18,11 @@
package com.itsaky.androidide.plugins
import BuildConfig
+import FDroidConfig
import VersionUtils
import com.android.build.api.variant.AndroidComponentsExtension
import com.android.build.gradle.BaseExtension
+import com.itsaky.androidide.plugins.conf.flavorsAbis
import com.itsaky.androidide.plugins.tasks.AddAndroidJarToAssetsTask
import com.itsaky.androidide.plugins.tasks.AddFileToAssetsTask
import com.itsaky.androidide.plugins.tasks.DownloadAapt2Task
@@ -31,6 +33,7 @@ import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.tasks.TaskProvider
import org.gradle.configurationcache.extensions.capitalized
+import java.io.File
/**
* Handles asset copying and generation.
@@ -57,15 +60,7 @@ class AndroidIDEAssetsPlugin : Plugin {
val androidComponentsExtension = extensions.getByType(AndroidComponentsExtension::class.java)
val baseExtension = extensions.getByType(BaseExtension::class.java)
- val aapt2Tasks = mutableMapOf>()
- baseExtension.productFlavors.forEach { flavor ->
- aapt2Tasks[flavor.name] = tasks.register("downloadAapt2${flavor.name.capitalized()}",
- DownloadAapt2Task::class.java) {
- arch.set(flavor.name)
- checksum.set(AAPT2_CHECKSUMS[flavor.name] ?: throw IllegalStateException(
- "Checksum for aapt2-${flavor.name} not found!"))
- }
- }
+ val aapt2Tasks = getAapt2DownloadTasks(baseExtension)
val addAndroidJarTaskProvider = tasks.register("addAndroidJarToAssets",
AddAndroidJarToAssetsTask::class.java) {
@@ -74,9 +69,17 @@ class AndroidIDEAssetsPlugin : Plugin {
androidComponentsExtension.onVariants { variant ->
- val downloadAapt2TaskProvider = aapt2Tasks[variant.flavorName]
- ?: throw IllegalStateException(
- "'aapt2' task not registered for flavor '${variant.flavorName}'")
+ if (aapt2Tasks.isNotEmpty()) {
+ val downloadAapt2TaskProvider = aapt2Tasks[variant.flavorName]
+ ?: throw IllegalStateException(
+ "'aapt2' task not registered for flavor '${variant.flavorName}'")
+
+ variant.sources.assets?.addGeneratedSourceDirectory(downloadAapt2TaskProvider,
+ DownloadAapt2Task::outputDirectory)
+ } else {
+ variant.sources.assets?.addStaticSourceDirectory(
+ getStaticFDroidAapt2Dir(variant.flavorName!!))
+ }
val variantNameCapitalized = variant.name.capitalized()
@@ -86,9 +89,6 @@ class AndroidIDEAssetsPlugin : Plugin {
variant.sources.assets?.addGeneratedSourceDirectory(addAndroidJarTaskProvider,
AddAndroidJarToAssetsTask::outputDirectory)
- variant.sources.assets?.addGeneratedSourceDirectory(downloadAapt2TaskProvider,
- DownloadAapt2Task::outputDirectory)
-
// Init script generator
val generateInitScript = tasks.register(
"generate${variantNameCapitalized}InitScript",
@@ -126,5 +126,64 @@ class AndroidIDEAssetsPlugin : Plugin {
}
}
}
+
+ private fun Project.getStaticFDroidAapt2Dir(flavorName: String): String {
+ val fdroidArch = FDroidConfig.fDroidBuildArch!!
+ val fdroidAapt2 = FDroidConfig.fDroidAapt2File!!
+
+ require(fdroidArch in flavorsAbis.keys) {
+ "F-Droid arch '${fdroidArch}' is not supported!"
+ }
+
+
+ val inFile = File(fdroidAapt2)
+ require(inFile.exists() && inFile.isFile) {
+ "F-Droid AAPT2 file does not exist or is not a file: $inFile"
+ }
+
+ val assetDir = project.layout.buildDirectory.dir("intermediates/fdroid-aapt2-${flavorName}")
+ .get().asFile
+
+ if (assetDir.exists()) {
+ assetDir.deleteRecursively()
+ }
+
+ assetDir.mkdirs()
+
+ val outFile = File(assetDir, "data/$flavorName/aapt2")
+ outFile.parentFile.mkdirs()
+
+ inFile.copyTo(outFile, overwrite = true)
+
+ return assetDir.absolutePath
+ }
+
+ private fun Project.getAapt2DownloadTasks(
+ baseExtension: BaseExtension
+ ): Map> {
+
+ if (FDroidConfig.isFDroidBuild) {
+ // Do not download AAPT2 when building for F-Droid
+ return emptyMap()
+ }
+
+ val aapt2Tasks = mutableMapOf>()
+
+ baseExtension.productFlavors.forEach { flavor ->
+
+ val task = tasks.register(
+ "downloadAapt2${flavor.name.capitalized()}",
+ DownloadAapt2Task::class.java
+ ) {
+ arch.set(flavor.name)
+ checksum.set(AAPT2_CHECKSUMS[flavor.name] ?: throw IllegalStateException(
+ "Checksum for aapt2-${flavor.name} not found!"))
+ }
+
+ aapt2Tasks[flavor.name] = task
+ }
+
+ return aapt2Tasks
+ }
}
diff --git a/build-logic/ide/src/main/java/com/itsaky/androidide/plugins/conf/AndroidModuleConf.kt b/build-logic/ide/src/main/java/com/itsaky/androidide/plugins/conf/AndroidModuleConf.kt
index 77c033652b..79c6de81d0 100644
--- a/build-logic/ide/src/main/java/com/itsaky/androidide/plugins/conf/AndroidModuleConf.kt
+++ b/build-logic/ide/src/main/java/com/itsaky/androidide/plugins/conf/AndroidModuleConf.kt
@@ -33,9 +33,7 @@ import projectVersionCode
* For example, if the base version code of the IDE is 270 (for v2.7.0), then for arm64-v8a
* flavor, the version code will be `100 * 270 + 1` i.e. `2701`
*/
-// IMPORTANT: When changing the configuration here, make sure to update the following file:
-// - /scripts/setup_fdroid_build.sh
-private val flavorsAbis = mapOf("arm64-v8a" to 1, "armeabi-v7a" to 2, "x86_64" to 3)
+internal val flavorsAbis = mapOf("arm64-v8a" to 1, "armeabi-v7a" to 2, "x86_64" to 3)
private val disableCoreLibDesugaringForModules = arrayOf(":logsender", ":logger")
fun Project.configureAndroidModule(
diff --git a/build.gradle.kts b/build.gradle.kts
index 5f1ce1a638..457cae3bab 100755
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -41,6 +41,9 @@ buildscript {
}
subprojects {
+ // Always load the F-Droid config
+ FDroidConfig.load(project)
+
afterEvaluate {
apply { plugin(AndroidIDEPlugin::class.java) }
}