mirror of
https://github.com/topjohnwu/Magisk.git
synced 2024-11-21 15:05:28 +00:00
Setup preliminary rust infrastructure
This commit is contained in:
parent
0b26882fce
commit
26116ac414
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -40,3 +40,6 @@
|
||||
[submodule "zopfli"]
|
||||
path = native/jni/external/zopfli
|
||||
url = https://github.com/google/zopfli.git
|
||||
[submodule "cxx-rs"]
|
||||
path = native/jni/external/cxx-rs
|
||||
url = https://github.com/topjohnwu/cxx.git
|
||||
|
@ -51,7 +51,7 @@ For Magisk app crashes, record and upload the logcat when the crash occurs.
|
||||
- Run `./build.py ndk` to let the script download and install NDK for you
|
||||
- To start building, run `build.py` to see your options. \
|
||||
For each action, use `-h` to access help (e.g. `./build.py all -h`)
|
||||
- To start development, open the project with Android Studio. The IDE can be used for both app (Kotlin/Java) and native (C++/C) sources.
|
||||
- To start development, open the project with Android Studio. The IDE can be used for both app (Kotlin/Java) and native sources.
|
||||
- Optionally, set custom configs with `config.prop`. A sample `config.prop.sample` is provided.
|
||||
|
||||
## Signing and Distribution
|
||||
|
138
build.py
138
build.py
@ -37,10 +37,10 @@ def vprint(str):
|
||||
|
||||
is_windows = os.name == 'nt'
|
||||
is_ci = 'CI' in os.environ and os.environ['CI'] == 'true'
|
||||
EXE_EXT = '.exe' if is_windows else ''
|
||||
|
||||
if not is_ci and is_windows:
|
||||
import colorama
|
||||
|
||||
colorama.init()
|
||||
|
||||
# Environment checks
|
||||
@ -58,16 +58,20 @@ except FileNotFoundError:
|
||||
|
||||
cpu_count = multiprocessing.cpu_count()
|
||||
archs = ['armeabi-v7a', 'x86', 'arm64-v8a', 'x86_64']
|
||||
triples = ['armv7a-linux-androideabi', 'i686-linux-android', 'aarch64-linux-android', 'x86_64-linux-android']
|
||||
default_targets = ['magisk', 'magiskinit', 'magiskboot', 'magiskpolicy', 'busybox']
|
||||
support_targets = default_targets + ['resetprop', 'test']
|
||||
rust_targets = ['magisk', 'magiskinit', 'magiskboot', 'magiskpolicy']
|
||||
|
||||
sdk_path = os.environ['ANDROID_SDK_ROOT']
|
||||
ndk_root = op.join(sdk_path, 'ndk')
|
||||
ndk_path = op.join(ndk_root, 'magisk')
|
||||
ndk_build = op.join(ndk_path, 'ndk-build')
|
||||
rust_bin = op.join(ndk_path, 'toolchains', 'rust', 'bin')
|
||||
cargo = op.join(rust_bin, 'cargo' + EXE_EXT)
|
||||
gradlew = op.join('.', 'gradlew' + ('.bat' if is_windows else ''))
|
||||
adb_path = op.join(sdk_path, 'platform-tools', 'adb' + ('.exe' if is_windows else ''))
|
||||
native_gen_path = op.join('native', 'out', 'generated')
|
||||
adb_path = op.join(sdk_path, 'platform-tools', 'adb' + EXE_EXT)
|
||||
native_gen_path = op.realpath(op.join('native', 'out', 'generated'))
|
||||
|
||||
# Global vars
|
||||
config = {}
|
||||
@ -123,16 +127,17 @@ def mkdir_p(path, mode=0o755):
|
||||
os.makedirs(path, mode, exist_ok=True)
|
||||
|
||||
|
||||
def execv(cmd):
|
||||
return subprocess.run(cmd, stdout=STDOUT)
|
||||
def execv(cmd, env=None):
|
||||
return subprocess.run(cmd, stdout=STDOUT, env=env)
|
||||
|
||||
|
||||
def system(cmd):
|
||||
return subprocess.run(cmd, shell=True, stdout=STDOUT)
|
||||
|
||||
|
||||
def cmd_out(cmd):
|
||||
return subprocess.check_output(cmd).strip().decode('utf-8')
|
||||
def cmd_out(cmd, env=None):
|
||||
return subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL, env=env) \
|
||||
.stdout.strip().decode('utf-8')
|
||||
|
||||
|
||||
def xz(data):
|
||||
@ -180,15 +185,6 @@ def load_config(args):
|
||||
STDOUT = None if args.verbose else subprocess.DEVNULL
|
||||
|
||||
|
||||
def collect_binary():
|
||||
for arch in archs:
|
||||
mkdir_p(op.join('native', 'out', arch))
|
||||
for bin in support_targets + ['libpreload.so']:
|
||||
source = op.join('native', 'libs', arch, bin)
|
||||
target = op.join('native', 'out', arch, bin)
|
||||
mv(source, target)
|
||||
|
||||
|
||||
def clean_elf():
|
||||
if is_windows:
|
||||
elf_cleaner = op.join('tools', 'elf-cleaner.exe')
|
||||
@ -203,48 +199,6 @@ def clean_elf():
|
||||
execv(args)
|
||||
|
||||
|
||||
def find_build_tools():
|
||||
global build_tools
|
||||
if build_tools:
|
||||
return build_tools
|
||||
build_tools_root = op.join(os.environ['ANDROID_SDK_ROOT'], 'build-tools')
|
||||
ls = os.listdir(build_tools_root)
|
||||
# Use the latest build tools available
|
||||
ls.sort()
|
||||
build_tools = op.join(build_tools_root, ls[-1])
|
||||
return build_tools
|
||||
|
||||
|
||||
# Unused but keep this code
|
||||
def sign_zip(unsigned):
|
||||
if 'keyStore' not in config:
|
||||
return
|
||||
|
||||
msg = '* Signing APK'
|
||||
apksigner = op.join(find_build_tools(), 'apksigner' + ('.bat' if is_windows else ''))
|
||||
|
||||
exec_args = [apksigner, 'sign',
|
||||
'--ks', config['keyStore'],
|
||||
'--ks-pass', f'pass:{config["keyStorePass"]}',
|
||||
'--ks-key-alias', config['keyAlias'],
|
||||
'--key-pass', f'pass:{config["keyPass"]}',
|
||||
'--v1-signer-name', 'CERT',
|
||||
'--v4-signing-enabled', 'false']
|
||||
|
||||
if unsigned.endswith('.zip'):
|
||||
msg = '* Signing zip'
|
||||
exec_args.extend(['--min-sdk-version', '17',
|
||||
'--v2-signing-enabled', 'false',
|
||||
'--v3-signing-enabled', 'false'])
|
||||
|
||||
exec_args.append(unsigned)
|
||||
|
||||
header(msg)
|
||||
proc = execv(exec_args)
|
||||
if proc.returncode != 0:
|
||||
error('Signing failed!')
|
||||
|
||||
|
||||
def binary_dump(src, var_name):
|
||||
out_str = f'constexpr unsigned char {var_name}[] = {{'
|
||||
for i, c in enumerate(xz(src.read())):
|
||||
@ -261,7 +215,70 @@ def run_ndk_build(flags):
|
||||
if proc.returncode != 0:
|
||||
error('Build binary failed!')
|
||||
os.chdir('..')
|
||||
collect_binary()
|
||||
for arch in archs:
|
||||
for tgt in support_targets + ['libpreload.so']:
|
||||
source = op.join('native', 'libs', arch, tgt)
|
||||
target = op.join('native', 'out', arch, tgt)
|
||||
mv(source, target)
|
||||
|
||||
|
||||
def run_cargo_build(args):
|
||||
os.chdir(op.join('native', 'rust'))
|
||||
targets = set(args.target) & set(rust_targets)
|
||||
|
||||
env = os.environ.copy()
|
||||
env['PATH'] = f'{rust_bin}:{env["PATH"]}'
|
||||
|
||||
# Install cxxbridge and generate C++ bindings
|
||||
native_out = op.join('..', '..', 'native', 'out')
|
||||
local_cargo_root = op.join(native_out, '.cargo')
|
||||
mkdir_p(local_cargo_root)
|
||||
cmds = [cargo, 'install', '--root', local_cargo_root, 'cxxbridge-cmd']
|
||||
if not args.verbose:
|
||||
cmds.append('-q')
|
||||
proc = execv(cmds, env)
|
||||
if proc.returncode != 0:
|
||||
error('cxxbridge-cmd installation failed!')
|
||||
cxxbridge = op.join(local_cargo_root, 'bin', 'cxxbridge' + EXE_EXT)
|
||||
mkdir(native_gen_path)
|
||||
for p in ['base', 'boot', 'core', 'init', 'sepolicy']:
|
||||
text = cmd_out([cxxbridge, op.join(p, 'src', 'lib.rs')])
|
||||
write_if_diff(op.join(native_gen_path, f'{p}-rs.cpp'), text)
|
||||
text = cmd_out([cxxbridge, '--header', op.join(p, 'src', 'lib.rs')])
|
||||
write_if_diff(op.join(native_gen_path, f'{p}-rs.hpp'), text)
|
||||
|
||||
# Start building the actual build commands
|
||||
cmds = [cargo, 'build', '-Z', 'build-std=std,panic_abort',
|
||||
'-Z', 'build-std-features=panic_immediate_abort']
|
||||
for target in targets:
|
||||
cmds.append('-p')
|
||||
cmds.append(target)
|
||||
rust_out = 'debug'
|
||||
if args.release:
|
||||
cmds.append('-r')
|
||||
rust_out = 'release'
|
||||
if not args.verbose:
|
||||
cmds.append('-q')
|
||||
|
||||
os_name = platform.system().lower()
|
||||
llvm_bin = op.join(ndk_path, 'toolchains', 'llvm', 'prebuilt', f'{os_name}-x86_64', 'bin')
|
||||
env['TARGET_CC'] = op.join(llvm_bin, 'clang' + EXE_EXT)
|
||||
env['RUSTFLAGS'] = '-Clinker-plugin-lto'
|
||||
for (arch, triple) in zip(archs, triples):
|
||||
env['TARGET_CFLAGS'] = f'--target={triple}21'
|
||||
rust_triple = 'thumbv7neon-linux-androideabi' if triple.startswith('armv7') else triple
|
||||
proc = execv([*cmds, '--target', rust_triple], env)
|
||||
if proc.returncode != 0:
|
||||
error('Build binary failed!')
|
||||
|
||||
arch_out = op.join(native_out, arch)
|
||||
mkdir(arch_out)
|
||||
for tgt in targets:
|
||||
source = op.join('target', rust_triple, rust_out, f'lib{tgt}.a')
|
||||
target = op.join(arch_out, f'lib{tgt}-rs.a')
|
||||
mv(source, target)
|
||||
|
||||
os.chdir(op.join('..', '..'))
|
||||
|
||||
|
||||
def write_if_diff(file_name, text):
|
||||
@ -326,6 +343,8 @@ def build_binary(args):
|
||||
|
||||
header('* Building binaries: ' + ' '.join(args.target))
|
||||
|
||||
run_cargo_build(args)
|
||||
|
||||
dump_flag_header()
|
||||
|
||||
flag = ''
|
||||
@ -402,6 +421,7 @@ def cleanup(args):
|
||||
rm_rf(op.join('native', 'out'))
|
||||
rm_rf(op.join('native', 'libs'))
|
||||
rm_rf(op.join('native', 'obj'))
|
||||
rm_rf(op.join('native', 'rust', 'target'))
|
||||
|
||||
if 'java' in args.target:
|
||||
header('* Cleaning java')
|
||||
|
34
native/README.md
Normal file
34
native/README.md
Normal 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
25
native/jni/Android-rs.mk
Normal 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)
|
@ -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
|
||||
|
||||
|
@ -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/jni/external/cxx-rs
vendored
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit 650e64bc3970625f580a61ad9cfc65faa5cdd948
|
1
native/rust/.gitignore
vendored
Normal file
1
native/rust/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
target/
|
99
native/rust/Cargo.lock
generated
Normal file
99
native/rust/Cargo.lock
generated
Normal 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
26
native/rust/Cargo.toml
Normal 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" }
|
6
native/rust/base/Cargo.toml
Normal file
6
native/rust/base/Cargo.toml
Normal file
@ -0,0 +1,6 @@
|
||||
[package]
|
||||
name = "base"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
0
native/rust/base/src/lib.rs
Normal file
0
native/rust/base/src/lib.rs
Normal file
10
native/rust/boot/Cargo.toml
Normal file
10
native/rust/boot/Cargo.toml
Normal file
@ -0,0 +1,10 @@
|
||||
[package]
|
||||
name = "magiskboot"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[lib]
|
||||
crate-type = ["staticlib"]
|
||||
|
||||
[dependencies]
|
||||
base = { path = "../base" }
|
0
native/rust/boot/src/lib.rs
Normal file
0
native/rust/boot/src/lib.rs
Normal file
11
native/rust/core/Cargo.toml
Normal file
11
native/rust/core/Cargo.toml
Normal 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"
|
0
native/rust/core/src/lib.rs
Normal file
0
native/rust/core/src/lib.rs
Normal file
10
native/rust/init/Cargo.toml
Normal file
10
native/rust/init/Cargo.toml
Normal file
@ -0,0 +1,10 @@
|
||||
[package]
|
||||
name = "magiskinit"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[lib]
|
||||
crate-type = ["staticlib"]
|
||||
|
||||
[dependencies]
|
||||
base = { path = "../base" }
|
0
native/rust/init/src/lib.rs
Normal file
0
native/rust/init/src/lib.rs
Normal file
10
native/rust/sepolicy/Cargo.toml
Normal file
10
native/rust/sepolicy/Cargo.toml
Normal file
@ -0,0 +1,10 @@
|
||||
[package]
|
||||
name = "magiskpolicy"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[lib]
|
||||
crate-type = ["staticlib", "rlib"]
|
||||
|
||||
[dependencies]
|
||||
base = { path = "../base" }
|
0
native/rust/sepolicy/src/lib.rs
Normal file
0
native/rust/sepolicy/src/lib.rs
Normal file
Loading…
Reference in New Issue
Block a user