Skip to content

Commit bcb76e3

Browse files
richyreachyihb2032
authored andcommitted
Merge branch 'main' into fix/non-x86-build
2 parents fe1a7a3 + d9cf689 commit bcb76e3

47 files changed

Lines changed: 709 additions & 6014 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.clang-tidy

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
Checks: >
2+
-*,
3+
modernize-use-nullptr,
4+
WarningsAsErrors: "*"
5+
HeaderFilterRegex: "^(src|tests|tools)/"
6+
FormatStyle: none
7+
SystemHeaders: false

.github/workflows/01-ci-pipeline.yml

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -42,42 +42,50 @@ jobs:
4242
!contains(github.event.pull_request.title, 'wip'))
4343
uses: ./.github/workflows/02-lint-check.yml
4444

45+
# Static analysis: clang-tidy on changed C/C++ files
46+
clang-tidy:
47+
if: >-
48+
github.event_name != 'pull_request' ||
49+
(!github.event.pull_request.draft &&
50+
!contains(github.event.pull_request.title, 'wip'))
51+
uses: ./.github/workflows/clang_tidy.yml
52+
4553
# Main build and test matrix
4654
build-and-test-macos-arm64:
4755
name: Build & Test (macos-arm64)
48-
needs: lint
56+
needs: [lint, clang-tidy]
4957
uses: ./.github/workflows/03-macos-linux-build.yml
5058
with:
5159
platform: macos-arm64
5260
os: macos-15
5361

5462
build-and-test-macos-26-arm64:
5563
name: Build & Test (macos-26-arm64)
56-
needs: lint
64+
needs: [lint, clang-tidy]
5765
uses: ./.github/workflows/03-macos-linux-build.yml
5866
with:
5967
platform: macos-arm64
6068
os: macos-26
6169

6270
build-and-test-linux-arm64:
6371
name: Build & Test (linux-arm64)
64-
needs: lint
72+
needs: [lint, clang-tidy]
6573
uses: ./.github/workflows/03-macos-linux-build.yml
6674
with:
6775
platform: linux-arm64
6876
os: ubuntu-24.04-arm
6977

7078
build-and-test-linux-x64:
7179
name: Build & Test (linux-x64)
72-
needs: lint
80+
needs: [lint, clang-tidy]
7381
uses: ./.github/workflows/03-macos-linux-build.yml
7482
with:
7583
platform: linux-x64
7684
os: ubuntu-24.04
7785

7886
build-and-test-linux-x64-clang:
7987
name: Build & Test (linux-x64-clang)
80-
needs: lint
88+
needs: [lint, clang-tidy]
8189
uses: ./.github/workflows/03-macos-linux-build.yml
8290
with:
8391
platform: linux-x64-clang
@@ -91,15 +99,15 @@ jobs:
9199

92100
build-android:
93101
name: Build & Test (android)
94-
needs: lint
102+
needs: [lint, clang-tidy]
95103
uses: ./.github/workflows/04-android-build.yml
96104

97105
build-and-test-on-windows:
98106
name: Build & Test (Windows)
99-
needs: lint
107+
needs: [lint, clang-tidy]
100108
uses: ./.github/workflows/05-windows-build.yml
101109

102110
build-ios:
103111
name: Build & Test (iOS)
104-
needs: lint
112+
needs: [lint, clang-tidy]
105113
uses: ./.github/workflows/06-ios-build.yml

.github/workflows/04-android-build.yml

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -411,11 +411,22 @@ jobs:
411411
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache
412412
cmake --build "$EXAMPLES_BUILD" --parallel
413413
414+
# Reuse the shared-library directory from Step 4; push again in
415+
# case Step 4 was skipped or the directory was cleaned.
416+
DEVICE_LIB_DIR="/data/local/tmp/zvec_tests/lib"
417+
adb shell "mkdir -p $DEVICE_LIB_DIR" 2>/dev/null || true
418+
SO_COUNT=0
419+
while IFS= read -r so_file; do
420+
adb push "$so_file" "$DEVICE_LIB_DIR/$(basename "$so_file")" > /dev/null 2>&1
421+
SO_COUNT=$((SO_COUNT + 1))
422+
done < <(find "$BUILD_DIR/lib" -name "*.so" -type f 2>/dev/null)
423+
echo "Pushed $SO_COUNT shared libraries to $DEVICE_LIB_DIR"
424+
414425
for example in ailego-example core-example db-example; do
415426
if [ -f "$EXAMPLES_BUILD/$example" ]; then
416427
echo "=== Running $example ==="
417428
adb push "$EXAMPLES_BUILD/$example" "/data/local/tmp/$example" > /dev/null 2>&1
418-
adb shell "chmod 755 /data/local/tmp/$example && cd /data/local/tmp && ./$example"
429+
adb shell "chmod 755 /data/local/tmp/$example && cd /data/local/tmp && LD_LIBRARY_PATH=$DEVICE_LIB_DIR ./$example"
419430
adb shell "rm -f /data/local/tmp/$example"
420431
fi
421432
done

.github/workflows/05-windows-build.yml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,30 @@ jobs:
9797
cd build
9898
cmake .. -G Ninja -DCMAKE_BUILD_TYPE=Release
9999
cmake --build . --config Release --parallel $env:NPROC
100+
101+
# Copy zvec.dll next to the example executables so Windows can find it.
102+
# CMake places DLLs in bin/ (RUNTIME output) and import libs in lib/.
103+
$buildDir = "$env:GITHUB_WORKSPACE\build"
104+
$found = $false
105+
foreach ($sub in @("$buildDir\bin", "$buildDir\bin\Release", "$buildDir\lib", "$buildDir\lib\Release")) {
106+
if (Test-Path "$sub\zvec.dll") {
107+
Copy-Item "$sub\zvec.dll" -Destination . -Force
108+
Write-Host "Copied zvec.dll from $sub"
109+
$found = $true
110+
break
111+
}
112+
}
113+
if (-not $found) {
114+
Write-Host "WARNING: zvec.dll not found, searching recursively..."
115+
$dll = Get-ChildItem -Path $buildDir -Filter "zvec.dll" -Recurse -ErrorAction SilentlyContinue | Select-Object -First 1
116+
if ($dll) {
117+
Copy-Item $dll.FullName -Destination . -Force
118+
Write-Host "Copied zvec.dll from $($dll.DirectoryName)"
119+
} else {
120+
Write-Error "zvec.dll not found anywhere under $buildDir"
121+
}
122+
}
123+
100124
.\db-example.exe
101125
.\core-example.exe
102126
.\ailego-example.exe

.github/workflows/07-linux-riscv-build.yml

Lines changed: 33 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,15 @@ jobs:
2323

2424
- name: Install build dependencies
2525
run: |
26-
sudo apt-get update
27-
sudo apt-get install -y python3-pybind11 pybind11-dev
26+
sudo systemctl stop apt-daily.timer apt-daily-upgrade.timer || true
27+
sudo systemctl stop apt-daily.service apt-daily-upgrade.service || true
28+
29+
sudo apt-get update -o Dpkg::Lock::Timeout=300
30+
sudo DEBIAN_FRONTEND=noninteractive apt-get install -yq \
31+
-o Dpkg::Options::="--force-confdef" \
32+
-o Dpkg::Options::="--force-confold" \
33+
-o Dpkg::Lock::Timeout=300 \
34+
python3-pybind11 pybind11-dev
2835
shell: bash
2936

3037
- name: Build from source
@@ -59,12 +66,6 @@ jobs:
5966
needs: build
6067

6168
steps:
62-
- name: Install test dependencies
63-
run: |
64-
sudo apt-get update
65-
sudo apt-get install -y python3-pybind11 pybind11-dev libgtest-dev liburing-dev
66-
shell: bash
67-
6869
- name: Download workspace artifacts
6970
uses: actions/download-artifact@v8
7071
with:
@@ -77,6 +78,19 @@ jobs:
7778
tar -xf linux-riscv64-workspace.tar
7879
shell: bash
7980

81+
- name: Install test dependencies
82+
run: |
83+
sudo systemctl stop apt-daily.timer apt-daily-upgrade.timer || true
84+
sudo systemctl stop apt-daily.service apt-daily-upgrade.service || true
85+
86+
sudo apt-get update -o Dpkg::Lock::Timeout=300
87+
sudo DEBIAN_FRONTEND=noninteractive apt-get install -yq \
88+
-o Dpkg::Options::="--force-confdef" \
89+
-o Dpkg::Options::="--force-confold" \
90+
-o Dpkg::Lock::Timeout=300 \
91+
python3-pybind11 pybind11-dev libgtest-dev liburing-dev
92+
shell: bash
93+
8094
- name: Reconfigure build directory
8195
run: |
8296
cd "$GITHUB_WORKSPACE"
@@ -129,8 +143,16 @@ jobs:
129143

130144
- name: Install dependencies
131145
run: |
132-
sudo apt-get update
133-
sudo apt-get install -y libgtest-dev liburing-dev
146+
sudo systemctl stop apt-daily.timer apt-daily-upgrade.timer || true
147+
sudo systemctl stop apt-daily.service apt-daily-upgrade.service || true
148+
149+
sudo apt-get update -o Dpkg::Lock::Timeout=300
150+
sudo DEBIAN_FRONTEND=noninteractive apt-get install -yq \
151+
-o Dpkg::Options::="--force-confdef" \
152+
-o Dpkg::Options::="--force-confold" \
153+
-o Dpkg::Lock::Timeout=300 \
154+
libgtest-dev liburing-dev
155+
134156
$PYTHON -m pip install --upgrade pip
135157
$PYTHON -m pip install numpy==2.2.2 cmake==3.30.0 ninja==1.11.1.1 --index-url "$RISE_PYPI"
136158
$PYTHON -m pip install pybind11==3.0 pytest scikit-build-core setuptools_scm
@@ -225,4 +247,4 @@ jobs:
225247
./c_api_field_schema_example
226248
./c_api_index_example
227249
./c_api_optimized_example
228-
shell: bash
250+
shell: bash

.github/workflows/clang_tidy.yml

Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
name: Clang-Tidy
2+
3+
on:
4+
workflow_call:
5+
workflow_dispatch:
6+
7+
concurrency:
8+
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
9+
cancel-in-progress: true
10+
11+
permissions:
12+
contents: read
13+
14+
jobs:
15+
clang_tidy:
16+
name: Clang-Tidy Checks
17+
runs-on: ubuntu-24.04
18+
steps:
19+
- name: Checkout code
20+
uses: actions/checkout@v6
21+
with:
22+
submodules: recursive
23+
# fetch-depth: 0 is required for tj-actions/changed-files to correctly
24+
# compute the diff against the base branch on pull_request events.
25+
fetch-depth: 0
26+
27+
- name: Install dependencies
28+
run: |
29+
sudo apt-get update
30+
sudo apt-get install -y clang-tidy=1:18.0-59~exp2 cmake ninja-build
31+
32+
- name: Configure CMake and export compile commands
33+
run: |
34+
cmake -S . -B build -G Ninja \
35+
-DCMAKE_EXPORT_COMPILE_COMMANDS=ON \
36+
-DBUILD_TOOLS=ON
37+
38+
- name: Collect changed C/C++ files
39+
id: changed_files
40+
uses: tj-actions/changed-files@v47
41+
with:
42+
files: |
43+
**/*.c
44+
**/*.cc
45+
**/*.cpp
46+
**/*.cxx
47+
files_ignore: |
48+
thirdparty/**
49+
build/**
50+
51+
- name: Filter changed files against compile_commands.json
52+
id: tidy_files
53+
if: steps.changed_files.outputs.any_changed == 'true'
54+
run: |
55+
python3 - <<'PY'
56+
import json
57+
import os
58+
from pathlib import Path
59+
60+
# all_changed_files is space-separated when output_format is not set;
61+
# tj-actions v46 defaults to space-separated for the env var form.
62+
# We read from the file written by the action instead via GITHUB_OUTPUT,
63+
# but the safest approach is to use the JSON output format.
64+
raw = os.environ.get("ALL_CHANGED_FILES", "")
65+
changed = [f for f in raw.split() if f]
66+
67+
compile_db_path = Path("build/compile_commands.json")
68+
with compile_db_path.open("r", encoding="utf-8") as fh:
69+
compile_db = json.load(fh)
70+
71+
# Build a set of absolute, normalised paths from compile_commands.json.
72+
compile_entries = set()
73+
for entry in compile_db:
74+
file_field = entry.get("file", "")
75+
if file_field:
76+
compile_entries.add(os.path.normpath(file_field))
77+
78+
cwd = Path.cwd().resolve()
79+
selected = []
80+
skipped = []
81+
82+
for rel_path in changed:
83+
abs_path = os.path.normpath(str((cwd / rel_path).resolve()))
84+
if abs_path in compile_entries:
85+
selected.append(rel_path)
86+
elif not Path(rel_path).is_file():
87+
skipped.append(f"{rel_path} (file not found)")
88+
else:
89+
skipped.append(f"{rel_path} (not in compile_commands.json)")
90+
91+
github_output = os.environ["GITHUB_OUTPUT"]
92+
with open(github_output, "a", encoding="utf-8") as out:
93+
out.write(f"any_tidy_files={'true' if selected else 'false'}\n")
94+
out.write("all_tidy_files<<TIDY_EOF\n")
95+
out.write("\n".join(selected) + "\n")
96+
out.write("TIDY_EOF\n")
97+
out.write("skipped_files<<SKIP_EOF\n")
98+
out.write("\n".join(skipped) + "\n")
99+
out.write("SKIP_EOF\n")
100+
PY
101+
env:
102+
ALL_CHANGED_FILES: ${{ steps.changed_files.outputs.all_changed_files }}
103+
104+
- name: Show skipped files
105+
if: steps.changed_files.outputs.any_changed == 'true' && steps.tidy_files.outputs.skipped_files != ''
106+
run: |
107+
echo "=== Files skipped by clang-tidy ==="
108+
printf '%s\n' "${{ steps.tidy_files.outputs.skipped_files }}"
109+
110+
- name: Compute submodule commits hash
111+
id: submodule_hash
112+
run: |
113+
# Collect each submodule's current commit SHA, sort for a stable order,
114+
# then SHA-256 the result so the cache key stays a fixed length.
115+
hash=$(git submodule status --recursive | awk '{print $1}' | sort | sha256sum | awk '{print $1}')
116+
echo "value=${hash}" >> "$GITHUB_OUTPUT"
117+
118+
- name: Cache third-party build artifacts
119+
id: cache_thirdparty
120+
uses: actions/cache@v5
121+
with:
122+
path: build/external
123+
# Cache key combines:
124+
# - thirdparty CMakeLists / cmake / patch file contents
125+
# - all submodule commit SHAs (upgrading a submodule busts the cache)
126+
key: thirdparty-${{ runner.os }}-${{ hashFiles('thirdparty/**/*.cmake', 'thirdparty/**/CMakeLists.txt', 'thirdparty/**/*.patch') }}-${{ steps.submodule_hash.outputs.value }}
127+
128+
- name: Build
129+
if: steps.tidy_files.outputs.any_tidy_files == 'true'
130+
run: |
131+
# build so that clang-tidy can find the headers
132+
ninja -C build zvec_db
133+
134+
- name: Run clang-tidy on changed files
135+
if: steps.tidy_files.outputs.any_tidy_files == 'true'
136+
run: |
137+
# Read the newline-delimited file list into an array.
138+
mapfile -t files_to_check <<'TIDY_EOF'
139+
${{ steps.tidy_files.outputs.all_tidy_files }}
140+
TIDY_EOF
141+
142+
failed=0
143+
for file in "${files_to_check[@]}"; do
144+
# Skip blank lines that mapfile may produce.
145+
[[ -z "${file// }" ]] && continue
146+
if [ -f "$file" ]; then
147+
echo "=== clang-tidy: $file ==="
148+
clang-tidy -p build --warnings-as-errors='*' "$file" || failed=1
149+
fi
150+
done
151+
152+
exit $failed
153+
154+
- name: No C/C++ files changed
155+
if: steps.changed_files.outputs.any_changed != 'true' || steps.tidy_files.outputs.any_tidy_files != 'true'
156+
run: echo "No changed source files with compile_commands entries to analyse."

0 commit comments

Comments
 (0)