【问题标题】:clang++ -stdlib=libc++ leads to undefined referenceclang++ -stdlib=libc++ 导致未定义的引用
【发布时间】:2013-08-27 07:51:21
【问题描述】:

为什么在 libc++ 中使用 clang 时出现以下链接器错误:

$ clang++ -stdlib=libc++  po.cxx -lpoppler
/tmp/po-QqlXGY.o: In function `main':
po.cxx:(.text+0x33): undefined reference to `Dict::lookup(char*, Object*, std::__1::set<int, std::__1::less<int>, std::__1::allocator<int> >*)'
clang: error: linker command failed with exit code 1 (use -v to see invocation)

地点:

$ nm -D /usr/lib/x86_64-linux-gnu/libpoppler.so | grep lookup | c++filt| grep \ Dict::lookup\(
00000000000c1870 T Dict::lookup(char*, Object*, std::set<int, std::less<int>, std::allocator<int> >*)

代码很简单:

#include <poppler/PDFDoc.h>

int main()
{
  Dict *infoDict;
  Object obj;
  infoDict->lookup((char*)"key", &obj);
  return 0;
}

【问题讨论】:

    标签: linker-errors clang++ libc++


    【解决方案1】:

    根据您的错误,应该就像您正在尝试将 libc++ 与 stdlibc++ 链接, libc++和stdlibc++不同,stdlibc++是gcc的c++标准库,不会互相兼容。

    对于您的问题,就像您的 libpoppler.so 正在使用 stdlibc++, 但是在您的 clang 命令行中,您正在尝试使用 libc++ 作为标准库,它们在链接阶段具有不同的名称,请参阅此答案末尾的链接以了解详细原因。

    所以,也许您的解决方案只是将编译命令更改为

        clang++ -stdlib=libstdc++  po.cxx -lpoppler
    

    请参阅此问题以了解为什么 std:__1::set 和 std::set 的详细信息。

    Why can't clang with libc++ in c++0x mode link this boost::program_options example?

    【讨论】:

      【解决方案2】:

      因为libpoppler.so 与 GNU stdlibc++ 相关联。单个可执行文件的所有部分都必须链接到相同的标准 C 和相同的标准 C++ 库。

      最简单的选择是使用默认的标准库。两者现在大多是 C++11-complete。

      或者,您可以针对libc++ 构建libpoppler.so 的版本,但您必须为其指定不同的名称,以便动态链接器找到正确的名称。

      在链接错误中,您可以看到libpoppler.so 引用std::setstd::less 等,但您的对象想要引用std::__1::setstd::__1::less 等。那是因为GNU stdlibc++ 和Clang libc++以不同的方式进行版本控制。

      【讨论】:

        【解决方案3】:

        因为 libc++ 使用与 GNU C++ 标准库不同的命名空间。这个链接器错误是一件好事,因为对于某些类型,这两个库的类型的布局肯定会有所不同。

        所以这意味着您的“poppler”库是针对具有一组名称的 GNU C++ std 库构建的——而编译器使用 libc++ 中的声明来进行程序翻译中的函数调用。因此,链接器在对象(例如 poppler 库)中查找符号,这些符号对 std 库声明具有 libc++ 命名,但它没有找到它们,因为它们不是以相同的名称发出的——它们可能存在于 poppler 库中使用 GNU 名称。

        当然,您可能只关心如何解决这个问题:使用相同的标准库构建您的程序和 poppler 库。如果您无法构建 poppler 库,则必须等待他们推出针对 libc++ 构建的二进制文件。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-09-14
          • 2011-10-24
          • 2020-06-05
          • 1970-01-01
          • 2012-08-04
          • 1970-01-01
          • 2012-08-13
          • 2012-09-08
          相关资源
          最近更新 更多