mirror of
https://github.com/ethauvin/kobalt.git
synced 2025-04-26 08:27:12 -07:00
Assets for Android.
This commit is contained in:
parent
4354d37ecf
commit
896102dedf
12 changed files with 107 additions and 87 deletions
|
@ -227,25 +227,26 @@ private class Main @Inject constructor(
|
|||
|
||||
private fun runClasspathInterceptors(allProjects: List<Project>) {
|
||||
allProjects.forEach {
|
||||
runClasspathInterceptors(it.compileDependencies)
|
||||
runClasspathInterceptors(it.compileProvidedDependencies)
|
||||
runClasspathInterceptors(it.compileRuntimeDependencies)
|
||||
runClasspathInterceptors(it.testProvidedDependencies)
|
||||
runClasspathInterceptors(it.testDependencies)
|
||||
runClasspathInterceptors(it, it.compileDependencies)
|
||||
runClasspathInterceptors(it, it.compileProvidedDependencies)
|
||||
runClasspathInterceptors(it, it.compileRuntimeDependencies)
|
||||
runClasspathInterceptors(it, it.testProvidedDependencies)
|
||||
runClasspathInterceptors(it, it.testDependencies)
|
||||
}
|
||||
}
|
||||
|
||||
private fun runClasspathInterceptors(dependencies: ArrayList<IClasspathDependency>) = with(dependencies) {
|
||||
val deps = interceptDependencies(pluginInfo, this)
|
||||
clear()
|
||||
addAll(deps)
|
||||
}
|
||||
private fun runClasspathInterceptors(project: Project, dependencies: ArrayList<IClasspathDependency>)
|
||||
= with(dependencies) {
|
||||
val deps = interceptDependencies(project, pluginInfo, this)
|
||||
clear()
|
||||
addAll(deps)
|
||||
}
|
||||
|
||||
private fun interceptDependencies(pluginInfo: PluginInfo, dependencies: ArrayList<IClasspathDependency>)
|
||||
: ArrayList<IClasspathDependency> {
|
||||
private fun interceptDependencies(project: Project, pluginInfo: PluginInfo,
|
||||
dependencies: ArrayList<IClasspathDependency>) : ArrayList<IClasspathDependency> {
|
||||
val result = arrayListOf<IClasspathDependency>()
|
||||
pluginInfo.classpathInterceptors.forEach {
|
||||
result.addAll(it.intercept(dependencies))
|
||||
result.addAll(it.intercept(project, dependencies))
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
package com.beust.kobalt.api
|
||||
|
||||
import com.beust.kobalt.api.IClasspathDependency
|
||||
|
||||
/**
|
||||
* Modify a list of dependencies before Kobalt starts using them.
|
||||
*/
|
||||
interface IClasspathInterceptor : IInterceptor {
|
||||
fun intercept(dependencies: List<IClasspathDependency>) : List<IClasspathDependency>
|
||||
fun intercept(project: Project, dependencies: List<IClasspathDependency>) : List<IClasspathDependency>
|
||||
}
|
||||
|
|
|
@ -29,14 +29,15 @@ class JvmCompiler @Inject constructor(val dependencyManager: DependencyManager)
|
|||
.distinct()
|
||||
|
||||
// Plugins that add flags to the compiler
|
||||
val addedFlags = ArrayList(info.compilerArgs) +
|
||||
if (project != null) {
|
||||
context.pluginInfo.compilerFlagContributors.flatMap {
|
||||
it.flagsFor(project, info.compilerArgs)
|
||||
}
|
||||
} else {
|
||||
emptyList()
|
||||
val contributorFlags = if (project != null) {
|
||||
context.pluginInfo.compilerFlagContributors.flatMap {
|
||||
it.flagsFor(project, info.compilerArgs)
|
||||
}
|
||||
} else {
|
||||
emptyList()
|
||||
}
|
||||
|
||||
val addedFlags = contributorFlags + ArrayList(info.compilerArgs)
|
||||
|
||||
validateClasspath(allDependencies.map { it.jarFile.get().absolutePath })
|
||||
return action.compile(info.copy(dependencies = allDependencies, compilerArgs = addedFlags))
|
||||
|
|
|
@ -112,7 +112,7 @@ abstract class JvmCompilerPlugin @Inject constructor(
|
|||
it.exists()
|
||||
} .forEach {
|
||||
log(2, "Copying from $sourceDirs to $absOutputDir")
|
||||
KFiles.copyRecursively(it, absOutputDir)
|
||||
KFiles.copyRecursively(it, absOutputDir, deleteFirst = true)
|
||||
}
|
||||
} else {
|
||||
lp(project, "No resources to copy for $sourceSet")
|
||||
|
|
|
@ -2,9 +2,12 @@ package com.beust.kobalt.maven
|
|||
|
||||
import com.beust.kobalt.KobaltException
|
||||
import com.beust.kobalt.api.IClasspathDependency
|
||||
import com.beust.kobalt.api.Kobalt
|
||||
import com.beust.kobalt.maven.dependency.FileDependency
|
||||
import com.beust.kobalt.maven.dependency.MavenDependency
|
||||
import com.beust.kobalt.misc.DependencyExecutor
|
||||
import com.beust.kobalt.misc.KobaltExecutors
|
||||
import com.google.inject.Key
|
||||
import java.util.concurrent.ExecutorService
|
||||
import javax.inject.Inject
|
||||
|
||||
|
@ -14,10 +17,15 @@ public class DepFactory @Inject constructor(val localRepo: LocalRepo,
|
|||
val downloadManager: DownloadManager,
|
||||
val pomFactory: Pom.IFactory) {
|
||||
|
||||
companion object {
|
||||
val defExecutor =
|
||||
Kobalt.INJECTOR.getInstance(Key.get(ExecutorService::class.java, DependencyExecutor::class.java))
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the id and return the correct IClasspathDependency
|
||||
*/
|
||||
public fun create(id: String, executor: ExecutorService,
|
||||
public fun create(id: String, executor: ExecutorService = defExecutor,
|
||||
localFirst : Boolean = true) : IClasspathDependency {
|
||||
if (id.startsWith(FileDependency.PREFIX_FILE)) {
|
||||
return FileDependency(id.substring(FileDependency.PREFIX_FILE.length))
|
||||
|
|
|
@ -137,7 +137,7 @@ class KFiles {
|
|||
return result
|
||||
}
|
||||
|
||||
fun copyRecursively(from: File, to: File, replaceExisting: Boolean = true, deleteFirst: Boolean = true,
|
||||
fun copyRecursively(from: File, to: File, replaceExisting: Boolean = true, deleteFirst: Boolean = false,
|
||||
onError: (File, IOException) -> OnErrorAction = { file, exception -> throw exception }) {
|
||||
// Need to wait until copyRecursively supports an overwrite: Boolean = false parameter
|
||||
// Until then, wipe everything first
|
||||
|
|
|
@ -48,10 +48,8 @@ open class RunCommand(val command: String) {
|
|||
}
|
||||
}
|
||||
val callSucceeded = process.waitFor(30, TimeUnit.SECONDS)
|
||||
val input = if (process.inputStream.available() > 0) fromStream(process.inputStream)
|
||||
else listOf()
|
||||
val error = if (process.errorStream.available() > 0) fromStream(process.errorStream)
|
||||
else listOf()
|
||||
val input = if (process.inputStream.available() > 0) fromStream(process.inputStream) else emptyList()
|
||||
val error = if (process.errorStream.available() > 0) fromStream(process.errorStream) else emptyList()
|
||||
val isSuccess = isSuccess(callSucceeded, input, error)
|
||||
|
||||
if (isSuccess) {
|
||||
|
@ -85,5 +83,8 @@ open class RunCommand(val command: String) {
|
|||
line = br.readLine()
|
||||
}
|
||||
return result
|
||||
|
||||
// val result = CharStreams.toString(InputStreamReader(ins, Charset.defaultCharset()))
|
||||
// return result.split("\n")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -106,6 +106,19 @@ class AndroidBuild {
|
|||
val dxJar = androidBuilder.dxJar
|
||||
val resourceMerger = ResourceMerger()
|
||||
|
||||
//
|
||||
// Assets
|
||||
//
|
||||
val intermediates = File(
|
||||
KFiles.joinDir(AndroidFiles.intermediates(project), "assets", variant.toIntermediateDir()))
|
||||
aarDependencies.forEach {
|
||||
val assetDir = File(it, "assets")
|
||||
if (assetDir.exists()) {
|
||||
println("COPY FROM $assetDir TO $intermediates")
|
||||
KFiles.copyRecursively(assetDir, intermediates)
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Manifest
|
||||
//
|
||||
|
@ -143,8 +156,8 @@ class AndroidBuild {
|
|||
|
||||
// TODO: figure out why the badSrcList is bad. All this information should be coming from the Variant
|
||||
val badSrcList = variant.resDirectories(project).map { it.path }
|
||||
val aarList = aarDependencies.map { it.path + File.separator}
|
||||
(aarList + srcList).map { it + File.separator + "res" }.forEach { path ->
|
||||
val goodAarList = aarDependencies.map { it.path + File.separator}
|
||||
(goodAarList + srcList).map { it + File.separator + "res" }.forEach { path ->
|
||||
val set = ResourceSet(path)
|
||||
set.addSource(File(path))
|
||||
set.loadFromFiles(logger)
|
||||
|
@ -157,7 +170,5 @@ class AndroidBuild {
|
|||
|
||||
|
||||
resourceMerger.mergeData(writer, true)
|
||||
|
||||
println("")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,9 @@ package com.beust.kobalt.plugin.android
|
|||
import com.beust.kobalt.Variant
|
||||
import com.beust.kobalt.api.KobaltContext
|
||||
import com.beust.kobalt.api.Project
|
||||
import com.beust.kobalt.maven.MavenId
|
||||
import com.beust.kobalt.misc.KFiles
|
||||
import java.nio.file.Paths
|
||||
|
||||
class AndroidFiles {
|
||||
companion object {
|
||||
|
@ -27,6 +29,10 @@ class AndroidFiles {
|
|||
fun mergedResources(project: Project, variant: Variant) =
|
||||
KFiles.joinAndMakeDir(mergedResourcesNoVariant(project), variant.toIntermediateDir())
|
||||
|
||||
fun classesJar(project: Project, mavenId: MavenId) =
|
||||
Paths.get(intermediates(project), "exploded-aar", mavenId.groupId, mavenId.artifactId, mavenId.version,
|
||||
"classes.jar").toFile().path
|
||||
|
||||
/**
|
||||
* Use the android home define on the project if any, otherwise use the environment variable.
|
||||
*/
|
||||
|
|
|
@ -4,6 +4,7 @@ import com.beust.kobalt.*
|
|||
import com.beust.kobalt.api.*
|
||||
import com.beust.kobalt.api.annotation.Directive
|
||||
import com.beust.kobalt.api.annotation.Task
|
||||
import com.beust.kobalt.maven.DependencyManager
|
||||
import com.beust.kobalt.maven.MavenId
|
||||
import com.beust.kobalt.maven.dependency.FileDependency
|
||||
import com.beust.kobalt.maven.dependency.MavenDependency
|
||||
|
@ -20,7 +21,7 @@ import java.nio.file.Paths
|
|||
|
||||
@Singleton
|
||||
public class AndroidPlugin @Inject constructor(val javaCompiler: JavaCompiler, val merger: Merger,
|
||||
val executors: KobaltExecutors)
|
||||
val executors: KobaltExecutors, val dependencyManager: DependencyManager)
|
||||
: ConfigPlugin<AndroidConfig>(), IClasspathContributor, IRepoContributor, ICompilerFlagContributor,
|
||||
ICompilerInterceptor, IBuildDirectoryIncerceptor, IRunnerContributor, IClasspathInterceptor,
|
||||
ISourceDirectoryContributor, IBuildConfigFieldContributor, ITaskContributor {
|
||||
|
@ -72,7 +73,7 @@ public class AndroidPlugin @Inject constructor(val javaCompiler: JavaCompiler, v
|
|||
return version as String
|
||||
}
|
||||
|
||||
inline fun androidHome(project: Project?) = AndroidFiles.androidHome(project, configurationFor(project)!!)
|
||||
fun androidHome(project: Project?) = AndroidFiles.androidHome(project, configurationFor(project)!!)
|
||||
|
||||
fun androidJar(project: Project): Path =
|
||||
Paths.get(androidHome(project), "platforms", "android-${compileSdkVersion(project)}", "android.jar")
|
||||
|
@ -91,9 +92,8 @@ public class AndroidPlugin @Inject constructor(val javaCompiler: JavaCompiler, v
|
|||
runBefore = arrayOf("compile"), runAfter = arrayOf("clean"))
|
||||
fun taskGenerateRFile(project: Project): TaskResult {
|
||||
|
||||
val intermediates = AndroidFiles.intermediates(project)
|
||||
val resDir = "temporaryBogusResDir"
|
||||
val aarDependencies= explodeAarFiles(project, intermediates, File(resDir))
|
||||
val aarDependencies = explodeAarFiles(project, File(resDir))
|
||||
AndroidBuild().run(project, context.variant, configurationFor(project)!!, aarDependencies)
|
||||
// merger.merge(project, context)
|
||||
|
||||
|
@ -151,31 +151,32 @@ public class AndroidPlugin @Inject constructor(val javaCompiler: JavaCompiler, v
|
|||
// "--output-text-symbols", KFiles.joinAndMakeDir(intermediates(project).toString(), "symbol", flavor)
|
||||
))
|
||||
|
||||
val rOutputDirectory = KFiles.joinDir(rDirectory, applicationId.replace(".", File.separator))
|
||||
val generatedBuildDir = compile(project, rOutputDirectory)
|
||||
project.compileDependencies.add(FileDependency(generatedBuildDir.path))
|
||||
// val rOutputDirectory = KFiles.joinDir(rDirectory, applicationId.replace(".", File.separator))
|
||||
// val generatedBuildDir = compile(project, rOutputDirectory)
|
||||
// project.compileDependencies.add(FileDependency(generatedBuildDir.path))
|
||||
return result == 0
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract all the .aar files found in the dependencies and add the android.jar to classpathEntries,
|
||||
* which will be added to the classpath at compile time
|
||||
* Extract all the .aar files found in the dependencies and add their android.jar to classpathEntries,
|
||||
* which will be added to the classpath at compile time via the classpath interceptor.
|
||||
*/
|
||||
private fun explodeAarFiles(project: Project, outputDir: String, resDir: File) : List<File> {
|
||||
private fun explodeAarFiles(project: Project, resDir: File) : List<File> {
|
||||
val result = arrayListOf<File>()
|
||||
project.compileDependencies.filter {
|
||||
it.jarFile.get().name.endsWith(".aar")
|
||||
}.forEach {
|
||||
val mavenId = MavenId(it.id)
|
||||
val outputDir = AndroidFiles.intermediates(project)
|
||||
val destDir = Paths.get(outputDir, "exploded-aar", mavenId.groupId,
|
||||
mavenId.artifactId, mavenId.version)
|
||||
.toFile()
|
||||
log(2, "Exploding ${it.jarFile.get()} to $destDir")
|
||||
JarUtils.extractJarFile(it.jarFile.get(), destDir)
|
||||
val classesJar = Paths.get(destDir.absolutePath, "classes.jar")
|
||||
val classesJar = AndroidFiles.classesJar(project, mavenId)
|
||||
|
||||
// Add the classses.jar of this .aar to the classpath entries (which are returned via IClasspathContributor)
|
||||
classpathEntries.put(project.name, FileDependency(classesJar.toFile().absolutePath))
|
||||
classpathEntries.put(project.name, FileDependency(classesJar))
|
||||
// Also add all the jar files found in the libs/ directory
|
||||
File(destDir, "libs").let { libsDir ->
|
||||
if (libsDir.exists()) {
|
||||
|
@ -188,7 +189,7 @@ public class AndroidPlugin @Inject constructor(val javaCompiler: JavaCompiler, v
|
|||
// Copy all the resources from this aar into the same intermediate directory
|
||||
log(2, "Copying the resources to $resDir")
|
||||
result.add(destDir)
|
||||
KFiles.copyRecursively(destDir.resolve("res"), resDir, deleteFirst = false)
|
||||
KFiles.copyRecursively(destDir.resolve("res"), resDir)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
@ -210,40 +211,13 @@ public class AndroidPlugin @Inject constructor(val javaCompiler: JavaCompiler, v
|
|||
*/
|
||||
override fun flagsFor(project: Project, currentFlags: List<String>) : List<String> {
|
||||
if (isAndroid(project)) {
|
||||
val result = arrayListOf<String>()
|
||||
var foundSource = false
|
||||
var foundTarget = false
|
||||
var noWarn = false
|
||||
var i = 0
|
||||
while (i < currentFlags.size) {
|
||||
with(currentFlags[i]) {
|
||||
if (this == "-source") {
|
||||
result.add(this)
|
||||
result.add(currentFlags[i + 1])
|
||||
i++
|
||||
foundSource = true
|
||||
} else if (this == "-target") {
|
||||
result.add(this)
|
||||
result.add(currentFlags[i + 1])
|
||||
i++
|
||||
foundTarget = true
|
||||
} else {
|
||||
result.add(this)
|
||||
}
|
||||
}
|
||||
i++
|
||||
}
|
||||
if (! foundSource) {
|
||||
var found = currentFlags.any { it == "-source" || it == "-target" }
|
||||
val result = arrayListOf<String>().apply { addAll(currentFlags) }
|
||||
if (! found) {
|
||||
result.add("-source")
|
||||
result.add("1.6")
|
||||
noWarn = true
|
||||
}
|
||||
if (! foundTarget) {
|
||||
result.add("-target")
|
||||
result.add("1.6")
|
||||
noWarn = true
|
||||
}
|
||||
if (noWarn) {
|
||||
result.add("-nowarn")
|
||||
}
|
||||
return result
|
||||
|
@ -286,12 +260,27 @@ public class AndroidPlugin @Inject constructor(val javaCompiler: JavaCompiler, v
|
|||
// java.exe -Xmx1024M -Dfile.encoding=windows-1252 -Duser.country=US -Duser.language=en -Duser.variant -cp D:\android\adt-bundle-windows-x86_64-20140321\sdk\build-tools\23.0.1\lib\dx.jar com.android.dx.command.Main --dex --verbose --num-threads=4 --output C:\Users\cbeust\android\android_hello_world\app\build\intermediates\dex\pro\debug C:\Users\cbeust\android\android_hello_world\app\build\intermediates\classes\pro\debug
|
||||
|
||||
val javaExecutable = JavaInfo.create(File(SystemProperties.javaBase)).javaExecutable!!
|
||||
RunCommand(javaExecutable.absolutePath).run(listOf(
|
||||
|
||||
val dependencies = dependencyManager.calculateDependencies(project, context, projects,
|
||||
project.compileDependencies).map {
|
||||
it.jarFile.get().path
|
||||
}.filterNot {
|
||||
it.contains("android.jar") || it.endsWith(".aar") || it.contains("com.android.support")
|
||||
|| it.contains("retrolambda")
|
||||
}.toHashSet().toTypedArray()
|
||||
|
||||
class DexCommand : RunCommand(javaExecutable.absolutePath) {
|
||||
override fun isSuccess(callSucceeded: Boolean, input: List<String>, error: List<String>) =
|
||||
error.size == 0
|
||||
}
|
||||
|
||||
DexCommand().run(listOf(
|
||||
"-cp", KFiles.joinDir(androidHome(project), "build-tools", buildToolsVersion(project), "lib", "dx.jar"),
|
||||
"com.android.dx.command.Main",
|
||||
"--dex", "--verbose", "--num-threads=4",
|
||||
"--output", outClassesDex,
|
||||
//KFiles.joinDir(intermediates(project), "dex", context.variant.toIntermediateDir()),
|
||||
*dependencies,
|
||||
// KFiles.joinDir(AndroidFiles.intermediates(project), "dex", context.variant.toIntermediateDir()),
|
||||
project.classesDir(context)
|
||||
))
|
||||
|
||||
|
@ -439,12 +428,14 @@ public class AndroidPlugin @Inject constructor(val javaCompiler: JavaCompiler, v
|
|||
* Automatically add the "aar" packaging for support libraries.
|
||||
*/
|
||||
// IClasspathInterceptor
|
||||
override fun intercept(dependencies: List<IClasspathDependency>): List<IClasspathDependency> {
|
||||
override fun intercept(project: Project, dependencies: List<IClasspathDependency>): List<IClasspathDependency> {
|
||||
val result = arrayListOf<IClasspathDependency>()
|
||||
dependencies.forEach {
|
||||
if (it is MavenDependency && it.groupId == "com.android.support") {
|
||||
if (it is MavenDependency && (it.groupId == "com.android.support" || it.mavenId.packaging == "aar")) {
|
||||
val newDep = FileDependency(AndroidFiles.classesJar(project, it.mavenId))
|
||||
result.add(newDep)
|
||||
val id = MavenId.create(it.groupId, it.artifactId, "aar", it.version)
|
||||
result.add(MavenDependency.create(id, executors.miscExecutor))
|
||||
result.add(MavenDependency.create(id))
|
||||
} else {
|
||||
result.add(it)
|
||||
}
|
||||
|
|
|
@ -91,7 +91,8 @@ class PackagingPlugin @Inject constructor(val dependencyManager : DependencyMana
|
|||
// The transitive closure of libraries goes into WEB-INF/libs.
|
||||
// Copy them all in kobaltBuild/war/WEB-INF/libs and create one IncludedFile out of that directory
|
||||
//
|
||||
val allDependencies = dependencyManager.transitiveClosure(project.compileDependencies)
|
||||
val allDependencies = dependencyManager.calculateDependencies(project, context, projects,
|
||||
project.compileDependencies)
|
||||
|
||||
val WEB_INF = "WEB-INF/lib"
|
||||
val outDir = project.buildDirectory + "/war"
|
||||
|
@ -268,7 +269,7 @@ class PackagingPlugin @Inject constructor(val dependencyManager : DependencyMana
|
|||
log(1, "Installing from $buildDir to ${config.libDir}")
|
||||
|
||||
val toDir = KFiles.makeDir(config.libDir)
|
||||
KFiles.copyRecursively(buildDirFile, toDir)
|
||||
KFiles.copyRecursively(buildDirFile, toDir, deleteFirst = true)
|
||||
}
|
||||
|
||||
return TaskResult()
|
||||
|
|
|
@ -34,7 +34,7 @@ class RetrolambdaPlugin @Inject constructor(val dependencyManager: DependencyMan
|
|||
override fun apply(project: Project, context: KobaltContext) {
|
||||
super.apply(project, context)
|
||||
taskContributor.addVariantTasks(this, project, context, "retrolambda", runTask = { taskRetrolambda(project) },
|
||||
alwaysRunAfter = listOf("compile"))
|
||||
runBefore = listOf("generateDex"), alwaysRunAfter = listOf("compile"))
|
||||
}
|
||||
|
||||
// IClasspathContributor
|
||||
|
@ -43,14 +43,16 @@ class RetrolambdaPlugin @Inject constructor(val dependencyManager: DependencyMan
|
|||
if (project != null && configurationFor(project) != null) listOf(JAR)
|
||||
else emptyList()
|
||||
|
||||
@Task(name = "retrolambda", description = "Run Retrolambda",
|
||||
@Task(name = "retrolambda", description = "Run Retrolambda", runBefore = arrayOf("generateDex"),
|
||||
alwaysRunAfter = arrayOf(JvmCompilerPlugin.TASK_COMPILE))
|
||||
fun taskRetrolambda(project: Project): TaskResult {
|
||||
val config = configurationFor(project)
|
||||
val result =
|
||||
if (config != null) {
|
||||
val classesDir = project.classesDir(context)
|
||||
val classpath = (dependencyManager.transitiveClosure(project.compileDependencies).map {
|
||||
val classpath = (dependencyManager.calculateDependencies(project, context, projects,
|
||||
project.compileDependencies)
|
||||
.map {
|
||||
it.jarFile.get()
|
||||
} + classesDir).joinToString(File.pathSeparator)
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue