Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
629457a
Integrate Cargo into the CMake build
0ax1 Sep 2, 2026
3ad58e1
Simplify the CMake Cargo integration
0ax1 Sep 3, 2026
a0926df
Clarify the CMake module structure
0ax1 Sep 4, 2026
510bf95
Support configurable Cargo profiles in CMake
0ax1 Sep 4, 2026
b36a839
Simplify the Cargo build script
0ax1 Sep 4, 2026
ecb4820
Simplify the Cargo build environment
0ax1 Sep 4, 2026
24d113c
Refine CMake profile and sanitizer handling
0ax1 Sep 4, 2026
8e9481d
Document CMake Cargo profile mappings
0ax1 Sep 4, 2026
38f893b
Clarify CMake FFI package requirements
0ax1 Sep 4, 2026
4e86b5c
Document CMake CUDA output initialization
0ax1 Sep 4, 2026
08ac676
Simplify CMake Cargo flag handling
0ax1 Sep 4, 2026
4fd6a8b
Harden CMake Rust toolchain integration
0ax1 Sep 4, 2026
7156735
Simplify CMake Rust toolchain resolution
0ax1 Sep 4, 2026
a19d1d1
Simplify CMake Cargo plumbing and default to Debug
0ax1 Sep 4, 2026
f435699
Simplify the C++ CMake entry point
0ax1 Sep 4, 2026
d7a23c3
Disable unnecessary CMake module scanning
0ax1 Sep 4, 2026
71ebeab
Disable unnecessary FFI CMake module scanning
0ax1 Sep 4, 2026
dac563e
Consolidate the CMake integration under vortex-ffi
0ax1 Sep 4, 2026
64080fd
Export compile commands for standalone configures
0ax1 Sep 4, 2026
706dbfe
Accept a list of sanitizers in VORTEX_SANITIZER
0ax1 Sep 4, 2026
9c5636a
Tidy the C++ test CMake file and coverage script
0ax1 Sep 4, 2026
1f230e9
Treat CMake dependencies as system includes
0ax1 Sep 4, 2026
39e8b0c
Do not require Ninja for C++ CI
0ax1 Sep 4, 2026
4f1a465
Do not require Ninja for C++ coverage
0ax1 Sep 4, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 24 additions & 24 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -585,26 +585,26 @@ jobs:
- uses: ./.github/actions/setup-prebuild
with:
enable-sccache: "true"

- name: Install Rust nightly toolchain
run: |
rustup toolchain install $NIGHTLY_TOOLCHAIN
rustup component add --toolchain $NIGHTLY_TOOLCHAIN rust-src rustfmt clippy llvm-tools-preview
- name: Build FFI library (asan)
run: |
RUSTFLAGS="-A warnings -Cunsafe-allow-abi-mismatch=sanitizer \
-C debuginfo=2 -C opt-level=0 -C strip=none -Zexternal-clangrt \
-Zsanitizer=address,leak" \
cargo +$NIGHTLY_TOOLCHAIN build --locked --no-default-features \
--target x86_64-unknown-linux-gnu -Zbuild-std \
-p vortex-ffi
- name: Build C++ tests and examples (asan)
run: |
mkdir -p build
cmake -S lang/cpp -Bbuild -DSANITIZER=asan -DBUILD_TESTS=1 -DBUILD_EXAMPLES=1 -DTARGET_TRIPLE="x86_64-unknown-linux-gnu"
cmake --build build --parallel $(nproc)
env:
RUSTUP_TOOLCHAIN: ${{ env.NIGHTLY_TOOLCHAIN }}
run: |
cmake -S lang/cpp -B build \
-DCMAKE_BUILD_TYPE=Debug \
-DCMAKE_C_COMPILER=clang \
-DCMAKE_CXX_COMPILER=clang++ \
-DVORTEX_SANITIZER=asan,lsan,ubsan \
-DVORTEX_SANITIZE_RUST_STD=ON \
-DVORTEX_BUILD_TESTING=ON \
-DVORTEX_BUILD_EXAMPLES=ON
cmake --build build --parallel
- name: Run C++ tests
run: |
build/tests/vortex_cxx_test
run: ctest --test-dir build --output-on-failure
- name: Run C++ examples
run: |
cd build/examples
Expand Down Expand Up @@ -782,13 +782,13 @@ jobs:
- uses: ./.github/actions/setup-prebuild
with:
enable-sccache: "true"
- name: "regenerate FFI header file"
run: |
cargo +$NIGHTLY_TOOLCHAIN build --profile ci -p vortex-ffi
- name: Build and run C++ unit tests
run: |
cd vortex-ffi
mkdir build
cmake -Bbuild -DRUST_BUILD_PROFILE=ci
cmake --build build -j $(nproc)
ctest --test-dir build -j $(nproc)
- name: Build and run C API tests
env:
# Nightly regenerates cinclude/vortex.h with cbindgen during the build.
RUSTUP_TOOLCHAIN: ${{ env.NIGHTLY_TOOLCHAIN }}
run: |
cmake -S vortex-ffi -B vortex-ffi/build \
-DVORTEX_CARGO_PROFILE=ci \
-DVORTEX_BUILD_TESTING=ON
cmake --build vortex-ffi/build --parallel
ctest --test-dir vortex-ffi/build --output-on-failure
37 changes: 14 additions & 23 deletions .github/workflows/rust-instrumented.yml
Original file line number Diff line number Diff line change
Expand Up @@ -140,8 +140,6 @@ jobs:
sudo apt-get update
sudo apt-get install -y lcov libjson-xs-perl
fi
- name: Build FFI library
run: cargo build -p vortex-ffi
- name: Build and test C++ API with coverage
working-directory: lang/cpp
run: ./gcov-report.sh
Expand Down Expand Up @@ -210,17 +208,14 @@ jobs:
--target x86_64-unknown-linux-gnu -Zbuild-std \
-p vortex-buffer -p vortex-fastlanes -p vortex-fsst -p vortex-alp -p vortex-array

# vortex-ffi requires --no-default-features as otherwise we pull in
# Mimalloc which interferes with sanitizers
# cargo nextest reports less sanitizer issues than cargo test
# TODO(myrrc): remove --no-default-features once we make Mimalloc opt-in
# --tests skips doctests: rustdoc ignores RUSTFLAGS (it uses RUSTDOCFLAGS),
# so doctests would build vortex-ffi without -Zsanitizer and mismatch the
# sanitizer-built deps.
- name: Run vortex-ffi tests with sanitizer
run: |
RUSTFLAGS="${RUSTFLAGS} ${{ matrix.sanitizer_flags }}" \
cargo +$NIGHTLY_TOOLCHAIN test --locked --no-default-features \
cargo +$NIGHTLY_TOOLCHAIN test --locked \
--target x86_64-unknown-linux-gnu --no-fail-fast -Zbuild-std \
-p vortex-ffi --tests -- --no-capture

Expand All @@ -231,10 +226,8 @@ jobs:
include:
# We don't run memory sanitizer as it's clang-only and provides many
# false positives for Catch2
- sanitizer: asan
sanitizer_flags: "-Zsanitizer=address,leak"
- sanitizer: "asan,lsan,ubsan"
- sanitizer: tsan
sanitizer_flags: "-Zsanitizer=thread"
name: "Rust/C++ FFI tests (${{ matrix.sanitizer }})"
timeout-minutes: 5
env:
Expand All @@ -246,8 +239,6 @@ jobs:
TSAN_OPTIONS: "symbolize=1:suppressions=${{ github.workspace }}/vortex-ffi/tsan_suppressions.txt"
TSAN_SYMBOLIZER_PATH: "/usr/bin/llvm-symbolizer"
VORTEX_SKIP_SLOW_TESTS: "1"
# -Cunsafe-allow-abi-mismatch=sanitizer: libraries like compiler_builtins
# unset -Zsanitizer flag and we should allow that.
runs-on: >-
${{ github.repository == 'vortex-data/vortex'
&& format('runs-on={0}/runner=amd64-medium/image=ubuntu24-full-x64-pre-v2/tag=rust-ffi-test-sanitizer', github.run_id)
Expand All @@ -265,20 +256,20 @@ jobs:
run: |
rustup toolchain install $NIGHTLY_TOOLCHAIN
rustup component add --toolchain $NIGHTLY_TOOLCHAIN rust-src rustfmt clippy llvm-tools-preview
- name: Build FFI library
run: |
# TODO(myrrc): remove --no-default-features
RUSTFLAGS="-A warnings -Cunsafe-allow-abi-mismatch=sanitizer \
-C debuginfo=2 -C opt-level=0 -C strip=none -Zexternal-clangrt \
${{ matrix.sanitizer_flags }}" \
cargo +$NIGHTLY_TOOLCHAIN build --locked --no-default-features \
--target x86_64-unknown-linux-gnu -Zbuild-std \
-p vortex-ffi
- name: Build FFI library tests and examples
- name: Build FFI library, tests, and examples
working-directory: vortex-ffi
env:
RUSTUP_TOOLCHAIN: ${{ env.NIGHTLY_TOOLCHAIN }}
run: |
cmake -Bbuild -DBUILD_TESTS=1 -DBUILD_EXAMPLES=1 -DSANITIZER=${{ matrix.sanitizer }} -DTARGET_TRIPLE="x86_64-unknown-linux-gnu"
cmake --build build -j
cmake -S . -B build \
-DCMAKE_BUILD_TYPE=Debug \
-DCMAKE_C_COMPILER=clang \
-DCMAKE_CXX_COMPILER=clang++ \
-DVORTEX_SANITIZER=${{ matrix.sanitizer }} \
-DVORTEX_SANITIZE_RUST_STD=ON \
-DVORTEX_BUILD_TESTING=ON \
-DVORTEX_BUILD_EXAMPLES=ON
cmake --build build --parallel
- name: Run tests
run: |
set -o pipefail
Expand Down
61 changes: 61 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# SPDX-License-Identifier: Apache-2.0
# SPDX-FileCopyrightText: Copyright the Vortex contributors

# CMake entry point for the Vortex native libraries.
#
# Layout:
# vortex-ffi/ Builds the Rust FFI archive with Cargo and exports
# Vortex::ffi_static for C consumers. Its cmake/ modules select
# the Rust toolchain, drive Cargo, and attach the system libraries
# the archive needs. The Cargo cache and the staged archive live
# under ffi/ in the build directory.
# lang/cpp/ Builds the C++ wrapper on top and exports Vortex::cpp_static.
#
# Usage:
# add_subdirectory(path/to/vortex vortex)
# target_link_libraries(my_c_target PRIVATE Vortex::ffi_static)
# target_link_libraries(my_cpp_target PRIVATE Vortex::cpp_static)
#
# Each subdirectory also configures on its own, and lang/cpp adds vortex-ffi
# itself when nothing else has. A separate `cargo build` is never required.
#
# Options, set before add_subdirectory() or passed with -D:
# VORTEX_BUILD_TESTING Tests of both layers, run with ctest.
# VORTEX_BUILD_EXAMPLES Examples of both layers.
# VORTEX_CARGO_PROFILE Cargo profile; otherwise mapped from CMAKE_BUILD_TYPE.
# VORTEX_ENABLE_CUDA Linux-only CUDA-enabled FFI archive.
# VORTEX_SANITIZER Comma-separated list of asan, lsan, ubsan, tsan
# for Rust, C, and C++ together; ubsan has no Rust
# side and covers C and C++ only.
# VORTEX_SANITIZE_RUST_STD Also instrument Rust's standard library.
# VORTEX_WARNINGS_AS_ERRORS ON for a Vortex-owned top level, OFF when embedded.
#
# A Vortex-owned top level, this file or either subdirectory, also defaults
# CMAKE_BUILD_TYPE to Debug.
#
# Documentation:
# lang/cpp/README.md Full option reference, embedding rules, the
# shared-library boundary, CUDA deployment,
# sanitizer and coverage workflows.
# docs/getting-started/cpp.rst C++ quickstart with API examples.
# vortex-ffi/README.md C API: runtime threading, header regeneration,
# CMake usage, Rust-side sanitizer tests.
# vortex-ffi/cinclude/vortex.h The C API header, generated by cbindgen.
# vortex-cuda/ffi/README.md CUDA-enabled FFI and Arrow Device export.
# vortex-cuda/README.md CUDA crate and cuDF integration notes.
# docs/project/bindings.md Language bindings roadmap.

cmake_minimum_required(VERSION 3.28)

project(VortexNative DESCRIPTION "Vortex native libraries" LANGUAGES NONE)

# A standalone configure writes compile_commands.json for editor tooling.
if(PROJECT_IS_TOP_LEVEL)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
endif()

# ctest only descends into subdirectories from a root that has testing enabled.
enable_testing()

add_subdirectory(vortex-ffi ffi)
add_subdirectory(lang/cpp cpp)
4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -419,6 +419,10 @@ lto = "off"
debug = "full"
inherits = "release"

[profile.release_size]
inherits = "release"
opt-level = "z"

[profile.bench]
codegen-units = 16
debug = "full"
Expand Down
68 changes: 44 additions & 24 deletions docs/getting-started/cpp.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,39 +10,59 @@ The only dependency apart from Vortex is ``nanoarrow``.
in using Vortex from C++ or you want a feature not covered yet e.g.
extension support.

Installation
------------
Building from source
--------------------

We don't provide prebuilt library files (yet) so you will need to build Vortex
from source, and for that you will need:

- C++20,
- Rust toolchain,
- and CMake 3.10.
Vortex does not provide prebuilt C++ libraries yet. Building from source requires
C++20, CMake 3.28 or newer with a single-config generator, and native Cargo and
rustc 1.95 or newer with the target standard library installed. The initial CMake
integration builds static position-independent-code libraries only. Use a complete
workspace checkout; the C++ directory cannot be built from an isolated source copy.

.. code-block:: bash

git clone --depth 1 https://github.com/vortex-data/vortex
cd vortex
cargo build --release -p vortex-ffi

cmake -S lang/cpp -Bbuild -DCMAKE_BUILD_TYPE=Release
# To build the examples, pass -DBUILD_EXAMPLES=1
# cmake -S lang/cpp -Bbuild -DBUILD_EXAMPLES=1
cmake -S lang/cpp -B build/cpp -G Ninja \
-DCMAKE_BUILD_TYPE=Release \
-DVORTEX_BUILD_EXAMPLES=ON
cmake --build build/cpp --parallel

Configuration locates Cargo and rustc and takes the Rust target from the rustc
host. The locked ``vortex-ffi`` compilation occurs only when the CMake build runs,
so a separate ``cargo build`` step is neither required nor recommended.
Building examples can download nanoarrow during configure; Cargo can download
locked Rust dependencies during the build.

cmake --build build -j
Tests and examples default to ``OFF``. ``VORTEX_WARNINGS_AS_ERRORS`` defaults to
``ON`` for a standalone build and ``OFF`` when a parent adds ``lang/cpp``.

This produces a shared and a static library which you can use directly or via
Source-tree consumers add the repository root, which builds the Rust FFI once and
the C++ wrapper on top, and link the canonical target:

.. code-block:: cmake

# static library
target_link_libraries(target PRIVATE vortex_cxx)
# shared library
target_link_libraries(target PRIVATE vortex_cxx_shared)
add_subdirectory(path/to/vortex vortex)
target_link_libraries(target PRIVATE Vortex::cpp_static)

The Vortex archives are PIC and can be embedded into a shared parent. Keep calls
behind a private C++ translation unit and use the parent's normal version script or
exported-symbol allowlist: the shared parent owns its public ABI, and the Vortex
interface target does not apply parent-wide symbol-export policy.

The CMake integration is source-only: it does not provide installation rules or a
``find_package(Vortex)`` package. Downstream projects should vendor or fetch a pinned
Vortex checkout and add it directly.

Native macOS arm64 is supported for standalone development, but macOS is not a
cuDF integration target. GNU/Linux x86_64 and aarch64 are modeled, while full
GCC 14, Conda compiler-wrapper, glibc 2.28, and cuDF validation remains deferred.

Have a look at the `examples
<https://github.com/vortex-data/vortex/tree/develop/lang/cpp/examples>`_
See the `C++ bindings README
<https://github.com/vortex-data/vortex/blob/develop/lang/cpp/README.md>`_ for all CMake
options, cache behavior, and source-integration rules. Have a look at the
`examples <https://github.com/vortex-data/vortex/tree/develop/lang/cpp/examples>`_
directory as well.

Reading files
Expand Down Expand Up @@ -205,7 +225,7 @@ Now you can build the example and read back the generated files:

.. code-block::

./build/examples/writer people0.vortex
./build/examples/writer people1.vortex
./build/examples/writer me.vortex
./build/examples/reader
./build/cpp/examples/writer people0.vortex
./build/cpp/examples/writer people1.vortex
./build/cpp/examples/writer me.vortex
./build/cpp/examples/reader
3 changes: 2 additions & 1 deletion docs/project/bindings.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,8 @@ Migrate from cxx to wrapping the C API:

- **RAII wrappers:** Provide C++ classes that manage lifetime of C API objects (files, scanners,
arrays, streams).
- **CMake integration:** Ship a CMake config so downstream projects can `find_package(Vortex)`.
- **CMake integration:** Provide source-tree CMake targets so vendored downstream projects can
build Vortex with `add_subdirectory`.
- **Header generation:** Auto-generate C++ headers from the C API headers, adding type safety and
namespace scoping.
- **Target:** Tier 2 (native array access through the C API).
Expand Down
Loading
Loading