web-dev-qa-db-ja.com

g ++コンパイルエラー:存在する共有ライブラリ関数への未定義の参照

最近、ubuntuマシンにhdf5ライブラリをインストールしましたが、エクスポートされた関数へのリンクに問題があります。問題を説明するために、簡単なテストスクリプトを作成しましたreadHDF.cpp

#include <hdf5.h>

int main(int argc, char * argv[])
{
  hid_t     h5_file_id = H5Fopen(argv[1], H5F_ACC_RDWR, H5P_DEFAULT);
  return 0;
}

コンパイルコマンドは

g++ -Wl,-rpath,$HOME/hdf5/lib -I$HOME/hdf5/include \
    -L$HOME/hdf5/lib -l:$HOME/hdf5/lib/libhdf5.so readHDF.cpp

これは次のエラーを返します

/tmp/cc6DXdxV.o: In function `main':  
readHDF.cpp:(.text+0x1f): undefined reference to `H5check_version'  
readHDF.cpp:(.text+0x3c): undefined reference to `H5Fopen'  
collect2: ld returned 1 exit status

nmコマンドは、関数がエクスポートされたと言っているように見えるため、混乱しています。

nm -C $HOME/hdf5/lib/libhdf5.so | grep H5check_version

戻る

0000000000034349 T H5check_version

H5Fopenについても同様の結果です。何がうまくいかないのかについて何か考えはありますか?それが役立つかどうかはわかりませんが、スクリプトのH5Fopen部分をコメントアウトすると、正常にコンパイルされます。

#include <hdf5.h>

int main(int argc, char * argv[])
{
hid_t     h5_file_id;// = H5Fopen(argv[1], H5F_ACC_RDWR, H5P_DEFAULT);
return 0;
}

また、h5pyやtablesなどのさまざまなpythonモジュールで使用されるhdf5の複数のバージョンがサーバーにインストールされていますが、それらのいずれも機能させることができなかったため、このバージョンをインストールしましたローカルディレクトリにあり、g ++リンカーのrpathオプションを変更しました。

15
dermen

了解しました。問題は、コンパイルコマンドでの-lhdf5の配置にありました。どうやら-lhdf5はreadHDF.cppの後に配置する必要があります。例えば ​​g++ -Wl,-rpath=$HOME/hdf5/lib -L$HOME/hdf5/lib -I$HOME/hdf5/include readHDF.cpp -lhdf5は問題なくコンパイルされますが、g++ -Wl,-rpath=$HOME/hdf5/lib -L$HOME/hdf5/lib -I$HOME/hdf5/include -lhdf5 readHDF.cppは未定義の参照エラーで失敗します。興味深いことに、両方のコンパイルコマンドがUbuntu 10.04で機能したため、これはUbuntu12.04でのみ問題でした。

この投稿で説明付きの答えを見つけました:

nmがこのシンボルが存在することを示している場合でも、シンボルへの未定義の参照

スクリプトの後に-lXXXを配置する方が安全だと思います。

30
dermen

これはバグではありません。 `FooClass :: SayHello() 'へのC++共有ライブラリの未定義の参照 を参照してください。

「GCCreuqireの最近のバージョンでは、オブジェクトファイルとライブラリを相互に依存する順序で配置しています...」

5
Chahé

コンパイルコマンドに-lhdf5を入れるのを忘れました。また、-l:$HOME/hdf5/lib/libhdf5.soは必要ありません。

これは機能するはずです:$ g++ -Wl,-rpath,$HOME/hdf5/lib -I$HOME/hdf5/include -L$HOME/hdf5/lib -lhdf5 readHDF5.cpp

0