Setup preliminary rust infrastructure

This commit is contained in:
topjohnwu
2022-06-30 14:50:21 -07:00
parent 0b26882fce
commit 26116ac414
21 changed files with 329 additions and 66 deletions

34
native/README.md Normal file
View File

@@ -0,0 +1,34 @@
# Native Development
## Prerequisite
Install the NDK required to build and develop Magisk with `./build.py ndk`. The NDK will be installed to `$ANDROID_SDK_ROOT/ndk/magisk`. You don't need to manually install a Rust toolchain with `rustup`, as the NDK installed already has a Rust toolchain bundled.
## Code Paths
- `jni`: Magisk's code in C++
- `jni/external`: external dependencies, mostly submodules
- `rust`: Magisk's code in Rust
- `src`: irrelevant, only exists to setup a native Android Studio project
## Build Configs
All C/C++ code and its dependencies are built with [`ndk-build`](https://developer.android.com/ndk/guides/ndk-build) and configured with several `*.mk` files scatterred in many places.
The `rust` folder is a proper Cargo workspace, and all Rust code is built with `cargo` just like any other Rust projects.
## Rust + C/C++
To reduce complexity involved in linking, all Rust code is built as `staticlib` and linked to C++ targets to ensure our final product is built with an officially supported NDK build system. Each C++ target can at most link to **one** Rust `staticlib` or else multiple definitions error will occur.
We use the [`cxx`](https://cxx.rs) project for interop between Rust and C++. Although cxx supports interop in both directions, for Magisk, it is strongly advised to avoid calling C++ functions in Rust; if some functionality required in Rust is already implemented in C++, the desired solution is to port the C++ implementation into Rust and export the migrated function back to C++.
## Development / IDE
All C++ code should be recognized and properly indexed by Android Studio out of the box. For Rust:
- Install the [Rust plugin](https://www.jetbrains.com/rust/) in Android Studio
- In Preferences > Languages & Frameworks > Rust, set `$ANDROID_SDK_ROOT/ndk/magisk/toolchains/rust/bin` as the toolchain location
- Open `native/rust/Cargo.toml`, and select "Attach" in the "No Cargo projects found" banner
Note: run `./build.py binary` before developing to make sure generated code is created.

25
native/jni/Android-rs.mk Normal file
View File

@@ -0,0 +1,25 @@
LOCAL_PATH := $(call my-dir)
###########################
# Rust compilation outputs
###########################
include $(CLEAR_VARS)
LOCAL_MODULE := magisk-rs
LOCAL_SRC_FILES := ../out/$(TARGET_ARCH_ABI)/libmagisk-rs.a
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := boot-rs
LOCAL_SRC_FILES := ../out/$(TARGET_ARCH_ABI)/libmagiskboot-rs.a
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := init-rs
LOCAL_SRC_FILES := ../out/$(TARGET_ARCH_ABI)/libmagiskinit-rs.a
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := policy-rs
LOCAL_SRC_FILES := ../out/$(TARGET_ARCH_ABI)/libmagiskpolicy-rs.a
include $(PREBUILT_STATIC_LIBRARY)

View File

@@ -14,7 +14,8 @@ LOCAL_STATIC_LIBRARIES := \
libsystemproperties \
libphmap \
libxhook \
libmincrypt
libmincrypt \
libmagisk-rs
LOCAL_SRC_FILES := \
core/applets.cpp \
@@ -68,7 +69,8 @@ LOCAL_STATIC_LIBRARIES := \
libbase \
libcompat \
libpolicy \
libxz
libxz \
libinit-rs
LOCAL_SRC_FILES := \
init/init.cpp \
@@ -95,7 +97,8 @@ LOCAL_STATIC_LIBRARIES := \
libbz2 \
libfdt \
libz \
libzopfli
libzopfli \
libboot-rs
LOCAL_SRC_FILES := \
boot/main.cpp \
@@ -119,7 +122,8 @@ LOCAL_MODULE := magiskpolicy
LOCAL_STATIC_LIBRARIES := \
libbase \
libbase \
libpolicy
libpolicy \
libpolicy-rs
LOCAL_SRC_FILES := sepolicy/main.cpp
@@ -135,7 +139,8 @@ LOCAL_STATIC_LIBRARIES := \
libbase \
libcompat \
libnanopb \
libsystemproperties
libsystemproperties \
libmagisk-rs
LOCAL_SRC_FILES := \
core/applet_stub.cpp \
@@ -181,6 +186,7 @@ LOCAL_SRC_FILES := \
sepolicy/statement.cpp
include $(BUILD_STATIC_LIBRARY)
include jni/Android-rs.mk
include jni/base/Android.mk
include jni/external/Android.mk

View File

@@ -15,7 +15,8 @@ LOCAL_SRC_FILES := \
selinux.cpp \
logging.cpp \
xwrap.cpp \
stream.cpp
stream.cpp \
../external/cxx-rs/src/cxx.cc
include $(BUILD_STATIC_LIBRARY)
# All static executables should link with libcompat

1
native/jni/external/cxx-rs vendored Submodule

1
native/rust/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
target/

99
native/rust/Cargo.lock generated Normal file
View File

@@ -0,0 +1,99 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "base"
version = "0.1.0"
[[package]]
name = "cc"
version = "1.0.73"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11"
[[package]]
name = "cxx"
version = "1.0.69"
dependencies = [
"cc",
"cxxbridge-flags",
"cxxbridge-macro",
]
[[package]]
name = "cxxbridge-flags"
version = "1.0.69"
[[package]]
name = "cxxbridge-macro"
version = "1.0.69"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "magisk"
version = "0.1.0"
dependencies = [
"base",
"cxx",
]
[[package]]
name = "magiskboot"
version = "0.1.0"
dependencies = [
"base",
]
[[package]]
name = "magiskinit"
version = "0.1.0"
dependencies = [
"base",
]
[[package]]
name = "magiskpolicy"
version = "0.1.0"
dependencies = [
"base",
]
[[package]]
name = "proc-macro2"
version = "1.0.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd96a1e8ed2596c337f8eae5f24924ec83f5ad5ab21ea8e455d3566c69fbcaf7"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3bcdf212e9776fbcb2d23ab029360416bb1706b1aea2d1a5ba002727cbcab804"
dependencies = [
"proc-macro2",
]
[[package]]
name = "syn"
version = "1.0.98"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c50aef8a904de4c23c788f104b7dddc7d6f79c647c7c8ce4cc8f73eb0ca773dd"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "unicode-ident"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5bd2fe26506023ed7b5e1e315add59d6f584c621d037f9368fea9cfb988f368c"

26
native/rust/Cargo.toml Normal file
View File

@@ -0,0 +1,26 @@
[workspace]
members = [
"base",
"boot",
"core",
"init",
"sepolicy",
]
[profile.dev]
opt-level = "z"
lto = true
codegen-units = 1
panic = "abort"
strip = true
[profile.release]
opt-level = "z"
lto = true
codegen-units = 1
panic = "abort"
strip = true
[patch.crates-io]
cxx = { path = "../jni/external/cxx-rs" }

View File

@@ -0,0 +1,6 @@
[package]
name = "base"
version = "0.1.0"
edition = "2021"
[dependencies]

View File

View File

@@ -0,0 +1,10 @@
[package]
name = "magiskboot"
version = "0.1.0"
edition = "2021"
[lib]
crate-type = ["staticlib"]
[dependencies]
base = { path = "../base" }

View File

View File

@@ -0,0 +1,11 @@
[package]
name = "magisk"
version = "0.1.0"
edition = "2021"
[lib]
crate-type = ["staticlib"]
[dependencies]
base = { path = "../base" }
cxx = "1.0.69"

View File

View File

@@ -0,0 +1,10 @@
[package]
name = "magiskinit"
version = "0.1.0"
edition = "2021"
[lib]
crate-type = ["staticlib"]
[dependencies]
base = { path = "../base" }

View File

View File

@@ -0,0 +1,10 @@
[package]
name = "magiskpolicy"
version = "0.1.0"
edition = "2021"
[lib]
crate-type = ["staticlib", "rlib"]
[dependencies]
base = { path = "../base" }

View File