Skip to content
Open
Show file tree
Hide file tree
Changes from 19 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
9ea48bb
Limit zvec C++ shared exports
feihongxu0824 Jun 23, 2026
086c3e7
Keep DiskAnnIndex symbols in core shared builds
feihongxu0824 Jun 23, 2026
a746c4c
Scope MSVC all-in-one exports to cloned objects
feihongxu0824 Jun 23, 2026
894fcca
Revert "Scope MSVC all-in-one exports to cloned objects"
feihongxu0824 Jun 23, 2026
33cc12d
Limit MSVC explicit exports to zvec all-in-one
feihongxu0824 Jun 23, 2026
2168115
Keep MSVC fts_bench on static zvec
feihongxu0824 Jun 23, 2026
c142bb2
Export core shared ABI helpers
feihongxu0824 Jun 23, 2026
6b88020
Export bundled public ABI on MSVC
feihongxu0824 Jun 24, 2026
bbcfe4d
Inline Float16 scalar conversions
feihongxu0824 Jun 24, 2026
5bafcc5
Merge main into windows explicit exports
feihongxu0824 Jul 21, 2026
f54a20e
Trim unnecessary PR diff
feihongxu0824 Jul 21, 2026
3a0dda9
Keep Float16 header-only
feihongxu0824 Jul 21, 2026
38476e8
Drop example shared import defines
feihongxu0824 Jul 21, 2026
d150b4e
Keep MSVC fts_bench on static zvec
feihongxu0824 Jul 21, 2026
edd1833
Apply explicit exports to all C++ shared libs
feihongxu0824 Jul 21, 2026
497a0ca
Keep DiskAnnIndex linkable when unsupported
feihongxu0824 Jul 21, 2026
d8c09d6
Limit explicit exports to zvec shared
feihongxu0824 Jul 21, 2026
2b6e417
Build Windows DLLs from scoped export objects
feihongxu0824 Jul 21, 2026
cd1576f
Propagate dependencies to object libraries
feihongxu0824 Jul 21, 2026
5b8c52d
fix: move exported parameter operations out of line
feihongxu0824 Jul 24, 2026
e49f2c0
style: format exported parameter definitions
feihongxu0824 Jul 24, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 47 additions & 5 deletions cmake/bazel.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@
## 1.3. Build a C/C++ static or shared library
## cc_library(
## NAME <name>
## [STATIC] [SHARED] [STRICT] [ALWAYS_LINK] [EXCLUDE] [PACKED] [SRCS_NO_GLOB]
## [STATIC] [SHARED] [OBJECTS] [STRICT] [ALWAYS_LINK] [EXCLUDE] [PACKED]
## [SRCS_NO_GLOB]
## SRCS <file1> [file2 ...]
## [INCS dir1 ...]
## [PUBINCS public_dir1 ...]
Expand All @@ -25,7 +26,10 @@
## [DEPS target1 ...]
## [PACKED_EXCLUDES pattern1 ...]
## [VERSION <version>]
## [EXPORT_DEF <definition>]
## )
## OBJECTS creates <name>_objects for a static library. EXPORT_DEF also
## creates <name>_export_objects from the same sources and build settings.
##
## 1.4. Build a C/C++ executable program
## cc_binary(
Expand Down Expand Up @@ -634,6 +638,14 @@ macro(_add_library _NAME _OPTION)
endif()
endmacro()

## Add a static library backed by an object library.
macro(_add_static_library_with_objects _NAME _OPTION)
add_library(${_NAME}_objects OBJECT ${_OPTION} ${ARGN})
add_library(
${_NAME} STATIC ${_OPTION} $<TARGET_OBJECTS:${_NAME}_objects>
)
endmacro()

## Link dependencies
function(_targets_link_dependencies _NAME)
foreach(LIB ${ARGN})
Expand Down Expand Up @@ -877,7 +889,9 @@ function(_cc_target_properties)
endif()

if(CC_ARGS_LIBS)
if(NOT TARGET_LINKABLE)
if("${TARGET_TYPE}" STREQUAL "OBJECT_LIBRARY")
target_link_libraries(${CC_ARGS_NAME} PRIVATE ${CC_ARGS_LIBS})
elseif(NOT TARGET_LINKABLE)
_targets_link_dependencies(${CC_ARGS_NAME} ${CC_ARGS_LIBS})
else()
if ("${TARGET_TYPE}" STREQUAL "EXECUTABLE")
Expand Down Expand Up @@ -918,9 +932,9 @@ endfunction()
## Build a C/C++ static or shared library
function(cc_library)
cmake_parse_arguments(
CC_ARGS
"STATIC;SHARED;EXCLUDE;PACKED;SRCS_NO_GLOB"
"NAME;VERSION"
CC_ARGS
"STATIC;SHARED;OBJECTS;EXCLUDE;PACKED;SRCS_NO_GLOB"
"NAME;VERSION;EXPORT_DEF"
"SRCS;INCS;PUBINCS;DEFS;LIBS;CFLAGS;CXXFLAGS;LDFLAGS;DEPS;PACKED_EXCLUDES"
${ARGN}
)
Expand Down Expand Up @@ -958,8 +972,16 @@ function(cc_library)
set(EXCLUDE_OPTION EXCLUDE_FROM_ALL)
endif()

if(CC_ARGS_OBJECTS AND (NOT CC_ARGS_STATIC OR CC_ARGS_SHARED))
message(FATAL_ERROR "OBJECTS requires a static-only cc_library target")
endif()

if(CC_ARGS_SHARED AND CC_ARGS_STATIC)
_add_library(${CC_ARGS_NAME} "${EXCLUDE_OPTION}" ${SOURCE_FILES})
elseif(CC_ARGS_OBJECTS)
_add_static_library_with_objects(
${CC_ARGS_NAME} "${EXCLUDE_OPTION}" ${SOURCE_FILES}
)
elseif(CC_ARGS_SHARED)
add_library(${CC_ARGS_NAME} SHARED ${EXCLUDE_OPTION} ${SOURCE_FILES})
elseif(CC_ARGS_STATIC)
Expand All @@ -982,6 +1004,26 @@ function(cc_library)
)
endif()

if(CC_ARGS_EXPORT_DEF)
if(NOT CC_ARGS_OBJECTS)
message(FATAL_ERROR "EXPORT_DEF requires OBJECTS for ${CC_ARGS_NAME}")
endif()
add_library(
${CC_ARGS_NAME}_export_objects OBJECT ${EXCLUDE_OPTION} ${SOURCE_FILES}
)
_cc_target_properties(
NAME "${CC_ARGS_NAME}_export_objects"
INCS "${CC_ARGS_INCS};${CC_ARGS_PUBINCS}"
DEFS "${CC_ARGS_DEFS};${CC_ARGS_EXPORT_DEF}"
LIBS "${CC_ARGS_LIBS}"
CFLAGS "${CC_ARGS_CFLAGS}"
CXXFLAGS "${CC_ARGS_CXXFLAGS}"
LDFLAGS "${CC_ARGS_LDFLAGS}"
DEPS "${CC_ARGS_DEPS}"
"${CC_ARGS_UNPARSED_ARGUMENTS}"
)
endif()

if(TARGET ${CC_ARGS_NAME}_static)
_cc_target_properties(
NAME "${CC_ARGS_NAME}_static"
Expand Down
73 changes: 66 additions & 7 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,14 @@ cc_directory(binding)
# Build ALL-IN-ONE C++ Shared Libraries
# =============================================================================
# Merges zvec internal static libraries into shared libraries while preserving
# C++ symbols for direct C++ linking.
# C++ symbols for direct C++ linking. Windows uses component-owned object
# variants so DLL export definitions never leak into static or plugin targets.

include(GNUInstallDirs)
find_package(Threads REQUIRED)

function(zvec_add_all_in_one_shared TARGET_NAME OUTPUT_NAME)
cmake_parse_arguments(ZVEC_ALLIN "" "" "LIBS" ${ARGN})
cmake_parse_arguments(ZVEC_ALLIN "" "" "LIBS;EXPORT_COMPONENTS" ${ARGN})
if(NOT ZVEC_ALLIN_LIBS)
message(FATAL_ERROR "zvec_add_all_in_one_shared requires LIBS")
endif()
Expand All @@ -31,6 +32,12 @@ function(zvec_add_all_in_one_shared TARGET_NAME OUTPUT_NAME)
message(FATAL_ERROR "Target ${ZVEC_ALLIN_LIB} is required by ${TARGET_NAME}")
endif()
endforeach()
foreach(ZVEC_ALLIN_EXPORT_COMPONENT ${ZVEC_ALLIN_EXPORT_COMPONENTS})
if(NOT ZVEC_ALLIN_EXPORT_COMPONENT IN_LIST ZVEC_ALLIN_LIBS)
message(FATAL_ERROR
"Export component ${ZVEC_ALLIN_EXPORT_COMPONENT} is not part of ${TARGET_NAME}")
endif()
endforeach()

file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/${TARGET_NAME}_stub.cc
"// Auto-generated stub for ${TARGET_NAME}\n"
Expand All @@ -43,26 +50,52 @@ function(zvec_add_all_in_one_shared TARGET_NAME OUTPUT_NAME)
set_target_properties(${TARGET_NAME} PROPERTIES
OUTPUT_NAME "${OUTPUT_NAME}"
POSITION_INDEPENDENT_CODE ON
WINDOWS_EXPORT_ALL_SYMBOLS ON
)
if(WIN32)
set_target_properties(${TARGET_NAME} PROPERTIES
WINDOWS_EXPORT_ALL_SYMBOLS OFF
)
endif()
if(WIN32)
set_target_properties(${TARGET_NAME} PROPERTIES
ARCHIVE_OUTPUT_NAME "${TARGET_NAME}"
)
endif()
target_compile_features(${TARGET_NAME} PUBLIC cxx_std_17)

if(MSVC)
if(WIN32)
foreach(ZVEC_ALLIN_LIB ${ZVEC_ALLIN_LIBS})
if(ZVEC_ALLIN_LIB IN_LIST ZVEC_ALLIN_EXPORT_COMPONENTS)
set(ZVEC_ALLIN_OBJECT_TARGET ${ZVEC_ALLIN_LIB}_export_objects)
else()
set(ZVEC_ALLIN_OBJECT_TARGET ${ZVEC_ALLIN_LIB}_objects)
endif()
if(NOT TARGET ${ZVEC_ALLIN_OBJECT_TARGET})
message(FATAL_ERROR
"Object target ${ZVEC_ALLIN_OBJECT_TARGET} is required by ${TARGET_NAME}")
endif()
target_sources(${TARGET_NAME} PRIVATE
$<TARGET_OBJECTS:${ZVEC_ALLIN_LIB}>
$<TARGET_OBJECTS:${ZVEC_ALLIN_OBJECT_TARGET}>
)
endforeach()

set(ZVEC_ALLIN_LINK_LIBS)
foreach(ZVEC_ALLIN_LIB ${ZVEC_ALLIN_LIBS})
get_target_property(ZVEC_ALLIN_LIB_DEPS ${ZVEC_ALLIN_LIB} LINK_LIBRARIES)
if(NOT ZVEC_ALLIN_LIB_DEPS)
continue()
endif()
foreach(ZVEC_ALLIN_LIB_DEP ${ZVEC_ALLIN_LIB_DEPS})
if(NOT ZVEC_ALLIN_LIB_DEP IN_LIST ZVEC_ALLIN_LIBS)
list(APPEND ZVEC_ALLIN_LINK_LIBS ${ZVEC_ALLIN_LIB_DEP})
endif()
endforeach()
endforeach()
list(APPEND ZVEC_ALLIN_LINK_LIBS Threads::Threads)
list(REMOVE_DUPLICATES ZVEC_ALLIN_LINK_LIBS)
target_link_libraries(${TARGET_NAME}
PRIVATE
${ZVEC_ALLIN_LIBS}
Threads::Threads
${ZVEC_ALLIN_LINK_LIBS}
)
elseif(APPLE)
foreach(ZVEC_ALLIN_LIB ${ZVEC_ALLIN_LIBS})
Expand Down Expand Up @@ -122,6 +155,23 @@ function(zvec_add_all_in_one_shared TARGET_NAME OUTPUT_NAME)
${PROJECT_SOURCE_DIR}/src
)

set(ZVEC_ALLIN_USE_DEFS)
foreach(ZVEC_ALLIN_LIB ${ZVEC_ALLIN_EXPORT_COMPONENTS})
if(ZVEC_ALLIN_LIB STREQUAL zvec)
list(APPEND ZVEC_ALLIN_USE_DEFS ZVEC_DB_USE_SHARED)
elseif(ZVEC_ALLIN_LIB STREQUAL zvec_core)
list(APPEND ZVEC_ALLIN_USE_DEFS ZVEC_CORE_USE_SHARED)
elseif(ZVEC_ALLIN_LIB STREQUAL zvec_ailego)
list(APPEND ZVEC_ALLIN_USE_DEFS ZVEC_AILEGO_USE_SHARED)
elseif(ZVEC_ALLIN_LIB STREQUAL zvec_turbo)
list(APPEND ZVEC_ALLIN_USE_DEFS ZVEC_TURBO_USE_SHARED)
endif()
endforeach()
if(ZVEC_ALLIN_USE_DEFS)
list(REMOVE_DUPLICATES ZVEC_ALLIN_USE_DEFS)
target_compile_definitions(${TARGET_NAME} INTERFACE ${ZVEC_ALLIN_USE_DEFS})
endif()

# Strip symbols in release builds to reduce library size.
if(NOT CMAKE_BUILD_TYPE STREQUAL "Debug")
if(UNIX AND NOT APPLE)
Expand All @@ -148,6 +198,8 @@ if(BUILD_ZVEC_AILEGO_SHARED)
zvec_add_all_in_one_shared(zvec_ailego_shared zvec_ailego
LIBS
zvec_ailego
EXPORT_COMPONENTS
zvec_ailego
)
endif()

Expand All @@ -157,6 +209,10 @@ if(BUILD_ZVEC_CORE_SHARED)
zvec_core
zvec_ailego
zvec_turbo
EXPORT_COMPONENTS
zvec_core
zvec_ailego
zvec_turbo
)
endif()

Expand All @@ -167,5 +223,8 @@ if(BUILD_ZVEC_SHARED)
zvec_core
zvec_ailego
zvec_turbo
EXPORT_COMPONENTS
zvec
Comment thread
richyreachy marked this conversation as resolved.
zvec_ailego
)
endif()
11 changes: 10 additions & 1 deletion src/ailego/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -117,8 +117,17 @@ if(NOT ANDROID AND AUTO_DETECT_ARCH)
endif()
endif()

set(ZVEC_AILEGO_LIBRARY_OPTIONS)
if(WIN32 AND
(BUILD_ZVEC_AILEGO_SHARED OR BUILD_ZVEC_CORE_SHARED OR BUILD_ZVEC_SHARED))
list(APPEND ZVEC_AILEGO_LIBRARY_OPTIONS
OBJECTS
EXPORT_DEF ZVEC_AILEGO_BUILD_SHARED
)
endif()

cc_library(
NAME zvec_ailego STATIC STRICT PACKED
NAME zvec_ailego STATIC STRICT PACKED ${ZVEC_AILEGO_LIBRARY_OPTIONS}
SRCS ${ALL_SRCS}
LIBS ${EXTRA_LIBS}
VERSION "${GIT_SRCS_VER}"
Expand Down
41 changes: 40 additions & 1 deletion src/ailego/utility/time_helper.cc
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,45 @@ size_t Realtime::Gmtime(const char *format, char *buf, size_t len) {
time_t now = time(0);
return strftime(buf, len, format, gmtime(&now));
}

namespace {

uint64_t FileTimeToTicks(FILETIME file_time) {
ULARGE_INTEGER value;
value.LowPart = file_time.dwLowDateTime;
value.HighPart = file_time.dwHighDateTime;
return value.QuadPart;
}

uint64_t CurrentThreadCpuTime100NanoSeconds(void) {
FILETIME creation_time;
FILETIME exit_time;
FILETIME kernel_time;
FILETIME user_time;
if (!GetThreadTimes(GetCurrentThread(), &creation_time, &exit_time,
&kernel_time, &user_time)) {
return 0;
}
return FileTimeToTicks(kernel_time) + FileTimeToTicks(user_time);
}

} // namespace

uint64_t CPUtime::NanoSeconds(void) {
return CurrentThreadCpuTime100NanoSeconds() * 100u;
}

uint64_t CPUtime::MicroSeconds(void) {
return CurrentThreadCpuTime100NanoSeconds() / 10u;
}

uint64_t CPUtime::MilliSeconds(void) {
return CurrentThreadCpuTime100NanoSeconds() / 10000u;
}

uint64_t CPUtime::Seconds(void) {
return CurrentThreadCpuTime100NanoSeconds() / 10000000u;
}
#else
uint64_t Monotime::NanoSeconds(void) {
struct timespec tspec;
Expand Down Expand Up @@ -212,4 +251,4 @@ uint64_t CPUtime::Seconds(void) {
#endif // _WIN64 || _WIN32

} // namespace ailego
} // namespace zvec
} // namespace zvec
1 change: 1 addition & 0 deletions src/binding/c/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ add_library(zvec_c_api SHARED
set_target_properties(zvec_c_api PROPERTIES
OUTPUT_NAME "zvec_c_api"
POSITION_INDEPENDENT_CODE ON
WINDOWS_EXPORT_ALL_SYMBOLS OFF
# Hide all symbols by default, only export C API
CXX_VISIBILITY_PRESET hidden
VISIBILITY_INLINES_HIDDEN ON
Expand Down
23 changes: 18 additions & 5 deletions src/core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -61,16 +61,19 @@ if(NOT RABITQ_SUPPORTED)
endif()

# Exclude algorithm/diskann implementation files from zvec_core when not
# supported (matching the hnsw_rabitq pattern above). When DISKANN_SUPPORTED,
# the diskann sources are packed into zvec_core directly, so libzvec_core.so
# includes diskann symbols without needing a separate whole-archive step.
# supported. Keep interface/indexes/diskann_index.cc in the core library so
# unsupported platforms still provide DiskAnnIndex's vtable and return
# IndexError_Unsupported from its guarded stubs.
#
# When DISKANN_SUPPORTED, the diskann sources are packed into zvec_core
# directly, so libzvec_core.so includes diskann symbols without needing a
# separate whole-archive step.
# The standalone core_knn_diskann library (built by algorithm/diskann) is still
# whole-archived into _zvec.so; since _zvec.so links zvec_core *normally*
# (not --whole-archive), the linker skips zvec_core's diskann objects there
# (symbols already resolved by core_knn_diskann_static) — no duplicates.
if(NOT DISKANN_SUPPORTED)
list(FILTER ALL_CORE_SRCS EXCLUDE REGEX ".*/algorithm/diskann/.*")
list(FILTER ALL_CORE_SRCS EXCLUDE REGEX ".*/interface/indexes/diskann_index\\.cc")
endif()

set(ZVEC_CORE_LIBS zvec_ailego zvec_turbo sparsehash magic_enum rabitqlib)
Expand All @@ -79,8 +82,18 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
list(APPEND ZVEC_CORE_LIBS ${CMAKE_DL_LIBS})
endif()

set(ZVEC_CORE_LIBRARY_OPTIONS)
if(WIN32 AND (BUILD_ZVEC_CORE_SHARED OR BUILD_ZVEC_SHARED))
list(APPEND ZVEC_CORE_LIBRARY_OPTIONS OBJECTS)
if(BUILD_ZVEC_CORE_SHARED)
list(APPEND ZVEC_CORE_LIBRARY_OPTIONS
EXPORT_DEF ZVEC_CORE_BUILD_SHARED
Comment thread
richyreachy marked this conversation as resolved.
)
endif()
endif()

cc_library(
NAME zvec_core STATIC STRICT PACKED
NAME zvec_core STATIC STRICT PACKED ${ZVEC_CORE_LIBRARY_OPTIONS}
SRCS ${ALL_CORE_SRCS}
LIBS ${ZVEC_CORE_LIBS}
INCS . ${PROJECT_ROOT_DIR}/src/core
Expand Down
Loading