Skip to content

Commit ed8c010

Browse files
chinauxkdy1
andauthored
feat: add c language support (alibaba#167)
* init branch Add GitHub Actions release workflow for C API add release linux-arm64 remove c api version refact some code add api reference * feat(c-api): add nullable/doc-result APIs for agency migration (alibaba#234) * Flattened index parameters structure * refact c api code * remove RAII guard * refact use opaque pointer pattern * refact version info * refact use pure opaque pointers * use typedef instead of enum * fix set_last_error * fix build yml * fix doc.h * remove wheel exclude * fix c msvc link * remove release yml * fix c link libstdc++ * fix c link libgcc --------- Co-authored-by: Donny/강동윤 <kdy.1997.dev@gmail.com>
1 parent 8182cff commit ed8c010

23 files changed

Lines changed: 18771 additions & 8 deletions

.github/workflows/03-macos-linux-build.yml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,3 +125,17 @@ jobs:
125125
./core-example
126126
./ailego-example
127127
shell: bash
128+
129+
- name: Run C Examples
130+
run: |
131+
cd "$GITHUB_WORKSPACE/examples/c"
132+
mkdir build && cd build
133+
cmake .. -DCMAKE_BUILD_TYPE=Release
134+
make -j $NPROC
135+
./c_api_basic_example
136+
./c_api_collection_schema_example
137+
./c_api_doc_example
138+
./c_api_field_schema_example
139+
./c_api_index_example
140+
./c_api_optimized_example
141+
shell: bash

CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,9 @@ include_directories(${PROJECT_ROOT_DIR})
5959
option(BUILD_PYTHON_BINDINGS "Build Python bindings using pybind11" OFF)
6060
message(STATUS "BUILD_PYTHON_BINDINGS:${BUILD_PYTHON_BINDINGS}")
6161

62+
option(BUILD_C_BINDINGS "Build C bindings" ON)
63+
message(STATUS "BUILD_C_BINDINGS:${BUILD_C_BINDINGS}")
64+
6265
option(BUILD_TOOLS "Build tools" ON)
6366
message(STATUS "BUILD_TOOLS:${BUILD_TOOLS}")
6467

examples/c/CMakeLists.txt

Lines changed: 209 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,209 @@
1+
# Copyright 2025-present the zvec project
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
cmake_minimum_required(VERSION 3.13)
16+
cmake_policy(SET CMP0077 NEW)
17+
project(zvec-example-c)
18+
set(CMAKE_C_STANDARD 99)
19+
set(CMAKE_C_STANDARD_REQUIRED ON)
20+
21+
# Enable compile_commands.json
22+
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
23+
24+
# --- Paths to Zvec and dependencies ---
25+
# Allow custom host build directory, default to "build"
26+
if(NOT DEFINED HOST_BUILD_DIR)
27+
set(HOST_BUILD_DIR "build")
28+
endif()
29+
30+
set(ZVEC_INCLUDE_DIR ${CMAKE_BINARY_DIR}/../../../src/include)
31+
set(ZVEC_GENERATED_INCLUDE_DIR ${CMAKE_BINARY_DIR}/../../../${HOST_BUILD_DIR}/src/generated)
32+
33+
# On Windows, libraries are in Debug/Release subdirectories
34+
if(WIN32)
35+
set(ZVEC_LIB_DIR ${CMAKE_BINARY_DIR}/../../../${HOST_BUILD_DIR}/lib/$<CONFIG>)
36+
set(ZVEC_DEPENDENCY_LIB_DIR ${CMAKE_BINARY_DIR}/../../../${HOST_BUILD_DIR}/external/usr/local/lib/$<CONFIG>)
37+
else()
38+
set(ZVEC_LIB_DIR ${CMAKE_BINARY_DIR}/../../../${HOST_BUILD_DIR}/lib)
39+
set(ZVEC_DEPENDENCY_LIB_DIR ${CMAKE_BINARY_DIR}/../../../${HOST_BUILD_DIR}/external/usr/local/lib)
40+
endif()
41+
42+
# Add include and library search paths
43+
include_directories(${ZVEC_INCLUDE_DIR} ${ZVEC_GENERATED_INCLUDE_DIR})
44+
link_directories(${ZVEC_LIB_DIR} ${ZVEC_DEPENDENCY_LIB_DIR})
45+
46+
# Find required packages
47+
find_package(Threads REQUIRED)
48+
49+
# --- Determine debug/release library names ---
50+
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
51+
set(GLOG_LIB glogd)
52+
set(GFLAGS_LIB gflags_nothreads_debug)
53+
set(PROTOBUF_LIB protobufd)
54+
else()
55+
set(GLOG_LIB glog)
56+
set(GFLAGS_LIB gflags_nothreads)
57+
set(PROTOBUF_LIB protobuf)
58+
endif()
59+
60+
# --- Dependency groups ---
61+
if(NOT WIN32)
62+
set(zvec_c_api_deps
63+
roaring
64+
rocksdb
65+
arrow
66+
arrow_acero
67+
arrow_bundled_dependencies
68+
arrow_compute
69+
arrow_dataset
70+
parquet
71+
antlr4-runtime
72+
${GLOG_LIB}
73+
${GFLAGS_LIB}
74+
${PROTOBUF_LIB}
75+
lz4
76+
${CMAKE_THREAD_LIBS_INIT}
77+
${CMAKE_DL_LIBS}
78+
)
79+
else()
80+
# Windows static libraries use different naming conventions
81+
set(PROTOBUF_LIB libprotobuf)
82+
set(zvec_c_api_deps
83+
roaring
84+
rocksdb
85+
arrow_static
86+
arrow_acero_static
87+
arrow_bundled_dependencies
88+
arrow_compute_static
89+
arrow_dataset_static
90+
parquet_static
91+
antlr4-runtime-static
92+
${GLOG_LIB}
93+
${GFLAGS_LIB}
94+
${PROTOBUF_LIB}
95+
lz4
96+
${CMAKE_THREAD_LIBS_INIT}
97+
rpcrt4
98+
shlwapi
99+
)
100+
endif()
101+
102+
# Create INTERFACE target for zvec_c_api with platform-specific linking
103+
add_library(zvec-c-api INTERFACE)
104+
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
105+
target_link_libraries(zvec-c-api INTERFACE
106+
-Wl,--whole-archive
107+
-lzvec_c_api
108+
-Wl,--no-whole-archive
109+
-Wl,--start-group
110+
${zvec_c_api_deps}
111+
-Wl,--end-group
112+
)
113+
elseif(APPLE)
114+
# On macOS, use -Wl,-force_load with full path to ensure all symbols are loaded
115+
target_link_libraries(zvec-c-api INTERFACE
116+
-Wl,-force_load
117+
${ZVEC_LIB_DIR}/libzvec_c_api.dylib
118+
${zvec_c_api_deps}
119+
)
120+
# Set rpath so the executable can find the dylib at runtime
121+
target_link_options(zvec-c-api INTERFACE
122+
-Wl,-rpath,${ZVEC_LIB_DIR}
123+
)
124+
elseif(ANDROID)
125+
target_link_libraries(zvec-c-api INTERFACE
126+
-Wl,--whole-archive
127+
-lzvec_c_api
128+
-Wl,--no-whole-archive
129+
-Wl,--start-group
130+
${zvec_c_api_deps}
131+
-Wl,--end-group
132+
)
133+
elseif(WIN32)
134+
target_link_libraries(zvec-c-api INTERFACE
135+
zvec_c_api
136+
${zvec_c_api_deps}
137+
)
138+
target_link_options(zvec-c-api INTERFACE "/WHOLEARCHIVE:zvec_c_api")
139+
else()
140+
message(FATAL_ERROR "Unsupported platform: ${CMAKE_SYSTEM_NAME}")
141+
endif()
142+
143+
# Basic example
144+
add_executable(c_api_basic_example basic_example.c)
145+
target_link_libraries(c_api_basic_example PRIVATE
146+
zvec-c-api
147+
)
148+
149+
# Schema example
150+
add_executable(c_api_collection_schema_example collection_schema_example.c)
151+
target_link_libraries(c_api_collection_schema_example PRIVATE
152+
zvec-c-api
153+
)
154+
155+
# Struct document example
156+
add_executable(c_api_doc_example doc_example.c)
157+
target_link_libraries(c_api_doc_example PRIVATE
158+
zvec-c-api
159+
)
160+
161+
# Index example
162+
add_executable(c_api_index_example index_example.c)
163+
target_link_libraries(c_api_index_example PRIVATE
164+
zvec-c-api
165+
)
166+
167+
# Field schema example
168+
add_executable(c_api_field_schema_example field_schema_example.c)
169+
target_link_libraries(c_api_field_schema_example PRIVATE
170+
zvec-c-api
171+
)
172+
173+
# Optimized example
174+
add_executable(c_api_optimized_example optimized_example.c)
175+
target_link_libraries(c_api_optimized_example PRIVATE
176+
zvec-c-api
177+
)
178+
179+
# Strip symbols to reduce executable size
180+
if(CMAKE_BUILD_TYPE STREQUAL "Release" AND (ANDROID OR (CMAKE_SYSTEM_NAME STREQUAL "Linux")))
181+
add_custom_command(TARGET c_api_basic_example POST_BUILD
182+
COMMAND ${CMAKE_STRIP} "$<TARGET_FILE:c_api_basic_example>"
183+
COMMENT "Stripping symbols from c_api_basic_example")
184+
add_custom_command(TARGET c_api_collection_schema_example POST_BUILD
185+
COMMAND ${CMAKE_STRIP} "$<TARGET_FILE:c_api_collection_schema_example>"
186+
COMMENT "Stripping symbols from c_api_collection_schema_example")
187+
add_custom_command(TARGET c_api_doc_example POST_BUILD
188+
COMMAND ${CMAKE_STRIP} "$<TARGET_FILE:c_api_doc_example>"
189+
COMMENT "Stripping symbols from c_api_doc_example")
190+
add_custom_command(TARGET c_api_index_example POST_BUILD
191+
COMMAND ${CMAKE_STRIP} "$<TARGET_FILE:c_api_index_example>"
192+
COMMENT "Stripping symbols from c_api_index_example")
193+
add_custom_command(TARGET c_api_field_schema_example POST_BUILD
194+
COMMAND ${CMAKE_STRIP} "$<TARGET_FILE:c_api_field_schema_example>"
195+
COMMENT "Stripping symbols from c_api_field_schema_example")
196+
add_custom_command(TARGET c_api_optimized_example POST_BUILD
197+
COMMAND ${CMAKE_STRIP} "$<TARGET_FILE:c_api_optimized_example>"
198+
COMMENT "Stripping symbols from c_api_optimized_example")
199+
endif()
200+
201+
# Optimize for size
202+
if(CMAKE_BUILD_TYPE STREQUAL "Release" AND ANDROID)
203+
set_property(TARGET c_api_basic_example c_api_collection_schema_example c_api_doc_example
204+
c_api_index_example c_api_field_schema_example c_api_optimized_example
205+
PROPERTY COMPILE_FLAGS "-Os")
206+
set_property(TARGET c_api_basic_example c_api_collection_schema_example c_api_doc_example
207+
c_api_index_example c_api_field_schema_example c_api_optimized_example
208+
PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE)
209+
endif()

0 commit comments

Comments
 (0)