gecko-dev/mobile/android/gradle/with_gecko_binaries.gradle
Nick Alexander bf575d403e Bug 1444546 - Part 4: Use GENERATED_FILES for Android JNI wrapper generation. r=froydnj,jchen
MozReview-Commit-ID: 1IjoQdEMqr8

--HG--
extra : rebase_source : 9f2e539328d83aa15bce0357a8c7d2722d517b2a
2018-03-06 20:09:37 -08:00

198 lines
8.2 KiB
Groovy

/* -*- Mode: Groovy; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// The omnijar inputs are listed as resource directory inputs to a dummy JAR.
// That arrangement labels them nicely in IntelliJ. See the comment in the
// :omnijar project for more context.
evaluationDependsOn(':omnijar')
// The JNI wrapper generation tasks depend on the JAR creation task of the :annotations project.
evaluationDependsOn(':annotations')
task buildOmnijars(type:Exec) {
dependsOn rootProject.generateCodeAndResources
// See comment in :omnijar project regarding interface mismatches here.
inputs.file(project(':omnijar').sourceSets.main.resources.srcDirs).skipWhenEmpty()
// Produce both the Fennec and the GeckoView omnijars.
outputs.file "${topobjdir}/dist/fennec/assets/omni.ja"
outputs.file "${topobjdir}/dist/geckoview/assets/omni.ja"
workingDir "${topobjdir}"
commandLine mozconfig.substs.GMAKE
args '-C'
args "${topobjdir}/mobile/android/base"
args 'gradle-omnijar'
// Only show the output if something went wrong.
ignoreExitValue = true
standardOutput = new ByteArrayOutputStream()
errorOutput = standardOutput
doLast {
if (execResult.exitValue != 0) {
throw new GradleException("Process '${commandLine}' finished with non-zero exit value ${execResult.exitValue}:\n\n${standardOutput.toString()}")
}
}
}
ext.configureVariantWithGeckoBinaries = { variant ->
// :app needs the full Fennec omni.ja, whereas other projects need the
// GeckoView-specific omni.ja.
def omnijar_dir = "app".equals(project.name) ? "fennec" : "geckoview"
def distDir = "${topobjdir}/dist/${omnijar_dir}"
def syncOmnijarFromDistDir = task("syncOmnijarFromDistDirFor${variant.name.capitalize()}", type: Sync) {
onlyIf {
if (source.empty) {
throw new StopExecutionException("Required omnijar not found in ${distDir}/{omni.ja,assets/omni.ja}. Have you built and packaged?")
}
return true
}
into("${project.buildDir}/moz.build/src/${variant.name}/omnijar")
from("${distDir}/omni.ja",
"${distDir}/assets/omni.ja") {
// Throw an exception if we find multiple, potentially conflicting omni.ja files.
duplicatesStrategy 'fail'
}
}
def syncLibsFromDistDir = task("syncLibsFromDistDirFor${variant.name.capitalize()}", type: Sync) {
onlyIf {
if (source.empty) {
throw new StopExecutionException("Required JNI libraries not found in ${distDir}/lib. Have you built and packaged?")
}
return true
}
into("${project.buildDir}/moz.build/src/${variant.name}/jniLibs")
from("${distDir}/lib")
}
def syncAssetsFromDistDir = task("syncAssetsFromDistDirFor${variant.name.capitalize()}", type: Sync) {
onlyIf {
if (source.empty) {
throw new StopExecutionException("Required assets not found in ${distDir}/assets. Have you built and packaged?")
}
return true
}
into("${project.buildDir}/moz.build/src/${variant.name}/assets")
from("${distDir}/assets") {
exclude 'omni.ja'
}
}
// Local (read, not 'official') builds want to reflect developer changes to
// the Omnijar sources. To do this, the Gradle build calls out to the
// moz.build system, which can be re-entrant. Official builds are driven by
// the moz.build system and should never be re-entrant in this way.
if (!((variant.productFlavors*.name).contains('official'))) {
syncOmnijarFromDistDir.dependsOn buildOmnijars
}
def assetGenTask = tasks.findByName("generate${variant.name.capitalize()}Assets")
if ((variant.productFlavors*.name).contains('withGeckoBinaries')) {
assetGenTask.dependsOn syncOmnijarFromDistDir
assetGenTask.dependsOn syncLibsFromDistDir
assetGenTask.dependsOn syncAssetsFromDistDir
android.sourceSets."${variant.name}".assets.srcDir syncOmnijarFromDistDir.destinationDir
android.sourceSets."${variant.name}".assets.srcDir syncAssetsFromDistDir.destinationDir
android.sourceSets."${variant.name}".jniLibs.srcDir syncLibsFromDistDir.destinationDir
}
}
ext.configureLibraryVariantWithJNIWrappers = { variant, module ->
// Library variants have two essentially independent transform* tasks:
//
// - ...WithSyncLibJars... is used by assemble* and bundle*
// - ...WithPrepareIntermediateJars... is used by consuming applications.
//
// It's not really possible to insert something immediately _after_
// ...WithPrepareIntermediateJars..., so we make the consuming moz.build
// system invoke this target directly, and force the
// ...WithPrepareIntermediateJars... dependency. The real consumer of the
// JNI wrappers is the moz.build system, which always builds geckoview to
// consume from Fennec, so that dependency likely adds less to the build time.
def jarTask = tasks["transformClassesAndResourcesWithPrepareIntermediateJarsFor${variant.name.capitalize()}"]
def output = jarTask.outputs.files.find({ it.absolutePath.contains('/classes.jar') })
def annotationProcessorsJarTask = project(':annotations').jar
def wrapperTask
if (System.env.IS_LANGUAGE_REPACK == '1') {
// Single-locale l10n repacks set `IS_LANGUAGE_REPACK=1` and don't
// really have a build environment.
wrapperTask = task("generateJNIWrappersFor${module}${variant.name.capitalize()}")
} else {
wrapperTask = task("generateJNIWrappersFor${module}${variant.name.capitalize()}", type: JavaExec) {
classpath annotationProcessorsJarTask.archivePath
// Configure the classpath at evaluation-time, not at
// configuration-time: see above comment.
doFirst {
classpath variant.javaCompile.classpath
// Include android.jar.
classpath variant.javaCompile.options.bootClasspath
}
main = 'org.mozilla.gecko.annotationProcessors.AnnotationProcessor'
args module
args output
workingDir "${topobjdir}/widget/android"
dependsOn jarTask
dependsOn annotationProcessorsJarTask
}
}
if (module == 'Generated') {
tasks["bundle${variant.name.capitalize()}"].dependsOn wrapperTask
} else {
tasks["assemble${variant.name.capitalize()}"].dependsOn wrapperTask
}
}
ext.configureApplicationVariantWithJNIWrappers = { variant, module ->
def jarTask = tasks["bundleAppClasses${variant.name.capitalize()}"]
def output = jarTask.outputs.files.find({ it.absolutePath.contains('/classes.jar') })
def annotationProcessorsJarTask = project(':annotations').jar
def wrapperTask
if (System.env.IS_LANGUAGE_REPACK == '1') {
// Single-locale l10n repacks set `IS_LANGUAGE_REPACK=1` and don't
// really have a build environment.
wrapperTask = task("generateJNIWrappersFor${module}${variant.name.capitalize()}")
} else {
wrapperTask = task("generateJNIWrappersFor${module}${variant.name.capitalize()}", type: JavaExec) {
classpath annotationProcessorsJarTask.archivePath
// Configure the classpath at evaluation-time, not at
// configuration-time: see above comment.
doFirst {
classpath variant.javaCompile.classpath
// Include android.jar.
classpath variant.javaCompile.options.bootClasspath
}
main = 'org.mozilla.gecko.annotationProcessors.AnnotationProcessor'
args module
args output
workingDir "${topobjdir}/widget/android/fennec"
// This forces bundling, which isn't usually part of the assemble* process.
dependsOn jarTask
dependsOn annotationProcessorsJarTask
}
}
}