-
-
Notifications
You must be signed in to change notification settings - Fork 14
/
UsePrebuiltBinariesWhenUnbuildablePlugin.kt
102 lines (89 loc) · 4.04 KB
/
UsePrebuiltBinariesWhenUnbuildablePlugin.kt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
import dev.nokee.platform.jni.JavaNativeInterfaceLibrary
import org.gradle.api.Action
import org.gradle.api.Plugin
import org.gradle.api.Project
import dev.nokee.platform.jni.JniLibrary
import org.gradle.nativeplatform.platform.internal.DefaultNativePlatform
import java.io.File
fun JniLibrary.canBuildSharedLibrary(): Boolean {
// FIXME: This shouldn't be necessary
if (!DefaultNativePlatform.getCurrentOperatingSystem().isMacOsX
&& targetMachine.variantName == "macos-arm64"
) {
return false
}
return sharedLibrary.isBuildable
}
class UsePrebuiltBinariesWhenUnbuildablePlugin : Plugin<Project> {
private lateinit var prebuiltExtension: PrebuiltBinariesExtension
fun prebuiltBinaries(action: Action<PrebuiltBinariesExtension>) {
action.execute(prebuiltExtension)
}
override fun apply(target: Project) {
prebuiltExtension = target.extensions.create("prebuiltBinaries", PrebuiltBinariesExtension::class.java)
val library = target.extensions.getByType(JavaNativeInterfaceLibrary::class.java)
library.variants.configureEach {
if (prebuiltExtension.alwaysUsePrebuiltArtifact || !canBuildSharedLibrary()) {
configure(target, this)
}
}
}
private fun configure(project: Project, library: JniLibrary) {
with(prebuiltExtension) {
val defaultLibraryName = libraryFileNameFor(project, library.targetMachine.operatingSystemFamily)
val variantName = library.targetMachine.variantName
val libraryFile = project.file("$prebuiltLibrariesFolder/$variantName/$defaultLibraryName")
if (libraryFile.exists()) {
useLocalLibrary(project, library, libraryFile, variantName)
} else {
// No local binary provided. Try to download it from github actions.
useGithubLibrary(project, library, variantName)
}
}
}
private fun useGithubLibrary(project: Project, library: JniLibrary, variantName: String) {
val prebuiltBinariesTask = project.tasks.register(
"downloadPrebuiltBinary$variantName",
DownloadPrebuiltBinariesTask::class.java,
variantName,
prebuiltExtension
)
library.sharedLibrary.compileTasks.configureEach { enabled = false }
library.sharedLibrary.linkTask.configure { enabled = false }
library.nativeRuntimeFiles.setFrom(prebuiltBinariesTask.map { it.getPrebuiltBinaryFile() })
library.nativeRuntimeFiles.from(CallableAction {
project.logger.warn(
"${project.name}: Using pre-build library from github for targetMachine $variantName."
)
})
}
private fun useLocalLibrary(project: Project, library: JniLibrary, libraryFile: File, variantName: String) {
library.sharedLibrary.compileTasks.configureEach { enabled = false }
library.sharedLibrary.linkTask.configure { enabled = false }
library.nativeRuntimeFiles.setFrom(libraryFile)
library.nativeRuntimeFiles.from(CallableAction {
val relativePath = project.rootProject.relativePath(libraryFile)
project.logger.warn(
"${project.name}: Using pre-build library $relativePath for targetMachine $variantName."
)
})
}
}
open class PrebuiltBinariesExtension {
internal var githubArtifactSpec: GithubArtifactSpec? = null
var prebuiltLibrariesFolder: String = "pre-build-libraries"
var alwaysUsePrebuiltArtifact: Boolean = false
var failIfLibraryIsMissing: Boolean = true
fun github(user: String, repository: String, workflow: String, action: Action<GithubArtifactSpec>) {
githubArtifactSpec = GithubArtifactSpec(user, repository, workflow).also { action.execute(it) }
}
}
data class GithubArtifactSpec(
var user: String,
var repository: String?,
var workflow: String,
var manualDownloadUrl: String = "",
var accessToken: String? = null,
var timeout: Int = 0,
var branches: List<String> = listOf("master")
)