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 glue #13

Merged
merged 17 commits into from
Apr 20, 2020
Merged
26 changes: 20 additions & 6 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,16 @@ jobs:
fail-fast: false
matrix:
rust-channel: ['stable', 'nightly']
rust-target: ['arm-linux-androideabi', 'armv7-linux-androideabi', 'aarch64-linux-android', 'i686-linux-android', 'x86_64-linux-android']
rust-target: [
'armv7-linux-androideabi',
'aarch64-linux-android',
'i686-linux-android',
'x86_64-linux-android',
]

steps:
- uses: actions/checkout@v1

- name: Download NDK
run: |
curl -LO https://dl.google.com/android/repository/android-ndk-r20-linux-x86_64.zip
Expand All @@ -28,13 +33,22 @@ jobs:

- name: Check formating
run: cargo fmt --all -- --check
- name: Check docs
run: cargo test --manifest-path android-ndk/Cargo.toml --doc --target=x86_64-unknown-linux-gnu --features rustdoc

- name: Run tests
run: cargo test --package android-ndk-sys --lib --target=x86_64-unknown-linux-gnu
run: |
cd ndk-sys && cargo test --features test && cd ..
cd ndk && cargo test --features rustdoc --doc && cd ..
cargo test -p ndk-build
cargo test -p cargo-apk

- name: Install cargo-apk
run:
cargo install --path cargo-apk

- name: Check compiling on target ${{ matrix.rust-target }}
run: |
export NDK_HOME="$GITHUB_WORKSPACE/android-ndk-r20"
export CC="$NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/clang"
export AR="$NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ar"
cargo check --package android-ndk --target=${{ matrix.rust-target }}
cargo check -p ndk --target ${{ matrix.rust-target }}
cargo apk build -p ndk-examples --target ${{ matrix.rust-target }} --examples
9 changes: 6 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
[workspace]

members = [
"android-ndk-sys",
"android-ndk",
"ndk",
"ndk-build",
"ndk-examples",
"ndk-glue",
"ndk-sys",
"cargo-apk",
]
70 changes: 57 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,62 @@
# `android-ndk`: Rust bindings of the Android NDK
# Rust on Android

[![Build Status](https://travis-ci.org/mb64/android-ndk-rs.svg?branch=master)](https://travis-ci.org/mb64/android-ndk-rs)
[![Crates.io Status](https://meritbadge.herokuapp.com/android-ndk-sys)](https://crates.io/crates/android-ndk-sys)
[![Docs.rs Status](https://docs.rs/android-ndk-sys/badge.svg)](https://docs.rs/android-ndk-sys)
[![Crates.io Status](https://meritbadge.herokuapp.com/android-ndk)](https://crates.io/crates/android-ndk)
[![Docs.rs Status](https://docs.rs/android-ndk/badge.svg)](https://docs.rs/android-ndk)
- Raw FFI bindings to the NDK ![ndk-sys-docs][ndk-sys-badge]
- Safe abstraction of the bindings ![ndk-docs][ndk-badge]
- Startup code ![ndk-glue-docs][ndk-glue-badge]
- Everything for building apk's ![ndk-build-docs][ndk-build-badge]
- Build tool ![cargo-apk-docs][cargo-apk-badge]

This is a work in progress at the moment.
## Hello world
`Cargo.toml`
```toml
[lib]
crate-type = ["lib", "cdylib"]
```

`android-ndk-sys` contains the raw FFI bindings, pre-generated from NDK r20, and `android-ndk`
provides a safe API over it.
`src/lib.rs`
```rust
#[cfg(target_os = "android")]
ndk_glue::ndk_glue!(main);

Other helpful crates for Android:
pub fn main() {
println!("hello world");
}
```

* [`jni`](https://crates.io/crates/jni), JNI bindings for Rust
* [`android_logger`](https://crates.io/crates/android_logger) and [`ndk-logger`](https://crates.io/crates/ndk-logger),
Android backends for the `log` crate
`src/main.rs`
```rust
fn main() {
$crate::main();
}
```

```sh
cargo install cargo-apk
cargo apk run
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alright, so yesterday I tried this, which didn't work:

  ~/Do…ts/gfx/eco3/glutin                                                                                                                           SIGINT(2) ↵  69%  
  12:39  17.02.20  cargo apk run --example window
   Compiling glutin v0.23.0-alpha1 (/home/gentz/Documents/gfx/eco3/glutin)
    Finished dev [unoptimized + debuginfo] target(s) in 6.00s
Error: Path "/home/gentz/Documents/gfx/eco3/glutin/target/aarch64-linux-android/debug/examples/libwindow.so" doesn't exist.

You mention it needs to be cdylib, so I tried this.

  ~/Do…ts/gfx/eco3/glutin                                                                                                                      1 ↵  6.41981s   69%  
  12:39  17.02.20  RUSTFLAGS="--crate-type cdylib" cargo apk run --example window  
   Compiling cfg-if v0.1.10
   Compiling lazy_static v1.4.0
   Compiling scopeguard v1.1.0
   Compiling adler32 v1.0.4
error: `#[panic_handler]` function required, but not found

error: language item required, but not found: `eh_personality`

error: aborting due to 2 previous errors

error: could not compile `cfg-if`.
warning: build failed, waiting for other jobs to finish...
error: `#[panic_handler]` function required, but not found

error: language item required, but not found: `eh_personality`

error: aborting due to 2 previous errors

error: could not compile `scopeguard`.
warning: build failed, waiting for other jobs to finish...
error: build failed
Error: Command 'cargo build --target aarch64-linux-android --example window' had a non-zero exit code.

I did some googling, and this gets rid of the eh_personality error:

  ~/Do…ts/gfx/eco3/glutin                                                                                                                      1 ↵  1.15127s   69%  
  12:40  17.02.20  RUSTFLAGS="--crate-type cdylib -C panic=abort" cargo apk run --example window
   Compiling cfg-if v0.1.10
   Compiling lazy_static v1.4.0
   Compiling scopeguard v1.1.0
   Compiling adler32 v1.0.4
error: `#[panic_handler]` function required, but not found

error: aborting due to previous error

error: could not compile `cfg-if`.
warning: build failed, waiting for other jobs to finish...
error: `#[panic_handler]` function required, but not found

error: aborting due to previous error

error: could not compile `scopeguard`.
warning: build failed, waiting for other jobs to finish...
error: build failed
Error: Command 'cargo build --target aarch64-linux-android --example window' had a non-zero exit code.

Implementing panic handler on a function wouldn't fix that error, though, so this readme leaves me kind of stumped :/

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This works for me:

diff --git a/Cargo.toml b/Cargo.toml
index 3898294..b2c6232 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -74,3 +74,7 @@ glutin_glx_sys = { version = "0.2.0", path = "../glutin_sys/glutin_glx_sys" }
 parking_lot = "0.10.0"
 glutin_x11_sym = { version = "0.1.0", path = "../glutin_x11_sym" }
 x11-dl = "2.18.4"
+
+[[example]]
+name = "window"
+crate-type = ["cdylib"]

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The rustflags env the way you set it gives me the same error

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The problem seems to be that it tries to compile all crates as cdylib, when only the example needs to be cdylib. Trying to compile a proc-macro as cdylib is no good.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also note that it'll crash in any case. we could add support to the ios-example and rename it to mobile-example?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, it is not making an apk at all.

  ~/Do…ts/gfx/eco3/glutin                                                                                                                          0.04887s   70%  
  15:49  17.02.20  rm target -rf    

  ~/Do…ts/gfx/eco3/glutin                                                                                                                          0.25960s   70%  
  15:51  17.02.20  cargo apk run --example window --manifest-path android/Cargo.toml --target aarch64-linux-android
ERROR: unable to open 'android/target/debug/apk/examples/window-unaligned.apk' as Zip file for writing
   Compiling glutin v0.23.0-alpha1 (/home/gentz/Documents/gfx/eco3/glutin/android)
    Finished dev [unoptimized + debuginfo] target(s) in 10.09s
ERROR: failed opening/creating 'android/target/debug/apk/examples/window-unaligned.apk' as Zip file
Error: Command '/home/gentz/Android/Sdk/build-tools/29.0.3/aapt add android/target/debug/apk/examples/window-unaligned.apk lib/arm64-v8a/libwindow.so' had a non-zero exit code.

  ~/Do…ts/gfx/eco3/glutin                                                                                                                     1 ↵  10.47813s   70%  
  15:51  17.02.20  find target android/target | grep window-u
find: ‘target’: No such file or directory

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll look into it tomorrow, need to sleep...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does it still do that after I reverted the cargo-rustc hack?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still broken when using --manifest-path:

  ~/Do…ts/gfx/eco3/glutin                                                                                                                                       70%  
  17:14  18.02.20  find target android/target | grep window-u | xargs rm

  ~/Do…ts/gfx/eco3/glutin                                                                                                                          0.07800s   70%  
  17:14  18.02.20  find target android/target | grep window-u           

  ~/Do…ts/gfx/eco3/glutin                                                                                                                    0|1 ↵  0.03062s   70%  
  17:14  18.02.20  cargo apk run --example window --manifest-path android/Cargo.toml --target aarch64-linux-android
ERROR: unable to open 'android/target/debug/apk/examples/window-unaligned.apk' as Zip file for writing
   Compiling glutin v0.23.0-alpha1 (/home/gentz/Documents/gfx/eco3/glutin/android)
    Finished dev [unoptimized + debuginfo] target(s) in 10.30s
ERROR: failed opening/creating 'android/target/debug/apk/examples/window-unaligned.apk' as Zip file
Error: Command '/home/gentz/Android/Sdk/build-tools/29.0.3/aapt add android/target/debug/apk/examples/window-unaligned.apk lib/arm64-v8a/libwindow.so' had a non-zero exit code.

  ~/Do…ts/gfx/eco3/glutin                                                                                                                     1 ↵  10.75456s   70%  
  17:14  18.02.20  find target android/target | grep window-u

  ~/Do…ts/gfx/eco3/glutin                                                                                                                    0|1 ↵  0.03277s   70%  
  17:15  18.02.20  cargo apk run --example window --manifest-path android/Cargo.toml --target aarch64-linux-androi 
Error: Target is not supported.

  ~/Do…ts/gfx/eco3/glutin                                                                                                                      1 ↵  0.11674s   70%  
  17:15  18.02.20  cargo apk run --example window --manifest-path android/Cargo.toml                              
ERROR: unable to open 'android/target/debug/apk/examples/window-unaligned.apk' as Zip file for writing
   Compiling glutin v0.23.0-alpha1 (/home/gentz/Documents/gfx/eco3/glutin/android)
    Finished dev [unoptimized + debuginfo] target(s) in 11.00s
ERROR: failed opening/creating 'android/target/debug/apk/examples/window-unaligned.apk' as Zip file
Error: Command '/home/gentz/Android/Sdk/build-tools/29.0.3/aapt add android/target/debug/apk/examples/window-unaligned.apk lib/arm64-v8a/libwindow.so' had a non-zero exit code.

  ~/Do…ts/gfx/eco3/glutin                                                                                                                     1 ↵  11.54048s   70%  
  17:15  18.02.20  find target android/target | grep window-u                                                     

  ~/Do…ts/gfx/eco3/glutin                                                                                                                    0|1 ↵  0.02819s   70%  
  17:15  18.02.20  cd android/                                                      

  ~/Do…ts/gfx/eco3/gl…in/android                                                                                                                   0.00127s   70%  
  17:15  18.02.20  cargo apk run --example window                                   
   Compiling glutin v0.23.0-alpha1 (/home/gentz/Documents/gfx/eco3/glutin/android)
    Finished dev [unoptimized + debuginfo] target(s) in 10.11s
 'lib/arm64-v8a/libwindow.so'...
Verifying alignment of /home/gentz/Documents/gfx/eco3/glutin/android/target/debug/apk/examples/window.apk (4)...
      49 AndroidManifest.xml (OK - compressed)
     970 lib/arm64-v8a/libwindow.so (OK - compressed)
Verification succesful
Generating 2,048 bit RSA key pair and self-signed certificate (SHA256withRSA) with a validity of 10,000 days
	for: CN=Android Debug, O=Android, C=US
[Storing /home/gentz/.android/debug.keystore]

Warning:
The JKS keystore uses a proprietary format. It is recommended to migrate to PKCS12 which is an industry standard format using "keytool -importkeystore -srckeystore /home/gentz/.android/debug.keystore -destkeystore /home/gentz/.android/debug.keystore -deststoretype pkcs12".
error: no devices/emulators found
Performing Push Install
adb: error: failed to get feature set: no devices/emulators found
Error: Command '/home/gentz/Android/Sdk/platform-tools/adb install -r /home/gentz/Documents/gfx/eco3/glutin/android/target/debug/apk/examples/window.apk' had a non-zero exit code.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The problem is that the path returned from cargo-subcommand to the Cargo.toml is relative to the current_dir, but the aapt command is executed from the target/{profile}/apk dir. Should be fixed now

```

## Logging and stdout
Stdout is redirected to the android log api when using `ndk-glue`. Any logger that logs to
stdout should therefore work.

## JNI
TODO: talk more about jni and add some examples

- [`jni`](https://crates.io/crates/jni), JNI bindings for Rust

## Winit and glutin
TODO shameless plug

## Flutter
TODO shameless plug

[ndk-sys-docs]: https://docs.rs/ndk-sys
[ndk-sys-badge]: https://docs.rs/ndk-sys/badge.svg
[ndk-docs]: https://docs.rs/ndk
[ndk-badge]: https://docs.rs/ndk/badge.svg
[ndk-glue-docs]: https://docs.rs/ndk-glue
[ndk-badge]: https://docs.rs/ndk-glue/badge.svg
[ndk-build-docs]: https://docs.rs/ndk-build
[ndk-build-badge]: https://docs.rs/ndk-build/badge.svg
[cargo-apk-docs]: https://docs.rs/cargo-apk
[cargo-apk-badge]: https://docs.rs/cargo-apk/badge.svg
2 changes: 0 additions & 2 deletions android-ndk-sys/.cargo/config

This file was deleted.

Loading