Skip to content

Commit 9b54cac

Browse files
authored
Merge pull request #629 from vlovich/fix-android-build
Fix Android build
2 parents 68178db + 093115e commit 9b54cac

File tree

5 files changed

+45
-22
lines changed

5 files changed

+45
-22
lines changed

llama-cpp-2/Cargo.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,16 @@ tracing = { workspace = true }
1818
encoding_rs = { workspace = true }
1919

2020
[features]
21-
default = ["openmp"]
21+
default = ["openmp", "android-shared-stdcxx"]
2222
cuda = ["llama-cpp-sys-2/cuda"]
2323
metal = ["llama-cpp-sys-2/metal"]
2424
dynamic-link = ["llama-cpp-sys-2/dynamic-link"]
2525
vulkan = ["llama-cpp-sys-2/vulkan"]
2626
native = ["llama-cpp-sys-2/native"]
2727
openmp = ["llama-cpp-sys-2/openmp"]
2828
sampler = []
29+
# Only has an impact on Android.
30+
android-shared-stdcxx = ["llama-cpp-sys-2/shared-stdcxx"]
2931

3032

3133
[target.'cfg(all(target_os = "macos", any(target_arch = "aarch64", target_arch = "arm64")))'.dependencies]

llama-cpp-2/src/model.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
//! A safe wrapper around `llama_model`.
2-
use std::ffi::CString;
2+
use std::ffi::{c_char, CString};
33
use std::num::NonZeroU16;
44
use std::os::raw::c_int;
55
use std::path::Path;
@@ -565,7 +565,7 @@ impl LlamaModel {
565565
chat.as_ptr(),
566566
chat.len(),
567567
add_ass,
568-
buff.as_mut_ptr().cast::<i8>(),
568+
buff.as_mut_ptr().cast::<c_char>(),
569569
buff.len().try_into().expect("Buffer size exceeds i32::MAX"),
570570
)
571571
};
@@ -579,7 +579,7 @@ impl LlamaModel {
579579
chat.as_ptr(),
580580
chat.len(),
581581
add_ass,
582-
buff.as_mut_ptr().cast::<i8>(),
582+
buff.as_mut_ptr().cast::<c_char>(),
583583
buff.len().try_into().expect("Buffer size exceeds i32::MAX"),
584584
)
585585
};

llama-cpp-2/src/sampling.rs

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//! Safe wrapper around `llama_sampler`.
22
33
use std::borrow::Borrow;
4-
use std::ffi::CString;
4+
use std::ffi::{c_char, CString};
55
use std::fmt::{Debug, Formatter};
66

77
use crate::context::LlamaContext;
@@ -20,14 +20,6 @@ impl Debug for LlamaSampler {
2020
}
2121
}
2222

23-
// this is needed for the dry sampler to typecheck on android
24-
// ...because what is normally an i8, is an u8
25-
#[cfg(target_os = "android")]
26-
type CChar = u8;
27-
28-
#[cfg(not(target_os = "android"))]
29-
type CChar = i8;
30-
3123
impl LlamaSampler {
3224
/// Sample and accept a token from the idx-th output of the last evaluation
3325
#[must_use]
@@ -266,7 +258,7 @@ impl LlamaSampler {
266258
.into_iter()
267259
.map(|s| CString::new(s.as_ref()).expect("A sequence breaker contains null bytes"))
268260
.collect();
269-
let mut seq_breaker_pointers: Vec<*const CChar> =
261+
let mut seq_breaker_pointers: Vec<*const c_char> =
270262
seq_breakers.iter().map(|s| s.as_ptr()).collect();
271263

272264
let sampler = unsafe {

llama-cpp-sys-2/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,3 +71,5 @@ dynamic-link = []
7171
vulkan = []
7272
native = []
7373
openmp = []
74+
# Only has an impact on Android.
75+
shared-stdcxx = []

llama-cpp-sys-2/build.rs

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -229,22 +229,44 @@ fn main() {
229229
config.static_crt(static_crt);
230230
}
231231

232-
if target.contains("android") && target.contains("aarch64") {
232+
if target.contains("android") {
233233
// build flags for android taken from this doc
234234
// https://github.com/ggerganov/llama.cpp/blob/master/docs/android.md
235235
let android_ndk = env::var("ANDROID_NDK")
236236
.expect("Please install Android NDK and ensure that ANDROID_NDK env variable is set");
237+
238+
println!("cargo::rerun-if-env-changed=ANDROID_NDK");
239+
237240
config.define(
238241
"CMAKE_TOOLCHAIN_FILE",
239242
format!("{android_ndk}/build/cmake/android.toolchain.cmake"),
240243
);
241-
config.define("ANDROID_ABI", "arm64-v8a");
242-
config.define("ANDROID_PLATFORM", "android-28");
243-
config.define("CMAKE_SYSTEM_PROCESSOR", "arm64");
244-
config.define("CMAKE_C_FLAGS", "-march=armv8.7a");
245-
config.define("CMAKE_CXX_FLAGS", "-march=armv8.7a");
246-
config.define("GGML_OPENMP", "OFF");
244+
if env::var("ANDROID_PLATFORM").is_ok() {
245+
println!("cargo::rerun-if-env-changed=ANDROID_PLATFORM");
246+
} else {
247+
config.define("ANDROID_PLATFORM", "android-28");
248+
}
249+
if target.contains("aarch64") {
250+
config.cflag("-march=armv8.7a");
251+
config.cxxflag("-march=armv8.7a");
252+
} else if target.contains("armv7") {
253+
config.cflag("-march=armv8.7a");
254+
config.cxxflag("-march=armv8.7a");
255+
} else if target.contains("x86_64") {
256+
config.cflag("-march=x86-64");
257+
config.cxxflag("-march=x86-64");
258+
} else if target.contains("i686") {
259+
config.cflag("-march=i686");
260+
config.cxxflag("-march=i686");
261+
} else {
262+
// Rather than guessing just fail.
263+
panic!("Unsupported Android target {target}");
264+
}
247265
config.define("GGML_LLAMAFILE", "OFF");
266+
if cfg!(feature = "shared-stdcxx") {
267+
println!("cargo:rustc-link-lib=dylib=stdc++");
268+
println!("cargo:rustc-link-lib=c++_shared");
269+
}
248270
}
249271

250272
if cfg!(feature = "vulkan") {
@@ -266,8 +288,13 @@ fn main() {
266288
config.define("GGML_CUDA", "ON");
267289
}
268290

269-
if cfg!(feature = "openmp") {
291+
// Android doesn't have OpenMP support AFAICT and openmp is a default feature. Do this here
292+
// rather than modifying the defaults in Cargo.toml just in case someone enables the OpenMP feature
293+
// and tries to build for Android anyway.
294+
if cfg!(feature = "openmp") && !target.contains("android") {
270295
config.define("GGML_OPENMP", "ON");
296+
} else {
297+
config.define("GGML_OPENMP", "OFF");
271298
}
272299

273300
// General

0 commit comments

Comments
 (0)