Initial: initial commit
This commit is contained in:
17
buildSrc/src/main/java/Build.kt
Normal file
17
buildSrc/src/main/java/Build.kt
Normal file
@@ -0,0 +1,17 @@
|
||||
import org.gradle.api.Project
|
||||
|
||||
const val buildVersionCode = 203022
|
||||
const val buildVersionName = "2.3.22"
|
||||
|
||||
const val buildMinSdkVersion = 21
|
||||
const val buildTargetSdkVersion = 30
|
||||
|
||||
const val buildNdkVersion = "23.0.7123448"
|
||||
|
||||
val Project.buildFlavor: String
|
||||
get() {
|
||||
return if (project(":core").file("src/main/golang/clash/script/script.go").exists())
|
||||
"premium"
|
||||
else
|
||||
"open"
|
||||
}
|
||||
14
buildSrc/src/main/java/Dependencies.kt
Normal file
14
buildSrc/src/main/java/Dependencies.kt
Normal file
@@ -0,0 +1,14 @@
|
||||
const val activityVersion = "1.2.3"
|
||||
const val coroutineVersion = "1.4.3"
|
||||
const val roomVersion = "2.3.0"
|
||||
const val ktxVersion = "1.3.2"
|
||||
const val appcompatVersion = "1.2.0"
|
||||
const val muiltprocessVersion = "1.0.0"
|
||||
const val kaidlVersion = "1.11"
|
||||
const val appcenterVersion = "4.1.1"
|
||||
const val serializationVersion = "1.2.1"
|
||||
const val materialVersion = "1.3.0"
|
||||
const val coordinatorlayoutVersion = "1.1.0"
|
||||
const val recyclerviewVersion = "1.2.0"
|
||||
const val fragmentVersion = "1.3.3"
|
||||
const val viewpagerVersion = "1.0.0"
|
||||
8
buildSrc/src/main/java/Files.kt
Normal file
8
buildSrc/src/main/java/Files.kt
Normal file
@@ -0,0 +1,8 @@
|
||||
import org.gradle.api.Project
|
||||
import java.io.File
|
||||
|
||||
val Project.golangSource: File
|
||||
get() = file("src/main/golang")
|
||||
|
||||
val Project.golangBuild: File
|
||||
get() = buildDir.resolve("intermediates/golang")
|
||||
119
buildSrc/src/main/java/GolangBuildTask.kt
Normal file
119
buildSrc/src/main/java/GolangBuildTask.kt
Normal file
@@ -0,0 +1,119 @@
|
||||
import org.apache.tools.ant.taskdefs.condition.Os
|
||||
import org.gradle.api.DefaultTask
|
||||
import org.gradle.api.GradleScriptException
|
||||
import org.gradle.api.file.DirectoryProperty
|
||||
import org.gradle.api.provider.Property
|
||||
import org.gradle.api.provider.SetProperty
|
||||
import org.gradle.api.tasks.*
|
||||
import java.io.ByteArrayOutputStream
|
||||
import java.io.File
|
||||
import java.io.FileNotFoundException
|
||||
import java.io.IOException
|
||||
|
||||
abstract class GolangBuildTask : DefaultTask() {
|
||||
abstract val debug: Property<Boolean>
|
||||
@Input get
|
||||
|
||||
abstract val premium: Property<Boolean>
|
||||
@Input get
|
||||
|
||||
abstract val nativeAbis: SetProperty<String>
|
||||
@Input get
|
||||
|
||||
abstract val minSdkVersion: Property<Int>
|
||||
@Input get
|
||||
|
||||
abstract val cCompilerBasePath: DirectoryProperty
|
||||
@InputDirectory get
|
||||
|
||||
abstract val inputDirectory: DirectoryProperty
|
||||
@InputDirectory get
|
||||
|
||||
abstract val outputDirectory: DirectoryProperty
|
||||
@OutputDirectory get
|
||||
|
||||
@TaskAction
|
||||
fun build() {
|
||||
val src = inputDirectory.get().asFile
|
||||
|
||||
val cmd = if (debug.get()) {
|
||||
"""
|
||||
go build --buildmode=c-shared -trimpath -o "%s" -tags "without_gvisor,without_system,debug${if (premium.get()) ",premium" else ""}"
|
||||
""".trimIndent().trim()
|
||||
} else {
|
||||
"""
|
||||
go build --buildmode=c-shared -trimpath -o "%s" -tags "without_gvisor,without_system${if (premium.get()) ",premium" else ""}" -ldflags "-s -w"
|
||||
""".trimIndent().trim()
|
||||
}
|
||||
|
||||
nativeAbis.get().parallelStream().forEach {
|
||||
val out = outputDirectory.get().file("$it/libclash.so")
|
||||
|
||||
cmd.format(out).exec(pwd = src, env = generateGolangBuildEnvironment(it))
|
||||
}
|
||||
}
|
||||
|
||||
private fun generateGolangBuildEnvironment(abi: String): Map<String, String> {
|
||||
val (goArch, goArm) = when (abi) {
|
||||
"arm64-v8a" -> "arm64" to ""
|
||||
"armeabi-v7a" -> "arm" to "7"
|
||||
"x86" -> "386" to ""
|
||||
"x86_64" -> "amd64" to ""
|
||||
else -> throw UnsupportedOperationException("unsupported abi: $abi")
|
||||
}
|
||||
|
||||
val compiler = when (abi) {
|
||||
"armeabi-v7a" ->
|
||||
"armv7a-linux-androideabi${minSdkVersion.get()}-clang"
|
||||
"arm64-v8a" ->
|
||||
"aarch64-linux-android${minSdkVersion.get()}-clang"
|
||||
"x86" ->
|
||||
"i686-linux-android${minSdkVersion.get()}-clang"
|
||||
"x86_64" ->
|
||||
"x86_64-linux-android${minSdkVersion.get()}-clang"
|
||||
else ->
|
||||
throw GradleScriptException(
|
||||
"Unsupported abi $abi",
|
||||
FileNotFoundException("Unsupported abi $abi")
|
||||
)
|
||||
}
|
||||
|
||||
return mapOf(
|
||||
"CC" to cCompilerBasePath.get().asFile.resolve(compiler).absolutePath,
|
||||
"GOOS" to "android",
|
||||
"GOARCH" to goArch,
|
||||
"GOARM" to goArm,
|
||||
"CGO_ENABLED" to "1",
|
||||
"CFLAGS" to "-O3 -Werror",
|
||||
)
|
||||
}
|
||||
|
||||
private fun String.exec(
|
||||
pwd: File,
|
||||
env: Map<String, String> = System.getenv()
|
||||
): String {
|
||||
val process = ProcessBuilder().run {
|
||||
if (Os.isFamily(Os.FAMILY_WINDOWS))
|
||||
command("cmd.exe", "/c", this@exec)
|
||||
else
|
||||
command("bash", "-c", this@exec)
|
||||
|
||||
environment().putAll(env)
|
||||
directory(pwd)
|
||||
|
||||
redirectErrorStream(true)
|
||||
|
||||
start()
|
||||
}
|
||||
|
||||
val outputStream = ByteArrayOutputStream()
|
||||
process.inputStream.copyTo(outputStream)
|
||||
|
||||
if (process.waitFor() != 0) {
|
||||
println(outputStream.toString("utf-8"))
|
||||
throw GradleScriptException("Exec $this failure", IOException())
|
||||
}
|
||||
|
||||
return outputStream.toString("utf-8")
|
||||
}
|
||||
}
|
||||
69
buildSrc/src/main/java/LibraryGolangPlugin.kt
Normal file
69
buildSrc/src/main/java/LibraryGolangPlugin.kt
Normal file
@@ -0,0 +1,69 @@
|
||||
import com.android.build.gradle.LibraryExtension
|
||||
import org.apache.tools.ant.taskdefs.condition.Os
|
||||
import org.gradle.api.GradleScriptException
|
||||
import org.gradle.api.Plugin
|
||||
import org.gradle.api.Project
|
||||
import java.io.File
|
||||
import java.io.FileNotFoundException
|
||||
import java.util.*
|
||||
|
||||
class LibraryGolangPlugin : Plugin<Project> {
|
||||
override fun apply(target: Project) {
|
||||
target.extensions.getByType(LibraryExtension::class.java).apply {
|
||||
target.afterEvaluate {
|
||||
libraryVariants.forEach { variant ->
|
||||
val abis = defaultConfig.externalNativeBuild.cmake.abiFilters +
|
||||
defaultConfig.externalNativeBuild.ndkBuild.abiFilters
|
||||
|
||||
val nameCapitalize = variant.name.capitalize(Locale.getDefault())
|
||||
val golangBuildDir = target.golangBuild.resolve(variant.name)
|
||||
|
||||
val task = target.tasks.register(
|
||||
"externalGolangBuild$nameCapitalize",
|
||||
GolangBuildTask::class.java
|
||||
) {
|
||||
it.premium.set(variant.flavorName == "premium")
|
||||
it.debug.set(variant.name == "debug")
|
||||
it.nativeAbis.set(abis)
|
||||
it.minSdkVersion.set(defaultConfig.minSdk!!)
|
||||
it.cCompilerBasePath.set(compilerBasePath)
|
||||
it.inputDirectory.set(target.golangSource)
|
||||
it.outputDirectory.set(golangBuildDir)
|
||||
}
|
||||
|
||||
sourceSets.named(variant.name) {
|
||||
it.jniLibs {
|
||||
srcDir(golangBuildDir)
|
||||
}
|
||||
}
|
||||
|
||||
variant.externalNativeBuildProviders.forEach {
|
||||
it.get().dependsOn(task)
|
||||
}
|
||||
target.tasks.filter { it.name.startsWith("buildCMake") }.forEach {
|
||||
it.mustRunAfter(task)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private val LibraryExtension.compilerBasePath: File
|
||||
get() {
|
||||
val host = when {
|
||||
Os.isFamily(Os.FAMILY_WINDOWS) ->
|
||||
"windows"
|
||||
Os.isFamily(Os.FAMILY_MAC) ->
|
||||
"darwin"
|
||||
Os.isFamily(Os.FAMILY_UNIX) ->
|
||||
"linux"
|
||||
else ->
|
||||
throw GradleScriptException(
|
||||
"Unsupported host",
|
||||
FileNotFoundException("Unsupported host")
|
||||
)
|
||||
}
|
||||
|
||||
return ndkDirectory.resolve("toolchains/llvm/prebuilt/$host-x86_64/bin")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user