autotools ビルド システムを使用して静的ライブラリを作成するプロジェクトがあります。このライブラリにリンクする小さなテスト プログラムを作成して、このライブラリをテストしたいと考えています。
テスト プログラムは code::blocks IDE で作成されています。ヘッダーを含むパスが検索ディレクトリに追加され、含まれているライブラリが追加されました。
テスト プログラムをコンパイルすると、次のエラーが発生します。
obj/Debug/main.o: In function `givens':
<snip> undefined reference to `xhypot(double, double)'
ただし、xhypot はグローバル関数として宣言されており、次のようにインクルード ヘッダーに含まれreal.h
ています。
nr_double_t xhypot (const nr_double_t, const nr_double_t);
コンパニオン ファイルで定義されますreal.cpp
。
nr_double_t xhypot (const nr_double_t a, const nr_double_t b) {
nr_double_t c = fabs (a);
nr_double_t d = fabs (b);
if (c > d) {
nr_double_t e = d / c;
return c * sqrt (1 + e * e);
}
else if (d == 0)
return 0;
else {
nr_double_t e = c / d;
return d * sqrt (1 + e * e);
}
}
タイプ nr_double_t は config.h で次のように定義されています。
/* The global type of double representation. */
#define nr_double_t double
問題のある呼び出しがxhypot
発生する場所は、次のようなテンプレート クラスの静的ヘルパー関数です。
static nr_double_t
givens (nr_double_t a, nr_double_t b, nr_double_t& c, nr_double_t& s) {
nr_double_t z = xhypot (a, b);
c = a / z;
s = b / z;
return z;
}
ただし、xhypot
クラスの他の非静的メンバー関数でもまったく同じ構文で呼び出されます (つまり、この静的メソッドの行を次xhypot(double,double)
の行に置き換えると、エラーは消えます。nr_double_t z = xhypot (a, b);
nr_double_t z = 0.0;
これが私のテストプログラムの全体です:
#include "config.h"
#include "m_trsolver.h"
int main (int argc, char ** argv)
{
char infile[] = "test.net";
m_trsolver the_m_trsolver;;
return 0;
}
完全なビルド ログ:
g++ -Wall -DHAVE_CONFIG_H -g -I../qucs/qucs-core -I../qucs/qucs-core/src -I../qucs/qucs-core/src/components -I../qucs/qucs-core/src/components/devices -I../qucs/qucs-core/src/components/digital -I../qucs/qucs-core/src/components/verilog -I../qucs/qucs-core/src/components/microstrip -I../qucs/qucs-core/src/converter -I../qucs/qucs-core/src/m-interface -I../qucs/qucs-core/src/math -c /home/s0237326/src/qucs_m_interface_test/main.cpp -o obj/Debug/main.o
/home/s0237326/src/qucs_m_interface_test/main.cpp: In function ‘int main(int, char**)’:
/home/s0237326/src/qucs_m_interface_test/main.cpp:10: warning: unused variable ‘infile’
g++ -L../qucs/qucs-core -L../qucs/qucs-core/src -L../qucs/qucs-core/src/components -L../qucs/qucs-core/src/components/devices -L../qucs/qucs-core/src/components/digital -L../qucs/qucs-core/src/components/verilog -L../qucs/qucs-core/src/components/microstrip -L../qucs/qucs-core/src/converter -L../qucs/qucs-core/src/m-interface -L../qucs/qucs-core/src/math -o bin/Debug/qucs_m_interface_test obj/Debug/main.o ../qucs/qucs-core/src/libqucsatorfull.a
obj/Debug/main.o: In function `givens':
/home/s0237326/src/qucs_m_interface_test/../qucs/qucs-core/src/eqnsys.cpp:1341: undefined reference to `xhypot(double, double)'
obj/Debug/main.o: In function `main':
/home/s0237326/src/qucs_m_interface_test/main.cpp:11: undefined reference to `m_trsolver::m_trsolver()'
/home/s0237326/src/qucs_m_interface_test/main.cpp:13: undefined reference to `m_trsolver::~m_trsolver()'
collect2: ld returned 1 exit status
Process terminated with status 1 (0 minutes, 0 seconds)
3 errors, 1 warnings
私はgcc 4.4.6を搭載したScientific Linux 6.1でcode::blocks 10.05を使用しており、たくさんあるので-DHAVE_CONFIG_Hを渡しています
#if HAVE_CONFIG_H
# include <config.h>
#endif
ソースでは、config.h
autoconf によって生成されます。また、プログラムとしてビルドすると、コードが正常にコンパイルされることも付け加えておく必要があります。このプログラムのコードのサブセット (1 つのファイルを除くすべて) を抽出して、この静的ライブラリに入れました。
テンプレート クラスは 2 つのファイルにまたがっておりeqnsys.h
、eqnsys.cpp
. これを行うのがベストプラクティスではないことはわかっていますが、かなり大きいため、おそらく行われています。それは私のコードではありません。( )eqnsys.cpp
の下に含まれています。静的ヘルパー関数は で定義されています。これが関連する場合にはそうではありません。の先頭に次を追加します。eqnsys.h
#include "eqnsys.cpp"
eqnsys.cpp
real.h
#include
eqnsys.cpp
eqnsys.h
eqnsys.cpp
template class eqnsys<nr_complex_t>;
template class eqnsys<nr_double_t>;
インスタンス化を強制しても問題は解決しません。与えられた関数を静的ヘルパー関数ではなくメンバー関数に変更すると、エラーは消えます。これは私が取るかもしれないルートですが、将来回避できるように、問題の本当の原因は何ですか?