Glue between Rust and Android

Related tags

Mobile android rust
Overview

deprecated in favor of https://github.com/rust-windowing/android-ndk-rs which works with winit master

Android Glue

Crates.io Crates.io CircleCI

Usage

With Docker

The easiest way to compile for Android is to use Docker and the philipalldredge/cargo-apk image.

In order to build an APK, simply do this:

docker run --rm -v <path-to-local-directory-with-Cargo.toml>:/root/src philipalldredge/cargo-apk cargo apk build

For example if you're on Linux and you want to compile the project in the current working directory.

docker run --rm -v "$(pwd):/root/src" -w /root/src philipalldredge/cargo-apk cargo apk build

Do not mount a volume on /root or you will erase the local installation of Cargo.

After the build is finished, you should get an Android package in target/android-artifacts/debug/apk.

Manual usage

Setting up your environment

Before you can compile for Android, you need to setup your environment. This needs to be done only once per system.

  • Install rustup.
  • Run rustup target add <target> for all supported targets to which you want to compile. Building will attempt to build for all supported targets unless the build targets are adjusted via Cargo.toml.
    • rustup target add armv7-linux-androideabi
    • rustup target add aarch64-linux-android
    • rustup target add i686-linux-android
    • rustup target add x86_64-linux-android
  • Install the Java JRE or JDK (on Ubuntu, sudo apt-get install openjdk-8-jdk).
  • Download and unzip the Android NDK.
  • Download and unzip the Android SDK.
  • Install some components in the SDK: ./android-sdk/tools/bin/sdkmanager "platform-tools" "platforms;android-29" "build-tools;29.0.0".
  • Install cargo-apk with cargo install cargo-apk.
  • Set the environment variables NDK_HOME to the path of the NDK and ANDROID_HOME to the path of the SDK.

Compiling

In the project root for your Android crate, run cargo apk build. You can use the same options as with the regular cargo build.

This will build an Android package in target/android-artifacts/<debug|release>/apk.

Compiling Multiple Binaries

cargo apk build supports building multiple binaries and examples using the same arguments as cargo build. It will produce an APK for each binary.

Android packages for bin targets are placed in target/android-artifacts/<debug|release>/apk.

Android packages for example targets are placed in target/android-artifacts/<debug|release>/apk/examples.

Testing on an Android emulator

Start the emulator, then run:

cargo apk run

This will install your application on the emulator, then run it.
If you only want to install, use cargo apk install.

To show log run: cargo apk logcat | grep RustAndroidGlueStdouterr

Interfacing with Android

An application is not very useful if it doesn't have access to the screen, the user inputs, etc.

The android_glue crate provides FFI with the Android environment for things that are not in the stdlib.

How it works

The build process

The build process works by:

  • Using rustc to always compile your crate as a shared library by:
    • Creating a custom CMake toolchain file and setting environment variables which expose the appropriate NDK provided build tools for use with the cc and cmake crates.
    • Creating a temporary file in the same directory as your crate root. This temporary file serves as the crate root of the static library. It contains the contents of the original crate root along with an android_main implementation.
    • Compiling a forked version of android_native_app_glue. android_native_app_glue is originally provided by the NDK. It provides the entrypoint used by Android's NativeActivity that calls android_main.
    • Linking using the NDK provided linker.

This first step outputs a shared library, and is run once per target architecture.

The command then builds the APK using the shared libraries, generated manifest, and tools from the Android SDK. If the C++ standard library is used, it adds the appropriate shared library to the APK. It signs the APK with the default debug keystore used by Android development tools. If the keystore doesn't exist, it creates it using the keytool from the JRE or JDK.

Supported [package.metadata.android] entries

# The target Android API level.
# "android_version" is the compile SDK version. It defaults to 29.
# (target_sdk_version defaults to the value of "android_version")
# (min_sdk_version defaults to 18) It defaults to 18 because this is the minimum supported by rustc.
android_version = 29
target_sdk_version = 29
min_sdk_version = 26

# Specifies the array of targets to build for.
# Defaults to "armv7-linux-androideabi", "aarch64-linux-android", "i686-linux-android".
build_targets = [ "armv7-linux-androideabi", "aarch64-linux-android", "i686-linux-android", "x86_64-linux-android" ]

# The following values can be customized on a per bin/example basis. See multiple_targets example
# If a value is not specified for a secondary target, it will inherit the value defined in the `package.metadata.android`
# section unless otherwise noted.
#

# The Java package name for your application.
# Hyphens are converted to underscores.
# Defaults to rust.<target_name> for binaries. 
# Defaults to rust.<package_name>.example.<target_name> for examples.
# For example: for a binary "my_app", the default package name will be "rust.my_app"
# Secondary targets will not inherit the value defined in the root android configuration.
package_name = "rust.cargo.apk.advanced"

# The user-friendly name for your app, as displayed in the applications menu.
# Defaults to the target name
# Secondary targets will not inherit the value defined in the root android configuration.
label = "My Android App"

# Internal version number used to determine whether one version is more recent than another. Must be an integer.
# Defaults to 1
# See https://developer.android.com/guide/topics/manifest/manifest-element
version_code = 2

# The version number shown to users.
# Defaults to the cargo package version number
# See https://developer.android.com/guide/topics/manifest/manifest-element
version_name = "2.0"

# Path to your application's resources folder.
# If not specified, resources will not be included in the APK
res = "path/to/res_folder"

# Virtual path your application's icon for any mipmap level.
# If not specified, an icon will not be included in the APK.
icon = "@mipmap/ic_launcher"

# Path to the folder containing your application's assets.
# If not specified, assets will not be included in the APK
assets = "path/to/assets_folder"

# If set to true, makes the app run in full-screen, by adding the following line
# as an XML attribute to the manifest's <application> tag :
#     android:theme="@android:style/Theme.DeviceDefault.NoActionBar.Fullscreen
# Defaults to false.
fullscreen = false

# The maximum supported OpenGL ES version , as claimed by the manifest.
# Defaults to 2.0.
# See https://developer.android.com/guide/topics/graphics/opengl.html#manifest
opengles_version_major = 3
opengles_version_minor = 2

# Adds extra arbitrary XML attributes to the <application> tag in the manifest.
# See https://developer.android.com/guide/topics/manifest/application-element.html
[package.metadata.android.application_attributes]
"android:debuggable" = "true"
"android:hardwareAccelerated" = "true"

# Adds extra arbitrary XML attributes to the <activity> tag in the manifest.
# See https://developer.android.com/guide/topics/manifest/activity-element.html
[package.metadata.android.activity_attributes]
"android:screenOrientation" = "unspecified"
"android:uiOptions" = "none"

# Adds a uses-feature element to the manifest
# Supported keys: name, required, version
# The glEsVersion attribute is not supported using this section. 
# It can be specified using the opengles_version_major and opengles_version_minor values
# See https://developer.android.com/guide/topics/manifest/uses-feature-element
[[package.metadata.android.feature]]
name = "android.hardware.camera"

[[package.metadata.android.feature]]
name = "android.hardware.vulkan.level"
version = "1"
required = false

# Adds a uses-permission element to the manifest.
# Note that android_version 23 and higher, Android requires the application to request permissions at runtime.
# There is currently no way to do this using a pure NDK based application.
# See https://developer.android.com/guide/topics/manifest/uses-permission-element
[[package.metadata.android.permission]]
name = "android.permission.WRITE_EXTERNAL_STORAGE"
max_sdk_version = 18

[[package.metadata.android.permission]]
name = "android.permission.CAMERA"

Environment Variables

Cargo-apk sets environment variables which are used to expose the appropriate C and C++ build tools to build scripts. The primary intent is to support building crates which have build scripts which use the cc and cmake crates.

  • CC : path to NDK provided clang wrapper for the appropriate target and android platform.
  • CXX : path to NDK provided clang++ wrapper for the appropriate target and android platform.
  • AR : path to NDK provided ar
  • CXXSTDLIB : c++ to use the full featured C++ standard library provided by the NDK.
  • CMAKE_TOOLCHAIN_FILE : the path to the generated CMake toolchain. This toolchain sets the ABI, overrides any target specified, and includes the toolchain provided by the NDK.
  • CMAKE_GENERATOR : Unix Makefiles to default to Unix Makefiles as opposed to using the CMake default which may not be appropriate depending on platform.
  • CMAKE_MAKE_PROGRAM: Path to NDK provided make.

C++ Standard Library Compatibility Issues

When a crate links to the C++ standard library, the shared library version provided by the NDK is used. Unfortunately, dependency loading issues will cause the application to crash on older versions of android. Once lld linker issues are resolved on all platforms, cargo apk will be updated to link to the static C++ library. This should resolve the compatibility issues.

Comments
  • What to replace `arm-linux-androideabi` with in manifest?

    What to replace `arm-linux-androideabi` with in manifest?

    I'm trying to get a project to compile that previously (About 6 months ago) compiled, I get the following error when I try to compile it as is:

    error: unknown variant `arm-linux-androideabi`, expected one of `armv7-linux-androideabi`, `aarch64-linux-android`, `i686-linux-android`, `x86_64-linux-android` for key `package.metadata.android.build_targets` at line 51 column 1
    

    So, I try armv7-linux-androideabi, which successfully compiles and installs through adb, but fails to launch. I'm trying to run this on a Pixel 2, where I used to use arm-linux-androideabi, cpu-z reports the kernel arch is aarch64 (Which apparently doesn't work) and the closest I could find was armv7-linux-androideabi (Which doesn't work either).

    In PR #223 I read the following:

    • The default and supported build targets has changed. The default is to build on all targets supported by the current NDK. arm-linux-androideabi was removed. See README for supported targets.

    How might I go about making my app compile and run on my Pixel 2?

    On a side note, I used to clone cargo-apk locally and edit the NativeActivity code to remove the decoration and navigation bars (It's kind of difficult to play snake with them), where might I inject that code now? "Injected"/"replaced" code is here.

    opened by OptimisticPeach 20
  • Packaging linked shared libraries together

    Packaging linked shared libraries together

    Brief explanation:

    1. Getting list of needed shared libs using readelf
    2. Filtering out platform libs such as libandroid.so, liblog.so and etc.
    3. Collecting libs search paths from rustc args
    4. Finding needed libs in collected paths to add to apk
    • [X] Seek libs search paths in rustc args, i.e. "-L" arg with succeeding "native=" or "dependency="
    • [X] Get list of platform libraries by reading directory of version dependent libraries in NDK.
    • [X] Execute readelf -d for main shared library and seek for needed shared libs in the output by parsing lines contains "[NEEDED]" "Shared library: []".
    • [X] Exclude platform libraries from found needed libraries.
    • [X] Find needed shared libs in known paths.
    • [x] Add found shared libs to package.
    • [X] Print warning when needed shared library not found.
    • [x] Execute readelf -d for each found library recursively to completely resolve dependencies.

    Fix for #174

    opened by katyo 18
  • jni.h : No such file or directory

    jni.h : No such file or directory

    I just set up a linux virtualbox with the android sdk/ndk etc. When I try to run cargo apk build, the following error is printed:

    /home/pim/android-ndk-r16/sources/android/native_app_glue/android_native_app_glue.c:18:17: fatal error: jni.h: No such file or directory
     #include <jni.h>
                     ^
    compilation terminated.
    error: process didn't exit successfully: `/home/pim/android-ndk-r16/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-gcc /home/pim/android-ndk-r16/sources/android/native_app_glue/android_native_app_glue.c -c -o /home/pim/GitHub/project/target/android-artifacts/arm-linux-androideabi/android_native_app_glue.o --sysroot /home/pim/android-ndk-r16/platforms/android-18/arch-arm` (exit code: 1)
    

    Any idea why? I've set ANDROID_HOME and NDK_HOME to the corresponding root directories.

    opened by PvdBerg1998 18
  • Remove injected glue

    Remove injected glue

    Can we merge this? It's blocking the winit port. I stripped out the rest of the glue code, if someone want's to continue using it instead of android-ndk-rs they can use a previous release.

    It also fixes a bug where a minimal binary won't link to libandroid.so unless use glue is added to the file.

    opened by dvc94ch 13
  • ANativeActivity_onCreate not found

    ANativeActivity_onCreate not found

    After installing the master branch cargo-apk, and running cargo-apk build --release on examples\basic and succesfully installing the apk built with cargo-apk install I got the following error while running adb logcat:

    08-31 17:03:21.909  1565  2982 I ActivityManager: Start proc 26269:rust.example/u0a554 for activity rust.example/android.app.NativeActivity
    08-31 17:03:21.972  2718  3521 D OpenGLRenderer: endAllActiveAnimators on 0x7d0dd700 (RippleDrawable) with handle 0x854337e0
    08-31 17:03:21.974 26269 26269 W System  : ClassLoader referenced unknown path:
    08-31 17:03:21.987   817   904 I SFPerfTracer:      triggers: (rate: 0:2) (139306 sw vsyncs) (0 skipped) (3:866946 vsyncs) (5:1075669)
    08-31 17:03:22.059 26269 26269 W NativeActivity: ANativeActivity_onCreate not found
    08-31 17:03:22.060 26269 26269 D AndroidRuntime: Shutting down VM
    08-31 17:03:22.060 26269 26269 E AndroidRuntime: FATAL EXCEPTION: main
    08-31 17:03:22.060 26269 26269 E AndroidRuntime: Process: rust.example, PID: 26269
    08-31 17:03:22.060 26269 26269 E AndroidRuntime: java.lang.UnsatisfiedLinkError: Unable to load native library "/data/app/rust.example-KW3icy8gwyxnx_5Bv9gl4w==/lib/arm/libexample.so": undefined symbol: ANativeActivity_onCreate
    08-31 17:03:22.060 26269 26269 E AndroidRuntime:        at android.app.NativeActivity.onCreate(NativeActivity.java:174)
    08-31 17:03:22.060 26269 26269 E AndroidRuntime:        at android.app.Activity.performCreate(Activity.java:7032)
    08-31 17:03:22.060 26269 26269 E AndroidRuntime:        at android.app.Activity.performCreate(Activity.java:7023)
    08-31 17:03:22.060 26269 26269 E AndroidRuntime:        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1236)
    08-31 17:03:22.060 26269 26269 E AndroidRuntime:        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2814)
    08-31 17:03:22.060 26269 26269 E AndroidRuntime:        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2943)
    08-31 17:03:22.060 26269 26269 E AndroidRuntime:        at android.app.ActivityThread.-wrap11(Unknown Source:0)
    08-31 17:03:22.060 26269 26269 E AndroidRuntime:        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1630)
    08-31 17:03:22.060 26269 26269 E AndroidRuntime:        at android.os.Handler.dispatchMessage(Handler.java:106)
    08-31 17:03:22.060 26269 26269 E AndroidRuntime:        at android.os.Looper.loop(Looper.java:164)
    08-31 17:03:22.060 26269 26269 E AndroidRuntime:        at android.app.ActivityThread.main(ActivityThread.java:6626)
    08-31 17:03:22.060 26269 26269 E AndroidRuntime:        at java.lang.reflect.Method.invoke(Native Method)
    08-31 17:03:22.060 26269 26269 E AndroidRuntime:        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
    08-31 17:03:22.060 26269 26269 E AndroidRuntime:        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:811)
    08-31 17:03:22.063  1565  2988 W ActivityManager:   Force finishing activity rust.example/android.app.NativeActivity
    08-31 17:03:22.065  1565 26283 W DropBoxManagerService: Dropping: data_app_crash (1271 > 0 bytes)
    08-31 17:03:22.069  1565  1648 I ActivityManager: Showing crash dialog for package rust.example u0
    
    opened by derezzedex 11
  • Cargo apk build system rework and other enhancements

    Cargo apk build system rework and other enhancements

    See #212

    Changes

    • Updates dependencies to newer version. For example uses serde instead of rustc-serialize.
    • Reworks build process - Use a custom Executor with cargo::ops::compile_with_exec and injected code build a static libraries for each build target(ABI) and cargo target(binaries and examples). This allows support for multiple cargo targets. - Uses ndk-build to build the shared library for each build target. This gets rid of the need for the linker work around and fixes issues related to compatibility with newer NDKs which do not include GCC. - Updates supported build targets to match those supported by the current NDK. - Minor change to injector glue to work with new system for calling main(). - Use SDK provided tools to build and sign APKs. This removes the gradle dependency. - If an Android debug keystore exists then it uses this to sign the APK. Otherwise, it creates it using the keytool provided by the Java JRE or JDK. This was previously handled by the gradle build.
    • Fixes injected glue warnings related to 2018 edition.
    • Formats code using rustfmt. This does result in extra noise in the diff but it should help when reviewing future contributions by myself or others.
    • Adds support for building and installing multiple cargo targets.
    • Adds support for customing uses-feature and uses-permission portions of Android manifest via Cargo.toml.
    • Removes hard coded uses-permission from manifest. Thie avoid unintended permission request.
    • Adds an example demonstrating additional settings in Cargo.toml.
    • Adds an example of a crate which includes multiple cargo targets(binaries and examples).
    • Adds an integration test which uses cargo apk to build all the examples
    • Updates android_version(compile version) to 29 and target sdk version to 29. The min_sdk_version remains at 18.
    • Updates Dockerfile to be based on the latest official rust docker image. It also updates to the latest Android SDK and NDK. This makes it easier to update SDK and NDK versions moving forward.
    • Updates Dockerfile to run tests as part of the build process. Recommend building it as part of CI at some point.
    • Updates README to match changes. Links to and references the docker image provided at https://hub.docker.com/r/philipalldredge/cargo-apk. If merged, it would likely be better to setup an official rust-windowing organization on github and automatically build the docker image based on that. The linked docker image automatically updates based on my fork.

    Tested using the window example in https://github.com/mb64/winit/tree/android-eventloop-2.0 referenced in rust-windowing/winit#1001

    Potential Compatibility Changes

    Most of this shouldn't be a factor for users of the Docker image but it may require others to upgrade their Android SDK/NDK. I have not performed testing on a large number of Android SDK and NDK combinations.

    • The default android version and target sdk version requires a newer Android platform. This prevents warnings when running on newer Android devices. The setting can be adjusted as appropriate. In general it is recommended to target the latest android devces.
    • The default and supported build targets has changed. The default is to build on all targets supported by the current NDK. arm-linux-androideabi was removed. See README for supported targets.
    • The removal of the hard coded uses-permission may result in minor issues when targeting older versions of android. Users will need to add the permission to the Cargo.toml. For newer version of android, users will also need to request permission at runtime using a Java API. A rust API that uses JNI to do that is needed but that is a separate concern from the build process.

    Related Issues

    Closes #212, #208, #191, #138, #123, #211, #202, #198, #192, #164, #134, (Reason for some of the closing is removal of gradle. Some of them may have been resolved by other pull requests but should be resolved by this as well.)

    Likely fixes: #109

    opened by philip-alldredge 11
  • The apk builder is now a Cargo subcommand

    The apk builder is now a Cargo subcommand

    Turns the apk-builder into cargo-apk, which provides the cargo apk Cargo subcommand.

    Using it will:

    • Build a android-artifacts directory inside target.
    • Compile your package for the given list of platforms (not configurable yet, defaults to just arm-android).
    • Compile android_native_glue for each platform.
    • Compile some glue that will make android_main call Rust's main.
    • Setup the build directory and run ant.

    To do:

    • Add parsing of a CargoApk.toml file that can indicate various information about the package.
    • Add parsing the .cargo/config file to find out the path to the Android SDK and NDK.
    • Add various subcommands, like cargo apk install that would invoke adb.
    • Make everything cleaner. It can fail in several ways, and error messages aren't very explicit.

    The idea is that it should now be much simpler to build an apk by just running cargo install cargo-apk followed with cargo apk, without having to modify your source code or anything fancy. You would be able to configure your build with a CargoApk.toml file whose content remains to be determined. Another advantage is that the build directory wouldn't be destroyed, making it possible to easily tweak and debug builds.

    The setup would also be greatly simplified by just having to install the NDK, the SDK, and a compatible rustc thanks to rustup. An NDK standalone toolchain would no longer be needed.

    cc @ozkriff @larsbergstrom (@brson and @alexcrichton maybe as well?)

    opened by tomaka 11
  • Missing arm-linux-androideabi-gcc

    Missing arm-linux-androideabi-gcc

    Following the readme instructions and reaching the point of running it:

    cargo apk build
    Compiling android_native_app_glue.c
    error: could not execute process `/hub/tools/android-ndk-r19c/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-gcc /hub/tools/android-ndk-r19c/sources/android/native_app_glue/android_native_app_glue.c -c -o /hub/moz/wr/target/android-artifacts/armv7-linux-androideabi/android_native_app_glue.o --sysroot /hub/tools/android-ndk-r19c/platforms/android-28/arch-arm` (never executed)
    
    Caused by:
      No such file or directory (os error 2)
    

    Checking the binaries in this folder:

    kvark@ant /hub/tools/android-ndk-r19c/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin $ ls
    arm-linux-androideabi-addr2line  arm-linux-androideabi-c++filt  arm-linux-androideabi-gprof   arm-linux-androideabi-ld.gold  arm-linux-androideabi-objdump  arm-linux-androideabi-size
    arm-linux-androideabi-ar         arm-linux-androideabi-dwp      arm-linux-androideabi-ld      arm-linux-androideabi-nm       arm-linux-androideabi-ranlib   arm-linux-androideabi-strings
    arm-linux-androideabi-as         arm-linux-androideabi-elfedit  arm-linux-androideabi-ld.bfd  arm-linux-androideabi-objcopy  arm-linux-androideabi-readelf  arm-linux-androideabi-strip
    
    opened by kvark 10
  • Unable to detect build tool version folder with symlink

    Unable to detect build tool version folder with symlink

    Description

    I download the build tools through NixOS package definition with build tools version folder (e.g. 28.0.3) as symbolic link. I am open whether case like this will/won't be supported (since it is an edge case but that how NixOS done thing).

    Expected

    Detect the build tools version and run.

    Actual

    $ cargo apk build
    error: Unable to determine build tools version
    
    opened by Abdillah 7
  • android_glue::add_sender: Sender error

    android_glue::add_sender: Sender error

    I get a panic when using the android_glue::add_sender api:

    thread '<unnamed>' panicked at 'assertion failed: (*self.data.get()).is_none()', src/libstd/sync/mpsc/oneshot.rs:90:13
    

    I would like to provide a larger backtrace, but it is quickly followed by a SIGABRT from the system:

    --------- beginning of crash
    F libc    : Fatal signal 6 (SIGABRT), code -6 (SI_TKILL) in tid 9521 (ust.doze_widget), pid 9505 (ust.doze_widget)
    V threaded_app: Resume: 0x7b5b135280
    I crash_dump64: obtaining output fd from tombstoned, type: kDebuggerdTombstone
    I /system/bin/tombstoned: received crash request for pid 9521
    I crash_dump64: performing dump of process 9505 (target tid = 9521)
    F DEBUG   : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
    F DEBUG   : Build fingerprint: 'google/walleye/walleye:9/PQ3A.190801.002/5670241:user/release-keys'
    F DEBUG   : Revision: 'MP1'
    F DEBUG   : ABI: 'arm64'
    F DEBUG   : pid: 9505, tid: 9521, name: ust.doze_widget  >>> rust.doze_widget <<<
    F DEBUG   : signal 6 (SIGABRT), code -6 (SI_TKILL), fault addr --------
    F DEBUG   :     x0  0000000000000000  x1  0000000000002531  x2  0000000000000006  x3  0000000000000008
    F DEBUG   :     x4  0000000000000000  x5  0000000000000000  x6  0000000000000000  x7  0000007b42ec0000
    F DEBUG   :     x8  0000000000000083  x9  0000007bdddf89a0  x10 fffffff87ffffbdf  x11 0000000000000001
    F DEBUG   :     x12 0000000000000001  x13 0000000000000000  x14 ffffffffffffffff  x15 0000000000000000
    F DEBUG   :     x16 0000007bdde312c8  x17 0000007bddd6f2d8  x18 0000007b453ec23a  x19 0000000000002521
    F DEBUG   :     x20 0000000000002531  x21 0000000000000083  x22 0000007b4374a7ac  x23 0000007b453ec130
    F DEBUG   :     x24 0000007b453ec130  x25 000000000000000d  x26 0000000000000001  x27 0000007b43794a9c
    F DEBUG   :     x28 000000000000001c  x29 0000007b453eaf70
    F DEBUG   :     sp  0000007b453eaf30  lr  0000007bddd63a90  pc  0000007bddd63abc
    F DEBUG   :
    F DEBUG   : backtrace:
    F DEBUG   :     #00 pc 0000000000021abc  /system/lib64/libc.so (abort+124)
    F DEBUG   :     #01 pc 00000000008d1224  /data/app/rust.doze_widget-P-GGnI-kpfm2VhbJLCPJDw==/lib/arm64/libdoze_widget.so (uw_init_context_1+84)
    W ActivityManager:   Force finishing activity rust.doze_widget/android.app.NativeActivity
    

    Times and pid (I think) are omitted for brevity.

    I have no unsafe code on my side, but while compiling I get

    warning: use of deprecated item 'std::mem::uninitialized': use `mem::MaybeUninit` instead
       --> Z:\android\doze_widget\doze_widget\target\android-artifacts\debug\injected-glue\lib.rs:348:61
        |
    348 |             let mut source: *mut ffi::android_poll_source = mem::uninitialized();
        |                                                             ^^^^^^^^^^^^^^^^^^
    

    Which might explain it, so I changed it on my local version to use MaybeUninit as follows (Which should probably be done either way):

    let mut events = mem::MaybeUninit::uninit();
    let mut source: mem::MaybeUninit<*mut ffi::android_poll_source> = mem::MaybeUninit::uninit();
    
    // A `-1` means to block forever, but any other positive value
    // specifies the number of milliseconds to block for, before
    // returning.
    let code = ffi::ALooper_pollAll(-1, ptr::null_mut(), events.as_mut_ptr(),
                                    source.as_mut_ptr() as *mut _ as *mut _);
    if code == ffi::ALOOPER_POLL_WAKE {
        send_event(Event::Wake)
    }
    
    // If the application thread has exited then we need to exit also.
    if is_app_thread_terminated().0 {
        // Not sure exactly how to do this, or what might be the proper
        // manner in which to do it.
        //
        // (1) hide ourselves by switching to home screen
        // (2) display message that we have finished
        // (3) do nothing like we are doing now
        //
        // We must keep this thread going so it can service events, else
        // the user will get a locked UI until the system terminates our
        // process. So we continue processing events..
    }
    let source = source.assume_init();
    // Processing the event
    if !source.is_null() {
        ((*source).process)(ANDROID_APP, source);
    }
    

    Which unfortunately didn't resolve the problem. I'm not well versed on how the event system works.

    The panic occurs here, on the docs version of the code and here on github.

    opened by OptimisticPeach 7
  • Fixes building of crates containing inner attributes.

    Fixes building of crates containing inner attributes.

    Creates a temporary file along side the crate root rather than using "lib.rs" in the target directory. Temporary file contains the user's crate root source file as well as the android_main Added test to ensure build crates with inner attributes work.

    Closes #229

    opened by philip-alldredge 7
  • Issues with cargo-apk + winit 0.19.0

    Issues with cargo-apk + winit 0.19.0

    I'm trying to use cargo-apk with winit 0.19.0.

    Sadly when I run cargo apk build --target ... I get the following error:

    = note: /root/src/target/aarch64-linux-android/debug/deps/winittest-5ef4fa9e35ece31e.56g2qny4080fqnx9.rcgu.o: In function `android_glue::get_native_window::h9f6ad735a1f5e276':
              /usr/local/cargo/registry/src/github.com-1ecc6299db9ec823/android_glue-0.2.3/src/lib.rs:123: undefined reference to `cargo_apk_injected_glue_get_native_window'
              /root/src/target/aarch64-linux-android/debug/deps/libwinit-cb9bde4e4aad5599.rlib(winit-cb9bde4e4aad5599.winit.3jes6306-cgu.7.rcgu.o): In function `android_glue::add_sender::h7785d30e730c9e30':
              /usr/local/cargo/registry/src/github.com-1ecc6299db9ec823/android_glue-0.2.3/src/lib.rs:77: undefined reference to `cargo_apk_injected_glue_add_sender'
              /root/src/target/aarch64-linux-android/debug/deps/libwinit-cb9bde4e4aad5599.rlib(winit-cb9bde4e4aad5599.winit.3jes6306-cgu.7.rcgu.o): In function `android_glue::set_multitouch::h6397524dfc3a3cc3':
              /usr/local/cargo/registry/src/github.com-1ecc6299db9ec823/android_glue-0.2.3/src/lib.rs:102: undefined reference to `cargo_apk_injected_glue_set_multitouch'
              /root/src/target/aarch64-linux-android/debug/deps/libwinit-cb9bde4e4aad5599.rlib(winit-cb9bde4e4aad5599.winit.3jes6306-cgu.7.rcgu.o): In function `android_glue::get_native_window::h0c5643fa0d486f75':
              /usr/local/cargo/registry/src/github.com-1ecc6299db9ec823/android_glue-0.2.3/src/lib.rs:123: undefined reference to `cargo_apk_injected_glue_get_native_window'
              clang: error: linker command failed with exit code 1 (use -v to see invocation)
    

    What causes this issue? Is it because winit is a dependency and I don't use android_glue directly?

    opened by VZout 6
  • Cannot find value `HOST_TAG` in this scope

    Cannot find value `HOST_TAG` in this scope

    I'm on Arch Linux.

    $ docker run -e PKG_CONFIG_ALLOW_CROSS=1 --rm -v "$(pwd):/root/src" \
       -w /root/src philipalldredge/cargo-apk cargo apk build
    
    ...
    
    error[E0425]: cannot find value `HOST_TAG` in this scope
      --> src/ops/build/util.rs:37:43
       |
    37 |     config.ndk_path.join("prebuild").join(HOST_TAG).join("make")
       |                                           ^^^^^^^^ not found in this scope
    
    error[E0425]: cannot find value `HOST_TAG` in this scope
      --> src/ops/build/util.rs:47:15
       |
    47 |         .join(HOST_TAG)
       |               ^^^^^^^^ not found in this scope
    
    error: aborting due to 2 previous errors
    

    Without PKG_CONFIG_ALLOW_CROSS I was getting openssl errors.

    Seems like the cfg statements aren't getting hit properly?

    What's weird is that when I run this program inside the same docker container it outputs "You are running linux".

    sudo docker run --rm -v "$(pwd):/root/src"    -w /root/src philipalldredge/cargo-apk cargo run
    
    opened by justinmoon 0
  • Common problems with linking with static c++ libs

    Common problems with linking with static c++ libs

    I developed bindings to c++ library, which widely uses global variables, which requires runtime initialization/finalization. The library builds using clang++ from android NDK.

    I have many linking errors like an error: undefined reference to '__dso_handle' when I build application.

    I'm sure that this is common problem, but I still cannot find appropriate workaround, which can help solve this.

    I guess that linker itself should use appropriate crt*.o module to deal around it but I don't know details why this is not so.

    opened by katyo 1
  • Docker image auto-publishing failing to upload

    Docker image auto-publishing failing to upload

    Command is failing with following message:

    #!/bin/sh -eo pipefail
    echo "$DOCKERHUB_PASSWORD" | docker login -u $DOCKERHUB_LOGIN --password-stdin
    docker push $IMAGE_NAME
    
    Error response from daemon: Get https://registry-1.docker.io/v2/: unauthorized: incorrect username or password
    Exited with code 1
    

    cc @tomaka

    opened by Osspial 3
  • Expose nicer JNI/NDK interface

    Expose nicer JNI/NDK interface

    Currently it is difficult to interact with the JNI and NDK through rust. This issue is asking for:

    • A way to insert code called on the main thread at startup (In java, or preferably rust)
    • A more exposed java interface for more complex calls to java code

    This can be mostly covered by android-ndk-rs but a portion of it should probably be done here.

    This is closer to a goal than an issue.

    opened by OptimisticPeach 9
Owner
Rust Windowing
Assorted Windowing Stuff, in Rust
Rust Windowing
Android-related tools for building and developing applications 🛠

Rust Android Tools Android-related tools for building and developing applications: Name Description Status aapt2 Android Asset Packaging Tool ✅ bundle

DodoRare 6 Dec 31, 2022
Android / iOS app with shared Rust logic

Rust core for native Android and iOS apps [TODO iOS badge] This is an example that shows how to use a shared Rust core in native Android and iOS apps.

Ivan Schütz 193 Dec 5, 2022
🤖🦀 A rust native replacement for Android's `sdkmanager`

???? A rust native replacement for Android's `sdkmanager`

Traverse Research 13 Dec 13, 2022
Android / iOS app with shared Rust logic

Rust core for native Android and iOS apps [TODO iOS badge] This is an example that shows how to use a shared Rust core in native Android and iOS apps.

null 193 Dec 5, 2022
Rust implementation of NearbyShare/QuickShare from Android for Linux.

rquickshare NearbyShare/QuickShare for Linux (WIP) How to use rquickshare offers two options for using its file sharing capabilities: command line (CM

Martin André 3 Feb 28, 2024
android-pathfinding

android-pathfinding Android pathfinding dependencies { implementation 'com.github.planet0104:android-pathfinding:1.0.0' } int[][] grid = new i

Jia Ye 1 Dec 17, 2021
Android resource file parsing & writing

arsc arsc is a Rust library that provides the ability to parse and write Android resource file (arsc) [dependencies] arsc = "0.1" Compiler support: ru

Yaxin Cheng 7 Dec 25, 2022
An Android application for ruffle.rs

This is a native Android application for Ruffle. It is in a very early stage. Prebuilt APKs The latest (successful) Actions run (here) should have a d

TÖRÖK Attila 28 Dec 21, 2022
Run all your Linux graphical apps on Android 💖✨✨✨

Waylovely Run all your Linux graphical apps on Android ?? ✨ ✨ ✨ The Android windowing system is different than those in desktop operating systems. In

Waylovely Project 14 Nov 23, 2022
Tokio based client library for the Android Debug Bridge (adb) based on mozdevice

forensic-adb Tokio based client library for the Android Debug Bridge (adb) based on mozdevice for Rust. Documentation This code has been extracted fro

null 6 Mar 31, 2023
Using Rust to create an iOS static library

ObjCrust A modified ObjCrust which uses Rust cross-compiler. Cross-compiler needs to be built first (note: it is on a separate branch now, so don't fo

Valerii Hiora 39 May 10, 2021
rust on pebble - functional with limited capabilities

Pebble.rs Pebble.rs is a crate that allows rust to be used to develop Pebble applications. It is compatible with SDK 3.0 and is known to work on the a

Andrew Foote 44 Aug 13, 2022
A Rust crate to load a shared library into a target process without using ptrace.

Intruducer A Rust crate to load a shared library into a target process without using ptrace. This is a portable rewrite of dlinject. Compatibility It

null 90 Jan 3, 2023
Fable Rust Raytracer - iOS version

Fable Rust Raytracer - iOS version Originally made by @ncave (https://github.com/ncave/fable-raytracer), port to iOS by @delneg Pre-requisites Rust, b

Denis 4 May 2, 2022
APK manifest & resources parser in Rust.

BXMLRS bxmlrs is a Rust library (WIP) for parsing binary Android XML files (AndroidManifest.xml). Usage use bxmlrs::parser; use quick_xml::reader::Rea

null 6 Oct 21, 2023
Simplified glue code generation for Deno FFI libraries written in Rust.

deno_bindgen This tool aims to simplify glue code generation for Deno FFI libraries written in Rust. Quickstart # install CLI deno install -Afq -n den

Divy Srivastava 173 Dec 17, 2022
Simple template to use csr and ssr leptos with tauri for ios/android/windows/macos/linux and web dev

Tailwind-Leptos-Tauri Template Simple template to use csr and ssr leptos with tauri for ios/android/windows/macos/linux and web dev Just clone the rep

Victor Batarse 11 Mar 10, 2024
Advanced Fuzzing Library - Slot your Fuzzer together in Rust! Scales across cores and machines. For Windows, Android, MacOS, Linux, no_std, ...

LibAFL, the fuzzer library. Advanced Fuzzing Library - Slot your own fuzzers together and extend their features using Rust. LibAFL is written and main

Advanced Fuzzing League ++ 1.2k Dec 29, 2022
A simple library for use one Rust code in multi platforms such as WebAssembly, Android and iOS

chameleon chameleon is a simple library for use one Rust code in multi platforms such as WebAssembly, Android and iOS. Key Features TBA Quick Start TB

Chris Ohk 3 Oct 18, 2021
Cross-platform GUI written in Rust using ADB to debloat non-rooted android devices. Improve your privacy, the security and battery life of your device.

Universal Android Debloater GUI DISCLAIMER: Use it at your own risk. I am not responsible for anything that could happen to your phone. This software

w1nst0n 7k Jan 7, 2023