使用 Objective-C 框架构建 Swift 项目时出现“架构 arm64 的未定义符号”错误

Posted

技术标签:

【中文标题】使用 Objective-C 框架构建 Swift 项目时出现“架构 arm64 的未定义符号”错误【英文标题】:Getting "Undefined symbol for architecture arm64" error while building Swift project with Objective-C framework 【发布时间】:2021-04-06 07:54:40 【问题描述】:

我正在使用 Cisco 的 JabberGuest 框架制作 ios 应用程序。我已经按照他们的指示(提供here)进行了必要的调整。在构建时,编译器返回了将近 100 个错误,都在 undefined symbol 附近。应用程序的核心是用 Swift 编写的。

部分错误日志如下:

Undefined symbols for architecture arm64:
      "std::__1::recursive_mutex::recursive_mutex()", referenced from:
      csf::edge::IpInterfaceChangedEventFilter::IpInterfaceChangedEventFilter() in JabberGuest(IpInterfaceChangedEventFilter.o)
  "std::__1::recursive_mutex::~recursive_mutex()", referenced from:
      csf::edge::IpInterfaceChangedEventFilter::IpInterfaceChangedEventFilter() in JabberGuest(IpInterfaceChangedEventFilter.o)
      csf::edge::IpInterfaceChangedEventFilter::~IpInterfaceChangedEventFilter() in JabberGuest(IpInterfaceChangedEventFilter.o)
      csf::edge::IpInterfaceChangedEventFilter::~IpInterfaceChangedEventFilter() in JabberGuest(IpInterfaceChangedEventFilter.o)
  "std::runtime_error::runtime_error(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)", referenced from:
      boost::regex_error::regex_error(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, boost::regex_constants::error_type, long) in JabberGuest(regex.o)
      boost::regex_error::regex_error(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, boost::regex_constants::error_type, long) in JabberGuest(regex.o)
  "std::__1::basic_streambuf<char, std::__1::char_traits<char> >::underflow()", referenced from:
      vtable for boost::re_detail_106501::parser_buf<char, std::__1::char_traits<char> > in JabberGuest(instances.o)
  "std::__1::basic_streambuf<char, std::__1::char_traits<char> >::pbackfail(int)", referenced from:
      vtable for boost::re_detail_106501::parser_buf<char, std::__1::char_traits<char> > in JabberGuest(instances.o)
[...]
JCFCoreUtils::EncryptionUtils::privateKeyDecryptToFile(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, csf::SecureString const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, bool) in JabberGuest(EncryptionUtils.o)
  "std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::insert(std::__1::__wrap_iter<char const*>, char)", referenced from:
      boost::re_detail_106501::basic_regex_creator<char, boost::regex_traits<char, boost::cpp_regex_traits<char> > >::append_set(boost::re_detail_106501::basic_char_set<char, boost::regex_traits<char, boost::cpp_regex_traits<char> > > const&, mpl_::bool_<false>*) in JabberGuest(instances.o)
  "std::__1::basic_ostream<char, std::__1::char_traits<char> >::sentry::sentry(std::__1::basic_ostream<char, std::__1::char_traits<char> >&)", referenced from:
      std::__1::basic_ostream<char, std::__1::char_traits<char> >& std::__1::__put_character_sequence<char, std::__1::char_traits<char> >(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, char const*, unsigned long) in JabberGuest(ObjectFoundry.o)
      std::__1::basic_ostream<char, std::__1::char_traits<char> >& std::__1::__put_character_sequence<char, std::__1::char_traits<char> >(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, char const*, unsigned long) in JabberGuest(ObjcLibraryLoader.o)
      std::__1::basic_ostream<char, std::__1::char_traits<char> >& std::__1::__put_character_sequence<char, std::__1::char_traits<char> >(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, char const*, unsigned long) in JabberGuest(FileUtils.o)
      std::__1::basic_ostream<char, std::__1::char_traits<char> >& std::__1::__put_character_sequence<char, std::__1::char_traits<char> >(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, char const*, unsigned long) in JabberGuest(UnifiedFactory.o)
      std::__1::basic_ostream<char, std::__1::char_traits<char> >& std::__1::__put_character_sequence<char, std::__1::char_traits<char> >(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, char const*, unsigned long) in JabberGuest(ServicesDispatcher.o)
      std::__1::basic_ostream<char, std::__1::char_traits<char> >& std::__1::__put_character_sequence<char, std::__1::char_traits<char> >(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, char const*, unsigned long) in JabberGuest(Base64FamilyEncoder.o)
      std::__1::basic_ostream<char, std::__1::char_traits<char> >& std::__1::__put_character_sequence<char, std::__1::char_traits<char> >(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, char const*, unsigned long) in JabberGuest(TaskDispatcher.o)
      ...
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

我的标题是这样的:

#ifndef _ltProjectName_gt_Bridging_Header_h
#define _ltProjectName_gt_Bridging_Header_h
#import "Frameworks/JabberGuest.framework/Headers/JabberGuest.h"

#endif 

在构建设置中,我正确设置了Framework Search PathObjective-C Bridging Header 用于DebugRelease 设置在正确的文件上,在armv7 arm64 上添加了VALID_ARCHSArchitectures 设置在Standard Achritectures (arm64 armv7) 上。所有必要的库都链接在Link Binary With Libraries

我尝试清理 Xcode 和缓存,将 $(inherited) 添加到 Other Linker Flags,将 Yes 设置为 Enable Modules (C and Objective-C)。没有使用 pod,也没有任何其他 3rd 方框架。

我正在检查项目是否立即构建,没有在其他文件中实现任何方法,因此我的项目中没有更多更改。

提前感谢所有帮助。

【问题讨论】:

看起来 C++ 标准库未链接/版本不正确。您确定将“C++ 标准库”切换为“libc++(支持 C++11 的 LLVM C++ 标准库)”吗? 是的,C++ Standard Library 设置为 libc++ (LLVM C++ standard library with C++11 support) 【参考方案1】:

看起来libc++.dylib 没有链接到项目。

    选择项目文件 选择目标 选择构建阶段子选项卡 在 Link Binary with Libraries 下,按 + 按钮 选择libc++.dylib并按添加

另一种选择是尝试将-lc++ 添加到OTHER_LDFLAGS

【讨论】:

以上是关于使用 Objective-C 框架构建 Swift 项目时出现“架构 arm64 的未定义符号”错误的主要内容,如果未能解决你的问题,请参考以下文章

构建通用的 swift 框架

构建纯Swift可可触摸框架

在自定义 Swift 框架中的 Objective-C 文件上使用 Swift

无法在框架项目的 Objective-C 代码中导入 Swift 类

如何在 Flutter 插件的 Swift 编写的 iOS 部分中使用 Objective-C 框架

如何在同一框架内访问 Objective-C 中的内部 Swift 类?