Android Studio 정보
Ladybug Feature Drop 2024.2.2
Build #AI-242.23726.103.2422.12816248, built on December 18, 2024
Runtime version: 21.0.4+-12422083-b607.1 aarch64
VM: OpenJDK 64-Bit Server VM by JetBrains s.r.o.
선행 작업
Rust 설치하기
MacOS - Rust 설치하기
설치방법 참고 사이트 한국 러스트 사용자 그룹Rust 설치하기 A. Rustup 사용하기 rustup을 쓰면 윈도우, 맥, 리눅스 등 대부분의 환경에서 별도의 지식 없이 손쉽게 러스트를 설치할 수 있습니다. R
charlie-dev.tistory.com
Rust 크로스 컴파일 타겟 추가
rustup target add aarch64-linux-android # 64비트 ARM
rustup target add armv7-linux-androideabi # 32비트 ARM
rustup target add i686-linux-android # 32비트 x86
rustup target add x86_64-linux-android # 64비트 x86
Android Studio NDK 설치
Android Studio NDK 설치하기
Android Studio 설정 열기Languages & Frameworks - Android SDK or Android Studio 상단 툴바 - Tools - SDK ManagerSDK Tools 탭 선택NDK(Side by side) 드롭다운에서 버전 선택 후 Apply or OK를 눌러서 설치
charlie-dev.tistory.com
New Project 생성하기
새로운 프로젝트를 생성해 봅시다.
저는 Ui가 Compose베이스로
설정되어있는 Empty Activity로
선택하겠습니다.
프로젝트 이름은 RustOnAndroid로 만들어 보겠습니다.
프로젝트 루트 경로에서 cargo 를 이용해서 프로젝트를 만들어 줍니다.
커맨드
cargo new <rust프로젝트이름> --lib
프로젝트 설정하기
Rust 프로젝트 설정
Android Studio ProjectView를 Android가 아닌 Project로 바꾸어 줍니다.
cargo를 이용해서 만들어준 rust프로젝트 폴더로 들어가 Cargo.toml 파일을 수정해 줍니다.
[package]
name = "rustlib" #프로젝트 패키지 이름
version = "0.1.0" #프로젝트 버전
edition = "2021" # Rust 에디션
[lib]
name = "rust_lib" #라이브러리 이름
crate-type = ["cdylib"] #동적 라이브러리 (.so, .dll, .dylib 파일을 생성하기 위한 라이브러리)
[dependencies]
jni = "0.21.1" #Java Native Interface를 위한 의존성
CMake 설정
app/src/main 디렉토리로 이동하여 cpp폴더를
만들고 CMakeLists.txt 파일을 만들어주세요.
(꼭 이 경로가 아니어도 괜찮습니다. 이유는 이후에 Gradle 설정에서 나옵니다.)
CMakeLists.txt 파일은 CMake를 이용하여 빌드를
어떻게 할 것인지 설명하는 스크립트 파일입니다.
CMakeLists.txt에 스크립트를 작성해 줍시다.
cmake_minimum_required(VERSION <최소CMake버전>)
project(<프로젝트이름>)
add_library(<Rust프로젝트 lib이름> SHARED IMPORTED)
set_target_properties(<Rust프로젝트 lib이름> PROPERTIES IMPORTED_LOCATION
#빌드되어 output으로 나올 so파일의 위치 (빌드시 output파일의 접두사 lib가 붙음)
#저는 main/jniLibs/아키텍쳐/librust_lib.so 로 설정했습니다.
${CMAKE_SOURCE_DIR}/../jniLibs/${ANDROID_ABI}/librust_lib.so)
target_link_libraries(<Rust프로젝트 lib이름>)
main/jniLibs/아키텍쳐/rust_lib.so 로 라이브러리를
경로를 설정했기 때문에 jniLibs 디렉토리를 만들어 줍시다.
Android Gradle 설정
app/build.gradle 파일에 ndk와 cmake 관련 스크립트를 추가해 주고 SyncNow로 그래들 싱크를 맞춰줍니다.
android {
//... 기존 설정들
defaultConfig {
//... 기존 설정들
//앱이 지원 할 아키텍쳐 종류
ndk {
abiFilters += listOf("arm64-v8a", "armeabi-v7a", "x86", "x86_64")
}
//STL 설정
externalNativeBuild {
cmake{
arguments("-DANDROID_STL=c++_shared")
}
}
}
//... 기존설정들
//CMakeLists.txt 파일 위치 설정 및 CMake 버전 설정
externalNativeBuild {
cmake {
path("src/main/cpp/CMakeLists.txt")
version = "3.22.1"
}
}
//... 기존설정들
}
코드 작성
Rust 코드 작성
Rust에서 JNI를 이용한 함수를 작성하기 위해서는 네이밍 규칙을 지켜서 작성을 해주어야 한다고 합니다.
규칙은
Java_<패키지 이름>_<클래스이름>_<함수이름>
제 프로젝트 기준으로 만들자면 저는 RustBridge라는 Object클래스를 생성하여 사용 할 예정이기 때문에
Java_com_example_rustonandroid_RustBridge_<함수이름>
으로 작성 할 수 있겠네요.
use jni::JNIEnv;
use jni::objects::{JClass, JString};
use jni::sys::jstring;
#[no_mangle]
pub extern "C" fn Java_com_example_rustonandroid_RustBridge_stringFromRust(
mut env: JNIEnv,
_: JClass,
input: JString,
) -> jstring {
let input: String = env
.get_string(&input)
.expect("Failed to get Java string")
.into();
let output = format!("Hello from Rust: {}", input);
env.new_string(output)
.expect("Failed to create Java string")
.as_raw()
}
함수명을 stringFromRust라는 이름으로 간단한 코드를 작성해 보았습니다.
Android Kotlin 코드 작성
app 모듈에 오브젝트 파일을 생성해 줍니다
저는 러스트 함수를 미리 정의 해서 RustBridge로 만들었지만
코틀린 파일을 먼저 정의하고 러스트 코드를 작성하셔도 무방합니다.
편하신 순서로 만들어주세요.
라이브러리 로드와 함수 호출코드를 작성해주세요
MainActivity에서 코드를 사용해 보겠습니다.
기본 UI에 인사를 출력하는 부분을 Rust함수로 변경해보았습니다.
빌드하기
환경변수 추가
Cargo로 빌드하기 위해서 환경변수 설정이 필요합니다.
저는 zsh를 사용하기 때문에 vi ~/.zshrc 명령어를 이용해서 파일 최하단에 아래 코드를 추가해주었습니다.
NDK의 버전을 주의해서 추가해 주세요
#export ANDROID_NDK_HOME="<USER 홈>/Library/Android/sdk/ndk/<NDK버전>"
export ANDROID_NDK_HOME="$HOME/Library/Android/sdk/ndk/28.0.12916984"
export NDK_HOME=$ANDROID_NDK_HOME
export CARGO_TARGET_AARCH64_LINUX_ANDROID_LINKER="$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/darwin-x86_64/bin/aarch64-linux-android24-clang"
export CARGO_TARGET_AARCH64_LINUX_ANDROID_AR="$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/darwin-x86_64/bin/llvm-ar"
이제 진짜 빌드를 해보겠습니다.
Rust 프로젝트 빌드> 라이브러리 so파일 이동 > Android 에뮬레이터 실행 순으로 따로 따로 빌드를 진행하도록 하겠습니다.
터미널에서 러스트 프로젝트로 이동하여 빌드를 해줍니다.
cargo build --target aarch64-linux-android #--release(릴리즈로 빌드시 옵션추가)
라이브러리 so 파일 이동
러스트 프로젝트 -> target -> aarch64-linux-android -> release 폴더에 lib접두사가 붙은 so 파일이 생성되어 있습니다.
app/src/main/jniLibs 하위에 빌드 아키텍쳐에 해당하는 폴더를 만들고 so 파일을 넣어 줍니다.
(저는 aarch64-linux-android 로 빌드하였기 때문에 arm64-v8a 폴더에 넣었습니다.)
Android 에뮬레이터 실행
Device Manager에 arm64 에뮬레이터를 만들어 실행 시켜보겠습니다.
Rust코드에서 정의했던 output이 출력되는걸 확인 할 수 있습니다.
이상 러스트코드를 안드로이드 NDK를 이용해서 실행하는 방법에 대한 글을 마치도록 하겠습니다. 잘못된 정보나 더 좋은 방법이나 팁을 알고 계신다면 댓글로 알려주시면 감사하겠습니다.
'안드로이드' 카테고리의 다른 글
Android Studio NDK 설치하기 (0) | 2025.02.06 |
---|---|
[Android] Android Studio Kotlin DSL 적용중 빨간줄 (0) | 2023.06.27 |
[Android] Activity에 대해서... ( feat. Android공식 문서 ) (1) | 2023.04.28 |
[Android] Room M1칩 MacBook 빌드 에러 삽질 of 삽질 (2) | 2022.06.23 |
[Android] Google Health Connect (5) | 2022.05.31 |