Read more about Rust, a relatively small but powerful programming language.
https://www.rust-lang.org/
Rust has a steep learning curve and recommends checking out Yin Wang’s article “How to Master All Programming Languages” at the following address before getting started:
https://www.yinwang.org/blog-cn/2017/07/06/master-pl
To learn a language, it is important to master its language features.
Wang gives some examples of language features:
-
Variable definitions
-
Arithmetic operations
-
For loop, while loop
-
Function definition, function call
-
recursive
-
Static type system
-
Type inference
-
Lambda functions
-
object-oriented
-
The garbage collection
-
Pointer arithmetic
-
Goto statements
See if these features look like some programming language book directories 🤔
You can also compare your mastery of rust with these language features.
So what makes Rust so powerful? When Kotlin first came out, he was talking about empty security, making up for the lack of Java in this area. Rust, on the other hand, contrasts C++ and makes up for C++ ‘s lack of null and wild Pointers (dangling Pointers).
Here are some features from Wikipedia that I haven’t tried yet:
Rust is a general-purpose, compiled programming language developed by Mozilla. The design criteria are “safe, concurrent, practical”, supporting functional, heuristic, procedural, and object-oriented programming styles.
There are already some teams developing with Rust in China, so you can wait and see before deciding whether to invest in it or not
Rust compiles so practices
The following is a practice for building Android dynamic libraries with Rust, with reference to examples from Mozilla, linked below.
Install the rust
The first step is to install rust with the following command:
1curl https://sh.rustup.rs -sSf | sh
Copy the code
Run the following command to output the RUST version and check whether the installation is successful:
1rustc --version
Copy the code
Configure Rust cross-compilation
Ensure that the Android SDK directory is configured in the system environment.
1export ANDROID_HOME=/Users/$USER/Library/Android/sdk2export NDK_HOME=$ANDROID_HOME/ndk-bundle
Copy the code
Then run the following command:
1mkdir NDK2${NDK_HOME}/build/tools/make_standalone_toolchain.py --api 26 --arch arm64 --install-dir NDK/arm643${NDK_HOME}/build/tools/make_standalone_toolchain.py --api 26 --arch arm --install-dir NDK/arm4${NDK_HOME}/build/tools/make_standalone_toolchain.py --api 26 --arch x86 --install-dir NDK/x86
Copy the code
This is done by executing python scripts in the NDK-bundle directory to create a compilation environment for ARM64, ARM, and x86 platforms.
Add the environment to rust’s configuration.
To create the cargo-config.toml file, enter the following:
1[target.aarch64-linux-android] 2ar = "<path>/NDK/arm64/bin/aarch64-linux-android-ar" 3linker = "<path>/NDK/arm64/bin/aarch64-linux-android-clang" 4 5[target.armv7-linux-androideabi] 6ar = "<path>/NDK/arm/bin/arm-linux-androideabi-ar" 7linker = "<path>/NDK/arm/bin/arm-linux-androideabi-clang" 8 9[target.i686-linux-android]10ar = "<path>/NDK/x86/bin/i686-linux-android-ar"11linker = "<path>/NDK/x86/bin/i686-linux-android-clang"
Copy the code
Remember to replace it with the path where the NDK folder is located.
Then execute:
1cp cargo-config.toml ~/.cargo/config
Copy the code
Move cargo-config.toml to the ~/.cargo/ directory.
Run the following command:
1rustup target add aarch64-linux-android armv7-linux-androideabi i686-linux-android
Copy the code
That completes the configuration of the cross-compile environment.
Developed and compiled by Rust
Now that it’s time to get into the specifics of Rust development, the JetBrains series of IntelliJ IDEA is recommended. You don’t need to activate it, just use the community edition, and install the Rust plug-in and have fun writing code.
Run the following command to create a project directory:
1mkdir rust-android2cd rust-android
Copy the code
Then create the Rust project:
1cargo new rust --lib2cd rust
Copy the code
Rust stands for the name of the folder where the project is created.
Lib means we are creating a library project, not an executable binary.
The project structure diagram is as follows:
The structure is very simple, just two files, this article will not go to the new file, of course, there will be compiled file.
Cargo. Toml is the Android equivalent of build.gradle, which is where some third-party libraries are referenced.
Lib.rs is where the code is written.
First we need to add something to Cargo. Toml:
1[dependencies] 2 And specify version 3jni = {version = "0.10.2", 5[profile.release] 6lto = true 7 8[lib] 9 12crate-type = ["cdylib"]
Copy the code
Add jNI dependencies and specify compilations to enable Android project code to call the content of the so dynamic library.
The next step is to write rust code.
1// Specify OS type 2#! [CFG (target_OS = "android")] 3// allow commands that are not snake_case. [allow(non_snake_case)] 5 6// use STD ::ffi::{CString, CStr}; 9use jni::JNIEnv; 9use jni::JNIEnv; 10use jni::objects::{JObject, JString}; 11use jni::sys::jstring; Unsafe extern fn Java_com_glumes_rust_MainActivity_hello(16 env: JNIEnv, _: JObject, j_recipient: 18 let Recipient= CString::from(19 CStr::from_ptr(20 env.get_string(j_recipient).unwrap().as_ptr()21 )22 ); 24 let output = env.new_string("hello".to_owned() + Recipient.to_str ().unwrap()).unwrap(); 25 output.into_inner()26}
Copy the code
Regardless of rust’s specific syntax, the code is simple: pass a string and return a new string.
The next step is to perform the actual compilation:
1cargo build --target aarch64-linux-android --release2cargo build --target armv7-linux-androideabi --release3cargo build --target i686-linux-android --release
Copy the code
Executing the above three commands separately builds so libraries for three different platforms.
Then replace the so library with the specific jniLibs folder of the Android project. You can use Rust so to build the Android so dynamic library and replace it with so every time you build it. You can also use Rust SO to build the Android Gradle as well as CMake.
Questions and reflections
This is just a small example, but there may be some holes to explore if you want to use rust to develop dynamic libraries like C++. Just implementing jNI calls is not enough. There are many header files in NDK development. How to implement calls in RUST?
If you want rust to print logs in the Android NDK, you can refer to the Android_logger-RS project.
In addition, there is a question, how to debug rust code in Android breakpoints, search the Internet, has not found a suitable answer, there are friends who know how to guide me 🥺
reference
For specific examples, please refer to my GitHub project:
https://github.com/glumes/rust-android-example
-
https://www.yinwang.org/blog-cn/2017/07/06/master-pl
-
https://mozilla.github.io/firefox-browser-architecture/experiments/2017-09-21-rust-on-android.html
Content recommendation
-
Android NDK development of CMake must know must know
-
Invader Vulkan mobile Development (I) of this life prelife
Welcome to pay attention to wechat public number: [paper talk], get the latest article push ~~~