Skip to content

Commit 756f97b

Browse files
committed
cc-0.3.34, fix the build issue on mac due to different openmp and older libomp
Signed-off-by: Eric <[email protected]>
1 parent 84f0485 commit 756f97b

File tree

4 files changed

+114
-58
lines changed

4 files changed

+114
-58
lines changed

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
0.3.33
1+
0.3.34

engine/CMakeLists.txt

Lines changed: 99 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -190,71 +190,109 @@ set_property(TARGET oatpp_swagger APPEND PROPERTY INTERFACE_LINK_LIBRARIES oatpp
190190

191191
# Configure OpenMP before defining libraries
192192
if(APPLE)
193-
# Try to find libomp using Homebrew
193+
# Try to find libomp using Homebrew (works for both Intel and Apple Silicon)
194194
execute_process(
195195
COMMAND brew --prefix libomp
196196
OUTPUT_VARIABLE LIBOMP_PREFIX
197197
OUTPUT_STRIP_TRAILING_WHITESPACE
198198
ERROR_QUIET
199+
RESULT_VARIABLE BREW_RESULT
199200
)
200201

201-
if(LIBOMP_PREFIX AND EXISTS "${LIBOMP_PREFIX}")
202-
set(OpenMP_C_FLAGS "-Xpreprocessor -fopenmp -I${LIBOMP_PREFIX}/include")
203-
set(OpenMP_C_LIB_NAMES "omp")
204-
set(OpenMP_CXX_FLAGS "-Xpreprocessor -fopenmp -I${LIBOMP_PREFIX}/include")
205-
set(OpenMP_CXX_LIB_NAMES "omp")
202+
if(BREW_RESULT EQUAL 0 AND LIBOMP_PREFIX AND EXISTS "${LIBOMP_PREFIX}")
203+
# Found via Homebrew - this is the preferred method
206204
set(OpenMP_omp_LIBRARY "${LIBOMP_PREFIX}/lib/libomp.dylib")
207205

208-
# Add include directory and link flags
209-
include_directories(${LIBOMP_PREFIX}/include)
210-
link_directories(${LIBOMP_PREFIX}/lib)
211-
212-
message(STATUS "Found libomp at: ${LIBOMP_PREFIX}")
206+
# Check if the library exists and has the required symbol
207+
if(EXISTS "${OpenMP_omp_LIBRARY}")
208+
# Try to get libomp version
209+
execute_process(
210+
COMMAND brew list --versions libomp
211+
OUTPUT_VARIABLE LIBOMP_VERSION_OUTPUT
212+
OUTPUT_STRIP_TRAILING_WHITESPACE
213+
ERROR_QUIET
214+
)
215+
216+
message(STATUS "Found libomp via Homebrew at: ${LIBOMP_PREFIX}")
217+
if(LIBOMP_VERSION_OUTPUT)
218+
message(STATUS "libomp version: ${LIBOMP_VERSION_OUTPUT}")
219+
endif()
220+
message(STATUS "OpenMP library: ${OpenMP_omp_LIBRARY}")
221+
else()
222+
message(WARNING "libomp library not found at: ${OpenMP_omp_LIBRARY}")
223+
set(LIBOMP_PREFIX "")
224+
endif()
213225
else()
214-
message(WARNING "libomp not found. Install with: brew install libomp")
226+
# Homebrew not available or libomp not installed
227+
message(WARNING "Could not find libomp via Homebrew.")
228+
message(WARNING "Please install it with: brew install libomp")
229+
message(WARNING "Note: libomp 21.1.3+ is required for compatibility with Apple Clang 17+")
230+
set(LIBOMP_PREFIX "")
215231
endif()
216232
endif()
217233

218-
find_package(OpenMP)
219-
if(OpenMP_CXX_FOUND)
220-
message(STATUS "OpenMP found via find_package")
221-
elseif(APPLE AND LIBOMP_PREFIX)
222-
# Manual OpenMP setup for macOS if find_package fails
223-
message(STATUS "Using manual OpenMP configuration for macOS")
234+
# Choose OpenMP implementation based on platform and availability
235+
if(APPLE AND LIBOMP_PREFIX)
236+
# On macOS, always prefer Homebrew libomp when available
237+
# This ensures compatibility with Apple Clang and avoids conflicts with gcc/llvm@14 OpenMP
238+
message(STATUS "Using Homebrew libomp for macOS (preferred for Apple Clang compatibility)")
239+
240+
# CRITICAL: Set include directory with BEFORE to ensure it has highest priority
241+
# This prevents conflicts with other OpenMP installations (gcc, llvm@14, etc.)
242+
include_directories(BEFORE SYSTEM ${LIBOMP_PREFIX}/include)
243+
link_directories(${LIBOMP_PREFIX}/lib)
224244

225-
# Use -fopenmp=libomp for both compile and link
226-
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fopenmp=libomp -I${LIBOMP_PREFIX}/include")
227-
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fopenmp=libomp -I${LIBOMP_PREFIX}/include")
245+
# Apply OpenMP flags globally to ensure all source files are compiled with OpenMP
246+
# On macOS with Apple Clang, we must use -Xpreprocessor -fopenmp
247+
add_compile_options(-Xpreprocessor -fopenmp)
228248

229-
# CRITICAL: Add -fopenmp=libomp to linker flags too
230-
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fopenmp=libomp -L${LIBOMP_PREFIX}/lib -Wl,-rpath,${LIBOMP_PREFIX}/lib")
231-
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -fopenmp=libomp -L${LIBOMP_PREFIX}/lib -Wl,-rpath,${LIBOMP_PREFIX}/lib")
249+
# Do NOT add -lomp to global linker flags as it causes linking order issues
250+
# Instead, we explicitly link libomp.dylib to each target via target_link_libraries
251+
252+
message(STATUS "Applied global OpenMP compile flags: -Xpreprocessor -fopenmp")
253+
message(STATUS "OpenMP include directory (highest priority): ${LIBOMP_PREFIX}/include")
254+
message(STATUS "OpenMP will be linked explicitly to each target")
255+
256+
# Set flag to indicate we're using manual OpenMP configuration
257+
set(USING_MANUAL_OPENMP TRUE)
232258
else()
233-
message(WARNING "OpenMP not found. Some features may be disabled.")
259+
# Try standard find_package for non-macOS or if Homebrew libomp not found
260+
find_package(OpenMP)
261+
if(OpenMP_CXX_FOUND)
262+
message(STATUS "OpenMP found via find_package")
263+
264+
# Apply OpenMP flags globally to ensure all source files are compiled with OpenMP
265+
separate_arguments(OpenMP_CXX_FLAGS_LIST UNIX_COMMAND "${OpenMP_CXX_FLAGS}")
266+
add_compile_options(${OpenMP_CXX_FLAGS_LIST})
267+
268+
message(STATUS "Applied global OpenMP compile flags: ${OpenMP_CXX_FLAGS}")
269+
message(STATUS "OpenMP libraries: ${OpenMP_CXX_LIBRARIES}")
270+
271+
set(USING_MANUAL_OPENMP FALSE)
272+
else()
273+
message(WARNING "OpenMP not found. Some features may be disabled.")
274+
message(WARNING "On macOS, install with: brew install libomp")
275+
set(USING_MANUAL_OPENMP FALSE)
276+
endif()
234277
endif()
235278

236279
add_library(vectordb_lib ${LIB_FILES})
237280
add_library(vectordb_dylib SHARED ${LIB_FILES})
238281
find_package(Boost REQUIRED COMPONENTS filesystem)
239282

240-
# Link OpenMP to libraries - Use special macOS linker flags
241-
if(APPLE AND LIBOMP_PREFIX)
242-
# Create interface library with OpenMP
243-
add_library(openmp_interface INTERFACE)
244-
target_link_libraries(openmp_interface INTERFACE omp)
245-
target_link_directories(openmp_interface INTERFACE ${LIBOMP_PREFIX}/lib)
246-
target_link_options(openmp_interface INTERFACE "-Wl,-rpath,${LIBOMP_PREFIX}/lib")
247-
248-
# Link OpenMP to the libraries
249-
target_link_libraries(vectordb_lib PUBLIC openmp_interface)
250-
target_link_libraries(vectordb_dylib PUBLIC openmp_interface)
283+
# Link OpenMP to libraries
284+
if(USING_MANUAL_OPENMP)
285+
# For shared library with manual OpenMP (Homebrew libomp on macOS)
286+
# Use target_link_directories and target_link_libraries to ensure proper link order
287+
target_link_directories(vectordb_dylib PUBLIC ${LIBOMP_PREFIX}/lib)
288+
target_link_libraries(vectordb_dylib PUBLIC omp)
289+
target_link_options(vectordb_dylib PUBLIC "-Wl,-rpath,${LIBOMP_PREFIX}/lib")
251290

252-
# CRITICAL: Add linker flag to force load ALL symbols from static library
253-
# This ensures OpenMP symbols are resolved even though libomp comes after libvectordb_lib.a
254-
# Note: These will be applied later after vectordb target is created
255-
target_link_options(vectordb_dylib PUBLIC "LINKER:-all_load")
256-
257-
message(STATUS "Created OpenMP interface library with force_load flags")
291+
message(STATUS "Linked Homebrew libomp to vectordb_dylib")
292+
elseif(OpenMP_CXX_FOUND)
293+
# Use find_package discovered OpenMP
294+
target_link_libraries(vectordb_dylib PUBLIC OpenMP::OpenMP_CXX)
295+
message(STATUS "Linked OpenMP::OpenMP_CXX to vectordb_dylib")
258296
endif()
259297

260298
target_include_directories(vectordb_lib PUBLIC ${Boost_INCLUDE_DIRS})
@@ -274,9 +312,15 @@ target_link_libraries(vectordb PUBLIC oatpp)
274312
target_link_libraries(vectordb PUBLIC oatpp_curl)
275313
target_link_libraries(vectordb PUBLIC oatpp_swagger)
276314

277-
# Apply force_load for vectordb executable on macOS to resolve OpenMP symbols
278-
if(APPLE AND LIBOMP_PREFIX)
279-
target_link_options(vectordb PUBLIC "LINKER:-force_load,$<TARGET_FILE:vectordb_lib>")
315+
# Add OpenMP linker flags for vectordb executable
316+
if(USING_MANUAL_OPENMP)
317+
target_link_directories(vectordb PUBLIC ${LIBOMP_PREFIX}/lib)
318+
target_link_libraries(vectordb PUBLIC omp)
319+
target_link_options(vectordb PUBLIC "-Wl,-rpath,${LIBOMP_PREFIX}/lib")
320+
message(STATUS "Linked Homebrew libomp to vectordb executable")
321+
elseif(OpenMP_CXX_FOUND)
322+
target_link_libraries(vectordb PUBLIC OpenMP::OpenMP_CXX)
323+
message(STATUS "Linked OpenMP::OpenMP_CXX to vectordb executable")
280324
endif()
281325

282326
find_package(CURL REQUIRED)
@@ -316,15 +360,6 @@ if(Python3_FOUND)
316360
endif()
317361
endif()
318362

319-
# Apply OpenMP to specific targets if found via find_package
320-
if(OpenMP_CXX_FOUND)
321-
target_link_libraries(vectordb PUBLIC OpenMP::OpenMP_CXX)
322-
target_link_libraries(vectordb_lib PUBLIC OpenMP::OpenMP_CXX)
323-
target_link_libraries(vectordb_dylib PUBLIC OpenMP::OpenMP_CXX)
324-
endif()
325-
326-
327-
328363
include(FetchContent)
329364
FetchContent_Declare(
330365
googletest
@@ -357,13 +392,20 @@ file(COPY test/engine/db/testdata DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/engine
357392

358393
target_link_libraries(
359394
vector_db_test
395+
PUBLIC
360396
GTest::gtest_main
361397
vectordb_lib
362398
)
363399

364-
# Apply force_load for vector_db_test executable on macOS to resolve OpenMP symbols
365-
if(APPLE AND LIBOMP_PREFIX)
366-
target_link_options(vector_db_test PUBLIC "LINKER:-force_load,$<TARGET_FILE:vectordb_lib>")
400+
# Link OpenMP after vectordb_lib to ensure OpenMP symbols are available
401+
if(USING_MANUAL_OPENMP)
402+
target_link_directories(vector_db_test PUBLIC ${LIBOMP_PREFIX}/lib)
403+
target_link_libraries(vector_db_test PUBLIC omp)
404+
target_link_options(vector_db_test PUBLIC "-Wl,-rpath,${LIBOMP_PREFIX}/lib")
405+
message(STATUS "Linked Homebrew libomp to vector_db_test")
406+
elseif(OpenMP_CXX_FOUND)
407+
target_link_libraries(vector_db_test PUBLIC OpenMP::OpenMP_CXX)
408+
message(STATUS "Linked OpenMP::OpenMP_CXX to vector_db_test")
367409
endif()
368410

369411
gtest_discover_tests(vector_db_test)

engine/build.sh

100755100644
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
#!/bin/bash
22
set -e
33

4+
bash scripts/install_oatpp_modules.sh
5+
46
# Create build directory
57
mkdir -p build
68
cd build

engine/scripts/install_oatpp_modules.sh

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,18 @@ N_PROCESSOR=1
5959
PLATFORM="$(uname -s)"
6060
CMAKE_EXTRA_FLAGS=""
6161

62+
# On macOS, try to upgrade libomp to ensure compatibility with Apple Clang 17+
63+
# libomp 21.1.3+ is required for ___kmpc_dispatch_deinit symbol
64+
if [[ "$PLATFORM" == "Darwin" ]]; then
65+
echo "Checking libomp version on macOS..."
66+
if command -v brew &> /dev/null; then
67+
echo "Attempting to upgrade libomp (required for OpenMP compatibility)..."
68+
brew upgrade libomp 2>/dev/null || echo "libomp upgrade failed or not needed, continuing..."
69+
else
70+
echo "Warning: Homebrew not found, skipping libomp upgrade"
71+
fi
72+
fi
73+
6274
if [[ "$PLATFORM" == "Darwin" ]]; then
6375
# Let CMake auto-detect the compiler on macOS
6476
# Use xcrun to find the actual SDK path

0 commit comments

Comments
 (0)