10

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;
}
4

3 に答える 3

12

エラーによると、libc++ を stdlibc++ とリンクしようとしているように見えるはずです。libc++ と stdlibc++ は異なります。stdlibc++ は gcc の C++ 標準ライブラリであり、互いに互換性がありません。

あなたの問題については、libpoppler.soがstdlibc ++を使用しているようですが、clangコマンドラインでlibc ++を標準ライブラリとして使用しようとしています。リンク段階で名前が異なります。理由の詳細については、この回答の最後にあるリンクを参照してください.

したがって、おそらくあなたの解決策は、コンパイルコマンドを次のように変更することです

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

std:__1::set と std::set の詳細については、この質問を参照してください。

このboost::program_optionsの例をリンクして、c++0xモードでlibc++を使用してclangできないのはなぜですか?

于 2013-08-27T08:12:45.643 に答える
4

libpoppler.soGNU stdlibc++ に対してリンクされているためです。1 つの実行可能ファイルのすべての部分は、同じ標準 C および同じ標準 C++ ライブラリに対してリンクする必要があります。

最も簡単なオプションは、デフォルトの標準ライブラリを使用することです。どちらも現在、ほとんど C++11 で完全です。

libpoppler.soまたは、バージョンのagainstをビルドすることもできますがlibc++、動的リンカーが正しい名前を見つけるように別の名前を付ける必要があります。

リンク エラーでは、and などを参照していることがわかりますlibpoppler.sostd::set、オブジェクトはandなどstd::lessを参照したいと考えています。これは、GNU stdlibc++ と Clang libc++ のバージョン管理のアプローチが異なるためです。std::__1::setstd::__1::less

于 2013-08-27T08:06:12.793 に答える
3

libc++ は GNU C++ 標準ライブラリとは異なる名前空間を使用するためです。2 つのライブラリの型のレイアウトは確かにいくつかの型で異なるため、このリンカ エラーは良いことです。

つまり、これが意味するのは、「poppler」ライブラリは、名前のセットが 1 つある GNU C++ std ライブラリに対して構築されたということです。一方、コンパイラは、プログラムの翻訳で関数呼び出しに libc++ の宣言を使用しました。したがって、リンカは std ライブラリ宣言の libc++ 命名を持つオブジェクト (poppler ライブラリなど) 内のシンボルを探しますが、それらは同じ名前で発行されていないため見つかりません。それらはおそらく poppler ライブラリに存在します。 GNU名で。

もちろん、これをどのように修正できるかだけが気になるでしょう: プログラムと poppler ライブラリの両方を同じ標準ライブラリを使用してビルドします。poppler ライブラリをビルドできない場合は、libc++ に対してビルドされたバイナリが公開されるまで待つ必要があります。

于 2013-08-27T08:07:19.340 に答える