This is an automated email from the ASF dual-hosted git repository.

yuxia pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/fluss-rust.git


The following commit(s) were added to refs/heads/main by this push:
     new bb8f26d  feat: support bazel build for cpp bindings (#107)
bb8f26d is described below

commit bb8f26dee41f827d1937a1e68ad4b21d7b89616f
Author: AlexZhao <[email protected]>
AuthorDate: Fri Jan 2 19:37:56 2026 +0800

    feat: support bazel build for cpp bindings (#107)
---
 bindings/cpp/.bazelrc     |  37 +++++
 bindings/cpp/.gitignore   |   9 ++
 bindings/cpp/BUILD.bazel  | 342 ++++++++++++++++++++++++++++++++++++++++++++++
 bindings/cpp/MODULE.bazel |  23 ++++
 bindings/cpp/ci.sh        | 100 ++++++++++++++
 5 files changed, 511 insertions(+)

diff --git a/bindings/cpp/.bazelrc b/bindings/cpp/.bazelrc
new file mode 100644
index 0000000..ce7d81f
--- /dev/null
+++ b/bindings/cpp/.bazelrc
@@ -0,0 +1,37 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+# Bazel configuration for fluss-rust C++ bindings
+
+# Enable BzlMod
+common --enable_bzlmod
+
+# Debug configuration (matches BUILD.bazel settings)
+build:debug --compilation_mode=dbg
+build:debug --copt=-g3
+build:debug --copt=-ggdb
+build:debug --copt=-O0
+build:debug --copt=-fno-omit-frame-pointer
+build:debug --copt=-DDEBUG
+build:debug --strip=never
+build:debug --linkopt=-g
+
+# Release configuration
+build:release --compilation_mode=opt
+build:release --copt=-O2
+build:release --copt=-DNDEBUG
+build:release --strip=always
diff --git a/bindings/cpp/.gitignore b/bindings/cpp/.gitignore
index 6836e70..43f761c 100644
--- a/bindings/cpp/.gitignore
+++ b/bindings/cpp/.gitignore
@@ -5,3 +5,12 @@ cmake-build-*/
 *.a
 *.so
 *.dylib
+
+# Bazel build outputs
+bazel-build/
+bazel-bin
+bazel-out
+bazel-testlogs
+bazel-cpp
+bazel-*
+MODULE.bazel.lock
diff --git a/bindings/cpp/BUILD.bazel b/bindings/cpp/BUILD.bazel
new file mode 100644
index 0000000..81d483c
--- /dev/null
+++ b/bindings/cpp/BUILD.bazel
@@ -0,0 +1,342 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+licenses(["notice"])
+
+load("@rules_cc//cc:defs.bzl", "cc_library", "cc_binary")
+
+config_setting(
+    name = "debug_mode",
+    values = {"compilation_mode": "dbg"},
+)
+
+config_setting(
+    name = "fastbuild_mode",
+    values = {"compilation_mode": "fastbuild"},
+)
+
+config_setting(
+    name = "release_mode",
+    values = {"compilation_mode": "opt"},
+)
+
+genrule(
+    name = "cargo_build_debug",
+    srcs = glob([
+        "src/**/*.rs",
+        "Cargo.toml",
+    ]),
+    outs = [
+        "rust_lib_debug.a",
+        "rust_bridge_cc_debug.cc",
+        "rust_bridge_h_debug.h",
+        "src/lib.rs_debug.h",
+        "cxxbridge/rust/cxx_debug.h",
+    ],
+    cmd = """
+        set -e
+        EXECROOT=$$(pwd)
+        OUTPUT_LIB=$(location rust_lib_debug.a)
+        OUTPUT_CC=$(location rust_bridge_cc_debug.cc)
+        OUTPUT_H=$(location rust_bridge_h_debug.h)
+        OUTPUT_SRC_H=$(location src/lib.rs_debug.h)
+        OUTPUT_CXX_H=$(location cxxbridge/rust/cxx_debug.h)
+        # Resolve real source path from sandbox symlink
+        SANDBOX_CARGO=$(location Cargo.toml)
+        REAL_CARGO=$$(readlink -f $$SANDBOX_CARGO 2>/dev/null || python3 -c 
"import os; print(os.path.realpath('$$SANDBOX_CARGO'))")
+        CARGO_DIR=$$(dirname $$REAL_CARGO)
+        # Find Cargo workspace root (fluss-rust directory, 2 levels up from 
bindings/cpp)
+        WORKSPACE_ROOT=$$(cd $$CARGO_DIR/../.. && pwd)
+        if [ ! -f $$WORKSPACE_ROOT/Cargo.toml ]; then
+            echo "Error: Cannot find workspace root Cargo.toml at 
$$WORKSPACE_ROOT" >&2
+            exit 1
+        fi
+        cd $$WORKSPACE_ROOT
+        cargo build --manifest-path $$CARGO_DIR/Cargo.toml
+        CARGO_TARGET_DIR=$$WORKSPACE_ROOT/target
+        # cxxbridge uses the Cargo package name (with hyphen): fluss-cpp
+        RUST_BRIDGE_DIR=$$CARGO_TARGET_DIR/cxxbridge/fluss-cpp/src
+        # Cargo converts hyphens to underscores in library file names: 
libfluss_cpp.a
+        RUST_LIB=$$CARGO_TARGET_DIR/debug/libfluss_cpp.a
+        if [ ! -f $$RUST_LIB ]; then
+            echo "Error: Rust library not found at $$RUST_LIB" >&2
+            exit 1
+        fi
+        if [ ! -f $$RUST_BRIDGE_DIR/lib.rs.cc ]; then
+            echo "Error: cxxbridge CC file not found at 
$$RUST_BRIDGE_DIR/lib.rs.cc" >&2
+            exit 1
+        fi
+        if [ ! -f $$RUST_BRIDGE_DIR/lib.rs.h ]; then
+            echo "Error: cxxbridge header file not found at 
$$RUST_BRIDGE_DIR/lib.rs.h" >&2
+            exit 1
+        fi
+        cd $$EXECROOT
+        mkdir -p $$(dirname $$OUTPUT_SRC_H) $$(dirname $$OUTPUT_CXX_H)
+        cp $$RUST_LIB $$OUTPUT_LIB || (echo "Failed to copy $$RUST_LIB to 
$$OUTPUT_LIB" >&2; exit 1)
+        cp $$RUST_BRIDGE_DIR/lib.rs.cc $$OUTPUT_CC || (echo "Failed to copy 
$$RUST_BRIDGE_DIR/lib.rs.cc to $$OUTPUT_CC" >&2; exit 1)
+        cp $$RUST_BRIDGE_DIR/lib.rs.h $$OUTPUT_H || (echo "Failed to copy 
$$RUST_BRIDGE_DIR/lib.rs.h to $$OUTPUT_H" >&2; exit 1)
+        cp $$RUST_BRIDGE_DIR/lib.rs.h $$OUTPUT_SRC_H || (echo "Failed to copy 
$$RUST_BRIDGE_DIR/lib.rs.h to $$OUTPUT_SRC_H" >&2; exit 1)
+        CXX_H_SOURCE=$$CARGO_TARGET_DIR/cxxbridge/rust/cxx.h
+        if [ ! -f $$CXX_H_SOURCE ] && [ ! -L $$CXX_H_SOURCE ]; then
+            echo "Error: cxx.h not found at $$CXX_H_SOURCE" >&2
+            exit 1
+        fi
+        cp -L $$CXX_H_SOURCE $$OUTPUT_CXX_H || (echo "Failed to copy 
$$CXX_H_SOURCE to $$OUTPUT_CXX_H" >&2; exit 1)
+    """,
+    message = "Building Rust library (debug) with cargo...",
+    local = 1,
+)
+
+genrule(
+    name = "cargo_build_release",
+    srcs = glob([
+        "src/**/*.rs",
+        "Cargo.toml",
+    ]),
+    outs = [
+        "rust_lib_release.a",
+        "rust_bridge_cc_release.cc",
+        "rust_bridge_h_release.h",
+        "src/lib.rs_release.h",
+        "cxxbridge/rust/cxx_release.h",
+    ],
+    cmd = """
+        set -e
+        EXECROOT=$$(pwd)
+        OUTPUT_LIB=$(location rust_lib_release.a)
+        OUTPUT_CC=$(location rust_bridge_cc_release.cc)
+        OUTPUT_H=$(location rust_bridge_h_release.h)
+        OUTPUT_SRC_H=$(location src/lib.rs_release.h)
+        OUTPUT_CXX_H=$(location cxxbridge/rust/cxx_release.h)
+        # Resolve real source path from sandbox symlink
+        SANDBOX_CARGO=$(location Cargo.toml)
+        REAL_CARGO=$$(readlink -f $$SANDBOX_CARGO 2>/dev/null || python3 -c 
"import os; print(os.path.realpath('$$SANDBOX_CARGO'))")
+        CARGO_DIR=$$(dirname $$REAL_CARGO)
+        # Find Cargo workspace root (fluss-rust directory, 2 levels up from 
bindings/cpp)
+        WORKSPACE_ROOT=$$(cd $$CARGO_DIR/../.. && pwd)
+        if [ ! -f $$WORKSPACE_ROOT/Cargo.toml ]; then
+            echo "Error: Cannot find workspace root Cargo.toml at 
$$WORKSPACE_ROOT" >&2
+            exit 1
+        fi
+        cd $$WORKSPACE_ROOT
+        cargo build --release --manifest-path $$CARGO_DIR/Cargo.toml
+        CARGO_TARGET_DIR=$$WORKSPACE_ROOT/target
+        # cxxbridge uses the Cargo package name (with hyphen): fluss-cpp
+        RUST_BRIDGE_DIR=$$CARGO_TARGET_DIR/cxxbridge/fluss-cpp/src
+        # Cargo converts hyphens to underscores in library file names: 
libfluss_cpp.a
+        RUST_LIB=$$CARGO_TARGET_DIR/release/libfluss_cpp.a
+        if [ ! -f $$RUST_LIB ]; then
+            echo "Error: Rust library not found at $$RUST_LIB" >&2
+            exit 1
+        fi
+        if [ ! -f $$RUST_BRIDGE_DIR/lib.rs.cc ]; then
+            echo "Error: cxxbridge CC file not found at 
$$RUST_BRIDGE_DIR/lib.rs.cc" >&2
+            exit 1
+        fi
+        if [ ! -f $$RUST_BRIDGE_DIR/lib.rs.h ]; then
+            echo "Error: cxxbridge header file not found at 
$$RUST_BRIDGE_DIR/lib.rs.h" >&2
+            exit 1
+        fi
+        cd $$EXECROOT
+        mkdir -p $$(dirname $$OUTPUT_SRC_H) $$(dirname $$OUTPUT_CXX_H)
+        cp $$RUST_LIB $$OUTPUT_LIB || (echo "Failed to copy $$RUST_LIB to 
$$OUTPUT_LIB" >&2; exit 1)
+        cp $$RUST_BRIDGE_DIR/lib.rs.cc $$OUTPUT_CC || (echo "Failed to copy 
$$RUST_BRIDGE_DIR/lib.rs.cc to $$OUTPUT_CC" >&2; exit 1)
+        cp $$RUST_BRIDGE_DIR/lib.rs.h $$OUTPUT_H || (echo "Failed to copy 
$$RUST_BRIDGE_DIR/lib.rs.h to $$OUTPUT_H" >&2; exit 1)
+        cp $$RUST_BRIDGE_DIR/lib.rs.h $$OUTPUT_SRC_H || (echo "Failed to copy 
$$RUST_BRIDGE_DIR/lib.rs.h to $$OUTPUT_SRC_H" >&2; exit 1)
+        CXX_H_SOURCE=$$CARGO_TARGET_DIR/cxxbridge/rust/cxx.h
+        if [ ! -f $$CXX_H_SOURCE ] && [ ! -L $$CXX_H_SOURCE ]; then
+            echo "Error: cxx.h not found at $$CXX_H_SOURCE" >&2
+            exit 1
+        fi
+        cp -L $$CXX_H_SOURCE $$OUTPUT_CXX_H || (echo "Failed to copy 
$$CXX_H_SOURCE to $$OUTPUT_CXX_H" >&2; exit 1)
+    """,
+    message = "Building Rust library (release) with cargo...",
+    local = 1,
+)
+
+filegroup(
+    name = "lib_rs_h_selected",
+    srcs = select({
+        ":debug_mode": [":src/lib.rs_debug.h"],
+        ":fastbuild_mode": [":src/lib.rs_debug.h"],
+        ":release_mode": [":src/lib.rs_release.h"],
+    }),
+)
+
+genrule(
+    name = "lib_rs_h_unified",
+    srcs = [":lib_rs_h_selected"],
+    outs = ["src/lib.rs.h"],
+    cmd = "cp $(location :lib_rs_h_selected) $(location src/lib.rs.h)",
+    message = "Unifying lib.rs.h for C++ includes",
+)
+
+filegroup(
+    name = "rust_bridge_cc_selected",
+    srcs = select({
+        ":debug_mode": [":rust_bridge_cc_debug.cc"],
+        ":fastbuild_mode": [":rust_bridge_cc_debug.cc"],
+        ":release_mode": [":rust_bridge_cc_release.cc"],
+    }),
+)
+
+genrule(
+    name = "rust_bridge_cc_unified",
+    srcs = [":rust_bridge_cc_selected"],
+    outs = ["rust_bridge_cc.cc"],
+    cmd = "cp $(location :rust_bridge_cc_selected) $(location 
rust_bridge_cc.cc)",
+    message = "Unifying rust_bridge_cc.cc for C++ compilation",
+)
+
+filegroup(
+    name = "rust_bridge_h_selected",
+    srcs = select({
+        ":debug_mode": [":rust_bridge_h_debug.h"],
+        ":fastbuild_mode": [":rust_bridge_h_debug.h"],
+        ":release_mode": [":rust_bridge_h_release.h"],
+    }),
+)
+
+genrule(
+    name = "rust_bridge_h_unified",
+    srcs = [":rust_bridge_h_selected"],
+    outs = ["rust_bridge_h.h"],
+    cmd = "cp $(location :rust_bridge_h_selected) $(location rust_bridge_h.h)",
+    message = "Unifying rust_bridge_h.h for C++ includes",
+)
+
+filegroup(
+    name = "cxx_h_selected",
+    srcs = select({
+        ":debug_mode": [":cxxbridge/rust/cxx_debug.h"],
+        ":fastbuild_mode": [":cxxbridge/rust/cxx_debug.h"],
+        ":release_mode": [":cxxbridge/rust/cxx_release.h"],
+    }),
+)
+
+genrule(
+    name = "cxx_h_unified",
+    srcs = [":cxx_h_selected"],
+    outs = ["cxxbridge/rust/cxx.h"],
+    cmd = "mkdir -p $$(dirname $(location cxxbridge/rust/cxx.h)) && cp 
$(location :cxx_h_selected) $(location cxxbridge/rust/cxx.h)",
+    message = "Unifying cxx.h for C++ includes",
+)
+
+cc_import(
+    name = "rust_lib",
+    static_library = select({
+        ":debug_mode": ":rust_lib_debug.a",
+        ":fastbuild_mode": ":rust_lib_debug.a",
+        ":release_mode": ":rust_lib_release.a",
+    }),
+    alwayslink = True,
+)
+
+cc_library(
+    name = "fluss_cpp",
+    srcs = [
+        "src/admin.cpp",
+        "src/connection.cpp",
+        "src/table.cpp",
+        ":rust_bridge_cc_unified",
+    ],
+    hdrs = [
+        "include/fluss.hpp",
+    ],
+    textual_hdrs = [
+        "src/ffi_converter.hpp",
+        ":rust_bridge_h_unified",
+        ":lib_rs_h_unified",
+        ":cxx_h_unified",
+    ],
+    strip_include_prefix = "include",
+    copts = [
+        "-std=c++17",
+    ] + select({
+        ":debug_mode": [
+            "-g3",
+            "-O0",
+            "-ggdb",
+            "-fno-omit-frame-pointer",
+            "-DDEBUG",
+        ],
+        ":fastbuild_mode": [
+            "-g",
+            "-O0",
+        ],
+        ":release_mode": [
+            "-O2",
+            "-DNDEBUG",
+        ],
+    }),
+    includes = [
+        "src",
+        "cxxbridge",
+    ],
+    linkopts = [
+        "-ldl",
+        "-lpthread",
+    ] + select({
+        ":debug_mode": ["-g"],
+        ":fastbuild_mode": ["-g"],
+        ":release_mode": [],
+    }) + select({
+        "@platforms//os:macos": [
+            "-framework", "CoreFoundation",
+            "-framework", "Security",
+        ],
+        "//conditions:default": [],
+    }),
+    deps = [
+        ":rust_lib",
+    ],
+    visibility = ["//visibility:public"],
+)
+
+cc_binary(
+    name = "fluss_cpp_example",
+    srcs = [
+        "examples/example.cpp",
+    ],
+    deps = [":fluss_cpp"],
+    copts = [
+        "-std=c++17",
+    ] + select({
+        ":debug_mode": [
+            "-g3",
+            "-O0",
+            "-ggdb",
+            "-fno-omit-frame-pointer",
+            "-DDEBUG",
+        ],
+        ":fastbuild_mode": [
+            "-g",
+            "-O0",
+        ],
+        ":release_mode": [
+            "-O2",
+            "-DNDEBUG",
+        ],
+    }),
+    linkopts = select({
+        ":debug_mode": ["-g"],
+        ":fastbuild_mode": ["-g"],
+        ":release_mode": [],
+    }),
+    visibility = ["//visibility:public"],
+)
+
diff --git a/bindings/cpp/MODULE.bazel b/bindings/cpp/MODULE.bazel
new file mode 100644
index 0000000..f75d3e6
--- /dev/null
+++ b/bindings/cpp/MODULE.bazel
@@ -0,0 +1,23 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+module(
+    name = "fluss_cpp",
+)
+
+bazel_dep(name = "rules_cc", version = "0.0.17")
+bazel_dep(name = "platforms", version = "0.0.10")
diff --git a/bindings/cpp/ci.sh b/bindings/cpp/ci.sh
new file mode 100755
index 0000000..b5eb967
--- /dev/null
+++ b/bindings/cpp/ci.sh
@@ -0,0 +1,100 @@
+#!/bin/bash
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+set -xe 
+
+DIR="$(cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd)"
+
+# Set Bazel output base to bazel-build directory
+# This ensures all Bazel outputs are in bazel-build/.bazel-output-base
+BAZEL_OUTPUT_BASE="$DIR/bazel-build/.bazel-output-base"
+
+# Create output base directory if it doesn't exist
+mkdir -p "$BAZEL_OUTPUT_BASE"
+
+# Wrapper function to run bazel with --output_base
+bazel() {
+    command bazel --output_base="$BAZEL_OUTPUT_BASE" "$@"
+}
+
+compile() {
+    bazel build //:fluss_cpp
+}
+
+build_example() {
+    bazel build //:fluss_cpp_example
+}
+
+run_example() {
+    build_example
+    bazel run //:fluss_cpp_example
+}
+
+clean() {
+    bazel clean
+    # Remove bazel-* symlinks (Bazel automatically creates these)
+    rm -f "$DIR"/bazel-*
+    # Also remove the bazel-build directory if it exists
+    if [ -d "$DIR/bazel-build" ]; then
+        rm -rf "$DIR/bazel-build"
+    fi
+    echo "Cleaned all Bazel outputs and symlinks"
+}
+
+show_outputs() {
+    echo "=== Library outputs ==="
+    bazel cquery //:fluss_cpp --output=files 2>/dev/null || echo "Run 'bazel 
build //:fluss_cpp' first"
+    echo ""
+    echo "=== Example binary outputs ==="
+    bazel cquery //:fluss_cpp_example --output=files 2>/dev/null || echo "Run 
'bazel build //:fluss_cpp_example' first"
+    echo ""
+    echo "=== To run the example ==="
+    echo "  bazel run //:fluss_cpp_example"
+    echo ""
+    echo "=== To find outputs manually ==="
+    echo "  bazel info bazel-bin"
+}
+
+case $1 in 
+    compile )
+        compile
+        ;;
+    example )
+        build_example
+        ;;
+    run )
+        run_example
+        ;;
+    outputs )
+        show_outputs
+        ;;
+    clean )
+        clean
+        ;;
+    * )
+        echo "Usage: $0 {compile|example|run|outputs|clean}"
+        echo ""
+        echo "Commands:"
+        echo "  compile  - Build the fluss_cpp library"
+        echo "  example  - Build the example binary"
+        echo "  run      - Build and run the example binary"
+        echo "  outputs  - Show the location of build outputs"
+        echo "  clean    - Clean all Bazel outputs"
+        exit 1
+        ;;
+esac

Reply via email to