You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

iOS编译Thrift 0.21.0 C++库时出现arm64未定义符号错误

iOS编译Thrift 0.21.0共享库失败问题

问题背景

尝试为iOS编译Thrift 0.21.0版本的共享库(.dylib)时遇到链接错误,静态库编译正常(设置-DBUILD_SHARED_LIBS=OFF),但无法生成所需的动态库。

使用的编译配置(CMake ExternalProject)

ExternalProject_Add(thrift
        SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/${THRIFT_DIR}
        INSTALL_DIR ${THIRDPARTY_INSTALL_DIR}
        CMAKE_ARGS ${EXTERNAL_PROJECT_CMAKE_ARGS}
            -DOPENSSL_ROOT_DIR=${OPENSSL_INSTALL_DIR}
            -DOPENSSL_CRYPTO_LIBRARY=${OPENSSL_INSTALL_DIR}/lib/libcrypto.a
            -DOPENSSL_SSL_LIBRARY=${OPENSSL_INSTALL_DIR}/lib/libssl.a
            -DBoost_INCLUDE_DIR=${BOOST_INCLUDE_DIR}
            -DWITH_ZLIB=${ZLIB_INSTALL_DIR}
            -DCMAKE_FIND_LIBRARY_SUFFIXES=".a"
            -DBUILD_SHARED_LIBS=ON
            -DBUILD_JAVA=OFF
            -DBUILD_JAVASCRIPT=OFF
            -DBUILD_NODEJS=OFF
            -DBUILD_PYTHON=OFF
            -DBUILD_PY3=OFF
            -DBUILD_QT=OFF
            -DBUILD_QT4=OFF
            -DBUILD_RUBY=OFF
            -DBUILD_PHP=OFF
            -DBUILD_SWIFT=OFF
            -DBUILD_TESTING=OFF
            
            BUILD_COMMAND make clean && make CFLAGS+=-DOPENSSL_NO_SSL3 CFLAGS+=-fPIC CXXFLAGS+=-DOPENSSL_NO_SSL3 CXXFLAGS+=-fPIC
        INSTALL_COMMAND make install
    )

错误信息

[ 93%] Linking CXX shared library ../libthriftz.dylib
cd /Users/Technaharia/Downloads/Demo/build-ios/SDKThirdParty-prefix/src/SDKThirdParty-build/thrift-prefix/src/thrift-build/lib/cpp && /Applications/CMake.app/Contents/bin/cmake -E cmake_link_script CMakeFiles/thriftz.dir/link.txt --verbose=1
Undefined symbols for architecture arm64:
"apache::thrift::GlobalOutput", referenced from:
apache::thrift::transport::TZlibTransport::checkZlibRvNothrow(int, char const*) in TZlibTransport.cpp.o
"apache::thrift::protocol::TProtocol::skip_virt(apache::thrift::protocol::TType)", referenced from:
vtable for apache::thrift::protocol::TProtocolDefaults in THeaderProtocol.cpp.o
"apache::thrift::protocol::TProtocol::~TProtocol()", referenced from:
std::__1::__shared_ptr_emplace<apache::thrift::protocol::TBinaryProtocolT<apache::thrift::transport::THeaderTransport, apache::thrift::protocol::TNetworkBigEndian>, std::__1::allocator<apache::thrift::protocol::TBinaryProtocolT<apache::thrift::transport::THeaderTransport, apache::thrift::protocol::TNetworkBigEndian>>>::~__shared_ptr_emplace() in THeaderProtocol.cpp.o
std::__1::__shared_ptr_emplace<apache::thrift::protocol::TBinaryProtocolT<apache::thrift::transport::THeaderTransport, apache::thrift::protocol::TNetworkBigEndian>, std::__1::allocator<apache::thrift::protocol::TBinaryProtocolT<apache::thrift::transport::THeaderTransport, apache::thrift::protocol::TNetworkBigEndian>>>::~__shared_ptr_emplace() in THeaderProtocol.cpp.o
apache::thrift::protocol::TBinaryProtocolT<apache::thrift::transport::THeaderTransport, apache::thrift::protocol::TNetworkBigEndian>::~TBinaryProtocolT() in THeaderProtocol.cpp.o

额外尝试的编译步骤

单独编译Thrift的流程:

  1. 下载Thrift 0.21.0源码包并解压
  2. 创建编译目录:mkdir build-ios && cd build-ios
  3. 执行CMake配置:
cmake \
-DCMAKE_TOOLCHAIN_FILE=/Users/varun/Downloads/ios-cmake-master/ios.toolchain.cmake \
-DPLATFORM=OS64 \
-DCMAKE_INSTALL_PREFIX=../install-ios \
-DOPENSSL_INCLUDE_DIR={OpenSSL头文件路径} \
-DOPENSSL_ROOT_DIR={iOS版OpenSSL根目录} \
-DOPENSSL_CRYPTO_LIBRARY={iOS版OpenSSL库路径}/libcrypto.1.1.dylib \
-DOPENSSL_SSL_LIBRARY={iOS版OpenSSL库路径}/libssl.1.1.dylib \
-DBoost_INCLUDE_DIR={iOS版Boost头文件路径}/include \
-DBUILD_SHARED_LIBS=ON \
-DWITH_ZLIB=ON \
-DWITH_C_GLIB=OFF \
-DWITH_CPP=ON \
-DWITH_STATIC_LIB=OFF \
..
  1. 执行编译:cmake --build . --target install --config Release,在此步骤失败
  2. 验证架构命令:otool -L install-ios/lib/libthrift.dylib

注意:使用脚本为Mac编译时成功,但为iOS编译时失败。推测问题为zlib未与Thrift正确链接。


解决思路

  1. 修正zlib链接参数:
    将-DWITH_ZLIB=${ZLIB_INSTALL_DIR}拆分为-DZLIB_INCLUDE_DIR=${ZLIB_INSTALL_DIR}/include和-DZLIB_LIBRARY=${ZLIB_INSTALL_DIR}/lib/libz.dylib,确保指定iOS版的动态zlib库,避免CMake仅找到静态库导致链接问题。

  2. 调整CMake库查找策略:
    移除-DCMAKE_FIND_LIBRARY_SUFFIXES=".a",编译动态库时需要优先查找.dylib后缀的库文件,强制只找静态库会导致依赖库无法以动态方式链接,进而引发符号缺失。

  3. 检查Thrift子库依赖关系:
    libthriftz.dylib依赖libthrift.dylib,确保编译libthriftz时正确链接了libthrift动态库。可在CMake配置中添加-DWITH_THRIFTZ=ON,并确认链接脚本中包含libthrift.dylib的引用。

  4. 统一依赖库类型:
    OpenSSL、Boost、zlib都必须是针对iOS arm64架构编译的动态库,不能混合使用静态库和动态库。比如将OpenSSL的库路径改为.dylib文件而非.a静态库。

  5. 添加显式链接参数:
    在BUILD_COMMAND中添加链接参数,比如LDFLAGS+=-L${ZLIB_INSTALL_DIR}/lib -lz,强制链接zlib动态库,避免CMake自动链接时出错。

  6. 检查符号导出设置:
    对于iOS动态库,需确保Thrift的全局符号(如GlobalOutput、TProtocol相关虚函数)被正确导出。可检查Thrift源码中的EXPORT宏定义,确保在iOS编译环境下生成正确的符号导出表。


内容的提问来源于stack exchange,提问作者Varun Naharia

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 11:44:52