Skip to content
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

Android support #470

Open
Bromeon opened this issue Nov 6, 2023 · 11 comments
Open

Android support #470

Bromeon opened this issue Nov 6, 2023 · 11 comments
Labels
c: android Android export target feature Adds functionality to the library

Comments

@Bromeon
Copy link
Member

Bromeon commented Nov 6, 2023

Knowledge base for the Android port: what's missing, insights, obstacles, etc.
There's no active work going on at the moment, but we can already collect some infos.

Related Discord thread.

@Bromeon Bromeon added the feature Adds functionality to the library label Nov 6, 2023
@kelteseth

This comment was marked as off-topic.

@Bromeon

This comment was marked as off-topic.

@scripturial
Copy link

scripturial commented Nov 23, 2023

First update rust binaries:

rustup target add aarch64-linux-android
rustup target add arm-linux-androideabi
rustup target add i686-linux-android
rustup target add x86_64-linux-android

Windows users need this for the cargo build. Install https://developer.android.com/ndk/downloads and Set environment variables:

C_INCLUDE_PATH=$HOME/Android/Sdk/ndk/26.0.10792818/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include/:$HOME/Android/Sdk/ndk/26.0.10792818/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include/arm-linux-androideabi cargo build --target armv7-linux-androideabi
C_INCLUDE_PATH=$HOME/Android/Sdk/ndk/26.0.10792818/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include/:$HOME/Android/Sdk/ndk/26.0.10792818/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include/aarch64-linux-android cargo build --target aarch64-linux-android

@moberer
Copy link

moberer commented Nov 26, 2023

What is actually missing here still?
Is it just some documentation, like the discord thread implies, or is there more to it than that?

@Bromeon
Copy link
Member Author

Bromeon commented Nov 26, 2023

It's mostly missing one or a few motivated users that drive this forward, in terms of:

  1. reproducible and robust toolchain to compile to Android (including Godot configuration)
  2. CI integration, maybe some tests to prevent regressions
  3. documentation

That is not to say a single person has to do all of them. I gladly provide support, especially when it comes to gdext-specific things such as CI setup, Godot integration tests etc. But I don't see myself realistically having the capacity to implement this myself in the next months, there's also the WASM port which is actively being worked on, and lots of core features to be ironed out.

@moberer
Copy link

moberer commented Nov 26, 2023

Ok, I can at least give a rough description on how I made it work locally (Linux/Arch):

  1. Install system dependencies
  • aur/android-sdk
  • aur/android-ndk
  1. Install rust targets
rustup target add aarch64-linux-android

2.5) Install cargo ndk

cargo install cargo ndk
  1. Build shared libraries for Android arm64
    (you need to repeat this step every time you change your Rust code)
   env ANDROID_NDK_HOME=/opt/android-ndk cargo ndk -t arm64-v8a build
   env ANDROID_NDK_HOME=/opt/android-ndk cargo ndk -t arm64-v8a build --release

NOTE: If you are on a different distro, or you installed the ndk through Android Studio, you'll need to change the path to point to your correct ndk!

  1. Generate a developer key for signing the APK
keytool -keyalg RSA -genkeypair -alias androiddebugkey -keypass android -keystore debug.keystore -storepass android -dname "CN=Android Debug,O=Android,C=US" -validity 9999 -deststoretype pkcs12

Note: I'm not quite sure which package keytool is from, it may not necessarily be installed by only installing the dependencies mentioned above.

  1. Add Android SDK path as well as username and password in Godot Settings
  • Top Bar
  • Editor
  • Editor Settings
  • Search for "Android" in the search bar
  • Click on Export->Android in the left pane
  • Set SDK path to /home/USER/Android/Sdk
    • You need Android Studio for this! - Don't forget to install the correct SDK
  • Set the debug keystore to the file you created in the previous step with keytool (debug.keystore)
  • Set user to "androiddebugkey"
  • Set password to "android"
  • Close the Settings
  1. Add Android Build-Template
  • Top Bar
  • Project
  • Create Android-Build-Template
  • follow the Wizard
  1. Add the Android targets to your .gdextensions file

In my case it looks like this:

[configuration]
entry_symbol = "gdext_rust_init"
compatibility_minimum = 4.1

[libraries]
linux.debug.x86_64     = "res://../rust/target/debug/librust_project.so"
linux.release.x86_64   = "res://../rust/target/release/librust_project.so"
                            
windows.debug.x86_64   = "res://../rust/target/debug/rust_project.dll"
windows.release.x86_64 = "res://../rust/target/release/rust_project.dll"
                            
macos.debug            = "res://../rust/target/debug/librust_project.dylib"
macos.release          = "res://../rust/target/release/librust_project.dylib"

macos.debug.arm64      = "res://../rust/target/debug/librust_project.dylib"
macos.release.arm64    = "res://../rust/target/release/librust_project.dylib"

android.release.arm64  = "res://../rust/target/aarch64-linux-android/debug/librust_project.so"
android.debug.arm64    = "res://../rust/target/aarch64-linux-android/release/librust_project.so"
  1. Reload the Project in the Editor
    You are either prompted to reload the project,
    or just use TopBar->Project->Reload, or just close Godot and re-open it.

  2. Export the APK

-> Top Bar
-> Project
-> Export

  • Select Android
  • Rename your project acc. to android rules (otherwise you'll get an error)
  • Click "Export Project"

You should now be left with an apk file in the godot/build folder.
You can copy this apk to an end device and it should work.

Note that Android Emulators which use x86/64-Android will not work for executing this. - We didn't compile in the necessary targets. - Though I'm sure you could add them somehow.

@MeganSpencer
Copy link

MeganSpencer commented Dec 5, 2023

Step-by-step for building Android library on Mac Apple/Arm devices

I'm experimenting with how to get this working on Mac (ARM) computers, using Godot 4.2.1, I dont have it working yet, but here is the work in progress.

  1. Setup needed before building anything.
    rustup target add aarch64-linux-android
    rustup target add armv7-linux-androideabi
  1. Install the ndk, then poke around your /User/$USER/Library/ folder to find the correct CC and AR paths inside the ndk and set them
export CC=/Users/USER/Library/Android/sdk/ndk/23.2.8568313/toolchains/llvm/prebuilt/darwin-x86_64/bin/aarch64-linux-android31-clang
export AR=/Users/USER/Library/Android/sdk/ndk/23.2.8568313/toolchains/llvm/prebuilt/darwin-x86_64/bin/llvm-ar
export RANLIB=/Users/USER/Library/Android/sdk/ndk/23.2.8568313/toolchains/llvm/prebuilt/darwin-x86_64/bin/llvm-ranlib
export PATH="/Users/USER/Library/Android/sdk/ndk/23.2.8568313/toolchains/llvm/prebuilt/darwin-x86_64/bin/:$PATH"
  1. Add the lazy-function-tables feature flag.

This feature flag makes your application non-thread safe. But bypasses a bug that is currently under investigation.

[dependencies]
godot = { git = "https://github.com/godot-rust/gdext", branch = "master", features = ["lazy-function-tables"]}
  1. Add this config ~/.cargo/config:

It is not clear to me why this is needed. The next step fails on Mac if you do not have these settings:

[target.armv7-linux-androideabi]
linker = "armv7a-linux-androideabi31-clang"
rustflags = [
  "-C", "link-arg=-undefined",
  "-C", "link-arg=dynamic_lookup",
]

[target.aarch64-linux-android]
linker = "aarch64-linux-android31-clang"
rustflags = [
  "-C", "link-arg=-undefined",
  "-C", "link-arg=dynamic_lookup",
]
  1. Build your rust code into a file to be shared into Godot:
cargo build --target armv7-linux-androideabi && \
    cargo build --target aarch64-linux-android && \
    cargo build --release --target armv7-linux-androideabi && \
    cargo build --release --target aarch64-linux-android
  1. Copy into project:
cp target/armv7-linux-androideabi/debug/libpolla.so ../Polla/lib_polla_armv7-linux-androideabi_debug.so
cp target/armv7-linux-androideabi/release/libpolla.so ../Polla/lib_polla_armv7-linux-androideabi_release.so
cp target/aarch64-linux-android/debug/libpolla.so ../Polla/lib_polla_aarch64-linux-android_debug.so
cp target/aarch64-linux-android/release/libpolla.so ../Polla/lib_polla_aarch64-linux-android_release.so

@Jim-Bar
Copy link

Jim-Bar commented Jan 19, 2024

I can confirm I got it working on Android too, as @moberer described, using Ubuntu 22.04.

I am not sure what cargo ndk is though, on my end this produced error: no such command: 'ndk'. Instead I used:

ANDROID_NDK_HOME=<path/to/the/ndk> cargo build --target aarch64-linux-android
ANDROID_NDK_HOME=<path/to/the/ndk> cargo build --target aarch64-linux-android --release

Also I got error: linking with 'cc' failed: exit status: 1 doing so, so I used the trick described here; I added this to ~/.cargo/config (actually I created this file):

[target.aarch64-linux-android]
linker = "<path/to/the/ndk>/26.1.10909125/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android34-clang"

The versions could be different.

It worked fine after that 👌

@moberer
Copy link

moberer commented Jan 19, 2024

I am not sure what cargo ndk is though, on my end this produced error: no such command: 'ndk'.

Cargo-NDK is a helper tool supposed to make this easier.

But you need to install it manually, before being able to use it.
I forgot to add that to my writeup, sorry for any wasted time because of that...

You can install it like that:

cargo install cargo-ndk

Afterward, the command should work.

But as you discovered, it is not really necessary and only a "helper" to make the commands a bit less annoying.

@walksanatora
Copy link

  • Rename your project acc. to android rules (otherwise you'll get an error)

I do not know what this field is or how to fix it. but it might just be the issue I am encountering. my app runs fine on my laptop, but when I run in android it is a black screen. could this be the cause?

@moberer
Copy link

moberer commented May 9, 2024

  • Rename your project acc. to android rules (otherwise you'll get an error)

I do not know what this field is or how to fix it. but it might just be the issue I am encountering. my app runs fine on my laptop, but when I run in android it is a black screen. could this be the cause?

Unlikely, when I had a bad name, I think it manifested as an export error.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
c: android Android export target feature Adds functionality to the library
Projects
None yet
Development

No branches or pull requests

7 participants