【问题标题】:STD linker error with Apple LLVM 4.1Apple LLVM 4.1 的 STD 链接器错误
【发布时间】:2012-10-06 22:02:32
【问题描述】:

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

我构建了它的 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++),我可以在 main.cpp 中毫无问题地使用 std::cout。

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

谢谢!

【问题讨论】:

  • 正如@gzfrancisco 所说,Link stdc++.6.dylib 将解决这个问题。

标签: c++ xcode macos linker-errors std


【解决方案1】:

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

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

【讨论】:

  • 谢谢!为我节省大量时间!
  • 这对我也有用。有谁知道为什么libstdc++.dylib 失败而libstdc++.6.dylib 有效?
  • 谢谢,在我所有的头发都被拔掉之前找到了这个:)
  • 与上面的 simeon 相呼应 - 为什么它适用于 libstdc++.6.dylib 而不是 libstdc++.dylib?当我在 Xcode 中为 libstdc++.dylib 执行“在查找器中显示”时,它是一个链接;当我点击链接时,它指向 libstdc++.6.0.9.dylib。这些有什么不同(但它们显然不是 - 因为将其直接设置为 libstdc++.6.0.9.dylib 修复了链接问题)。
  • 谢谢!不知道为什么 .6 有效而另一个也无效,似乎都指向 libstdc++.6.0.9.dylib
【解决方案2】:

将链接的标准库更改为使用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&)

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

【讨论】:

  • 你可以分辨出来,因为libc++在std中使用了一个内联命名空间,所以libc++中的符号就像std::__1::cout
  • @bames53 这是跟踪此类链接错误的好方法!
  • 好的,谢谢!我没有意识到有 2 个可用的标准库实现。我知道它们有不同的内部结构,但我不明白为什么这会导致链接器出现问题,例如std::cout。 /edit:看到@bames53 的回答。现在我明白了。虽然有点困惑为什么 :)
  • @antho 好吧,不同的内部结构意味着如果链接成功,程序将被严重破坏。所以 libc++ 的设计者采取了特殊的措施来确保使用不兼容的标准库实现的模块之间的链接不会成功;他使用称为内联命名空间的特殊功能来确保链接器尝试匹配的符号不匹配。
  • 谢谢!我也没有意识到有两种类型的库。
【解决方案3】:

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

编辑:正如另一位发帖人所说,XCode 可能表现正确。我原以为它会知道添加 C++ 链接,因为 C++ lib 源代码在同一个工作区中。

【讨论】:

    【解决方案4】:

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

    【讨论】:

      【解决方案5】:

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

      【讨论】:

      • 谢谢!这是唯一对我有用的解决方案。我尝试与 libc++ 和 libstdc++ 链接(在 LLVM c++ 和“其他链接器标志”构建设置中指定),但没有运气......向项目添加了一个空的“foo.cpp”文件,瞧,没有更多的链接器错误!谢谢!
      【解决方案6】:

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-03-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多