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