include(${PROJECT_ROOT_DIR}/cmake/bazel.cmake)
include(${PROJECT_ROOT_DIR}/cmake/option.cmake)

# utility/block_heap.cc uses AVX2 intrinsics guarded by __AVX2__. When the
# host toolchain supports it, compile this source with an AVX2-capable
# -march so AVX2 codegen is emitted. zvec_core glob-collects this source
# too, so per-file flags must be set here as well (in addition to the
# core_utility target in utility/CMakeLists.txt). Callers runtime-gate
# invocation of BlockHeap paths on CpuFeatures::AVX2.
if(NOT ANDROID AND AUTO_DETECT_ARCH)
  if(HOST_ARCH MATCHES "^(x86|x64)$")
    setup_compiler_march_for_x86(
        _BLOCK_HEAP_MARCH_SSE _BLOCK_HEAP_MARCH_AVX2
        _BLOCK_HEAP_MARCH_AVX512 _BLOCK_HEAP_MARCH_AVX512FP16)
    if(_BLOCK_HEAP_MARCH_AVX2)
      set_source_files_properties(
          utility/block_heap.cc
          PROPERTIES
          COMPILE_FLAGS "${_BLOCK_HEAP_MARCH_AVX2}"
      )
    endif()
  endif()
endif()

cc_directory(framework)
cc_directory(algorithm)
cc_directory(metric)
cc_directory(quantizer)
cc_directory(utility)
cc_directory(interface)
cc_directory(mixed_reducer)

file(GLOB_RECURSE ALL_CORE_SRCS *.cc *.c *.h)

# Remove algorithm/hnsw_rabitq implementation files if not supported.
# interface/indexes/hnsw_rabitq_index.cc is kept because it provides the vtable
# for HNSWRabitqIndex and guards rabitqlib usage with #if RABITQ_SUPPORTED.
if(NOT RABITQ_SUPPORTED)
  list(FILTER ALL_CORE_SRCS EXCLUDE REGEX ".*/algorithm/hnsw_rabitq/.*")
  list(FILTER ALL_CORE_SRCS EXCLUDE REGEX ".*/algorithm/ivf_rabitq/.*")
endif()

# Keep the guarded DiskAnn interface available everywhere, but pack its
# implementation into zvec_core only on supported platforms.
if(NOT DISKANN_SUPPORTED)
  list(FILTER ALL_CORE_SRCS EXCLUDE REGEX ".*/algorithm/diskann/.*")
endif()

set(ZVEC_CORE_LIBS zvec_ailego zvec_turbo sparsehash magic_enum rabitqlib)
# The DiskAnn runtime loader uses dlopen/dlsym, so link libdl on Linux.
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
    )
  endif()
endif()

cc_library(
    NAME zvec_core STATIC STRICT PACKED ${ZVEC_CORE_LIBRARY_OPTIONS}
    SRCS ${ALL_CORE_SRCS}
    LIBS ${ZVEC_CORE_LIBS}
    INCS . ${PROJECT_ROOT_DIR}/src/core
    VERSION "${ZVEC_VERSION_STRING}"
)
