• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2019 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.ndkports
18 
19 import com.github.ajalt.clikt.core.CliktCommand
20 import com.github.ajalt.clikt.parameters.arguments.argument
21 import com.github.ajalt.clikt.parameters.arguments.multiple
22 import com.github.ajalt.clikt.parameters.arguments.validate
23 import com.github.ajalt.clikt.parameters.options.convert
24 import com.github.ajalt.clikt.parameters.options.default
25 import com.github.ajalt.clikt.parameters.options.flag
26 import com.github.ajalt.clikt.parameters.options.option
27 import com.github.ajalt.clikt.parameters.options.required
28 import com.github.ajalt.clikt.parameters.types.file
29 import de.swirtz.ktsrunner.objectloader.KtsObjectLoader
30 import java.io.File
31 import java.io.FileNotFoundException
32 import java.lang.RuntimeException
33 import kotlin.system.exitProcess
34 
35 class Cli : CliktCommand(help = "ndkports") {
36     private val outDir: File by option(
37         "-o",
38         "--out",
39         help = "Build directory."
40     ).file().default(File("out"))
41 
42     private val publishToMavenLocal: Boolean by option(
43         help = "Publish AARs to the local Maven repository (~/.m2/repository)"
44     ).flag()
45 
46     private val packages: List<String> by argument(
47         help = "Names of packages to build."
<lambda>null48     ).multiple().validate {
49         require(it.isNotEmpty()) { "must provide at least one package" }
50     }
51 
<lambda>null52     private val ndk: Ndk by option().convert { Ndk(File(it)) }.required()
53 
portDirectoryFornull54     private fun portDirectoryFor(name: String): File =
55         File("ports").resolve(name)
56 
57     private fun loadPort(name: String): Port {
58         val portDir = portDirectoryFor(name).also {
59             if (!it.exists()) {
60                 throw FileNotFoundException("Could not find ${it.path}")
61             }
62         }
63 
64         val portFile = portDir.resolve("port.kts").also {
65             if (!it.exists()) {
66                 throw FileNotFoundException("Could not find ${it.path}")
67             }
68         }
69 
70         return KtsObjectLoader().load(portFile.reader())
71     }
72 
runnull73     override fun run() {
74         println("Building packages: ${packages.joinToString(", ")}")
75         val portsByName = packages.map { loadPort(it) }.associateBy { it.name }
76         for (port in portsByName.values) {
77             val workingDirectory =
78                 outDir.resolve(port.name).also { it.mkdirs() }
79 
80             val sourceDirectory = workingDirectory.resolve("src")
81             val sourceTarball =
82                 portDirectoryFor(port.name).resolve("src.tar.gz")
83 
84             port.extractSource(sourceTarball, sourceDirectory, workingDirectory)
85 
86             val apiForAbi = mapOf(
87                 Abi.Arm to 16,
88                 Abi.Arm64 to 21,
89                 Abi.X86 to 16,
90                 Abi.X86_64 to 21
91             )
92             for (abi in Abi.values()) {
93                 val api = apiForAbi.getOrElse(abi) {
94                     throw RuntimeException(
95                         "No API level specified for ${abi.abiName}"
96                     )
97                 }
98                 val toolchain = Toolchain(ndk, abi, api)
99 
100                 val buildDirectory = workingDirectory.resolve("build/$abi")
101                 val installDirectory = installDirectoryForPort(
102                     port.name, workingDirectory, toolchain
103                 )
104 
105                 port.run(
106                     toolchain,
107                     sourceDirectory,
108                     buildDirectory,
109                     installDirectory,
110                     workingDirectory
111                 ).onFailure {
112                     println(it)
113                     exitProcess(1)
114                 }
115             }
116 
117             PrefabPackageBuilder(
118                 port,
119                 workingDirectory,
120                 sourceDirectory,
121                 publishToMavenLocal,
122                 ndk,
123                 apiForAbi,
124                 portsByName
125             ).build()
126         }
127     }
128 }
129 
mainnull130 fun main(args: Array<String>) {
131     Cli().main(args)
132 }