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

xuanwo pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/opendal.git


The following commit(s) were added to refs/heads/main by this push:
     new 737012f6e7 build(bindings/c): replace the build system with CMake 
(#5182)
737012f6e7 is described below

commit 737012f6e7bc57469a06e37b1f3b5ce2da9b8d62
Author: Twice <[email protected]>
AuthorDate: Tue Oct 15 19:08:27 2024 +0800

    build(bindings/c): replace the build system with CMake (#5182)
---
 .github/workflows/ci_bindings_c.yml | 21 +++------
 bindings/c/CMakeLists.txt           | 90 +++++++++++++++++++++++++++++++++++++
 bindings/c/Makefile                 | 58 ------------------------
 bindings/c/examples/basic.c         |  2 +-
 bindings/c/tests/bdd.cpp            |  6 ---
 bindings/c/tests/error_msg.cpp      |  6 ---
 bindings/c/tests/list.cpp           |  6 ---
 bindings/c/tests/opinfo.cpp         |  6 ---
 bindings/zig/build.zig              | 11 +++--
 9 files changed, 101 insertions(+), 105 deletions(-)

diff --git a/.github/workflows/ci_bindings_c.yml 
b/.github/workflows/ci_bindings_c.yml
index 33b2ecbcc9..28cd852b68 100644
--- a/.github/workflows/ci_bindings_c.yml
+++ b/.github/workflows/ci_bindings_c.yml
@@ -44,31 +44,20 @@ jobs:
     runs-on: ubuntu-latest
     steps:
       - uses: actions/checkout@v4
-      - name: Install gtest manually
-        run: |
-          sudo apt-get update
-          sudo apt-get install libgtest-dev valgrind
-          cd /usr/src/gtest
-          sudo cmake CMakeLists.txt
-          sudo make
-          sudo cp lib/*.a /usr/lib
-          sudo ln -s /usr/lib/libgtest.a /usr/local/lib/libgtest.a
-          sudo ln -s /usr/lib/libgtest_main.a /usr/local/lib/libgtest_main.a
 
       - name: Setup Rust toolchain
         uses: ./.github/actions/setup
 
       - name: Build C binding
         working-directory: "bindings/c"
-        run: make build
+        run: |
+          mkdir build && cd build
+          cmake .. -DTEST_ENABLE_ASAN=ON
+          make -j$(nproc)
 
       - name: Check diff
         run: git diff --exit-code
 
       - name: Build and Run tests
         working-directory: "bindings/c"
-        run: make test
-
-      - name: Build and Run memory-leak tests
-        working-directory: "bindings/c"
-        run: make memory_leak
+        run: ./build/tests
diff --git a/bindings/c/CMakeLists.txt b/bindings/c/CMakeLists.txt
new file mode 100644
index 0000000000..3c5a54019f
--- /dev/null
+++ b/bindings/c/CMakeLists.txt
@@ -0,0 +1,90 @@
+# 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.
+
+cmake_minimum_required(VERSION 3.22)
+project(opendal-c)
+
+if (NOT CMAKE_BUILD_TYPE)
+    set(CMAKE_BUILD_TYPE "Debug")
+endif()
+
+option(TEST_ENABLE_ASAN "Enable AddressSanitizer for tests" OFF)
+set(GOOGLETEST_VERSION 1.15.2)
+
+# force the compiler to support these standards
+set(CMAKE_C_STANDARD 11)
+set(CMAKE_C_STANDARD_REQUIRED ON)
+
+# for GoogleTest, it should be no less than C++14
+set(CMAKE_CXX_STANDARD 14)
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
+
+# fetch google test via GitHub
+include(FetchContent)
+FetchContent_Declare(
+  googletest
+  URL 
https://github.com/google/googletest/archive/refs/tags/v${GOOGLETEST_VERSION}.zip
+)
+# For Windows: Prevent overriding the parent project's compiler/linker settings
+set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
+FetchContent_MakeAvailable(googletest)
+
+set(CARGO_DIST_DIR "${PROJECT_SOURCE_DIR}/target/debug")
+if (NOT CMAKE_BUILD_TYPE STREQUAL "Debug")
+    set(CARGO_BUILD_TYPE "--release")
+    set(CARGO_DIST_DIR "${PROJECT_SOURCE_DIR}/target/release")
+endif()
+
+set(OPENDAL_STATIC_LIB "${CARGO_DIST_DIR}/libopendal_c.a")
+set(OPENDAL_SHARED_LIB "${CARGO_DIST_DIR}/libopendal_c.so")
+message(NOTICE "-- OpenDAL C static lib: ${OPENDAL_STATIC_LIB}")
+message(NOTICE "-- OpenDAL C shared lib: ${OPENDAL_SHARED_LIB}")
+
+# custom target for cargo build
+add_custom_target(cargo_build
+    COMMAND sh -c "cargo build ${CARGO_BUILD_TYPE}"
+    BYPRODUCTS  ${OPENDAL_STATIC_LIB} ${OPENDAL_SHARED_LIB}
+    WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
+)
+
+# cmake target for static lib
+add_library(opendal_c_static INTERFACE)
+target_link_libraries(opendal_c_static INTERFACE ${OPENDAL_STATIC_LIB})
+target_include_directories(opendal_c_static INTERFACE include)
+add_dependencies(opendal_c_static cargo_build)
+
+# cmake target for shared lib
+add_library(opendal_c_shared INTERFACE)
+target_link_libraries(opendal_c_shared INTERFACE ${OPENDAL_SHARED_LIB})
+target_include_directories(opendal_c_shared INTERFACE include)
+add_dependencies(opendal_c_shared cargo_build)
+
+# example targets
+add_executable(basic examples/basic.c)
+target_link_libraries(basic opendal_c_shared)
+
+add_executable(error_handle examples/error_handle.c)
+target_link_libraries(error_handle opendal_c_shared)
+
+# test targets
+file(GLOB TEST_SRCS tests/*.cpp)
+add_executable(tests ${TEST_SRCS})
+target_link_libraries(tests opendal_c_shared gtest_main)
+if (TEST_ENABLE_ASAN)
+    target_compile_options(tests PRIVATE -fsanitize=address)
+    target_link_options(tests PRIVATE -fsanitize=address)
+endif()
diff --git a/bindings/c/Makefile b/bindings/c/Makefile
index a9b13d842e..5acf1e908d 100644
--- a/bindings/c/Makefile
+++ b/bindings/c/Makefile
@@ -15,75 +15,17 @@
 # specific language governing permissions and limitations
 # under the License.
 
-RPATH=$(PWD)/target/debug
-OBJ_DIR=./build
 DOC_DIR=./docs
 
-CCFLAGS=-I./include
-CXXFLAGS=-I./include -std=c++14
-LDFLAGS=-L$(RPATH) -Wl,-rpath,$(RPATH)
-
-LIBS=-lopendal_c -lgtest -lpthread
-
-VALGRIND=valgrind --error-exitcode=1 --leak-check=full --
-
-.PHONY: all
-all: build test examples
-
 .PHONY: format
 format:
        cargo fmt
        find . -name '*.cpp' -exec clang-format -i --style=WebKit --verbose {} 
\;
        find . -name '*.c' -exec clang-format -i --style=WebKit --verbose {} \;
 
-.PHONY: build
-build:
-       mkdir -p $(OBJ_DIR)
-       cargo build
-
-.PHONY: test
-test:
-       $(CXX) tests/bdd.cpp -o $(OBJ_DIR)/bdd $(CXXFLAGS) $(LDFLAGS) $(LIBS)
-       $(CXX) tests/list.cpp -o $(OBJ_DIR)/list $(CXXFLAGS) $(LDFLAGS) $(LIBS)
-       $(CXX) tests/error_msg.cpp -o $(OBJ_DIR)/error_msg $(CXXFLAGS) 
$(LDFLAGS) $(LIBS)
-       $(CXX) tests/opinfo.cpp -o $(OBJ_DIR)/opinfo $(CXXFLAGS) $(LDFLAGS) 
$(LIBS)
-       $(OBJ_DIR)/bdd
-       $(OBJ_DIR)/list
-       $(OBJ_DIR)/error_msg
-       $(OBJ_DIR)/opinfo
-
-.PHONY: test_memory_leak
-memory_leak:
-       $(VALGRIND) $(OBJ_DIR)/bdd
-       $(VALGRIND) $(OBJ_DIR)/list
-       $(VALGRIND) $(OBJ_DIR)/error_msg
-
 .PHONY: doc
 doc:
        mkdir -p $(DOC_DIR)
        curl --proto '=https' --tlsv1.2 -sSf 
https://cdn.jsdelivr.net/gh/jothepro/[email protected]/doxygen-awesome.min.css
 \
                -o $(DOC_DIR)/doxygen-awesome.css
        doxygen Doxyfile
-
-# build examples begin
-EXAMPLES=$(wildcard ./examples/*.c)
-EXAMPLE_OBJECTS=$(EXAMPLES:.c=.o)
-EXAMPLE_TARGETS=$(EXAMPLES:.c=)
-.PHONY: examples
-examples: $(EXAMPLE_TARGETS)
-
-$(EXAMPLE_TARGETS): % : %.o
-       $(CC) $(CCFLAGS) -o $@ $< $(LDFLAGS) $(LIBS)
-
-%.o: %.c
-       $(CC) $(CCFLAGS) -c $< -o $@
-# build examples end
-
-.PHONY: clean
-clean:
-       cargo clean
-       rm -rf $(EXAMPLE_OBJECTS)
-       rm -rf $(EXAMPLE_TARGETS)
-       rm -rf $(OBJ_DIR)
-       rm -rf $(DOC_DIR)
-
diff --git a/bindings/c/examples/basic.c b/bindings/c/examples/basic.c
index af55faeea0..199403ca53 100644
--- a/bindings/c/examples/basic.c
+++ b/bindings/c/examples/basic.c
@@ -37,7 +37,7 @@ int main()
     };
 
     /* Write this into path "/testpath" */
-    opendal_error* error = opendal_operator_write(op, "/testpath", data);
+    opendal_error* error = opendal_operator_write(op, "/testpath", &data);
     assert(error == NULL);
 
     /* We can read it out, make sure the data is the same */
diff --git a/bindings/c/tests/bdd.cpp b/bindings/c/tests/bdd.cpp
index 65e97f52bf..16bea5f10e 100644
--- a/bindings/c/tests/bdd.cpp
+++ b/bindings/c/tests/bdd.cpp
@@ -133,9 +133,3 @@ TEST_F(OpendalBddTest, FeatureTest)
     error = opendal_operator_delete(this->p, "tmpdir/");
     EXPECT_EQ(error, nullptr);
 }
-
-int main(int argc, char** argv)
-{
-    ::testing::InitGoogleTest(&argc, argv);
-    return RUN_ALL_TESTS();
-}
diff --git a/bindings/c/tests/error_msg.cpp b/bindings/c/tests/error_msg.cpp
index 516d27865a..16bc57aaed 100644
--- a/bindings/c/tests/error_msg.cpp
+++ b/bindings/c/tests/error_msg.cpp
@@ -64,9 +64,3 @@ TEST_F(OpendalErrorTest, ErrorReadTest)
     // free the error
     opendal_error_free(r.error);
 }
-
-int main(int argc, char** argv)
-{
-    ::testing::InitGoogleTest(&argc, argv);
-    return RUN_ALL_TESTS();
-}
diff --git a/bindings/c/tests/list.cpp b/bindings/c/tests/list.cpp
index 3b64fef460..533fda7a81 100644
--- a/bindings/c/tests/list.cpp
+++ b/bindings/c/tests/list.cpp
@@ -119,9 +119,3 @@ TEST_F(OpendalListTest, ListEmptyDirTest) { }
 
 // todo: Try list a directory that does not exist
 TEST_F(OpendalListTest, ListNotExistDirTest) { }
-
-int main(int argc, char** argv)
-{
-    ::testing::InitGoogleTest(&argc, argv);
-    return RUN_ALL_TESTS();
-}
diff --git a/bindings/c/tests/opinfo.cpp b/bindings/c/tests/opinfo.cpp
index 9684b03604..4312a152a8 100644
--- a/bindings/c/tests/opinfo.cpp
+++ b/bindings/c/tests/opinfo.cpp
@@ -97,9 +97,3 @@ TEST_F(OpendalOperatorInfoTest, InfoTest)
     free(scheme);
     free(root);
 }
-
-int main(int argc, char** argv)
-{
-    ::testing::InitGoogleTest(&argc, argv);
-    return RUN_ALL_TESTS();
-}
diff --git a/bindings/zig/build.zig b/bindings/zig/build.zig
index fc1623ddce..b5d26bfa47 100644
--- a/bindings/zig/build.zig
+++ b/bindings/zig/build.zig
@@ -31,13 +31,12 @@ pub fn build(b: *std.Build) void {
     opendal_module.addIncludePath(b.path("../c/include"));
 
     // Creates a step for building the dependent C bindings
-    const libopendal_c = b.addSystemCommand(&[_][]const u8{
-        "make",
-        "-C",
-        "../c",
-        "build",
-    });
+    const libopendal_c_cmake = b.addSystemCommand(&[_][]const u8{ "cmake", 
"-S", "../c", "-B", "../c/build" });
+    const config_libopendal_c = b.step("libopendal_c_cmake", "Generate OpenDAL 
C binding CMake files");
+    config_libopendal_c.dependOn(&libopendal_c_cmake.step);
+    const libopendal_c = b.addSystemCommand(&[_][]const u8{ "make", "-C", 
"../c/build" });
     const build_libopendal_c = b.step("libopendal_c", "Build OpenDAL C 
bindings");
+    libopendal_c.step.dependOn(config_libopendal_c);
     build_libopendal_c.dependOn(&libopendal_c.step);
 
     // Creates a step for unit testing. This only builds the test executable

Reply via email to