diff --git a/.github/workflows/build-libseekdb.yml b/.github/workflows/build-libseekdb.yml
new file mode 100644
index 000000000..0b1a178e2
--- /dev/null
+++ b/.github/workflows/build-libseekdb.yml
@@ -0,0 +1,950 @@
+# Build, pack and upload libseekdb for multiple platforms (linux x64/arm64, macos arm64, windows x64, android arm64-v8a) to S3
+#
+# Reference build environments (use these systems/env as the standard):
+# linux-x64: runner ubuntu-22.04, container quay.io/pypa/manylinux2014_x86_64 (glibc 2.17, CentOS 7+), zip libseekdb-linux-x64.zip
+# linux-arm64: runner ubuntu-22.04-arm, container quay.io/pypa/manylinux2014_aarch64 (glibc 2.17), zip libseekdb-linux-arm64.zip
+# darwin-arm64: runner macos-15, native, zip libseekdb-darwin-arm64.zip (min macOS 11.0)
+# windows-x64: runner windows-2022, .\build.ps1 + libseekdb-build.ps1, zip libseekdb-windows-x64.zip (seekdb.dll + libs/*.dll)
+# android-arm64-v8a: runner macos-15, NDK + ./build.sh --android, zip libseekdb-android-arm64-v8a.zip
+#
+# macOS builds use runner macos-15 and set CMAKE_OSX_DEPLOYMENT_TARGET=11.0 so the dylib runs on macOS 11+ (Big Sur and later).
+# On macOS, dylibs are signed in libseekdb-build.sh: ad-hoc when no cert; when repo is oceanbase/seekdb and secrets are set,
+# use Developer ID (secrets: OSX_CODESIGN_BUILD_CERTIFICATE_BASE64, OSX_CODESIGN_P12_PASSWORD, OSX_CODESIGN_KEYCHAIN_PASSWORD, OSX_CODESIGN_IDENTITY).
+# Optional: add notarization step and APPLE_ID/PASSWORD/TEAM_ID secrets to notarize the zip.
+# Artifacts: platform zips including libseekdb-android-arm64-v8a.zip; combined artifact libseekdb-all-platforms; optional S3 upload when DESTINATION_TARGET_PATH or AWS_S3_BUCKET and credentials are set.
+#
+# Job step order: Checkout → caches → compile → setup Node/Rust/Go/Java → FFI binding tests (continue-on-error per language
+# so all languages run; final summary step fails the job if any binding test failed) → pack → packed-zip smoke (nodejs_napi)
+# → upload artifact → save caches (always).
+# macOS ccache keys include COMMIT_SHA so object files from other commits are not reused (see package/libseekdb/README.md).
+# Android: compile → setup toolchains → host-skip FFI notice → pack → verify zip → upload → save caches → summary (see job comment).
+name: Build libseekdb
+run-name: Build libseekdb for ${{ github.event_name == 'workflow_dispatch' && inputs.ref != '' && inputs.ref || (github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha) }}
+
+# PRs: pull_request. Direct pushes: only long-lived / release lines — avoids duplicate runs when the same commit
+# is both "push" to a feature branch and "pull_request" sync (open PR to upstream from that branch).
+# S3 upload still only on main, master, develop, *.*.x, integration/* (UPLOAD_S3; see release-artifacts job).
+on:
+ push:
+ branches:
+ - main
+ - master
+ - develop
+ - "integration/**"
+ - "release/**"
+ # e.g. 1.0.x; aligns with S3 / UPLOAD_S3 for dot-x lines
+ - "*.*.x"
+ paths-ignore:
+ - "*.md"
+ - "LICENSE"
+ - "CODEOWNERS"
+ - "docs/**"
+ workflow_dispatch:
+ inputs:
+ ref:
+ description: "Branch, tag or commit SHA to build (empty = use default branch)"
+ required: false
+ type: string
+ default: ""
+ pull_request:
+ paths-ignore:
+ - "*.md"
+ - "LICENSE"
+ - "CODEOWNERS"
+ - "docs/**"
+
+env:
+ COMMIT_SHA: ${{ github.event_name == 'workflow_dispatch' && inputs.ref != '' && inputs.ref || (github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha) }}
+ AWS_REGION: ${{ vars.AWS_REGION || 'ap-southeast-1' }}
+ UPLOAD_S3: ${{ github.event_name == 'workflow_dispatch' || (github.event_name == 'push' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/master' || github.ref == 'refs/heads/develop' || startsWith(github.ref, 'refs/heads/integration/') || contains(github.ref, '.x'))) }}
+ BUCKET_NAME: ${{ vars.AWS_S3_BUCKET || 'oceanbase-seekdb-builds' }}
+ DESTINATION_TARGET_PATH: ${{ vars.DESTINATION_TARGET_PATH || format('s3://oceanbase-seekdb-builds/libseekdb/all_commits/{0}', github.event_name == 'workflow_dispatch' && inputs.ref != '' && inputs.ref || (github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha)) }}
+ S3_BUCKET: ${{ vars.AWS_S3_BUCKET || 'oceanbase-seekdb-builds' }}
+ S3_PREFIX: libseekdb/all_commits/${{ github.event_name == 'workflow_dispatch' && inputs.ref != '' && inputs.ref || (github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha) }}
+
+jobs:
+ # ---------- Build libseekdb on Linux / macOS ----------
+ build:
+ name: Build libseekdb (${{ matrix.platform }})
+ runs-on: ${{ matrix.runner }}
+ strategy:
+ fail-fast: false
+ matrix:
+ include:
+ - platform: linux-x64
+ runner: ubuntu-22.04
+ artifact_name: libseekdb-linux-x64
+ container_image: quay.io/pypa/manylinux2014_x86_64
+ deps_file: oceanbase.el7.x86_64.deps
+ - platform: linux-arm64
+ runner: ubuntu-22.04-arm
+ artifact_name: libseekdb-linux-arm64
+ container_image: quay.io/pypa/manylinux2014_aarch64
+ deps_file: oceanbase.el7.aarch64.deps
+
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+ with:
+ # workflow_dispatch: use inputs.ref if set; PR: head sha; push: event sha
+ ref: ${{ github.event_name == 'workflow_dispatch' && inputs.ref != '' && inputs.ref || (github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha) }}
+
+ - name: Cache deps (Linux, el7)
+ uses: actions/cache@v4
+ with:
+ path: deps/3rd
+ key: ${{ runner.os }}-libseekdb-deps-${{ matrix.platform }}-el7-${{ hashFiles(format('deps/init/{0}', matrix.deps_file)) }}
+ restore-keys: |
+ ${{ runner.os }}-libseekdb-deps-${{ matrix.platform }}-el7-
+
+ - name: Cache ccache (Linux)
+ uses: actions/cache@v4
+ with:
+ path: .ccache
+ key: ${{ runner.os }}-ccache-libseekdb-${{ matrix.platform }}-${{ env.COMMIT_SHA }}
+ restore-keys: |
+ ${{ runner.os }}-ccache-libseekdb-${{ matrix.platform }}-
+
+ # Run build inside manylinux2014 so Node/actions run on host (glibc 2.28+), build runs in CentOS 7 (glibc 2.17) for compatibility
+ - name: Build libseekdb (Linux, manylinux2014)
+ env:
+ BUILD_TYPE: release
+ run: |
+ docker run --rm -u root \
+ -v "$GITHUB_WORKSPACE:$GITHUB_WORKSPACE" -w "$GITHUB_WORKSPACE" \
+ -e BUILD_TYPE -e GITHUB_WORKSPACE \
+ ${{ matrix.container_image }} \
+ bash -c '
+ set -e
+ # Install deps in two steps: base first (wget required for dep_create.sh), then ccache if available
+ yum install -y git wget rpm cpio make glibc-devel glibc-headers binutils m4 python3 python3-devel libtool libaio ncurses-devel which zlib-devel
+ yum install -y epel-release 2>/dev/null || true
+ yum install -y ccache 2>/dev/null || true
+ git config --global --add safe.directory "$GITHUB_WORKSPACE"
+ export CCACHE_DIR="$GITHUB_WORKSPACE/.ccache"
+ export CCACHE_COMPILERCHECK=content
+ export CCACHE_NOHASHDIR=1
+ mkdir -p deps/3rd/usr/local/oceanbase/devtools/bin
+ CCACHE_SRC=$(command -v ccache 2>/dev/null || true)
+ if [ -n "$CCACHE_SRC" ] && [ -x "$CCACHE_SRC" ]; then
+ ln -sf "$CCACHE_SRC" deps/3rd/usr/local/oceanbase/devtools/bin/ccache
+ USE_CCACHE="-DOB_USE_CCACHE=ON"
+ else
+ USE_CCACHE="-DOB_USE_CCACHE=OFF"
+ fi
+ export PATH="$GITHUB_WORKSPACE/deps/3rd/usr/local/oceanbase/devtools/bin:$PATH"
+ bash build.sh init
+ if [ -x /opt/python/cp39-cp39/bin/python3.9 ]; then
+ export PATH="/opt/python/cp39-cp39/bin:$PATH"
+ PYVER=3.9
+ else
+ PYVER=$(python3 -c "import sys; print(f\"{sys.version_info.major}.{sys.version_info.minor}\")")
+ fi
+ bash build.sh release --init $USE_CCACHE -DBUILD_EMBED_MODE=ON -DPYTHON_VERSION=$PYVER --make libseekdb
+ [ -n "$USE_CCACHE" ] && ccache -s || true
+ '
+ - name: Fix ownership (container writes as root)
+ run: sudo chown -R "$(id -u):$(id -g)" "$GITHUB_WORKSPACE"
+
+ - name: Setup Node.js (Linux)
+ uses: actions/setup-node@v4
+ with:
+ node-version: "18"
+
+ - name: Setup Rust (Linux)
+ uses: dtolnay/rust-toolchain@stable
+ with:
+ toolchain: stable
+
+ - name: Setup Go (Linux)
+ uses: actions/setup-go@v5
+ with:
+ go-version: "1.21"
+
+ - name: Setup Java (Linux)
+ uses: actions/setup-java@v4
+ with:
+ distribution: "temurin"
+ java-version: "17"
+
+ - name: Test Node.js FFI binding (Linux)
+ id: binding_node_ffi
+ continue-on-error: true
+ run: |
+ cd unittest/include/nodejs
+ npm install
+ bash test.sh
+
+ - name: Test Node.js N-API binding (Linux)
+ id: binding_node_napi
+ continue-on-error: true
+ run: |
+ PATH=$(echo "$PATH" | tr ':' '\n' | grep -v 'deps/3rd' | tr '\n' ':' | sed 's/:$//')
+ cd unittest/include/nodejs_napi
+ npm install
+ bash test.sh
+
+ - name: Test Python binding (Linux)
+ id: binding_python
+ continue-on-error: true
+ run: |
+ cd unittest/include/python
+ bash test.sh
+
+ - name: Test Rust binding (Linux)
+ id: binding_rust
+ continue-on-error: true
+ run: |
+ cd unittest/include/rust
+ bash test.sh
+
+ - name: Test Go binding (Linux)
+ id: binding_go
+ continue-on-error: true
+ run: |
+ PATH=$(echo "$PATH" | tr ':' '\n' | grep -v 'deps/3rd' | tr '\n' ':' | sed 's/:$//')
+ cd unittest/include/go
+ bash test.sh
+
+ - name: Test Java binding (Linux)
+ id: binding_java
+ continue-on-error: true
+ run: |
+ PATH=$(echo "$PATH" | tr ':' '\n' | grep -v 'deps/3rd' | tr '\n' ':' | sed 's/:$//')
+ cd unittest/include/java
+ bash test.sh
+
+ - name: Pack libseekdb (Linux)
+ run: |
+ chmod +x package/libseekdb/libseekdb-build.sh
+ cd package/libseekdb && bash libseekdb-build.sh "${GITHUB_WORKSPACE}/build_release/src/include"
+
+ - name: Smoke test packed artifact (Linux)
+ run: |
+ chmod +x package/libseekdb/test-packed-artifact-smoke.sh
+ package/libseekdb/test-packed-artifact-smoke.sh "package/libseekdb/libseekdb-${{ matrix.platform }}.zip"
+
+ - name: Upload artifact
+ uses: actions/upload-artifact@v4
+ with:
+ name: ${{ matrix.artifact_name }}
+ path: package/libseekdb/libseekdb-*.zip
+
+ - name: Save Cache deps (Linux)
+ if: always()
+ uses: actions/cache/save@v4
+ with:
+ path: deps/3rd
+ key: ${{ runner.os }}-libseekdb-deps-${{ matrix.platform }}-el7-${{ hashFiles(format('deps/init/{0}', matrix.deps_file)) }}
+ - name: Save Cache ccache (Linux)
+ if: always()
+ uses: actions/cache/save@v4
+ with:
+ path: .ccache
+ key: ${{ runner.os }}-ccache-libseekdb-${{ matrix.platform }}-${{ env.COMMIT_SHA }}
+
+ - name: Binding tests outcome (Linux)
+ if: always()
+ run: |
+ failed=0
+ for o in \
+ "${{ steps.binding_node_ffi.outcome }}" \
+ "${{ steps.binding_node_napi.outcome }}" \
+ "${{ steps.binding_python.outcome }}" \
+ "${{ steps.binding_rust.outcome }}" \
+ "${{ steps.binding_go.outcome }}" \
+ "${{ steps.binding_java.outcome }}"; do
+ [ "$o" = "failure" ] && failed=1
+ done
+ if [ "$failed" -ne 0 ]; then
+ echo "::error::One or more libseekdb binding tests failed on Linux"
+ exit 1
+ fi
+ echo "All binding test steps succeeded (or were skipped)."
+
+ # ---------- Build on macOS (no container) ----------
+ build-macos:
+ name: Build libseekdb (${{ matrix.platform }})
+ runs-on: ${{ matrix.runner }}
+ strategy:
+ fail-fast: false
+ matrix:
+ include:
+ - platform: darwin-arm64
+ runner: macos-15
+ artifact_name: libseekdb-darwin-arm64
+ arch: arm64
+ cmake_arch: arm64
+
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+ with:
+ ref: ${{ github.event_name == 'workflow_dispatch' && inputs.ref != '' && inputs.ref || (github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha) }}
+
+ - name: Install macOS dependencies (pinned Homebrew)
+ run: |
+ chmod +x package/libseekdb/install-macos-brew-deps.sh
+ package/libseekdb/install-macos-brew-deps.sh
+
+ - name: Cache deps (macOS)
+ uses: actions/cache@v4
+ with:
+ path: deps/3rd
+ key: ${{ runner.os }}-libseekdb-deps-${{ matrix.platform }}-${{ hashFiles('deps/init/oceanbase.macos.arm64.deps') }}
+ restore-keys: |
+ ${{ runner.os }}-libseekdb-deps-${{ matrix.platform }}-
+
+ - name: Cache ccache (macOS)
+ uses: actions/cache@v4
+ with:
+ path: .ccache
+ key: ${{ runner.os }}-ccache-libseekdb-${{ matrix.platform }}-${{ env.COMMIT_SHA }}
+ restore-keys: |
+ ${{ runner.os }}-ccache-libseekdb-${{ matrix.platform }}-
+
+ - name: Build init (macOS)
+ run: bash build.sh init
+
+ - name: Build libseekdb (macOS)
+ env:
+ BUILD_TYPE: release
+ ARCH: ${{ matrix.arch }}
+ CMAKE_OSX_ARCHITECTURES: ${{ matrix.cmake_arch }}
+ CCACHE_DIR: ${{ github.workspace }}/.ccache
+ CCACHE_COMPILERCHECK: content
+ CCACHE_NOHASHDIR: 1
+ run: |
+ # Env.cmake looks for ccache in deps/3rd/.../devtools/bin; put it there so no Env.cmake change is needed
+ mkdir -p deps/3rd/usr/local/oceanbase/devtools/bin
+ ln -sf "$(which ccache)" deps/3rd/usr/local/oceanbase/devtools/bin/ccache
+ # Use runner's Python (macOS has 3.x, not 3.8 by default) so embed CMake finds it
+ PYVER=$(python3 -c "import sys; print(f'{sys.version_info.major}.{sys.version_info.minor}')")
+ bash build.sh release --init -DOB_USE_CCACHE=ON -DBUILD_EMBED_MODE=ON -DPYTHON_VERSION=$PYVER -DCMAKE_OSX_ARCHITECTURES=${{ matrix.cmake_arch }} -DCMAKE_OSX_DEPLOYMENT_TARGET=11.0 --make libseekdb
+ ccache -s
+
+ - name: Setup Node.js (macOS)
+ uses: actions/setup-node@v4
+ with:
+ node-version: "18"
+
+ - name: Setup Rust (macOS)
+ uses: dtolnay/rust-toolchain@stable
+ with:
+ toolchain: stable
+
+ - name: Setup Go (macOS)
+ uses: actions/setup-go@v5
+ with:
+ go-version: "1.21"
+
+ - name: Setup Java (macOS)
+ uses: actions/setup-java@v4
+ with:
+ distribution: "temurin"
+ java-version: "17"
+
+ - name: Test Node.js FFI binding (macOS)
+ id: binding_node_ffi
+ continue-on-error: true
+ run: |
+ cd unittest/include/nodejs
+ npm install
+ bash test.sh
+
+ - name: Test Node.js N-API binding (macOS)
+ id: binding_node_napi
+ continue-on-error: true
+ run: |
+ PATH=$(echo "$PATH" | tr ':' '\n' | grep -v 'deps/3rd' | tr '\n' ':' | sed 's/:$//')
+ cd unittest/include/nodejs_napi
+ npm install
+ bash test.sh
+
+ - name: Test Python binding (macOS)
+ id: binding_python
+ continue-on-error: true
+ run: |
+ cd unittest/include/python
+ bash test.sh
+
+ - name: Test Rust binding (macOS)
+ id: binding_rust
+ continue-on-error: true
+ run: |
+ cd unittest/include/rust
+ bash test.sh
+
+ - name: Test Go binding (macOS)
+ id: binding_go
+ continue-on-error: true
+ run: |
+ PATH=$(echo "$PATH" | tr ':' '\n' | grep -v 'deps/3rd' | tr '\n' ':' | sed 's/:$//')
+ cd unittest/include/go
+ bash test.sh
+
+ - name: Test Java binding (macOS)
+ id: binding_java
+ continue-on-error: true
+ run: |
+ PATH=$(echo "$PATH" | tr ':' '\n' | grep -v 'deps/3rd' | tr '\n' ':' | sed 's/:$//')
+ cd unittest/include/java
+ bash test.sh
+
+ # macOS code signing. Entitlements allow loading embedded dylib.
+ - name: Create entitlements (macOS)
+ run: |
+ echo -e '\n\n\n\n com.apple.security.cs.disable-library-validation\n \n\n' > package/libseekdb/entitlements.plist
+
+ # Only import certificate on main repo; script skips when cert empty (ad-hoc signing used).
+ - name: Import certificate (macOS)
+ if: github.repository == 'oceanbase/seekdb'
+ env:
+ BUILD_CERTIFICATE_BASE64: ${{ secrets.OSX_CODESIGN_BUILD_CERTIFICATE_BASE64 }}
+ P12_PASSWORD: ${{ secrets.OSX_CODESIGN_P12_PASSWORD }}
+ KEYCHAIN_PASSWORD: ${{ secrets.OSX_CODESIGN_KEYCHAIN_PASSWORD }}
+ run: . package/libseekdb/osx_import_codesign_certificate.sh
+
+ - name: Pack libseekdb (macOS)
+ env:
+ ARCH: ${{ matrix.arch }}
+ CODESIGN_IDENTITY: ${{ secrets.OSX_CODESIGN_IDENTITY }}
+ CODESIGN_ENTITLEMENTS: ${{ github.workspace }}/package/libseekdb/entitlements.plist
+ run: cd package/libseekdb && bash libseekdb-build.sh
+
+ - name: Checkout seekdb-js (macOS JS smoke)
+ uses: actions/checkout@v4
+ with:
+ repository: oceanbase/seekdb-js
+ path: seekdb-js
+ fetch-depth: 1
+
+ - name: Setup Node/pnpm (macOS JS smoke)
+ uses: pnpm/action-setup@v4
+ with:
+ version: 9
+
+ - name: Install seekdb-js deps (macOS JS smoke)
+ working-directory: seekdb-js
+ run: pnpm install --filter seekdb --filter @seekdb/js-bindings-build
+
+ - name: Smoke test packed artifact (macOS)
+ env:
+ SEEKDB_JS_ROOT: ${{ github.workspace }}/seekdb-js
+ run: |
+ chmod +x package/libseekdb/test-packed-artifact-smoke.sh \
+ package/libseekdb/test-packed-artifact-smoke-js.sh
+ package/libseekdb/test-packed-artifact-smoke.sh package/libseekdb/libseekdb-darwin-arm64.zip
+
+ - name: Upload artifact
+ uses: actions/upload-artifact@v4
+ with:
+ name: ${{ matrix.artifact_name }}
+ path: package/libseekdb/libseekdb-*.zip
+
+ # Save caches even on failure so next run can resume (deps/ccache)
+ - name: Save Cache deps (macOS)
+ if: always()
+ uses: actions/cache/save@v4
+ with:
+ path: deps/3rd
+ key: ${{ runner.os }}-libseekdb-deps-${{ matrix.platform }}-${{ hashFiles('deps/init/oceanbase.macos.arm64.deps') }}
+ - name: Save Cache ccache (macOS)
+ if: always()
+ uses: actions/cache/save@v4
+ with:
+ path: .ccache
+ key: ${{ runner.os }}-ccache-libseekdb-${{ matrix.platform }}-${{ env.COMMIT_SHA }}
+
+ - name: Binding tests outcome (macOS)
+ if: always()
+ run: |
+ failed=0
+ for o in \
+ "${{ steps.binding_node_ffi.outcome }}" \
+ "${{ steps.binding_node_napi.outcome }}" \
+ "${{ steps.binding_python.outcome }}" \
+ "${{ steps.binding_rust.outcome }}" \
+ "${{ steps.binding_go.outcome }}" \
+ "${{ steps.binding_java.outcome }}"; do
+ [ "$o" = "failure" ] && failed=1
+ done
+ if [ "$failed" -ne 0 ]; then
+ echo "::error::One or more libseekdb binding tests failed on macOS"
+ exit 1
+ fi
+ echo "All binding test steps succeeded (or were skipped)."
+
+ # ---------- Android NDK cross-compile (macOS arm64 host; target arm64-v8a) ----------
+ # ubuntu-* runners are x86_64 by default. macOS-15 uses Apple silicon + NDK darwin-arm64 prebuilts (see docs).
+ # Alternative: runs-on: ubuntu-24.04-arm for Linux ARM64.
+ #
+ # Why no FFI binding tests here: libseekdb.so is Android arm64-v8a / ELF for Bionic — the dynamic linker,
+ # libc, and JNI/NDK ABI differ from macOS dyld. CI cannot dlopen/load that .so on the host like Linux/macOS/Windows jobs.
+ # Running the same unittest/include/*/test.sh would require an Android emulator, rooted device, or adb push + adb shell test.
+ build-android:
+ name: Build libseekdb (android-arm64-v8a)
+ runs-on: macos-15
+ timeout-minutes: 180
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+ with:
+ ref: ${{ github.event_name == 'workflow_dispatch' && inputs.ref != '' && inputs.ref || (github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha) }}
+
+ - name: Install macOS packages
+ run: |
+ brew install cmake ccache wget || true
+
+ - name: Install Android NDK
+ uses: nttld/setup-ndk@v1
+ with:
+ # Use rYYx form (e.g. r27d); full build numbers (27.3.13750724) 404 on the action download URL
+ ndk-version: r27d
+
+ - name: Cache deps (Android)
+ uses: actions/cache@v4
+ with:
+ path: deps/3rd
+ key: ${{ runner.os }}-libseekdb-deps-android-arm64-v8a-${{ hashFiles('deps/init/oceanbase.android.arm64.deps') }}
+ restore-keys: |
+ ${{ runner.os }}-libseekdb-deps-android-arm64-v8a-
+
+ - name: Cache ccache (Android)
+ uses: actions/cache@v4
+ with:
+ path: .ccache
+ key: ${{ runner.os }}-ccache-libseekdb-android-arm64-v8a
+ restore-keys: |
+ ${{ runner.os }}-ccache-libseekdb-android-arm64-v8a-
+
+ - name: Build libseekdb (Android)
+ env:
+ BUILD_TYPE: release
+ CCACHE_DIR: ${{ github.workspace }}/.ccache
+ CCACHE_COMPILERCHECK: content
+ CCACHE_NOHASHDIR: 1
+ run: |
+ set -e
+ # Do not symlink ccache into deps/3rd before --init: dep_create.sh rm -rf deps/3rd.
+ # CMake finds ccache on PATH when devtools has none (Android deps omit obdevtools-ccache).
+ # ANDROID_NDK_HOME is set by the NDK install step; build.sh fixes ANDROID_ABI=arm64-v8a.
+ bash build.sh release --android -DOB_USE_CCACHE=ON -DBUILD_EMBED_MODE=ON --init --make libseekdb
+ ccache -s
+
+ # Same toolchain install order as other jobs (no host FFI below).
+ - name: Setup Node.js (Android)
+ uses: actions/setup-node@v4
+ with:
+ node-version: "18"
+
+ - name: Setup Rust (Android)
+ uses: dtolnay/rust-toolchain@stable
+ with:
+ toolchain: stable
+
+ - name: Setup Go (Android)
+ uses: actions/setup-go@v5
+ with:
+ go-version: "1.21"
+
+ - name: Setup Java (Android)
+ uses: actions/setup-java@v4
+ with:
+ distribution: "temurin"
+ java-version: "17"
+
+ - name: Binding tests (Android)
+ id: android_binding_notice
+ run: |
+ echo "::notice::Skipping native FFI binding tests on this runner: libseekdb.so targets Android arm64-v8a / Bionic and cannot be dlopen()'d on the macOS host."
+ echo "Zip verification runs after pack; device or emulator CI would be required for full FFI tests."
+
+ - name: Pack libseekdb (Android)
+ run: cd package/libseekdb && bash libseekdb-build.sh --android
+
+ - name: Verify packaged zip (Android)
+ id: android_verify_zip
+ continue-on-error: true
+ run: unzip -t package/libseekdb/libseekdb-android-arm64-v8a.zip
+
+ - name: Upload artifact
+ uses: actions/upload-artifact@v4
+ with:
+ name: libseekdb-android-arm64-v8a
+ path: package/libseekdb/libseekdb-android-arm64-v8a.zip
+
+ - name: Save Cache deps (Android)
+ if: always()
+ uses: actions/cache/save@v4
+ with:
+ path: deps/3rd
+ key: ${{ runner.os }}-libseekdb-deps-android-arm64-v8a-${{ hashFiles('deps/init/oceanbase.android.arm64.deps') }}
+
+ - name: Save Cache ccache (Android)
+ if: always()
+ uses: actions/cache/save@v4
+ with:
+ path: .ccache
+ key: ${{ runner.os }}-ccache-libseekdb-android-arm64-v8a
+
+ - name: Pack / zip verification outcome (Android)
+ if: always()
+ run: |
+ if [ "${{ steps.android_verify_zip.outcome }}" = "failure" ]; then
+ echo "::error::Packaged zip verification failed (unzip -t)"
+ exit 1
+ fi
+ echo "Android pack and zip verification OK (or verify step skipped)."
+
+ # ---------- Build on Windows x64 (native, embed DLL) ----------
+ build-windows:
+ name: Build libseekdb (windows-x64)
+ runs-on: windows-2022
+ timeout-minutes: 360
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+ with:
+ ref: ${{ github.event_name == 'workflow_dispatch' && inputs.ref != '' && inputs.ref || (github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha) }}
+
+ - name: Setup Python
+ uses: actions/setup-python@v5
+ with:
+ python-version: "3.12"
+
+ - name: Cache deps (Windows)
+ uses: actions/cache@v4
+ with:
+ path: deps/3rd
+ key: ${{ runner.os }}-libseekdb-deps-windows-x64-${{ hashFiles('deps/init/oceanbase.windows.x86_64.deps') }}
+ restore-keys: |
+ ${{ runner.os }}-libseekdb-deps-windows-x64-
+
+ - name: Cache ccache (Windows)
+ uses: actions/cache@v4
+ with:
+ path: .ccache
+ key: ${{ runner.os }}-ccache-libseekdb-windows-x64
+ restore-keys: |
+ ${{ runner.os }}-ccache-libseekdb-windows-x64-
+
+ - name: Install ccache (Windows)
+ shell: pwsh
+ run: |
+ Set-StrictMode -Version Latest
+ $ErrorActionPreference = "Stop"
+ function Refresh-Path {
+ $env:Path = [System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path","User")
+ }
+ Refresh-Path
+ if (Get-Command ccache -ErrorAction SilentlyContinue) {
+ Write-Host "ccache already on PATH"
+ Get-Command ccache | Out-Host
+ exit 0
+ }
+ choco install ccache -y --no-progress 2>&1 | Out-Host
+ Refresh-Path
+ if ($LASTEXITCODE -ne 0 -or -not (Get-Command ccache -ErrorAction SilentlyContinue)) {
+ Write-Host "::notice::choco install ccache failed or ccache not on PATH; installing from ccache GitHub releases."
+ $ver = "4.13.2"
+ $zipName = "ccache-$ver-windows-x86_64.zip"
+ $url = "https://github.com/ccache/ccache/releases/download/v$ver/$zipName"
+ $tools = Join-Path $env:GITHUB_WORKSPACE ".tools"
+ $dest = Join-Path $tools "ccache-$ver-win64"
+ New-Item -ItemType Directory -Force -Path $dest | Out-Null
+ $zipPath = Join-Path $dest $zipName
+ Invoke-WebRequest -Uri $url -OutFile $zipPath -UseBasicParsing
+ Expand-Archive -Path $zipPath -DestinationPath $dest -Force
+ $exe = Get-ChildItem -Path $dest -Filter ccache.exe -Recurse | Select-Object -First 1
+ if (-not $exe) { throw "ccache.exe not found after extracting $zipName under $dest" }
+ $binDir = $exe.Directory.FullName
+ Add-Content -Path $env:GITHUB_PATH -Value $binDir -Encoding utf8
+ $env:PATH = "$binDir;$env:PATH"
+ }
+ Get-Command ccache | Out-Host
+
+ - name: Build libseekdb (Windows)
+ shell: pwsh
+ env:
+ BUILD_TYPE: release
+ CCACHE_DIR: ${{ github.workspace }}/.ccache
+ CCACHE_COMPILERCHECK: content
+ CCACHE_NOHASHDIR: 1
+ run: |
+ Set-StrictMode -Version Latest
+ $ErrorActionPreference = "Stop"
+ # Pick up Chocolatey / GITHUB_PATH / fallback-installed ccache
+ $env:Path = [System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path","User")
+ $py = python -c "import sys; print(f'{sys.version_info.major}.{sys.version_info.minor}')"
+ if (-not (Test-Path "deps/3rd/DONE")) {
+ .\build.ps1 init
+ }
+ # Prepend deps LLVM to PATH; pass lld-link so CMake does not pick GNU ld (MinGW) for clang-cl.
+ $ws = if ($env:GITHUB_WORKSPACE) { $env:GITHUB_WORKSPACE } else { (Get-Location).Path }
+ # CMake -G Ninja requires ninja on PATH at configure time (otherwise CMake may fall back or leave a stale non-Ninja cache).
+ foreach ($rel in @("deps/3rd/tools/ninja", "deps/3rd/tools/cmake/bin")) {
+ $tp = Join-Path $ws $rel
+ if (Test-Path -LiteralPath $tp) { $env:PATH = "$tp;$env:PATH" }
+ }
+ $llvmRoot = if ($env:OB_LLVM_DIR) { $env:OB_LLVM_DIR } else { Join-Path $ws "deps/3rd/tools/llvm18" }
+ $llvmBin = Join-Path $llvmRoot "bin"
+ $lldLink = Join-Path $llvmBin "lld-link.exe"
+ if (-not (Test-Path $lldLink)) { throw "lld-link.exe not found: $lldLink" }
+ $lldFwd = $lldLink.Replace("\", "/")
+ $env:PATH = "$llvmBin;$env:PATH"
+ $ccacheOpt = "-DOB_USE_CCACHE=OFF"
+ if (Get-Command ccache -ErrorAction SilentlyContinue) {
+ $ccacheOpt = "-DOB_USE_CCACHE=ON"
+ } else {
+ Write-Host "::warning::ccache not found; building without compiler cache."
+ }
+ # Map RelWithDebInfo/Debug/MinSizeRel -> Release for IMPORTED targets (e.g. Python3::Module .lib/.dll on Windows).
+ # Ensures cache has these on first cmake run; complements cmake/Env.cmake for CI runners where Python stubs omit RelWithDebInfo.
+ .\build.ps1 release --ninja --target libseekdb "-DBUILD_EMBED_MODE=ON" "-DPYTHON_VERSION=$py" "-DCMAKE_LINKER=$lldFwd" "-DCMAKE_MAP_IMPORTED_CONFIG_RELWITHDEBINFO=Release" "-DCMAKE_MAP_IMPORTED_CONFIG_DEBUG=Release" "-DCMAKE_MAP_IMPORTED_CONFIG_MINSIZEREL=Release" $ccacheOpt
+ if (Get-Command ccache -ErrorAction SilentlyContinue) { ccache -s }
+
+ - name: Debug facts — libseekdb Windows (deterministic)
+ shell: pwsh
+ env:
+ BUILD_TYPE: release
+ run: |
+ $ErrorActionPreference = "Continue"
+ $ws = if ($env:GITHUB_WORKSPACE) { $env:GITHUB_WORKSPACE } else { (Get-Location).Path }
+ foreach ($rel in @("deps/3rd/tools/ninja", "deps/3rd/tools/cmake/bin")) {
+ $tp = Join-Path $ws $rel
+ if (Test-Path -LiteralPath $tp) { $env:PATH = "$tp;$env:PATH" }
+ }
+ . ./unittest/include/seekdb-windows-dll-resolve.ps1
+ . ./unittest/include/debug-libseekdb-windows.ps1
+ Write-LibseekdbWindowsBuildFacts -RepoRoot "$PWD"
+
+ - name: Verify libseekdb DLL (Windows)
+ shell: pwsh
+ env:
+ BUILD_TYPE: release
+ run: |
+ Set-StrictMode -Version Latest
+ $ErrorActionPreference = "Stop"
+ . ./unittest/include/seekdb-windows-dll-resolve.ps1
+ $bdn = Get-SeekDbWindowsBuildDirNameFromEnv
+ $r = Find-SeekDbWindowsDll -RepoRoot "$PWD" -BuildDirName $bdn
+ if (-not $r) {
+ Write-SeekDbWindowsDllDiagnostics -RepoRoot "$PWD" -BuildDirName $bdn
+ throw "libseekdb build did not produce seekdb.dll under build_$bdn (see diagnostics above)."
+ }
+ Write-Host "libseekdb DLL: $($r.DllPath)"
+ "SEEKDB_LIB_PATH=$($r.DllPath)" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
+
+ - name: Setup Node.js (Windows)
+ uses: actions/setup-node@v4
+ with:
+ node-version: "18"
+
+ - name: Setup Rust (Windows)
+ uses: dtolnay/rust-toolchain@stable
+ with:
+ toolchain: stable
+
+ - name: Setup Go (Windows)
+ uses: actions/setup-go@v5
+ with:
+ go-version: "1.21"
+
+ - name: Setup Java (Windows)
+ uses: actions/setup-java@v4
+ with:
+ distribution: "temurin"
+ java-version: "17"
+
+ - name: Install MinGW and Maven (Go CGO + Java)
+ shell: pwsh
+ run: choco install mingw maven -y --no-progress
+
+ # One job step per language: if something hangs, the in-progress step name in the Actions UI shows
+ # whether the stall is in Python, npm, node-gyp, cargo, go, or Java (not “whole binding” vs global timeout).
+ - name: Binding tests — Python (Windows)
+ id: bind_win_python
+ continue-on-error: true
+ shell: pwsh
+ env:
+ SEEKDB_BINDING_SECTION: Python
+ run: |
+ Set-StrictMode -Version Latest
+ $ErrorActionPreference = "Stop"
+ $env:Path = [System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path","User")
+ Get-Command gcc | Out-Host
+ Get-Command mvn | Out-Host
+ .\unittest\include\run-libseekdb-binding-tests.ps1 -RepoRoot "$PWD" -ContinueOnError
+
+ - name: Binding tests — Node FFI / koffi (Windows)
+ id: bind_win_node_ffi
+ continue-on-error: true
+ shell: pwsh
+ env:
+ SEEKDB_BINDING_SECTION: NodeFfi
+ run: |
+ Set-StrictMode -Version Latest
+ $ErrorActionPreference = "Stop"
+ $env:Path = [System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path","User")
+ .\unittest\include\run-libseekdb-binding-tests.ps1 -RepoRoot "$PWD" -ContinueOnError
+
+ - name: Binding tests — Node N-API (Windows)
+ id: bind_win_node_napi
+ continue-on-error: true
+ shell: pwsh
+ env:
+ SEEKDB_BINDING_SECTION: NodeNapi
+ # VECTOR + DBMS_HYBRID_SEARCH cases can stall native code on Windows runners; core N-API still covered.
+ SEEKDB_NODE_NAPI_SKIP_HEAVY: "1"
+ run: |
+ Set-StrictMode -Version Latest
+ $ErrorActionPreference = "Stop"
+ $env:Path = [System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path","User")
+ .\unittest\include\run-libseekdb-binding-tests.ps1 -RepoRoot "$PWD" -ContinueOnError
+
+ - name: Binding tests — Rust (Windows)
+ id: bind_win_rust
+ continue-on-error: true
+ shell: pwsh
+ env:
+ SEEKDB_BINDING_SECTION: Rust
+ run: |
+ Set-StrictMode -Version Latest
+ $ErrorActionPreference = "Stop"
+ $env:Path = [System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path","User")
+ .\unittest\include\run-libseekdb-binding-tests.ps1 -RepoRoot "$PWD" -ContinueOnError
+
+ - name: Binding tests — Go (Windows)
+ id: bind_win_go
+ continue-on-error: true
+ shell: pwsh
+ env:
+ SEEKDB_BINDING_SECTION: Go
+ run: |
+ Set-StrictMode -Version Latest
+ $ErrorActionPreference = "Stop"
+ $env:Path = [System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path","User")
+ .\unittest\include\run-libseekdb-binding-tests.ps1 -RepoRoot "$PWD" -ContinueOnError
+
+ - name: Binding tests — Java (Windows)
+ id: bind_win_java
+ continue-on-error: true
+ shell: pwsh
+ env:
+ SEEKDB_BINDING_SECTION: Java
+ run: |
+ Set-StrictMode -Version Latest
+ $ErrorActionPreference = "Stop"
+ $env:Path = [System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path","User")
+ .\unittest\include\run-libseekdb-binding-tests.ps1 -RepoRoot "$PWD" -ContinueOnError
+
+ - name: Pack libseekdb zip (Windows)
+ shell: pwsh
+ env:
+ BUILD_TYPE: release
+ run: .\package\libseekdb\libseekdb-build.ps1
+
+ - name: Verify libseekdb Windows zip layout
+ shell: pwsh
+ run: |
+ Set-StrictMode -Version Latest
+ $ErrorActionPreference = "Stop"
+ $zip = "package/libseekdb/libseekdb-windows-x64.zip"
+ if (-not (Test-Path $zip)) { throw "Missing $zip" }
+ $tmp = Join-Path $env:TEMP ("libseekdb-verify-" + [guid]::NewGuid().ToString())
+ Expand-Archive -Path $zip -DestinationPath $tmp -Force
+ foreach ($f in @("seekdb.h", "seekdb.dll")) {
+ if (-not (Test-Path (Join-Path $tmp $f))) { throw "Zip missing $f" }
+ }
+ $libs = Join-Path $tmp "libs"
+ if (-not (Test-Path $libs)) { throw "Zip missing libs/ (runtime DLLs required for standalone load)" }
+ $n = @(Get-ChildItem $libs -Filter *.dll -File).Count
+ if ($n -lt 1) { throw "libs/ has no .dll files ($n)" }
+ Write-Host "libseekdb-windows-x64.zip OK: seekdb.dll + libs/ ($n DLLs)"
+
+ - name: Upload artifact
+ uses: actions/upload-artifact@v4
+ with:
+ name: libseekdb-windows-x64
+ path: package/libseekdb/libseekdb-windows-x64.zip
+
+ - name: Save Cache deps (Windows)
+ if: always()
+ uses: actions/cache/save@v4
+ with:
+ path: deps/3rd
+ key: ${{ runner.os }}-libseekdb-deps-windows-x64-${{ hashFiles('deps/init/oceanbase.windows.x86_64.deps') }}
+
+ - name: Save Cache ccache (Windows)
+ if: always()
+ uses: actions/cache/save@v4
+ with:
+ path: .ccache
+ key: ${{ runner.os }}-ccache-libseekdb-windows-x64
+
+ - name: Binding tests outcome (Windows)
+ if: always()
+ shell: pwsh
+ run: |
+ $failed = $false
+ if ("${{ steps.bind_win_python.outcome }}" -eq "failure") { Write-Host "::error::Binding section failed: Python"; $failed = $true }
+ if ("${{ steps.bind_win_node_ffi.outcome }}" -eq "failure") { Write-Host "::error::Binding section failed: Node FFI (koffi)"; $failed = $true }
+ if ("${{ steps.bind_win_node_napi.outcome }}" -eq "failure") { Write-Host "::error::Binding section failed: Node N-API"; $failed = $true }
+ if ("${{ steps.bind_win_rust.outcome }}" -eq "failure") { Write-Host "::error::Binding section failed: Rust"; $failed = $true }
+ if ("${{ steps.bind_win_go.outcome }}" -eq "failure") { Write-Host "::error::Binding section failed: Go"; $failed = $true }
+ if ("${{ steps.bind_win_java.outcome }}" -eq "failure") { Write-Host "::error::Binding section failed: Java"; $failed = $true }
+ if ($failed) { exit 1 }
+ Write-Host "All Windows binding test sections succeeded."
+
+ # ---------- Collect libseekdb artifacts and upload to S3 (runs only when all needed build jobs succeed, including binding tests) ----------
+ release-artifacts:
+ name: Collect artifacts and upload to S3
+ runs-on: ubuntu-22.04
+ needs:
+ - build
+ - build-macos
+ - build-android
+ - build-windows
+ steps:
+ - name: Download all artifacts
+ uses: actions/download-artifact@v4
+ with:
+ path: release-artifacts
+ merge-multiple: true
+
+ - name: List all artifacts
+ run: |
+ echo "=== All artifacts ==="
+ ls -la release-artifacts/
+
+ - name: Upload combined artifact (for workflow download)
+ uses: actions/upload-artifact@v4
+ with:
+ name: libseekdb-all-platforms
+ path: release-artifacts/
+
+ - name: Configure AWS credentials
+ if: env.UPLOAD_S3 == 'true'
+ uses: aws-actions/configure-aws-credentials@v4
+ with:
+ aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
+ aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
+ aws-region: ${{ env.AWS_REGION }}
+
+ - name: Upload to S3
+ if: env.UPLOAD_S3 == 'true'
+ run: |
+ set -e
+ if [ -n "${{ env.DESTINATION_TARGET_PATH }}" ]; then
+ S3_TARGET="${{ env.DESTINATION_TARGET_PATH }}"
+ else
+ S3_TARGET="s3://${{ env.S3_BUCKET }}/${{ env.S3_PREFIX }}/"
+ fi
+ [ "${S3_TARGET: -1}" != "/" ] && S3_TARGET="${S3_TARGET}/"
+ echo "Uploading to $S3_TARGET"
+ aws s3 cp release-artifacts/ "$S3_TARGET" --recursive --exclude "*" --include "*.zip" --no-progress
+ echo "Uploaded:"
+ aws s3 ls "$S3_TARGET" --recursive
+ echo "Done."
+ continue-on-error: true
diff --git a/.gitignore b/.gitignore
index 50b0751c9..655f16600 100644
--- a/.gitignore
+++ b/.gitignore
@@ -187,6 +187,14 @@ src/pl/parser/pl_parser_mysql_mode.output
src/pl/parser/pl_parser_oracle_mode.output
src/share/inner_table/sys_package/syspack_source.cpp
src/share/inner_table/sys_package/*.plw
+# generate_inner_table_schema.py (run at cmake configure)
+src/share/inner_table/ob_inner_table_schema.h
+src/share/inner_table/ob_inner_table_schema.*.cpp
+src/share/inner_table/ob_inner_table_schema_constants.h
+src/share/inner_table/ob_inner_table_schema_misc.ipp
+src/share/inner_table/table_id_to_name
+src/observer/virtual_table/ob_all_virtual_sqlite_tables.cpp
+src/observer/virtual_table/ob_all_virtual_sqlite_tables.h
src/share/parameter/standalone_default_parameter.json
src/share/parameter/shared_storage_default_parameter.json
src/share/system_variable/standalone_default_system_variable.json
@@ -381,6 +389,9 @@ tools/ob-configserver/bin/*
tools/ob-configserver/tests/*.log
tools/ob-configserver/tests/*.out
+############# package/libseekdb #############
+package/libseekdb/libseekdb-*.zip
+
## .NET Configurator build output (rebuilt by dotnet publish)
tools/windows/seekdbConfigurator/bin/
tools/windows/seekdbConfigurator/obj/
@@ -404,3 +415,4 @@ test/var
.worktrees/
.claude/
CLAUDE.md
+.codegraph/
diff --git a/CMakeLists.txt b/CMakeLists.txt
index e252ab5b0..11c923cd5 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -9,6 +9,13 @@ project("OceanBase"
HOMEPAGE_URL "https://www.oceanbase.ai"
LANGUAGES CXX C ASM)
+# Android NDK toolchain / defaults may pin C++17 after project(); enforce C++20 for language features (e.g. consteval).
+if(ANDROID)
+ set(CMAKE_CXX_STANDARD 20)
+ set(CMAKE_CXX_STANDARD_REQUIRED ON)
+ set(CMAKE_CXX_EXTENSIONS ON)
+endif()
+
if(WIN32)
find_program(LLVM_LIB_PROGRAM llvm-lib)
if(LLVM_LIB_PROGRAM)
@@ -79,6 +86,7 @@ if(EXISTS "${STDC_SHARED_LIB_SYMLINK}")
endif()
add_subdirectory(deps/oblib)
+include(${CMAKE_SOURCE_DIR}/cmake/EnsureWindowsDiaGuids.cmake)
add_subdirectory(src)
include(CMakeDependentOption)
diff --git a/build.ps1 b/build.ps1
index ec43864d9..7995b6ea7 100644
--- a/build.ps1
+++ b/build.ps1
@@ -18,7 +18,9 @@ $Action = "debug"
$Ninja = $false
$Init = $false
$Jobs = 0
-$h = $false
+$h = $false
+$NinjaTarget = "observer"
+$ExtraCmake = @()
$i = 0
while ($i -lt $args.Count) {
@@ -27,12 +29,17 @@ while ($i -lt $args.Count) {
{ $_ -in "-h", "--help", "-help" } { $h = $true }
{ $_ -in "--ninja", "-ninja" } { $Ninja = $true }
{ $_ -in "--init", "-init" } { $Init = $true }
+ { $_ -in "--target" } {
+ $i++
+ if ($i -lt $args.Count) { $NinjaTarget = "$($args[$i])" }
+ }
{ $_ -in "-j", "--jobs" } {
$i++
if ($i -lt $args.Count) { $Jobs = [int]$args[$i] }
}
default {
if (-not $a.StartsWith("-")) { $Action = $a }
+ elseif ($a.StartsWith("-D")) { $ExtraCmake += $a }
else { Write-Host "[build.ps1][WARN] Unknown flag: $a" -ForegroundColor Yellow }
}
}
@@ -181,6 +188,7 @@ Usage:
.\build.ps1 [BuildType] --ninja Configure + compile (ninja)
.\build.ps1 [BuildType] --ninja -j 16 Compile with 16 jobs
.\build.ps1 [BuildType] --ninja --init Init deps, then build
+ .\build.ps1 release --ninja --target libseekdb Build embed DLL (example)
.\build.ps1 package Build release + MSI/ZIP installer
BuildType:
@@ -191,6 +199,8 @@ BuildType:
Flags:
--ninja Configure + compile with Ninja
--init Run dependency init before building (like build.sh --init)
+ --target NAME Ninja target (default: observer); e.g. libseekdb
+ -DVAR=VALUE Extra CMake cache entries (repeatable); e.g. -DBUILD_EMBED_MODE=ON
Environment variables (override dependency paths):
OB_VCPKG_DIR vcpkg install root (default: deps/3rd or C:/VcpkgInstalled)
@@ -286,7 +296,13 @@ function Do-Build {
[string[]]$ExtraCMakeArgs = @()
)
- $buildDir = "$TOPDIR\build_$($BuildType.ToLower())"
+ # Align directory names with build.sh: release -> build_release, debug -> build_debug
+ $folderName = switch ($BuildType) {
+ "RelWithDebInfo" { "release" }
+ "Debug" { "debug" }
+ default { $BuildType.ToLower() }
+ }
+ $buildDir = "$TOPDIR\build_$folderName"
if (-not (Test-Path $buildDir)) {
New-Item -ItemType Directory -Path $buildDir | Out-Null
}
@@ -300,9 +316,9 @@ function Do-Build {
"-DOB_VCPKG_DIR=$DefaultVcpkgDir",
"-DOB_OPENSSL_DIR=$DefaultOpenSSLDir",
"-DOB_LLVM_DIR=$DefaultLLVMDir"
- ) + $ExtraCMakeArgs
+ ) + $ExtraCMakeArgs + $ExtraCmake
- Write-Log "CMake configure: build_$($BuildType.ToLower())"
+ Write-Log "CMake configure: build_$folderName"
Write-Log " Build type : $BuildType"
Write-Log " VcpkgDir : $DefaultVcpkgDir"
Write-Log " OpenSSLDir : $DefaultOpenSSLDir"
@@ -311,13 +327,54 @@ function Do-Build {
Push-Location $buildDir
try {
- & cmake @cmakeArgs | Out-Host
- if ($LASTEXITCODE -ne 0) {
- Write-Err "CMake configure failed (exit code $LASTEXITCODE)"
- exit $LASTEXITCODE
+ function Invoke-CMakeConfigure {
+ & cmake @cmakeArgs | Out-Host
+ return $LASTEXITCODE
+ }
+
+ $exit = Invoke-CMakeConfigure
+ if ($exit -ne 0) {
+ Write-Err "CMake configure failed (exit code $exit)"
+ exit $exit
}
Write-Log "CMake configure succeeded."
+ # Facts from CI: CMakeCache can say CMAKE_GENERATOR=Ninja while no *.ninja exists (incomplete/stale tree).
+ # Recover once by wiping cache + CMakeFiles and re-running cmake.
+ function Test-HasNinjaBuildFiles {
+ param([string]$Dir)
+ if (Test-Path (Join-Path $Dir "build.ninja")) { return $true }
+ try {
+ $nf = [System.IO.Directory]::GetFiles($Dir, "*.ninja", [System.IO.SearchOption]::TopDirectoryOnly)
+ return ($nf.Length -gt 0)
+ } catch {
+ return $false
+ }
+ }
+
+ if (-not (Test-HasNinjaBuildFiles -Dir $buildDir)) {
+ Write-Log "[build.ps1] No Ninja build files after configure; clearing CMakeCache + CMakeFiles and re-configuring once."
+ Remove-Item (Join-Path $buildDir "CMakeCache.txt") -Force -ErrorAction SilentlyContinue
+ Remove-Item (Join-Path $buildDir "CMakeFiles") -Recurse -Force -ErrorAction SilentlyContinue
+ $exit2 = Invoke-CMakeConfigure
+ if ($exit2 -ne 0) {
+ Write-Err "CMake re-configure failed (exit code $exit2)"
+ exit $exit2
+ }
+ Write-Log "CMake re-configure finished."
+ }
+
+ # Fail fast if Ninja was requested but the build tree still has no Ninja backend files.
+ if (-not (Test-HasNinjaBuildFiles -Dir $buildDir)) {
+ Write-Err "CMake did not create build.ninja (or any *.ninja) under $buildDir after configure/retry (expected -G Ninja)."
+ $cache = Join-Path $buildDir "CMakeCache.txt"
+ if (Test-Path $cache) {
+ Select-String -Path $cache -Pattern "^CMAKE_GENERATOR:" | ForEach-Object { Write-Err $_.Line }
+ }
+ Write-Err "Fix: delete $buildDir completely and re-run, or ensure Ninja is on PATH when cmake runs (e.g. deps\3rd\tools\ninja)."
+ exit 1
+ }
+
# Copy compile_commands.json to project root for IDE support
$ccJson = "$buildDir\compile_commands.json"
if (Test-Path $ccJson) {
@@ -334,17 +391,41 @@ function Do-Build {
# -- ninja build -----------------------------------------------------
function Do-Ninja {
- param([string]$BuildDir)
+ param(
+ [string]$BuildDir,
+ [string]$Target = "observer"
+ )
- Write-Log "Building with Ninja (-j $Jobs) in $BuildDir ..."
+ Write-Log "Building with Ninja (-j $Jobs) target=$Target in $BuildDir ..."
Push-Location $BuildDir
try {
- & ninja -j $Jobs observer | Out-Host
+ & ninja -j $Jobs $Target | Out-Host
if ($LASTEXITCODE -ne 0) {
Write-Err "Build failed (exit code $LASTEXITCODE)"
exit $LASTEXITCODE
}
Write-Log "Build succeeded!"
+
+ # Deterministic post-condition for libseekdb: link must emit a DLL somewhere under the build dir.
+ if ($Target -eq "libseekdb") {
+ $foundDll = $false
+ foreach ($leaf in @("seekdb.dll", "libseekdb.dll")) {
+ try {
+ $arr = [System.IO.Directory]::GetFiles($BuildDir, $leaf, [System.IO.SearchOption]::AllDirectories)
+ if ($arr -and $arr.Length -gt 0) {
+ $foundDll = $true
+ Write-Log "Found ${leaf} at $($arr[0])"
+ break
+ }
+ } catch {
+ # ignore enumeration errors; treat as not found
+ }
+ }
+ if (-not $foundDll) {
+ Write-Err "ninja libseekdb succeeded but no seekdb.dll / libseekdb.dll under $BuildDir — link step did not produce a DLL (check ninja/link output above)."
+ exit 1
+ }
+ }
}
finally {
Pop-Location
@@ -404,7 +485,7 @@ function Do-Package {
}
$buildDir = Do-Build -BuildType "RelWithDebInfo" -ExtraCMakeArgs @("-DOB_BUILD_PACKAGE=ON")
- Do-Ninja -BuildDir $buildDir
+ Do-Ninja -BuildDir $buildDir -Target observer
# Sign binaries before they are packaged into the MSI
$exesToSign = @(
@@ -476,12 +557,12 @@ switch ($Action.ToLower()) {
{ $_ -in "release", "relwithdebinfo" } {
if ($Init) { Do-Init }
$buildDir = Do-Build -BuildType "RelWithDebInfo"
- if ($Ninja) { Do-Ninja -BuildDir $buildDir }
+ if ($Ninja) { Do-Ninja -BuildDir $buildDir -Target $NinjaTarget }
}
{ $_ -in "debug", "" } {
if ($Init) { Do-Init }
$buildDir = Do-Build -BuildType "Debug"
- if ($Ninja) { Do-Ninja -BuildDir $buildDir }
+ if ($Ninja) { Do-Ninja -BuildDir $buildDir -Target $NinjaTarget }
}
"-h" {
Show-Usage
diff --git a/build.sh b/build.sh
index 296f0b668..cd3969583 100755
--- a/build.sh
+++ b/build.sh
@@ -6,13 +6,11 @@ BUILD_SH=$TOPDIR/build.sh
DEP_DIR=${TOPDIR}/deps/3rd/usr/local/oceanbase/deps/devel
TOOLS_DIR=${TOPDIR}/deps/3rd/usr/local/oceanbase/devtools
-# Get CPU cores and CMAKE command, compatible with macOS and Linux
+# Get CPU cores; cmake path is resolved in do_build() (Linux may use host cmake before deps devtools exist)
if [[ "$(uname -s)" == "Darwin" ]]; then
- CMAKE_COMMAND="cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=1"
CPU_CORES=$(sysctl -n hw.ncpu)
KERNEL_RELEASE=""
else
- CMAKE_COMMAND="${TOOLS_DIR}/bin/cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=1"
CPU_CORES=$(grep -c ^processor /proc/cpuinfo)
KERNEL_RELEASE=$(grep -Po 'release [0-9]{1}' /etc/issue 2>/dev/null)
fi
@@ -169,22 +167,25 @@ function do_init
# make build directory && cmake && make (if need)
function do_build
{
- # Check if cmake exists, compatible with macOS and Linux
+ # Resolve cmake: prefer OceanBase devtools on Linux; else Homebrew/common paths; else PATH (e.g. apt cmake on CI)
CMAKE_PATH=""
if [[ "$(uname -s)" == "Darwin" ]]; then
- # macOS: cmake may be at /opt/homebrew/bin/cmake or /usr/local/bin/cmake
if [ -f /opt/homebrew/bin/cmake ]; then
CMAKE_PATH="/opt/homebrew/bin/cmake"
elif [ -f /usr/local/bin/cmake ]; then
CMAKE_PATH="/usr/local/bin/cmake"
fi
else
- # Linux
- CMAKE_PATH="${TOOLS_DIR}/bin/cmake"
+ if [[ -x "${TOOLS_DIR}/bin/cmake" ]]; then
+ CMAKE_PATH="${TOOLS_DIR}/bin/cmake"
+ fi
+ fi
+ if [[ -z "$CMAKE_PATH" ]] && command -v cmake >/dev/null 2>&1; then
+ CMAKE_PATH="$(command -v cmake)"
fi
if [ -z "$CMAKE_PATH" ]; then
- echo_log "[NOTICE] Your workspace has not initialized dependencies, please append '--init' args to initialize dependencies"
+ echo_log "[NOTICE] cmake not found. On Linux install cmake (e.g. apt install cmake) or run --init so ${TOOLS_DIR}/bin/cmake exists"
exit 1
fi
@@ -199,11 +200,11 @@ function do_build
echo_err "Set ANDROID_NDK_HOME or install the NDK"
exit 1
fi
- ANDROID_CMAKE_ARGS="-DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK_HOME/build/cmake/android.toolchain.cmake -DANDROID_ABI=arm64-v8a -DANDROID_PLATFORM=android-28"
+ ANDROID_CMAKE_ARGS="-DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK_HOME/build/cmake/android.toolchain.cmake -DANDROID_ABI=arm64-v8a -DANDROID_PLATFORM=android-28 -DCMAKE_CXX_STANDARD=20 -DCMAKE_CXX_EXTENSIONS=ON"
echo_log "Android NDK: $ANDROID_NDK_HOME"
fi
- ${CMAKE_COMMAND} ${TOPDIR} ${ANDROID_CMAKE_ARGS} "$@"
+ "${CMAKE_PATH}" -DCMAKE_EXPORT_COMPILE_COMMANDS=1 ${TOPDIR} ${ANDROID_CMAKE_ARGS} "$@"
if [ $? -ne 0 ]; then
echo_err "Failed to generate Makefile"
exit 1
diff --git a/cmake/EnsureWindowsDiaGuids.cmake b/cmake/EnsureWindowsDiaGuids.cmake
new file mode 100644
index 000000000..91397e936
--- /dev/null
+++ b/cmake/EnsureWindowsDiaGuids.cmake
@@ -0,0 +1,66 @@
+# LLVM imports may reference BuildTools\DIA SDK\...\diaguids.lib; CI/home often only have Community/etc.
+# Copy one existing VS 2022 diaguids.lib there before linking (must run before add_subdirectory(src)).
+
+if(NOT WIN32)
+ return()
+endif()
+
+# LLVM/seekdb Windows CI is x64 -> amd64 DIA libs; ARM64 host uses arm64.
+if(CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "^(ARM64|aarch64)$")
+ set(_a "arm64")
+else()
+ set(_a "amd64")
+endif()
+
+set(_dst "C:/Program Files (x86)/Microsoft Visual Studio/2022/BuildTools/DIA SDK/lib/${_a}/diaguids.lib")
+if(EXISTS "${_dst}")
+ return()
+endif()
+
+set(_cand "")
+if(DEFINED ENV{VSINSTALLDIR})
+ file(TO_CMAKE_PATH "$ENV{VSINSTALLDIR}" _r)
+ string(REGEX REPLACE "/+$" "" _r "${_r}")
+ list(APPEND _cand "${_r}/DIA SDK/lib/${_a}/diaguids.lib")
+endif()
+
+set(_vw "C:/Program Files (x86)/Microsoft Visual Studio/Installer/vswhere.exe")
+if(EXISTS "${_vw}")
+ execute_process(
+ COMMAND "${_vw}" -latest -products * -utf8 -property installationPath
+ OUTPUT_VARIABLE _vp OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET RESULT_VARIABLE _vr
+ )
+ if(_vr EQUAL 0 AND _vp)
+ string(STRIP "${_vp}" _vp)
+ list(APPEND _cand "${_vp}/DIA SDK/lib/${_a}/diaguids.lib")
+ endif()
+endif()
+
+foreach(_root "C:/Program Files/Microsoft Visual Studio/2022" "C:/Program Files (x86)/Microsoft Visual Studio/2022")
+ if(EXISTS "${_root}")
+ file(GLOB _g "${_root}/*/DIA SDK/lib/${_a}/diaguids.lib")
+ list(APPEND _cand ${_g})
+ endif()
+endforeach()
+
+set(_src "")
+foreach(_i IN LISTS _cand)
+ if(EXISTS "${_i}")
+ set(_src "${_i}")
+ break()
+ endif()
+endforeach()
+
+if(NOT _src)
+ message(WARNING "EnsureWindowsDiaGuids: diaguids.lib (${_a}) not found. LLVM/lld link may fail.")
+ return()
+endif()
+
+get_filename_component(_dd "${_dst}" DIRECTORY)
+file(MAKE_DIRECTORY "${_dd}")
+execute_process(COMMAND "${CMAKE_COMMAND}" -E copy "${_src}" "${_dst}" RESULT_VARIABLE _ec)
+if(NOT _ec EQUAL 0)
+ message(WARNING "EnsureWindowsDiaGuids: copy failed (${_ec}); try elevated cmake or install DIA SDK.")
+else()
+ message(STATUS "EnsureWindowsDiaGuids: ${_src} -> ${_dst}")
+endif()
diff --git a/cmake/Env.cmake b/cmake/Env.cmake
index 21293d7fe..bdb64d331 100644
--- a/cmake/Env.cmake
+++ b/cmake/Env.cmake
@@ -10,19 +10,28 @@ endif()
ob_define(DEBUG_PREFIX "-fdebug-prefix-map=${CMAKE_SOURCE_DIR}=.")
ob_define(FILE_PREFIX "-ffile-prefix-map=${CMAKE_SOURCE_DIR}=.")
ob_define(OB_LD_BIN ld)
+ob_define(ASAN_IGNORE_LIST "${CMAKE_SOURCE_DIR}/asan_ignore_list.txt")
+
ob_define(DEP_3RD_DIR "${CMAKE_SOURCE_DIR}/deps/3rd")
ob_define(DEVTOOLS_DIR "${CMAKE_SOURCE_DIR}/deps/3rd/usr/local/oceanbase/devtools")
ob_define(DEP_DIR "${CMAKE_SOURCE_DIR}/deps/3rd/usr/local/oceanbase/deps/devel")
+ob_define(BUILD_CDC_ONLY OFF)
# Deprecated no-op retained for compatibility with existing build invocations.
ob_define(BUILD_EMBED_MODE OFF)
if(BUILD_EMBED_MODE)
- message(STATUS "BUILD_EMBED_MODE is deprecated and has no effect")
+ add_definitions(-DOB_BUILD_EMBED_MODE)
endif()
ob_define(OB_USE_CLANG ON)
ob_define(OB_ERRSIM OFF)
ob_define(BUILD_NUMBER 1)
+ob_define(OB_GPERF_MODE OFF)
+ob_define(ENABLE_OBJ_LEAK_CHECK OFF)
+ob_define(ENABLE_FATAL_ERROR_HANG ON)
+ob_define(DETECT_RECURSION OFF)
+ob_define(ENABLE_COMPILE_DLL_MODE OFF)
ob_define(OB_CMAKE_RULES_CHECK ON)
+ob_define(OB_STATIC_LINK_LGPL_DEPS ON)
ob_define(OB_BUILD_CCLS OFF)
ob_define(LTO_JOBS all)
ob_define(LTO_CACHE_DIR "${CMAKE_BINARY_DIR}/cache")
@@ -31,9 +40,15 @@ ob_define(NEED_PARSER_CACHE ON)
# get compiler from build.sh
ob_define(OB_CC "")
ob_define(OB_CXX "")
+ob_define(OB_BUILD_STANDALONE OFF)
ob_define(DEFAULT_LOG_LEVEL OB_LOG_LEVEL_ERROR)
ob_define(DEFAULT_LOG_FILE_SIZE_MB 256)
+# 'ENABLE_PERF_MODE' use for offline system insight performance test
+# PERF_MODE macro controls many special code path in system
+# we can open this to benchmark our system partial/layered
+ob_define(ENABLE_PERF_MODE OFF)
+
# begin of unity build config
ob_define(OB_MAX_UNITY_BATCH_SIZE 30)
# the global switch of unity build, default is 'ON'
@@ -47,6 +62,8 @@ ob_define(OB_ENABLE_MCMODEL OFF)
ob_define(USE_LTO_CACHE OFF)
+ob_define(ASAN_DISABLE_STACK ON)
+
# 开源模式默认支持系统租户使用向量索引
ob_define(OB_BUILD_SYS_VEC_IDX ON)
@@ -123,6 +140,17 @@ else()
set(CMAKE_CXX_FLAGS "-std=gnu++20")
endif()
+
+# Before the first project(), WIN32 may be unset, so the elseif(WIN32) block below can skip
+# CMAKE_MAP_IMPORTED_CONFIG_*. That breaks Windows RelWithDebInfo with FindPython3 (Python3::Module
+# has no IMPORTED_IMPLIB for that config). CMAKE_HOST_WIN32 is set when cmake runs on Windows; skip
+# for Android NDK cross-builds (OB_ANDROID) so we do not force host mapping onto the NDK tree.
+if(CMAKE_HOST_WIN32 AND NOT OB_ANDROID)
+ set(CMAKE_MAP_IMPORTED_CONFIG_DEBUG Release CACHE STRING "imported: map Debug -> Release" FORCE)
+ set(CMAKE_MAP_IMPORTED_CONFIG_RELWITHDEBINFO Release CACHE STRING "imported: map RelWithDebInfo -> Release" FORCE)
+ set(CMAKE_MAP_IMPORTED_CONFIG_MINSIZEREL Release CACHE STRING "imported: map MinSizeRel -> Release" FORCE)
+endif()
+
if(OB_DISABLE_PIE)
message(STATUS "build without pie")
set(PIE_OPT "-no-pie")
@@ -133,10 +161,25 @@ endif()
set(ob_close_deps_static_name "")
+set(OB_BUILD_CLOSE_MODULES OFF)
+
+if(OB_BUILD_STANDALONE)
+ add_definitions(-DOB_BUILD_STANDALONE)
+endif()
+
+if (OB_USE_TEST_PUBKEY)
+ add_definitions(-DOB_USE_TEST_PUBKEY)
+endif()
+
if (OB_BUILD_SYS_VEC_IDX)
add_definitions(-DOB_BUILD_SYS_VEC_IDX)
endif()
+# should not use initial-exec for tls-model if building OBCDC.
+if(BUILD_CDC_ONLY)
+ add_definitions(-DOB_BUILD_CDC_DISABLE_VSAG)
+endif()
+
# Find objcopy - on macOS it may be installed via Homebrew or available as llvm-objcopy
set(OB_CLANG_BIN "clang-17")
set(OB_CLANGXX_BIN "clang++-17")
@@ -155,9 +198,15 @@ if(OB_ANDROID)
# and Env.cmake runs before project() which would set ANDROID.
set(OB_CLANG_BIN "clang")
set(OB_CLANGXX_BIN "clang++")
- # NDK toolchain bin dir (derive from ANDROID_NDK_HOME or CMAKE_TOOLCHAIN_FILE)
+ # NDK toolchain bin dir (derive from ANDROID_NDK_HOME or CMAKE_TOOLCHAIN_FILE).
+ # GLOB prebuilt/*/bin so Linux hosts (e.g. CI) resolve linux-x86_64, macOS resolves darwin-x86_64.
if(DEFINED ENV{ANDROID_NDK_HOME})
- set(_NDK_TOOLCHAIN_BIN "$ENV{ANDROID_NDK_HOME}/toolchains/llvm/prebuilt/darwin-x86_64/bin")
+ file(GLOB _NDK_TOOLCHAIN_BIN "$ENV{ANDROID_NDK_HOME}/toolchains/llvm/prebuilt/*/bin")
+ list(LENGTH _NDK_TOOLCHAIN_BIN _ndk_bin_n)
+ if(_ndk_bin_n LESS 1)
+ message(FATAL_ERROR "ANDROID_NDK_HOME: no toolchains/llvm/prebuilt/*/bin under $ENV{ANDROID_NDK_HOME}")
+ endif()
+ list(GET _NDK_TOOLCHAIN_BIN 0 _NDK_TOOLCHAIN_BIN)
else()
# Derive from toolchain file path: .../build/cmake/android.toolchain.cmake -> .../toolchains/llvm/prebuilt/*/bin
get_filename_component(_NDK_ROOT "${CMAKE_TOOLCHAIN_FILE}" DIRECTORY)
@@ -258,9 +307,14 @@ endif()
ob_define(OB_USE_CCACHE OFF)
if (OB_USE_CCACHE)
+ # Prefer devtools (from deps); dep_create may wipe deps/3rd before a symlink is recreated,
+ # and Android deps do not ship obdevtools-ccache — fall back to ccache on PATH.
find_program(OB_CCACHE ccache PATHS "${DEVTOOLS_DIR}/bin" NO_DEFAULT_PATH)
if (NOT OB_CCACHE)
- message(FATAL_ERROR "cannot find ccache.")
+ find_program(OB_CCACHE ccache)
+ endif()
+ if (NOT OB_CCACHE)
+ message(FATAL_ERROR "cannot find ccache. Install ccache (e.g. apt install ccache) or place it under ${DEVTOOLS_DIR}/bin.")
else()
set(CMAKE_C_COMPILER_LAUNCHER ${OB_CCACHE})
set(CMAKE_CXX_COMPILER_LAUNCHER ${OB_CCACHE})
@@ -295,6 +349,14 @@ if (OB_USE_CLANG)
set(_CMAKE_TOOLCHAIN_PREFIX llvm-)
set(_CMAKE_TOOLCHAIN_LOCATION "${CMAKE_TOOLCHAIN_PATH}/bin")
+ if (OB_USE_ASAN)
+ if (ASAN_DISABLE_STACK)
+ ob_define(CMAKE_ASAN_FLAG "-mllvm -asan-stack=0 -fsanitize=address -fno-optimize-sibling-calls -fsanitize-blacklist=${ASAN_IGNORE_LIST}")
+ else()
+ ob_define(CMAKE_ASAN_FLAG "-fstack-protector-strong -fsanitize=address -fno-optimize-sibling-calls -fsanitize-blacklist=${ASAN_IGNORE_LIST}")
+ endif()
+ endif()
+
if (OB_USE_LLD)
if(OB_ANDROID)
# Android: OB_LD_BIN already set in platform block above
@@ -320,33 +382,33 @@ if (OB_USE_CLANG)
if(OB_ANDROID)
# Android NDK: no --gcc-toolchain, no macOS frameworks
# -D_LIBCPP_ENABLE_CXX17_REMOVED_UNARY_BINARY_FUNCTION: Boost headers use std::unary_function removed in C++17
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${DEBUG_PREFIX} ${FILE_PREFIX} ${AUTO_FDO_OPT} ${THIN_LTO_OPT} -fcolor-diagnostics ${REORDER_COMP_OPT} -fmax-type-align=8 -D_LIBCPP_ENABLE_CXX17_REMOVED_UNARY_BINARY_FUNCTION")
- set(CMAKE_C_FLAGS "${DEBUG_PREFIX} ${FILE_PREFIX} ${AUTO_FDO_OPT} ${THIN_LTO_OPT} -fcolor-diagnostics ${REORDER_COMP_OPT} -fmax-type-align=8")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${DEBUG_PREFIX} ${FILE_PREFIX} ${AUTO_FDO_OPT} ${THIN_LTO_OPT} -fcolor-diagnostics ${REORDER_COMP_OPT} -fmax-type-align=8 ${CMAKE_ASAN_FLAG} -D_LIBCPP_ENABLE_CXX17_REMOVED_UNARY_BINARY_FUNCTION")
+ set(CMAKE_C_FLAGS "${DEBUG_PREFIX} ${FILE_PREFIX} ${AUTO_FDO_OPT} ${THIN_LTO_OPT} -fcolor-diagnostics ${REORDER_COMP_OPT} -fmax-type-align=8 ${CMAKE_ASAN_FLAG}")
set(CMAKE_CXX_LINK_FLAGS "${LD_OPT} ${DEBUG_PREFIX} ${FILE_PREFIX} ${AUTO_FDO_OPT}")
set(CMAKE_SHARED_LINKER_FLAGS "${LD_OPT} ${THIN_LTO_CONCURRENCY_LINK} ${REORDER_LINK_OPT}")
set(CMAKE_EXE_LINKER_FLAGS "${LD_OPT} ${THIN_LTO_CONCURRENCY_LINK} ${REORDER_LINK_OPT} ${CMAKE_COVERAGE_EXE_LINKER_OPTIONS}")
elseif(APPLE)
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${DEBUG_PREFIX} ${FILE_PREFIX} ${AUTO_FDO_OPT} ${THIN_LTO_OPT} -fcolor-diagnostics ${REORDER_COMP_OPT} -fmax-type-align=8")
- set(CMAKE_C_FLAGS "${DEBUG_PREFIX} ${FILE_PREFIX} ${AUTO_FDO_OPT} ${THIN_LTO_OPT} -fcolor-diagnostics ${REORDER_COMP_OPT} -fmax-type-align=8")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${DEBUG_PREFIX} ${FILE_PREFIX} ${AUTO_FDO_OPT} ${THIN_LTO_OPT} -fcolor-diagnostics ${REORDER_COMP_OPT} -fmax-type-align=8 ${CMAKE_ASAN_FLAG}")
+ set(CMAKE_C_FLAGS "${DEBUG_PREFIX} ${FILE_PREFIX} ${AUTO_FDO_OPT} ${THIN_LTO_OPT} -fcolor-diagnostics ${REORDER_COMP_OPT} -fmax-type-align=8 ${CMAKE_ASAN_FLAG}")
set(CMAKE_CXX_LINK_FLAGS "${LD_OPT} ${DEBUG_PREFIX} ${FILE_PREFIX} ${AUTO_FDO_OPT}")
set(CMAKE_SHARED_LINKER_FLAGS "${LD_OPT} ${THIN_LTO_CONCURRENCY_LINK} ${REORDER_LINK_OPT} ${COMPACT_UNWIND_FLAG}")
set(CMAKE_EXE_LINKER_FLAGS "${LD_OPT} ${THIN_LTO_CONCURRENCY_LINK} ${REORDER_LINK_OPT} ${CMAKE_COVERAGE_EXE_LINKER_OPTIONS} ${COMPACT_UNWIND_FLAG}")
elseif(WIN32)
set(OB_OBJCOPY_BIN "llvm-objcopy")
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${DEBUG_PREFIX} ${FILE_PREFIX} ${AUTO_FDO_OPT} ${THIN_LTO_OPT} ${REORDER_COMP_OPT}")
- set(CMAKE_C_FLAGS "${DEBUG_PREFIX} ${FILE_PREFIX} ${AUTO_FDO_OPT} ${THIN_LTO_OPT} ${REORDER_COMP_OPT}")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${DEBUG_PREFIX} ${FILE_PREFIX} ${AUTO_FDO_OPT} ${THIN_LTO_OPT} ${REORDER_COMP_OPT} ${CMAKE_ASAN_FLAG}")
+ set(CMAKE_C_FLAGS "${DEBUG_PREFIX} ${FILE_PREFIX} ${AUTO_FDO_OPT} ${THIN_LTO_OPT} ${REORDER_COMP_OPT} ${CMAKE_ASAN_FLAG}")
set(CMAKE_CXX_LINK_FLAGS "${LD_OPT} ${DEBUG_PREFIX} ${FILE_PREFIX} ${AUTO_FDO_OPT}")
set(CMAKE_SHARED_LINKER_FLAGS "/INCREMENTAL:NO ${LD_OPT} ${THIN_LTO_CONCURRENCY_LINK} ${REORDER_LINK_OPT} ${COMPACT_UNWIND_FLAG}")
set(CMAKE_EXE_LINKER_FLAGS "/INCREMENTAL:NO ${LD_OPT} ${THIN_LTO_CONCURRENCY_LINK} ${REORDER_LINK_OPT} ${CMAKE_COVERAGE_EXE_LINKER_OPTIONS} ${COMPACT_UNWIND_FLAG}")
elseif(OB_ANDROID)
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${DEBUG_PREFIX} ${FILE_PREFIX} ${AUTO_FDO_OPT} ${THIN_LTO_OPT} -fcolor-diagnostics ${REORDER_COMP_OPT} -fmax-type-align=8")
- set(CMAKE_C_FLAGS "${DEBUG_PREFIX} ${FILE_PREFIX} ${AUTO_FDO_OPT} ${THIN_LTO_OPT} -fcolor-diagnostics ${REORDER_COMP_OPT} -fmax-type-align=8")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${DEBUG_PREFIX} ${FILE_PREFIX} ${AUTO_FDO_OPT} ${THIN_LTO_OPT} -fcolor-diagnostics ${REORDER_COMP_OPT} -fmax-type-align=8 ${CMAKE_ASAN_FLAG}")
+ set(CMAKE_C_FLAGS "${DEBUG_PREFIX} ${FILE_PREFIX} ${AUTO_FDO_OPT} ${THIN_LTO_OPT} -fcolor-diagnostics ${REORDER_COMP_OPT} -fmax-type-align=8 ${CMAKE_ASAN_FLAG}")
set(CMAKE_CXX_LINK_FLAGS "${LD_OPT} ${DEBUG_PREFIX} ${FILE_PREFIX} ${AUTO_FDO_OPT}")
set(CMAKE_SHARED_LINKER_FLAGS "${LD_OPT} ${THIN_LTO_CONCURRENCY_LINK} ${REORDER_LINK_OPT}")
set(CMAKE_EXE_LINKER_FLAGS "${LD_OPT} ${THIN_LTO_CONCURRENCY_LINK} ${REORDER_LINK_OPT} ${CMAKE_COVERAGE_EXE_LINKER_OPTIONS}")
else()
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --gcc-toolchain=${GCC9} -gdwarf-4 ${DEBUG_PREFIX} ${FILE_PREFIX} ${AUTO_FDO_OPT} ${THIN_LTO_OPT} -fcolor-diagnostics ${REORDER_COMP_OPT} -fmax-type-align=8")
- set(CMAKE_C_FLAGS "--gcc-toolchain=${GCC9} -gdwarf-4 ${DEBUG_PREFIX} ${FILE_PREFIX} ${AUTO_FDO_OPT} ${THIN_LTO_OPT} -fcolor-diagnostics ${REORDER_COMP_OPT} -fmax-type-align=8")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --gcc-toolchain=${GCC9} -gdwarf-4 ${DEBUG_PREFIX} ${FILE_PREFIX} ${AUTO_FDO_OPT} ${THIN_LTO_OPT} -fcolor-diagnostics ${REORDER_COMP_OPT} -fmax-type-align=8 ${CMAKE_ASAN_FLAG}")
+ set(CMAKE_C_FLAGS "--gcc-toolchain=${GCC9} -gdwarf-4 ${DEBUG_PREFIX} ${FILE_PREFIX} ${AUTO_FDO_OPT} ${THIN_LTO_OPT} -fcolor-diagnostics ${REORDER_COMP_OPT} -fmax-type-align=8 ${CMAKE_ASAN_FLAG}")
set(CMAKE_CXX_LINK_FLAGS "${LD_OPT} --gcc-toolchain=${GCC9} ${DEBUG_PREFIX} ${FILE_PREFIX} ${AUTO_FDO_OPT}")
set(CMAKE_SHARED_LINKER_FLAGS "${LD_OPT} -Wl,-z,noexecstack ${THIN_LTO_CONCURRENCY_LINK} ${REORDER_LINK_OPT}")
set(CMAKE_EXE_LINKER_FLAGS "${LD_OPT} -Wl,-z,noexecstack ${PIE_OPT} ${THIN_LTO_CONCURRENCY_LINK} ${REORDER_LINK_OPT} ${CMAKE_COVERAGE_EXE_LINKER_OPTIONS}")
diff --git a/deps/init/dep_create.ps1 b/deps/init/dep_create.ps1
index 118b82834..96095662e 100644
--- a/deps/init/dep_create.ps1
+++ b/deps/init/dep_create.ps1
@@ -9,7 +9,7 @@
After extraction the layout is:
deps/3rd/vcpkg/x64-windows/ (vcpkg installed packages)
deps/3rd/openssl/ (OpenSSL)
- deps/3rd/vsag/ (vsag vector search library)
+ deps/3rd/vsag/ (vsag vector search library)
deps/3rd/tools/cmake/ (CMake)
deps/3rd/tools/ninja/ (Ninja)
deps/3rd/tools/llvm18/ (LLVM 18)
@@ -123,20 +123,16 @@ foreach ($sect in $sections.Keys) {
Write-Log " cached"
} else {
Write-Log " downloading from $url ..."
+ # Schannel/CI: use --ssl-no-revoke (avoids curl 35 / revocation offline); retries for flaky links.
$tmpPath = "$pkgPath.tmp"
- try {
- & curl.exe -L -f -s --retry 3 --retry-delay 2 -o $tmpPath $url
- if ($LASTEXITCODE -ne 0) {
- throw "curl exit code $LASTEXITCODE"
- }
- Move-Item -Force $tmpPath $pkgPath
- }
- catch {
- if (Test-Path $tmpPath) { Remove-Item -Force $tmpPath }
- Write-Err "Failed to download: $url"
- Write-Err "$_"
+ if (Test-Path $tmpPath) { Remove-Item -Force $tmpPath -ErrorAction SilentlyContinue }
+ & curl.exe -L -f -sS --connect-timeout 120 --ssl-no-revoke --retry 3 --retry-delay 2 -o $tmpPath $url
+ if ($LASTEXITCODE -ne 0) {
+ if (Test-Path $tmpPath) { Remove-Item -Force $tmpPath -ErrorAction SilentlyContinue }
+ Write-Err "Failed to download: $url (curl exit $LASTEXITCODE)"
exit 4
}
+ Move-Item -Force $tmpPath $pkgPath
}
# -- Extract -------------------------------------------------
diff --git a/deps/init/dep_create.sh b/deps/init/dep_create.sh
index ac91f1d1d..1c79bccbe 100644
--- a/deps/init/dep_create.sh
+++ b/deps/init/dep_create.sh
@@ -72,6 +72,17 @@ function echo_err() {
echo -e "[dep_create.sh][ERROR] $@" 1>&2
}
+# GNU tar: archives built on macOS may contain PAX extended headers (e.g. LIBARCHIVE.xattr.com.apple.provenance);
+# extracting on Linux otherwise prints harmless "Ignoring unknown extended header keyword" noise.
+function extract_tar_gz_strip1() {
+ local dir="$1" archive="$2"
+ if tar --version 2>/dev/null | head -n1 | grep -q 'GNU tar'; then
+ (cd "$dir" && tar --warning=no-unknown-keyword -xzf "$archive" --strip-components=1)
+ else
+ (cd "$dir" && tar -xzf "$archive" --strip-components=1)
+ fi
+}
+
function get_os_release() {
if [[ "${ANDROID_BUILD}" == "true" ]]; then
OS_RELEASE="android"
@@ -461,7 +472,7 @@ do
fi
echo_log "unpack package <${pkg}>... \c"
if [[ "${IS_TAR_PLATFORM}" == "true" ]]; then
- (cd ${TARGET_DIR_3RD} && tar -xzf "${TARGET_DIR_3RD}/pkg/${pkg}" --strip-components=1)
+ extract_tar_gz_strip1 "${TARGET_DIR_3RD}" "${TARGET_DIR_3RD}/pkg/${pkg}"
elif [[ "$ID" = "arch" || "$ID" = "garuda" ]]; then
(cd ${TARGET_DIR_3RD} && rpmextract.sh "${TARGET_DIR_3RD}/pkg/${pkg}")
else
diff --git a/deps/oblib/src/grpc/CMakeLists.txt b/deps/oblib/src/grpc/CMakeLists.txt
new file mode 100644
index 000000000..919c898e5
--- /dev/null
+++ b/deps/oblib/src/grpc/CMakeLists.txt
@@ -0,0 +1,179 @@
+set(PROTO_SRC_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
+set(PROTO_GEN_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
+
+set(PROTO_NAMES
+ example
+ storageservice
+ logservice
+ serverservice
+)
+
+# On Linux: grpc libs are in lib/grpc/, abseil/protobuf libs are in lib64/grpc/
+# On macOS: all libs are in lib/grpc/
+if(APPLE OR OB_ANDROID)
+ set(GRPC_LIB_DIR "lib")
+ set(ABSL_LIB_DIR "lib")
+else()
+ set(GRPC_LIB_DIR "lib")
+ set(ABSL_LIB_DIR "lib64")
+endif()
+
+if(WIN32)
+ list(APPEND CMAKE_PREFIX_PATH "${OB_VCPKG_DIR}")
+ # NOTE: CMAKE_MAP_IMPORTED_CONFIG_ (DEBUG/RelWithDebInfo/MinSizeRel
+ # -> Release) is set globally in cmake/Env.cmake. It forces imported
+ # targets from find_package(... CONFIG) below (and any transitive deps
+ # such as abseil/protobuf/openssl from gRPC) to resolve to their Release
+ # .lib variants, matching our Release MSVC runtime in all build types.
+ find_package(gRPC CONFIG REQUIRED)
+ find_package(protobuf CONFIG REQUIRED)
+ set(_PROTOC $)
+ set(_GRPC_CPP_PLUGIN $)
+else()
+ set(DEVEL_PATH "${DEP_3RD_DIR}/usr/local/oceanbase/deps/devel")
+ option(protobuf_MODULE_COMPATIBLE TRUE)
+ set(_PROTOC "${DEVEL_PATH}/bin/protoc")
+ set(_GRPC_CPP_PLUGIN "${DEVEL_PATH}/bin/grpc_cpp_plugin")
+ set(_PROTOC_LD_PATH "${DEVTOOLS_DIR}/lib64")
+ include_directories(
+ ${DEP_3RD_DIR}/usr/include
+ ${DEVEL_PATH}/include
+ )
+endif()
+
+# Generate .pb.cc/.pb.h and .grpc.pb.cc/.grpc.pb.h from .proto files at build time
+set(GENERATED_SRCS)
+foreach(PROTO_NAME ${PROTO_NAMES})
+ set(PROTO_FILE "${PROTO_SRC_DIR}/${PROTO_NAME}.proto")
+ set(PB_CC "${PROTO_GEN_DIR}/${PROTO_NAME}.pb.cc")
+ set(PB_H "${PROTO_GEN_DIR}/${PROTO_NAME}.pb.h")
+ set(GRPC_CC "${PROTO_GEN_DIR}/${PROTO_NAME}.grpc.pb.cc")
+ set(GRPC_H "${PROTO_GEN_DIR}/${PROTO_NAME}.grpc.pb.h")
+
+ # Linux/macOS: protoc may need LD_LIBRARY_PATH for bundled libprotobuf.so.
+ # Windows (vcpkg): invoke protoc/grpc_cpp_plugin directly; LD_LIBRARY_PATH is meaningless.
+ if(WIN32)
+ add_custom_command(
+ OUTPUT ${PB_CC} ${PB_H}
+ COMMAND ${_PROTOC}
+ --cpp_out=${PROTO_GEN_DIR}
+ -I${PROTO_SRC_DIR}
+ ${PROTO_FILE}
+ DEPENDS ${PROTO_FILE}
+ COMMENT "Generating protobuf C++ from ${PROTO_NAME}.proto"
+ )
+
+ add_custom_command(
+ OUTPUT ${GRPC_CC} ${GRPC_H}
+ COMMAND ${_PROTOC}
+ --grpc_out=${PROTO_GEN_DIR}
+ --plugin=protoc-gen-grpc=${_GRPC_CPP_PLUGIN}
+ -I${PROTO_SRC_DIR}
+ ${PROTO_FILE}
+ DEPENDS ${PROTO_FILE}
+ COMMENT "Generating gRPC C++ from ${PROTO_NAME}.proto"
+ )
+ else()
+ add_custom_command(
+ OUTPUT ${PB_CC} ${PB_H}
+ COMMAND ${CMAKE_COMMAND} -E env "LD_LIBRARY_PATH=${_PROTOC_LD_PATH}:$ENV{LD_LIBRARY_PATH}"
+ ${_PROTOC}
+ --cpp_out=${PROTO_GEN_DIR}
+ -I${PROTO_SRC_DIR}
+ ${PROTO_FILE}
+ DEPENDS ${PROTO_FILE}
+ COMMENT "Generating protobuf C++ from ${PROTO_NAME}.proto"
+ )
+
+ add_custom_command(
+ OUTPUT ${GRPC_CC} ${GRPC_H}
+ COMMAND ${CMAKE_COMMAND} -E env "LD_LIBRARY_PATH=${_PROTOC_LD_PATH}:$ENV{LD_LIBRARY_PATH}"
+ ${_PROTOC}
+ --grpc_out=${PROTO_GEN_DIR}
+ --plugin=protoc-gen-grpc=${_GRPC_CPP_PLUGIN}
+ -I${PROTO_SRC_DIR}
+ ${PROTO_FILE}
+ DEPENDS ${PROTO_FILE}
+ COMMENT "Generating gRPC C++ from ${PROTO_NAME}.proto"
+ )
+ endif()
+
+ list(APPEND GENERATED_SRCS ${PB_CC} ${GRPC_CC})
+endforeach()
+
+add_library(oblib_grpc STATIC
+ ${GENERATED_SRCS}
+ ob_grpc_context.cpp
+ ob_grpc_server.cpp
+)
+
+target_include_directories(oblib_grpc
+ PUBLIC ${PROTO_GEN_DIR}
+)
+
+if(WIN32)
+ target_link_libraries(oblib_grpc
+ PUBLIC oblib_base
+ gRPC::grpc++
+ gRPC::grpc++_reflection
+ protobuf::libprotobuf
+ )
+else()
+ set(GRPC_STATIC_LIB_DIR "${DEVEL_PATH}/${GRPC_LIB_DIR}/grpc")
+ set(ABSL_STATIC_LIB_DIR "${DEVEL_PATH}/${ABSL_LIB_DIR}/grpc")
+
+ set(GRPC_CORE_LIB_NAMES
+ grpc++ grpc grpc_unsecure grpc++_reflection grpc++_error_details
+ grpc_plugin_support grpcpp_channelz gpr
+ address_sorting re2 upb
+ )
+
+ set(ABSL_LIB_NAMES
+ absl_base absl_int128 absl_throw_delegate absl_raw_logging_internal
+ absl_log_severity absl_spinlock_wait absl_malloc_internal
+ absl_debugging_internal absl_demangle_internal absl_stacktrace
+ absl_symbolize absl_examine_stack absl_failure_signal_handler
+ absl_strerror
+ absl_strings absl_strings_internal absl_str_format_internal
+ absl_cord absl_cord_internal absl_cordz_info absl_cordz_handle
+ absl_cordz_functions absl_cordz_sample_token
+ absl_hash absl_low_level_hash absl_city
+ absl_raw_hash_set absl_hashtablez_sampler
+ absl_status absl_statusor
+ absl_bad_any_cast_impl absl_bad_optional_access absl_bad_variant_access
+ absl_synchronization absl_graphcycles_internal absl_time absl_time_zone
+ absl_civil_time absl_exponential_biased absl_periodic_sampler
+ absl_random_distributions absl_random_seed_sequences
+ absl_random_seed_gen_exception absl_random_internal_pool_urbg
+ absl_random_internal_randen absl_random_internal_randen_hwaes
+ absl_random_internal_randen_hwaes_impl absl_random_internal_randen_slow
+ absl_random_internal_seed_material absl_random_internal_platform
+ absl_random_internal_distribution_test_util
+ absl_flags absl_flags_commandlineflag absl_flags_commandlineflag_internal
+ absl_flags_config absl_flags_internal absl_flags_marshalling
+ absl_flags_parse absl_flags_private_handle_accessor
+ absl_flags_program_name absl_flags_reflection
+ absl_flags_usage absl_flags_usage_internal
+ absl_leak_check absl_leak_check_disable absl_scoped_set_env
+ )
+
+ set(_GRPC_STATIC_LIBS)
+ foreach(_name ${GRPC_CORE_LIB_NAMES})
+ list(APPEND _GRPC_STATIC_LIBS "${GRPC_STATIC_LIB_DIR}/lib${_name}.a")
+ endforeach()
+ foreach(_name ${ABSL_LIB_NAMES})
+ list(APPEND _GRPC_STATIC_LIBS "${ABSL_STATIC_LIB_DIR}/lib${_name}.a")
+ endforeach()
+
+ target_link_libraries(oblib_grpc
+ PUBLIC oblib_base
+ ${_GRPC_STATIC_LIBS}
+ ${ABSL_STATIC_LIB_DIR}/libcares.a
+ ${ABSL_STATIC_LIB_DIR}/libprotobuf.a
+ )
+endif()
+
+# macOS requires libresolv for c-ares DNS resolution
+if(APPLE)
+ target_link_libraries(oblib_grpc PUBLIC resolv)
+endif()
diff --git a/deps/oblib/src/lib/cpu/ob_cpu_topology.cpp b/deps/oblib/src/lib/cpu/ob_cpu_topology.cpp
index a6be8c531..22923bf39 100644
--- a/deps/oblib/src/lib/cpu/ob_cpu_topology.cpp
+++ b/deps/oblib/src/lib/cpu/ob_cpu_topology.cpp
@@ -75,7 +75,12 @@ int CpuFlagSet::init_from_os(uint64_t& flags)
{
int ret = OB_SUCCESS;
flags = 0;
-#if defined(__linux__)
+#if defined(__ANDROID__)
+ // Android defines __linux__ as well, but app processes are sandboxed and shelling
+ // out to grep /proc/cpuinfo via system()/posix_spawn() is unsafe during startup.
+ // Rely on direct CPU probing instead.
+ init_from_cpu(flags);
+#elif defined(__linux__)
const char* const CPU_FLAG_CMDS[(int)CpuFlag::MAX] = {"grep -E ' sse4_2( |$)' /proc/cpuinfo > /dev/null 2>&1",
"grep -E ' avx( |$)' /proc/cpuinfo > /dev/null 2>&1",
"grep -E ' avx2( |$)' /proc/cpuinfo > /dev/null 2>&1",
@@ -95,8 +100,8 @@ int CpuFlagSet::init_from_os(uint64_t& flags)
flags |= (1 << i);
}
}
-#elif defined(__APPLE__) || defined(__ANDROID__)
- // On macOS/Android, /proc/cpuinfo doesn't exist or SSE/AVX features are irrelevant.
+#elif defined(__APPLE__)
+ // On macOS, /proc/cpuinfo doesn't exist or SSE/AVX features are irrelevant.
// We can use sysctl to check for features, but for now we rely on init_from_cpu
// and just return success here with flags set to a reasonable default or
// matched with cpu flags to avoid mismatch error in constructor.
diff --git a/deps/oblib/src/lib/oblog/ob_log.h b/deps/oblib/src/lib/oblog/ob_log.h
index e3a43519f..566fcd637 100644
--- a/deps/oblib/src/lib/oblog/ob_log.h
+++ b/deps/oblib/src/lib/oblog/ob_log.h
@@ -1017,6 +1017,10 @@ void ObLogger::log_it(const char *mod_name,
// (before main() enters or after main() returns). Fall back to stderr.
if (OB_UNLIKELY(!g_ob_log_main_entered)) {
if (OB_NOT_NULL(file) && OB_NOT_NULL(function)) {
+ // Static init is noisy at INFO; stderr fallback cannot honor module filters — drop chatter only.
+ if (level == OB_LOG_LEVEL_INFO || level == OB_LOG_LEVEL_TRACE || level == OB_LOG_LEVEL_DEBUG) {
+ return;
+ }
static constexpr const char *const lvlstr[] = {"ERROR", "WARN", "INFO", "EDIAG", "WDIAG", "TRACE", "DEBUG"};
const char *lvl = (level >= 0 && level < (int)(sizeof(lvlstr)/sizeof(lvlstr[0]))) ? lvlstr[level] : "?";
fprintf(stderr, "[PRE-MAIN] %-5s %s:%d %s\n", lvl, file, line, function);
diff --git a/deps/oblib/src/lib/signal/ob_signal_handlers.cpp b/deps/oblib/src/lib/signal/ob_signal_handlers.cpp
index ee2c151cd..4d264ed69 100644
--- a/deps/oblib/src/lib/signal/ob_signal_handlers.cpp
+++ b/deps/oblib/src/lib/signal/ob_signal_handlers.cpp
@@ -69,6 +69,13 @@ static inline void handler(int sig, siginfo_t *s, void *p)
int install_ob_signal_handler()
{
int ret = OB_SUCCESS;
+#ifdef __ANDROID__
+ // ART/libsigchain owns fatal signal dispatch for app processes. Installing
+ // OceanBase's process-wide crash handlers here interferes with JNI/runtime
+ // fault handling and can turn startup failures into opaque instrumentation
+ // crashes.
+ return ret;
+#else
struct sigaction sa;
sa.sa_flags = SA_SIGINFO | SA_RESTART | SA_NODEFER | SA_ONSTACK;
sa.sa_sigaction = handler;
@@ -84,6 +91,7 @@ int install_ob_signal_handler()
}
}
return ret;
+#endif
}
bool g_redirect_handler = false;
diff --git a/deps/oblib/src/lib/utility/ob_macro_utils.h b/deps/oblib/src/lib/utility/ob_macro_utils.h
index 4d4d4e309..6794216b5 100644
--- a/deps/oblib/src/lib/utility/ob_macro_utils.h
+++ b/deps/oblib/src/lib/utility/ob_macro_utils.h
@@ -17,7 +17,10 @@
#ifndef _OB_MACRO_UTILS_H_
#define _OB_MACRO_UTILS_H_
-#ifdef _WIN32
+/* Windows MSVC (cl.exe) has no weak symbols; stubs in ob_log.cpp etc. rely on OB_WEAK_SYMBOL.
+ * clang-cl + lld-link support __attribute__((weak)) on COFF — use it so strong defs in
+ * src/share/ob_errno.cpp override stubs (same as ELF). Plain _WIN32 must leave this empty. */
+#if defined(_WIN32) && !(defined(__clang__) || defined(__GNUC__))
#define OB_WEAK_SYMBOL
#else
#define OB_WEAK_SYMBOL __attribute__((weak))
diff --git a/deps/oblib/src/lib/utility/utility.h b/deps/oblib/src/lib/utility/utility.h
index dd5285c91..4f17a76a8 100644
--- a/deps/oblib/src/lib/utility/utility.h
+++ b/deps/oblib/src/lib/utility/utility.h
@@ -47,8 +47,10 @@ inline int usleep(useconds_t usec) {
#include "lib/allocator/ob_malloc.h"
#include "lib/time/ob_clock_generator.h"
-#ifdef __APPLE__
+#if defined(__APPLE__)
#include // includes BSD type definitions
+#endif
+#if defined(__APPLE__) || defined(_WIN32)
using uint = unsigned int;
#endif
#define FALSE_IT(stmt) ({ (stmt); false; })
diff --git a/deps/oblib/src/lib/vector/ob_vector_util.cpp b/deps/oblib/src/lib/vector/ob_vector_util.cpp
index ad1775c2e..7fa5a2ba9 100644
--- a/deps/oblib/src/lib/vector/ob_vector_util.cpp
+++ b/deps/oblib/src/lib/vector/ob_vector_util.cpp
@@ -65,19 +65,28 @@ void ObVsagLogger::Critical(const std::string& msg)
int init_vasg_logger(void* logger)
{
+ INIT_SUCC(ret);
if (!check_vsag_init()) {
return -4016;
} else {
+#if defined(OB_BUILD_CDC_DISABLE_VSAG) && !defined(OB_BUILD_EMBED_MODE)
+#else
obvsag::set_logger(logger);
obvsag::set_log_level(static_cast(OB_LOGGER.get_log_level()));
+#endif
}
return 0;
}
bool check_vsag_init()
-{
+{
+ INIT_SUCC(ret);
+#if defined(OB_BUILD_CDC_DISABLE_VSAG) && !defined(OB_BUILD_EMBED_MODE)
+ return true;
+#else
return obvsag::is_init();
+#endif
}
@@ -88,6 +97,10 @@ int create_index(obvsag::VectorIndexPtr& index_handler, int index_type,
int16_t refine_type /*= 0*/, int16_t bq_bits_query /*= 32*/,
bool bq_use_fht /*= false*/)
{
+ INIT_SUCC(ret);
+#if defined(OB_BUILD_CDC_DISABLE_VSAG) && !defined(OB_BUILD_EMBED_MODE)
+ return ret;
+#else
obvsag::set_block_size_limit(2*1024*1024);
LOG_INFO("vector index create params: ", K(index_type), K(dim), KCSTRING(dtype), KCSTRING(metric), K(max_degree), K(ef_construction), K(ef_search),
KP(allocator), K(extra_info_size), K(refine_type), K(bq_bits_query), K(bq_use_fht));
@@ -103,10 +116,17 @@ int create_index(obvsag::VectorIndexPtr& index_handler, int index_type,
refine_type,
bq_bits_query,
bq_use_fht);
+#endif
}
int validate_create_index(const CreateIndexParam ¶m, std::string &err_msg)
{
+#if defined(OB_BUILD_CDC_DISABLE_VSAG) && !defined(OB_BUILD_EMBED_MODE)
+ INIT_SUCC(ret);
+ UNUSED(param);
+ err_msg.clear();
+ return ret;
+#else
obvsag::set_block_size_limit(2*1024*1024);
LOG_INFO("vector index validate params: ", K(param.index_type_), KCSTRING(param.dtype_),
KCSTRING(param.metric_), K(param.is_sparse_), K(param.dim_), K(param.max_degree_),
@@ -114,48 +134,85 @@ int validate_create_index(const CreateIndexParam ¶m, std::string &err_msg)
K(param.refine_type_), K(param.bq_bits_query_), K(param.bq_use_fht_),
K(param.use_reorder_), K(param.doc_prune_ratio_), K(param.window_size_), KP(param.allocator_));
return obvsag::validate_create_index(param, err_msg);
+#endif
}
int create_index(obvsag::VectorIndexPtr &index_handler, int index_type, const char *dtype, const char *metric,
bool use_reorder, float doc_prune_ratio, int window_size, void *allocator, int extra_info_size /* 0 */)
{
+ INIT_SUCC(ret);
+#if defined(OB_BUILD_CDC_DISABLE_VSAG) && !defined(OB_BUILD_EMBED_MODE)
+ return ret;
+#else
obvsag::set_block_size_limit(2*1024*1024);
LOG_INFO("vector index create params: ", K(index_type), KCSTRING(dtype), KCSTRING(metric), K(use_reorder), K(doc_prune_ratio), K(window_size), KP(allocator), K(extra_info_size));
return obvsag::create_index(index_handler, static_cast(index_type),
dtype, metric, use_reorder, doc_prune_ratio, window_size,
allocator, extra_info_size);
+#endif
}
int build_index(obvsag::VectorIndexPtr index_handler, float* vector_list, int64_t* ids, int dim, int size, char* extra_info /*= nullptr*/)
{
+ INIT_SUCC(ret);
+#if defined(OB_BUILD_CDC_DISABLE_VSAG) && !defined(OB_BUILD_EMBED_MODE)
+ return ret;
+#else
return obvsag::build_index(index_handler, vector_list, ids, dim, size, extra_info);
+#endif
+
}
int build_index(obvsag::VectorIndexPtr &index_handler, uint32_t *lens, uint32_t *dims, float *vals, int64_t *ids,
int size, char *extra_infos /*= nullptr*/)
{
+ INIT_SUCC(ret);
+#if defined(OB_BUILD_CDC_DISABLE_VSAG) && !defined(OB_BUILD_EMBED_MODE)
+ return ret;
+#else
return obvsag::build_index(index_handler, lens, dims, vals, ids, size, extra_infos);
+#endif
}
int add_index(obvsag::VectorIndexPtr index_handler, float* vector_list, int64_t* ids, int dim, char *extra_info, int size)
{
+ INIT_SUCC(ret);
+#if defined(OB_BUILD_CDC_DISABLE_VSAG) && !defined(OB_BUILD_EMBED_MODE)
+ return ret;
+#else
return obvsag::add_index(index_handler, vector_list, ids, dim, size, extra_info);
+#endif
}
int add_index(obvsag::VectorIndexPtr &index_handler, uint32_t *lens, uint32_t *dims, float *vals, int64_t *ids, int size,
char *extra_infos)
{
+ INIT_SUCC(ret);
+#if defined(OB_BUILD_CDC_DISABLE_VSAG) && !defined(OB_BUILD_EMBED_MODE)
+ return ret;
+#else
return obvsag::add_index(index_handler, lens, dims, vals, ids, size, extra_infos);
+#endif
}
int get_index_number(obvsag::VectorIndexPtr index_handler, int64_t &size)
{
+ INIT_SUCC(ret);
+#if defined(OB_BUILD_CDC_DISABLE_VSAG) && !defined(OB_BUILD_EMBED_MODE)
+ return ret;
+#else
return obvsag::get_index_number(index_handler, size);
+#endif
}
int get_index_type(obvsag::VectorIndexPtr index_handler)
{
+ INIT_SUCC(ret);
+#if defined(OB_BUILD_CDC_DISABLE_VSAG) && !defined(OB_BUILD_EMBED_MODE)
+ return ret;
+#else
return obvsag::get_index_type(index_handler);
+#endif
}
int cal_distance_by_id(obvsag::VectorIndexPtr index_handler,
@@ -164,7 +221,12 @@ int cal_distance_by_id(obvsag::VectorIndexPtr index_handler,
int64_t count,
const float *&distances)
{
+ INIT_SUCC(ret);
+#if defined(OB_BUILD_CDC_DISABLE_VSAG) && !defined(OB_BUILD_EMBED_MODE)
+ return ret;
+#else
return obvsag::cal_distance_by_id(index_handler, vector, ids, count, distances);
+#endif
}
int cal_distance_by_id(obvsag::VectorIndexPtr index_handler,
@@ -173,19 +235,34 @@ int cal_distance_by_id(obvsag::VectorIndexPtr index_handler,
int64_t count,
const float *&distances)
{
+ INIT_SUCC(ret);
+#if defined(OB_BUILD_CDC_DISABLE_VSAG) && !defined(OB_BUILD_EMBED_MODE)
+ return ret;
+#else
return obvsag::cal_distance_by_id(index_handler, len, dims, vals, ids, count, distances);
+#endif
}
int get_vid_bound(obvsag::VectorIndexPtr index_handler, int64_t &min_vid, int64_t &max_vid)
{
+ INIT_SUCC(ret);
+#if defined(OB_BUILD_CDC_DISABLE_VSAG) && !defined(OB_BUILD_EMBED_MODE)
+ return ret;
+#else
return obvsag::get_vid_bound(index_handler, min_vid, max_vid);
+#endif
}
int get_extra_info_by_ids(obvsag::VectorIndexPtr& index_handler,
const int64_t* ids,
int64_t count,
char *extra_infos) {
+INIT_SUCC(ret);
+#if defined(OB_BUILD_CDC_DISABLE_VSAG) && !defined(OB_BUILD_EMBED_MODE)
+ return ret;
+#else
return obvsag::get_extra_info_by_ids(index_handler, ids, count, extra_infos);
+#endif
}
int knn_search(obvsag::VectorIndexPtr index_handler, float* query_vector,int dim, int64_t topk,
@@ -193,11 +270,16 @@ int knn_search(obvsag::VectorIndexPtr index_handler, float* query_vector,int dim
void* invalid, bool reverse_filter, bool is_extra_info_filter, float valid_ratio, void *allocator, bool need_extra_info,
float distance_threshold)
{
+ INIT_SUCC(ret);
+#if defined(OB_BUILD_CDC_DISABLE_VSAG) && !defined(OB_BUILD_EMBED_MODE)
+ return ret;
+#else
return obvsag::knn_search(index_handler, query_vector, dim, topk,
result_dist, result_ids, result_size,
ef_search, need_extra_info, extra_info,
invalid, reverse_filter, is_extra_info_filter,
allocator, valid_ratio, distance_threshold);
+#endif
}
int knn_search(obvsag::VectorIndexPtr index_handler, float* query_vector,int dim, int64_t topk,
@@ -205,11 +287,16 @@ int knn_search(obvsag::VectorIndexPtr index_handler, float* query_vector,int dim
void* invalid, bool reverse_filter, bool is_extra_info_filter, float valid_ratio, void *allocator,
bool need_extra_info, void *&iter_ctx, bool is_last_search)
{
+ INIT_SUCC(ret);
+#if defined(OB_BUILD_CDC_DISABLE_VSAG) && !defined(OB_BUILD_EMBED_MODE)
+ return ret;
+#else
return obvsag::knn_search(index_handler, query_vector, dim, topk,
result_dist, result_ids, result_size,
ef_search, need_extra_info, extra_info,
invalid, reverse_filter, is_extra_info_filter,
valid_ratio, iter_ctx, is_last_search, allocator);
+#endif
}
int knn_search(obvsag::VectorIndexPtr index_handler, uint32_t len, uint32_t *dims, float *vals, int64_t topk,
@@ -217,42 +304,76 @@ int knn_search(obvsag::VectorIndexPtr index_handler, uint32_t len, uint32_t *dim
void *invalid, bool reverse_filter,
bool is_extra_info_filter, float valid_ratio, void *allocator, bool need_extra_info)
{
+ INIT_SUCC(ret);
+#if defined(OB_BUILD_CDC_DISABLE_VSAG) && !defined(OB_BUILD_EMBED_MODE)
+ return ret;
+#else
return obvsag::knn_search(index_handler, len, dims, vals, topk,
result_dist, result_ids, extra_info, result_size,
query_prune_ratio, n_candidate,
invalid, reverse_filter, is_extra_info_filter,
valid_ratio, allocator, need_extra_info);
+#endif
}
int fserialize(obvsag::VectorIndexPtr index_handler, std::ostream& out_stream)
{
+ INIT_SUCC(ret);
+#if defined(OB_BUILD_CDC_DISABLE_VSAG) && !defined(OB_BUILD_EMBED_MODE)
+ return ret;
+#else
return obvsag::fserialize(index_handler, out_stream);
+#endif
}
int fdeserialize(obvsag::VectorIndexPtr& index_handler, std::istream& in_stream)
{
+ INIT_SUCC(ret);
+#if defined(OB_BUILD_CDC_DISABLE_VSAG) && !defined(OB_BUILD_EMBED_MODE)
+ return ret;
+#else
return obvsag::fdeserialize(index_handler,in_stream);
+#endif
}
int delete_index(obvsag::VectorIndexPtr& index_handler)
{
+ INIT_SUCC(ret);
+#if defined(OB_BUILD_CDC_DISABLE_VSAG) && !defined(OB_BUILD_EMBED_MODE)
+ return ret;
+#else
return obvsag::delete_index(index_handler);
+#endif
}
void delete_iter_ctx(void *iter_ctx)
{
+#if defined(OB_BUILD_CDC_DISABLE_VSAG) && !defined(OB_BUILD_EMBED_MODE)
+#else
obvsag::delete_iter_ctx(iter_ctx);
+#endif
}
// return byte
uint64_t estimate_memory(obvsag::VectorIndexPtr& index_handler, const uint64_t row_count, const bool is_build)
{
+ INIT_SUCC(ret);
+#if defined(OB_BUILD_CDC_DISABLE_VSAG) && !defined(OB_BUILD_EMBED_MODE)
+ return ret;
+#else
return obvsag::estimate_memory(index_handler, row_count, is_build);
+#endif
+
}
int immutable_optimize(obvsag::VectorIndexPtr& index_handler)
{
+ int ret = OB_SUCCESS;
+#if defined(OB_BUILD_CDC_DISABLE_VSAG) && !defined(OB_BUILD_EMBED_MODE)
+ return ret;
+#else
return obvsag::immutable_optimize(index_handler);
+#endif
}
} //namespace obvectorlib
diff --git a/deps/oblib/src/lib/vector/ob_vsag_adaptor.cpp b/deps/oblib/src/lib/vector/ob_vsag_adaptor.cpp
index e2a6137ba..8fad38c8d 100644
--- a/deps/oblib/src/lib/vector/ob_vsag_adaptor.cpp
+++ b/deps/oblib/src/lib/vector/ob_vsag_adaptor.cpp
@@ -18,6 +18,7 @@
#include "ob_vsag_adaptor.h"
#include