1
0
Fork 0
mirror of https://github.com/ethauvin/kobalt.git synced 2025-04-26 08:27:12 -07:00

Use android-builder to generate resources.

This commit is contained in:
Cedric Beust 2015-12-08 14:32:37 -08:00
parent 114a2b7a3a
commit e65e111ecb
7 changed files with 87 additions and 85 deletions

View file

@ -3,7 +3,6 @@ package com.beust.kobalt
import com.beust.kobalt.api.*
import com.beust.kobalt.misc.KFiles
import com.beust.kobalt.misc.log
import com.beust.kobalt.plugin.android.AndroidFiles
import com.beust.kobalt.plugin.android.AndroidPlugin
import java.io.File
@ -129,8 +128,6 @@ class Variant(val initialProductFlavor: ProductFlavorConfig? = null,
* respect the priorities). Return the generated file if it was generated, null otherwise.
*/
fun maybeGenerateBuildConfig(project: Project, context: KobaltContext) : File? {
fun generated(project: Project) = AndroidFiles.generatedSourceDir(project)
val buildConfigs = findBuildConfigs(project, context.variant)
if (buildConfigs.size > 0) {
@ -141,7 +138,7 @@ class Variant(val initialProductFlavor: ProductFlavorConfig? = null,
"packageName needs to be defined on the project in order to generate BuildConfig")
val code = project.projectInfo.generateBuildConfig(project, context, pkg, context.variant, buildConfigs)
val result = KFiles.makeDir(generated(project))
val result = KFiles.makeDir(KFiles.generatedSourceDir(project, context.variant, "buildConfig"))
// Make sure the generatedSourceDirectory doesn't contain the project.directory since
// that directory will be added when trying to find recursively all the sources in it
generatedSourceDirectory = File(result.relativeTo(File(project.directory)))

View file

@ -61,6 +61,7 @@ abstract class JvmCompilerPlugin @Inject constructor(
super.apply(project, context)
project.projectProperties.put(DEPENDENT_PROJECTS, projects())
taskContributor.addVariantTasks(this, project, context, "compile", runTask = { taskCompile(project) })
sourceDirectories.addAll(context.variant.sourceDirectories(project))
}
@Task(name = TASK_TEST, description = "Run the tests",
@ -135,8 +136,11 @@ abstract class JvmCompilerPlugin @Inject constructor(
@Task(name = JvmCompilerPlugin.TASK_COMPILE, description = "Compile the project")
fun taskCompile(project: Project) : TaskResult {
val generatedDir = context.variant.maybeGenerateBuildConfig(project, context)
val info = createCompilerActionInfo(project, context, generatedDir, isTest = false)
val sourceDirectory = context.variant.maybeGenerateBuildConfig(project, context)
if (sourceDirectory != null) {
sourceDirectories.add(sourceDirectory)
}
val info = createCompilerActionInfo(project, context, isTest = false)
val compiler = ActorUtils.selectAffinityActor(project, context, context.pluginInfo.compilerContributors)
if (compiler != null) {
return compiler.compile(project, context, info)
@ -151,7 +155,7 @@ abstract class JvmCompilerPlugin @Inject constructor(
fun taskJavadoc(project: Project) : TaskResult {
val docGenerator = ActorUtils.selectAffinityActor(project, context, context.pluginInfo.docContributors)
if (docGenerator != null) {
return docGenerator.generateDoc(project, context, createCompilerActionInfo(project, context, null,
return docGenerator.generateDoc(project, context, createCompilerActionInfo(project, context,
isTest = false))
} else {
warn("Couldn't find any doc contributor for project ${project.name}")
@ -163,8 +167,8 @@ abstract class JvmCompilerPlugin @Inject constructor(
* Create a CompilerActionInfo (all the information that a compiler needs to know) for the given parameters.
* Runs all the contributors and interceptors relevant to that task.
*/
protected fun createCompilerActionInfo(project: Project, context: KobaltContext, generatedSourceDir: File?,
isTest: Boolean) : CompilerActionInfo {
protected fun createCompilerActionInfo(project: Project, context: KobaltContext, isTest: Boolean) :
CompilerActionInfo {
copyResources(project, JvmCompilerPlugin.SOURCE_SET_MAIN)
val classpath = if (isTest)
@ -178,11 +182,6 @@ abstract class JvmCompilerPlugin @Inject constructor(
val initialSourceDirectories = arrayListOf<File>()
// Add the generated source dir if any
generatedSourceDir?.let {
initialSourceDirectories.add(it)
}
// Source directories from the contributors
initialSourceDirectories.addAll(
if (isTest) {
@ -213,8 +212,10 @@ abstract class JvmCompilerPlugin @Inject constructor(
return result
}
val sourceDirectories = arrayListOf<File>()
// ISourceDirectoryContributor
override fun sourceDirectoriesFor(project: Project, context: KobaltContext)
= if (accept(project)) context.variant.sourceDirectories(project) else listOf()
= if (accept(project)) sourceDirectories else arrayListOf()
}

View file

@ -2,6 +2,7 @@ package com.beust.kobalt.misc
import com.beust.kobalt.IFileSpec
import com.beust.kobalt.SystemProperties
import com.beust.kobalt.Variant
import com.beust.kobalt.api.Kobalt
import com.beust.kobalt.api.Project
import com.beust.kobalt.homeDir
@ -58,6 +59,13 @@ class KFiles {
val TEST_CLASSES_DIR : String = "test-classes"
private fun generatedDir(project: Project, variant: Variant)
= KFiles.joinDir(project.directory, project.buildDirectory, "generated", variant.toIntermediateDir())
fun generatedSourceDir(project: Project, variant: Variant, name: String) =
KFiles.joinDir(project.directory, project.buildDirectory, "generated", "source", name,
variant.toIntermediateDir())
/**
* Join the paths elements with the file separator.
*/

View file

@ -1,9 +1,12 @@
package com.beust.kobalt.plugin.android
import com.android.builder.core.AaptPackageProcessBuilder
import com.android.builder.core.AndroidBuilder
import com.android.builder.core.ErrorReporter
import com.android.builder.core.LibraryRequest
import com.android.builder.dependency.ManifestDependency
import com.android.builder.dependency.SymbolFileProvider
import com.android.builder.model.AaptOptions
import com.android.builder.model.SyncIssue
import com.android.builder.sdk.DefaultSdkLoader
import com.android.builder.sdk.SdkLoader
@ -67,7 +70,8 @@ class AndroidBuild {
// val annotationsJar = File("/Users/beust/adt-bundle-mac-x86_64-20140702/sdk/tools/lib/annotations.jar")
// val adb = File("/Users/beust/adt-bundle-mac-x86_64-20140702/sdk/platform-tools/adb")
fun run(project: Project, variant: Variant, config: AndroidConfig, aarDependencies: List<File>) {
fun run(project: Project, variant: Variant, config: AndroidConfig, aarDependencies: List<File>,
rDirectory: String) {
val logger = StdLogger(StdLogger.Level.VERBOSE)
val processExecutor = DefaultProcessExecutor(logger)
val javaProcessExecutor = KobaltJavaProcessExecutor()
@ -95,15 +99,6 @@ class AndroidBuild {
sdkLoader.getTargetInfo(maxPlatformTargetHash, maxPlatformTarget.buildToolInfo.revision, logger),
libraryRequests)
val writer = MergedResourceWriter(File(outputDir),
androidBuilder.getAaptCruncher(processOutputHandler),
false /* don't crunch */,
false /* don't process 9patch */,
layout.publicText,
layout.mergeBlame,
preprocessor)
val target = androidBuilder.target
val dxJar = androidBuilder.dxJar
val resourceMerger = ResourceMerger()
//
@ -114,7 +109,6 @@ class AndroidBuild {
aarDependencies.forEach {
val assetDir = File(it, "assets")
if (assetDir.exists()) {
println("COPY FROM $assetDir TO $intermediates")
KFiles.copyRecursively(assetDir, intermediates)
}
}
@ -168,7 +162,53 @@ class AndroidBuild {
resourceMerger.addDataSet(set)
}
val writer = MergedResourceWriter(File(outputDir),
androidBuilder.getAaptCruncher(processOutputHandler),
false /* don't crunch */,
false /* don't process 9patch */,
layout.publicText,
layout.mergeBlame,
preprocessor)
resourceMerger.mergeData(writer, true)
//
// Process resources
//
val aaptOptions = object : AaptOptions {
override fun getAdditionalParameters() = emptyList<String>()
override fun getFailOnMissingConfigEntry() = false
override fun getIgnoreAssets() = null
override fun getNoCompress() = null
}
val aaptCommand = AaptPackageProcessBuilder(File(AndroidFiles.mergedManifest(project, variant)),
aaptOptions)
fun toSymbolFileProvider(aarDirectory: File) = object: SymbolFileProvider {
override fun getManifest() = File(aarDirectory, "AndroidManifest.xml")
override fun isOptional() = false
override fun getSymbolFile() = File(aarDirectory, "R.txt")
}
val variantDir = variant.toIntermediateDir()
val generated = KFiles.joinAndMakeDir(project.directory, project.buildDirectory, "symbols")
with(aaptCommand) {
setSourceOutputDir(rDirectory)
val libraries = aarDependencies.map { toSymbolFileProvider(it) }
setLibraries(libraries)
val r = libraries[0].symbolFile
setResFolder(File(AndroidFiles.mergedResources(project, variant)))
setAssetsFolder(File(KFiles.joinAndMakeDir(AndroidFiles.intermediates(project), "assets", variantDir)))
aaptCommand.setResPackageOutput(AndroidFiles.temporaryApk(project, variant.shortArchiveName))
aaptCommand.setSymbolOutputDir(generated)
// aaptCommand.setSourceOutputDir(generated)
// aaptCommand.setPackageForR(pkg)
// aaptCommand.setProguardOutput(proguardTxt)
// aaptCommand.setType(if (lib) VariantType.LIBRARY else VariantType.DEFAULT)
// aaptCommand.setDebuggable(debug)
}
androidBuilder.processResources(aaptCommand, true, processOutputHandler)
}
}

View file

@ -9,8 +9,6 @@ import java.nio.file.Paths
class AndroidFiles {
companion object {
fun generated(project: Project) = KFiles.joinDir(project.directory, project.buildDirectory, "generated")
fun intermediates(project: Project) = KFiles.joinDir(project.directory, project.buildDirectory,
"intermediates")
@ -33,6 +31,12 @@ class AndroidFiles {
Paths.get(intermediates(project), "exploded-aar", mavenId.groupId, mavenId.artifactId, mavenId.version,
"classes.jar").toFile().path
fun classesDir(project: Project, variant: Variant): String =
KFiles.joinDir(project.directory, project.buildDirectory, variant.toIntermediateDir(), "classes")
fun temporaryApk(project: Project, flavor: String)
= KFiles.joinFileAndMakeDir(AndroidFiles.intermediates(project), "res", "resources$flavor.ap_")
/**
* Use the android home define on the project if any, otherwise use the environment variable.
*/
@ -48,6 +52,5 @@ class AndroidFiles {
fun androidHome(project: Project?, config: AndroidConfig) = androidHomeNoThrows(project, config) ?:
throw IllegalArgumentException("Neither androidHome nor \$ANDROID_HOME were defined")
fun generatedSourceDir(project: Project) = KFiles.joinDir(AndroidFiles.generated(project), "source")
}
}

View file

@ -82,9 +82,6 @@ public class AndroidPlugin @Inject constructor(val javaCompiler: JavaCompiler, v
private fun adb(project: Project) = "${androidHome(project)}/platform-tools/adb"
private fun temporaryApk(project: Project, flavor: String)
= KFiles.joinFileAndMakeDir(AndroidFiles.intermediates(project), "res", "resources$flavor.ap_")
private fun apk(project: Project, flavor: String)
= KFiles.joinFileAndMakeDir(project.buildDirectory, "outputs", "apk", "${project.name}$flavor.apk")
@ -94,13 +91,11 @@ public class AndroidPlugin @Inject constructor(val javaCompiler: JavaCompiler, v
val resDir = "temporaryBogusResDir"
val aarDependencies = explodeAarFiles(project, File(resDir))
AndroidBuild().run(project, context.variant, configurationFor(project)!!, aarDependencies)
// merger.merge(project, context)
val rDirectory = KFiles.joinAndMakeDir(KFiles.generatedSourceDir(project, context.variant, "r"))
extraSourceDirectories.add(File(rDirectory))
AndroidBuild().run(project, context.variant, configurationFor(project)!!, aarDependencies, rDirectory)
val notUsed = ""
val generated = AndroidFiles.generated(project)
val success = generateR(project, generated, aapt(project))
return TaskResult(success)
return TaskResult(true)
}
/**
@ -117,46 +112,6 @@ public class AndroidPlugin @Inject constructor(val javaCompiler: JavaCompiler, v
override fun call(args: List<String>) = super.run(arrayListOf(aaptCommand) + args)
}
private fun generateR(project: Project, generated: String, aapt: String) : Boolean {
val compileSdkVersion = compileSdkVersion(project)
val androidJar = Paths.get(androidHome(project), "platforms", "android-$compileSdkVersion", "android.jar")
val applicationId = configurationFor(project)?.applicationId!!
val intermediates = AndroidFiles.intermediates(project)
// AaptCommand(project, aapt, "crunch").call(listOf(
// "-v",
// "-C", mergedResources(project, context.variant),
// "-S", crunchedPngDir
// ))
val variantDir = context.variant.toIntermediateDir()
val rDirectory = KFiles.joinAndMakeDir(generated, "source", "r", variantDir).toString()
val result = AaptCommand(project, aapt, "package").call(listOf(
"-f",
"--no-crunch",
"-I", androidJar.toString(),
"-M", AndroidFiles.mergedManifest(project, context.variant),
"-S", AndroidFiles.mergedResources(project, context.variant),
// where to find more assets
"-A", KFiles.joinAndMakeDir(intermediates, "assets", variantDir),
"-m", // create directory
// where all gets generated
"-J", rDirectory,
"-F", temporaryApk(project, context.variant.shortArchiveName),
"--debug-mode",
"-0", "apk",
"--auto-add-overlay",
"--custom-package", applicationId
// "--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))
return result == 0
}
/**
* 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.
@ -196,7 +151,7 @@ public class AndroidPlugin @Inject constructor(val javaCompiler: JavaCompiler, v
private fun compile(project: Project, rDirectory: String): File {
val sourceFiles = arrayListOf(Paths.get(rDirectory, "R.java").toFile().path)
val buildDir = File(AndroidFiles.generated(project), "classes")
val buildDir = File(AndroidFiles.classesDir(project, context.variant))
// Using a directory of "." since the project.directory is already present in buildDir
val cai = CompilerActionInfo(".", listOf(), sourceFiles, buildDir, listOf(
"-source", "1.6", "-target", "1.6"))
@ -257,8 +212,6 @@ public class AndroidPlugin @Inject constructor(val javaCompiler: JavaCompiler, v
val classesDex = "classes.dex"
val outClassesDex = KFiles.joinDir(classesDexDir, classesDex)
// 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!!
val dependencies = dependencyManager.calculateDependencies(project, context, projects,
@ -292,7 +245,7 @@ public class AndroidPlugin @Inject constructor(val javaCompiler: JavaCompiler, v
AaptCommand(project, aapt(project), "add").apply {
directory = File(outClassesDex).parentFile
}.call(listOf("-v", KFiles.joinDir(
File(temporaryApk(project, context.variant.shortArchiveName)).absolutePath), classesDex))
File(AndroidFiles.temporaryApk(project, context.variant.shortArchiveName)).absolutePath), classesDex))
return TaskResult()
}
@ -313,7 +266,7 @@ public class AndroidPlugin @Inject constructor(val javaCompiler: JavaCompiler, v
runBefore = arrayOf("assemble"))
fun taskSignApk(project: Project): TaskResult {
val apk = apk(project, context.variant.shortArchiveName)
val temporaryApk = temporaryApk(project, context.variant.shortArchiveName)
val temporaryApk = AndroidFiles.temporaryApk(project, context.variant.shortArchiveName)
val buildType = context.variant.buildType.name
val config = configurationFor(project)

View file

@ -54,7 +54,7 @@ class JavaPlugin @Inject constructor(
runAfter = arrayOf(JvmCompilerPlugin.TASK_COMPILE))
fun taskCompileTest(project: Project): TaskResult {
copyResources(project, JvmCompilerPlugin.SOURCE_SET_TEST)
val compilerActionInfo = createCompilerActionInfo(project, context, null, isTest = true)
val compilerActionInfo = createCompilerActionInfo(project, context, isTest = true)
val result = javaCompiler.compile(project, context, compilerActionInfo)
return result
}