Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
85f89dc
fix
iaojnh May 20, 2026
9e58670
Merge branch 'main' into fix/exclude-arrow
iaojnh May 20, 2026
46bf9aa
Merge branch 'alibaba:main' into main
iaojnh May 21, 2026
d6547aa
Merge branch 'alibaba:main' into main
iaojnh May 25, 2026
c9a4d94
Merge branch 'alibaba:main' into main
iaojnh May 26, 2026
5bff8b6
Merge branch 'alibaba:main' into main
iaojnh May 29, 2026
10f1dee
Merge branch 'alibaba:main' into main
iaojnh Jun 1, 2026
ad6ac3a
Merge branch 'alibaba:main' into main
iaojnh Jun 2, 2026
5c045b0
Merge branch 'alibaba:main' into main
iaojnh Jun 3, 2026
570da53
Merge branch 'alibaba:main' into main
iaojnh Jun 8, 2026
d3fecea
Merge branch 'alibaba:main' into main
iaojnh Jun 9, 2026
4f07741
Merge branch 'alibaba:main' into main
iaojnh Jun 10, 2026
9e900c5
Merge branch 'alibaba:main' into main
iaojnh Jun 11, 2026
4761640
Merge branch 'alibaba:main' into main
iaojnh Jun 15, 2026
a842e22
Merge branch 'alibaba:main' into main
iaojnh Jun 15, 2026
8bb7e53
Merge branch 'alibaba:main' into main
iaojnh Jun 17, 2026
d9af524
Merge branch 'alibaba:main' into main
iaojnh Jun 22, 2026
973d233
Merge branch 'alibaba:main' into main
iaojnh Jun 24, 2026
43cb151
Merge branch 'alibaba:main' into main
iaojnh Jun 25, 2026
4685c96
Merge branch 'alibaba:main' into main
iaojnh Jun 30, 2026
a07dd9d
Merge branch 'alibaba:main' into main
iaojnh Jul 10, 2026
229dc57
Merge branch 'alibaba:main' into main
iaojnh Jul 13, 2026
9ac71b2
Merge branch 'alibaba:main' into main
iaojnh Jul 15, 2026
23a4354
Merge branch 'alibaba:main' into main
iaojnh Jul 17, 2026
a1ad5fc
Merge branch 'alibaba:main' into main
iaojnh Jul 20, 2026
ef12c90
Merge branch 'alibaba:main' into main
iaojnh Jul 23, 2026
95d9225
Merge branch 'alibaba:main' into main
iaojnh Jul 27, 2026
76e41c4
Merge branch 'alibaba:main' into main
iaojnh Jul 28, 2026
46777d4
Merge branch 'alibaba:main' into main
iaojnh Jul 29, 2026
492bd1d
Merge branch 'alibaba:main' into main
iaojnh Aug 3, 2026
e5ad3c7
open mobile diskann
iaojnh Aug 3, 2026
b425f78
clang format
iaojnh Aug 3, 2026
dec0b2e
clang format
iaojnh Aug 3, 2026
843ea2c
upd ut
iaojnh Aug 3, 2026
ccbdab5
add ut
iaojnh Aug 3, 2026
bddcb5a
upd
iaojnh Aug 3, 2026
0b97746
fix ut
iaojnh Aug 4, 2026
12851e8
fix
iaojnh Aug 4, 2026
cba2c8f
fix ut
iaojnh Aug 4, 2026
1a42833
fix ut
iaojnh Aug 4, 2026
f23bc9a
fix ut
iaojnh Aug 4, 2026
4b2f7f5
upd cmake
iaojnh Aug 4, 2026
633a70e
fix(mobile): use a single static C++ runtime
iaojnh Aug 4, 2026
20f2a11
fix(tests): avoid shadowed C variables
iaojnh Aug 4, 2026
1f7edb7
fix(tests): make RAND_MAX conversion explicit
iaojnh Aug 4, 2026
35feada
fix(diskann): prevent PQ pivot buffer overrun
iaojnh Aug 4, 2026
45494d2
fix(diskann): instantiate PQ pivot conversion templates
iaojnh Aug 5, 2026
f3ba90b
fix(android): scope static SDK whole-archive flags
iaojnh Aug 5, 2026
738c4dc
upd workflow
iaojnh Aug 5, 2026
b8f043c
fix
iaojnh Aug 5, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
118 changes: 83 additions & 35 deletions .github/workflows/04-android-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@ jobs:
strategy:
fail-fast: false
matrix:
abi: [x86_64]
# x86_64 runs the emulator suite; arm64-v8a provides compile/link
# coverage for the ABI used by physical Android devices.
abi: [x86_64, arm64-v8a]
api: ${{ github.event.inputs.api && fromJSON(format('["{0}"]', github.event.inputs.api)) || fromJSON('["34"]') }}
steps:
# ── Environment setup ──────────────────────────────────────────────
Expand Down Expand Up @@ -55,16 +57,22 @@ jobs:
uses: android-actions/setup-android@v4

- name: Enable KVM
if: matrix.abi == 'x86_64'
run: sudo chmod 666 /dev/kvm || true

- name: Install NDK, emulator and system image
- name: Install NDK and Android platform
shell: bash
run: |
sdkmanager --install \
"ndk;$NDK_VERSION" \
"platform-tools" \
"platforms;android-${{ matrix.api }}" \
"emulator"
"platforms;android-${{ matrix.api }}"

- name: Install emulator and x86_64 system image
if: matrix.abi == 'x86_64'
shell: bash
run: |
sdkmanager --install "emulator"

# Install x86_64 system image (try variants in order of availability)
sdkmanager --install "system-images;android-${{ matrix.api }};google_apis;x86_64" 2>/dev/null || \
Expand Down Expand Up @@ -117,8 +125,12 @@ jobs:
-DANDROID_NATIVE_API_LEVEL=${{ matrix.api }} \
-DANDROID_STL=c++_static \
-DCMAKE_BUILD_TYPE=Release \
-DBUILD_ZVEC_SHARED=OFF \
-DBUILD_ZVEC_AILEGO_SHARED=OFF \
-DBUILD_ZVEC_CORE_SHARED=OFF \
-DBUILD_PYTHON_BINDINGS=OFF \
-DBUILD_TOOLS=OFF \
-DBUILD_CPP_EXAMPLES=ON \
-DENABLE_NATIVE=OFF \
-DAUTO_DETECT_ARCH=OFF \
-DENABLE_WERROR=ON \
Expand All @@ -127,7 +139,15 @@ jobs:
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache

echo "Building all targets..."
if [ "${{ matrix.abi }}" = "arm64-v8a" ]; then
echo "Building focused DiskAnn tests and public C++ examples for arm64-v8a..."
cmake --build "$BUILD_DIR" \
--target diskann_mobile_compat_test diskann_mobile_collection_test zvec_cpp_examples \
--parallel
exit 0
fi

echo "Building all x86_64 targets..."
cmake --build "$BUILD_DIR" --parallel

# Discover test targets from ctest metadata
Expand All @@ -152,6 +172,7 @@ jobs:

# ── Step 3: start emulator ─────────────────────────────────────────
- name: 'Step 3: Start Android emulator'
if: matrix.abi == 'x86_64'
shell: bash
run: |
AVD_NAME="zvec_test_avd"
Expand Down Expand Up @@ -246,6 +267,7 @@ jobs:

# ── Step 4: run unit tests on emulator ─────────────────────────────
- name: 'Step 4: Run unit tests on emulator'
if: matrix.abi == 'x86_64'
shell: bash
env:
BUILD_DIR: build_android_${{ matrix.abi }}
Expand Down Expand Up @@ -387,47 +409,73 @@ jobs:

# ── Step 5: build and run examples ─────────────────────────────────
- name: 'Step 5: Build and run examples'
if: matrix.abi == 'x86_64'
shell: bash
env:
BUILD_DIR: build_android_${{ matrix.abi }}
run: |
ANDROID_NDK_HOME="$ANDROID_HOME/ndk/$NDK_VERSION"
EXAMPLES_BUILD="examples/c++/build-android-examples-${{ matrix.abi }}"
cmake --build "$BUILD_DIR" --target zvec_cpp_examples --parallel
READELF="$ANDROID_HOME/ndk/$NDK_VERSION/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-readelf"

cmake -S examples/c++ -B "$EXAMPLES_BUILD" -G Ninja \
-DCMAKE_TOOLCHAIN_FILE="$ANDROID_NDK_HOME/build/cmake/android.toolchain.cmake" \
-DANDROID_ABI=${{ matrix.abi }} \
-DANDROID_PLATFORM=android-${{ matrix.api }} \
-DANDROID_STL=c++_static \
-DCMAKE_BUILD_TYPE=Release \
-DHOST_BUILD_DIR="$BUILD_DIR" \
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache
cmake --build "$EXAMPLES_BUILD" --parallel
for example in ailego-example core-example external-vector-example db-example; do
example_path="$BUILD_DIR/bin/$example"
if [ ! -f "$example_path" ]; then
echo "Missing example binary: $example_path"
exit 1
fi

# Reuse the shared-library directory from Step 4; push again in
# case Step 4 was skipped or the directory was cleaned.
DEVICE_LIB_DIR="/data/local/tmp/zvec_tests/lib"
adb shell "mkdir -p $DEVICE_LIB_DIR" 2>/dev/null || true
SO_COUNT=0
while IFS= read -r so_file; do
adb push "$so_file" "$DEVICE_LIB_DIR/$(basename "$so_file")" > /dev/null 2>&1
SO_COUNT=$((SO_COUNT + 1))
done < <(find "$BUILD_DIR/lib" -name "*.so" -type f 2>/dev/null)
echo "Pushed $SO_COUNT shared libraries to $DEVICE_LIB_DIR"

for example in ailego-example core-example db-example; do
if [ -f "$EXAMPLES_BUILD/$example" ]; then
echo "=== Running $example ==="
adb push "$EXAMPLES_BUILD/$example" "/data/local/tmp/$example" > /dev/null 2>&1
adb shell "chmod 755 /data/local/tmp/$example && cd /data/local/tmp && LD_LIBRARY_PATH=$DEVICE_LIB_DIR ./$example"
adb shell "rm -f /data/local/tmp/$example"
echo "=== Verifying $example is self-contained ==="
dynamic_section=$("$READELF" --dynamic "$example_path")
echo "$dynamic_section" | grep NEEDED || true
if echo "$dynamic_section" | grep -Eq 'libzvec[^]]*\.so|libc\+\+_shared\.so'; then
echo "$example unexpectedly depends on a C++ shared library"
exit 1
fi

echo "=== Running $example ==="
adb push "$example_path" "/data/local/tmp/$example" > /dev/null 2>&1
adb shell "chmod 755 /data/local/tmp/$example && cd /data/local/tmp && ./$example"
adb shell "rm -f /data/local/tmp/$example"
done

- name: 'Step 3: Verify arm64-v8a artifacts'
if: matrix.abi == 'arm64-v8a'
shell: bash
env:
BUILD_DIR: build_android_${{ matrix.abi }}
run: |
READELF="$ANDROID_HOME/ndk/$NDK_VERSION/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-readelf"

for binary in \
diskann_mobile_compat_test \
diskann_mobile_collection_test \
ailego-example \
core-example \
external-vector-example \
db-example; do
binary_path="$BUILD_DIR/bin/$binary"
if [ ! -f "$binary_path" ]; then
echo "Missing arm64-v8a binary: $binary_path"
exit 1
fi
if ! "$READELF" --file-header "$binary_path" | grep -q 'Machine:.*AArch64'; then
echo "$binary_path is not an AArch64 binary"
exit 1
fi
done

for example in ailego-example core-example external-vector-example db-example; do
example_path="$BUILD_DIR/bin/$example"
dynamic_section=$("$READELF" --dynamic "$example_path")
if echo "$dynamic_section" | grep -Eq 'libzvec[^]]*\.so|libc\+\+_shared\.so'; then
echo "$example unexpectedly depends on a C++ shared library"
exit 1
fi
done

# ── Cleanup ────────────────────────────────────────────────────────
- name: Stop emulator
if: always()
if: matrix.abi == 'x86_64' && always()
shell: bash
run: |
adb emu kill 2>/dev/null || true
Expand Down
18 changes: 18 additions & 0 deletions .github/workflows/06-ios-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,12 @@ jobs:
-DCMAKE_OSX_ARCHITECTURES="${{ matrix.arch }}" \
-DCMAKE_OSX_SYSROOT="$SDK_PATH" \
-DCMAKE_BUILD_TYPE=Release \
-DBUILD_ZVEC_SHARED=OFF \
-DBUILD_ZVEC_AILEGO_SHARED=OFF \
-DBUILD_ZVEC_CORE_SHARED=OFF \
-DBUILD_PYTHON_BINDINGS=OFF \
-DBUILD_TOOLS=OFF \
-DBUILD_CPP_EXAMPLES=ON \
-DENABLE_WERROR=ON \
-DCMAKE_INSTALL_PREFIX="./install" \
-DGLOBAL_CC_PROTOBUF_PROTOC="$GITHUB_WORKSPACE/build_host/bin/protoc" \
Expand All @@ -81,6 +85,20 @@ jobs:

cmake --build build_ios_${{ matrix.platform }} --parallel $NPROC

- name: Build public static C++ examples
run: |
NPROC=$(sysctl -n hw.ncpu)
BUILD_DIR=build_ios_${{ matrix.platform }}
cmake --build "$BUILD_DIR" --target zvec_cpp_examples --parallel "$NPROC"

for example in ailego-example core-example external-vector-example db-example; do
example_binary="$BUILD_DIR/bin/$example.app/$example"
if [ ! -f "$example_binary" ]; then
echo "Missing iOS example binary: $example_binary"
exit 1
fi
done

- name: Build test targets
if: matrix.test_on_simulator
run: |
Expand Down
28 changes: 22 additions & 6 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -74,20 +74,30 @@ endif()
include_directories(${PROJECT_ROOT_DIR}/src/include)
include_directories(${PROJECT_ROOT_DIR}/src)

option(BUILD_ZVEC_SHARED "Build all-in-one C++ shared library libzvec" ON)
option(BUILD_ZVEC_AILEGO_SHARED "Build all-in-one zvec-ailego shared library libzvec_ailego" ON)
option(BUILD_ZVEC_CORE_SHARED "Build all-in-one zvec-core shared library libzvec_core" ON)
set(ZVEC_CPP_SHARED_DEFAULT ON)
if(ANDROID OR IOS)
# A C++ shared library built with a static libc++ cannot safely exchange STL
# objects with a mobile application. Mobile C++ consumers use the static SDK
# targets below; the shared C API remains available through BUILD_C_BINDINGS.
set(ZVEC_CPP_SHARED_DEFAULT OFF)
endif()

option(BUILD_ZVEC_SHARED "Build all-in-one C++ shared library libzvec" ${ZVEC_CPP_SHARED_DEFAULT})
option(BUILD_ZVEC_AILEGO_SHARED "Build all-in-one zvec-ailego shared library libzvec_ailego" ${ZVEC_CPP_SHARED_DEFAULT})
option(BUILD_ZVEC_CORE_SHARED "Build all-in-one zvec-core shared library libzvec_core" ${ZVEC_CPP_SHARED_DEFAULT})

option(BUILD_PYTHON_BINDINGS "Build Python bindings using pybind11" OFF)
option(BUILD_C_BINDINGS "Build C bindings" ON)
option(BUILD_TOOLS "Build tools" ON)
option(BUILD_CPP_EXAMPLES "Build C++ examples" OFF)

message(STATUS "BUILD_ZVEC_SHARED:${BUILD_ZVEC_SHARED}")
message(STATUS "BUILD_ZVEC_AILEGO_SHARED:${BUILD_ZVEC_AILEGO_SHARED}")
message(STATUS "BUILD_ZVEC_CORE_SHARED:${BUILD_ZVEC_CORE_SHARED}")
message(STATUS "BUILD_PYTHON_BINDINGS:${BUILD_PYTHON_BINDINGS}")
message(STATUS "BUILD_C_BINDINGS:${BUILD_C_BINDINGS}")
message(STATUS "BUILD_TOOLS:${BUILD_TOOLS}")
message(STATUS "BUILD_CPP_EXAMPLES:${BUILD_CPP_EXAMPLES}")

option(RABITQ_ENABLE_AVX512 "Compile RaBitQ with AVX-512 support" OFF)

Expand Down Expand Up @@ -122,14 +132,16 @@ else()
endif()
message(STATUS "RABITQ_ARCH_FLAG: ${RABITQ_ARCH_FLAG}")

# DiskAnn support (Linux x86_64 only; libaio loaded at runtime via dlopen)
if(CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64|i686|i386" AND NOT ANDROID AND NOT IOS)
# DiskAnn support. Desktop Linux x86 uses libaio when available, while
# Android and iOS use the portable synchronous pread backend.
if((CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64|i686|i386" AND NOT ANDROID AND NOT IOS)
OR ANDROID OR IOS)
set(DISKANN_SUPPORTED ON)
add_definitions(-DDISKANN_SUPPORTED=1)
else()
set(DISKANN_SUPPORTED OFF)
add_definitions(-DDISKANN_SUPPORTED=0)
message(STATUS "DiskAnn support disabled - only supported on Linux x86_64")
message(STATUS "DiskAnn support disabled - supported on Linux x86 and Android/iOS")
endif()
message(STATUS "DISKANN_SUPPORTED: ${DISKANN_SUPPORTED}")

Expand All @@ -142,6 +154,10 @@ message(STATUS "USE_OSS_MIRROR:${USE_OSS_MIRROR}")
cc_directory(thirdparty)
cc_directories(src)

if(BUILD_CPP_EXAMPLES)
add_subdirectory(examples/c++ EXCLUDE_FROM_ALL)
endif()

cc_directories(tests)

add_custom_target(clang_tidy_deps DEPENDS zvec_proto ARROW.BUILD glog gflags Lz4.BUILD)
Expand Down
44 changes: 37 additions & 7 deletions cmake/bazel.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -616,17 +616,24 @@ function(_absolute_paths _RESULT)
set(${_RESULT} "${FILEPATHS}" PARENT_SCOPE)
endfunction()

## Add both shared and static library
## Add a main library target and an explicit static variant.
macro(_add_library _NAME _OPTION)
add_library(${_NAME}_objects OBJECT ${_OPTION} ${ARGN})
add_library(
${_NAME}_static STATIC ${_OPTION} $<TARGET_OBJECTS:${_NAME}_objects>
)
if(IOS)
# iOS: create the main target as static too (no shared libs on iOS)
if(IOS OR (ANDROID AND ANDROID_STL STREQUAL "c++_static"))
add_library(
${_NAME} STATIC ${_OPTION} $<TARGET_OBJECTS:${_NAME}_objects>
)
# Keep the two mobile build targets available but give the main archive a
# distinct file name for Ninja. Link-time canonicalization below ensures
# only the main archive is ever whole-archived into an executable.
set_property(TARGET ${_NAME} PROPERTY OUTPUT_NAME ${_NAME}_main)
set_property(
TARGET ${_NAME} PROPERTY ZVEC_CANONICAL_LINK_TARGET ${_NAME})
set_property(
TARGET ${_NAME}_static PROPERTY ZVEC_CANONICAL_LINK_TARGET ${_NAME})
else()
add_library(
${_NAME} SHARED ${_OPTION} $<TARGET_OBJECTS:${_NAME}_objects>
Expand Down Expand Up @@ -671,13 +678,26 @@ endfunction()

## Link libraries
function(_target_link_libraries _NAME)
function(_resolve_link_target LIB RESULT_VAR)
if(TARGET ${LIB})
get_target_property(
CANONICAL_LINK_TARGET ${LIB} ZVEC_CANONICAL_LINK_TARGET)
if(CANONICAL_LINK_TARGET)
set(${RESULT_VAR} ${CANONICAL_LINK_TARGET} PARENT_SCOPE)
return()
endif()
endif()
set(${RESULT_VAR} ${LIB} PARENT_SCOPE)
endfunction()

function(_collect_always_link_libs LIB_LIST RESULT_VAR)
if(NOT _COLLECT_ALWAYS_LINK_VISITED)
set(_COLLECT_ALWAYS_LINK_VISITED "" PARENT_SCOPE)
endif()

set(LOCAL_RESULT "")
foreach(LIB ${LIB_LIST})
_resolve_link_target(${LIB} LIB)
if(NOT TARGET ${LIB})
continue()
endif()
Expand Down Expand Up @@ -707,7 +727,10 @@ function(_target_link_libraries _NAME)
endif()

get_target_property(LINK_LIBS ${LIB} LINK_LIBRARIES)
if(LINK_LIBS)
get_target_property(LIB_TYPE ${LIB} TYPE)
if(LINK_LIBS AND
NOT LIB_TYPE STREQUAL "SHARED_LIBRARY" AND
NOT LIB_TYPE STREQUAL "MODULE_LIBRARY")
_collect_always_link_libs("${LINK_LIBS}" LINK_ALWAYS_LINK_LIBS)
list(APPEND LOCAL_RESULT ${LINK_ALWAYS_LINK_LIBS})
endif()
Expand All @@ -717,11 +740,18 @@ function(_target_link_libraries _NAME)
set(${RESULT_VAR} "${LOCAL_RESULT}" PARENT_SCOPE)
endfunction()

_collect_always_link_libs("${ARGN}" ALL_ALWAYS_LINK_LIBS)
set(INPUT_LIBS "")
foreach(LIB ${ARGN})
_resolve_link_target(${LIB} RESOLVED_LIB)
list(APPEND INPUT_LIBS ${RESOLVED_LIB})
endforeach()
list(REMOVE_DUPLICATES INPUT_LIBS)

_collect_always_link_libs("${INPUT_LIBS}" ALL_ALWAYS_LINK_LIBS)

set(ALL_LIBS_TO_PROCESS ${ARGN})
set(ALL_LIBS_TO_PROCESS ${INPUT_LIBS})
foreach(ALWAYS_LIB ${ALL_ALWAYS_LINK_LIBS})
list(FIND ARGN ${ALWAYS_LIB} FOUND_INDEX)
list(FIND INPUT_LIBS ${ALWAYS_LIB} FOUND_INDEX)
if(FOUND_INDEX EQUAL -1)
list(APPEND ALL_LIBS_TO_PROCESS ${ALWAYS_LIB})
endif()
Expand Down
Loading