百度地图 SDK 导入 Xcode 编译出错:symbol(s) not found for architecture arm64

0x00 前言

上周接了一个外包的活,因为使用的是百度坐标,所以需要用到百度地图 SDK 里面的坐标转换功能,所以就导入了百度地图的 SDK。项目使用的是 Swift 语言开发,但是有 Objective-C 代码,所以是混编,恰好是因为混编,所以问题解决起来非常快。

0x01 错误信息

导入 SDK 之后,连接手机,编译运行发现出错了:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
Undefined symbols for architecture arm64:
"vtable for __cxxabiv1::__class_type_info", referenced from:
typeinfo for _baidu_vi::CVArray<_baidu_vi::_VPoint, _baidu_vi::_VPoint> in BaiduMapAPI_Base(SpatialUtil.o)
typeinfo for _baidu_vi::CVArray<_baidu_vi::CVArray<_baidu_vi::_VPoint, _baidu_vi::_VPoint>, _baidu_vi::CVArray<_baidu_vi::_VPoint, _baidu_vi::_VPoint>&> in BaiduMapAPI_Base(SpatialUtil.o)
typeinfo for _baidu_vi::CVArray<_baidu_vi::CVArray<_baidu_vi::_VPoint3, _baidu_vi::_VPoint3>*, _baidu_vi::CVArray<_baidu_vi::_VPoint3, _baidu_vi::_VPoint3>*&> in BaiduMapAPI_Base(SpatialUtil.o)
typeinfo for _baidu_vi::CVArray<unsigned int, unsigned int&> in BaiduMapAPI_Base(SpatialUtil.o)
typeinfo for _baidu_vi::CVArray<_baidu_vi::tagMarkPoint, _baidu_vi::tagMarkPoint&> in BaiduMapAPI_Base(SpatialUtil.o)
typeinfo for _baidu_vi::CVArray<float, float&> in BaiduMapAPI_Base(SpatialUtil.o)
typeinfo for _baidu_vi::CVArray<_baidu_vi::CVArray<_baidu_vi::_VPoint3, _baidu_vi::_VPoint3>, _baidu_vi::CVArray<_baidu_vi::_VPoint3, _baidu_vi::_VPoint3>&> in BaiduMapAPI_Base(SpatialUtil.o)
...
NOTE: a missing vtable usually means the first non-inline virtual member function has no definition.
"___cxa_begin_catch", referenced from:
___clang_call_terminate in BaiduMapAPI_Base(SpatialUtil.o)
"operator new[](unsigned long)", referenced from:
_BMKPolygonContainsPoint in BaiduMapAPI_Utils(BMKGeometry.o)
"std::terminate()", referenced from:
___clang_call_terminate in BaiduMapAPI_Base(SpatialUtil.o)
"operator delete[](void*)", referenced from:
_BMKPolygonContainsPoint in BaiduMapAPI_Utils(BMKGeometry.o)
"operator delete(void*)", referenced from:
_baidu_vi::CVArray<_baidu_vi::_VPoint, _baidu_vi::_VPoint>::~CVArray() in BaiduMapAPI_Base(SpatialUtil.o)
_baidu_vi::CVArray<_baidu_vi::CVArray<_baidu_vi::_VPoint, _baidu_vi::_VPoint>, _baidu_vi::CVArray<_baidu_vi::_VPoint, _baidu_vi::_VPoint>&>::~CVArray() in BaiduMapAPI_Base(SpatialUtil.o)
_baidu_vi::CVArray<_baidu_vi::CVArray<_baidu_vi::_VPoint3, _baidu_vi::_VPoint3>*, _baidu_vi::CVArray<_baidu_vi::_VPoint3, _baidu_vi::_VPoint3>*&>::~CVArray() in BaiduMapAPI_Base(SpatialUtil.o)
_baidu_vi::CVArray<unsigned int, unsigned int&>::~CVArray() in BaiduMapAPI_Base(SpatialUtil.o)
_baidu_vi::CVArray<_baidu_vi::tagMarkPoint, _baidu_vi::tagMarkPoint&>::~CVArray() in BaiduMapAPI_Base(SpatialUtil.o)
_baidu_vi::CVArray<float, float&>::~CVArray() in BaiduMapAPI_Base(SpatialUtil.o)
_baidu_vi::CVArray<_baidu_vi::CVArray<_baidu_vi::_VPoint3, _baidu_vi::_VPoint3>, _baidu_vi::CVArray<_baidu_vi::_VPoint3, _baidu_vi::_VPoint3>&>::~CVArray() in BaiduMapAPI_Base(SpatialUtil.o)
...
"___gxx_personality_v0", referenced from:
l001 in BaiduMapAPI_Base(BMKBaseGeoUtil.o)
l004 in BaiduMapAPI_Base(BMKBaseGeoUtil.o)
l005 in BaiduMapAPI_Base(BMKBaseGeoUtil.o)
_baidu_vi::encode_geo_diff(_baidu_vi::CComplexPt*, _baidu_vi::CVString*) in BaiduMapAPI_Base(SpatialUtil.o)
_baidu_vi::decode_geo_diff(char const*, _baidu_vi::CComplexPt*) in BaiduMapAPI_Base(SpatialUtil.o)
_baidu_vi::line_clip(_baidu_vi::CVArray<_baidu_vi::_VPoint, _baidu_vi::_VPoint> const*, _baidu_vi::tagMBR const&, _baidu_vi::CVArray<_baidu_vi::_VPoint, _baidu_vi::_VPoint>*) in BaiduMapAPI_Base(SpatialUtil.o)
_baidu_vi::line_clip(_baidu_vi::CComplexPt const*, _baidu_vi::tagMBR const&, _baidu_vi::CComplexPt*) in BaiduMapAPI_Base(SpatialUtil.o)
...
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

看着这一大坨错误信息,心里一万只草泥马奔过。

按照正常顺序,copy symbol(s) not found for architecture arm64 去 Google 了一会儿,但是并没有找到解决办法。

0x02 解决办法

不过仔细一看:"vtable for __cxxabiv1::__class_type_info",发现是跟 C++ 有关,遂将项目里面的 Objective-C 的一个 .m 文件后缀改成 .mm,编译运行就成功了。

就是这么简单。

原因嘛,大概是这样的,带有这种扩展名的源代码文件,除了可以包含 Objective-C 和 C 代码以外还可以包含 C++ 代码。不过这种文件后缀最好仅在你的 Objective-C 代码中确实需要使用 C++ 类或者特性的时候才用。