25ba1f2b7d | ||
---|---|---|
.. | ||
gradle/wrapper | ||
src | ||
CHANGELOG.md | ||
LICENSE | ||
README.md | ||
build.gradle | ||
gradlew | ||
gradlew.bat |
README.md
Mozilla Application Services Gradle Plugin
Plugin for consuming Mozilla Application Services megazord native libraries.
Overview
Mozilla Application Services publishes many native (Rust) code libraries that stand alone: each
published Android ARchive (AAR) contains managed code (classes.jar
) and multiple .so
library
files (one for each supported architecture). That means consuming multiple such libraries entails
at least two .so
libraries, and each of those libraries includes the entire Rust standard library
as well as (potentially many) duplicated dependencies. To save space and allow cross-component
native-code Link Time Optimization (LTO, i.e., inlining, dead code elimination, etc) Application
Services also publishes composite libraries -- so called megazord libraries or just megazords --
that compose multiple Rust components into a single optimized .so
library file. The managed code
can be easily configured to use such a megazord without additional changes.
The org.mozilla.appservices
plugin makes it easy to consume such megazord libraries.
Configuration
appservices {
defaultConfig {
// Megazord in all Android variants. The default is to not megazord.
megazord = 'lockbox' // Or 'reference-browser', etc.
enableUnitTests = false // Defaults to true.
}
}
You can configure per Android variant, per Android product flavor, or per Android build type (in order of preference, i.e., a matching variant is preferred to a matching product flavor is preferred to a matching build type is preferred to the default config).
appservices {
variants {
stageDebug {
megazord = 'org.mozilla.appservices.megazord'
enableUnitTests = false // Defaults to true.
}
// Do not megazord or enable unit tests in other variants.
}
// overrides:
productFlavors {
stage {
megazord = 'org.mozilla.appservices.megazord'
}
// Do not megazord or enable unit tests in other product flavors.
}
// overrides:
buildTypes {
debug {
megazord = 'org.mozilla.appservices.megazord'
}
// Do not megazord or enable unit tests in release build type.
}
// overrides defaultConfig.
}
megazords
New megazord definitions can be defined, and existing megazord definitions modified, using the
megazords
block. For example, the existing "lockbox" megazord could be defined like:
appservices {
megazords {
lockbox {
moduleIdentifier 'org.mozilla.appservices:lockbox-megazord'
component 'org.mozilla.fxaclient:fxaclient'
component 'org.mozilla.sync15', 'logins'
}
}
}
while the existing "reference-browser" megazord could be modified to match the "lockbox" megazord like:
appservices {
megazords {
"reference-browser" {
moduleIdentifier 'org.mozilla.appservices:reference-browser-megazord'
components.clear()
component 'org.mozilla.fxaclient:fxaclient'
component 'org.mozilla.sync15:logins'
}
}
}
To reset the known Mozilla megazords:
appservices {
// Reset to the default megazord definitions.
setMozillaMegazords()
}
Development
To run the integration tests:
./gradlew -p gradle-plugin test
To publish locally, for testing against a consuming application:
./gradlew -p gradle-plugin publishToMavenLocal
Then use mavenLocal()
in the consuming application to find the updated version.
To publish to the Gradle plugin portal (requires credentials in $HOME/.gradle/gradle.properties
):
./gradlew -p gradle-plugin publishPlugin
Megazord Maven details
The megazord Maven publication is a shell Android ARchive (AAR) that contains a native library and
depends on special -withoutLibs
versions of the component modules. For example, we have:
org.mozilla.sync15/logins.aar
- classes.jar
- libs/liblogins_ffi.so
and a -withoutLibs
version, like:
org.mozilla.sync15-withoutLibs/logins-withoutLibs.aar
- classes.jar
and then a megazord like:
org.mozilla.appservices/lockbox-megazord.aar
- libs/liblockbox.so
The org.mozilla.appservices:lockbox-megazord
Maven publication then depends on
org.mozilla.sync15-withoutLibs:logins-withoutLibs
so that the JVM code (classes.jar
) is used but
the component module native library (libs/liblogins_ffi.so
) is not.
Pseudo-code details
For each Android variant variant
, the corresponding Gradle configurations
(variant.{compileConfiguration,runtimeConfiguration}
) have module substitutions applied, like:
// Pseudo-code!
configuration.resolutionStrategy.dependencySubstitution.all { dependency ->
if (dependency.isComponentModule()) {
dependency.useTarget('org.mozilla.appservices:example-megazord:...')
}
}
Application Services Maven repository details
The megazord libraries and dependencies aren't yet published to maven.mozilla.org (see issue #252) and for technical reasons they aren't yet mirrored to jcenter either (see this bintray plugin issue).
That means we need a non-standard Maven repository:
repositories {
maven {
name 'appservices'
url 'https://dl.bintray.com/ncalexander/application-services'
}
}
The Gradle plugin adds such needed repositories automatically.
Unit testing Rust native code
The Application Services Maven publications contain Rust native code targeting Android devices. To unit test against the provided functionality, we require an additional dependency that packages Rust native code for use on Desktop hosts and Java Native Access (JNA) internals in a form suitable for consuming in Robolectric unit tests.
Pseudo-code details
For unit testing support, for each test variant variant.unitTestVariant
, the corresponding Gradle
configurations (variant.unitTestVariant.{compileConfiguration,runtimeConfiguration}
) have
additional dependencies added, like:
// Pseudo-code!
dependencies {
configuration.name 'org.mozilla.places:places-forUnitTests:...'
}
When a megazord is used, the additional dependencies will be megazord-specific, like:
// Pseudo-code!
dependencies {
configuration.name 'org.mozilla.appservices:megazord-forUnitTests:...'
}