Skip to content

Commit

Permalink
build(bindings/c): replace the build system with CMake (#5182)
Browse files Browse the repository at this point in the history
  • Loading branch information
PragmaTwice authored Oct 15, 2024
1 parent 2a332f3 commit 737012f
Show file tree
Hide file tree
Showing 9 changed files with 101 additions and 105 deletions.
21 changes: 5 additions & 16 deletions .github/workflows/ci_bindings_c.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
90 changes: 90 additions & 0 deletions bindings/c/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -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()
58 changes: 0 additions & 58 deletions bindings/c/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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)

2 changes: 1 addition & 1 deletion bindings/c/examples/basic.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down
6 changes: 0 additions & 6 deletions bindings/c/tests/bdd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
6 changes: 0 additions & 6 deletions bindings/c/tests/error_msg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
6 changes: 0 additions & 6 deletions bindings/c/tests/list.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
6 changes: 0 additions & 6 deletions bindings/c/tests/opinfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
11 changes: 5 additions & 6 deletions bindings/zig/build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 737012f

Please sign in to comment.