2012-10-16 67 views
23

我有一个C++中的大型静态库,其中包含最初为iOS构建的Objective-C(armv7)。STD链接器与苹果LLVM 4.1错误

我构建了它的OS X(64位Intel x86_64)版本,但只要我尝试在OS X应用程序项目(针对Lion 10.7)中使用它,就会出现数十个链接器错误,大部分他们关于标准库符号。

我知道如何解决“我的”连接器问题,但下面复制的STD人正在窃听我。

"std::basic_filebuf<char, std::char_traits<char> >::is_open() const" 
"std::basic_stringbuf<char, std::char_traits<char>, std::allocator<char> >::str() const" 
"std::basic_ios<char, std::char_traits<char> >::widen(char) const" 
"std::istream& std::istream::_M_extract<double>(double&)" 
"std::ostream::put(char)" 
"std::ostream::flush()" 
"std::ostream& std::ostream::_M_insert<void const*>(void const*)" 
"std::ostream& std::ostream::_M_insert<bool>(bool)" 
"std::ostream& std::ostream::_M_insert<double>(double)" 
"std::ostream& std::ostream::_M_insert<unsigned long>(unsigned long)" 
"std::ostream::operator<<(int)" 
"std::ostream::operator<<(short)" 
"std::string::_Rep::_M_destroy(std::allocator<char> const&)" 
"std::string::_Rep::_S_terminal" 
"std::string::_Rep::_S_empty_rep_storage" 
"std::string::_Rep::_S_create(unsigned long, unsigned long, std::allocator<char> const&)" 
"std::string::append(char const*, unsigned long)" 
"std::string::append(std::string const&)" 
"std::string::assign(std::string const&)" 
"std::string::reserve(unsigned long)" 
"std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&)" 
"std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(std::string const&)" 
"std::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string()" 
"std::basic_ofstream<char, std::char_traits<char> >::open(char const*, std::_Ios_Openmode)" 
"std::basic_ofstream<char, std::char_traits<char> >::close()" 
"std::basic_ofstream<char, std::char_traits<char> >::basic_ofstream()" 
"std::basic_ofstream<char, std::char_traits<char> >::~basic_ofstream()" 
"std::_List_node_base::hook(std::_List_node_base*)" 
"std::_List_node_base::unhook()" 
"std::basic_stringstream<char, std::char_traits<char>, std::allocator<char> >::basic_stringstream(std::string const&, std::_Ios_Openmode)" 
"std::basic_stringstream<char, std::char_traits<char>, std::allocator<char> >::basic_stringstream(std::_Ios_Openmode)" 
"std::basic_stringstream<char, std::char_traits<char>, std::allocator<char> >::~basic_stringstream()" 
"std::basic_ostringstream<char, std::char_traits<char>, std::allocator<char> >::basic_ostringstream(std::_Ios_Openmode)" 
"std::basic_ostringstream<char, std::char_traits<char>, std::allocator<char> >::~basic_ostringstream()" 
"std::ios_base::Init::Init()" 
"std::ios_base::Init::~Init()" 
"std::basic_ios<char, std::char_traits<char> >::clear(std::_Ios_Iostate)" 
"std::basic_ostream<char, std::char_traits<char> >& std::__ostream_insert<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*, long)" 
"std::_Rb_tree_decrement(std::_Rb_tree_node_base*)" 
"std::_Rb_tree_increment(std::_Rb_tree_node_base const*)" 
"std::_Rb_tree_increment(std::_Rb_tree_node_base*)" 
"std::__throw_logic_error(char const*)" 
"std::__throw_length_error(char const*)" 
"std::__throw_out_of_range(char const*)" 
"std::_Rb_tree_rebalance_for_erase(std::_Rb_tree_node_base*, std::_Rb_tree_node_base&)" 
"std::_Rb_tree_insert_and_rebalance(bool, std::_Rb_tree_node_base*, std::_Rb_tree_node_base*, std::_Rb_tree_node_base&)" 
"std::cerr" 
"std::cout" 

我检查我的构建设置,我的项目链接到标准库(-stdlib=libc++),我可以使用std ::法院没有在我的main.cpp任何问题。

我将生成设置中的编译器从Apple LLVM 4.1更改为LLVM GCC 4.2,问题消失。 我想继续使用Apple LLVM 4.1。我该如何解决这个问题?

谢谢!

+0

正如@ gzfrancisco所说,链接stdC++。6.dylib将解决这个问题。 – aksani56

回答

44

更改链接到使用libstdc++代替libc++标准库 - 问题是,其他图书馆使用它使用libstdc++g++模式编译。

考虑下面的示例代码:

dhcp-191:~/Development/testy/fred% cat fred.cpp 
#include <iostream> 
#include <string> 
#include "fred.h" 

using namespace std; 

bool dofred(string &x) 
{ 
    cout << x << endl; 
    return true; 
} 
dhcp-191:~/Development/testy/fred% cat fred.h 

#include <iostream> 
#include <string> 

bool dofred(std::string &x); 

dhcp-191:~/Development/testy/fred% clang++ -stdlib=libc++ -shared -o fred.dylib fred.cpp 
dhcp-191:~/Development/testy/fred% nm fred.dylib | c++filt | grep dofred 
0000000000000fa0 T dofred(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&) 
dhcp-191:~/Development/testy/fred% clang++ -stdlib=libstdc++ -shared -o fred.dylib fred.cpp 
dhcp-191:~/Development/testy/fred% nm fred.dylib | c++filt | grep dofred      
0000000000000e30 T dofred(std::string&) 

你得到两个完全不同的导出符号。尝试使用该符号时,使用相同-stdlib标志的应用将能够链接,而不会显示链接错误的应用。

+9

因为libC++在std内部使用了一个内联命名空间,所以你可以区分这个区别,所以libC++中的符号就像'std :: __ 1 :: cout'。 – bames53

+0

@ bames53这是一个很好的提示,用于追踪这些链接错误! – Petesh

+0

好的,谢谢!我没有意识到有2个可用的标准库实现。我知道他们有不同的内部结构,但我不明白为什么会导致像'std :: cout'这样的链接器问题。 /编辑:saw @ bames53的回答。现在我明白了。有点困惑_why_虽然:) – antho

11

将所有C++文件放入单独的库后,出现此问题。我确实将所有项目的设置设置为使用libC++,但链接程序不与libC++链接。如果我将C++文件添加到主项目中,问题就会消失。为了解决这个问题,你可以在主项目的“Other Linker Flags”部分添加'-lC++'。这将迫使XCode链接到libC++。

编辑:正如另一张海报所说,XCode可能表现正确。我曾预料它会知道添加C++链接,因为C++ lib源代码位于同一个工作区中。

0

回复jlukanta:我有同样的问题。我一直小心选择正确的性病,但我仍然有这些错误。但这不是一个错误,它实际上是有道理的:如果您的项目中没有任何C++代码,为什么Xcode应该与C++ stdlib链接?

当然,如果你的项目中没有C++代码,但仍然是C++库,这是一个问题。

44

在iOS 7中,我使用图表库,并且有相同的问题。在这种情况下,lib stdC++不能解决问题。

我将stdC++。6.dylib添加到我的构建阶段并找到符号。

+0

谢谢!节省了我很多次! – liuyaodong

+4

这也适用于我。有谁知道为什么'libstdC++。dylib'失败和'libstdC++。6.dylib'工作? – simeon

+1

谢谢,在我所有的头发都被拉出之前发现了这个:) –

3

我刚刚有一个类似的问题,我不得不去“构建设置”,然后“Apple LLVM 5.1 - 语言 - C++”,然后将“C++标准库”更改为libstdC++。

1

您也可以尝试在您的项目中添加一个空的.cpp文件。这将欺骗Xcode到加载C++ std库

+1

谢谢!这是为我工作的唯一解决方案。我尝试使用libC++和libstdC++(在LLVM C++和“其他链接器标记”构建设置中指定)链接,但没有运气......将一个空的“foo.cpp”文件添加到项目中,并且没有更多链接器错误!谢谢! –