Apple LLVM 4.1的STD链接器错误

ant*_*tho 23 c++ macos xcode std linker-errors

我在C++中有一个大型静态库,其中有一些Objective-C最初是为iOS(armv7)构建的.

我构建了一个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"
Run Code Online (Sandbox Code Playgroud)

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

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

谢谢!

小智 46

在iOS 7中,我使用图表库并遇到同样的问题.在这种情况下,lib stdc ++不能解决问题.

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

  • 这对我也有用.有谁知道为什么`libstdc ++.dylib`失败和`libstdc ++.6.dylib`有效? (5认同)
  • 回应上面的simeon - 为什么它可以用libstdc ++.6.dylib而不是libstdc ++.dylib?当我在Xcode中为libstdc ++做一个'show in finder'时,dylib就是一个链接; 当我按照链接指向libstdc ++.6.0.9.dylib时.这些不一样(但它们显然不是 - 因为它直接设置为libstdc ++.6.0.9.dylib修复了链接问题). (4认同)

Pet*_*esh 45

更改链接使用的标准库libstdc++而不是libc++- 问题是其他库是使用g++使用libstdc++库的模式编译的.

请考虑以下示例代码:

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&)
Run Code Online (Sandbox Code Playgroud)

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

  • 你可以区分,因为libc ++在std中使用了一个内联命名空间,因此libc ++中的符号就像`std :: __ 1 :: cout`. (9认同)
  • @antho嗯,不同的内部意味着如果链接成功,程序将会非常可怕,可怕的破坏.因此,libc ++的设计者采取了特殊措施来确保使用不兼容的标准库实现的模块之间的链接不会成功; 他使用了一个称为内联命名空间的特殊功能来确保链接器尝试匹配的符号不匹配. (2认同)

jlu*_*nta 11

将所有C++文件放入单独的库后,我遇到了这个问题.我确实将所有项目的设置设置为使用libc ++,但链接器不与libc ++链接.如果我将C++文件添加到主项目,问题就会消失.要解决此问题,您可以在主项目的"其他链接器标志"部分添加"-lc ++".这将迫使XCode链接到libc ++.

编辑:正如另一张海报所说,XCode可能表现正常.我曾经期望它知道添加C++链接,因为C++ lib源代码在同一个工作区.