Bug 1661406 - Allow artifact builds without an NDK when working around Android-Gradle plugin bug substituting GeckoView. r=agi,geckoview-reviewers

Differential Revision: https://phabricator.services.mozilla.com/D88501
This commit is contained in:
Nick Alexander 2020-08-28 16:51:52 +00:00
Родитель 0e0f07423b
Коммит d36eacb26b
1 изменённых файлов: 47 добавлений и 28 удалений

Просмотреть файл

@ -7,11 +7,39 @@
evaluationDependsOn(':annotations')
import groovy.util.FileNameFinder
import groovy.transform.Memoized
import java.nio.file.Path
import java.nio.file.Paths
import java.security.MessageDigest
// To find the LLVM tools from the Android NDK, there are a few wrinkles. In a compiled build,
// we can use our own `ANDROID_NDK` configure option. But in an artifact build, that isn't
// defined, so we fall back to `android.ndkDirectory` -- but that's defined in
// `local.properties`, which may not define it. In that case, fall back to crawling the
// filesystem.
@Memoized
def getNDKDirectory() {
if (project.mozconfig.substs.ANDROID_NDK) {
return project.mozconfig.substs.ANDROID_NDK
}
if (project.android.ndkDirectory) {
return project.android.ndkDirectory
}
def mozbuild = System.getenv('MOZBUILD_STATE_PATH') ?: "${System.getProperty('user.home')}/.mozbuild"
def files = new FileNameFinder().getFileNames(mozbuild, "android-ndk-*/source.properties")
if (files) {
// It would be nice to sort these by version, but that's too much effort right now.
return project.file(files.first()).parentFile.toString()
}
return null
}
ext.getNDKDirectory = {
// This is the easiest way to expose the memoized function to consumers.
getNDKDirectory()
}
// Bug 1657190: This task works around a bug in the Android-Gradle plugin. When using SNAPSHOT
// builds (and possibly in other situations) the JNI library invalidation process isn't correct. If
// there are two JNI libs `a.so` and `b.so` and a new snapshot updates only `a.so`, then the
@ -26,7 +54,7 @@ import java.security.MessageDigest
// and use this as our own Mozilla-specific "library generation ID". We then add our own
// Mozilla-specific ELF section to every library so that they will all be invalidated by the
// Android-Gradle plugin of a consuming project.
class SyncLibsAndUpdateGeneration extends DefaultTask {
class SyncLibsAndUpdateGenerationID extends DefaultTask {
@InputDirectory
File source
@ -36,34 +64,12 @@ class SyncLibsAndUpdateGeneration extends DefaultTask {
@OutputDirectory
File destinationDir
// To find the LLVM tools from the Android NDK, there are a few wrinkles. In a compiled build,
// we can use our own `ANDROID_NDK` configure option. But in an artifact build, that isn't
// defined, so we fall back to `android.ndkDirectory` -- but that's defined in
// `local.properties`, which may not define it. In that case, fall back to crawling the
// filesystem.
@Input
String ndkDirectory = {
if (project.mozconfig.substs.ANDROID_NDK) {
return project.mozconfig.substs.ANDROID_NDK
}
if (project.android.ndkDirectory) {
return project.android.ndkDirectory
}
def mozbuild = System.getenv('MOZBUILD_STATE_PATH') ?: "${System.getProperty('user.home')}/.mozbuild"
project.logger.lifecycle("mozbuild: ${mozbuild}")
def files = new FileNameFinder().getFileNames(mozbuild, "android-ndk-*/source.properties")
if (files) {
// It would be nice to sort these by version, but that's too much effort right now.
return project.file(files.first()).parentFile.toString()
}
throw new GradleException("Could not determine Android NDK directory. Set `ndk.dir` in `${project.topsrcdir}/local.properties`")
}()
// The `**` in the pattern depends on the host architecture. We could compute them or bake them
// in, but this is easy enough. `FileNameFinder` won't return a directory, so we find a file
// and return its parent directory.
@Input
File llvmBin = project.file(new FileNameFinder().getFileNames(ndkDirectory, "toolchains/llvm/prebuilt/**/bin/llvm-*").first()).parentFile
File llvmBin = project.file(new FileNameFinder().getFileNames(project.ext.getNDKDirectory(), "toolchains/llvm/prebuilt/**/bin/llvm-*")
.first()).parentFile
// Sibling to `.note.gnu.build-id`.
@Input
@ -178,12 +184,25 @@ ext.configureVariantWithGeckoBinaries = { variant ->
}
// For !MOZILLA_OFFICIAL builds, work around an Android-Gradle plugin bug that causes startup
// crashes with local substitution. See class comment above.
def syncLibsFromDistDir = { if (!mozconfig.substs.MOZILLA_OFFICIAL) {
// crashes with local substitution. But -- we want to allow artifact builds that don't have the
// NDK installed. See class comment above.
def shouldUpdateGenerationID = {
if (mozconfig.substs.MOZILLA_OFFICIAL) {
return false
} else if (ext.getNDKDirectory() == null) {
logger.warn("Could not determine Android NDK directory.")
logger.warn("Set `ndk.dir` in `${project.topsrcdir}/local.properties` to avoid startup crashes when using `substitute-local-geckoview.gradle`.")
logger.warn("See https://bugzilla.mozilla.org/show_bug.cgi?id=1657190.")
return false
}
return true
}()
def syncLibsFromDistDir = { if (shouldUpdateGenerationID) {
def jarTask = tasks["bundleLibRuntime${variant.name.capitalize()}"]
def bundleJar = jarTask.outputs.files.find({ it.name == 'classes.jar' })
task("syncLibsFromDistDirFor${variant.name.capitalize()}", type: SyncLibsAndUpdateGeneration) {
task("syncLibsAndUpdateGenerationIDFromDistDirFor${variant.name.capitalize()}", type: SyncLibsAndUpdateGenerationID) {
source file("${distDir}/lib")
destinationDir file("${project.buildDir}/moz.build/src/${variant.name}/jniLibs")
// Include the hash of classes.jar as well, so that JVM-only changes don't leave every