opencv-rust icon indicating copy to clipboard operation
opencv-rust copied to clipboard

Build fails on macOS Apple Silicon (aarch64) with "a 'libclang' shared library is not loaded on this thread"

Open youngqj opened this issue 8 months ago • 2 comments

Environment

  • OS: macOS Sonoma 24.5.0 (Apple Silicon, aarch64-apple-darwin)
  • rustc: rustc 1.88.0 (6b00bc388 2025-06-23)
  • OpenCV: 4.11.0 (Installed via Homebrew)
  • LLVM: 19.1.0 (Installed via Homebrew)
  • Xcode Command Line Tools: Installed and up-to-date

Problem Description

When building a project with opencv-rs as a dependency on an Apple Silicon Mac, the build consistently fails during the opencv crate's build script execution.

The error message is: thread 'main' panicked at /Users/yangqijun/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/clang-sys-1.8.1/src/lib.rs:1859:1: a 'libclang' shared library is not loaded on this thread

This happens even though pkg-config successfully finds the OpenCV library, and all relevant environment variables seem to be set correctly. The issue appears to be with clang-sys's ability to dynamically load libclang.dylib at runtime within the build script.

Cargo.toml Dependency

[dependencies]
opencv = "0.92"

Attempts to fix

We have tried multiple combinations of environment variables, including all standard and community-suggested solutions, but the error persists.

Attempt 1: Basic Paths

export LIBCLANG_PATH="/opt/homebrew/opt/llvm/lib"
export PKG_CONFIG_PATH="/opt/homebrew/opt/opencv/lib/pkgconfig"
cargo build

Result: Failed with the same error.

Attempt 2: Comprehensive Standard Paths

export PKG_CONFIG_PATH="/opt/homebrew/opt/opencv/lib/pkgconfig"
export LIBCLANG_PATH="/opt/homebrew/opt/llvm/lib"
export DYLD_FALLBACK_LIBRARY_PATH="$(xcode-select -p)/Toolchains/XcodeDefault.xctoolchain/usr/lib"
export LD_LIBRARY_PATH="/opt/homebrew/lib"
export PATH="/opt/homebrew/opt/llvm/bin:$PATH"
cargo build

Result: Failed with the same error.

Attempt 3: Adding BINDGEN_EXTRA_CLANG_ARGS (based on community suggestions)

export PKG_CONFIG_PATH="/opt/homebrew/opt/opencv/lib/pkgconfig"
export LIBCLANG_PATH="/opt/homebrew/opt/llvm/lib"
export LD_LIBRARY_PATH="/opt/homebrew/lib"
export PATH="/opt/homebrew/opt/llvm/bin:$PATH"
export BINDGEN_EXTRA_CLANG_ARGS="-isysroot $(xcrun --sdk macosx --show-sdk-path)"
cargo build

Result: Still failed with the exact same error.

Final Build Log

This is the output from the last attempt (Attempt 3).

=== Crate version: Some("0.92.3")
=== Environment configuration:
===   OpenCV_DIR = Some("/opt/homebrew/opt/opencv")
===   PKG_CONFIG_PATH = Some("/opt/homebrew/opt/opencv/lib/pkgconfig")
...
=== Probing OpenCV library using pkg_config
=== Successfully probed using: pkg_config
=== OpenCV library configuration: Library {
    include_paths: [
        "/opt/homebrew/opt/opencv/include/opencv4",
    ],
    version: Version {
        major: 4,
        minor: 11,
        patch: 0,
    },
...
}
=== Detected OpenCV module header dir at: /opt/homebrew/opt/opencv/include/opencv4/opencv2
=== Found OpenCV version: 4.11.0 in headers located at: /opt/homebrew/opt/opencv/include/opencv4
=== Generating code in: /path/to/project/src-tauri/target/debug/build/opencv-621a83dcc0ce5751/out
=== Placing generated bindings into: /path/to/project/src-tauri/target/debug/build/opencv-621a83dcc0ce5751/out/opencv
=== Using OpenCV headers from: /opt/homebrew/opt/opencv/include/opencv4

thread 'main' panicked at /Users/yangqijun/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/clang-sys-1.8.1/src/lib.rs:1859:1:
a `libclang` shared library is not loaded on this thread
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

Question

Given that all standard environment variable configurations have been attempted, could this be a deeper issue related to System Integrity Protection (SIP), the dynamic linker (dyld), or a specific incompatibility between clang-sys, the Homebrew-installed llvm, and the Apple Silicon architecture?

Are there any other diagnostic steps or environment configurations we can try to resolve this dynamic loading failure?

Thank you for your help.

youngqj avatar Jul 15 '25 10:07 youngqj

最终的成功方案是一个组合拳,结合了社区智慧和版本升级:

  1. 启用 clang-runtime 特性: 这是最关键的一步。通过研究 GitHub Issue #657,我们发现在 Cargo.toml 中为 opencv 依赖启用 clang-runtime 特性,可以强制 clang-sys 在运行时查找 libclang.dylib,解决了动态加载失败的问题。

  2. 升级 opencv 版本: 启用 clang-runtime 后,虽然解决了环境问题,但出现了大量关于 Vector 和 trait 实现的编译错误。这通常是由于库版本不匹配或内部API变更导致的。我们将 opencv 版本从 0.92.3 升级到了 0.94.2,成功解决了这些代码兼容性问题。

最终 Cargo.toml 配置:

[dependencies]
# ... 其他依赖

# OpenCV 支持 (需要系统库)
opencv = { version = "0.94.2", default-features = false, features = ["imgproc", "imgcodecs", "videoio", "highgui", "clang-runtime"] }

3. macOS 正确编译方法 (终极版)

要在 macOS (特别是 Apple Silicon) 环境下成功编译本项目,请严格遵循以下步骤:

前提: 确保已通过 Homebrew 安装了必要的库。

brew install opencv llvm

编译命令: 在项目根目录的 src-tauri 文件夹下,执行以下单行命令。它会设置所有必要的环境变量并开始构建。

export PKG_CONFIG_PATH="/opt/homebrew/opt/opencv/lib/pkgconfig" && \
export LIBCLANG_PATH="/opt/homebrew/opt/llvm/lib" && \
export LD_LIBRARY_PATH="/opt/homebrew/lib" && \
export PATH="/opt/homebrew/opt/llvm/bin:$PATH" && \
export BINDGEN_EXTRA_CLANG_ARGS="-isysroot $(xcrun --sdk macosx --show-sdk-path)" && \
cargo build

4. 结论

本次问题的成功解决,再次印证了项目“以交付为导向”的原则。在遇到顽固的环境问题时,积极从社区寻求解决方案,并结合版本升级策略,最终高效地解决了问题,使项目重回正轨。

youngqj avatar Jul 15 '25 11:07 youngqj

Did you check https://github.com/twistedfall/opencv-rust/blob/master/TROUBLESHOOTING.md, item 8?

twistedfall avatar Jul 16 '25 14:07 twistedfall