Skip to content

Commit 06c6b06

Browse files
committed
Improve VSAG's compatibility with macOS
Signed-off-by: stuBirdFly <[email protected]>
1 parent 987bac1 commit 06c6b06

File tree

216 files changed

+2731
-2532
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

216 files changed

+2731
-2532
lines changed

CMakeLists.txt

Lines changed: 55 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -73,24 +73,28 @@ option (DISABLE_NEON_FORCE "Force disable neon instructions" OFF)
7373
option (DISABLE_SVE_FORCE "Force disable sve instructions" OFF)
7474
# AIO library configuration
7575
option (ENABLE_LIBAIO "Whether to enable libaio support" ON)
76+
if (NOT APPLE)
77+
if (ENABLE_CXX11_ABI)
78+
add_definitions (-D_GLIBCXX_USE_CXX11_ABI=1)
79+
message (STATUS "Using libstdc++ with ${Yellow}C++11 ABI${CR}")
80+
else ()
81+
add_definitions (-D_GLIBCXX_USE_CXX11_ABI=0)
82+
message (STATUS "Using libstdc++ with ${Yellow}pre-C++11 ABI${CR}")
7683

77-
if (ENABLE_CXX11_ABI)
78-
add_definitions (-D_GLIBCXX_USE_CXX11_ABI=1)
79-
message (STATUS "Using libstdc++ with ${Yellow}C++11 ABI${CR}")
80-
else ()
81-
add_definitions (-D_GLIBCXX_USE_CXX11_ABI=0)
82-
message (STATUS "Using libstdc++ with ${Yellow}pre-C++11 ABI${CR}")
83-
84-
# for avoiding symbol conflict: _Rep::_S_create
85-
vsag_add_shared_linker_flag(-fvisibility-inlines-hidden)
84+
# for avoiding symbol conflict: _Rep::_S_create
85+
vsag_add_shared_linker_flag(-fvisibility-inlines-hidden)
86+
endif ()
8687
endif ()
8788

8889
if (ENABLE_WERROR)
8990
add_compile_options (-Werror)
9091
endif ()
9192

92-
vsag_add_exe_linker_flag (-static-libstdc++)
93-
vsag_add_shared_linker_flag (-static-libstdc++)
93+
# On Apple platforms, use the system's libc++ instead of static linking libstdc++
94+
if (NOT APPLE)
95+
vsag_add_exe_linker_flag (-static-libstdc++)
96+
vsag_add_shared_linker_flag (-static-libstdc++)
97+
endif ()
9498
vsag_add_shared_linker_flag (-fvisibility=hidden)
9599

96100
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
@@ -107,25 +111,30 @@ else ()
107111
endif ()
108112
endif ()
109113

110-
if (ENABLE_LIBCXX)
114+
if (ENABLE_LIBCXX OR APPLE)
111115
message (STATUS "Using libc++ with C++11 ABI")
112-
113-
set (LIBCXX_SEARCH_PATH /opt/alibaba-cloud-compiler/lib64)
114-
find_library (LIBCXX_STATIC libc++.a PATHS ${LIBCXX_SEARCH_PATH})
115-
find_library (LIBCXXABI_STATIC libc++abi.a PATHS ${LIBCXX_SEARCH_PATH})
116-
if (LIBCXX_STATIC AND LIBCXXABI_STATIC)
117-
get_filename_component (LIBCXX_DIR "${LIBCXX_STATIC}" DIRECTORY)
118-
message (STATUS "Found libc++ at ${LIBCXX_STATIC}")
119-
message (STATUS "Found libc++abi at ${LIBCXXABI_STATIC}")
120-
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
121-
122-
vsag_add_shared_linker_flag ("-fuse-ld=lld")
123-
vsag_add_shared_linker_flag ("-Wl,-rpath,${LIBCXX_DIR}")
124-
vsag_add_exe_linker_flag ("-fuse-ld=lld")
125-
vsag_add_exe_linker_flag ("-Wl,-rpath,${LIBCXX_DIR}")
126-
set (CMAKE_CXX_STANDARD_LIBRARIES "${CMAKE_CXX_STANDARD_LIBRARIES} ${LIBCXX_STATIC} ${LIBCXXABI_STATIC}")
127-
else ()
128-
message (FATAL_ERROR "libc++ or libc++abi not found")
116+
if (APPLE)
117+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
118+
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -stdlib=libc++")
119+
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -stdlib=libc++")
120+
else()
121+
set (LIBCXX_SEARCH_PATH /opt/alibaba-cloud-compiler/lib64)
122+
find_library (LIBCXX_STATIC libc++.a PATHS ${LIBCXX_SEARCH_PATH})
123+
find_library (LIBCXXABI_STATIC libc++abi.a PATHS ${LIBCXX_SEARCH_PATH})
124+
if (LIBCXX_STATIC AND LIBCXXABI_STATIC)
125+
get_filename_component (LIBCXX_DIR "${LIBCXX_STATIC}" DIRECTORY)
126+
message (STATUS "Found libc++ at ${LIBCXX_STATIC}")
127+
message (STATUS "Found libc++abi at ${LIBCXXABI_STATIC}")
128+
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
129+
130+
vsag_add_shared_linker_flag ("-fuse-ld=lld")
131+
vsag_add_shared_linker_flag ("-Wl,-rpath,${LIBCXX_DIR}")
132+
vsag_add_exe_linker_flag ("-fuse-ld=lld")
133+
vsag_add_exe_linker_flag ("-Wl,-rpath,${LIBCXX_DIR}")
134+
set (CMAKE_CXX_STANDARD_LIBRARIES "${CMAKE_CXX_STANDARD_LIBRARIES} ${LIBCXX_STATIC} ${LIBCXXABI_STATIC}")
135+
else ()
136+
message (FATAL_ERROR "libc++ or libc++abi not found")
137+
endif ()
129138
endif ()
130139
else ()
131140
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
@@ -202,17 +211,17 @@ set (common_cmake_args
202211
"-DCMAKE_INCLUDE_PATH=${CMAKE_INSTALL_PREFIX}/include"
203212
"-DCMAKE_LIBRARY_PATH=${CMAKE_INSTALL_PREFIX}/lib:/opt/alibaba-cloud-compiler/lib64"
204213
)
205-
206-
set (common_configure_envs
207-
"env"
208-
"CC=${CMAKE_C_COMPILER}"
209-
"CXX=${CMAKE_CXX_COMPILER}"
210-
"CFLAGS=${CMAKE_C_FLAGS} -fno-omit-frame-pointer -fPIC -O2 -D_DEFAULT_SOURCE -D_GNU_SOURCE -gdwarf-4"
211-
"CXXFLAGS=${CMAKE_CXX_FLAGS} -fno-omit-frame-pointer -fPIC -O2 -D_DEFAULT_SOURCE -D_GNU_SOURCE -gdwarf-4"
212-
"CPPFLAGS=-isystem ${CMAKE_INSTALL_PREFIX}/include"
213-
"LDFLAGS=-Wl,-rpath=\\\\$\\$ORIGIN ${ld_flags}"
214-
"PATH=${BUILDING_PATH}:$ENV{PATH}"
215-
"ACLOCAL_PATH=${ACLOCAL_PATH}"
214+
include (cmake/DarwinDep.cmake)
215+
set(common_configure_envs
216+
"env"
217+
"CC=${CMAKE_C_COMPILER}"
218+
"CXX=${CMAKE_CXX_COMPILER}"
219+
"CFLAGS=${CMAKE_C_FLAGS} -fno-omit-frame-pointer -fPIC -O2 -D_DEFAULT_SOURCE -D_GNU_SOURCE -gdwarf-4"
220+
"CXXFLAGS=${CMAKE_CXX_FLAGS} -fno-omit-frame-pointer -fPIC -O2 -D_DEFAULT_SOURCE -D_GNU_SOURCE -gdwarf-4"
221+
"CPPFLAGS=-isystem ${CMAKE_INSTALL_PREFIX}/include"
222+
"LDFLAGS=${ld_flags_workaround} ${ld_flags}" # Use the workaround for LDFLAGS
223+
"PATH=${BUILDING_PATH}:$ENV{PATH}"
224+
"ACLOCAL_PATH=${ACLOCAL_PATH}"
216225
)
217226

218227
# set the default compilation parallelism of thirdparties
@@ -319,7 +328,9 @@ endif ()
319328

320329
# sources
321330
add_subdirectory (src)
322-
add_subdirectory (mockimpl)
331+
if (NOT APPLE)
332+
add_subdirectory (mockimpl)
333+
endif ()
323334
if (ENABLE_EXAMPLES)
324335
add_subdirectory (examples/cpp)
325336
endif ()
@@ -353,7 +364,9 @@ if (ENABLE_PYBINDS)
353364
pybind11_add_module (_pyvsag python_bindings/binding.cpp)
354365
target_compile_options (_pyvsag PRIVATE -fopenmp)
355366
target_link_libraries (_pyvsag PRIVATE pybind11::module vsag)
356-
target_link_options(_pyvsag PRIVATE -static-libstdc++ -static-libgcc)
367+
if (NOT APPLE)
368+
target_link_options(_pyvsag PRIVATE -static-libstdc++ -static-libgcc)
369+
endif ()
357370

358371
message(STATUS "Building _pyvsag for Python ${Python3_VERSION}")
359372
message(STATUS "Expected output: _pyvsag${Python3_SOABI}${CMAKE_SHARED_MODULE_SUFFIX}")

Makefile

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@ ifdef EXTRA_DEFINED
1919
endif
2020
VSAG_CMAKE_ARGS := ${VSAG_CMAKE_ARGS} -G ${CMAKE_GENERATOR} -S.
2121

22+
UNAME_S := $(shell uname -s)
23+
ifeq ($(UNAME_S),Darwin)
24+
VSAG_CMAKE_ARGS := ${VSAG_CMAKE_ARGS} -DENABLE_LIBCXX=ON -DENABLE_WERROR=OFF -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++
25+
endif
26+
2227
UT_FILTER = ""
2328
ifdef CASE
2429
UT_FILTER = $(CASE)

cmake/DarwinDep.cmake

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
2+
# Copyright 2025-present the vsag project
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
16+
if(APPLE)
17+
set(ld_flags_workaround "-Wl,-rpath,@loader_path")
18+
# Find OpenMP - will locate libomp on macOS
19+
find_package(OpenMP REQUIRED)
20+
if (OpenMP_CXX_FOUND)
21+
message(STATUS "Found OpenMP: ${OpenMP_CXX_INCLUDE_DIRS}")
22+
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
23+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
24+
endif()
25+
26+
# Find LAPACK - will automatically use Accelerate framework on macOS
27+
find_package(LAPACK)
28+
if (LAPACK_FOUND)
29+
message(STATUS "Found LAPACK (using Accelerate framework on macOS)")
30+
# LAPACK libraries are in LAPACK_LIBRARIES variable
31+
else()
32+
message(WARNING "LAPACK not found")
33+
endif()
34+
35+
# Find gfortran and its library path for OpenBLAS
36+
find_program(GFORTRAN_EXECUTABLE NAMES gfortran)
37+
if(GFORTRAN_EXECUTABLE)
38+
execute_process(
39+
COMMAND ${GFORTRAN_EXECUTABLE} -print-file-name=libgfortran.dylib
40+
OUTPUT_VARIABLE GFORTRAN_LIB
41+
OUTPUT_STRIP_TRAILING_WHITESPACE
42+
)
43+
if(EXISTS "${GFORTRAN_LIB}" AND NOT IS_DIRECTORY "${GFORTRAN_LIB}")
44+
get_filename_component(GFORTRAN_LIB_DIR "${GFORTRAN_LIB}" DIRECTORY)
45+
list(APPEND CMAKE_INSTALL_RPATH "${GFORTRAN_LIB_DIR}")
46+
else()
47+
unset(GFORTRAN_LIB)
48+
message(WARNING "gfortran found but libgfortran.dylib not found via -print-file-name; OpenBLAS link may fail")
49+
endif()
50+
else()
51+
message(WARNING "gfortran not found; OpenBLAS/LAPACKE features may not link on macOS")
52+
endif()
53+
54+
# Fixup: some scripts (e.g. OpenBLAS fallback) set BLAS_LIBRARIES/LAPACK_LIBRARIES to include
55+
# a bare `gfortran` token (expands to -lgfortran). On macOS libgfortran is often not in the
56+
# default linker search paths, causing: `ld: library 'gfortran' not found`.
57+
function(vsag_darwin_fixup_blas_lapack_libs)
58+
if (NOT APPLE)
59+
return()
60+
endif()
61+
if (NOT DEFINED GFORTRAN_LIB OR NOT EXISTS "${GFORTRAN_LIB}")
62+
return()
63+
endif()
64+
65+
foreach(_var BLAS_LIBRARIES LAPACK_LIBRARIES)
66+
if(DEFINED ${_var})
67+
set(_new_list "")
68+
foreach(_item IN LISTS ${_var})
69+
if(_item STREQUAL "gfortran")
70+
list(APPEND _new_list "${GFORTRAN_LIB}")
71+
else()
72+
list(APPEND _new_list "${_item}")
73+
endif()
74+
endforeach()
75+
# Keep cache in sync so downstream includes/targets see the rewritten list.
76+
set(${_var} "${_new_list}" CACHE STRING "" FORCE)
77+
endif()
78+
endforeach()
79+
endfunction()
80+
81+
# Run after the whole top-level configure has defined BLAS/LAPACK variables (order independent).
82+
cmake_language(DEFER CALL vsag_darwin_fixup_blas_lapack_libs)
83+
else()
84+
set(ld_flags_workaround "-Wl,-rpath=\\$\\$ORIGIN")
85+
endif()

examples/cpp/102_index_diskann.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ main(int argc, char** argv) {
121121
}
122122

123123
/******************* Serialize and Clean Index *****************/
124-
std::unordered_map<std::string, size_t> meta_info;
124+
std::unordered_map<std::string, uint64_t> meta_info;
125125
{
126126
if (auto bs = index->Serialize(); bs.has_value()) {
127127
index = nullptr;

examples/cpp/107_index_pyramid.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ create_random_string(bool is_full) {
4949
}
5050

5151
std::string random_string = selected_levels.empty() ? "" : selected_levels[0];
52-
for (size_t i = 1; i < selected_levels.size(); ++i) {
52+
for (uint64_t i = 1; i < selected_levels.size(); ++i) {
5353
random_string += "/" + selected_levels[i];
5454
}
5555

examples/cpp/201_custom_allocator.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ class ExampleAllocator : public vsag::Allocator {
2626
}
2727

2828
void*
29-
Allocate(size_t size) override {
29+
Allocate(uint64_t size) override {
3030
vsag::Options::Instance().logger()->Debug("allocate " + std::to_string(size) + " bytes.");
3131
auto addr = (void*)malloc(size);
3232
sizes_[addr] = size;
@@ -44,7 +44,7 @@ class ExampleAllocator : public vsag::Allocator {
4444
}
4545

4646
void*
47-
Reallocate(void* p, size_t size) override {
47+
Reallocate(void* p, uint64_t size) override {
4848
vsag::Options::Instance().logger()->Debug("reallocate " + std::to_string(size) + " bytes.");
4949
auto addr = (void*)realloc(p, size);
5050
sizes_.erase(p);
@@ -53,7 +53,7 @@ class ExampleAllocator : public vsag::Allocator {
5353
}
5454

5555
private:
56-
std::unordered_map<void*, size_t> sizes_;
56+
std::unordered_map<void*, uint64_t> sizes_;
5757
};
5858

5959
int

examples/cpp/313_feature_search_allocator.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ class ExampleAllocator : public vsag::Allocator {
2828
}
2929

3030
void*
31-
Allocate(size_t size) override {
31+
Allocate(uint64_t size) override {
3232
vsag::Options::Instance().logger()->Debug("allocate " + std::to_string(size) + " bytes.");
3333
auto addr = (void*)malloc(size);
3434
sizes_[addr] = size;
@@ -46,7 +46,7 @@ class ExampleAllocator : public vsag::Allocator {
4646
}
4747

4848
void*
49-
Reallocate(void* p, size_t size) override {
49+
Reallocate(void* p, uint64_t size) override {
5050
vsag::Options::Instance().logger()->Debug("reallocate " + std::to_string(size) + " bytes.");
5151
auto addr = (void*)realloc(p, size);
5252
sizes_.erase(p);
@@ -55,7 +55,7 @@ class ExampleAllocator : public vsag::Allocator {
5555
}
5656

5757
private:
58-
std::unordered_map<void*, size_t> sizes_;
58+
std::unordered_map<void*, uint64_t> sizes_;
5959
};
6060

6161
int

examples/cpp/314_feature_hgraph_search_allocator.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ class ExampleAllocator : public vsag::Allocator {
2828
}
2929

3030
void*
31-
Allocate(size_t size) override {
31+
Allocate(uint64_t size) override {
3232
vsag::Options::Instance().logger()->Debug("allocate " + std::to_string(size) + " bytes.");
3333
auto addr = (void*)malloc(size);
3434
sizes_[addr] = size;
@@ -46,7 +46,7 @@ class ExampleAllocator : public vsag::Allocator {
4646
}
4747

4848
void*
49-
Reallocate(void* p, size_t size) override {
49+
Reallocate(void* p, uint64_t size) override {
5050
vsag::Options::Instance().logger()->Debug("reallocate " + std::to_string(size) + " bytes.");
5151
auto addr = (void*)realloc(p, size);
5252
sizes_.erase(p);
@@ -55,7 +55,7 @@ class ExampleAllocator : public vsag::Allocator {
5555
}
5656

5757
private:
58-
std::unordered_map<void*, size_t> sizes_;
58+
std::unordered_map<void*, uint64_t> sizes_;
5959
};
6060

6161
int

extern/antlr4/antlr4.cmake

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,9 @@ ExternalProject_Add(
4242

4343
include_directories(${install_dir}/include/antlr4-runtime)
4444
link_directories(${install_dir}/lib)
45-
link_directories(${install_dir}/lib64)
45+
if (NOT APPLE)
46+
link_directories(${install_dir}/lib64)
47+
endif()
4648

4749
include_directories(extern/antlr4/fc)
4850
file(GLOB ANTLR4_GEN_SRC "extern/antlr4/fc/*.cpp")

extern/boost/boost.cmake

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@ cmake_policy(SET CMP0114 NEW)
55
set(name boost)
66
set(source_dir ${CMAKE_CURRENT_BINARY_DIR}/${name}/source)
77
set(install_dir ${CMAKE_CURRENT_BINARY_DIR}/${name}/install)
8+
if(APPLE)
9+
set(BOOST_TOOLSET "clang")
10+
else()
11+
set(BOOST_TOOLSET "gcc")
12+
endif()
813
get_filename_component(compiler_path ${CMAKE_CXX_COMPILER} DIRECTORY)
914
ExternalProject_Add(
1015
${name}
@@ -39,6 +44,7 @@ ExternalProject_Add(
3944
runtime-link=static
4045
link=static
4146
variant=release
47+
toolset=${BOOST_TOOLSET}
4248
BUILD_IN_SOURCE 1
4349
INSTALL_COMMAND ""
4450
LOG_CONFIGURE TRUE

0 commit comments

Comments
 (0)