Fix taskcluster breakage from #6524
Build a JAR file with libjnidispatch and libmegazord, targetted at Desktop arches so that devs can run unit tests with it. Export this as a configuration and Maven package. This allows android-components code to run the unit tests and also simplifies the gradle code for our own components. Named this full-megazord-libsForTest, which I think is a bit more clear than full-megazord-forUnitTests.
This commit is contained in:
Родитель
83ad69b756
Коммит
176f82f69d
|
@ -127,7 +127,7 @@ projects:
|
|||
publications:
|
||||
- name: full-megazord
|
||||
type: aar
|
||||
- name: full-megazord-forUnitTests
|
||||
- name: full-megazord-libsForTests
|
||||
type: jar
|
||||
description: Megazord containing all features
|
||||
tooling-nimbus-gradle:
|
||||
|
|
|
@ -60,21 +60,11 @@ ext.dependsOnTheMegazord = {
|
|||
api project(":full-megazord")
|
||||
|
||||
// Add a JNA dependency, which is required by UniFFI.
|
||||
//
|
||||
// The tricky thing is getting the correct libjnidispatch library. Use the AAR version for
|
||||
// normal builds, since that ensures the various Android libraries get packaged correctly when
|
||||
// we build our own AAR. Use the JAR version for tests, since that ensures the tests can load
|
||||
// the native version.
|
||||
implementation(libs.jna) {
|
||||
artifact {
|
||||
type = "aar"
|
||||
}
|
||||
}
|
||||
testImplementation(libs.jna) {
|
||||
artifact {
|
||||
type = "jar"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Configurations are a somewhat mysterious Gradle concept. For our purposes, we can treat them
|
||||
|
@ -85,33 +75,15 @@ ext.dependsOnTheMegazord = {
|
|||
}
|
||||
}
|
||||
|
||||
// Wire up the megazordNative configuration to the output produced from the `full-megazord` project.
|
||||
dependencies {
|
||||
megazordNative(project("path": ":full-megazord", "configuration": "megazordNative"))
|
||||
megazordNative project("path": ":full-megazord", "configuration": "megazordNative")
|
||||
implementation project("path": ":full-megazord", "configuration": "libsForTests")
|
||||
}
|
||||
|
||||
afterEvaluate {
|
||||
android.libraryVariants.all { variant ->
|
||||
def variantName = variant.name.capitalize();
|
||||
def testTask = tasks["test${variantName}UnitTest"]
|
||||
def processTestResTask = tasks["process${variantName}UnitTestJavaRes"]
|
||||
|
||||
// Copy the native libmegazord to the resource dir so that it can be loaded by JNA.
|
||||
// Note: we have to manually copy the library to the output dir ourselves. If we simply
|
||||
// added the megazordNative directory to sourceSets.test.resources.srcDirs, then the
|
||||
// android gradle plugin will refuse to copy it. For details see:
|
||||
//
|
||||
// * https://github.com/mozilla/application-services/pull/6476#issuecomment-2537227576
|
||||
// * https://github.com/mozilla/glean/pull/2680#issuecomment-2056627683
|
||||
def copyNativeMegazord = tasks.register("copy${variantName}NativeMegazord", Copy) {
|
||||
from configurations.getByName("megazordNative")
|
||||
into processTestResTask.destinationDir
|
||||
// Make sure to run after the process java res task, otherwise that one may
|
||||
// overwrite our work.
|
||||
dependsOn(processTestResTask)
|
||||
}
|
||||
|
||||
testTask.dependsOn(copyNativeMegazord)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -130,10 +102,9 @@ ext.configureUniFFIBindgen = { crateName ->
|
|||
// Call `uniffi-bindgen` to generate the Kotlin bindings
|
||||
def generateUniffiBindings = tasks.register("generateUniffiBindings") {
|
||||
def megazordNative = configurations.getByName("megazordNative")
|
||||
|
||||
doFirst {
|
||||
def libraryPath = megazordNative.asFileTree.matching {
|
||||
include "**/libmegazord.*"
|
||||
include "${nativeRustTarget}/libmegazord.*"
|
||||
}.singleFile
|
||||
|
||||
if (libraryPath == null) {
|
||||
|
@ -143,6 +114,7 @@ ext.configureUniFFIBindgen = { crateName ->
|
|||
workingDir project.rootDir
|
||||
commandLine '/usr/bin/env', 'cargo', 'uniffi-bindgen', 'generate', '--library', libraryPath, "--crate", crateName, '--language', 'kotlin', '--out-dir', uniffiOutDir.get()
|
||||
}
|
||||
|
||||
}
|
||||
outputs.dir uniffiOutDir
|
||||
// Re-generate when the native megazord library is rebuilt
|
||||
|
|
|
@ -57,11 +57,12 @@ the name of the component and the expected version number of the shared library.
|
|||
|
||||
## Unit Tests
|
||||
|
||||
The full-megazord AAR contains compiled rust code that targets various Android platforms, and is not
|
||||
The full-megazord AAR contains compiled Rust code that targets various Android platforms, and is not
|
||||
suitable for running on a Desktop development machine. In order to support integration with unittest
|
||||
suites such as robolectric, each megazord has a corresponding Java ARchive (JAR) distribution named e.g.
|
||||
`full-megazord-forUnitTests.jar`. This contains the rust code compiled for various Desktop architectures,
|
||||
and consumers can add it to their classpath when running tests on a Desktop machine.
|
||||
suites such as robolectric, each Megazord has a corresponding Java ARchive (JAR) distribution named
|
||||
e.g. `full-megazord-libsForTests.jar`. This contains the compiled Megazord code as well as
|
||||
libjnidispatch, targetted at various Desktop architectures. Consumers can add it to their classpath
|
||||
when running tests on a Desktop machine.
|
||||
|
||||
|
||||
## Gotchas and Rough Edges
|
||||
|
|
|
@ -35,25 +35,68 @@ kotlin {
|
|||
// Configurations are a somewhat mysterious Gradle concept. For our purposes, we can treat them
|
||||
// sets of files produced by one component and consumed by another.
|
||||
configurations {
|
||||
// Libraries for unit tests
|
||||
//
|
||||
// This is a JAR file that contains libmegazord and libjnidispatch built for desktop platforms
|
||||
// -- i.e. non-Android. These include linux-x86-64, darwin-x86-64, and darwin-aarch64. These
|
||||
// libraries are needed to run unit tests, since the AAR packages only contain libraries for
|
||||
// Android.
|
||||
//
|
||||
// For libmegazord, we copy the desktop libs from the
|
||||
// [rust-android-gradle plugin](https://github.com/mozilla/rust-android-gradle), which is
|
||||
// configurable via `local.properties`. The official packages are built in taskcluster include
|
||||
// `linux-x86-64` and `darwin-x86-64` and the list is controlled by
|
||||
// taskcluster/kinds/module-build/kind.yml
|
||||
//
|
||||
// For libjnidispatch, we include all libraries included in the official JAR file.
|
||||
consumable("libsForTests")
|
||||
// Stores the JNA jar file
|
||||
jna {
|
||||
canBeConsumed = false
|
||||
canBeResolved = true
|
||||
canBeDeclared = true
|
||||
}
|
||||
// Native megazord library, this is the one compatible with the user's local machine. We use it
|
||||
// to run unit tests.
|
||||
// to run uniffi-bindgen against.
|
||||
consumable("megazordNative")
|
||||
}
|
||||
|
||||
// Wrap the cargoBuild task to copy the native library to an output dir
|
||||
//
|
||||
// This allows it to be piped in to a Gradle configuration.
|
||||
def cargoBuildNativeArtifacts = tasks.register("copyNativeMegazord", Copy) {
|
||||
from layout.buildDirectory.dir("rustJniLibs/desktop")
|
||||
into layout.buildDirectory.dir("nativeMegazord")
|
||||
|
||||
def nativeTarget = rootProject.ext.nativeRustTarget
|
||||
dependsOn tasks["cargoBuild${nativeTarget.capitalize()}"]
|
||||
dependencies {
|
||||
// Needed so we can copy the libraries into libsForTests.
|
||||
jna(libs.jna) {
|
||||
artifact {
|
||||
type = "jar"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Extract JNI dispatch libraries from the JAR into a directory, so that we can then package them
|
||||
// into our own megazord-desktopLibraries JAR.
|
||||
def extractLibJniDispatch = tasks.register("extractLibJniDispatch", Copy) {
|
||||
from zipTree(configurations.jna.singleFile).matching {
|
||||
include "**/libjnidispatch.*"
|
||||
}
|
||||
into layout.buildDirectory.dir("libjnidispatch").get()
|
||||
}
|
||||
|
||||
def packageLibsForTest = tasks.register("packageLibsForTest", Jar) {
|
||||
archiveBaseName = "full-megazord-libsForTests"
|
||||
|
||||
from extractLibJniDispatch
|
||||
from layout.buildDirectory.dir("rustJniLibs/desktop")
|
||||
dependsOn tasks["cargoBuild${rootProject.ext.nativeRustTarget.capitalize()}"]
|
||||
}
|
||||
|
||||
def copyMegazordNative = tasks.register("copyMegazordNative", Copy) {
|
||||
from layout.buildDirectory.dir("rustJniLibs/desktop")
|
||||
into layout.buildDirectory.dir("megazordNative")
|
||||
}
|
||||
|
||||
|
||||
artifacts {
|
||||
// Connect task output to configurations
|
||||
megazordNative(cargoBuildNativeArtifacts)
|
||||
// Connect task output to the configurations
|
||||
libsForTests(packageLibsForTest)
|
||||
megazordNative(copyMegazordNative)
|
||||
}
|
||||
|
||||
cargo {
|
||||
|
@ -99,3 +142,51 @@ afterEvaluate {
|
|||
|
||||
apply from: "$rootDir/publish.gradle"
|
||||
ext.configurePublish()
|
||||
|
||||
afterEvaluate {
|
||||
publishing {
|
||||
publications {
|
||||
// Publish a second package named `full-megazord-libsForTests` to Maven with the
|
||||
// `libsForTests` output. This contains the same content as our `libsForTests`
|
||||
// configuration. Publishing it allows the android-components code to depend on it.
|
||||
libsForTests(MavenPublication) {
|
||||
artifact tasks['packageLibsForTest']
|
||||
artifact file("${projectDir}/../DEPENDENCIES.md"), {
|
||||
extension "LICENSES.md"
|
||||
}
|
||||
pom {
|
||||
groupId = rootProject.ext.library.groupId
|
||||
artifactId = "${project.ext.artifactId}-libsForTests"
|
||||
description = project.ext.description
|
||||
// For mavenLocal publishing workflow, increment the version number every publish.
|
||||
version = rootProject.ext.library.version + (rootProject.hasProperty('local') ? '-' + rootProject.property('local') : '')
|
||||
packaging = "jar"
|
||||
|
||||
licenses {
|
||||
license {
|
||||
name = libLicense
|
||||
url = libLicenseUrl
|
||||
}
|
||||
}
|
||||
|
||||
developers {
|
||||
developer {
|
||||
name = 'Sync Team'
|
||||
email = 'sync-team@mozilla.com'
|
||||
}
|
||||
}
|
||||
|
||||
scm {
|
||||
connection = libVcsUrl
|
||||
developerConnection = libVcsUrl
|
||||
url = libUrl
|
||||
}
|
||||
}
|
||||
|
||||
// This is never the publication we want to use when publishing a
|
||||
// parent project with us as a child `project()` dependency.
|
||||
alias = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче