mirror of
https://github.com/mamoe/mirai.git
synced 2025-01-27 08:50:15 +08:00
[build] Support both configuring Android targets by Android SDK or JVM
- try to fix sdk dir when android is desired - Do not printAndroidNotInstalled multiple times
This commit is contained in:
parent
2cf97a181f
commit
4ed551027a
12
.github/workflows/release.yml
vendored
12
.github/workflows/release.yml
vendored
@ -74,6 +74,18 @@ jobs:
|
||||
GPG_PRIVATE: ${{ secrets.GPG_PRIVATE_KEY }}
|
||||
GPG_PUBLIC_: ${{ secrets.GPG_PUBLIC_KEY }}
|
||||
|
||||
- name: Setup Android SDK Ubuntu
|
||||
if: ${{ env.isUbuntu == 'true' }}
|
||||
run: 'touch local.properties && echo sdk.dir=/usr/local/lib/android/sdk >> local.properties'
|
||||
|
||||
- name: Setup Android SDK macOS
|
||||
if: ${{ env.isMac == 'true' }}
|
||||
run: 'touch local.properties && echo sdk.dir=/Users/runner/Library/Android/sdk >> local.properties'
|
||||
|
||||
- name: Setup Android SDK Windows
|
||||
if: ${{ env.isWindows == 'true' }}
|
||||
run: 'echo sdk.dir=C:\Android\android-sdk >> local.properties'
|
||||
|
||||
- name: Setup Gradle
|
||||
uses: gradle/gradle-build-action@v2
|
||||
|
||||
|
268
buildSrc/src/main/kotlin/Android.kt
Normal file
268
buildSrc/src/main/kotlin/Android.kt
Normal file
@ -0,0 +1,268 @@
|
||||
/*
|
||||
* Copyright 2019-2023 Mamoe Technologies and contributors.
|
||||
*
|
||||
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
*
|
||||
* https://github.com/mamoe/mirai/blob/dev/LICENSE
|
||||
*/
|
||||
|
||||
@file:Suppress("UNUSED_VARIABLE")
|
||||
|
||||
import com.android.build.api.dsl.LibraryExtension
|
||||
import org.gradle.api.JavaVersion
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.kotlin.dsl.*
|
||||
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
|
||||
import java.util.*
|
||||
|
||||
const val PROP_MIRAI_ENABLE_ANDROID_INSTRUMENTED_TESTS = "mirai.enable.android.instrumented.tests"
|
||||
|
||||
/**
|
||||
* Use [usingAndroidInstrumentedTests] instead.
|
||||
*/
|
||||
val ENABLE_ANDROID_INSTRUMENTED_TESTS by projectLazy {
|
||||
val name = PROP_MIRAI_ENABLE_ANDROID_INSTRUMENTED_TESTS
|
||||
(System.getProperty(name)
|
||||
?: System.getenv(name)
|
||||
?: rootProject.getLocalProperty(name)
|
||||
?: "true").toBooleanStrict()
|
||||
}
|
||||
|
||||
val Project.usingAndroidInstrumentedTests
|
||||
get() = ENABLE_ANDROID_INSTRUMENTED_TESTS && isAndroidSdkAvailable
|
||||
|
||||
fun Project.configureAndroidTarget() {
|
||||
if (ENABLE_ANDROID_INSTRUMENTED_TESTS && !isAndroidSdkAvailable) {
|
||||
if (!ProjectAndroidSdkAvailability.tryFixAndroidSdk(this)) {
|
||||
printAndroidNotInstalled()
|
||||
}
|
||||
}
|
||||
|
||||
extensions.getByType(KotlinMultiplatformExtension::class.java).apply {
|
||||
if (project.usingAndroidInstrumentedTests) {
|
||||
configureAndroidTargetWithSdk()
|
||||
} else {
|
||||
configureAndroidTargetWithJvm()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun Project.configureAndroidTargetWithJvm() {
|
||||
extensions.getByType(KotlinMultiplatformExtension::class.java).apply {
|
||||
jvm("android") {
|
||||
jvmToolchain(JVM_TOOLCHAIN_VERSION)
|
||||
attributes.attribute(KotlinPlatformType.attribute, KotlinPlatformType.androidJvm)
|
||||
|
||||
if (IDEA_ACTIVE) {
|
||||
attributes.attribute(MIRAI_PLATFORM_ATTRIBUTE, "android") // workaround for IDE bug
|
||||
}
|
||||
}
|
||||
|
||||
sourceSets.getByName("androidTest").configureJvmTest("configureAndroidTargetWithJvm")
|
||||
sourceSets.getByName("androidTest").kotlin.srcDir(projectDir.resolve("src/androidUnitTest/kotlin"))
|
||||
|
||||
sourceSets.getByName("androidMain").apply {
|
||||
dependencies {
|
||||
compileOnly(`android-runtime`)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("UnstableApiUsage")
|
||||
private fun Project.configureAndroidTargetWithSdk() {
|
||||
extensions.getByType(KotlinMultiplatformExtension::class.java).apply {
|
||||
android {
|
||||
if (IDEA_ACTIVE) {
|
||||
attributes.attribute(MIRAI_PLATFORM_ATTRIBUTE, "android") // workaround for IDE bug
|
||||
}
|
||||
}
|
||||
|
||||
val jvmBaseMain = sourceSets.maybeCreate("jvmBaseMain")
|
||||
val jvmBaseTest = sourceSets.maybeCreate("jvmBaseTest")
|
||||
|
||||
val androidMain by sourceSets.getting
|
||||
androidMain.dependsOn(jvmBaseMain)
|
||||
|
||||
// don't use androidTest, deprecated by Kotlin
|
||||
|
||||
// this can cause problems on sync
|
||||
// for (s in arrayOf("androidDebug", "androidRelease")) {
|
||||
// sourceSets.all { if (name in s) dependsOn(androidMain) }
|
||||
// }
|
||||
|
||||
// we should have added a "androidBaseTest" (or "androidTest") for "androidUnitTest" and "androidInstrumentedTest",
|
||||
// but this currently cause bugs in IntelliJ (2023.2)
|
||||
// val androidBaseTest = sourceSets.maybeCreate("androidBaseTest").apply {
|
||||
// dependsOn(jvmBaseTest)
|
||||
// }
|
||||
val androidUnitTest by sourceSets.getting {
|
||||
dependsOn(jvmBaseTest)
|
||||
}
|
||||
// for (s in arrayOf("androidUnitTestDebug", "androidUnitTestRelease")) {
|
||||
// sourceSets.all { if (name in s) dependsOn(androidUnitTest) }
|
||||
// }
|
||||
val androidInstrumentedTest by sourceSets.getting {
|
||||
dependsOn(jvmBaseTest)
|
||||
}
|
||||
// for (s in arrayOf("androidInstrumentedTestDebug")) {
|
||||
// sourceSets.all { if (name in s) dependsOn(androidInstrumentedTest) }
|
||||
// }
|
||||
|
||||
// afterEvaluate {
|
||||
//// > androidDebug dependsOn commonMain
|
||||
//// androidInstrumentedTest dependsOn jvmBaseTest
|
||||
//// androidInstrumentedTestDebug dependsOn
|
||||
//// androidMain dependsOn commonMain, jvmBaseMain
|
||||
//// androidRelease dependsOn commonMain
|
||||
//// androidUnitTest dependsOn commonTest, jvmBaseTest
|
||||
//// androidUnitTestDebug dependsOn commonTest
|
||||
//// androidUnitTestRelease dependsOn commonTest
|
||||
// error(this@apply.sourceSets.joinToString("\n") {
|
||||
// it.name + " dependsOn " + it.dependsOn.joinToString { it.name }
|
||||
// })
|
||||
// }
|
||||
|
||||
configure(
|
||||
listOf(
|
||||
sourceSets.getByName("androidInstrumentedTest"),
|
||||
sourceSets.getByName("androidUnitTest"),
|
||||
)
|
||||
) {
|
||||
dependencies { implementation(kotlin("test-annotations-common"))?.because("configureAndroidTargetWithSdk") }
|
||||
}
|
||||
}
|
||||
|
||||
// trick for compiler bug
|
||||
this.sourceSets.apply {
|
||||
removeIf { it.name == "androidAndroidTestRelease" }
|
||||
removeIf { it.name == "androidTestFixtures" }
|
||||
removeIf { it.name == "androidTestFixturesDebug" }
|
||||
removeIf { it.name == "androidTestFixturesRelease" }
|
||||
}
|
||||
|
||||
extensions.getByType(LibraryExtension::class.java).apply {
|
||||
compileSdk = 33
|
||||
sourceSets["main"].manifest.srcFile("src/androidMain/AndroidManifest.xml")
|
||||
defaultConfig {
|
||||
minSdk = rootProject.extra["mirai.android.target.api.level"]!!.toString().toInt()
|
||||
targetSdk = 33
|
||||
}
|
||||
compileOptions {
|
||||
sourceCompatibility = JavaVersion.VERSION_1_8
|
||||
targetCompatibility = JavaVersion.VERSION_1_8
|
||||
}
|
||||
buildTypes.getByName("release") {
|
||||
isMinifyEnabled = true
|
||||
isShrinkResources = false
|
||||
proguardFiles(
|
||||
getDefaultProguardFile("proguard-android-optimize.txt"),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
extensions.getByType(LibraryExtension::class.java).apply {
|
||||
defaultConfig {
|
||||
// 1) Make sure to use the AndroidJUnitRunner, or a subclass of it. This requires a dependency on androidx.test:runner, too!
|
||||
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||
// 2) Connect JUnit 5 to the runner
|
||||
testInstrumentationRunnerArguments["runnerBuilder"] = "de.mannodermaus.junit5.AndroidJUnit5Builder"
|
||||
}
|
||||
}
|
||||
|
||||
// val sourceSets = arrayOf("androidInstrumentedTest", "androidUnitTest")
|
||||
// .map { kotlin.sourceSets.getByName(it) }
|
||||
|
||||
// for (sourceSet in sourceSets) {
|
||||
// sourceSet.dependencies {
|
||||
// implementation("androidx.test:runner:1.5.2")
|
||||
// implementation("org.junit.jupiter:junit-jupiter-api:5.9.2")
|
||||
// runtimeOnly("org.junit.jupiter:junit-jupiter-engine:5.8.2")
|
||||
//
|
||||
// implementation("de.mannodermaus.junit5:android-test-core:1.3.0")
|
||||
// implementation("de.mannodermaus.junit5:android-test-runner:1.3.0")
|
||||
// }
|
||||
// }
|
||||
|
||||
dependencies {
|
||||
// 4) Jupiter API & Test Runner, if you don't have it already
|
||||
"androidTestImplementation"("androidx.test:runner:1.5.2")
|
||||
"androidTestImplementation"("org.junit.jupiter:junit-jupiter-api:${Versions.junit}")
|
||||
"androidTestRuntimeOnly"("org.junit.jupiter:junit-jupiter-engine:${Versions.junit}")
|
||||
|
||||
// 5) The instrumentation test companion libraries
|
||||
"androidTestImplementation"("de.mannodermaus.junit5:android-test-core:1.3.0")
|
||||
"androidTestRuntimeOnly"("de.mannodermaus.junit5:android-test-runner:1.3.0")
|
||||
}
|
||||
}
|
||||
|
||||
private fun Project.printAndroidNotInstalled() {
|
||||
logger.warn(
|
||||
"""
|
||||
你设置了启用 Android Instrumented Test, 但是未配置 Android SDK. $name 的 Android 目标将会使用桌面 JVM 编译和测试.
|
||||
Android Instrumented Test 将不会进行. 这不会影响 Android 以外的平台的编译和测试.
|
||||
|
||||
如果你要给 mirai PR 并且你修改了 Android 部分, 建议解决此警告.
|
||||
如果你没有修改 Android 部分, 则可以忽略, 或者在项目根目录 local.properties (如果不存在就创建一个) 添加 `$PROP_MIRAI_ENABLE_ANDROID_INSTRUMENTED_TESTS=false`.
|
||||
|
||||
在安装 Android SDK 后, 请在项目根目录 local.properties 中添加 `sdk.dir=/path/to/Android/sdk` 指向本机 Android SDK 安装路径.
|
||||
|
||||
若要关闭 Android Instrumented Test, 在项目根目录 local.properties 添加 `$PROP_MIRAI_ENABLE_ANDROID_INSTRUMENTED_TESTS=false`.
|
||||
-------
|
||||
""".trimIndent()
|
||||
)
|
||||
// logger.warn(
|
||||
// """Android SDK might not be installed. Android target of $name will not be compiled. It does no influence on the compilation of other platforms.
|
||||
// """.trimIndent()
|
||||
// )
|
||||
}
|
||||
|
||||
|
||||
private object ProjectAndroidSdkAvailability {
|
||||
val map: MutableMap<String, Boolean> by projectLazy { mutableMapOf() }
|
||||
|
||||
@Synchronized
|
||||
operator fun get(project: Project): Boolean {
|
||||
if (map[project.path] != null) return map[project.path]!!
|
||||
|
||||
val projectAvailable = project.runCatching {
|
||||
val keyProps = Properties().apply {
|
||||
file("local.properties").takeIf { it.exists() }?.inputStream()?.use { load(it) }
|
||||
}
|
||||
keyProps.getProperty("sdk.dir", "").isNotEmpty()
|
||||
}.getOrElse { false }
|
||||
|
||||
|
||||
fun impl(): Boolean {
|
||||
if (project === project.rootProject) return projectAvailable
|
||||
return projectAvailable || get(project.rootProject)
|
||||
}
|
||||
map[project.path] = impl()
|
||||
return map[project.path]!!
|
||||
}
|
||||
|
||||
fun tryFixAndroidSdk(project: Project): Boolean {
|
||||
val androidHome = System.getenv("ANDROID_HOME") ?: kotlin.run {
|
||||
project.logger.info("tryFixAndroidSdk: environment `ANDROID_HOME` does not exist")
|
||||
return false
|
||||
}
|
||||
|
||||
val escaped = androidHome
|
||||
.replace(""":""", """\:""")
|
||||
.replace("""\""", """\\""")
|
||||
.trim()
|
||||
|
||||
project.rootDir.resolve("local.properties")
|
||||
.apply { if (!exists()) createNewFile() }
|
||||
.appendText("sdk.dir=$escaped")
|
||||
|
||||
project.logger.info("tryFixAndroidSdk: fixed sdk.dir in local.properties: $escaped")
|
||||
|
||||
map.clear()
|
||||
return get(project)
|
||||
}
|
||||
}
|
||||
|
||||
private val Project.isAndroidSdkAvailable: Boolean get() = ProjectAndroidSdkAvailability[this]
|
@ -9,12 +9,13 @@
|
||||
|
||||
@file:Suppress("UNUSED_VARIABLE")
|
||||
|
||||
import com.android.build.api.dsl.LibraryExtension
|
||||
import com.google.gradle.osdetector.OsDetector
|
||||
import org.gradle.api.JavaVersion
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.attributes.Attribute
|
||||
import org.gradle.kotlin.dsl.*
|
||||
import org.gradle.kotlin.dsl.get
|
||||
import org.gradle.kotlin.dsl.getting
|
||||
import org.gradle.kotlin.dsl.provideDelegate
|
||||
import org.gradle.kotlin.dsl.withType
|
||||
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation.Companion.MAIN_COMPILATION_NAME
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation.Companion.TEST_COMPILATION_NAME
|
||||
@ -155,6 +156,16 @@ val NATIVE_TARGETS by projectLazy { UNIX_LIKE_TARGETS + WIN_TARGETS }
|
||||
|
||||
private val POSSIBLE_NATIVE_TARGETS by lazy { setOf("mingwX64", "macosX64", "macosArm64", "linuxX64") }
|
||||
|
||||
const val JVM_TOOLCHAIN_VERSION = 8
|
||||
|
||||
/**
|
||||
* ## Android Test 结构
|
||||
*
|
||||
* 如果[启用 Android Instrumented Test][ENABLE_ANDROID_INSTRUMENTED_TESTS], 将会配置使用 Android SDK 配置真 Android target,
|
||||
* `androidMain` 将能访问 Android SDK, 也能获得针对 Android 的 IDE 错误检查.
|
||||
*
|
||||
* @see configureNativeTargetsHierarchical
|
||||
*/
|
||||
fun Project.configureJvmTargetsHierarchical() {
|
||||
extensions.getByType(KotlinMultiplatformExtension::class.java).apply {
|
||||
val commonMain by sourceSets.getting
|
||||
@ -162,15 +173,21 @@ fun Project.configureJvmTargetsHierarchical() {
|
||||
|
||||
if (IDEA_ACTIVE) {
|
||||
jvm("jvmBase") { // dummy target for resolution, not published
|
||||
jvmToolchain(JVM_TOOLCHAIN_VERSION)
|
||||
compilations.all {
|
||||
this.compileTaskProvider.configure { // IDE complain
|
||||
// magic to help IDEA
|
||||
this.compileTaskProvider.configure {
|
||||
enabled = false
|
||||
}
|
||||
}
|
||||
attributes.attribute(KotlinPlatformType.attribute, KotlinPlatformType.common) // magic
|
||||
attributes.attribute(MIRAI_PLATFORM_ATTRIBUTE, "jvmBase") // avoid resolution
|
||||
attributes.attribute(MIRAI_PLATFORM_INTERMEDIATE, true)
|
||||
|
||||
// avoid resolution when other modules dependsOn this project
|
||||
attributes.attribute(MIRAI_PLATFORM_ATTRIBUTE, "jvmBase")
|
||||
attributes.attribute(MIRAI_PLATFORM_INTERMEDIATE, true) // no shadow
|
||||
}
|
||||
} else {
|
||||
// if not in IDEA, no need to create intermediate targets.
|
||||
}
|
||||
|
||||
val jvmBaseMain by lazy {
|
||||
@ -185,62 +202,12 @@ fun Project.configureJvmTargetsHierarchical() {
|
||||
}
|
||||
|
||||
if (isTargetEnabled("android")) {
|
||||
if (isAndroidSDKAvailable) {
|
||||
// apply(plugin = "com.android.library")
|
||||
android {
|
||||
if (IDEA_ACTIVE) {
|
||||
attributes.attribute(MIRAI_PLATFORM_ATTRIBUTE, "android") // avoid resolution
|
||||
}
|
||||
}
|
||||
configureAndroidTarget()
|
||||
val androidMain by sourceSets.getting
|
||||
for (s in arrayOf("androidMain")) {
|
||||
sourceSets.all { if (name in s) dependsOn(jvmBaseMain) }
|
||||
}
|
||||
// this can cause problems on sync
|
||||
// for (s in arrayOf("androidDebug", "androidRelease")) {
|
||||
// sourceSets.all { if (name in s) dependsOn(androidMain) }
|
||||
// }
|
||||
|
||||
// we should have added a "androidBaseTest" (or "androidTest") for "androidUnitTest" and "androidInstrumentedTest",
|
||||
// but this currently cause bugs in IntelliJ (2023.2)
|
||||
// val androidBaseTest = sourceSets.maybeCreate("androidBaseTest").apply {
|
||||
// dependsOn(jvmBaseTest)
|
||||
// }
|
||||
val androidUnitTest by sourceSets.getting {
|
||||
dependsOn(jvmBaseTest)
|
||||
}
|
||||
// for (s in arrayOf("androidUnitTestDebug", "androidUnitTestRelease")) {
|
||||
// sourceSets.all { if (name in s) dependsOn(androidUnitTest) }
|
||||
// }
|
||||
val androidInstrumentedTest by sourceSets.getting {
|
||||
dependsOn(jvmBaseTest)
|
||||
}
|
||||
// for (s in arrayOf("androidInstrumentedTestDebug")) {
|
||||
// sourceSets.all { if (name in s) dependsOn(androidInstrumentedTest) }
|
||||
// }
|
||||
|
||||
// afterEvaluate {
|
||||
//// > androidDebug dependsOn commonMain
|
||||
//// androidInstrumentedTest dependsOn jvmBaseTest
|
||||
//// androidInstrumentedTestDebug dependsOn
|
||||
//// androidMain dependsOn commonMain, jvmBaseMain
|
||||
//// androidRelease dependsOn commonMain
|
||||
//// androidUnitTest dependsOn commonTest, jvmBaseTest
|
||||
//// androidUnitTestDebug dependsOn commonTest
|
||||
//// androidUnitTestRelease dependsOn commonTest
|
||||
// error(this@apply.sourceSets.joinToString("\n") {
|
||||
// it.name + " dependsOn " + it.dependsOn.joinToString { it.name }
|
||||
// })
|
||||
// }
|
||||
} else {
|
||||
printAndroidNotInstalled()
|
||||
}
|
||||
configureAndroidTarget()
|
||||
}
|
||||
|
||||
if (isTargetEnabled("jvm")) {
|
||||
jvm("jvm") {
|
||||
|
||||
jvmToolchain(JVM_TOOLCHAIN_VERSION)
|
||||
}
|
||||
val jvmMain by sourceSets.getting
|
||||
val jvmTest by sourceSets.getting
|
||||
@ -250,67 +217,9 @@ fun Project.configureJvmTargetsHierarchical() {
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("UnstableApiUsage")
|
||||
fun Project.configureAndroidTarget() {
|
||||
extensions.getByType(KotlinMultiplatformExtension::class.java).apply {
|
||||
|
||||
// trick
|
||||
this.sourceSets.apply {
|
||||
removeIf { it.name == "androidAndroidTestRelease" }
|
||||
removeIf { it.name == "androidTestFixtures" }
|
||||
removeIf { it.name == "androidTestFixturesDebug" }
|
||||
removeIf { it.name == "androidTestFixturesRelease" }
|
||||
}
|
||||
}
|
||||
|
||||
extensions.getByType(LibraryExtension::class.java).apply {
|
||||
compileSdk = 33
|
||||
sourceSets["main"].manifest.srcFile("src/androidMain/AndroidManifest.xml")
|
||||
defaultConfig {
|
||||
minSdk = rootProject.extra["mirai.android.target.api.level"]!!.toString().toInt()
|
||||
targetSdk = 33
|
||||
}
|
||||
compileOptions {
|
||||
sourceCompatibility = JavaVersion.VERSION_1_8
|
||||
targetCompatibility = JavaVersion.VERSION_1_8
|
||||
}
|
||||
buildTypes.getByName("release") {
|
||||
isMinifyEnabled = true
|
||||
isShrinkResources = false
|
||||
proguardFiles(
|
||||
getDefaultProguardFile("proguard-android-optimize.txt"),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// if (USE_JUNIT5_FOR_ANDROID_TEST) {
|
||||
// extensions.getByType(LibraryExtension::class.java).apply {
|
||||
// defaultConfig {
|
||||
// // 1) Make sure to use the AndroidJUnitRunner, or a subclass of it. This requires a dependency on androidx.test:runner, too!
|
||||
// testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||
// // 2) Connect JUnit 5 to the runner
|
||||
// testInstrumentationRunnerArguments["runnerBuilder"] = "de.mannodermaus.junit5.AndroidJUnit5Builder"
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// dependencies {
|
||||
// // 4) Jupiter API & Test Runner, if you don't have it already
|
||||
// "androidTestImplementation"("androidx.test:runner:1.5.2")
|
||||
// "androidTestImplementation"("org.junit.jupiter:junit-jupiter-api:5.9.2")
|
||||
// runtimeOnly("org.junit.jupiter:junit-jupiter-engine:5.8.2")
|
||||
//
|
||||
// // 5) The instrumentation test companion libraries
|
||||
// "androidTestImplementation"("de.mannodermaus.junit5:android-test-core:1.3.0")
|
||||
// "androidTestRuntimeOnly"("de.mannodermaus.junit5:android-test-runner:1.3.0")
|
||||
// }
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
private const val USE_JUNIT5_FOR_ANDROID_TEST = true
|
||||
|
||||
|
||||
/**
|
||||
* Target 结构:
|
||||
* ```
|
||||
* common
|
||||
* |
|
||||
@ -326,7 +235,9 @@ private const val USE_JUNIT5_FOR_ANDROID_TEST = true
|
||||
* <darwin targets>
|
||||
* ```
|
||||
*
|
||||
* `<darwin targets>`: macosX64, macosArm64, tvosX64, iosArm64, iosArm32...
|
||||
* `<darwin targets>`: macosX64, macosArm64
|
||||
*
|
||||
* @see configureJvmTargetsHierarchical
|
||||
*/
|
||||
fun KotlinMultiplatformExtension.configureNativeTargetsHierarchical(
|
||||
project: Project
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2019-2022 Mamoe Technologies and contributors.
|
||||
* Copyright 2019-2023 Mamoe Technologies and contributors.
|
||||
*
|
||||
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
@ -16,35 +16,6 @@ import org.gradle.api.artifacts.component.ComponentSelector
|
||||
import org.gradle.api.plugins.ExtensionAware
|
||||
import org.jetbrains.kotlin.gradle.dsl.KotlinJvmProjectExtension
|
||||
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
|
||||
import java.util.*
|
||||
|
||||
private object ProjectAndroidSdkAvailability {
|
||||
val map: MutableMap<String, Boolean> = mutableMapOf()
|
||||
|
||||
@Suppress("UNUSED_PARAMETER", "UNREACHABLE_CODE")
|
||||
@Synchronized
|
||||
operator fun get(project: Project): Boolean {
|
||||
return true
|
||||
if (map[project.path] != null) return map[project.path]!!
|
||||
|
||||
val projectAvailable = project.runCatching {
|
||||
val keyProps = Properties().apply {
|
||||
file("local.properties").takeIf { it.exists() }?.inputStream()?.use { load(it) }
|
||||
}
|
||||
keyProps.getProperty("sdk.dir", "").isNotEmpty()
|
||||
}.getOrElse { false }
|
||||
|
||||
|
||||
fun impl(): Boolean {
|
||||
if (project === project.rootProject) return projectAvailable
|
||||
return projectAvailable || get(project.rootProject)
|
||||
}
|
||||
map[project.path] = impl()
|
||||
return map[project.path]!!
|
||||
}
|
||||
}
|
||||
|
||||
val Project.isAndroidSDKAvailable: Boolean get() = ProjectAndroidSdkAvailability[this]
|
||||
|
||||
val <T> NamedDomainObjectCollection<T>.androidMain: NamedDomainObjectProvider<T>
|
||||
get() = named("androidMain")
|
||||
@ -61,16 +32,6 @@ val <T> NamedDomainObjectCollection<T>.jvmTest: NamedDomainObjectProvider<T>
|
||||
val <T> NamedDomainObjectCollection<T>.commonMain: NamedDomainObjectProvider<T>
|
||||
get() = named("commonMain")
|
||||
|
||||
fun Project.printAndroidNotInstalled() {
|
||||
println(
|
||||
"""Android SDK 可能未安装. $name 的 Android 目标编译将不会进行. 这不会影响 Android 以外的平台的编译.
|
||||
""".trimIndent()
|
||||
)
|
||||
println(
|
||||
"""Android SDK might not be installed. Android target of $name will not be compiled. It does no influence on the compilation of other platforms.
|
||||
""".trimIndent()
|
||||
)
|
||||
}
|
||||
|
||||
inline fun forMppModules(action: (suffix: String) -> Unit) {
|
||||
arrayOf(
|
||||
|
@ -92,21 +92,6 @@ fun Project.configureJvmTarget() {
|
||||
|
||||
allKotlinTargets().all {
|
||||
if (this !is KotlinJvmTarget) return@all
|
||||
when (this.attributes.getAttribute(KotlinPlatformType.attribute)) { // mirai does magic, don't use target.platformType
|
||||
KotlinPlatformType.androidJvm -> {
|
||||
this.compilations.all {
|
||||
/*
|
||||
* Kotlin JVM compiler generates Long.hashCode witch is available since API 26 when targeting JVM 1.8 while IR prefer member function hashCode always.
|
||||
*/
|
||||
// kotlinOptions.useIR = true
|
||||
|
||||
// IR cannot compile mirai. We'll wait for Kotlin 1.5 for stable IR release.
|
||||
}
|
||||
}
|
||||
|
||||
else -> {
|
||||
}
|
||||
}
|
||||
this.testRuns["test"].executionTask.configure { useJUnitPlatform() }
|
||||
}
|
||||
}
|
||||
@ -135,37 +120,23 @@ fun Project.configureKotlinTestSettings() {
|
||||
isKotlinMpp -> {
|
||||
kotlinSourceSets?.all {
|
||||
val sourceSet = this
|
||||
fun configureJvmTest(sourceSet: KotlinSourceSet) {
|
||||
sourceSet.dependencies {
|
||||
implementation(kotlin("test-junit5"))?.because(b)
|
||||
|
||||
implementation(`junit-jupiter-api`)?.because(b)
|
||||
runtimeOnly(`junit-jupiter-engine`)?.because(b)
|
||||
}
|
||||
}
|
||||
|
||||
val target = allKotlinTargets()
|
||||
.find { it.name == sourceSet.name.substringBeforeLast("Main").substringBeforeLast("Test") }
|
||||
|
||||
when {
|
||||
sourceSet.name == "commonTest" -> {
|
||||
if (target?.platformType == KotlinPlatformType.jvm &&
|
||||
target.attributes.getAttribute(MIRAI_PLATFORM_INTERMEDIATE) != true
|
||||
) {
|
||||
configureJvmTest(sourceSet)
|
||||
} else {
|
||||
if (sourceSet.name.contains("test", ignoreCase = true)) {
|
||||
if (isJvmFinalTarget(target)) {
|
||||
// For android, this should be done differently. See Android.kt
|
||||
sourceSet.configureJvmTest(b)
|
||||
} else {
|
||||
if (sourceSet.name == "commonTest") {
|
||||
sourceSet.dependencies {
|
||||
implementation(kotlin("test"))?.because(b)
|
||||
implementation(kotlin("test-annotations-common"))?.because(b)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sourceSet.name.contains("test", ignoreCase = true) -> {
|
||||
if (target?.platformType == KotlinPlatformType.jvm &&
|
||||
target.attributes.getAttribute(MIRAI_PLATFORM_INTERMEDIATE) != true
|
||||
) {
|
||||
configureJvmTest(sourceSet)
|
||||
} else {
|
||||
// can be an Android sourceSet
|
||||
// Do not even add "kotlin-test" for Android sourceSets. IDEA can't resolve them on sync
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -174,6 +145,19 @@ fun Project.configureKotlinTestSettings() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun isJvmFinalTarget(target: KotlinTarget?) =
|
||||
target?.platformType == KotlinPlatformType.jvm &&
|
||||
target.attributes.getAttribute(MIRAI_PLATFORM_INTERMEDIATE) != true // jvmBase is intermediate
|
||||
|
||||
fun KotlinSourceSet.configureJvmTest(because: String) {
|
||||
dependencies {
|
||||
implementation(kotlin("test-junit5"))?.because(because)
|
||||
|
||||
implementation(`junit-jupiter-api`)?.because(because)
|
||||
runtimeOnly(`junit-jupiter-engine`)?.because(because)
|
||||
}
|
||||
}
|
||||
|
||||
private fun isJvmLikePlatform(target: KotlinTarget?) =
|
||||
target?.platformType == KotlinPlatformType.jvm || target?.platformType == KotlinPlatformType.androidJvm
|
||||
|
||||
|
@ -71,19 +71,13 @@ kotlin {
|
||||
}
|
||||
|
||||
afterEvaluate {
|
||||
getByName("androidUnitTest") {
|
||||
findByName("androidUnitTest")?.apply {
|
||||
dependencies {
|
||||
runtimeOnly(`slf4j-api`)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
findByName("androidMain")?.apply {
|
||||
dependencies {
|
||||
// compileOnly(`android-runtime`)
|
||||
}
|
||||
}
|
||||
|
||||
findByName("jvmMain")?.apply {
|
||||
|
||||
}
|
||||
|
@ -1,14 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright 2019-2020 Mamoe Technologies and contributors.
|
||||
~
|
||||
~ 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||
~ Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
~
|
||||
~ https://github.com/mamoe/mirai/blob/master/LICENSE
|
||||
-->
|
||||
|
||||
<manifest package="net.mamoe.mirai" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
|
||||
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
|
||||
</manifest>
|
@ -64,13 +64,6 @@ kotlin {
|
||||
}
|
||||
}
|
||||
|
||||
findByName("androidMain")?.apply {
|
||||
dependencies {
|
||||
compileOnly(`android-runtime`)
|
||||
// api1(`ktor-client-android`)
|
||||
}
|
||||
}
|
||||
|
||||
findByName("jvmMain")?.apply {
|
||||
|
||||
}
|
||||
|
@ -77,17 +77,8 @@ kotlin {
|
||||
}
|
||||
}
|
||||
|
||||
findByName("androidMain")?.apply {
|
||||
dependencies {
|
||||
compileOnly(`android-runtime`)
|
||||
}
|
||||
}
|
||||
findByName("androidTest")?.apply {
|
||||
dependencies {
|
||||
implementation(kotlin("test", Versions.kotlinCompiler))
|
||||
implementation(kotlin("test-junit5", Versions.kotlinCompiler))
|
||||
implementation(kotlin("test-annotations-common"))
|
||||
implementation(kotlin("test-common"))
|
||||
implementation(bouncycastle)
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user