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