From ace9dd6e1397cc52e5d66928dd13993e46622f1f Mon Sep 17 00:00:00 2001 From: Ally Heev Date: Wed, 24 Jun 2026 12:19:00 +0530 Subject: [PATCH 01/16] update macOs dev target; C++20 --- .github/workflows/ci.yml | 2 ++ .github/workflows/consumer-smoke-test.yml | 1 + .github/workflows/release.yml | 7 ++++--- CMakeLists.txt | 10 ++++++++++ examples/cmake-consumer/CMakeLists.txt | 2 +- recipes/lance-c/all/test_package/CMakeLists.txt | 2 +- tests/compile_and_run_test.rs | 2 +- 7 files changed, 20 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a089e5f..8bb7705 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -65,6 +65,8 @@ jobs: name: Tests (macOS) runs-on: macos-14 timeout-minutes: 30 + env: + MACOSX_DEPLOYMENT_TARGET: "11" steps: - uses: actions/checkout@v4 - uses: actions-rust-lang/setup-rust-toolchain@v1 diff --git a/.github/workflows/consumer-smoke-test.yml b/.github/workflows/consumer-smoke-test.yml index 7c649f7..c2d3f80 100644 --- a/.github/workflows/consumer-smoke-test.yml +++ b/.github/workflows/consumer-smoke-test.yml @@ -41,6 +41,7 @@ jobs: env: CC: clang CXX: clang++ + MACOSX_DEPLOYMENT_TARGET: "11" steps: - uses: actions/checkout@v4 - uses: actions-rust-lang/setup-rust-toolchain@v1 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 92d07a4..3cd3385 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -30,15 +30,16 @@ jobs: - target: aarch64-unknown-linux-gnu runner: ubuntu-24.04-arm os_label: linux - # x86_64-apple-darwin temporarily disabled: GitHub is deprecating - # macos-13 runners and jobs queue 24h+ before timing out. Restore - # this row once a macos-* Intel runner is reliably available again. + - target: x86_64-apple-darwin + runner: macos-15-intel + os_label: macos - target: aarch64-apple-darwin runner: macos-14 os_label: macos env: CC: clang CXX: clang++ + MACOSX_DEPLOYMENT_TARGET: "11" steps: - uses: actions/checkout@v4 - uses: actions-rust-lang/setup-rust-toolchain@v1 diff --git a/CMakeLists.txt b/CMakeLists.txt index 6960752..4d7e977 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,6 +7,10 @@ list(PREPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake") include(cargo-version) read_cargo_version("${CMAKE_CURRENT_LIST_DIR}/Cargo.toml" LANCE_C_VERSION) +if(APPLE AND NOT DEFINED CMAKE_OSX_DEPLOYMENT_TARGET) + set(CMAKE_OSX_DEPLOYMENT_TARGET "11" CACHE STRING "Minimum macOS deployment target") +endif() + project(LanceC VERSION ${LANCE_C_VERSION} DESCRIPTION "C/C++ bindings for the Lance columnar data format" @@ -14,6 +18,12 @@ project(LanceC LANGUAGES C CXX ) +if(NOT DEFINED CMAKE_CXX_STANDARD OR CMAKE_CXX_STANDARD LESS 20) + set(CMAKE_CXX_STANDARD 20) +endif() +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS OFF) + include(GNUInstallDirs) # ─── Options ───────────────────────────────────────────────────────────────── diff --git a/examples/cmake-consumer/CMakeLists.txt b/examples/cmake-consumer/CMakeLists.txt index aef3535..8d51bd0 100644 --- a/examples/cmake-consumer/CMakeLists.txt +++ b/examples/cmake-consumer/CMakeLists.txt @@ -7,5 +7,5 @@ project(lance_c_consumer LANGUAGES CXX) find_package(LanceC 0.1 REQUIRED) add_executable(consumer main.cpp) -target_compile_features(consumer PRIVATE cxx_std_17) +target_compile_features(consumer PRIVATE cxx_std_20) target_link_libraries(consumer PRIVATE LanceC::lance_c) diff --git a/recipes/lance-c/all/test_package/CMakeLists.txt b/recipes/lance-c/all/test_package/CMakeLists.txt index 34f50e2..8030dd8 100644 --- a/recipes/lance-c/all/test_package/CMakeLists.txt +++ b/recipes/lance-c/all/test_package/CMakeLists.txt @@ -4,5 +4,5 @@ project(test_package LANGUAGES CXX) find_package(LanceC CONFIG REQUIRED) add_executable(test_package test_package.cpp) -target_compile_features(test_package PRIVATE cxx_std_17) +target_compile_features(test_package PRIVATE cxx_std_20) target_link_libraries(test_package PRIVATE LanceC::lance_c) diff --git a/tests/compile_and_run_test.rs b/tests/compile_and_run_test.rs index d736d61..7e7626f 100644 --- a/tests/compile_and_run_test.rs +++ b/tests/compile_and_run_test.rs @@ -124,7 +124,7 @@ fn compile_cpp_test(source: &Path, output: &Path, include_dir: &Path, lib_path: let status = Command::new("c++") .args([ - "-std=c++17", + "-std=c++20", "-Wall", "-Wextra", "-o", From 45aed68dbc154e807d251e9eebaa485761b47ae7 Mon Sep 17 00:00:00 2001 From: Ally Heev Date: Wed, 24 Jun 2026 16:52:05 +0530 Subject: [PATCH 02/16] expand support for pcs with GLIBC ~ 2.28 --- .github/workflows/release.yml | 60 ++++++++++++++++++++++++++++++++--- CMakeLists.txt | 3 ++ 2 files changed, 58 insertions(+), 5 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 3cd3385..284840e 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -30,9 +30,9 @@ jobs: - target: aarch64-unknown-linux-gnu runner: ubuntu-24.04-arm os_label: linux - - target: x86_64-apple-darwin - runner: macos-15-intel - os_label: macos + # x86_64-apple-darwin temporarily disabled: GitHub is deprecating + # macos-13 runners and jobs queue 24h+ before timing out. Restore + # this row once a macos-* Intel runner is reliably available again. - target: aarch64-apple-darwin runner: macos-14 os_label: macos @@ -51,6 +51,11 @@ jobs: - name: Install protobuf (Linux) if: matrix.os_label == 'linux' run: sudo apt-get update && sudo apt-get install -y protobuf-compiler + - name: Setup Zig Toolchain (Linux Only) + if: matrix.os_label == 'linux' + uses: mlugg/setup-zig@v2 + with: + version: 0.13.0 - name: Install protobuf (macOS) if: matrix.os_label == 'macos' run: brew install protobuf @@ -62,10 +67,54 @@ jobs: else echo "version=${GITHUB_REF_NAME#v}" >>"$GITHUB_OUTPUT" fi - - name: Configure + build + - name: Configure CMake + shell: bash + run: | + CMAKE_FLAGS=( + "-DCMAKE_BUILD_TYPE=Release" + ) + + if [ "${{ matrix.os_label }}" = "linux" ]; then + case "${{ matrix.target }}" in + x86_64-unknown-linux-gnu) + ZIG_TARGET="x86_64-linux-gnu.2.28" + ;; + aarch64-unknown-linux-gnu) + ZIG_TARGET="aarch64-linux-gnu.2.28" + ;; + *) + echo "::error::Unsupported Linux target: ${{ matrix.target }}" + exit 1 + ;; + esac + CMAKE_FLAGS+=( + "-DCMAKE_C_COMPILER=zig;cc;-target;${ZIG_TARGET}" + "-DCMAKE_CXX_COMPILER=zig;c++;-target;${ZIG_TARGET}" + ) + fi + + mkdir build + cmake -S . -B build "${CMAKE_FLAGS[@]}" + - name: build run: | - cmake -S . -B build -DCMAKE_BUILD_TYPE=Release cmake --build build --parallel + - name: Verify GLIBC Baseline + if: matrix.os_label == 'linux' + run: | + TARGET_SO=$(find build -name "*.so" | head -n 1) + if [ -z "$TARGET_SO" ]; then + echo "::error::No shared library (.so) found to verify!" + exit 1 + fi + + echo "Verifying file: $TARGET_SO" + objdump -p "$TARGET_SO" | grep -A 10 "Version References:" + + # Fails the pipeline if any leaking symbols match GLIBC 2.29 through 2.39+ + if objdump -p "$TARGET_SO" | grep -E "GLIBC_2\.(2[9]|3[0-9]|[4-9][0-9])" -q; then + echo "::error::GLIBC Leak Detected! The binary contains symbols newer than GLIBC 2.28." + exit 1 + fi - name: Install to staging prefix run: cmake --install build --prefix stage - name: Tar @@ -93,6 +142,7 @@ jobs: name: Publish GitHub Release needs: build runs-on: ubuntu-24.04 + timeout-minutes: 15 if: startsWith(github.ref, 'refs/tags/v') steps: - uses: actions/checkout@v4 diff --git a/CMakeLists.txt b/CMakeLists.txt index 4d7e977..aa56ec1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -23,6 +23,9 @@ if(NOT DEFINED CMAKE_CXX_STANDARD OR CMAKE_CXX_STANDARD LESS 20) endif() set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) +set(CMAKE_C_VISIBILITY_PRESET hidden) +set(CMAKE_CXX_VISIBILITY_PRESET hidden) +set(CMAKE_VISIBILITY_INLINES_HIDDEN ON) include(GNUInstallDirs) From 5f51766bdbdff888a40fbd18318119f79ae53e68 Mon Sep 17 00:00:00 2001 From: Ally Heev Date: Wed, 24 Jun 2026 19:12:02 +0530 Subject: [PATCH 03/16] add supported build tools --- README.md | 74 +++++++++---------------------------------------------- 1 file changed, 11 insertions(+), 63 deletions(-) diff --git a/README.md b/README.md index 893589c..3f9b835 100644 --- a/README.md +++ b/README.md @@ -6,67 +6,15 @@ The C/C++ binding to [Lance](https://github.com/lancedb/lance), providing native - **C++ wrappers:** [`include/lance/lance.hpp`](include/lance/lance.hpp) (header-only, RAII, exceptions) - **Data exchange:** [Arrow C Data Interface](https://arrow.apache.org/docs/format/CDataInterface.html) for zero-copy interop -## Roadmap - -Based on the [liblance RFC](https://github.com/lance-format/lance/discussions/6035). - -### Phase 1: Core Read Path + C++ Wrappers (MVP) - -| Status | Component | Description | -|--------|-----------|-------------| -| [x] | Infrastructure | `lance-c` crate with Cargo.toml, Tokio runtime initialization | -| [x] | Error handling | Thread-local error codes/messages for cross-FFI safety | -| [x] | C header | `lance.h` with Arrow C Data Interface structs | -| [x] | Dataset operations | Open/close with URI + storage options + version support | -| [x] | Schema export | Arrow C Data Interface for zero-copy schema exchange | -| [x] | Scanner builder | Column projection, SQL filters, limit/offset, batch size, row ID, fragment filtering | -| [x] | ArrowArrayStream export | `lance_scanner_to_arrow_stream()` blocking API | -| [x] | Batch iteration | `lance_scanner_next()` blocking function | -| [x] | Poll + waker iteration | `lance_scanner_poll_next()` for async engines (Velox, Presto) | -| [x] | Random access | Index-based row retrieval via `lance_dataset_take()` | -| [x] | C++ wrappers | Header-only RAII library (`lance::Dataset`, `lance::Scanner`, `lance::Batch`) | -| [x] | Builder pattern | Fluent Scanner API (`.limit().offset().batch_size().with_row_id()`) | - -### Phase 2: Vector Search & Indexing - -| Status | Component | Description | -|--------|-----------|-------------| -| [x] | Vector search | Nearest-neighbor via scanner with metric/k/nprobes | -| [x] | Full-text search | FTS queries through scanner interface | -| [x] | Vector index creation | IVF_PQ, IVF_FLAT, IVF_SQ, HNSW variants | -| [x] | Scalar index creation | BTree, Bitmap, Inverted, Label-List indexes | -| [x] | Index management | List and drop index operations | -| [x] | C++ wrappers | `create_vector_index()` and `create_scalar_index()` methods | - -### Phase 3: Write Path & Mutations - -| Status | Component | Description | -|--------|-----------|-------------| -| [x] | Dataset write | Create / append / overwrite from ArrowArrayStream via `lance_dataset_write()`; tunable variant `lance_dataset_write_with_params()` for file/row-group sizing, Lance format version, and stable row IDs | -| [x] | Fragment writer | Batch-at-a-time fragment file writing (no commit) via `lance_write_fragments()` | -| [x] | Delete operations | Predicate-based deletion via `lance_dataset_delete()` | -| [x] | Update operations | Expression-based row updates via `lance_dataset_update()` | -| [x] | Merge-insert | Upsert via configurable when-matched / when-not-matched policies with `lance_dataset_merge_insert()` | -| [x] | Schema evolution | Add columns via SQL / all-null / `ArrowArrayStream` with `lance_dataset_add_columns_*()`, drop via `lance_dataset_drop_columns()`, rename / retype / set nullability via `lance_dataset_alter_columns()` | -| [x] | Version management | List via `lance_dataset_versions()`, rollback via `lance_dataset_restore()`, checkout via `lance_dataset_open(uri, opts, version)` | - -### Phase 4: Advanced Features - -| Status | Component | Description | -|--------|-----------|-------------| -| [x] | Fragment-level access | Fragment enumeration, ID listing, scanner fragment filtering | -| [x] | Compaction | Fragment consolidation via `lance_dataset_compact_files()` | -| [x] | Statistics export | Per-field compressed on-disk size for query planning via `lance_dataset_calculate_data_stats()` | -| [x] | Cloud storage | S3, GCS, Azure via storage options pass-through | -| [x] | Package distribution | vcpkg and Conan recipe packaging | - -### Additional (not in RFC) - -| Status | Component | Description | -|--------|-----------|-------------| -| [x] | Async scan | Callback-based `lance_scanner_scan_async()` for non-blocking scans | -| [x] | Dataset metadata | `lance_dataset_version()`, `lance_dataset_count_rows()`, `lance_dataset_latest_version()` | -| [x] | Substrait filter pushdown | `lance_scanner_set_substrait_filter()` accepts a serialized Substrait `ExtendedExpression` (preferred over SQL strings for query engines) | +## Supported build targets + +| Component | Target / minimum | +|-----------|------------------| +| CMake | 3.22+ | +| C++ | C++20 | +| GLIBC | 2.28 | +| Clang | Clang 18; Apple Clang 15 | +| macOS | 11.0 | ## Building @@ -81,11 +29,11 @@ cargo build --release Produces `target/release/liblance_c.{so,dylib,dll}` and a `liblance_c.a`. Headers stay in `include/lance/`. -### From source via CMake (C/C++ developers) +### From source via CMake (C/C++ developers and packagers) ```bash cmake -S . -B build -DCMAKE_BUILD_TYPE=Release -cmake --build build +cmake --build build --parallel cmake --install build --prefix /your/prefix ``` From 015601b644074cb4bc177ade8ecd8629721ccd03 Mon Sep 17 00:00:00 2001 From: Ally Heev Date: Wed, 24 Jun 2026 19:12:38 +0530 Subject: [PATCH 04/16] make consumer-smoke-test config same as release --- .github/workflows/consumer-smoke-test.yml | 36 +++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/.github/workflows/consumer-smoke-test.yml b/.github/workflows/consumer-smoke-test.yml index c2d3f80..75d80d0 100644 --- a/.github/workflows/consumer-smoke-test.yml +++ b/.github/workflows/consumer-smoke-test.yml @@ -49,12 +49,44 @@ jobs: - name: Install protobuf-compiler (Linux) if: matrix.os_label == 'linux' run: sudo apt-get update && sudo apt-get install -y protobuf-compiler + - name: Setup Zig Toolchain (Linux Only) + if: matrix.os_label == 'linux' + uses: mlugg/setup-zig@v2 + with: + version: 0.13.0 - name: Install protobuf (macOS) if: matrix.os_label == 'macos' run: brew install protobuf - - name: Configure + build + install lance-c + - name: Configure CMake + shell: bash + run: | + CMAKE_FLAGS=( + "-DCMAKE_BUILD_TYPE=Release" + ) + + if [ "${{ matrix.os_label }}" = "linux" ]; then + case "${{ matrix.target }}" in + x86_64-unknown-linux-gnu) + ZIG_TARGET="x86_64-linux-gnu.2.28" + ;; + aarch64-unknown-linux-gnu) + ZIG_TARGET="aarch64-linux-gnu.2.28" + ;; + *) + echo "::error::Unsupported Linux target: ${{ matrix.target }}" + exit 1 + ;; + esac + CMAKE_FLAGS+=( + "-DCMAKE_C_COMPILER=zig;cc;-target;${ZIG_TARGET}" + "-DCMAKE_CXX_COMPILER=zig;c++;-target;${ZIG_TARGET}" + ) + fi + + mkdir build + cmake -S . -B build "${CMAKE_FLAGS[@]}" + - name: build + install lance-c run: | - cmake -S . -B build -DCMAKE_BUILD_TYPE=Release cmake --build build cmake --install build --prefix "$PWD/_install" - name: Build consumer example against the install From 7808b19dab912ea3d1165acd4ddbaebc8f60b235 Mon Sep 17 00:00:00 2001 From: Ally Heev Date: Thu, 25 Jun 2026 12:04:55 +0530 Subject: [PATCH 05/16] fix misc errors --- .github/actions/configure-cmake/action.yml | 62 ++++++++++++++++++ .../actions/verify-glibc-baseline/action.yml | 42 ++++++++++++ .github/baseline.env | 2 + .github/workflows/ci.yml | 9 ++- .github/workflows/consumer-smoke-test.yml | 49 ++++++-------- .github/workflows/release.yml | 64 ++++++------------- CMakeLists.txt | 8 ++- README.md | 6 +- cmake/baseline.cmake | 24 +++++++ 9 files changed, 188 insertions(+), 78 deletions(-) create mode 100644 .github/actions/configure-cmake/action.yml create mode 100644 .github/actions/verify-glibc-baseline/action.yml create mode 100644 .github/baseline.env create mode 100644 cmake/baseline.cmake diff --git a/.github/actions/configure-cmake/action.yml b/.github/actions/configure-cmake/action.yml new file mode 100644 index 0000000..956c2e0 --- /dev/null +++ b/.github/actions/configure-cmake/action.yml @@ -0,0 +1,62 @@ +name: Configure CMake +description: Configure LanceC with the appropriate compiler setup for the current target +inputs: + target: + description: architecture + required: true + os_label: + description: Operating-system label + required: true + build_dir: + description: CMake build directory + required: false + default: build + build_type: + description: CMake build type + required: false + default: Release +runs: + using: composite + steps: + - name: Configure CMake + shell: bash + run: | + build_dir="${{ inputs.build_dir }}" + CMAKE_FLAGS=( + "-DCMAKE_BUILD_TYPE=${{ inputs.build_type }}" + ) + + if [ "${{ inputs.os_label }}" = "linux" ]; then + baseline="${GLIBC_BASELINE:?Baseline env not loaded}" + case "${{ inputs.target }}" in + x86_64-unknown-linux-gnu) + zig_target="x86_64-linux-gnu.${baseline}" + ;; + aarch64-unknown-linux-gnu) + zig_target="aarch64-linux-gnu.${baseline}" + ;; + *) + echo "::error::Unsupported Linux target: ${{ inputs.target }}" + exit 1 + ;; + esac + + wrapper_dir="${RUNNER_TEMP}/zig-linkers/${{ inputs.target }}" + mkdir -p "$wrapper_dir" + + printf '%s\n' '#!/usr/bin/env bash' \ + "exec zig cc -target \"$zig_target\" \"\$@\"" >"$wrapper_dir/cc" + printf '%s\n' '#!/usr/bin/env bash' \ + "exec zig c++ -target \"$zig_target\" \"\$@\"" >"$wrapper_dir/cxx" + chmod +x "$wrapper_dir/cc" "$wrapper_dir/cxx" + + echo "Resolved linker wrapper: $wrapper_dir/cc" + echo "Resolved C++ wrapper: $wrapper_dir/cxx" + + CMAKE_FLAGS+=( + "-DCMAKE_C_COMPILER=$wrapper_dir/cc" + "-DCMAKE_CXX_COMPILER=$wrapper_dir/cxx" + ) + fi + + cmake -S . -B "$build_dir" "${CMAKE_FLAGS[@]}" diff --git a/.github/actions/verify-glibc-baseline/action.yml b/.github/actions/verify-glibc-baseline/action.yml new file mode 100644 index 0000000..b7aa490 --- /dev/null +++ b/.github/actions/verify-glibc-baseline/action.yml @@ -0,0 +1,42 @@ +name: Verify GLIBC baseline +description: Check a built Linux shared library for symbols newer than the configured baseline +inputs: + search_root: + description: Directory to search for the shared library + required: false + default: stage + library_name: + description: Shared library filename to verify + required: false + default: liblance_c.so +runs: + using: composite + steps: + - name: Verify GLIBC baseline + shell: bash + run: | + search_root="${{ inputs.search_root }}" + library_name="${{ inputs.library_name }}" + baseline="${GLIBC_BASELINE:?Baseline env not loaded}" + + target_so=$(find "$search_root" -type f -name "$library_name" -print -quit) + if [ -z "$target_so" ]; then + echo "::error::No shared library (${library_name}) found under ${search_root}!" + exit 1 + fi + + echo "Verifying file: $target_so" + + objdump_output=$(objdump -p "$target_so") + printf '%s\n' "$objdump_output" | grep -A 10 "Version References:" || true + + version_gt() { + [ "$(printf '%s\n%s\n' "$2" "$1" | sort -V | tail -n1)" = "$1" ] && [ "$1" != "$2" ] + } + + while IFS= read -r version; do + if version_gt "$version" "$baseline"; then + echo "::error::GLIBC Leak Detected! The binary contains symbols newer than GLIBC ${baseline}." + exit 1 + fi + done < <(printf '%s\n' "$objdump_output" | grep -oE 'GLIBC_[0-9]+(\.[0-9]+)+' | sed 's/^GLIBC_//' | sort -Vu) diff --git a/.github/baseline.env b/.github/baseline.env new file mode 100644 index 0000000..79beda6 --- /dev/null +++ b/.github/baseline.env @@ -0,0 +1,2 @@ +MACOSX_DEPLOYMENT_TARGET=11 +GLIBC_BASELINE=2.28 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8bb7705..abccf0c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -65,10 +65,15 @@ jobs: name: Tests (macOS) runs-on: macos-14 timeout-minutes: 30 - env: - MACOSX_DEPLOYMENT_TARGET: "11" steps: - uses: actions/checkout@v4 + - name: Load baseline floors + shell: bash + run: | + set -a + source .github/baseline.env + set +a + echo "MACOSX_DEPLOYMENT_TARGET=$MACOSX_DEPLOYMENT_TARGET" >>"$GITHUB_ENV" - uses: actions-rust-lang/setup-rust-toolchain@v1 - uses: Swatinem/rust-cache@v2 - name: Install dependencies diff --git a/.github/workflows/consumer-smoke-test.yml b/.github/workflows/consumer-smoke-test.yml index 75d80d0..c300cd5 100644 --- a/.github/workflows/consumer-smoke-test.yml +++ b/.github/workflows/consumer-smoke-test.yml @@ -36,14 +36,25 @@ jobs: include: - runner: ubuntu-24.04 os_label: linux + target: x86_64-unknown-linux-gnu - runner: macos-14 os_label: macos + target: aarch64-apple-darwin env: CC: clang CXX: clang++ - MACOSX_DEPLOYMENT_TARGET: "11" steps: - uses: actions/checkout@v4 + - name: Load baseline floors + shell: bash + run: | + set -a + source .github/baseline.env + set +a + { + echo "MACOSX_DEPLOYMENT_TARGET=$MACOSX_DEPLOYMENT_TARGET" + echo "GLIBC_BASELINE=$GLIBC_BASELINE" + } >>"$GITHUB_ENV" - uses: actions-rust-lang/setup-rust-toolchain@v1 - uses: Swatinem/rust-cache@v2 - name: Install protobuf-compiler (Linux) @@ -58,37 +69,19 @@ jobs: if: matrix.os_label == 'macos' run: brew install protobuf - name: Configure CMake - shell: bash - run: | - CMAKE_FLAGS=( - "-DCMAKE_BUILD_TYPE=Release" - ) - - if [ "${{ matrix.os_label }}" = "linux" ]; then - case "${{ matrix.target }}" in - x86_64-unknown-linux-gnu) - ZIG_TARGET="x86_64-linux-gnu.2.28" - ;; - aarch64-unknown-linux-gnu) - ZIG_TARGET="aarch64-linux-gnu.2.28" - ;; - *) - echo "::error::Unsupported Linux target: ${{ matrix.target }}" - exit 1 - ;; - esac - CMAKE_FLAGS+=( - "-DCMAKE_C_COMPILER=zig;cc;-target;${ZIG_TARGET}" - "-DCMAKE_CXX_COMPILER=zig;c++;-target;${ZIG_TARGET}" - ) - fi - - mkdir build - cmake -S . -B build "${CMAKE_FLAGS[@]}" + uses: ./.github/actions/configure-cmake + with: + target: ${{ matrix.target }} + os_label: ${{ matrix.os_label }} - name: build + install lance-c run: | cmake --build build cmake --install build --prefix "$PWD/_install" + - name: Verify GLIBC Baseline + if: matrix.os_label == 'linux' + uses: ./.github/actions/verify-glibc-baseline + with: + search_root: ${{ github.workspace }}/_install - name: Build consumer example against the install run: | cmake -S examples/cmake-consumer -B consumer-build \ diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 284840e..6953256 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -39,9 +39,18 @@ jobs: env: CC: clang CXX: clang++ - MACOSX_DEPLOYMENT_TARGET: "11" steps: - uses: actions/checkout@v4 + - name: Load baseline floors + shell: bash + run: | + set -a + source .github/baseline.env + set +a + { + echo "MACOSX_DEPLOYMENT_TARGET=$MACOSX_DEPLOYMENT_TARGET" + echo "GLIBC_BASELINE=$GLIBC_BASELINE" + } >>"$GITHUB_ENV" - uses: actions-rust-lang/setup-rust-toolchain@v1 with: target: ${{ matrix.target }} @@ -68,55 +77,20 @@ jobs: echo "version=${GITHUB_REF_NAME#v}" >>"$GITHUB_OUTPUT" fi - name: Configure CMake - shell: bash - run: | - CMAKE_FLAGS=( - "-DCMAKE_BUILD_TYPE=Release" - ) - - if [ "${{ matrix.os_label }}" = "linux" ]; then - case "${{ matrix.target }}" in - x86_64-unknown-linux-gnu) - ZIG_TARGET="x86_64-linux-gnu.2.28" - ;; - aarch64-unknown-linux-gnu) - ZIG_TARGET="aarch64-linux-gnu.2.28" - ;; - *) - echo "::error::Unsupported Linux target: ${{ matrix.target }}" - exit 1 - ;; - esac - CMAKE_FLAGS+=( - "-DCMAKE_C_COMPILER=zig;cc;-target;${ZIG_TARGET}" - "-DCMAKE_CXX_COMPILER=zig;c++;-target;${ZIG_TARGET}" - ) - fi - - mkdir build - cmake -S . -B build "${CMAKE_FLAGS[@]}" + uses: ./.github/actions/configure-cmake + with: + target: ${{ matrix.target }} + os_label: ${{ matrix.os_label }} - name: build run: | cmake --build build --parallel - - name: Verify GLIBC Baseline - if: matrix.os_label == 'linux' - run: | - TARGET_SO=$(find build -name "*.so" | head -n 1) - if [ -z "$TARGET_SO" ]; then - echo "::error::No shared library (.so) found to verify!" - exit 1 - fi - - echo "Verifying file: $TARGET_SO" - objdump -p "$TARGET_SO" | grep -A 10 "Version References:" - - # Fails the pipeline if any leaking symbols match GLIBC 2.29 through 2.39+ - if objdump -p "$TARGET_SO" | grep -E "GLIBC_2\.(2[9]|3[0-9]|[4-9][0-9])" -q; then - echo "::error::GLIBC Leak Detected! The binary contains symbols newer than GLIBC 2.28." - exit 1 - fi - name: Install to staging prefix run: cmake --install build --prefix stage + - name: Verify GLIBC Baseline + if: matrix.os_label == 'linux' + uses: ./.github/actions/verify-glibc-baseline + with: + search_root: ${{ github.workspace }}/stage - name: Tar id: pack run: | diff --git a/CMakeLists.txt b/CMakeLists.txt index aa56ec1..fc33e8a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,10 +5,13 @@ cmake_minimum_required(VERSION 3.22) list(PREPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake") include(cargo-version) +include(baseline) read_cargo_version("${CMAKE_CURRENT_LIST_DIR}/Cargo.toml" LANCE_C_VERSION) +lance_c_load_baseline_env("${CMAKE_CURRENT_LIST_DIR}/.github/baseline.env") + if(APPLE AND NOT DEFINED CMAKE_OSX_DEPLOYMENT_TARGET) - set(CMAKE_OSX_DEPLOYMENT_TARGET "11" CACHE STRING "Minimum macOS deployment target") + set(CMAKE_OSX_DEPLOYMENT_TARGET "${MACOSX_DEPLOYMENT_TARGET}" CACHE STRING "Minimum macOS deployment target") endif() project(LanceC @@ -55,6 +58,9 @@ if(NOT LANCE_C_USE_PREBUILT) CRATE_TYPES staticlib cdylib PROFILE release ) + if(APPLE) + corrosion_set_env_vars(lance-c "MACOSX_DEPLOYMENT_TARGET=${CMAKE_OSX_DEPLOYMENT_TARGET}") + endif() endif() # Imported targets and install rules are added in subsequent tasks. diff --git a/README.md b/README.md index 3f9b835..3812cd1 100644 --- a/README.md +++ b/README.md @@ -12,9 +12,9 @@ The C/C++ binding to [Lance](https://github.com/lancedb/lance), providing native |-----------|------------------| | CMake | 3.22+ | | C++ | C++20 | -| GLIBC | 2.28 | +| GLIBC baseline | `.github/baseline.env` (`GLIBC_BASELINE`) | | Clang | Clang 18; Apple Clang 15 | -| macOS | 11.0 | +| macOS | `.github/baseline.env` (`MACOSX_DEPLOYMENT_TARGET`) | ## Building @@ -48,6 +48,8 @@ target_link_libraries(myapp PRIVATE LanceC::lance_c) See [`examples/cmake-consumer/`](examples/cmake-consumer/) for a minimal working example. +Baseline values are defined once in [`.github/baseline.env`](.github/baseline.env) and loaded by CI, release workflows, and CMake. + ### vcpkg ```bash diff --git a/cmake/baseline.cmake b/cmake/baseline.cmake new file mode 100644 index 0000000..4768feb --- /dev/null +++ b/cmake/baseline.cmake @@ -0,0 +1,24 @@ +# SPDX-License-Identifier: Apache-2.0 +# SPDX-FileCopyrightText: Copyright The Lance Authors + +include_guard(GLOBAL) + +function(lance_c_load_baseline_env env_file) + if(NOT EXISTS "${env_file}") + message(FATAL_ERROR "Missing baseline env file: ${env_file}") + endif() + + file(STRINGS "${env_file}" _baseline_lines) + foreach(_line IN LISTS _baseline_lines) + string(STRIP "${_line}" _line) + if(_line STREQUAL "" OR _line MATCHES "^#") + continue() + endif() + + if(NOT _line MATCHES "^([A-Za-z_][A-Za-z0-9_]*)=(.*)$") + message(FATAL_ERROR "Invalid baseline line: ${_line}") + endif() + + set("${CMAKE_MATCH_1}" "${CMAKE_MATCH_2}" PARENT_SCOPE) + endforeach() +endfunction() From f99ac4f39d04af6d8d135fbaf775b31b13fe66db Mon Sep 17 00:00:00 2001 From: Ally Heev Date: Thu, 25 Jun 2026 12:12:35 +0530 Subject: [PATCH 06/16] fix create name --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index fc33e8a..bca9c56 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -59,7 +59,7 @@ if(NOT LANCE_C_USE_PREBUILT) PROFILE release ) if(APPLE) - corrosion_set_env_vars(lance-c "MACOSX_DEPLOYMENT_TARGET=${CMAKE_OSX_DEPLOYMENT_TARGET}") + corrosion_set_env_vars(lance_c "MACOSX_DEPLOYMENT_TARGET=${CMAKE_OSX_DEPLOYMENT_TARGET}") endif() endif() From 8dfa3435bf467f140fa884e8a60b93e7a7b0e579 Mon Sep 17 00:00:00 2001 From: Ally Heev Date: Thu, 25 Jun 2026 16:09:36 +0530 Subject: [PATCH 07/16] create glibc check override --- .../actions/verify-glibc-baseline/action.yml | 20 ++++++++++++++++--- .github/workflows/release.yml | 13 +++++++++++- CMakeLists.txt | 7 +++++++ 3 files changed, 36 insertions(+), 4 deletions(-) diff --git a/.github/actions/verify-glibc-baseline/action.yml b/.github/actions/verify-glibc-baseline/action.yml index b7aa490..30d70c2 100644 --- a/.github/actions/verify-glibc-baseline/action.yml +++ b/.github/actions/verify-glibc-baseline/action.yml @@ -9,6 +9,10 @@ inputs: description: Shared library filename to verify required: false default: liblance_c.so + workflow_type: + description: Workflow type + required: false + default: dev runs: using: composite steps: @@ -28,15 +32,25 @@ runs: echo "Verifying file: $target_so" objdump_output=$(objdump -p "$target_so") - printf '%s\n' "$objdump_output" | grep -A 10 "Version References:" || true + printf '%s\n' "$objdump_output" | grep -A 10 "Version References: (truncated to first 10)" || true version_gt() { - [ "$(printf '%s\n%s\n' "$2" "$1" | sort -V | tail -n1)" = "$1" ] && [ "$1" != "$2" ] + [ "$1" = "$2" ] && return 1 + [ "$(printf '%s\n%s\n' "$1" "$2" | sort -V | tail -n1)" = "$1" ] } while IFS= read -r version; do if version_gt "$version" "$baseline"; then - echo "::error::GLIBC Leak Detected! The binary contains symbols newer than GLIBC ${baseline}." + { + echo "## GLIBC baseline violation" + echo "One or more symbols in \`$SEARCH_ROOT\` exceed the **$GLIBC_BASELINE** floor." + echo "Run \`objdump -T | grep GLIBC_\` to identify the offending symbols." + + if [ "${{ inputs.workflow_type }}" = "release" ]; then + echo "To override in an emergency, re-dispatch with \`skip_glibc_check=true\`." + fi + } >> "$GITHUB_STEP_SUMMARY" + echo "::error title=GLIBC baseline violated::See job summary for details." exit 1 fi done < <(printf '%s\n' "$objdump_output" | grep -oE 'GLIBC_[0-9]+(\.[0-9]+)+' | sed 's/^GLIBC_//' | sort -Vu) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 6953256..d39ebb1 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -8,6 +8,10 @@ on: version: description: "Version to build (without leading 'v')" required: true + skip_glibc_check: + description: "Emergency override: skip GLIBC baseline check (set to 'true' only if intentional)" + required: false + default: 'false' permissions: contents: write # needed for softprops/action-gh-release @@ -87,10 +91,17 @@ jobs: - name: Install to staging prefix run: cmake --install build --prefix stage - name: Verify GLIBC Baseline - if: matrix.os_label == 'linux' + if: matrix.os_label == 'linux' && inputs.skip_glibc_check != 'true' uses: ./.github/actions/verify-glibc-baseline with: search_root: ${{ github.workspace }}/stage + workflow_type: release + - name: Annotate skipped GLIBC check + if: matrix.os_label == 'linux' && inputs.skip_glibc_check == 'true' + run: | + echo "::warning title=GLIBC check skipped::skip_glibc_check=true was set — this release may exceed the GLIBC_BASELINE (${{ env.GLIBC_BASELINE }}) floor. Audit the artifact before distributing." + echo "## ⚠️ GLIBC baseline check was skipped" >> "$GITHUB_STEP_SUMMARY" + echo "skip_glibc_check=true was set on this run. The artifact may link symbols above **${{ env.GLIBC_BASELINE }}**." >> "$GITHUB_STEP_SUMMARY" - name: Tar id: pack run: | diff --git a/CMakeLists.txt b/CMakeLists.txt index bca9c56..3861be2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -21,11 +21,18 @@ project(LanceC LANGUAGES C CXX ) +if(NOT DEFINED CMAKE_C_STANDARD OR CMAKE_C_STANDARD LESS 11) + set(CMAKE_C_STANDARD 11) +endif() +set(CMAKE_C_STANDARD_REQUIRED ON) +set(CMAKE_C_EXTENSIONS OFF) + if(NOT DEFINED CMAKE_CXX_STANDARD OR CMAKE_CXX_STANDARD LESS 20) set(CMAKE_CXX_STANDARD 20) endif() set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) + set(CMAKE_C_VISIBILITY_PRESET hidden) set(CMAKE_CXX_VISIBILITY_PRESET hidden) set(CMAKE_VISIBILITY_INLINES_HIDDEN ON) From dbf7512e3f67cb565f4013154ce2f0cf47303c3c Mon Sep 17 00:00:00 2001 From: Ally Heev Date: Sun, 28 Jun 2026 10:02:30 +0530 Subject: [PATCH 08/16] fix cargo zig link error --- .github/actions/configure-cmake/action.yml | 27 +++++++++++++--------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/.github/actions/configure-cmake/action.yml b/.github/actions/configure-cmake/action.yml index 956c2e0..c7c97ba 100644 --- a/.github/actions/configure-cmake/action.yml +++ b/.github/actions/configure-cmake/action.yml @@ -44,19 +44,24 @@ runs: wrapper_dir="${RUNNER_TEMP}/zig-linkers/${{ inputs.target }}" mkdir -p "$wrapper_dir" - printf '%s\n' '#!/usr/bin/env bash' \ - "exec zig cc -target \"$zig_target\" \"\$@\"" >"$wrapper_dir/cc" - printf '%s\n' '#!/usr/bin/env bash' \ - "exec zig c++ -target \"$zig_target\" \"\$@\"" >"$wrapper_dir/cxx" - chmod +x "$wrapper_dir/cc" "$wrapper_dir/cxx" + # Single wrapper: used by rustc as linker only (via CARGO_TARGET_*_RUSTFLAGS). + # We do NOT set it as CMAKE_C_COMPILER — Corrosion propagates CMAKE_C_COMPILER + # as CC_ to all cargo C build scripts (aws-lc-sys, sha2-asm, etc.), + # and zig cc cannot handle LLVM-style flags those scripts pass (e.g. + # --target=x86_64-unknown-linux-gnu, -march=armv8-a+crypto). + printf '#!/usr/bin/env bash\nexec zig cc -target "%s" "$@"\n' "$zig_target" > "$wrapper_dir/cc" + chmod +x "$wrapper_dir/cc" - echo "Resolved linker wrapper: $wrapper_dir/cc" - echo "Resolved C++ wrapper: $wrapper_dir/cxx" + triple_upper=$(echo "${{ inputs.target }}" | tr '[:lower:]-' '[:upper:]_') - CMAKE_FLAGS+=( - "-DCMAKE_C_COMPILER=$wrapper_dir/cc" - "-DCMAKE_CXX_COMPILER=$wrapper_dir/cxx" - ) + { + # Tell rustc to use zig cc as linker only (not as CC for build scripts). + # Cargo C build deps (aws-lc-sys, sha2-asm, etc.) will use the system + # clang via CC/CXX set at the job level, avoiding zig's CPU/flag + # parsing issues (e.g. -march=armv8-a+crypto, --target= LLVM triples). + # linker-flavor=gcc means rustc will NOT pass --target to the linker. + echo "CARGO_TARGET_${triple_upper}_RUSTFLAGS=-C linker=$wrapper_dir/cc -C linker-flavor=gcc" + } >> "$GITHUB_ENV" fi cmake -S . -B "$build_dir" "${CMAKE_FLAGS[@]}" From e751eba572f2a5f4184f653fe4fad236e9469da0 Mon Sep 17 00:00:00 2001 From: Ally Heev Date: Sun, 28 Jun 2026 16:03:32 +0530 Subject: [PATCH 09/16] pin zig to a SHA --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index d39ebb1..2208085 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -66,7 +66,7 @@ jobs: run: sudo apt-get update && sudo apt-get install -y protobuf-compiler - name: Setup Zig Toolchain (Linux Only) if: matrix.os_label == 'linux' - uses: mlugg/setup-zig@v2 + uses: mlugg/setup-zig@d1434d08867e3ee9daa34448df10607b98908d29 # v2 with: version: 0.13.0 - name: Install protobuf (macOS) From a417a27b1b645dac669f20e781002ca2c3f00ad1 Mon Sep 17 00:00:00 2001 From: Ally Heev Date: Sun, 28 Jun 2026 16:03:56 +0530 Subject: [PATCH 10/16] fix template injection --- .github/actions/configure-cmake/action.yml | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/.github/actions/configure-cmake/action.yml b/.github/actions/configure-cmake/action.yml index c7c97ba..c15ba09 100644 --- a/.github/actions/configure-cmake/action.yml +++ b/.github/actions/configure-cmake/action.yml @@ -20,15 +20,21 @@ runs: steps: - name: Configure CMake shell: bash + env: + LANCE_TARGET: ${{ inputs.target }} + LANCE_OS_LABEL: ${{ inputs.os_label }} + LANCE_BUILD_DIR: ${{ inputs.build_dir }} + LANCE_BUILD_TYPE: ${{ inputs.build_type }} run: | - build_dir="${{ inputs.build_dir }}" + set -euo pipefail + build_dir="$LANCE_BUILD_DIR" CMAKE_FLAGS=( - "-DCMAKE_BUILD_TYPE=${{ inputs.build_type }}" + "-DCMAKE_BUILD_TYPE=$LANCE_BUILD_TYPE" ) - if [ "${{ inputs.os_label }}" = "linux" ]; then + if [ "$LANCE_OS_LABEL" = "linux" ]; then baseline="${GLIBC_BASELINE:?Baseline env not loaded}" - case "${{ inputs.target }}" in + case "$LANCE_TARGET" in x86_64-unknown-linux-gnu) zig_target="x86_64-linux-gnu.${baseline}" ;; @@ -36,12 +42,12 @@ runs: zig_target="aarch64-linux-gnu.${baseline}" ;; *) - echo "::error::Unsupported Linux target: ${{ inputs.target }}" + echo "::error::Unsupported Linux target: $LANCE_TARGET" exit 1 ;; esac - wrapper_dir="${RUNNER_TEMP}/zig-linkers/${{ inputs.target }}" + wrapper_dir="${RUNNER_TEMP}/zig-linkers/$LANCE_TARGET" mkdir -p "$wrapper_dir" # Single wrapper: used by rustc as linker only (via CARGO_TARGET_*_RUSTFLAGS). @@ -52,7 +58,7 @@ runs: printf '#!/usr/bin/env bash\nexec zig cc -target "%s" "$@"\n' "$zig_target" > "$wrapper_dir/cc" chmod +x "$wrapper_dir/cc" - triple_upper=$(echo "${{ inputs.target }}" | tr '[:lower:]-' '[:upper:]_') + triple_upper=$(echo "$LANCE_TARGET" | tr '[:lower:]-' '[:upper:]_') { # Tell rustc to use zig cc as linker only (not as CC for build scripts). From 888019e1d7582c8f5a54edcc8b8b8c041a7a0aee Mon Sep 17 00:00:00 2001 From: Ally Heev Date: Sun, 28 Jun 2026 16:04:06 +0530 Subject: [PATCH 11/16] ping zig to a SHA --- .github/workflows/consumer-smoke-test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/consumer-smoke-test.yml b/.github/workflows/consumer-smoke-test.yml index c300cd5..43c5a81 100644 --- a/.github/workflows/consumer-smoke-test.yml +++ b/.github/workflows/consumer-smoke-test.yml @@ -62,7 +62,7 @@ jobs: run: sudo apt-get update && sudo apt-get install -y protobuf-compiler - name: Setup Zig Toolchain (Linux Only) if: matrix.os_label == 'linux' - uses: mlugg/setup-zig@v2 + uses: mlugg/setup-zig@d1434d08867e3ee9daa34448df10607b98908d29 # v2 with: version: 0.13.0 - name: Install protobuf (macOS) From d2b96d9e1406cd82fe3d42c7d7bf0b9188890a3c Mon Sep 17 00:00:00 2001 From: Ally Heev Date: Sun, 28 Jun 2026 16:04:28 +0530 Subject: [PATCH 12/16] fix objdump --- .github/actions/verify-glibc-baseline/action.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/actions/verify-glibc-baseline/action.yml b/.github/actions/verify-glibc-baseline/action.yml index 30d70c2..92bda1d 100644 --- a/.github/actions/verify-glibc-baseline/action.yml +++ b/.github/actions/verify-glibc-baseline/action.yml @@ -31,8 +31,7 @@ runs: echo "Verifying file: $target_so" - objdump_output=$(objdump -p "$target_so") - printf '%s\n' "$objdump_output" | grep -A 10 "Version References: (truncated to first 10)" || true + objdump_output=$(objdump -T "$target_so") version_gt() { [ "$1" = "$2" ] && return 1 @@ -43,7 +42,7 @@ runs: if version_gt "$version" "$baseline"; then { echo "## GLIBC baseline violation" - echo "One or more symbols in \`$SEARCH_ROOT\` exceed the **$GLIBC_BASELINE** floor." + echo "One or more symbols in \`$search_root\` exceed the **$GLIBC_BASELINE** floor." echo "Run \`objdump -T | grep GLIBC_\` to identify the offending symbols." if [ "${{ inputs.workflow_type }}" = "release" ]; then From 23ea753767e80b4307221ded3b40349446fd38eb Mon Sep 17 00:00:00 2001 From: Ally Heev Date: Sun, 28 Jun 2026 16:18:51 +0530 Subject: [PATCH 13/16] linker override fix --- CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3861be2..ae2a13a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -64,6 +64,7 @@ if(NOT LANCE_C_USE_PREBUILT) CRATES lance-c CRATE_TYPES staticlib cdylib PROFILE release + NO_LINKER_OVERRIDE # linker is set via CARGO_TARGET_*_RUSTFLAGS in the CI action ) if(APPLE) corrosion_set_env_vars(lance_c "MACOSX_DEPLOYMENT_TARGET=${CMAKE_OSX_DEPLOYMENT_TARGET}") From cba57dec9abf33a069ddc63a33a3d412734dbd12 Mon Sep 17 00:00:00 2001 From: Ally Heev Date: Sun, 28 Jun 2026 16:42:18 +0530 Subject: [PATCH 14/16] print missing links --- .../actions/verify-glibc-baseline/action.yml | 38 +++++++++++-------- .github/workflows/consumer-smoke-test.yml | 2 +- .github/workflows/release.yml | 2 +- 3 files changed, 25 insertions(+), 17 deletions(-) diff --git a/.github/actions/verify-glibc-baseline/action.yml b/.github/actions/verify-glibc-baseline/action.yml index 92bda1d..7226b5e 100644 --- a/.github/actions/verify-glibc-baseline/action.yml +++ b/.github/actions/verify-glibc-baseline/action.yml @@ -38,18 +38,26 @@ runs: [ "$(printf '%s\n%s\n' "$1" "$2" | sort -V | tail -n1)" = "$1" ] } - while IFS= read -r version; do - if version_gt "$version" "$baseline"; then - { - echo "## GLIBC baseline violation" - echo "One or more symbols in \`$search_root\` exceed the **$GLIBC_BASELINE** floor." - echo "Run \`objdump -T | grep GLIBC_\` to identify the offending symbols." - - if [ "${{ inputs.workflow_type }}" = "release" ]; then - echo "To override in an emergency, re-dispatch with \`skip_glibc_check=true\`." - fi - } >> "$GITHUB_STEP_SUMMARY" - echo "::error title=GLIBC baseline violated::See job summary for details." - exit 1 - fi - done < <(printf '%s\n' "$objdump_output" | grep -oE 'GLIBC_[0-9]+(\.[0-9]+)+' | sed 's/^GLIBC_//' | sort -Vu) + violating_symbols=$(printf '%s\n' "$objdump_output" | grep -E 'GLIBC_[0-9]' | \ + awk '{for(i=1;i<=NF;i++) if($i~/GLIBC_[0-9]/) print $i, $(NF)}' | \ + while read -r ver sym; do + v=$(echo "$ver" | grep -oE '[0-9]+(\.[0-9]+)+') + if version_gt "$v" "$baseline"; then echo "$sym $ver"; fi + done | sort -u) + + if [ -n "$violating_symbols" ]; then + { + echo "## GLIBC baseline violation" + echo "One or more symbols in \`$target_so\` exceed the **$GLIBC_BASELINE** floor." + echo "" + echo "### Offending symbols" + echo "\`\`\`" + echo "$violating_symbols" + echo "\`\`\`" + if [ "${{ inputs.workflow_type }}" = "release" ]; then + echo "To override in an emergency, re-dispatch with \`skip_glibc_check=true\`." + fi + } >> "$GITHUB_STEP_SUMMARY" + echo "::error title=GLIBC baseline violated::See job summary for details." + exit 1 + fi diff --git a/.github/workflows/consumer-smoke-test.yml b/.github/workflows/consumer-smoke-test.yml index 43c5a81..ddc4b71 100644 --- a/.github/workflows/consumer-smoke-test.yml +++ b/.github/workflows/consumer-smoke-test.yml @@ -64,7 +64,7 @@ jobs: if: matrix.os_label == 'linux' uses: mlugg/setup-zig@d1434d08867e3ee9daa34448df10607b98908d29 # v2 with: - version: 0.13.0 + version: 0.14.0 - name: Install protobuf (macOS) if: matrix.os_label == 'macos' run: brew install protobuf diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 2208085..dfa3210 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -68,7 +68,7 @@ jobs: if: matrix.os_label == 'linux' uses: mlugg/setup-zig@d1434d08867e3ee9daa34448df10607b98908d29 # v2 with: - version: 0.13.0 + version: 0.14.0 - name: Install protobuf (macOS) if: matrix.os_label == 'macos' run: brew install protobuf From 47d276efab331025d0f98db76c4e83a39d0ce8ba Mon Sep 17 00:00:00 2001 From: Ally Heev Date: Sun, 28 Jun 2026 18:55:49 +0530 Subject: [PATCH 15/16] revert zig changes --- .github/actions/configure-cmake/action.yml | 73 ------------------- .../actions/verify-glibc-baseline/action.yml | 63 ---------------- .github/baseline.env | 1 - .github/workflows/consumer-smoke-test.yml | 21 +----- .github/workflows/release.yml | 30 +------- CMakeLists.txt | 1 - README.md | 2 +- cmake/baseline.cmake | 5 -- 8 files changed, 5 insertions(+), 191 deletions(-) delete mode 100644 .github/actions/configure-cmake/action.yml delete mode 100644 .github/actions/verify-glibc-baseline/action.yml diff --git a/.github/actions/configure-cmake/action.yml b/.github/actions/configure-cmake/action.yml deleted file mode 100644 index c15ba09..0000000 --- a/.github/actions/configure-cmake/action.yml +++ /dev/null @@ -1,73 +0,0 @@ -name: Configure CMake -description: Configure LanceC with the appropriate compiler setup for the current target -inputs: - target: - description: architecture - required: true - os_label: - description: Operating-system label - required: true - build_dir: - description: CMake build directory - required: false - default: build - build_type: - description: CMake build type - required: false - default: Release -runs: - using: composite - steps: - - name: Configure CMake - shell: bash - env: - LANCE_TARGET: ${{ inputs.target }} - LANCE_OS_LABEL: ${{ inputs.os_label }} - LANCE_BUILD_DIR: ${{ inputs.build_dir }} - LANCE_BUILD_TYPE: ${{ inputs.build_type }} - run: | - set -euo pipefail - build_dir="$LANCE_BUILD_DIR" - CMAKE_FLAGS=( - "-DCMAKE_BUILD_TYPE=$LANCE_BUILD_TYPE" - ) - - if [ "$LANCE_OS_LABEL" = "linux" ]; then - baseline="${GLIBC_BASELINE:?Baseline env not loaded}" - case "$LANCE_TARGET" in - x86_64-unknown-linux-gnu) - zig_target="x86_64-linux-gnu.${baseline}" - ;; - aarch64-unknown-linux-gnu) - zig_target="aarch64-linux-gnu.${baseline}" - ;; - *) - echo "::error::Unsupported Linux target: $LANCE_TARGET" - exit 1 - ;; - esac - - wrapper_dir="${RUNNER_TEMP}/zig-linkers/$LANCE_TARGET" - mkdir -p "$wrapper_dir" - - # Single wrapper: used by rustc as linker only (via CARGO_TARGET_*_RUSTFLAGS). - # We do NOT set it as CMAKE_C_COMPILER — Corrosion propagates CMAKE_C_COMPILER - # as CC_ to all cargo C build scripts (aws-lc-sys, sha2-asm, etc.), - # and zig cc cannot handle LLVM-style flags those scripts pass (e.g. - # --target=x86_64-unknown-linux-gnu, -march=armv8-a+crypto). - printf '#!/usr/bin/env bash\nexec zig cc -target "%s" "$@"\n' "$zig_target" > "$wrapper_dir/cc" - chmod +x "$wrapper_dir/cc" - - triple_upper=$(echo "$LANCE_TARGET" | tr '[:lower:]-' '[:upper:]_') - - { - # Tell rustc to use zig cc as linker only (not as CC for build scripts). - # Cargo C build deps (aws-lc-sys, sha2-asm, etc.) will use the system - # clang via CC/CXX set at the job level, avoiding zig's CPU/flag - # parsing issues (e.g. -march=armv8-a+crypto, --target= LLVM triples). - # linker-flavor=gcc means rustc will NOT pass --target to the linker. - echo "CARGO_TARGET_${triple_upper}_RUSTFLAGS=-C linker=$wrapper_dir/cc -C linker-flavor=gcc" - } >> "$GITHUB_ENV" - fi - - cmake -S . -B "$build_dir" "${CMAKE_FLAGS[@]}" diff --git a/.github/actions/verify-glibc-baseline/action.yml b/.github/actions/verify-glibc-baseline/action.yml deleted file mode 100644 index 7226b5e..0000000 --- a/.github/actions/verify-glibc-baseline/action.yml +++ /dev/null @@ -1,63 +0,0 @@ -name: Verify GLIBC baseline -description: Check a built Linux shared library for symbols newer than the configured baseline -inputs: - search_root: - description: Directory to search for the shared library - required: false - default: stage - library_name: - description: Shared library filename to verify - required: false - default: liblance_c.so - workflow_type: - description: Workflow type - required: false - default: dev -runs: - using: composite - steps: - - name: Verify GLIBC baseline - shell: bash - run: | - search_root="${{ inputs.search_root }}" - library_name="${{ inputs.library_name }}" - baseline="${GLIBC_BASELINE:?Baseline env not loaded}" - - target_so=$(find "$search_root" -type f -name "$library_name" -print -quit) - if [ -z "$target_so" ]; then - echo "::error::No shared library (${library_name}) found under ${search_root}!" - exit 1 - fi - - echo "Verifying file: $target_so" - - objdump_output=$(objdump -T "$target_so") - - version_gt() { - [ "$1" = "$2" ] && return 1 - [ "$(printf '%s\n%s\n' "$1" "$2" | sort -V | tail -n1)" = "$1" ] - } - - violating_symbols=$(printf '%s\n' "$objdump_output" | grep -E 'GLIBC_[0-9]' | \ - awk '{for(i=1;i<=NF;i++) if($i~/GLIBC_[0-9]/) print $i, $(NF)}' | \ - while read -r ver sym; do - v=$(echo "$ver" | grep -oE '[0-9]+(\.[0-9]+)+') - if version_gt "$v" "$baseline"; then echo "$sym $ver"; fi - done | sort -u) - - if [ -n "$violating_symbols" ]; then - { - echo "## GLIBC baseline violation" - echo "One or more symbols in \`$target_so\` exceed the **$GLIBC_BASELINE** floor." - echo "" - echo "### Offending symbols" - echo "\`\`\`" - echo "$violating_symbols" - echo "\`\`\`" - if [ "${{ inputs.workflow_type }}" = "release" ]; then - echo "To override in an emergency, re-dispatch with \`skip_glibc_check=true\`." - fi - } >> "$GITHUB_STEP_SUMMARY" - echo "::error title=GLIBC baseline violated::See job summary for details." - exit 1 - fi diff --git a/.github/baseline.env b/.github/baseline.env index 79beda6..deb034b 100644 --- a/.github/baseline.env +++ b/.github/baseline.env @@ -1,2 +1 @@ MACOSX_DEPLOYMENT_TARGET=11 -GLIBC_BASELINE=2.28 diff --git a/.github/workflows/consumer-smoke-test.yml b/.github/workflows/consumer-smoke-test.yml index ddc4b71..a06a407 100644 --- a/.github/workflows/consumer-smoke-test.yml +++ b/.github/workflows/consumer-smoke-test.yml @@ -36,10 +36,8 @@ jobs: include: - runner: ubuntu-24.04 os_label: linux - target: x86_64-unknown-linux-gnu - runner: macos-14 os_label: macos - target: aarch64-apple-darwin env: CC: clang CXX: clang++ @@ -53,35 +51,20 @@ jobs: set +a { echo "MACOSX_DEPLOYMENT_TARGET=$MACOSX_DEPLOYMENT_TARGET" - echo "GLIBC_BASELINE=$GLIBC_BASELINE" } >>"$GITHUB_ENV" - uses: actions-rust-lang/setup-rust-toolchain@v1 - uses: Swatinem/rust-cache@v2 - name: Install protobuf-compiler (Linux) if: matrix.os_label == 'linux' run: sudo apt-get update && sudo apt-get install -y protobuf-compiler - - name: Setup Zig Toolchain (Linux Only) - if: matrix.os_label == 'linux' - uses: mlugg/setup-zig@d1434d08867e3ee9daa34448df10607b98908d29 # v2 - with: - version: 0.14.0 - name: Install protobuf (macOS) if: matrix.os_label == 'macos' run: brew install protobuf - - name: Configure CMake - uses: ./.github/actions/configure-cmake - with: - target: ${{ matrix.target }} - os_label: ${{ matrix.os_label }} - - name: build + install lance-c + - name: Configure + build + install lance-c run: | + cmake -S . -B build -DCMAKE_BUILD_TYPE=Release cmake --build build cmake --install build --prefix "$PWD/_install" - - name: Verify GLIBC Baseline - if: matrix.os_label == 'linux' - uses: ./.github/actions/verify-glibc-baseline - with: - search_root: ${{ github.workspace }}/_install - name: Build consumer example against the install run: | cmake -S examples/cmake-consumer -B consumer-build \ diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index dfa3210..84f33d2 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -8,10 +8,6 @@ on: version: description: "Version to build (without leading 'v')" required: true - skip_glibc_check: - description: "Emergency override: skip GLIBC baseline check (set to 'true' only if intentional)" - required: false - default: 'false' permissions: contents: write # needed for softprops/action-gh-release @@ -53,7 +49,6 @@ jobs: set +a { echo "MACOSX_DEPLOYMENT_TARGET=$MACOSX_DEPLOYMENT_TARGET" - echo "GLIBC_BASELINE=$GLIBC_BASELINE" } >>"$GITHUB_ENV" - uses: actions-rust-lang/setup-rust-toolchain@v1 with: @@ -64,11 +59,6 @@ jobs: - name: Install protobuf (Linux) if: matrix.os_label == 'linux' run: sudo apt-get update && sudo apt-get install -y protobuf-compiler - - name: Setup Zig Toolchain (Linux Only) - if: matrix.os_label == 'linux' - uses: mlugg/setup-zig@d1434d08867e3ee9daa34448df10607b98908d29 # v2 - with: - version: 0.14.0 - name: Install protobuf (macOS) if: matrix.os_label == 'macos' run: brew install protobuf @@ -80,28 +70,12 @@ jobs: else echo "version=${GITHUB_REF_NAME#v}" >>"$GITHUB_OUTPUT" fi - - name: Configure CMake - uses: ./.github/actions/configure-cmake - with: - target: ${{ matrix.target }} - os_label: ${{ matrix.os_label }} - - name: build + - name: Configure + build run: | + cmake -S . -B build -DCMAKE_BUILD_TYPE=Release cmake --build build --parallel - name: Install to staging prefix run: cmake --install build --prefix stage - - name: Verify GLIBC Baseline - if: matrix.os_label == 'linux' && inputs.skip_glibc_check != 'true' - uses: ./.github/actions/verify-glibc-baseline - with: - search_root: ${{ github.workspace }}/stage - workflow_type: release - - name: Annotate skipped GLIBC check - if: matrix.os_label == 'linux' && inputs.skip_glibc_check == 'true' - run: | - echo "::warning title=GLIBC check skipped::skip_glibc_check=true was set — this release may exceed the GLIBC_BASELINE (${{ env.GLIBC_BASELINE }}) floor. Audit the artifact before distributing." - echo "## ⚠️ GLIBC baseline check was skipped" >> "$GITHUB_STEP_SUMMARY" - echo "skip_glibc_check=true was set on this run. The artifact may link symbols above **${{ env.GLIBC_BASELINE }}**." >> "$GITHUB_STEP_SUMMARY" - name: Tar id: pack run: | diff --git a/CMakeLists.txt b/CMakeLists.txt index ae2a13a..3861be2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -64,7 +64,6 @@ if(NOT LANCE_C_USE_PREBUILT) CRATES lance-c CRATE_TYPES staticlib cdylib PROFILE release - NO_LINKER_OVERRIDE # linker is set via CARGO_TARGET_*_RUSTFLAGS in the CI action ) if(APPLE) corrosion_set_env_vars(lance_c "MACOSX_DEPLOYMENT_TARGET=${CMAKE_OSX_DEPLOYMENT_TARGET}") diff --git a/README.md b/README.md index 3812cd1..fbfeea7 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ The C/C++ binding to [Lance](https://github.com/lancedb/lance), providing native |-----------|------------------| | CMake | 3.22+ | | C++ | C++20 | -| GLIBC baseline | `.github/baseline.env` (`GLIBC_BASELINE`) | +| GLIBC baseline | 2.28 | | Clang | Clang 18; Apple Clang 15 | | macOS | `.github/baseline.env` (`MACOSX_DEPLOYMENT_TARGET`) | diff --git a/cmake/baseline.cmake b/cmake/baseline.cmake index 4768feb..5b314e0 100644 --- a/cmake/baseline.cmake +++ b/cmake/baseline.cmake @@ -14,11 +14,6 @@ function(lance_c_load_baseline_env env_file) if(_line STREQUAL "" OR _line MATCHES "^#") continue() endif() - - if(NOT _line MATCHES "^([A-Za-z_][A-Za-z0-9_]*)=(.*)$") - message(FATAL_ERROR "Invalid baseline line: ${_line}") - endif() - set("${CMAKE_MATCH_1}" "${CMAKE_MATCH_2}" PARENT_SCOPE) endforeach() endfunction() From c7f7de87437f5c4c188512d407af5213f3e7aa13 Mon Sep 17 00:00:00 2001 From: Ally Heev Date: Sun, 28 Jun 2026 21:41:34 +0530 Subject: [PATCH 16/16] refactor: ubuntu -> manylinux --- .github/workflows/ci.yml | 32 +++++++++++++-- .github/workflows/consumer-smoke-test.yml | 24 ++++++++---- .github/workflows/release.yml | 47 ++++++++++++++--------- CMakeLists.txt | 4 +- README.md | 2 +- cmake/baseline.cmake | 5 +++ 6 files changed, 80 insertions(+), 34 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index abccf0c..6b1a9c6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -19,6 +19,7 @@ jobs: format: name: Rustfmt runs-on: ubuntu-24.04 + container: quay.io/pypa/manylinux_2_28_x86_64 timeout-minutes: 10 steps: - uses: actions/checkout@v4 @@ -31,6 +32,7 @@ jobs: clippy: name: Clippy runs-on: ubuntu-24.04 + container: quay.io/pypa/manylinux_2_28_x86_64 timeout-minutes: 30 steps: - uses: actions/checkout@v4 @@ -39,13 +41,18 @@ jobs: components: clippy - uses: Swatinem/rust-cache@v2 - name: Install dependencies - run: sudo apt-get update && sudo apt-get install -y protobuf-compiler + run: | + ARCH=$(uname -m) + case "${ARCH}" in x86_64) PA="linux-x86_64" ;; aarch64) PA="linux-aarch_64" ;; esac + curl -fsSL "https://github.com/protocolbuffers/protobuf/releases/download/v25.3/protoc-25.3-${PA}.zip" -o /tmp/protoc.zip + unzip -o /tmp/protoc.zip -d /usr/local bin/protoc 'include/*' && rm /tmp/protoc.zip - name: Clippy run: cargo clippy --all-targets -- -D warnings test-linux: name: Tests (Linux) runs-on: ubuntu-24.04 + container: quay.io/pypa/manylinux_2_28_x86_64 timeout-minutes: 30 env: CC: clang @@ -54,8 +61,14 @@ jobs: - uses: actions/checkout@v4 - uses: actions-rust-lang/setup-rust-toolchain@v1 - uses: Swatinem/rust-cache@v2 + - name: Install Clang 20 + run: manylinux-install-clang -v 20.1.8.0 - name: Install dependencies - run: sudo apt-get update && sudo apt-get install -y protobuf-compiler + run: | + ARCH=$(uname -m) + case "${ARCH}" in x86_64) PA="linux-x86_64" ;; aarch64) PA="linux-aarch_64" ;; esac + curl -fsSL "https://github.com/protocolbuffers/protobuf/releases/download/v25.3/protoc-25.3-${PA}.zip" -o /tmp/protoc.zip + unzip -o /tmp/protoc.zip -d /usr/local bin/protoc 'include/*' && rm /tmp/protoc.zip - name: Run tests run: cargo test - name: Run C/C++ compilation tests @@ -86,19 +99,25 @@ jobs: rustdoc: name: Rustdoc runs-on: ubuntu-24.04 + container: quay.io/pypa/manylinux_2_28_x86_64 timeout-minutes: 30 steps: - uses: actions/checkout@v4 - uses: actions-rust-lang/setup-rust-toolchain@v1 - uses: Swatinem/rust-cache@v2 - name: Install dependencies - run: sudo apt-get update && sudo apt-get install -y protobuf-compiler + run: | + ARCH=$(uname -m) + case "${ARCH}" in x86_64) PA="linux-x86_64" ;; aarch64) PA="linux-aarch_64" ;; esac + curl -fsSL "https://github.com/protocolbuffers/protobuf/releases/download/v25.3/protoc-25.3-${PA}.zip" -o /tmp/protoc.zip + unzip -o /tmp/protoc.zip -d /usr/local bin/protoc 'include/*' && rm /tmp/protoc.zip - name: Check documentation run: RUSTDOCFLAGS="-D warnings" cargo doc --no-deps msrv: name: MSRV (1.91.0) runs-on: ubuntu-24.04 + container: quay.io/pypa/manylinux_2_28_x86_64 timeout-minutes: 30 steps: - uses: actions/checkout@v4 @@ -107,13 +126,18 @@ jobs: toolchain: "1.91.0" - uses: Swatinem/rust-cache@v2 - name: Install dependencies - run: sudo apt-get update && sudo apt-get install -y protobuf-compiler + run: | + ARCH=$(uname -m) + case "${ARCH}" in x86_64) PA="linux-x86_64" ;; aarch64) PA="linux-aarch_64" ;; esac + curl -fsSL "https://github.com/protocolbuffers/protobuf/releases/download/v25.3/protoc-25.3-${PA}.zip" -o /tmp/protoc.zip + unzip -o /tmp/protoc.zip -d /usr/local bin/protoc 'include/*' && rm /tmp/protoc.zip - name: Check MSRV run: cargo check --all-targets license-headers: name: License headers runs-on: ubuntu-24.04 + container: quay.io/pypa/manylinux_2_28_x86_64 timeout-minutes: 5 steps: - uses: actions/checkout@v4 diff --git a/.github/workflows/consumer-smoke-test.yml b/.github/workflows/consumer-smoke-test.yml index a06a407..544b4a7 100644 --- a/.github/workflows/consumer-smoke-test.yml +++ b/.github/workflows/consumer-smoke-test.yml @@ -28,16 +28,16 @@ env: jobs: consumer-smoke-test: name: find_package(LanceC) smoke test - runs-on: ${{ matrix.runner }} + runs-on: ${{ matrix.os }} + container: ${{ matrix.container }} timeout-minutes: 45 strategy: fail-fast: false matrix: include: - - runner: ubuntu-24.04 - os_label: linux - - runner: macos-14 - os_label: macos + - os: ubuntu-24.04 + container: quay.io/pypa/manylinux_2_28_x86_64 + - os: macos-14 env: CC: clang CXX: clang++ @@ -55,10 +55,18 @@ jobs: - uses: actions-rust-lang/setup-rust-toolchain@v1 - uses: Swatinem/rust-cache@v2 - name: Install protobuf-compiler (Linux) - if: matrix.os_label == 'linux' - run: sudo apt-get update && sudo apt-get install -y protobuf-compiler + if: runner.os == 'Linux' + run: | + ARCH=$(uname -m) + case "${ARCH}" in x86_64) PA="linux-x86_64" ;; aarch64) PA="linux-aarch_64" ;; esac + curl -fsSL "https://github.com/protocolbuffers/protobuf/releases/download/v25.3/protoc-25.3-${PA}.zip" -o /tmp/protoc.zip + unzip -o /tmp/protoc.zip -d /usr/local bin/protoc 'include/*' && rm /tmp/protoc.zip + - name: Install Clang 20 (Linux) + if: runner.os == 'Linux' + run: | + manylinux-install-clang -v 20.1.8.0 - name: Install protobuf (macOS) - if: matrix.os_label == 'macos' + if: runner.os == 'macOS' run: brew install protobuf - name: Configure + build + install lance-c run: | diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 84f33d2..255907c 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -18,24 +18,24 @@ env: jobs: build: name: Build (${{ matrix.target }}) - runs-on: ${{ matrix.runner }} + runs-on: ${{ matrix.os }} + container: ${{ matrix.container }} timeout-minutes: 90 strategy: fail-fast: false matrix: include: - - target: x86_64-unknown-linux-gnu - runner: ubuntu-24.04 - os_label: linux - - target: aarch64-unknown-linux-gnu - runner: ubuntu-24.04-arm - os_label: linux + - os: ubuntu-24.04 + container: quay.io/pypa/manylinux_2_28_x86_64 + target: x86_64-unknown-linux-gnu + - os: ubuntu-24.04-arm + container: quay.io/pypa/manylinux_2_28_aarch64 + target: aarch64-unknown-linux-gnu # x86_64-apple-darwin temporarily disabled: GitHub is deprecating # macos-13 runners and jobs queue 24h+ before timing out. Restore # this row once a macos-* Intel runner is reliably available again. - - target: aarch64-apple-darwin - runner: macos-14 - os_label: macos + - os: macos-14 + target: aarch64-apple-darwin env: CC: clang CXX: clang++ @@ -51,16 +51,20 @@ jobs: echo "MACOSX_DEPLOYMENT_TARGET=$MACOSX_DEPLOYMENT_TARGET" } >>"$GITHUB_ENV" - uses: actions-rust-lang/setup-rust-toolchain@v1 - with: - target: ${{ matrix.target }} - uses: Swatinem/rust-cache@v2 - with: - key: ${{ matrix.target }} - name: Install protobuf (Linux) - if: matrix.os_label == 'linux' - run: sudo apt-get update && sudo apt-get install -y protobuf-compiler + if: runner.os == 'Linux' + run: | + ARCH=$(uname -m) + case "${ARCH}" in x86_64) PA="linux-x86_64" ;; aarch64) PA="linux-aarch_64" ;; esac + curl -fsSL "https://github.com/protocolbuffers/protobuf/releases/download/v25.3/protoc-25.3-${PA}.zip" -o /tmp/protoc.zip + unzip -o /tmp/protoc.zip -d /usr/local bin/protoc 'include/*' && rm /tmp/protoc.zip + - name: Install Clang 20 (Linux) + if: runner.os == 'Linux' + run: | + manylinux-install-clang -v 20.1.8.0 - name: Install protobuf (macOS) - if: matrix.os_label == 'macos' + if: runner.os == 'macOS' run: brew install protobuf - name: Resolve version id: ver @@ -83,8 +87,13 @@ jobs: TARGET=${{ matrix.target }} ARCHIVE="lance-c-v${VERSION}-${TARGET}.tar.xz" tar -C stage -cJf "${ARCHIVE}" . - shasum -a 256 "${ARCHIVE}" > "${ARCHIVE}.sha256" - shasum -a 512 "${ARCHIVE}" > "${ARCHIVE}.sha512" + if command -v shasum > /dev/null 2>&1; then + shasum -a 256 "${ARCHIVE}" > "${ARCHIVE}.sha256" + shasum -a 512 "${ARCHIVE}" > "${ARCHIVE}.sha512" + else + sha256sum "${ARCHIVE}" > "${ARCHIVE}.sha256" + sha512sum "${ARCHIVE}" > "${ARCHIVE}.sha512" + fi echo "archive=${ARCHIVE}" >>"$GITHUB_OUTPUT" - name: Upload as workflow artifact uses: actions/upload-artifact@v4 diff --git a/CMakeLists.txt b/CMakeLists.txt index 3861be2..aa5c7b1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,8 +10,8 @@ read_cargo_version("${CMAKE_CURRENT_LIST_DIR}/Cargo.toml" LANCE_C_VERSION) lance_c_load_baseline_env("${CMAKE_CURRENT_LIST_DIR}/.github/baseline.env") -if(APPLE AND NOT DEFINED CMAKE_OSX_DEPLOYMENT_TARGET) - set(CMAKE_OSX_DEPLOYMENT_TARGET "${MACOSX_DEPLOYMENT_TARGET}" CACHE STRING "Minimum macOS deployment target") +if(APPLE AND NOT CMAKE_OSX_DEPLOYMENT_TARGET) + set(CMAKE_OSX_DEPLOYMENT_TARGET "${MACOSX_DEPLOYMENT_TARGET}" CACHE STRING "Minimum macOS deployment target" FORCE) endif() project(LanceC diff --git a/README.md b/README.md index fbfeea7..5883273 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ The C/C++ binding to [Lance](https://github.com/lancedb/lance), providing native | CMake | 3.22+ | | C++ | C++20 | | GLIBC baseline | 2.28 | -| Clang | Clang 18; Apple Clang 15 | +| Clang | Clang 20; Apple Clang 15 | | macOS | `.github/baseline.env` (`MACOSX_DEPLOYMENT_TARGET`) | ## Building diff --git a/cmake/baseline.cmake b/cmake/baseline.cmake index 5b314e0..4768feb 100644 --- a/cmake/baseline.cmake +++ b/cmake/baseline.cmake @@ -14,6 +14,11 @@ function(lance_c_load_baseline_env env_file) if(_line STREQUAL "" OR _line MATCHES "^#") continue() endif() + + if(NOT _line MATCHES "^([A-Za-z_][A-Za-z0-9_]*)=(.*)$") + message(FATAL_ERROR "Invalid baseline line: ${_line}") + endif() + set("${CMAKE_MATCH_1}" "${CMAKE_MATCH_2}" PARENT_SCOPE) endforeach() endfunction()