2016-10-18 5 views
0

私はランタイムエラー「未定義のシンボル:_ZTIN5eckit9ExceptionE」にこだわっているlibMagPlus.so libaray共有を構築しながら、このMAGICS - 未定義のシンボル:_ZTIN5eckit9ExceptionE

Start 2: basic_python 
2: Test command: /usr/local/Python/2.7.10/bin/python "coast.py" 
2: Environment variables: 
2: PYTHONPATH=/opt/src/ecmwf/Magics-2.29.4-Source/build/python 
2: LD_LIBRARY_PATH=/opt/src/ecmwf/Magics-2.29.4-Source/build/lib 
2: MAGPLUS_HOME=/opt/src/ecmwf/Magics-2.29.4-Source/test/.. 
2: OMP_NUM_THREADS=1 
2: Test timeout computed to be: 1500 
2: Traceback (most recent call last): 
2: File "coast.py", line 11, in <module> 
2:  from Magics.macro import * 
2: File "/opt/src/ecmwf/Magics-2.29.4-Source/build/python/Magics/__init__.py", line 32, in <module> 
2:  _Magics = swig_import_helper() 
2: File "/opt/src/ecmwf/Magics-2.29.4-Source/build/python/Magics/__init__.py", line 28, in swig_import_helper 
2:  _mod = imp.load_module('_Magics', fp, pathname, description) 
2: ImportError: /usr/local/Magics/2.29.4/gnu/4.4.7/lib/libMagPlus.so: undefined symbol: _ZTIN5eckit9ExceptionE 

のようなエラーはありませんでした。このエラーは、実行時にPythonモジュールが読み込んだときに発生しています。 NMでチェック

は、未定義のシンボル「_ZTIN5eckit9ExceptionE」はこの

nm libOdb.a | grep _ZTIN5eckit9ExceptionE 
       U _ZTIN5eckit9ExceptionE 
       U _ZTIN5eckit9ExceptionE 
       U _ZTIN5eckit9ExceptionE 
       U _ZTIN5eckit9ExceptionE 
       U _ZTIN5eckit9ExceptionE 
       U _ZTIN5eckit9ExceptionE 
0000000000000000 V DW.ref._ZTIN5eckit9ExceptionE 
       U _ZTIN5eckit9ExceptionE 
       U _ZTIN5eckit9ExceptionE 
       U _ZTIN5eckit9ExceptionE 
       U _ZTIN5eckit9ExceptionE 
       U _ZTIN5eckit9ExceptionE 
       U _ZTIN5eckit9ExceptionE 

のように、静的ライブラリlibOdb.aからではありませんしかし、誰に対してリンクexcutablesのための未定義のシンボル「_ZTIN5eckit9ExceptionE」についての苦情がありました静的ライブラリlibOdb.aは、コンパレーション時とランタイム時の両方で直接実行されます。すべてのC、Fortranのコードは、共有ライブラリlibMagPlus.soを除いて、静的ライブラリlibOdb.aでもうまくいきました。

ライブラリLibMagPlus.so

この

/usr/bin/g++ -fPIC -pipe -O2 -g \ 
-Wl,--disable-new-dtags -shared \ 
-Wl,-soname,libMagPlus.so -o ../lib/libMagPlus.so \ 
... ... \ 
-Wl,-Bstatic -L$ODB_API/lib -lOdb \ 
... ... 

ようlibOdb.aはFAQとググ、私の問題で少し助けを検索この

usr/bin/ar qc ../../lib/libOdb.a ... ... 

/usr/bin/ranlib ../../lib/libOdb.a 

のように構築されたライブラリをリンクしました。私はC++についてほとんど知りませんでしたが、これをどうやって解決するのか分かりません。

Exceptions.h

#ifndef eckit_Exceptions_h 
#define eckit_Exceptions_h 

#include <errno.h> 

#include "eckit/eckit.h" 
#include "eckit/eckit_version.h" 

#include "eckit/log/CodeLocation.h" 
#include "eckit/log/Log.h" 
#include "eckit/log/SavedStatus.h" 
#include "eckit/compat/StrStream.h" 

namespace eckit { 

//----------------------------------------------------------------------------- 

void handle_panic(const char*); 
void handle_panic(const char*, const CodeLocation&); 

/// @brief General purpose exception 
/// Derive other exceptions from this class and implement then in the class that throws them. 
class Exception : public std::exception { 

public: // methods 

    /// Constructor with message 
    Exception(const std::string& what, const CodeLocation& location = CodeLocation()); 

    /// Destructor 
    /// @throws nothing 
    ~Exception() throw(); 

    virtual const char *what() const throw() { return what_.c_str(); } 
    virtual bool retryOnServer() const  { return false; } 
    virtual bool retryOnClient() const  { return false; } 
    virtual bool terminateApplication() const { return false; } 

    static bool throwing(); 
    static void exceptionStack(std::ostream&,bool callStack = false); 

    const std::string& callStack() const { return callStack_; } 

protected: // methods 

void reason(const std::string&); 
Exception(); 

    virtual void print(std::ostream&) const; 

private: // members 

    std::string  what_;  ///< description 
    std::string  callStack_; ///< call stack 
    SavedStatus  save_;  ///< saved monitor status to recover after destruction 
    Exception*  next_; 
    CodeLocation  location_; ///< where exception was first thrown 

    friend std::ostream& operator<<(std::ostream& s,const Exception& p) 
    { 
     p.print(s); 
     return s; 
    } 
}; 

nmの-Cl $ ODB_API/libに/ libOdb.a [これらの更新ホルヘの入力に応答して、]

| grep -i「eckit ::例外」

    U eckit::Exception::Exception(std::string const&, eckit::CodeLocation const&) /opt/src/OdbAPI-0.10.2-Source/eckit/src/eckit/exception/Exceptions.h:84 
       U eckit::Exception::~Exception()  /opt/src/OdbAPI-0.10.2-Source/eckit/src/eckit/exception/Exceptions.h:108 
0000000000000000 W eckit::Exception::retryOnClient() const  /opt/src/OdbAPI-0.10.2-Source/eckit/src/eckit/exception/Exceptions.h:48 
0000000000000000 W eckit::Exception::retryOnServer() const  /opt/src/OdbAPI-0.10.2-Source/eckit/src/eckit/exception/Exceptions.h:47 
0000000000000000 W eckit::Exception::terminateApplication() const  /opt/src/OdbAPI-0.10.2-Source/eckit/src/eckit/exception/Exceptions.h:49 
0000000000000000 W eckit::Exception::what() const  /opt/src/OdbAPI-0.10.2-Source/eckit/src/eckit/exception/Exceptions.h:46 
       U eckit::Exception::print(std::ostream&) const 
       U typeinfo for eckit::Exception 

は、私はまた、このように、libOdb.aからすべてのオブジェクト・ファイルを解凍し、「-fvisibility =デフォルト-rdynamic」オプションで、それらのすべてをlibMagPlus.soを再リンクしてみました

ar x libOdb.a (./Odb) 

/usr/bin/g++ -fvisibility=default -rdynamic -fPIC -pipe -O2 -g \ 
-Wl,--disable-new-dtags -shared \ 
-Wl,-soname,libMagPlus.so -o ../lib/libMagPlus.so \ 
... ... \ 
./Odb/*.o \ 
... ... 

しかし、まだニーズがExceptions.hをタッチすると、それに触れるする方法を疑問に思う場合

U eckit::Exception::~Exception()  /opt/src/OdbAPI-0.10.2-Source/eckit/src/eckit/exception/Exceptions.h:108 
U eckit::Exception::print(std::ostream&) const 
U typeinfo for eckit::Exception 

これらの未定義のシンボルを得ましたか。

誰かが助けることができますか?

お時間

よろしく

+0

C++シンボル名は(関数のオーバーロードをサポートするために、翻訳の一種)をマングルされています。 'C++ filt'のようなツールを使用して、それを読み取り可能なシンボル、' typeinfo for eckit :: Exception'に変換することを検討してください。おそらくライブラリにリンクしたり、 'eckit :: Exception'クラスを定義する(宣言しない)ヘッダを含んでいないでしょう。もう一つの可能​​性は、リンカにそのシンボルを隠すように指示することで、シンボルテーブルにエクスポートされないため、未定義とは見なされません。 –

+0

ありがとう、ホルヘ!私はもっ​​と多くの情報で投稿を更新しました。可能であれば見てください。 @JorgeB – jerry

答えて

0

Exceptions.hファイルを見てみましょう鑑賞。定義されていないシンボルはすべてと宣言されていますが、定義されていない関数に属することに注意してください。

~Exception() throw(); 
// [...] 
virtual void print(std::ostream&) const; 

eckit::Exception::~Exception()あなたのデストラクタ(Exceptions.h:108で宣言されたが定義されていない)です。 eckit::Exception::print(std::ostream&) constも同様です。typeinfo for eckit::Exceptionの場合は、ここでの問題は、あなたが(抽象クラ​​スで)純粋仮想として宣言されていませんが、どちらも定義されていないので、タイプが完了していないされている。仮想関数を持っていることを

です

私が間違っていない場合、eckit::Exceptionクラスは他の派生クラスのスーパークラスであるため、そのデストラクタもvirtualと宣言する必要があります。

欠落している機能が宣言されている場所を確認します。アーカイバがスキップしたオブジェクトファイル(欠落した関数が.cppファイルに定義されている場合)または含まれていないヘッダーファイル(.hppファイルで定義されている場合)に存在する必要があります。

も参照してください:g++ undefined reference to typeinfo

+0

入力いただきありがとうございます。共有オブジェクト(.so)ファイルをg ++にリンクすると、シンボルの欠落については不平を言わず、この問題が発生します。 '-Wl、-no-undefined'を追加すると、不足しているものがすべて見つかり、問題を修正しました。 – jerry