2016-12-14 10 views
5

これをコンパイルしようとしていますcfgparser exampleリンカはシンボルを見つけることができませんが、そこにありますか?

$ g++ example.cc -lcfgparser 
: In function `main': 
example.cc:(.text+0x6b): undefined reference to `ConfigParser_t::readFile(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)' 
example.cc:(.text+0x160): undefined reference to `ConfigParser_t::getValue(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*) const' 
example.cc:(.text+0x2d9): undefined reference to `ConfigParser_t::getValue(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, int*) const' 
example.cc:(.text+0x43c): undefined reference to `ConfigParser_t::getValue(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, double*) const' 
example.cc:(.text+0x5b1): undefined reference to `ConfigParser_t::getValue(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, bool*) const' 
example.cc:(.text+0x78c): undefined reference to `ConfigParser_t::getValue(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >*) const' 
example.cc:(.text+0xa15): undefined reference to `ConfigParser_t::getValue(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*) const' 
example.cc:(.text+0xba2): undefined reference to `ConfigParser_t::getValue(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*) const' 
example.cc:(.text+0xd15): undefined reference to `ConfigParser_t::getValue(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*) const' 
example.cc:(.text+0xe7f): undefined reference to `ConfigParser_t::getValue(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*) const' 
collect2: error: ld returned 1 exit statu 

しかし、明確にそれらのシンボルがあります。リンクされている唯一のオブジェクトファイルがあるように、他の同様の問題とは異なり

$ nm -gC /usr/lib/libcfgparser.so 
000000000003710 T ConfigParser_t::readFile(std::string const&) 
0000000000004880 T ConfigParser_t::ConfigParser_t(std::string const&) 
00000000000024c0 T ConfigParser_t::ConfigParser_t() 
0000000000004ad0 T ConfigParser_t::ConfigParser_t(std::string const&) 
00000000000024a0 T ConfigParser_t::ConfigParser_t() 
0000000000004d20 T ConfigParser_t::getOptions(std::string const&) const 
00000000000028d0 T ConfigParser_t::getSections() const 
0000000000002ff0 T ConfigParser_t::getValue(std::string, std::string, bool*) const 
0000000000002de0 T ConfigParser_t::getValue(std::string, std::string, double*) const 
0000000000002bd0 T ConfigParser_t::getValue(std::string, std::string, int*) const 
00000000000027d0 T ConfigParser_t::getValue(std::string, std::string, std::string*) const 
0000000000003500 T ConfigParser_t::getValue(std::string, std::string, std::vector<std::string, std::allocator<std::string> >*) const 

、これは、順番をリンクではありません。何か私は行方不明です?

+1

私の推測では、2つのモジュールは、 'std :: string'が異なることを意味するように構築されています。多分、C++ランタイムライブラリの異なるフレーバーにリンクされていますか? –

+0

サンプルコードをコピーした場合、 'stdio.h'をインクルードし、' cstdio'をインクルードしないと問題になることがあります。それは、char関連のものの壊れたリンケージと一致します。チェックするべき他のもの:あなたの 'libcfgparser.so'は' std :: string'で 'wchar_t'をサポートしていましたか? – starturtle

+0

私はABIとの互換性を確保するために同じ問題を抱えていたため、-m32/-m64がライブラリ/実行可能ビルドと一致するようにしました。 – ceorron

答えて

11

しかし、明確にそれらのシンボルがあります

明らかに、彼らはありません。よく見ると、 リンカーによって報告されていない署名と、ライブラリから報告された署名との間に一致するものはありません。 nmです。

標準ヘッダ<string>でのtypedefとしてstd::stringを定義:cxx11 ABI(GCC 4.7.0)のように、

std::basic_string<char, std::char_traits<char>, std::allocator<char>> 

<string>のGCC実装 がのtypedefとしてstd::stringを定義:

std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> 

std::__cxx11の名前空間は、バイナリ実装が で、そのタイプがcxx1 1 ABI。タイプ定義はstd::stringとしてデマングルシンボルを含むオブジェクトコードにGCC> = 4.7でコンパイル、<string>わけではない 標準ヘッダを含むC++変換ユニットを意味

バイナリ場合 - あなたのlibcfgparser.soなどが - それはstd::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>、 を参照していないとできないん、そのシンボルは、それが構築されたソースに言及しているかもしれないものは何でも その後、std::stringとしてデマングル記号が含まれていますその定義がstd::stringでコンパイルされた他のバイナリとリンクする必要があります。

あなたlibcfgparser.soは(最後の3年前に更新されました) cfgparser Sourceforce project からlibcfgparser0_1.1.2_amd64.debによってインストールされたものです。私はこれから、私は 同じパッケージでインストールされているライブラリにリンクされている同じexample.ccプログラムであなたのリンケージエラーを取得するということになります。 - cxx11 ABIを事前このライブラリはGCC 4.3.2で構築されたことを教えてくれる

/usr/lib$ strings -a libcfgparser.so | grep "GCC: (" 
GCC: (Debian 4.3.2-1.1) 4.3.2 
... 

エラーの説明がで明らかにされています。あなたのnm出力に表示されます

std::stringstd::basic_string<char, std::char_traits<char>, std::allocator<char>>の前cxx11デマングルの略語 です。

このlibcfgparser.soは現在のGCCとABI互換ではないため、 は、そのコンパイラでビルドしたプログラムとリンクすることはできません。できることは ソースパッケージからlibcfgparser-1.1.2.tar.bz2、 を現在のコンパイラでビルドしてから をビルドしたライブラリにプログラムをリンクすることです。

これはうまく動作しますが、簡単にはできません。まず、作業中の./configure スクリプトを作成するために、壊れた とソースパッケージの古い自動ツールを修正する必要があります。

パッケージメンテナーの熟練した印象を与えるものではありません。 パッケージのソースコード、著作権2008は、アマチュア品質のものです。 INI形式のファイルのC++パーサーが後であれば、boost::property_tree::ini_parserは のgotoソリューションになります。 this answer

+0

ありがとう!あなたの答えはとても役に立ち、教育的です。私は同様の理由を推測していましたが、おそらく "あなたの' nm'出力に現れる 'std :: string'は' std :: basic_string 、std :: allocator > '' std :: string'の短縮形を正しく省略する方法はありません。 – qweruiop

+0

'boost :: property_tree :: ini_parser'を使っても良いです。 – qweruiop

+0

@string :: string(demangled)= 'Ss'(mangled)は、cxx11以前のGCCの名前でmanglingされた*ハードコーディングされた*略語でした。 *リンカが見ているものなので、リンカとは違って*いますか? –

関連する問題