【问题标题】:How I do compile a application against a static library compiled with libc++ in xcode/clang/macos?如何针对在 xcode/clang/macos 中使用 libc++ 编译的静态库编译应用程序?
【发布时间】:2013-02-10 23:00:46
【问题描述】:

当我尝试编译测试控制台应用程序以测试同一工作区上静态库上的某些功能时,我在二进制文件的链接阶段遇到了问题,只有当我选择使用 libc++ 标准库时才会发生。

缺少符号错误如下:

    Undefined symbols for architecture x86_64:
  "std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::empty() const", referenced from:
      libtorrent::torrent::replace_trackers(std::__1::vector<libtorrent::announce_entry, std::__1::allocator<libtorrent::announce_entry> > const&) in libLibOFFTorrent-xcode.a(torrent.o)
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

当我在两个目标中选择 stdlibc++ 时,一切都可以编译并且运行正常。

我的问题是:

  1. 在静态库上使用 libc++ 有一些限制吗?
  2. 它是 apple/clang++ 链接器工具中的一个错误?
  3. 如何配置项目以使用 libc++ 与我的静态 图书馆?
  4. 为什么链接器工具找不到标准 c++ 的符号 静态库上的库?,(任何其他依赖的库都是针对 libc++ 编译的)
  5. 我应该忘记使用 libc++ 的想法吗?

注释:

  1. 静态库依赖于 libboost_system,我使用 libc++ 和 libstdc++ 编译得到相同的结果
  2. 当我使用“bjam”工具运行测试时,它运行正常,可能是 jam 文件选择了 libstdc++ 来编译文件。
  3. 我知道更改标准库可以解决链接问题,我只想知道这是为什么。

更新:当我在静态库项目中删除对 string::empty 的引用时,依赖的项目可以使用 libc++ 正常编译并运行,但它会进入无限循环。

更新 2:当我用 libstdc++ 编译整个东西时,删除 string::empty 引用没有任何效果,它运行良好。没有循环,这让我认为这是一个错误或类似的东西。

更新 3:当它编译时,这是程序无限循环的地方:

【问题讨论】:

    标签: c++ xcode static-libraries clang libc++


    【解决方案1】:

    您的一个依赖项 (libtorrent) 似乎是针对 libstdc++ 构建的。

    检查命名空间:std::__1::basic_string。它有__1前缀,通常表示libstdc++)。

    我可能是错的,但我认为如果你绝对想使用这个,你需要重建你的 libtorrentlibc++

    请注意,使用stdlibc++ 是很常见的。

    【讨论】:

    • libtorrent 是我在 xcode 的工作区中设置的静态库,它是用 libc++ 编译的(截图来自 libtorrent 的设置),当我用 libstdc++ 编译时一切都很好,我已经重建了很多次lib。这很奇怪。生病尝试删除对 string::empty() 的调用以查看会发生什么。
    【解决方案2】:

    您是否有机会使用 -D_LIBCPP_INLINE_VISIBILITY="" 编译 libtorrent?

    我问的原因是 std::string::empty() 不在 libc++.dylib 中,因为它被标记为“always_inline”。所以它应该在使用时被内联到 libtorrent 中。

    【讨论】:

    • 不,当用那个标志编译它时,我得到了很多未解决的符号错误。全部与字符串相关,暂时使用libstdc++。
    • 好吧,我不建议你使用那个标志。事实上,我建议你不要。顺便说一句,std::__1 符号来自 libc++,而不是 libstdc++。
    • 我注意到,我很早就做了那个测试,我知道 std::__1 来自 libc++,这就是为什么很奇怪。正如我在问题更新中所说,我能够编译和运行测试,但它挂在向量类中的某些方法上。我不期待这个问题,但很高兴知道为什么会发生这种情况。
    • 在您编译的每个库上使用命令行工具 nm,您能找到对 __ZNSsD1Ev 的任何引用吗?这是来自 libstdc++ 的 ~string()。找到它表明该对象是用 libstdc++ 而不是 libc++ 编译的。
    • 黑暗中的一枪:尝试将以下内容添加到 C++ 其他标志:-D'_LIBCPP_EXTERN_TEMPLATE(...)='
    猜你喜欢
    • 2010-11-25
    • 2011-09-22
    • 2013-10-27
    • 1970-01-01
    • 1970-01-01
    • 2012-01-19
    • 2012-09-14
    • 2022-08-03
    • 2016-07-28
    相关资源
    最近更新 更多