首先,介紹下Apple
LLVM compiler 4.2 與LLVM GCC的區別:
某些項目採用了一些第三方庫,有時候可能會因爲編譯方式的不同導致無法項目編譯通過,目前xcode 最新的默認的Compiler for C/C++/Objective C爲apple LLVM compiler 4.2, 但其採用的C++ Standard Library 卻爲libc++(LLVM C++ standard libraryth C++ 11 support), 有些開源類的第三方庫可能會採用 原始的LLVM GCC編譯器(c++ 標準庫爲libstdC++)。而libstdC++
與 libc++(LLVM C++ standard libraryth C++ 11 support) 是有很大區別的,具體的歷史淵源可以維基百科等等的查詢一下,這裏就不詳細的講解了。
解決方式有兩種:
1. 選擇 apple LLVM compiler 4.2, c++ 標準庫改爲libstdc++(GNU C++ standard library)
2. 選擇LLVM GCC, c++標準庫爲libstdC++
下面是對應真機的處理器:
armv7 , armv7s對應真機的32位處理器,
arm64對應真機的64位模擬器,
i386對應模擬器的32位模擬器;
x86_64對應模擬器的64位模擬器。
碰到一個類似上述的問題,感覺還是stl的C++庫加載造成的問題。
即使通過gcc -v查看了編譯過程,
然後用gcc -E 導出了預編譯後的文件,
查看到的仍然只是std::string,爲什麼會出現接口中
有的是fucn(std::string)
有的是func(std::__1::basic_string...)
仍然沒有搞清楚,網上有一篇似乎可以處理這個問題的文章,如下:
http://blog.csdn.net/kaizi318/article/details/10362673
但是嘗試後,發現xcode仍然報錯。
通過在後臺用nm查看調用。
發現如果用libstdc++庫,則需要使用指定頭文件,添加頭文件路徑如下:
-I $(shell $(XCRUN) --show-sdk-path)/usr/include/c++/4.2.1
其對應使用的std::string類型就是std::string。
而若是不指定用libstdc++,而是使用默認的libc++庫,則使用的是默認的C++頭文件,
其對應使用的std::string變成了std::__1::basic_string(........)之類的
因此,c++頭文件使用的不同導致其他使用stl的庫的函數簽名和實現都不同了
參考文章如下:
Undefined symbols for architecture i386或者armv7:
“_OBJC_CLASS_$_XXX
Undefined symbols for architecture i386:
“_OBJC_CLASS_$_XXX”, referenced
from:
objc-class-ref in XXX
ld: symbol(s) not found for architecture i386
clang: error: linker command failed with exit code 1 (use -v to see invocation)
如果真機調試就是 undefined symbols for architecture armv7錯誤!
發生這種錯誤通常是project.pbxproj這個文件引起的,尤其在多人合作開發的時候,svn提交不規範可能導致project.pbxproj發生錯誤,導致文件的引用不在project.pbxproj文件中。
xcode項目import文件會根據project.pbxproj來查找,查找不到文件的引用則會有上述的錯誤。
解決方法點擊工程,在主界面中點擊Build Phases,根據提示信息“XXX”來判斷缺少什麼文件,一般如果缺少自定義的文件,XXX會是缺少的類名,那麼就在Complie Sources中加入該文件。如果缺少類庫,則在Link Binary With Libraries中加入該類庫。
Undefined
symbols for architecture
i386: |
02 |
"TextureMan::LoadTexture(std::__1::basic_string,
std::__1::allocator > const&, int, bool)" ,
referenced from: |
03 |
tolua_gameinterface_TextureMan_loadTexture00(lua_State*) in libCoreClientiOS.a(tolua_gameinterface.o) |
04 |
"SoundManager::BgndMusicPlay(std::__1::basic_string,
std::__1::allocator > const&, bool)" ,
referenced from: |
05 |
tolua_gameinterface_SoundManager_BgndMusicPlay00(lua_State*) in libCoreClientiOS.a(tolua_gameinterface.o) |
06 |
"SoundManager::BgndMusicStop(std::__1::basic_string,
std::__1::allocator > const&, bool)" ,
referenced from: |
07 |
tolua_gameinterface_SoundManager_BgndMusicStop00(lua_State*) in libCoreClientiOS.a(tolua_gameinterface.o) |
08 |
"Font::LoadFont(std::__1::basic_string,
std::__1::allocator > const&)" ,
referenced from: |
09 |
tolua_gameinterface_Font_loadFont00(lua_State*) in libCoreClientiOS.a(tolua_gameinterface.o) |
10 |
"System::MakeDocumentPath(std::__1::basic_string,
std::__1::allocator > const&) const" ,
referenced from: |
11 |
tolua_gameinterface_System_makeDocumentPath00(lua_State*) in libCoreClientiOS.a(tolua_gameinterface.o) |
12 |
"System::MakeResourcePath(std::__1::basic_string,
std::__1::allocator > const&) const" ,
referenced from: |
13 |
ExUnit::LogicThread::Run() in libCoreClientiOS.a(logicthread.o) |
14 |
tolua_gameinterface_System_makeResourcePath00(lua_State*) in libCoreClientiOS.a(tolua_gameinterface.o) |
15 |
"std::__1::__vector_base_common::__throw_length_error()
const" ,
referenced from: |
16 |
void
std::__1::vector >::__push_back_slow_path(float const&&&) in libCoreClientiOS.a(tolua_gameinterface.o) |
17 |
void
std::__1::vector, std::__1::allocator > >::__push_back_slow_path const&>(std::__1::basic_string, std::__1::allocator > const&&&) in libCoreClientiOS.a(tolua_gameinterface.o) |
18 |
void
std::__1::vector >::__push_back_slow_path(int const&&&) in libCoreClientiOS.a(tolua_gameinterface.o) |
19 |
"std::__1::locale::use_facet(std::__1::locale::id&)
const" ,
referenced from: |
20 |
std::__1::basic_ostream
>& std::__1::endl >(std::__1::basic_ostream >&) in libCoreClientiOS.a(logicthread.o) |
21 |
"std::__1::ios_base::getloc()
const" ,
referenced from: |
22 |
std::__1::basic_ostream
>& std::__1::endl >(std::__1::basic_ostream >&) in libCoreClientiOS.a(logicthread.o) |
23 |
"std::__1::basic_string,
std::__1::allocator >::__init(char const*, unsigned long)" ,
referenced from: |
24 |
_l_registercallback in libCoreClientiOS.a(logicthread.o) |
25 |
_luapanic in libCoreClientiOS.a(logicthread.o) |
26 |
ExUnit::LogicThread::Run() in libCoreClientiOS.a(logicthread.o) |
27 |
ExUnit::LogicThread::HandleError() in libCoreClientiOS.a(logicthread.o) |
28 |
ExUnit::LogicThread::CallVA(char
const*, char const*, ...) in libCoreClientiOS.a(logicthread.o) |
29 |
ExUnit::LogicThread::RemoveCallback(char
const*) in libCoreClientiOS.a(logicthread.o) |
30 |
ExUnit::LogicThread::SetCallback(char
const*, int) in libCoreClientiOS.a(logicthread.o) |
32 |
"std::__1::basic_string,
std::__1::allocator >::assign(char const*)" ,
referenced from: |
33 |
System::SetEngineScriptPath(char
const*) in libCoreClientiOS.a(tolua_gameinterface.o) |
34 |
"std::__1::basic_string,
std::__1::allocator >::basic_string(std::__1::basic_string, std::__1::allocator > const&)" ,
referenced from: |
35 |
tolua_gameinterface_vector_string___geti00(lua_State*) in libCoreClientiOS.a(tolua_gameinterface.o) |
36 |
tolua_gameinterface_vector_string___geti01(lua_State*) in libCoreClientiOS.a(tolua_gameinterface.o) |
37 |
tolua_gameinterface_vector_string__push_back00(lua_State*) in libCoreClientiOS.a(tolua_gameinterface.o) |
38 |
void
std::__1::vector, std::__1::allocator > >::__push_back_slow_path const&>(std::__1::basic_string, std::__1::allocator > const&&&) in libCoreClientiOS.a(tolua_gameinterface.o) |
39 |
"std::__1::basic_string,
std::__1::allocator >::~basic_string()" ,
referenced from: |
40 |
_l_registercallback in libCoreClientiOS.a(logicthread.o) |
41 |
_luapanic in libCoreClientiOS.a(logicthread.o) |
42 |
ExUnit::LogicThread::Run() in libCoreClientiOS.a(logicthread.o) |
43 |
ExUnit::LogicThread::HandleError() in libCoreClientiOS.a(logicthread.o) |
44 |
ExUnit::LogicThread::CallVA(char
const*, char const*, ...) in libCoreClientiOS.a(logicthread.o) |
45 |
ExUnit::LogicThread::RemoveCallback(char
const*) in libCoreClientiOS.a(logicthread.o) |
46 |
ExUnit::LogicThread::SetCallback(char
const*, int) in libCoreClientiOS.a(logicthread.o) |
48 |
"std::__1::basic_string,
std::__1::allocator >::operator=(std::__1::basic_string, std::__1::allocator > const&)" ,
referenced from: |
49 |
tolua_gameinterface_vector_string___seti00(lua_State*) in libCoreClientiOS.a(tolua_gameinterface.o) |
50 |
"std::__1::basic_ostream
>::put(char)" ,
referenced from: |
51 |
std::__1::basic_ostream
>& std::__1::endl >(std::__1::basic_ostream >&) in libCoreClientiOS.a(logicthread.o) |
52 |
"std::__1::basic_ostream
>::flush()" ,
referenced from: |
53 |
std::__1::basic_ostream
>& std::__1::endl >(std::__1::basic_ostream >&) in libCoreClientiOS.a(logicthread.o) |
54 |
"std::__1::basic_ostream
>::sentry::sentry(std::__1::basic_ostream >&)" ,
referenced from: |
55 |
std::__1::basic_ostream
>& std::__1::operator<<<std::__1::char_traits >(std::__1::basic_ostream >&, char const*) in libCoreClientiOS.a(logicthread.o) |
56 |
"std::__1::basic_ostream
>::sentry::~sentry()" ,
referenced from: |
57 |
std::__1::basic_ostream
>& std::__1::operator<<<std::__1::char_traits >(std::__1::basic_ostream >&, char const*) in libCoreClientiOS.a(logicthread.o) |
58 |
"std::__1::cerr" ,
referenced from: |
59 |
ExUnit::LogicThread::Run() in libCoreClientiOS.a(logicthread.o) |
60 |
ExUnit::LogicThread::ContactTriggered(b2Contact*) in libCoreClientiOS.a(logicthread.o) |
61 |
ExUnit::LogicThread::SensorTriggered(b2Contact*) in libCoreClientiOS.a(logicthread.o) |
62 |
"std::__1::ctype::id" ,
referenced from: |
63 |
std::__1::basic_ostream
>& std::__1::endl >(std::__1::basic_ostream >&) in libCoreClientiOS.a(logicthread.o) |
64 |
"std::__1::locale::~locale()" ,
referenced from: |
65 |
std::__1::basic_ostream
>& std::__1::endl >(std::__1::basic_ostream >&) in libCoreClientiOS.a(logicthread.o) |
66 |
"std::__1::ios_base::__set_badbit_and_consider_rethrow()" ,
referenced from: |
67 |
std::__1::basic_ostream
>& std::__1::operator<<<std::__1::char_traits >(std::__1::basic_ostream >&, char const*) in libCoreClientiOS.a(logicthread.o) |
68 |
"std::__1::ios_base::clear(unsigned
int)" ,
referenced from: |
69 |
std::__1::basic_ostream
>& std::__1::operator<<<std::__1::char_traits >(std::__1::basic_ostream >&, char const*) in libCoreClientiOS.a(logicthread.o) |
70 |
ld:
symbol(s) not found for architecture
i386 |
71 |
clang:
error: linker command failed
with exit code
1 (use - v to
see invocation) |
看着就非常複雜!
有這麼多的link STL的錯誤。
其實,就是你編譯靜態庫的時候使用不同版本的標準庫, C++ Standard Library
那麼如何fix掉這個issue呢?看下面這兩張圖!
如果你這兩個在編譯靜態庫和在使用靜態庫的app中設置的是一樣的,應該就可以解決掉這個問題!
事實上,compiler default 足夠了。
今天,使用了第三方一個庫,結果,出現,iOS Undefined symbols for architecture armv7 std::basic_string<char, std::char_traits<char>
注意:不是修改Build Setting裏面的設置,而是添加一個libstdc++.dylib, 搞定!