fix: fix macOS 15 ARM64 compilation issues (#7437) (#47810)

issue: #47809

---------

Signed-off-by: xiaofanluan <xiaofan.luan@zilliz.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Xiaofan
2026-03-06 23:19:21 +08:00
committed by GitHub
co-authored by Claude Opus 4.6
parent d88c5655e1
commit d69bdd288c
92 changed files with 653 additions and 423 deletions
+131 -3
View File
@@ -88,11 +88,39 @@ if [[ -f "$HOME/.local/bin/conan" ]]; then
export PATH="$HOME/.local/bin:$PATH"
fi
# Ensure conan version matches the required version (1.66.0)
# CI Docker images may have an older version pre-installed
REQUIRED_CONAN_VERSION="1.66.0"
CURRENT_CONAN_VERSION=$(conan --version 2>/dev/null | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' || echo "0.0.0")
if [[ "${CURRENT_CONAN_VERSION}" != "${REQUIRED_CONAN_VERSION}" ]]; then
echo "Conan version mismatch: ${CURRENT_CONAN_VERSION} != ${REQUIRED_CONAN_VERSION}, upgrading..."
pip3 install conan==${REQUIRED_CONAN_VERSION} 2>/dev/null || pip install conan==${REQUIRED_CONAN_VERSION}
fi
pushd ${BUILD_OUTPUT_DIR}
# Unset LD_PRELOAD and LD_LIBRARY_PATH to prevent jemalloc and other shared
# libraries (set by setenv.sh) from being injected into conan's Python process.
# - LD_PRELOAD with jemalloc causes immediate segfaults in Python.
# - LD_LIBRARY_PATH with cmake_build/lib/ (populated by conan imports on
# previous runs) causes the Python ssl module to load a mismatched
# libssl.so during the conan update check, also triggering segfaults.
# The pre_build hook (below) handles setting LD_LIBRARY_PATH per-build
# for tools like grpc_cpp_plugin that need shared libs at build time.
SAVED_LD_LIBRARY_PATH="${LD_LIBRARY_PATH:-}"
unset LD_PRELOAD
unset LD_LIBRARY_PATH
export CONAN_REVISIONS_ENABLED=1
export CXXFLAGS="-Wno-error=address -Wno-error=deprecated-declarations -include cstdint"
export CFLAGS="-Wno-error=address -Wno-error=deprecated-declarations"
# LLVM from Homebrew doesn't set TARGET_OS_OSX=1 (unlike Apple's clang), which causes
# macOS SDK headers to exclude macOS-specific APIs (SecImportExport, SCPreferences, etc.).
# This fixes aws-c-cal, c-ares, and other packages that depend on macOS Security/SystemConfig APIs.
if [[ "$(uname -s)" == "Darwin" ]]; then
export CFLAGS="${CFLAGS} -DTARGET_OS_OSX=1"
export CXXFLAGS="${CXXFLAGS} -DTARGET_OS_OSX=1"
fi
# Allow CMake 4.x to build packages with old cmake_minimum_required versions (< 3.5)
export CMAKE_POLICY_VERSION_MINIMUM=3.5
@@ -103,6 +131,51 @@ if [[ ! `conan remote list` == *default-conan-local* ]]; then
conan remote add default-conan-local $CONAN_ARTIFACTORY_URL
fi
# Install a conan pre_build hook that sets LD_LIBRARY_PATH (Linux) or
# DYLD_LIBRARY_PATH (macOS) before each package build. This ensures that
# tools like grpc_cpp_plugin can find shared libraries (e.g. libprotoc.so)
# when invoked during downstream package builds (opentelemetry-cpp, googleapis).
# Use "conan config home" to get the correct conan home directory, as ~ may
# differ from the conan home in CI containers.
CONAN_HOME_DIR=$(conan config home 2>/dev/null || echo "${CONAN_USER_HOME:-$HOME}/.conan")
mkdir -p "$CONAN_HOME_DIR/hooks"
cat > "$CONAN_HOME_DIR/hooks/fix_shared_lib_env.py" << 'HOOK_EOF'
import os, platform
_saved_env = {}
def pre_build(output, conanfile, **kwargs):
"""Set library path before build so tools like grpc_cpp_plugin can find
shared libs (e.g. libprotoc.so). Saved state is restored in post_build
to avoid polluting the conan process environment."""
dep_lib_dirs = []
try:
for _, dep in conanfile.deps_cpp_info.dependencies:
for p in dep.lib_paths:
if os.path.isdir(p):
dep_lib_dirs.append(p)
except Exception:
return
if not dep_lib_dirs:
return
env_var = "DYLD_LIBRARY_PATH" if platform.system() == "Darwin" else "LD_LIBRARY_PATH"
_saved_env[env_var] = os.environ.get(env_var)
existing = os.environ.get(env_var, "")
new_val = ":".join(dep_lib_dirs) + (":" + existing if existing else "")
os.environ[env_var] = new_val
output.info("Set %s for %d dependency lib dirs" % (env_var, len(dep_lib_dirs)))
def post_build(output, conanfile, **kwargs):
"""Restore library path after build to prevent conan process corruption."""
for env_var, old_val in _saved_env.items():
if old_val is None:
os.environ.pop(env_var, None)
else:
os.environ[env_var] = old_val
_saved_env.clear()
HOOK_EOF
conan config set hooks.fix_shared_lib_env 2>/dev/null
unameOut="$(uname -s)"
case "${unameOut}" in
Darwin*)
@@ -111,7 +184,57 @@ case "${unameOut}" in
export CMAKE_CXX_COMPILER_LAUNCHER=ccache
echo "Using CXX: $CXX"
echo "Using CC: $CC"
conan install ${CPP_SRC_DIR} --install-folder conan --build=missing -s build_type=${BUILD_TYPE} -s compiler=clang -s compiler.version=${llvm_version} -s compiler.libcxx=libc++ -s compiler.cppstd=17 -u || { echo 'conan install failed'; exit 1; }
CONAN_ARGS="--install-folder conan --build=missing -s build_type=${BUILD_TYPE} -s compiler=clang -s compiler.version=${llvm_version} -s compiler.libcxx=libc++ -s compiler.cppstd=17 -u"
# On macOS, Conan packages with shared libraries (protobuf, grpc) produce
# binaries (protoc, grpc_cpp_plugin) whose install rpaths don't include
# dependency lib dirs (e.g. abseil). This causes dyld failures when
# downstream packages (opentelemetry-cpp, googleapis) invoke them.
#
# Fix: install a Conan post_package hook that adds dependency rpaths to
# each package's binaries right after it is built (before the manifest is
# sealed), so every tool binary works the first time it is invoked.
mkdir -p "$CONAN_HOME_DIR/hooks"
conan config set hooks.fix_macos_rpaths 2>/dev/null
cat > "$CONAN_HOME_DIR/hooks/fix_macos_rpaths.py" << 'HOOK_EOF'
import os, platform, subprocess, stat
def post_package(output, conanfile, conanfile_path, **kwargs):
if platform.system() != "Darwin":
return
pkg = conanfile.package_folder
if not pkg:
return
bin_dir = os.path.join(pkg, "bin")
if not os.path.isdir(bin_dir):
return
dep_lib_dirs = []
try:
for _, dep in conanfile.deps_cpp_info.dependencies:
for p in dep.lib_paths:
if os.path.isdir(p):
dep_lib_dirs.append(p)
except Exception:
return
if not dep_lib_dirs:
return
fixed = []
for name in os.listdir(bin_dir):
fp = os.path.join(bin_dir, name)
if not os.path.isfile(fp) or not (os.stat(fp).st_mode & stat.S_IXUSR):
continue
r = subprocess.run(["file", fp], capture_output=True, text=True)
if "Mach-O" not in r.stdout:
continue
for lib_path in dep_lib_dirs:
subprocess.run(["install_name_tool", "-add_rpath", lib_path, fp],
capture_output=True)
fixed.append(name)
if fixed:
output.info("Fixed macOS rpaths for: %s" % ", ".join(fixed))
HOOK_EOF
conan install ${CPP_SRC_DIR} ${CONAN_ARGS} || { echo 'conan install failed'; exit 1; }
;;
Linux*)
if [ -f /etc/os-release ]; then
@@ -123,9 +246,9 @@ case "${unameOut}" in
export CPU_TARGET=avx
GCC_VERSION=`gcc -dumpversion`
if [[ `gcc -v 2>&1 | sed -n 's/.*\(--with-default-libstdcxx-abi\)=\(\w*\).*/\2/p'` == "gcc4" ]]; then
conan install ${CPP_SRC_DIR} --install-folder conan --build=missing -s build_type=${BUILD_TYPE} -s compiler.version=${GCC_VERSION} -u || { echo 'conan install failed'; exit 1; }
conan install ${CPP_SRC_DIR} --install-folder conan --build=missing -s build_type=${BUILD_TYPE} -s compiler.version=${GCC_VERSION} -s compiler.cppstd=17 -u || { echo 'conan install failed'; exit 1; }
else
conan install ${CPP_SRC_DIR} --install-folder conan --build=missing -s build_type=${BUILD_TYPE} -s compiler.version=${GCC_VERSION} -s compiler.libcxx=libstdc++11 -u || { echo 'conan install failed'; exit 1; }
conan install ${CPP_SRC_DIR} --install-folder conan --build=missing -s build_type=${BUILD_TYPE} -s compiler.version=${GCC_VERSION} -s compiler.libcxx=libstdc++11 -s compiler.cppstd=17 -u || { echo 'conan install failed'; exit 1; }
fi
;;
*)
@@ -133,6 +256,11 @@ case "${unameOut}" in
;;
esac
# Restore LD_LIBRARY_PATH so downstream build steps can find shared libs
if [[ -n "${SAVED_LD_LIBRARY_PATH}" ]]; then
export LD_LIBRARY_PATH="${SAVED_LD_LIBRARY_PATH}"
fi
popd
mkdir -p ${ROOT_DIR}/internal/core/output/lib
+1 -1
View File
@@ -6,7 +6,7 @@
OS: Ubuntu 20.04
go1.21
cmake: >=3.18
gcc 7.5
gcc: >= 11
```
## Install dependencies
+3 -1
View File
@@ -29,7 +29,9 @@ if [[ $(uname -s) == "Darwin" ]]; then
export PATH="/usr/local/opt/grep/libexec/gnubin:$PATH"
fi
check_result=$(git status | grep -E ".*pb.go|.*pb.cc|.*pb.h")
# Use -I to ignore hunks where all changed lines are protoc version comments.
# This avoids false failures when CI protoc version differs from the committer's.
check_result=$(git diff -I '//.*protoc' --name-only -- '*.pb.go' '*.pb.cc' '*.pb.h')
echo "check_result: $check_result"
if test -z "$check_result"; then
exit 0
+7 -9
View File
@@ -254,15 +254,13 @@ echo "CC $CC"
echo ${CMAKE_CMD}
${CMAKE_CMD} -G "${CMAKE_GENERATOR}"
# Export PROTOC for Rust prost-build (used by lance-encoding).
# Conan imports() copies the protoc binary into cmake_build/bin/.
# We prefer that over a system protoc to match the Conan protobuf version.
if [ -z "${PROTOC}" ] && [ -x "${BUILD_OUTPUT_DIR}/bin/protoc" ]; then
export PROTOC="${BUILD_OUTPUT_DIR}/bin/protoc"
echo "Using Conan protoc: ${PROTOC}"
elif [ -z "${PROTOC}" ] && command -v protoc &> /dev/null; then
export PROTOC="$(command -v protoc)"
echo "Using system protoc: ${PROTOC}"
# Export PROTOC for Rust crates (e.g. lance-encoding) that need it at build time
if [ -z "$PROTOC" ]; then
_PROTOC=$(grep -m1 "^Protobuf_PROTOC_EXECUTABLE" CMakeCache.txt 2>/dev/null | cut -d= -f2-)
if [ -n "$_PROTOC" ] && [ -f "$_PROTOC" ]; then
export PROTOC="$_PROTOC"
echo "Exported PROTOC=$PROTOC for Rust builds"
fi
fi
if [[ ${RUN_CPPLINT} == "ON" ]]; then
+22 -60
View File
@@ -21,12 +21,12 @@
# Supported platforms:
# - macOS 12, 13, 14, 15 (Intel and Apple Silicon)
# - Ubuntu 20.04, 22.04, 24.04
# - Rocky Linux 8, 9
# - Rocky Linux 9
# - Amazon Linux 2023
#
# Compiler requirements:
# - macOS: LLVM/Clang 14-18
# - Linux: GCC 9-14
# - macOS: LLVM/Clang 15-17
# - Linux: GCC 11-14
#
# Usage:
# ./scripts/install_deps.sh
@@ -57,7 +57,7 @@ print_error() {
# Minimum version requirements
MIN_CMAKE_VERSION="3.26"
MIN_GO_VERSION="1.21"
CONAN_VERSION="1.64.1"
CONAN_VERSION="1.66.0"
RUST_VERSION="1.89"
#######################################
@@ -198,11 +198,6 @@ install_mac_deps() {
if [[ "$arch" == "arm64" ]]; then
print_info "Installing Apple Silicon specific dependencies..."
brew install --quiet openssl librdkafka
# AWS SDK for S3 support on macOS (needed for milvus-storage)
brew install --quiet aws-sdk-cpp
else
# Intel Mac
brew install --quiet aws-sdk-cpp
fi
# Create symlink for LLVM (for scripts that expect /usr/local/opt/llvm)
@@ -328,60 +323,26 @@ install_rocky_deps() {
local rocky_version=$(detect_rocky_version)
print_info "Detected Rocky Linux ${rocky_version}"
# Enable EPEL repository
sudo dnf install -y epel-release
if [ "$rocky_version" -lt 9 ]; then
print_error "Rocky Linux ${rocky_version} is no longer supported. Please upgrade to Rocky Linux 9+."
exit 1
fi
# Base packages
local base_packages=(
wget curl which git make ninja-build
automake python3-devel python3-pip
openblas-devel libaio libuuid-devel
# Enable EPEL and CRB repositories
sudo dnf install -y epel-release dnf-plugins-core
sudo dnf config-manager --set-enabled crb
# Rocky 9 ships with GCC 11 by default — no toolset needed
print_info "Installing GCC and build dependencies for Rocky ${rocky_version}..."
sudo dnf install -y \
gcc gcc-c++ gcc-gfortran \
wget curl which git make ninja-build \
automake python3-devel python3-pip \
openblas-devel libaio libuuid-devel \
zip unzip ccache lcov libtool m4 autoconf
)
# Version-specific packages
case "$rocky_version" in
8)
print_info "Installing GCC toolset for Rocky 8..."
sudo dnf install -y gcc-toolset-12 gcc-toolset-12-libatomic-devel gcc-toolset-12-libstdc++-devel
sudo dnf install -y "${base_packages[@]}"
sudo dnf install -y atlas-devel
# Enable GCC toolset
echo "source /opt/rh/gcc-toolset-12/enable" | sudo tee /etc/profile.d/gcc-toolset-12.sh
source /opt/rh/gcc-toolset-12/enable
# Create libstdc++.a symlink for static linking (needed by conan packages like ninja)
local gcc12_libstdcxx="/opt/rh/gcc-toolset-12/root/usr/lib/gcc/x86_64-redhat-linux/12/libstdc++.a"
local system_gcc_dir="/usr/lib/gcc/x86_64-redhat-linux/8"
if [ -f "$gcc12_libstdcxx" ] && [ -d "$system_gcc_dir" ] && [ ! -f "$system_gcc_dir/libstdc++.a" ]; then
print_info "Creating libstdc++.a symlink for static linking..."
sudo ln -s "$gcc12_libstdcxx" "$system_gcc_dir/libstdc++.a"
fi
# Install LLVM toolset for clang-format
sudo dnf install -y llvm-toolset
echo "export CLANG_TOOLS_PATH=/usr/bin" | sudo tee -a /etc/profile.d/llvm-toolset.sh
;;
9)
print_info "Installing GCC for Rocky 9..."
sudo dnf install -y gcc gcc-c++ gcc-gfortran
sudo dnf install -y "${base_packages[@]}"
# Optionally install newer GCC toolset
sudo dnf install -y gcc-toolset-13 || true
if [ -d /opt/rh/gcc-toolset-13 ]; then
echo "source /opt/rh/gcc-toolset-13/enable" | sudo tee /etc/profile.d/gcc-toolset-13.sh
fi
# Install clang-tools
sudo dnf install -y clang-tools-extra || sudo dnf install -y clang
;;
*)
print_warn "Rocky Linux ${rocky_version} not explicitly supported"
sudo dnf install -y gcc gcc-c++ gcc-gfortran "${base_packages[@]}"
;;
esac
# Install clang-tools for formatting
sudo dnf install -y clang-tools-extra || sudo dnf install -y clang
# Install CMake if needed
install_cmake_linux
@@ -397,6 +358,7 @@ install_rocky_deps() {
conan profile new default --detect --force 2>/dev/null || true
conan profile update settings.compiler.version="$gcc_ver" default
conan profile update settings.compiler.libcxx=libstdc++11 default
conan profile update settings.compiler.cppstd=17 default
fi
# Install Rust
+1 -1
View File
@@ -23,7 +23,7 @@ pacmanInstall()
mingw-w64-x86_64-diffutils \
mingw-w64-x86_64-go
pip3 install conan==1.64.1
pip3 install conan==1.66.0
}
updateKey()
+10
View File
@@ -31,6 +31,12 @@ source ${ROOT_DIR}/scripts/setenv.sh
MILVUS_CORE_DIR="${ROOT_DIR}/internal/core"
MILVUS_CORE_UNITTEST_DIR="${MILVUS_CORE_DIR}/output/unittest"
# Suppress known LeakSanitizer false positives from uninstrumented shared libraries
LSAN_SUPPRESSIONS="${MILVUS_CORE_DIR}/lsan_suppressions.txt"
if [ -f "${LSAN_SUPPRESSIONS}" ]; then
export LSAN_OPTIONS="suppressions=${LSAN_SUPPRESSIONS}"
fi
echo "ROOT_DIR = ${ROOT_DIR}"
echo "MILVUS_CORE_DIR = ${MILVUS_CORE_DIR}"
echo "MILVUS_CORE_UNITTEST_DIR = ${MILVUS_CORE_UNITTEST_DIR}"
@@ -67,6 +73,10 @@ for test in $(ls ${MILVUS_CORE_UNITTEST_DIR}); do
# run unittest
if [ -n "$MILVUS_ENABLE_ASAN_LIB" ]; then
echo "ASAN is enabled with env MILVUS_ENABLE_ASAN_LIB, set {$MILVUS_ENABLE_ASAN_LIB} at the front of LD_PRELOAD"
# protobuf 5.x RepeatedField triggers ASAN container-overflow false positives during static init
# LSAN suppression: __cxa_allocate_exception false positives from uninstrumented shared libs
ASAN_OPTIONS="${ASAN_OPTIONS:+${ASAN_OPTIONS}:}detect_container_overflow=0" \
LSAN_OPTIONS="${LSAN_OPTIONS:+${LSAN_OPTIONS}:}suppressions=${MILVUS_CORE_DIR}/lsan_suppressions.txt" \
LD_PRELOAD="$MILVUS_ENABLE_ASAN_LIB:$LD_PRELOAD" ${MILVUS_CORE_UNITTEST_DIR}/${test}
else
${MILVUS_CORE_UNITTEST_DIR}/${test}
+6
View File
@@ -35,6 +35,12 @@ if [ -d "${CORE_INSTALL_PREFIX}/lib" ]; then
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${CORE_INSTALL_PREFIX}/lib
fi
# Suppress known LeakSanitizer false positives from uninstrumented shared libraries
LSAN_SUPPRESSIONS="${MILVUS_CORE_DIR}/lsan_suppressions.txt"
if [ -f "${LSAN_SUPPRESSIONS}" ]; then
export LSAN_OPTIONS="suppressions=${LSAN_SUPPRESSIONS}"
fi
# run unittest
arg="$1"
filter_value="${arg#*=}"
+11 -1
View File
@@ -47,6 +47,12 @@ source ${ROOT_DIR}/scripts/setenv.sh
MILVUS_CORE_DIR="${ROOT_DIR}/internal/core"
MILVUS_CORE_UNITTEST_DIR="${MILVUS_CORE_DIR}/output/unittest"
# Suppress known LeakSanitizer false positives from uninstrumented shared libraries
LSAN_SUPPRESSIONS="${MILVUS_CORE_DIR}/lsan_suppressions.txt"
if [ -f "${LSAN_SUPPRESSIONS}" ]; then
export LSAN_OPTIONS="suppressions=${LSAN_SUPPRESSIONS}"
fi
echo "=============================================="
echo "=== C++ Unit Tests (No Coverage) ==="
echo "=============================================="
@@ -85,7 +91,11 @@ run_test() {
if [ -n "$MILVUS_ENABLE_ASAN_LIB" ]; then
echo "ASAN is enabled with env MILVUS_ENABLE_ASAN_LIB"
env $env_vars LD_PRELOAD="$MILVUS_ENABLE_ASAN_LIB:$LD_PRELOAD" ${MILVUS_CORE_UNITTEST_DIR}/${test}
# protobuf 5.x RepeatedField triggers ASAN container-overflow false positives during static init
# LSAN suppression: __cxa_allocate_exception false positives from uninstrumented shared libs
env $env_vars ASAN_OPTIONS="${ASAN_OPTIONS:+${ASAN_OPTIONS}:}detect_container_overflow=0" \
LSAN_OPTIONS="${LSAN_OPTIONS:+${LSAN_OPTIONS}:}suppressions=${MILVUS_CORE_DIR}/lsan_suppressions.txt" \
LD_PRELOAD="$MILVUS_ENABLE_ASAN_LIB:$LD_PRELOAD" ${MILVUS_CORE_UNITTEST_DIR}/${test}
else
env $env_vars ${MILVUS_CORE_UNITTEST_DIR}/${test}
fi
+1
View File
@@ -56,6 +56,7 @@ for d in cmd/tools internal pkg client; do
-coverprofile="$PROFILE" \
-covermode=atomic \
-p "$PARALLEL" \
-ldflags="-r ${RPATH}" \
./...
if [ -f "$PROFILE" ]; then
+2 -1
View File
@@ -45,8 +45,9 @@ TEST_CMD_WITH_ARGS=(
-coverpkg=./...
-coverprofile=profile.out
-covermode=atomic
-caseTimeout=20m
-caseTimeout=20m
-timeout=60m
-ldflags="-r ${RPATH}"
)
function test_cmd() {
+37 -11
View File
@@ -51,20 +51,26 @@ case "${unameOut}" in
echo "WARN: Cannot find $LIBJEMALLOC"
fi
export PKG_CONFIG_PATH="${PKG_CONFIG_PATH:+$PKG_CONFIG_PATH:}$ROOT_DIR/internal/core/output/lib/pkgconfig:$ROOT_DIR/internal/core/output/lib64/pkgconfig"
export LD_LIBRARY_PATH="${LD_LIBRARY_PATH:+$LD_LIBRARY_PATH:}$ROOT_DIR/internal/core/output/lib:$ROOT_DIR/internal/core/output/lib64"
export RPATH=$LD_LIBRARY_PATH;;
MILVUS_LIB_DIRS="$ROOT_DIR/internal/core/output/lib:$ROOT_DIR/internal/core/output/lib64:$ROOT_DIR/cmake_build/lib"
# LIBRARY_PATH: build-time linker search path (gcc/ld)
export LIBRARY_PATH="${LIBRARY_PATH:+$LIBRARY_PATH:}$MILVUS_LIB_DIRS"
# LD_LIBRARY_PATH: runtime linker search path - needed for transitive
# shared library dependencies (e.g. libfolly_exception_tracer.so has no
# RPATH and depends on libfolly_exception_tracer_base.so)
export LD_LIBRARY_PATH="${LD_LIBRARY_PATH:+$LD_LIBRARY_PATH:}$MILVUS_LIB_DIRS"
export RPATH=$MILVUS_LIB_DIRS;;
Darwin*)
# detect llvm version by valid list (supports LLVM 14-17)
# detect llvm version by valid list (supports LLVM 15-17)
# Note: LLVM 18 is NOT supported because Conan 1.x cannot handle the newer
# compiler profiles/settings that LLVM 18 requires. Until we migrate to Conan 2,
# please use LLVM 17 or earlier.
for llvm_version in 17 16 15 14 NOT_FOUND ; do
# please use LLVM 15-17.
for llvm_version in 17 16 15 NOT_FOUND ; do
if brew ls --versions llvm@${llvm_version} > /dev/null 2>&1; then
break
fi
done
if [ "${llvm_version}" = "NOT_FOUND" ] ; then
echo "ERROR: Valid LLVM (14-17) not installed. Run: brew install llvm@17"
echo "ERROR: Valid LLVM (15-17) not installed. Run: brew install llvm@17"
echo "NOTE: LLVM 18 is not supported due to Conan 1.x incompatibility."
exit 1
fi
@@ -74,14 +80,35 @@ case "${unameOut}" in
export CXX=${llvm_prefix}/bin/clang++
export ASM=${llvm_prefix}/bin/clang
macos_sdk_path="$(xcrun --show-sdk-path)"
export CFLAGS="-Wno-deprecated-declarations -I$(brew --prefix libomp)/include -isysroot ${macos_sdk_path}"
# LLVM from Homebrew doesn't set TARGET_OS_OSX=1 (unlike Apple's clang), causing
# macOS SDK headers to exclude macOS-specific APIs. Define it explicitly.
export CFLAGS="-Wno-deprecated-declarations -I$(brew --prefix libomp)/include -isysroot ${macos_sdk_path} -DTARGET_OS_OSX=1"
export CXXFLAGS=${CFLAGS}
export LDFLAGS="-L$(brew --prefix libomp)/lib"
# Include LLVM's own libc++/libc++abi so Conan packages that reference
# Apple-extension symbols (e.g. ___cxa_decrement_exception_refcount in
# folly) are resolved against the same runtime they were built with.
# -lc++abi is explicit because Homebrew LLVM clang++ does not inject it
# automatically (unlike Apple clang), but folly's static archive references it.
export LDFLAGS="-L$(brew --prefix libomp)/lib -L${llvm_prefix}/lib/c++ -lc++abi"
# Rust cc-rs crate uses the Xcode SDK version as deployment target if
# MACOSX_DEPLOYMENT_TARGET is unset. When the SDK version (e.g. 26.2) is
# newer than what this LLVM version understands, compilation fails.
# Cap it at the current macOS major version to stay compatible.
sdk_ver="$(xcrun --show-sdk-version 2>/dev/null)"
os_major="$(sw_vers -productVersion | cut -d. -f1)"
if [ -n "${sdk_ver}" ] && [ -n "${os_major}" ] && \
[ "$(echo "${sdk_ver}" | cut -d. -f1)" -gt "${os_major}" ]; then
export MACOSX_DEPLOYMENT_TARGET="${os_major}.0"
fi
# Rust cc-rs needs TARGET_OS_OSX for correct platform detection in aws-lc-sys.
# Set for both ARM and Intel targets so cross-compilation also works.
export CFLAGS_aarch64_apple_darwin="-DTARGET_OS_OSX=1"
export CFLAGS_x86_64_apple_darwin="-DTARGET_OS_OSX=1"
export CGO_CFLAGS="${CFLAGS}"
export CGO_LDFLAGS="${LDFLAGS} -framework Security -framework CoreFoundation"
export PKG_CONFIG_PATH="${PKG_CONFIG_PATH:+$PKG_CONFIG_PATH:}$ROOT_DIR/internal/core/output/lib/pkgconfig"
export DYLD_LIBRARY_PATH=$ROOT_DIR/internal/core/output/lib
export PKG_CONFIG_PATH="${PKG_CONFIG_PATH}:$ROOT_DIR/internal/core/output/lib/pkgconfig"
export DYLD_LIBRARY_PATH=$ROOT_DIR/cmake_build/lib:$ROOT_DIR/internal/core/output/lib
export RPATH=$DYLD_LIBRARY_PATH;;
MINGW*)
extra_path=$(cygpath -w "$ROOT_DIR/internal/core/output/lib")
@@ -91,4 +118,3 @@ case "${unameOut}" in
*)
echo "does not supported"
esac