1

我有一个使用自动工具构建系统创建静态库的项目。我希望通过制作一个链接到它的小测试程序来测试这个库。

测试程序正在 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 生成。我还应该补充一点,当构建为程序时,代码编译得很好。我已经提取了该程序的代码子集(除了一个文件之外的所有代码)以放入该静态库中。

模板类分布在两个文件中,eqnsys.h并且eqnsys.cpp. 我知道这样做不是最佳做法,它可能已经完成,因为它非常大。这不是我的代码。eqnsys.cpp包含在eqnsys.h( #include "eqnsys.cpp") 的底部。静态辅助函数定义在eqnsys.cpp. 在顶部real.h被编辑,但如果这是相关的,则不是。将以下内容添加到顶部:#includeeqnsys.cppeqnsys.heqnsys.cpp

template class eqnsys<nr_complex_t>; 
template class eqnsys<nr_double_t>;

强制实例化并不能解决问题。如果我将给定函数更改为成员函数而不是静态辅助函数,则错误消失。这是我可能采取的路线,但问题的真正根源是什么,以便我将来可以避免它?

4

2 回答 2

0

基于构建命令行,您只是在编译main.cpp,而不是链接任何库。您必须链接一个包含缺失符号的库,或者也将它们的源代码编译到您的可执行文件中。

在您的情况下,我认为正确的解决方案是将静态库(您正在尝试测试的)链接到您的测试程序中。

于 2013-05-24T17:51:10.693 回答
0

这几乎可以肯定是模板实例化问题,因为您的模板代码位于 .cpp 而不是 .h 中。
将您的代码移动到标头 - 这样当编译器需要它时,它可以即时为所需类型实例化模板,或者将代码保留在 .cpp 但强制实例化模板(在 .cpp 文件的顶部)您需要的模板 arg 添加 . 例如:

// Explicite template instantiations
#pragma warning(disable: 4660) // For template-class specialization is already instantiated.
template class MyTemplateClass<MyTemplateParamClass>;
于 2013-05-28T09:24:53.780 回答