1 package com.android.ndkports 2 3 import org.gradle.api.DefaultTask 4 import org.gradle.api.file.Directory 5 import org.gradle.api.file.DirectoryProperty 6 import org.gradle.api.provider.Property 7 import org.gradle.api.provider.Provider 8 import org.gradle.api.tasks.Input 9 import org.gradle.api.tasks.InputDirectory 10 import org.gradle.api.tasks.Internal 11 import org.gradle.api.tasks.OutputDirectory 12 import org.gradle.api.tasks.TaskAction 13 import java.io.File 14 15 @Suppress("UnstableApiUsage") 16 abstract class PortTask : DefaultTask() { 17 18 @get:InputDirectory 19 abstract val sourceDirectory: DirectoryProperty 20 21 @get:OutputDirectory 22 abstract val buildDir: DirectoryProperty 23 24 @get:OutputDirectory 25 val installDir: Provider<Directory> 26 get() = buildDir.dir("install") 27 28 @get:InputDirectory 29 abstract val prefabGenerated: DirectoryProperty 30 31 @get:Input 32 abstract val minSdkVersion: Property<Int> 33 34 @get:InputDirectory 35 abstract val ndkPath: DirectoryProperty 36 37 private val ndk: Ndk 38 get() = Ndk(ndkPath.asFile.get()) 39 40 /** 41 * The number of CPUs available for building. 42 * 43 * May be passed to the build system if required. 44 */ 45 @Internal 46 protected val ncpus = Runtime.getRuntime().availableProcessors() 47 executeSubprocessnull48 protected fun executeSubprocess( 49 args: List<String>, 50 workingDirectory: File, 51 additionalEnvironment: Map<String, String>? = null 52 ) { 53 val pb = ProcessBuilder(args).redirectErrorStream(true) 54 .directory(workingDirectory) 55 56 if (additionalEnvironment != null) { 57 pb.environment().putAll(additionalEnvironment) 58 } 59 60 val result = pb.start() 61 val output = result.inputStream.bufferedReader().use { it.readText() } 62 if (result.waitFor() != 0) { 63 throw RuntimeException("Subprocess failed with:\n$output") 64 } 65 } 66 67 @Suppress("MemberVisibilityCanBePrivate") buildDirectoryFornull68 fun buildDirectoryFor(abi: Abi): File = 69 buildDir.asFile.get().resolve("build/$abi") 70 71 @Suppress("MemberVisibilityCanBePrivate") 72 fun installDirectoryFor(abi: Abi): File = 73 installDir.get().asFile.resolve("$abi") 74 75 @TaskAction 76 fun run() { 77 for (abi in Abi.values()) { 78 val api = abi.adjustMinSdkVersion(minSdkVersion.get()) 79 buildForAbi( 80 Toolchain(ndk, abi, api), 81 buildDir.asFile.get(), 82 buildDirectory = buildDirectoryFor(abi), 83 installDirectory = installDirectoryFor(abi), 84 ) 85 } 86 } 87 buildForAbinull88 abstract fun buildForAbi( 89 toolchain: Toolchain, 90 workingDirectory: File, 91 buildDirectory: File, 92 installDirectory: File 93 ) 94 }