Sửa lỗi LoadError - không tìm thấy symbol dlsym _ffi_prep_closure_loc trên Apple Silicon

intermediate🍎 macOS2026-04-30| macOS (Apple Silicon M1/M2/M3), CocoaPods, Ruby 3.x, Xcode

Error Message

LoadError - dlsym(0x7f9...): symbol not found in flat namespace '_ffi_prep_closure_loc'
#cocoapods#ios#apple-silicon#ruby#ffi

Cách khắc phục nhanh trong 30 giây

Nếu bạn đang trong giai đoạn nước rút của sprint và chỉ cần pod install hoạt động ngay lập tức, hãy ép lệnh chạy qua lớp biên dịch Rosetta 2. Cách này giúp bỏ qua xung đột kiến trúc bằng cách giả lập môi trường Intel.

sudo arch -x86_64 gem install ffi
arch -x86_64 pod install

Lệnh này yêu cầu Mac xử lý các lệnh cụ thể này như thể chúng đang chạy trên một máy Intel cũ. Nó thường giải quyết lỗi không khớp symbol ngay lập tức.

Tại sao lỗi này xảy ra

Lỗi này bắt nguồn từ sự thất bại trong việc "bắt tay" giữa trình thông dịch Ruby và gem ffi (Foreign Function Interface). Symbol cụ thể _ffi_prep_closure_loc thuộc về thư viện libffi.

Các dòng Mac hiện đại sử dụng kiến trúc ARM64, nhưng nhiều công cụ lập trình vẫn dựa trên các file nhị phân x86_64 (Intel). Lỗi này xảy ra khi CocoaPods cố gắng tải một phiên bản ffi được biên dịch cho Intel trong khi Ruby đang chạy native trên ARM64. Vì kiến trúc không khớp nhau, trình liên kết động (dyld) không thể tìm thấy các symbol cần thiết trong "flat namespace." Về cơ bản, đây là rào cản ngôn ngữ ở cấp độ nhị phân.

Các giải pháp lâu dài

Cách 1: Cài đặt lại Native

Cách tiếp cận sạch nhất là build lại gem ffi dành riêng cho chip ARM64 native của Mac. Điều này giúp loại bỏ hoàn toàn việc sử dụng Rosetta.

  • Xóa gem cũ:

sudo gem uninstall ffi

  
  - **Cài đặt lại với flag trình biên dịch native:**
    ```
sudo gem install ffi -- --with-cflags="-Wno-error=implicit-function-declaration"

Sử dụng flag -Wno-error là rất quan trọng ở đây. Các phiên bản Xcode mới hơn coi việc khai báo hàm ngầm định (implicit function declarations) là lỗi, điều này có thể chặn quá trình cài đặt ffi trên macOS 14 (Sonoma) hoặc 15 (Sequoia).

  • Xác nhận cài đặt:

pod install

  

### Cách 2: Cầu nối Rosetta
Đôi khi dự án của bạn có các dependency cũ không thể chạy trên ARM64. Trong trường hợp đó, bạn nên chạy toàn bộ stack CocoaPods thông qua Rosetta. Đầu tiên, hãy đảm bảo Rosetta 2 đã được cài đặt trên hệ thống:

softwareupdate --install-rosetta


Sau khi cài đặt, hãy thêm tiền tố cho các lệnh cài đặt như sau:

sudo arch -x86_64 gem install ffi arch -x86_64 pod install


Đừng gõ các lệnh dài dòng nữa. Hãy thêm một alias vào file `.zshrc` của bạn để tiết kiệm thời gian:

alias rpod='arch -x86_64 pod install'


### Cách 3: Sử dụng Ruby Version Manager (Khuyên dùng)
Phiên bản Ruby "hệ thống" mặc định do Apple cung cấp nổi tiếng là khó quản lý. Nó thường gây ra lỗi quyền truy cập (yêu cầu `sudo`) và xung đột kiến trúc. Các công cụ như `rbenv` hoặc `asdf` cho phép bạn cài đặt một môi trường Ruby ARM64 native riêng biệt trong thư mục người dùng.

  - **Cài đặt rbenv qua Homebrew:**
    ```
brew install rbenv ruby-build
  • Cài đặt một phiên bản Ruby hiện đại, native (ví dụ: 3.3.1):

rbenv install 3.3.1 rbenv global 3.3.1

  
  - **Làm mới shell và cài đặt lại các công cụ:**
    ```
gem install cocoapods ffi
pod install

Các gem được cài đặt qua rbenv sẽ được biên dịch tương ứng với phiên bản Ruby cụ thể của bạn. Thiết lập này hầu như luôn loại bỏ triệt để các lỗi symbol dlsym.

Kiểm tra kết quả

Xác nhận môi trường của bạn đã ổn định bằng ba bước kiểm tra nhanh sau:

  • Kiến trúc CPU: Chạy ruby -e "puts RbConfig::CONFIG['host_cpu']". Kết quả phải trả về arm64 cho chế độ native.
  • Lệnh chạy thành công: Chạy pod --version. Nếu nó in ra số phiên bản (như 1.15.2) mà không bị crash, bạn đã thành công.
  • Cài đặt cuối cùng: Chạy pod install. Bạn sẽ thấy thông báo màu xanh "Pod installation complete".

Những "cạm bẫy" tiềm ẩn

Thiết lập Terminal: Mở Finder, vào Applications > Utilities, và chuột phải vào Terminal (hoặc iTerm2). Chọn Get Info. Đảm bảo mục "Open using Rosetta" không được chọn nếu bạn muốn quy trình làm việc native ARM64. Nếu mục này được chọn, mọi lệnh bạn chạy sẽ bị chậm đi do phải giả lập Intel.

Đường dẫn Homebrew: Kiểm tra các đường dẫn (path) của bạn. Homebrew ARM64 nằm ở /opt/homebrew, trong khi phiên bản Intel cũ nằm ở /usr/local. Nếu biến $PATH của bạn ưu tiên /usr/local/bin trước, bạn có thể đang vô tình sử dụng các công cụ dựa trên Intel trên máy Mac native của mình.

Related Error Notes