Skip to content

Commit

Permalink
Always use the NDK version from source.properties.
Browse files Browse the repository at this point in the history
Previously, `RustAndroidPlugin` would read the
NDK version from `source.properties` in the NDK
path, while `CargoBuildTask` would try to infer
the NDK version from the pathname.

Inferring the NDK version from the pathname would
fail if the pathname didn't contain the version
(e.g., Mach currently installs the NDK used to
build Firefox for Android into
`~/.mozbuild/android-ndk-r26c`), causing
`Toolchain` to return the wrong path to `ar` for
new NDK versions.
  • Loading branch information
linabutler authored and ncalexan committed Apr 10, 2024
1 parent 109ce8a commit e1e2f1f
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 19 deletions.
21 changes: 10 additions & 11 deletions plugin/src/main/kotlin/com/nishtahir/CargoBuildTask.kt
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ open class CargoBuildTask : DefaultTask() {
@Input
var toolchain: Toolchain? = null

@Input
var ndk: Ndk? = null

@Suppress("unused")
@TaskAction
fun build() = with(project) {
Expand All @@ -25,10 +28,12 @@ open class CargoBuildTask : DefaultTask() {
throw GradleException("toolchain cannot be null")
}

val ndk = ndk ?: throw GradleException("ndk cannot be null")

project.plugins.all {
when (it) {
is AppPlugin -> buildProjectForTarget<AppExtension>(project, toolchain, this)
is LibraryPlugin -> buildProjectForTarget<LibraryExtension>(project, toolchain, this)
is AppPlugin -> buildProjectForTarget<AppExtension>(project, toolchain, ndk, this)
is LibraryPlugin -> buildProjectForTarget<LibraryExtension>(project, toolchain, ndk, this)
}
}
// CARGO_TARGET_DIR can be used to force the use of a global, shared target directory
Expand Down Expand Up @@ -77,8 +82,7 @@ open class CargoBuildTask : DefaultTask() {
}
}

inline fun <reified T : BaseExtension> buildProjectForTarget(project: Project, toolchain: Toolchain, cargoExtension: CargoExtension) {
val app = project.extensions[T::class]
inline fun <reified T : BaseExtension> buildProjectForTarget(project: Project, toolchain: Toolchain, ndk: Ndk, cargoExtension: CargoExtension) {
val apiLevel = cargoExtension.apiLevels[toolchain.platform]!!
val defaultTargetTriple = getDefaultTargetTriple(project, cargoExtension.rustcCommand)

Expand Down Expand Up @@ -165,13 +169,8 @@ open class CargoBuildTask : DefaultTask() {

// Cross-compiling to Android requires toolchain massaging.
if (toolchain.type != ToolchainType.DESKTOP) {
val ndkPath = app.ndkDirectory
val ndkVersion = ndkPath.name
val ndkVersionMajor = try {
ndkVersion.split(".").first().toInt()
} catch (ex: NumberFormatException) {
0 // Falls back to generic behaviour.
}
val ndkPath = ndk.path
val ndkVersionMajor = ndk.versionMajor

val toolchainDirectory = if (toolchain.type == ToolchainType.ANDROID_PREBUILT) {
environment("CARGO_NDK_MAJOR_VERSION", ndkVersionMajor)
Expand Down
24 changes: 16 additions & 8 deletions plugin/src/main/kotlin/com/nishtahir/RustAndroidPlugin.kt
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,11 @@ val toolchains = listOf(
"android/x86_64")
)

data class Ndk(val path: File, val version: String) {
val versionMajor: Int
get() = version.split(".").first().toInt()
}

data class Toolchain(val platform: String,
val type: ToolchainType,
val target: String,
Expand Down Expand Up @@ -227,21 +232,23 @@ open class RustAndroidPlugin : Plugin<Project> {
}

// Determine the NDK version, if present
val ndkSourceProperties = Properties()
val ndkSourcePropertiesFile = File(extensions[T::class].ndkDirectory, "source.properties")
if (ndkSourcePropertiesFile.exists()) {
ndkSourceProperties.load(ndkSourcePropertiesFile.inputStream())
val ndk = extensions[T::class].ndkDirectory.let {
val ndkSourceProperties = Properties()
val ndkSourcePropertiesFile = File(it, "source.properties")
if (ndkSourcePropertiesFile.exists()) {
ndkSourceProperties.load(ndkSourcePropertiesFile.inputStream())
}
val ndkVersion = ndkSourceProperties.getProperty("Pkg.Revision", "0.0")
Ndk(path = it, version = ndkVersion)
}
val ndkVersion = ndkSourceProperties.getProperty("Pkg.Revision", "0.0")
val ndkVersionMajor = ndkVersion.split(".").first().toInt()

// Determine whether to use prebuilt or generated toolchains
val usePrebuilt =
cargoExtension.localProperties.getProperty("rust.prebuiltToolchains")?.equals("true") ?:
cargoExtension.prebuiltToolchains ?:
(ndkVersionMajor >= 19);
(ndk.versionMajor >= 19);

if (usePrebuilt && ndkVersionMajor < 19) {
if (usePrebuilt && ndk.versionMajor < 19) {
throw GradleException("usePrebuilt = true requires NDK version 19+")
}

Expand Down Expand Up @@ -299,6 +306,7 @@ open class RustAndroidPlugin : Plugin<Project> {
group = RUST_TASK_GROUP
description = "Build library ($target)"
toolchain = theToolchain
this.ndk = ndk
}

if (!usePrebuilt) {
Expand Down

0 comments on commit e1e2f1f

Please sign in to comment.