-
Notifications
You must be signed in to change notification settings - Fork 71
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Automatically bundle libc++_shared
in apk?
#106
Comments
I found out how to write a task to automatically copy the library to rustJniLibs. I take reference from rust-android-gradle itself, and from the NDK Build System Maintainers Guide. But I have yet to write a task for each architecture. tasks.whenTaskAdded { task ->
if (task.name == 'mergeDebugJniLibFolders' || task.name == 'mergeReleaseJniLibFolders') {
task.dependsOn 'cargoBuild'
}
if (task.name == 'cargoBuildArm64') {
task.dependsOn 'copy_libc++_sharedArm64'
}
}
// TODO: make a task for each architecture
tasks.register('copy_libc++_sharedArm64', Copy) {
def ndkDir = android.ndkDirectory
// hostTag and archTriple from: https://developer.android.com/ndk/guides/other_build_systems
// TODO: detect the correct host tag
def hostTag = 'windows-x86_64'
def archTriple = 'aarch64-linux-android'
from "$ndkDir/toolchains/llvm/prebuilt/$hostTag/sysroot/usr/lib/$archTriple/libc++_shared.so"
into layout.buildDirectory.dir("rustJniLibs/android/arm64-v8a")
} |
The necessity for fixing the TODOs has finally come: def localProperties = new Properties()
localProperties.load(new FileInputStream(rootProject.file("local.properties")))
tasks.whenTaskAdded { task ->
if (task.name == 'mergeDebugJniLibFolders' || task.name == 'mergeReleaseJniLibFolders') {
task.dependsOn 'cargoBuild'
}
for (target in cargo.targets) {
if (task.name == "cargoBuild${target.capitalize()}") {
task.dependsOn "copy_libc++_shared${target.capitalize()}"
}
}
}
for (target in cargo.targets) {
tasks.register("copy_libc++_shared${target.capitalize()}", Copy) {
def ndkDir = android.ndkDirectory
// hostTag and archTriple from: https://developer.android.com/ndk/guides/other_build_systems
def hostTag = localProperties['hostTag']
def archTriple = [
arm: 'armv7a-linux-androideabi',
arm64: 'aarch64-linux-android',
x86: 'i686-linux-android',
x86_64: 'x86_64-linux-android',
][target]
from "$ndkDir/toolchains/llvm/prebuilt/$hostTag/sysroot/usr/lib/$archTriple/libc++_shared.so"
into layout.buildDirectory.dir("rustJniLibs/android/arm64-v8a")
}
} As long as the code that generate the task name don't change, this probably will continue to work. I didn't find a way to get the current host tag, so I am manually writing it to |
Hi @Rodrigodd -- sorry for not responding to this when you filed it moons ago. I'd be happy to have this happen automatically, perhaps behind a flag, in the main plugin, since it's probably a common issue. Inside the plugin, we do some similar things with the prebuilt toolchains and must find the host tag somewhere. Also, there's a small issue where you're copying into the |
Hi @ncalexan , thanks for responding!
Oh, true. I also noticed that the abi name for the arm target is wrong, because it is different for bintools, according to the android documentation. I also noticed that the task fails silently if the file does not exists.
Ah yes, it happens here. I will copy it, if you don't mind. Taking everything above in consideration, now I have the following code: import org.apache.tools.ant.taskdefs.condition.Os
tasks.whenTaskAdded { task ->
if (task.name == 'mergeDebugJniLibFolders' || task.name == 'mergeReleaseJniLibFolders') {
task.dependsOn 'cargoBuild'
}
for (target in cargo.targets) {
if (task.name == "cargoBuild${target.capitalize()}") {
task.dependsOn "copy_libc++_shared${target.capitalize()}"
}
}
}
for (target in cargo.targets) {
tasks.register("copy_libc++_shared${target.capitalize()}", Copy) {
def ndkDir = android.ndkDirectory
// hostTag, abi and archTriple from: https://developer.android.com/ndk/guides/other_build_systems
def hostTag
if (Os.isFamily(Os.FAMILY_WINDOWS)) {
if (Os.isArch("x86_64") || Os.isArch("amd64")) {
hostTag = "windows-x86_64"
} else {
hostTag = "windows"
}
} else if (Os.isFamily(Os.FAMILY_MAC)) {
hostTag = "darwin-x86_64"
} else {
hostTag = "linux-x86_64"
}
def (abi, archTriple) = [
arm: ['armeabi-v7a', 'arm-linux-androideabi'],
arm64: ['arm64-v8a', 'aarch64-linux-android'],
x86: ['x86', 'i686-linux-android'],
x86_64: ['x86_64', 'x86_64-linux-android'],
][target]
def from_path = "$ndkDir/toolchains/llvm/prebuilt/$hostTag/sysroot/usr/lib/$archTriple/libc++_shared.so"
def into_path = layout.buildDirectory.dir("rustJniLibs/android/$abi")
assert file(from_path).exists()
from from_path
into into_path
}
} |
I am currently migrating a project from using cargo-apk to a Gradle project, using
rust-android-gradle
.The problem is that my project need to link to
libc++_shared
, but I am yet to find a compelling way to automatically bundle this library, that come with the NDK. I know that cargo-apk automatically bundles the library when linking to c++_shared, and, from searching, apparently gradle automatically also do this when using cmake or ndk-build.Currently, I am simply copying the shared library to jniLibs, and searching how I could specify the original library in NDK to Gradle, but maybe
rust-android-gradle
should handle that?The text was updated successfully, but these errors were encountered: