mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-17 15:25:52 +00:00
455 lines
19 KiB
Groovy
455 lines
19 KiB
Groovy
buildDir "${topobjdir}/gradle/build/mobile/android/geckoview"
|
|
|
|
apply plugin: 'com.android.library'
|
|
apply plugin: 'kotlin-android'
|
|
|
|
apply from: "${topsrcdir}/mobile/android/gradle/product_flavors.gradle"
|
|
|
|
// The SDK binding generation tasks depend on the JAR creation task of the
|
|
// :annotations project.
|
|
evaluationDependsOn(':annotations')
|
|
|
|
// Non-official versions are like "61.0a1", where "a1" is the milestone.
|
|
// This simply strips that off, leaving "61.0" in this example.
|
|
def getAppVersionWithoutMilestone() {
|
|
return mozconfig.substs.MOZ_APP_VERSION.replaceFirst(/a[0-9]/, "")
|
|
}
|
|
|
|
// This converts MOZ_APP_VERSION into an integer
|
|
// version code.
|
|
//
|
|
// We take something like 58.1.2a1 and come out with 5800102
|
|
// This gives us 3 digits for the major number, and 2 digits
|
|
// each for the minor and build number. Beta and Release
|
|
def computeVersionCode() {
|
|
String appVersion = getAppVersionWithoutMilestone()
|
|
|
|
// Split on the dot delimiter, e.g. 58.1.1a1 -> ["58, "1", "1a1"]
|
|
String[] parts = appVersion.split('\\.')
|
|
|
|
assert parts.size() == 2 || parts.size() == 3
|
|
|
|
// Major
|
|
int code = Integer.parseInt(parts[0]) * 100000
|
|
|
|
// Minor
|
|
code += Integer.parseInt(parts[1]) * 100
|
|
|
|
// Build
|
|
if (parts.size() == 3) {
|
|
code += Integer.parseInt(parts[2])
|
|
}
|
|
|
|
return code;
|
|
}
|
|
|
|
def computeVersionNumber() {
|
|
def appVersion = getAppVersionWithoutMilestone()
|
|
def parts = appVersion.split('\\.')
|
|
return parts[0] + "." + parts[1] + "." + getBuildId()
|
|
}
|
|
|
|
// Mimic Python: open(os.path.join(buildconfig.topobjdir, 'buildid.h')).readline().split()[2]
|
|
def getBuildId() {
|
|
return file("${topobjdir}/buildid.h").getText('utf-8').split()[2]
|
|
}
|
|
|
|
android {
|
|
compileSdkVersion project.ext.compileSdkVersion
|
|
|
|
defaultConfig {
|
|
targetSdkVersion project.ext.targetSdkVersion
|
|
minSdkVersion project.ext.minSdkVersion
|
|
manifestPlaceholders = project.ext.manifestPlaceholders
|
|
|
|
versionCode computeVersionCode()
|
|
versionName "${mozconfig.substs.MOZ_APP_VERSION}-${mozconfig.substs.MOZ_UPDATE_CHANNEL}"
|
|
consumerProguardFiles 'proguard-rules.txt'
|
|
|
|
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
|
|
|
buildConfigField 'String', "GRE_MILESTONE", "\"${mozconfig.substs.GRE_MILESTONE}\""
|
|
// This should really come from the included binaries, but that's not easy.
|
|
buildConfigField 'String', "MOZ_APP_ABI", mozconfig.substs['COMPILE_ENVIRONMENT'] ? "\"${ mozconfig.substs.TARGET_XPCOM_ABI}\"" : '"arm-eabi-gcc3"';
|
|
buildConfigField 'String', "MOZ_APP_BASENAME", "\"${mozconfig.substs.MOZ_APP_BASENAME}\"";
|
|
|
|
// For the benefit of future archaeologists:
|
|
// GRE_BUILDID is exactly the same as MOZ_APP_BUILDID unless you're running
|
|
// on XULRunner, which is never the case on Android.
|
|
buildConfigField 'String', "MOZ_APP_BUILDID", "\"${getBuildId()}\"";
|
|
buildConfigField 'String', "MOZ_APP_ID", "\"${mozconfig.substs.MOZ_APP_ID}\"";
|
|
buildConfigField 'String', "MOZ_APP_NAME", "\"${mozconfig.substs.MOZ_APP_NAME}\"";
|
|
buildConfigField 'String', "MOZ_APP_VENDOR", "\"${mozconfig.substs.MOZ_APP_VENDOR}\"";
|
|
buildConfigField 'String', "MOZ_APP_VERSION", "\"${mozconfig.substs.MOZ_APP_VERSION}\"";
|
|
buildConfigField 'String', "MOZ_APP_DISPLAYNAME", "\"${mozconfig.substs.MOZ_APP_DISPLAYNAME}\"";
|
|
buildConfigField 'String', "MOZ_APP_UA_NAME", "\"${mozconfig.substs.MOZ_APP_UA_NAME}\"";
|
|
buildConfigField 'String', "MOZ_UPDATE_CHANNEL", "\"${mozconfig.substs.MOZ_UPDATE_CHANNEL}\"";
|
|
|
|
// MOZILLA_VERSION is oddly quoted from autoconf, but we don't have to handle it specially in Gradle.
|
|
buildConfigField 'String', "MOZILLA_VERSION", "\"${mozconfig.substs.MOZILLA_VERSION}\"";
|
|
buildConfigField 'String', "OMNIJAR_NAME", "\"${mozconfig.substs.OMNIJAR_NAME}\"";
|
|
|
|
buildConfigField 'String', "USER_AGENT_GECKOVIEW_MOBILE", "\"Mozilla/5.0 (Android \" + android.os.Build.VERSION.RELEASE + \"; Mobile; rv: ${mozconfig.substs.MOZ_APP_VERSION}) Gecko/${mozconfig.substs.MOZ_APP_VERSION} GeckoView/${mozconfig.substs.MOZ_APP_VERSION}\"";
|
|
buildConfigField 'String', "USER_AGENT_GECKOVIEW_TABLET", "\"Mozilla/5.0 (Android \" + android.os.Build.VERSION.RELEASE + \"; Tablet; rv: ${mozconfig.substs.MOZ_APP_VERSION}) Gecko/${mozconfig.substs.MOZ_APP_VERSION} GeckoView/${mozconfig.substs.MOZ_APP_VERSION}\"";
|
|
|
|
buildConfigField 'String', "ANDROID_CPU_ARCH", "\"${mozconfig.substs.ANDROID_CPU_ARCH}\"";
|
|
|
|
buildConfigField 'int', 'MIN_SDK_VERSION', mozconfig.substs.MOZ_ANDROID_MIN_SDK_VERSION;
|
|
|
|
// Is the underlying compiled C/C++ code compiled with --enable-debug?
|
|
buildConfigField 'boolean', 'DEBUG_BUILD', mozconfig.substs.MOZ_DEBUG ? 'true' : 'false';
|
|
|
|
// See this wiki page for more details about channel specific build defines:
|
|
// https://wiki.mozilla.org/Platform/Channel-specific_build_defines
|
|
// This makes no sense for GeckoView and should be removed as soon as possible.
|
|
buildConfigField 'boolean', 'RELEASE_OR_BETA', mozconfig.substs.RELEASE_OR_BETA ? 'true' : 'false';
|
|
// This makes no sense for GeckoView and should be removed as soon as possible.
|
|
buildConfigField 'boolean', 'NIGHTLY_BUILD', mozconfig.substs.NIGHTLY_BUILD ? 'true' : 'false';
|
|
// This makes no sense for GeckoView and should be removed as soon as possible.
|
|
buildConfigField 'boolean', 'MOZ_CRASHREPORTER', mozconfig.substs.MOZ_CRASHREPORTER ? 'true' : 'false';
|
|
|
|
// Official corresponds, roughly, to whether this build is performed on
|
|
// Mozilla's continuous integration infrastructure. You should disable
|
|
// developer-only functionality when this flag is set.
|
|
// This makes no sense for GeckoView and should be removed as soon as possible.
|
|
buildConfigField 'boolean', 'MOZILLA_OFFICIAL', mozconfig.substs.MOZILLA_OFFICIAL ? 'true' : 'false';
|
|
}
|
|
|
|
project.configureProductFlavors.delegate = it
|
|
project.configureProductFlavors()
|
|
|
|
compileOptions {
|
|
sourceCompatibility JavaVersion.VERSION_1_8
|
|
targetCompatibility JavaVersion.VERSION_1_8
|
|
}
|
|
|
|
dexOptions {
|
|
javaMaxHeapSize "2g"
|
|
}
|
|
|
|
lintOptions {
|
|
abortOnError false
|
|
}
|
|
|
|
sourceSets {
|
|
main {
|
|
java {
|
|
srcDir "${topsrcdir}/mobile/android/geckoview/src/thirdparty/java"
|
|
|
|
if (!mozconfig.substs.MOZ_ANDROID_HLS_SUPPORT) {
|
|
exclude 'com/google/android/exoplayer2/**'
|
|
exclude 'org/mozilla/gecko/media/GeckoHlsAudioRenderer.java'
|
|
exclude 'org/mozilla/gecko/media/GeckoHlsPlayer.java'
|
|
exclude 'org/mozilla/gecko/media/GeckoHlsRendererBase.java'
|
|
exclude 'org/mozilla/gecko/media/GeckoHlsVideoRenderer.java'
|
|
exclude 'org/mozilla/gecko/media/Utils.java'
|
|
}
|
|
|
|
if (mozconfig.substs.MOZ_WEBRTC) {
|
|
srcDir "${topsrcdir}/media/webrtc/trunk/webrtc/base/java/src"
|
|
srcDir "${topsrcdir}/media/webrtc/trunk/webrtc/modules/audio_device/android/java/src"
|
|
srcDir "${topsrcdir}/media/webrtc/trunk/webrtc/modules/video_capture/android/java/src"
|
|
}
|
|
}
|
|
|
|
assets {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile) {
|
|
// Translate Kotlin messages like "w: ..." and "e: ..." into
|
|
// "...: warning: ..." and "...: error: ...", to make Treeherder understand.
|
|
def listener = {
|
|
if (it.startsWith('w: ') || it.startsWith('e: ')) {
|
|
def matches = (it =~ /([ew]): (.+): \((\d+), (\d+)\): (.*)/)
|
|
if (!matches) {
|
|
logger.quiet "kotlinc message format has changed!"
|
|
if (it.startsWith('w: ')) {
|
|
// For warnings, don't continue because we don't want to throw an
|
|
// exception. For errors, we want the exception so that the new error
|
|
// message format gets translated properly.
|
|
return
|
|
}
|
|
}
|
|
def (_, type, file, line, column, message) = matches[0]
|
|
type = (type == 'w') ? 'warning' : 'error'
|
|
// Use logger.lifecycle, which does not go through stderr again.
|
|
logger.lifecycle "$file:$line:$column: $type: $message"
|
|
}
|
|
} as StandardOutputListener
|
|
|
|
kotlinOptions {
|
|
allWarningsAsErrors = true
|
|
}
|
|
|
|
doFirst {
|
|
logging.addStandardErrorListener(listener)
|
|
}
|
|
doLast {
|
|
logging.removeStandardErrorListener(listener)
|
|
}
|
|
}
|
|
|
|
tasks.withType(Javadoc) {
|
|
// Implement warning-as-error for javadoc.
|
|
def warnings = 0
|
|
def listener = {
|
|
if (it.contains(': warning')) {
|
|
warnings++
|
|
}
|
|
} as StandardOutputListener
|
|
|
|
doFirst {
|
|
logging.addStandardErrorListener(listener)
|
|
}
|
|
doLast {
|
|
logging.removeStandardErrorListener(listener)
|
|
if (warnings > 0) {
|
|
throw new GradleException("Treating $warnings javadoc warning(s) as error(s)")
|
|
}
|
|
}
|
|
}
|
|
|
|
dependencies {
|
|
implementation "com.android.support:support-v4:$support_library_version"
|
|
implementation "com.android.support:palette-v7:$support_library_version"
|
|
|
|
testImplementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
|
|
testImplementation 'junit:junit:4.12'
|
|
testImplementation 'org.robolectric:robolectric:3.8'
|
|
testImplementation 'org.mockito:mockito-core:1.10.19'
|
|
|
|
androidTestImplementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
|
|
androidTestImplementation 'com.android.support.test:runner:1.0.1'
|
|
androidTestImplementation 'com.android.support.test:rules:1.0.1'
|
|
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
|
|
androidTestImplementation "com.android.support:support-annotations:$support_library_version"
|
|
}
|
|
|
|
apply from: "${topsrcdir}/mobile/android/gradle/with_gecko_binaries.gradle"
|
|
|
|
android.libraryVariants.all { variant ->
|
|
// See the notes in mobile/android/app/build.gradle for details on including
|
|
// Gecko binaries and the Omnijar.
|
|
if ((variant.productFlavors*.name).contains('withGeckoBinaries')) {
|
|
configureVariantWithGeckoBinaries(variant)
|
|
}
|
|
|
|
// Javadoc and Sources JAR configuration cribbed from
|
|
// https://github.com/mapbox/mapbox-gl-native/blob/d169ea55c1cfa85cd8bf19f94c5f023569f71810/platform/android/MapboxGLAndroidSDK/build.gradle#L85
|
|
// informed by
|
|
// https://code.tutsplus.com/tutorials/creating-and-publishing-an-android-library--cms-24582,
|
|
// and amended from numerous Stackoverflow posts.
|
|
def name = variant.name
|
|
def javadoc = task "javadoc${name.capitalize()}"(type: Javadoc) {
|
|
description = "Generate Javadoc for build variant $name"
|
|
destinationDir = new File(destinationDir, variant.baseName)
|
|
doFirst {
|
|
classpath = files(variant.javaCompile.classpath.files)
|
|
}
|
|
|
|
source = files(variant.javaCompile.source)
|
|
exclude '**/R.java', '**/BuildConfig.java'
|
|
include 'org/mozilla/geckoview/**'
|
|
options.addPathOption('sourcepath', ':').setValue(
|
|
variant.sourceSets.collect({ it.javaDirectories }).flatten() +
|
|
variant.generateBuildConfig.sourceOutputDir +
|
|
variant.aidlCompile.sourceOutputDir)
|
|
|
|
// javadoc 8 has a bug that requires the rt.jar file from the JRE to be
|
|
// in the bootclasspath (https://stackoverflow.com/a/30458820).
|
|
options.bootClasspath = [
|
|
file("${System.properties['java.home']}/lib/rt.jar")] + android.bootClasspath
|
|
options.memberLevel = JavadocMemberLevel.PROTECTED
|
|
options.source = 7
|
|
options.links("https://d.android.com/reference/")
|
|
|
|
options.docTitle = "GeckoView ${mozconfig.substs.MOZ_APP_VERSION} API"
|
|
options.header = "GeckoView ${mozconfig.substs.MOZ_APP_VERSION} API"
|
|
options.noTimestamp = true
|
|
options.noIndex = true
|
|
options.noQualifiers = ['java.lang']
|
|
options.tags = ['hide:a:']
|
|
}
|
|
|
|
def javadocJar = task("javadocJar${name.capitalize()}", type: Jar, dependsOn: javadoc) {
|
|
classifier = 'javadoc'
|
|
from javadoc.destinationDir
|
|
}
|
|
|
|
def sourcesJar = task("sourcesJar${name.capitalize()}", type: Jar) {
|
|
classifier 'sources'
|
|
description = "Generate Javadoc for build variant $name"
|
|
destinationDir = new File(destinationDir, variant.baseName)
|
|
from files(variant.javaCompile.source)
|
|
}
|
|
}
|
|
|
|
android.libraryVariants.all { variant ->
|
|
configureLibraryVariantWithJNIWrappers(variant, "Generated")
|
|
}
|
|
|
|
apply plugin: 'maven'
|
|
|
|
uploadArchives {
|
|
repositories.mavenDeployer {
|
|
pom.groupId = 'org.mozilla.geckoview'
|
|
pom.artifactId = "geckoview-${mozconfig.substs.MOZ_UPDATE_CHANNEL}-${mozconfig.substs.ANDROID_CPU_ARCH}"
|
|
pom.version = computeVersionNumber()
|
|
|
|
pom.project {
|
|
licenses {
|
|
license {
|
|
name 'The Mozilla Public License, v. 2.0'
|
|
url 'http://mozilla.org/MPL/2.0/'
|
|
distribution 'repo'
|
|
}
|
|
}
|
|
}
|
|
repository(url: "file://${project.buildDir}/maven")
|
|
}
|
|
}
|
|
|
|
// This is all related to the withGeckoBinaries approach; see
|
|
// mobile/android/gradle/with_gecko_binaries.gradle.
|
|
afterEvaluate {
|
|
// The bundle tasks are only present when the particular configuration is
|
|
// being built, so this task might not exist. (This is due to the way the
|
|
// Android Gradle plugin defines things during configuration.)
|
|
def bundleWithGeckoBinaries = tasks.findByName('bundleOfficialWithGeckoBinariesNoMinApiRelease')
|
|
if (!bundleWithGeckoBinaries) {
|
|
return
|
|
}
|
|
|
|
// Remove default configuration, which is the release configuration, when
|
|
// we're actually building withGeckoBinaries. This makes `gradle install`
|
|
// install the withGeckoBinaries artifacts, not the release artifacts (which
|
|
// are withoutGeckoBinaries and not suitable for distribution.)
|
|
def Configuration archivesConfig = project.getConfigurations().getByName('archives')
|
|
archivesConfig.artifacts.removeAll { it.extension.equals('aar') }
|
|
|
|
artifacts {
|
|
// Instead of default (release) configuration, publish one with Gecko binaries.
|
|
archives bundleOfficialWithGeckoBinariesNoMinApiRelease
|
|
// Javadoc and sources for developer ergononomics.
|
|
archives javadocJarOfficialWithGeckoBinariesNoMinApiRelease
|
|
archives sourcesJarOfficialWithGeckoBinariesNoMinApiRelease
|
|
}
|
|
|
|
// For now, ensure Kotlin is only used in tests.
|
|
android.sourceSets.all { sourceSet ->
|
|
if (sourceSet.name.startsWith('test') || sourceSet.name.startsWith('androidTest')) {
|
|
return
|
|
}
|
|
(sourceSet.java.srcDirs + sourceSet.kotlin.srcDirs).each {
|
|
if (!fileTree(it, { include '**/*.kt' }).empty) {
|
|
throw new GradleException("Kotlin used in non-test directory ${it.path}")
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Bug 1353055 - Strip 'vars' debugging information to agree with moz.build.
|
|
apply from: "${topsrcdir}/mobile/android/gradle/debug_level.gradle"
|
|
android.libraryVariants.all configureVariantDebugLevel
|
|
|
|
// There's nothing specific to the :geckoview project here -- this just needs to
|
|
// be somewhere where the Android plugin is available so that we can fish the
|
|
// path to "android.jar".
|
|
task("generateSDKBindings", type: JavaExec) {
|
|
classpath project(':annotations').jar.archivePath
|
|
classpath project(':annotations').compileJava.classpath
|
|
|
|
// To use the lint APIs: "Lint must be invoked with the System property
|
|
// com.android.tools.lint.bindir pointing to the ANDROID_SDK tools
|
|
// directory"
|
|
systemProperties = [
|
|
'com.android.tools.lint.bindir': "${android.sdkDirectory}/tools",
|
|
]
|
|
|
|
main = 'org.mozilla.gecko.annotationProcessors.SDKProcessor'
|
|
args android.bootClasspath
|
|
args 16
|
|
args "${topobjdir}/widget/android/bindings"
|
|
|
|
// Configure the arguments at evaluation-time, not at configuration-time.
|
|
doFirst {
|
|
// From -Pgenerate_sdk_bindings_args=... on command line.
|
|
args project.generate_sdk_bindings_args.split(':')
|
|
}
|
|
|
|
workingDir "${topsrcdir}/widget/android/bindings"
|
|
|
|
dependsOn project(':annotations').jar
|
|
}
|
|
|
|
apply from: "${topsrcdir}/mobile/android/gradle/jacoco_dependencies.gradle"
|
|
if (project.hasProperty('enable_code_coverage')) {
|
|
apply from: "${topsrcdir}/mobile/android/gradle/jacoco_for_junit.gradle"
|
|
}
|
|
|
|
// Set up code coverage for tests on emulators.
|
|
if (mozconfig.substs.MOZ_JAVA_CODE_COVERAGE) {
|
|
android {
|
|
jacoco {
|
|
version = "$jacoco_version"
|
|
}
|
|
buildTypes {
|
|
debug {
|
|
testCoverageEnabled true
|
|
}
|
|
}
|
|
}
|
|
|
|
configurations {
|
|
// This configuration is used for dependencies that are not needed at compilation or
|
|
// runtime, but need to be exported as artifacts of the build for usage on the testing
|
|
// machines.
|
|
coverageDependency
|
|
}
|
|
|
|
dependencies {
|
|
// This is required both in the instrumented application classes and the test classes,
|
|
// so `api` has to be used instead of `androidTestImplementation`.
|
|
api "org.jacoco:org.jacoco.agent:$jacoco_version:runtime"
|
|
|
|
coverageDependency ("org.jacoco:org.jacoco.cli:$jacoco_version:nodeps") {
|
|
exclude group: 'org.ow2.asm', module: '*'
|
|
}
|
|
}
|
|
|
|
// This task is used by `mach android archive-coverage-artifacts`.
|
|
task copyCoverageDependencies(type: Copy) {
|
|
from(configurations.coverageDependency) {
|
|
include 'org.jacoco.cli-*-nodeps.jar'
|
|
rename { _ -> 'target.jacoco-cli.jar' }
|
|
}
|
|
into "$buildDir/coverage"
|
|
}
|
|
|
|
// Generate tasks to archive compiled classfiles for later use with JaCoCo report generation.
|
|
// One of these tasks is used by `mach android archive-coverage-artifacts`.
|
|
android.libraryVariants.all { variant ->
|
|
def name = variant.name
|
|
def compileTask = tasks.getByName("compile${name.capitalize()}JavaWithJavac")
|
|
task "archiveClassfiles${name.capitalize()}"(type: Zip, dependsOn: compileTask) {
|
|
description = "Archive compiled classfiles for $name in order to export them as code coverage artifacts."
|
|
def fileFilter = ['**/androidTest/**',
|
|
'**/test/**',
|
|
'**/R.class',
|
|
'**/R$*.class',
|
|
'**/BuildConfig.*',
|
|
'**/Manifest*.*',
|
|
'**/*Test*.*',
|
|
'android/**/*.*']
|
|
from fileTree(dir: compileTask.destinationDir, excludes: fileFilter)
|
|
destinationDir = file("${buildDir}/coverage")
|
|
// Note: This task assumes only one variant of archiveClassfiles* will be used.
|
|
// Running multiple variants of this task will overwrite the output archive.
|
|
archiveName = 'target.geckoview_classfiles.zip'
|
|
}
|
|
}
|
|
}
|