Skip to content

Commit 8fa3090

Browse files
authored
Merge pull request #499 from CCnut/main-dev
Add Rust and Android CI build
2 parents 08c835d + 9969f10 commit 8fa3090

File tree

2 files changed

+148
-39
lines changed

2 files changed

+148
-39
lines changed

.github/workflows/prerelease.yml

+105-4
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ env:
1111
PYTHONUTF8: 1
1212
PYTHON_VERSION: 3.11
1313
DOTNET_VERSION: 7.0.x
14+
ANDROID_NDK_VERSION: 26.3.11579264
15+
ANDROID_SDK_VERSION: 21
1416

1517
# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
1618
permissions:
@@ -101,11 +103,15 @@ jobs:
101103
run: npm test
102104

103105
# Rust
106+
- name: Set up Rust
107+
run: |
108+
rustup update stable
109+
rustup default stable
110+
rustc -vV
111+
- name: Build Rust
112+
run: cargo build
104113
- name: Test Rust
105-
uses: actions-rs/toolchain@v1
106-
with:
107-
toolchain: stable
108-
override: true
114+
run: cargo test
109115

110116
# Java
111117
- name: Setup Java
@@ -193,6 +199,17 @@ jobs:
193199
- name: Test Python
194200
run: pytest
195201

202+
# Rust
203+
- name: Set up Rust
204+
run: |
205+
rustup update stable
206+
rustup default stable
207+
rustc -vV
208+
- name: Build Rust
209+
run: cargo build
210+
- name: Test Rust
211+
run: cargo test
212+
196213
# C#
197214
- name: Setup .NET ${{ env.DOTNET_VERSION }}
198215
uses: actions/setup-dotnet@v3
@@ -260,6 +277,17 @@ jobs:
260277
- name: Test ObjC/Swift
261278
run: swift test
262279

280+
# Rust
281+
- name: Set up Rust
282+
run: |
283+
rustup update stable
284+
rustup default stable
285+
rustc -vV
286+
- name: Build Rust
287+
run: cargo build
288+
- name: Test Rust
289+
run: cargo test
290+
263291
# C#
264292
- name: Setup .NET ${{ env.DOTNET_VERSION }}
265293
uses: actions/setup-dotnet@v3
@@ -318,6 +346,17 @@ jobs:
318346
- name: Test JavaScript
319347
run: npm test
320348

349+
# Rust
350+
- name: Set up Rust
351+
run: |
352+
rustup update stable
353+
rustup default stable
354+
rustc -vV
355+
- name: Build Rust
356+
run: cargo build
357+
- name: Test Rust
358+
run: cargo test
359+
321360
# C#
322361
- name: Setup .NET ${{ env.DOTNET_VERSION }}
323362
uses: actions/setup-dotnet@v3
@@ -421,3 +460,65 @@ jobs:
421460
run: |
422461
test -e build_artifacts/libusearch_c.so
423462
test -e build_artifacts/libusearch_sqlite.so
463+
464+
test_ubuntu_android_ndk:
465+
name: Android NDK Build
466+
runs-on: ubuntu-22.04
467+
strategy:
468+
matrix:
469+
include:
470+
- processor: armv7a
471+
abi: armeabi-v7a
472+
target: armv7-linux-androideabi
473+
- processor: aarch64
474+
abi: arm64-v8a
475+
target: aarch64-linux-android
476+
steps:
477+
- uses: actions/checkout@v4
478+
- run: git submodule update --init --recursive
479+
480+
- name: Install NDK ndk
481+
run: |
482+
${ANDROID_HOME}/cmdline-tools/latest/bin/sdkmanager --install "ndk;${{ env.ANDROID_NDK_VERSION }}"
483+
484+
- name: Build C/C++
485+
run: |
486+
cmake -B build_artifacts \
487+
-D CMAKE_BUILD_TYPE=RelWithDebInfo \
488+
-D CMAKE_EXPORT_COMPILE_COMMANDS=1 \
489+
-D CMAKE_TOOLCHAIN_FILE=${ANDROID_HOME}/ndk/${{ env.ANDROID_NDK_VERSION }}/build/cmake/android.toolchain.cmake \
490+
-D CMAKE_ANDROID_STL_TYPE=c++_static \
491+
-D ANDROID_PLATFORM=${{ env.ANDROID_SDK_VERSION }} \
492+
-D ANDROID_ABI=${{ matrix.abi }} \
493+
-D USEARCH_BUILD_LIB_C=1 \
494+
-D USEARCH_BUILD_TEST_CPP=0 \
495+
-D USEARCH_BUILD_BENCH_CPP=0
496+
497+
cmake --build build_artifacts --config RelWithDebInfo
498+
499+
# We can't run the produced builds, but we can make sure they exist
500+
- name: Test artifacts presense
501+
run: |
502+
test -e build_artifacts/libusearch_c.so
503+
504+
# Rust
505+
- name: Set up Rust
506+
run: |
507+
rustup update stable
508+
rustup default stable
509+
rustup target add ${{ matrix.target }}
510+
rustc -vV
511+
512+
- name: Set up Rust Env
513+
run: |
514+
TOOLCHAIN=${ANDROID_HOME}/ndk/${{ env.ANDROID_NDK_VERSION }}/toolchains/llvm/prebuilt/linux-x86_64/bin/
515+
NDK_CLANG=$(find ${TOOLCHAIN} -name "${{ matrix.processor }}*${{ env.ANDROID_SDK_VERSION }}-clang")
516+
echo "CC_${{ matrix.target }}=${NDK_CLANG}" >> ${GITHUB_ENV}
517+
echo "CXX_${{ matrix.target }}=${NDK_CLANG}++" >> ${GITHUB_ENV}
518+
echo "AR_${{ matrix.target }}=${TOOLCHAIN}/llvm-ar" >> ${GITHUB_ENV}
519+
echo "CARGO_${{ matrix.target }}=${NDK_CLANG}" >> ${GITHUB_ENV}
520+
echo "CARGO_${{ matrix.target }}=${TOOLCHAIN}/llvm-ar" >> ${GITHUB_ENV}
521+
522+
- name: Build Rust
523+
run: |
524+
cargo build --target ${{ matrix.target }}

build.rs

+43-35
Original file line numberDiff line numberDiff line change
@@ -25,39 +25,37 @@ fn main() {
2525

2626
// Define all possible SIMD targets as 1
2727
let target_arch = std::env::var("CARGO_CFG_TARGET_ARCH").unwrap_or_default();
28-
let flags_to_try = match target_arch.as_str() {
29-
"arm" | "aarch64" => vec![
30-
"SIMSIMD_TARGET_SVE_BF16",
31-
"SIMSIMD_TARGET_SVE_F16",
32-
"SIMSIMD_TARGET_SVE_I8",
33-
"SIMSIMD_TARGET_SVE",
34-
"SIMSIMD_TARGET_NEON_BF16",
35-
"SIMSIMD_TARGET_NEON_F16",
36-
"SIMSIMD_TARGET_NEON_I8",
37-
"SIMSIMD_TARGET_NEON",
38-
],
39-
_ => vec![
40-
"SIMSIMD_TARGET_SAPPHIRE",
41-
"SIMSIMD_TARGET_GENOA",
42-
"SIMSIMD_TARGET_ICE",
43-
"SIMSIMD_TARGET_SKYLAKE",
44-
"SIMSIMD_TARGET_HASWELL",
45-
],
46-
};
4728

29+
let mut flags_to_try;
4830
if cfg!(feature = "simsimd") {
4931
build
5032
.file("simsimd/c/lib.c")
5133
.define("USEARCH_USE_SIMSIMD", "1")
5234
.define("SIMSIMD_DYNAMIC_DISPATCH", "1")
5335
.define("SIMSIMD_NATIVE_BF16", "0")
5436
.define("SIMSIMD_NATIVE_F16", "0");
55-
56-
for flag in &flags_to_try {
57-
build.define(flag, "1");
58-
}
37+
flags_to_try = match target_arch.as_str() {
38+
"arm" | "aarch64" => vec![
39+
"SIMSIMD_TARGET_NEON",
40+
"SIMSIMD_TARGET_NEON_I8",
41+
"SIMSIMD_TARGET_NEON_F16",
42+
"SIMSIMD_TARGET_NEON_BF16",
43+
"SIMSIMD_TARGET_SVE",
44+
"SIMSIMD_TARGET_SVE_I8",
45+
"SIMSIMD_TARGET_SVE_F16",
46+
"SIMSIMD_TARGET_SVE_BF16",
47+
],
48+
_ => vec![
49+
"SIMSIMD_TARGET_HASWELL",
50+
"SIMSIMD_TARGET_SKYLAKE",
51+
"SIMSIMD_TARGET_ICE",
52+
"SIMSIMD_TARGET_GENOA",
53+
"SIMSIMD_TARGET_SAPPHIRE",
54+
],
55+
};
5956
} else {
6057
build.define("USEARCH_USE_SIMSIMD", "0");
58+
flags_to_try = vec![];
6159
}
6260

6361
let target_os = std::env::var("CARGO_CFG_TARGET_OS").unwrap();
@@ -91,26 +89,36 @@ fn main() {
9189
.define("_ALLOW_POINTER_TO_CONST_MISMATCH", None);
9290
}
9391

94-
let mut result = build.try_compile("usearch");
95-
if result.is_err() {
96-
print!("cargo:warning=Failed to compile with all SIMD backends...");
97-
for flag in flags_to_try {
98-
build.define(flag, "0");
99-
result = build.try_compile("usearch");
100-
if result.is_err() {
92+
let base_build = build.clone();
93+
94+
let mut pop_flag = None;
95+
loop {
96+
let mut sub_build = base_build.clone();
97+
for flag in &flags_to_try {
98+
sub_build.define(flag, "1");
99+
}
100+
let result = sub_build.try_compile("usearch");
101+
if result.is_err() {
102+
if let Some(flag) = pop_flag {
101103
println!(
102-
"cargo:warning=Failed to compile after disabling {}, trying next configuration...",
104+
"cargo:warning=Failed to compile after disabling {:?}, trying next configuration...",
103105
flag
104106
);
105107
} else {
106-
break;
108+
if !flags_to_try.is_empty() {
109+
print!("cargo:warning=Failed to compile with all SIMD backends...");
110+
}
111+
}
112+
113+
pop_flag = flags_to_try.pop();
114+
if pop_flag.is_none() {
115+
result.unwrap();
107116
}
117+
} else {
118+
break;
108119
}
109120
}
110121

111-
// Ensure one build has been successful
112-
result.unwrap();
113-
114122
println!("cargo:rerun-if-changed=rust/lib.rs");
115123
println!("cargo:rerun-if-changed=rust/lib.cpp");
116124
println!("cargo:rerun-if-changed=rust/lib.hpp");

0 commit comments

Comments
 (0)