mirror of
https://gitee.com/zhangsken/AndroidIDE.git
synced 2026-10-16 07:49:44 +08:00
build: reorganize and reconfigure modules to resolve dependency resolution errors
Gradle, for some reason, does not the path of modules to identify them uniquely. Instead, the 'build id' is used to do so, which consists of the maven group and artifact ID. So, even if two modules are located in separate directories, but have the name group and artifact ID, including both of them in other modules may result in dependency resolution errors.
This commit is contained in:
+4
-1
@@ -78,7 +78,10 @@ class AndroidIDEAssetsPlugin : Plugin<Project> {
|
||||
// Tooling API JAR copier
|
||||
val copyToolingApiJar = tasks.register("copy${variantNameCapitalized}ToolingApiJar",
|
||||
AddFileToAssetsTask::class.java) {
|
||||
val toolingApi = rootProject.findProject(":subprojects:tooling-api-impl")!!
|
||||
val implPath = ":tooling:impl"
|
||||
val toolingApi = checkNotNull(rootProject.findProject(implPath)) {
|
||||
"Cannot find the Tooling Impl module with project path: '$implPath'"
|
||||
}
|
||||
dependsOn(toolingApi.tasks.getByName("copyJar"))
|
||||
|
||||
val toolingApiJar = toolingApi.layout.buildDirectory.file("libs/tooling-api-all.jar")
|
||||
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* This file is part of AndroidIDE.
|
||||
*
|
||||
* AndroidIDE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* AndroidIDE is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.itsaky.androidide.plugins
|
||||
|
||||
import org.gradle.api.Plugin
|
||||
import org.gradle.api.Project
|
||||
|
||||
/**
|
||||
* Marker plugin that is applied to the core application module project.
|
||||
*
|
||||
* @author Akash Yadav
|
||||
*/
|
||||
class AndroidIDECoreAppPlugin : Plugin<Project> {
|
||||
override fun apply(target: Project) {}
|
||||
}
|
||||
+28
-30
@@ -30,43 +30,41 @@ import org.gradle.api.Project
|
||||
*/
|
||||
class AndroidIDEPlugin : Plugin<Project> {
|
||||
|
||||
override fun apply(target: Project) {
|
||||
target.run {
|
||||
if (project.path == rootProject.path) {
|
||||
throw GradleException("Cannot apply ${AndroidIDEPlugin::class.simpleName} to root project")
|
||||
}
|
||||
override fun apply(target: Project) = target.run {
|
||||
if (project.path == rootProject.path) {
|
||||
throw GradleException("Cannot apply ${AndroidIDEPlugin::class.simpleName} to root project")
|
||||
}
|
||||
|
||||
if (!project.buildFile.exists() || !project.buildFile.isFile) {
|
||||
return@run
|
||||
}
|
||||
if (!project.buildFile.exists() || !project.buildFile.isFile) {
|
||||
return@run
|
||||
}
|
||||
|
||||
val isAndroidModule = plugins.hasPlugin("com.android.application") ||
|
||||
plugins.hasPlugin("com.android.library")
|
||||
val isAndroidModule = plugins.hasPlugin("com.android.application") ||
|
||||
plugins.hasPlugin("com.android.library")
|
||||
|
||||
if (isAndroidModule && !isFDroidBuild) {
|
||||
// setup signing configuration
|
||||
plugins.apply(SigningConfigPlugin::class.java)
|
||||
}
|
||||
if (isAndroidModule && !isFDroidBuild) {
|
||||
// setup signing configuration
|
||||
plugins.apply(SigningConfigPlugin::class.java)
|
||||
}
|
||||
|
||||
if (isFDroidBuild && project.path == ":app") {
|
||||
val baseExtension = extensions.getByType(BaseExtension::class.java)
|
||||
logger.warn("Building for F-Droid with configuration:")
|
||||
logger.warn("applicationId = ${baseExtension.defaultConfig.applicationId}")
|
||||
logger.warn("versionName = ${baseExtension.defaultConfig.versionName}")
|
||||
logger.warn("versionCode = ${baseExtension.defaultConfig.versionCode}")
|
||||
logger.warn("--- x --- x ---")
|
||||
}
|
||||
if (isFDroidBuild && project.plugins.hasPlugin(AndroidIDECoreAppPlugin::class.java)) {
|
||||
val baseExtension = extensions.getByType(BaseExtension::class.java)
|
||||
logger.warn("Building for F-Droid with configuration:")
|
||||
logger.warn("applicationId = ${baseExtension.defaultConfig.applicationId}")
|
||||
logger.warn("versionName = ${baseExtension.defaultConfig.versionName}")
|
||||
logger.warn("versionCode = ${baseExtension.defaultConfig.versionCode}")
|
||||
logger.warn("--- x --- x ---")
|
||||
}
|
||||
|
||||
val taskName = when {
|
||||
isAndroidModule -> "testDebugUnitTest"
|
||||
else -> "test"
|
||||
}
|
||||
val taskName = when {
|
||||
isAndroidModule -> "testDebugUnitTest"
|
||||
else -> "test"
|
||||
}
|
||||
|
||||
logger.info("${project.path} will run task '$taskName' for tests in CI")
|
||||
logger.info("${project.path} will run task '$taskName' for tests in CI")
|
||||
|
||||
project.tasks.create("runTestsInCI") {
|
||||
dependsOn(taskName)
|
||||
}
|
||||
project.tasks.create("runTestsInCI") {
|
||||
dependsOn(taskName)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* This file is part of AndroidIDE.
|
||||
*
|
||||
* AndroidIDE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* AndroidIDE is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.itsaky.androidide.plugins
|
||||
|
||||
import com.itsaky.androidide.build.config.BuildConfig
|
||||
import com.itsaky.androidide.plugins.exts.GroupConfigPluginExtension.Companion.groupConfigExtension
|
||||
import org.gradle.api.Plugin
|
||||
import org.gradle.api.Project
|
||||
|
||||
/**
|
||||
* @author Akash Yadav
|
||||
*/
|
||||
class GroupConfigPlugin : Plugin<Project> {
|
||||
override fun apply(target: Project) = target.run {
|
||||
val extension = groupConfigExtension()
|
||||
extension.groupIdSuffix.convention("")
|
||||
|
||||
afterEvaluate {
|
||||
val suffix = extension.groupIdSuffix.get().let {
|
||||
if (it.isNotEmpty()) ".${it}" else ""
|
||||
}
|
||||
|
||||
project.group = "${BuildConfig.packageName}${suffix}"
|
||||
logger.info("Maven group ID set to : ${project.group}")
|
||||
}
|
||||
}
|
||||
}
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* This file is part of AndroidIDE.
|
||||
*
|
||||
* AndroidIDE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* AndroidIDE is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.itsaky.androidide.plugins
|
||||
|
||||
import org.gradle.api.Plugin
|
||||
import org.gradle.api.Project
|
||||
|
||||
/**
|
||||
* Marker plugin to indicate that the desugaring plugin should not be applied to the project.
|
||||
*
|
||||
* @author Akash Yadav
|
||||
*/
|
||||
class NoDesugarPlugin : Plugin<Project> {
|
||||
override fun apply(target: Project) {}
|
||||
}
|
||||
+19
-17
@@ -27,6 +27,8 @@ import com.itsaky.androidide.build.config.BuildConfig
|
||||
import com.itsaky.androidide.build.config.FDroidConfig
|
||||
import com.itsaky.androidide.build.config.isFDroidBuild
|
||||
import com.itsaky.androidide.build.config.projectVersionCode
|
||||
import com.itsaky.androidide.plugins.AndroidIDECoreAppPlugin
|
||||
import com.itsaky.androidide.plugins.NoDesugarPlugin
|
||||
import com.itsaky.androidide.plugins.util.SdkUtils.getAndroidJar
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.artifacts.MinimalExternalModuleDependency
|
||||
@@ -42,19 +44,20 @@ import org.gradle.api.provider.Provider
|
||||
* flavor, the version code will be `100 * 270 + 1` i.e. `27001`
|
||||
*/
|
||||
internal val flavorsAbis = mapOf("armeabi-v7a" to 1, "arm64-v8a" to 2, "x86_64" to 3)
|
||||
private val disableCoreLibDesugaringForModules = arrayOf(":logsender", ":logger")
|
||||
|
||||
fun Project.configureAndroidModule(
|
||||
coreLibDesugDep: Provider<MinimalExternalModuleDependency>
|
||||
) {
|
||||
val isAppModule = plugins.hasPlugin("com.android.application")
|
||||
assert(
|
||||
plugins.hasPlugin("com.android.application") || plugins.hasPlugin("com.android.library")) {
|
||||
isAppModule || plugins.hasPlugin("com.android.library")
|
||||
) {
|
||||
"${javaClass.simpleName} can only be applied to Android projects"
|
||||
}
|
||||
|
||||
val androidJar = extensions.getByType(AndroidComponentsExtension::class.java)
|
||||
.getAndroidJar(assertExists = true)
|
||||
val frameworkStubsJar = findProject(":subprojects:framework-stubs")!!.file("libs/android.jar")
|
||||
val frameworkStubsJar = findProject(":utilities:framework-stubs")!!.file("libs/android.jar")
|
||||
.also { it.parentFile.mkdirs() }
|
||||
|
||||
if (!(frameworkStubsJar.exists() && frameworkStubsJar.isFile)) {
|
||||
@@ -116,20 +119,13 @@ fun Project.configureAndroidModule(
|
||||
|
||||
configureCoreLibDesugaring(this, coreLibDesugDep)
|
||||
|
||||
if (":app" == project.path) {
|
||||
if (project.plugins.hasPlugin(AndroidIDECoreAppPlugin::class.java)) {
|
||||
packagingOptions {
|
||||
jniLibs {
|
||||
useLegacyPackaging = true
|
||||
}
|
||||
}
|
||||
|
||||
flavorsAbis.forEach { (abi, _) ->
|
||||
// the common defaultConfig, not the flavor-specific
|
||||
defaultConfig.buildConfigField("String",
|
||||
"ABI_${abi.replace('-', '_').uppercase()}",
|
||||
"\"${abi}\"")
|
||||
}
|
||||
|
||||
splits {
|
||||
abi {
|
||||
reset()
|
||||
@@ -149,7 +145,8 @@ fun Project.configureAndroidModule(
|
||||
|
||||
// version code increment
|
||||
val verCodeIncr = flavorsAbis[output.getFilter(
|
||||
FilterConfiguration.FilterType.ABI)?.identifier]
|
||||
FilterConfiguration.FilterType.ABI
|
||||
)?.identifier]
|
||||
?: throw UnsupportedOperationException("Universal APKs are not supported!")
|
||||
|
||||
output.versionCode.set(100 * projectVersionCode + verCodeIncr)
|
||||
@@ -167,7 +164,11 @@ fun Project.configureAndroidModule(
|
||||
|
||||
buildTypes.getByName("debug") { isMinifyEnabled = false }
|
||||
buildTypes.getByName("release") {
|
||||
isMinifyEnabled = true
|
||||
|
||||
// from AGP 8.4.0 onwards, there are some behavioral changes in R8
|
||||
// enabling R8 on library projects results in missing class errors
|
||||
// see https://issuetracker.google.com/issues/338411137#comment11
|
||||
isMinifyEnabled = isAppModule
|
||||
proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
|
||||
}
|
||||
|
||||
@@ -177,7 +178,6 @@ fun Project.configureAndroidModule(
|
||||
// the build are faster for this build type as compared to 'release'
|
||||
buildTypes.register("dev") {
|
||||
initWith(buildTypes.getByName("release"))
|
||||
|
||||
isMinifyEnabled = false
|
||||
}
|
||||
|
||||
@@ -188,9 +188,11 @@ fun Project.configureAndroidModule(
|
||||
}
|
||||
}
|
||||
|
||||
private fun Project.configureCoreLibDesugaring(baseExtension: BaseExtension,
|
||||
coreLibDesugDep: Provider<MinimalExternalModuleDependency>) {
|
||||
val coreLibDesugaringEnabled = project.path !in disableCoreLibDesugaringForModules
|
||||
private fun Project.configureCoreLibDesugaring(
|
||||
baseExtension: BaseExtension,
|
||||
coreLibDesugDep: Provider<MinimalExternalModuleDependency>
|
||||
) {
|
||||
val coreLibDesugaringEnabled = !project.plugins.hasPlugin(NoDesugarPlugin::class.java)
|
||||
|
||||
baseExtension.compileOptions.isCoreLibraryDesugaringEnabled = coreLibDesugaringEnabled
|
||||
|
||||
|
||||
+6
-1
@@ -35,7 +35,7 @@ import org.gradle.kotlin.dsl.withType
|
||||
import com.itsaky.androidide.build.config.publishingVersion
|
||||
import java.io.File
|
||||
|
||||
private val projectsRequiringMavenLocalForTests = arrayOf(":gradle-plugin")
|
||||
private val projectsRequiringMavenLocalForTests = arrayOf(":tooling:plugin")
|
||||
private val mavenLocalRepos = hashMapOf<String, String>()
|
||||
|
||||
@Suppress("UnstableApiUsage")
|
||||
@@ -45,6 +45,11 @@ fun Project.configureMavenPublish() {
|
||||
}
|
||||
|
||||
gradle.projectsEvaluated {
|
||||
for (path in projectsRequiringMavenLocalForTests) {
|
||||
checkNotNull(rootProject.findProject(path)) {
|
||||
"Unable to configure maven local for project '$path' (project cannot be found)."
|
||||
}
|
||||
}
|
||||
rootProject.subprojects {
|
||||
if (project.path in projectsRequiringMavenLocalForTests) {
|
||||
tasks.withType<Test> {
|
||||
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* This file is part of AndroidIDE.
|
||||
*
|
||||
* AndroidIDE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* AndroidIDE is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.itsaky.androidide.plugins.exts
|
||||
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.provider.Property
|
||||
import org.gradle.kotlin.dsl.create
|
||||
|
||||
/**
|
||||
* @author Akash Yadav
|
||||
*/
|
||||
abstract class GroupConfigPluginExtension {
|
||||
|
||||
/**
|
||||
* The suffix for the maven group ID for the module.
|
||||
*
|
||||
* Example:
|
||||
* If the [groupIdSuffix] is "core", then the maven group ID will be
|
||||
* `${BuildConfig.packageName}.core`.
|
||||
*/
|
||||
abstract val groupIdSuffix: Property<String>
|
||||
|
||||
companion object {
|
||||
|
||||
/**
|
||||
* Create the [GroupConfigPluginExtension] for the project.
|
||||
*/
|
||||
fun Project.groupConfigExtension(): GroupConfigPluginExtension {
|
||||
return extensions.create<GroupConfigPluginExtension>("groupConfig")
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user