Created
November 4, 2019 17:20
-
-
Save willir/ed03396a9f2055a3914b7df0baa5a8f0 to your computer and use it in GitHub Desktop.
Android Rust
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.nio.file.Files | |
import java.nio.file.Paths | |
import java.nio.file.Path | |
class BuildRust extends DefaultTask { | |
String variant | |
static String OUT_LIB_NAME = "libhello.so" | |
enum TargetType { | |
ARM64("arm64", "aarch64-linux-android", "arm64-v8a"), | |
ARM_V7("armv7", "armv7-linux-androideabi", "armeabi-v7a"), | |
X86("x86", "i686-linux-android", "x86"), | |
X86_64("x86_64", "x86_64-linux-android", "x86_64"), | |
final String id | |
final String rustTarget | |
final String jniLibDirName | |
private TargetType(String id, String rustTarget, String jniLibDirName) { | |
this.id = id | |
this.rustTarget = rustTarget | |
this.jniLibDirName = jniLibDirName | |
} | |
static TargetType fromId(String id) { | |
TargetType res = values().find {it.id == id} | |
if (res != null) { | |
return res | |
} else { | |
throw new GradleException( | |
"Wrong rust target: " + id + " supported: " + values().each {it.id}) | |
} | |
} | |
boolean is64Bit() { | |
return this == ARM64 || this == X86_64 | |
} | |
} | |
@TaskAction | |
void buildRust() { | |
TargetType rustTargetName = null | |
if (project.hasProperty("rustTarget")) { | |
rustTargetName = TargetType.fromId((String) project.findProperty("rustTarget")) | |
} | |
if (rustTargetName != null) { | |
buildTarget(rustTargetName) | |
} else { | |
for (target in TargetType.values()) { | |
buildTarget(target) | |
} | |
} | |
} | |
void buildTarget(TargetType target) { | |
int sdkVersion = | |
project.android.defaultConfig.minSdkVersion.getApiLevel() | |
if (target.is64Bit() && sdkVersion < 21) { | |
logger.warn( | |
"" + target + " doesn't support " + sdkVersion + | |
" SDK version. Changing to 21") | |
sdkVersion = 21 | |
} | |
def cmd = ["cargo", "ndk", | |
"--target", target.rustTarget, | |
"--android-platform", sdkVersion.toString(), | |
"--", "build"] | |
if (isRelease()) { | |
cmd.add("--release") | |
} | |
logger.info("Executiong: " + cmd) | |
project.exec { | |
workingDir = getCargoPath() | |
commandLine = cmd | |
}.assertNormalExitValue() | |
copyTarget(target) | |
} | |
void copyTarget(TargetType target) { | |
def copyFrom = getRustLibOutPath(target) | |
def copyTo = getJniLibPath(target) | |
Files.deleteIfExists(copyTo) | |
Files.copy(copyFrom, copyTo) | |
logger.info("Copy ${copyFrom} -> ${copyTo}") | |
} | |
Path getRustLibOutPath(TargetType target) { | |
return Paths.get(getCargoPath().toString(), "target", target.rustTarget, variant, OUT_LIB_NAME) | |
} | |
Path getJniLibPath(TargetType target) { | |
return Paths.get(getSrcRootPath().toString(), "jniLibs", target.jniLibDirName, OUT_LIB_NAME) | |
} | |
Path getCargoPath() { | |
return Paths.get(getSrcRootPath().toString(), "rust") | |
} | |
Path getSrcRootPath() { | |
return Paths.get(project.rootDir.getPath(), "app", "src", "main") | |
} | |
boolean isRelease() { | |
return variant == "release" | |
} | |
} | |
task buildRustDebug(type: BuildRust) { | |
group = "Build" | |
description = "Build debug rust library" | |
variant = "debug" | |
} | |
task buildRustRelease(type: BuildRust) { | |
group = "Build" | |
description = "Build release rust library" | |
variant = "release" | |
} | |
tasks.whenTaskAdded { task -> | |
if (task.name == "compileDebugSources" || task.name == "mergeDebugJniLibFolders") { | |
task.dependsOn buildRustDebug | |
} | |
if (task.name == "compileReleaseSources" || task.name == "mergeReleaseJniLibFolders") { | |
task.dependsOn buildRustRelease | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment