[K/N] Make XCTest runner project configuration cache friendly
Use ValueSource with ExecOperations to obtain developer framework location where the XCTest.framework is located. This is necessary for Gradle configuration cache.
This commit is contained in:
committed by
Space Team
parent
808d4353e5
commit
bc55eccf28
@@ -12,58 +12,89 @@ plugins {
|
||||
kotlin("multiplatform")
|
||||
}
|
||||
|
||||
/**
|
||||
* Path to the target SDK platform.
|
||||
*
|
||||
* By default, K/N includes only SDK frameworks as platform libs.
|
||||
* It's required to get the Library frameworks path where the `XCTest.framework` is located.
|
||||
* Consider making XCTest a platform lib with KT-61709.
|
||||
*/
|
||||
fun targetPlatform(target: String): String {
|
||||
val out = ByteArrayOutputStream()
|
||||
val result = project.exec {
|
||||
executable = "/usr/bin/xcrun"
|
||||
args = listOf("--sdk", target, "--show-sdk-platform-path")
|
||||
standardOutput = out
|
||||
}
|
||||
check(result.exitValue == 0) {
|
||||
"xcrun failed with ${result.exitValue}. See the output: $out"
|
||||
}
|
||||
|
||||
return out.toString().trim()
|
||||
}
|
||||
// region XCTest framework location
|
||||
|
||||
/**
|
||||
* Returns a path to the Xcode developer frameworks location based on the specified KonanTarget.
|
||||
* Value source for the Xcode developer framework path location.
|
||||
*/
|
||||
fun KonanTarget.developerFrameworkPath(): String {
|
||||
val platform = when (this) {
|
||||
KonanTarget.MACOS_ARM64, KonanTarget.MACOS_X64 -> "macosx"
|
||||
KonanTarget.IOS_SIMULATOR_ARM64, KonanTarget.IOS_X64 -> "iphonesimulator"
|
||||
KonanTarget.IOS_ARM64 -> "iphoneos"
|
||||
else -> error("Target $this is not supported here")
|
||||
abstract class DevFrameworkPathValueSource : ValueSource<String, DevFrameworkPathValueSource.Parameters> {
|
||||
@get:Inject
|
||||
abstract val execOperations: ExecOperations
|
||||
|
||||
interface Parameters : ValueSourceParameters {
|
||||
val konanTarget: Property<KonanTarget>
|
||||
}
|
||||
|
||||
return targetPlatform(platform) + "/Developer/Library/Frameworks/"
|
||||
}
|
||||
override fun obtain(): String {
|
||||
val devFrameworkPath = parameters.konanTarget.get().developerFrameworkPath()
|
||||
|
||||
/**
|
||||
* Registers a task to copy the XCTest framework to the build directory for the specified KonanTarget.
|
||||
*
|
||||
* @param target The KonanTarget for which the copy framework task should be registered.
|
||||
* @return The TaskProvider representing the registered copy framework task.
|
||||
*/
|
||||
fun registerCopyFrameworkTask(target: KonanTarget): TaskProvider<Sync> =
|
||||
tasks.register<Sync>("${target}FrameworkCopy") {
|
||||
val devFrameworkPath = Paths.get(target.developerFrameworkPath())
|
||||
check(devFrameworkPath.toFile().exists()) {
|
||||
check(File(devFrameworkPath).exists()) {
|
||||
"Developer frameworks path wasn't found at $devFrameworkPath. Check configuration and Xcode installation"
|
||||
}
|
||||
|
||||
from(devFrameworkPath.resolve("XCTest.framework"))
|
||||
return parameters.konanTarget.get().developerFrameworkPath()
|
||||
}
|
||||
|
||||
/**
|
||||
* Path to the target SDK platform.
|
||||
*
|
||||
* By default, K/N includes only SDK frameworks as platform libs.
|
||||
* It's required to get the Library frameworks path where the `XCTest.framework` is located.
|
||||
* Consider making XCTest a platform lib with KT-61709.
|
||||
*/
|
||||
private fun targetPlatform(target: String): String {
|
||||
val out = ByteArrayOutputStream()
|
||||
val result = execOperations.exec {
|
||||
executable = "/usr/bin/xcrun"
|
||||
args = listOf("--sdk", target, "--show-sdk-platform-path")
|
||||
standardOutput = out
|
||||
}
|
||||
check(result.exitValue == 0) {
|
||||
"xcrun failed with ${result.exitValue}. See the output: $out"
|
||||
}
|
||||
|
||||
return out.toString().trim()
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a path to the Xcode developer frameworks location based on the specified [KonanTarget].
|
||||
*/
|
||||
private fun KonanTarget.developerFrameworkPath(): String {
|
||||
val platform = when (this) {
|
||||
KonanTarget.MACOS_ARM64, KonanTarget.MACOS_X64 -> "macosx"
|
||||
KonanTarget.IOS_SIMULATOR_ARM64, KonanTarget.IOS_X64 -> "iphonesimulator"
|
||||
KonanTarget.IOS_ARM64 -> "iphoneos"
|
||||
else -> error("Target $this is not supported here")
|
||||
}
|
||||
|
||||
return targetPlatform(platform) + "/Developer/Library/Frameworks/"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a task to copy the XCTest framework to the build directory for the specified [KonanTarget].
|
||||
*
|
||||
* @param target The [KonanTarget] for which the copy framework task should be registered.
|
||||
* @return The [TaskProvider] representing the registered copy framework task.
|
||||
*/
|
||||
fun registerCopyFrameworkTask(target: KonanTarget): TaskProvider<Sync> =
|
||||
tasks.register<Sync>("${target}FrameworkCopy") {
|
||||
from(
|
||||
providers.of(DevFrameworkPathValueSource::class) {
|
||||
parameters {
|
||||
konanTarget = target
|
||||
}
|
||||
}.map {
|
||||
Paths.get(it).resolve("XCTest.framework")
|
||||
}
|
||||
)
|
||||
into(layout.buildDirectory.dir("$target/Frameworks/XCTest.framework"))
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
// region Kotlin Multiplatform build configuration
|
||||
|
||||
val nativeTargets = mutableListOf<KotlinNativeTarget>()
|
||||
|
||||
if (HostManager.hostIsMac) {
|
||||
@@ -80,13 +111,7 @@ if (HostManager.hostIsMac) {
|
||||
it.compilations.all {
|
||||
cinterops {
|
||||
register("XCTest") {
|
||||
compilerOpts(
|
||||
"-iframework", project.layout.buildDirectory
|
||||
.dir("$konanTarget/Frameworks")
|
||||
.get()
|
||||
.asFile
|
||||
.absolutePath
|
||||
)
|
||||
compilerOpts("-iframework", copyTask.map { it.destinationDir }.get().absolutePath)
|
||||
// cinterop task should depend on the framework copy task
|
||||
tasks.named(interopProcessingTaskName).configure {
|
||||
dependsOn(copyTask)
|
||||
@@ -107,6 +132,10 @@ if (HostManager.hostIsMac) {
|
||||
}
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
// region Artifact collection for consumers
|
||||
|
||||
val kotlinTestNativeXCTest by configurations.creating {
|
||||
attributes {
|
||||
attribute(Usage.USAGE_ATTRIBUTE, objects.named(KotlinUsages.KOTLIN_API))
|
||||
@@ -143,4 +172,6 @@ nativeTargets.forEach { target ->
|
||||
builtBy(frameworkCopyTask)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// endregion
|
||||
Reference in New Issue
Block a user