GraphCrunch2(GC2)是我工作中要用到的一个软件,可是因为要在64位的工作环境下使用,所以只能自己用源码来编译。可是没想到一直编译顺利的我,遇到了一个让我头疼了三天的问题。
系统 Ubuntu server 10.10 -64
硬件 HP WX8600
编译环境 QT4 g++ 4.5.x
外部库 LEDA qwt-5.2.1
我一开始编译好qwt和LEDA并按照库里要求的进行了配置,然后开始编译GC2,莫名其妙的开始报错。基本上是 undefined reference 这种错误。我想当然的认为是库没有装好。搜了半天资料也没有解决。不过学到了一些知识。
关于 undefined reference 有篇博文总结大致原因如下:
- 没有指定对应的库(.o/.a/.so) 使用了库中定义的实体,但没有指定库(-lXXX)或者没有指定库路径(-LYYY),会导致该错误,
- 连接库参数的顺序不对 在默认情况下,对于-l 使用库的要求是越是基础的库越要写在后面,无论是静态还动态
- gcc/ld 版本不匹配 gcc/ld的版本的兼容性问题,由于gcc2 到 gcc3大版本的兼容性存在问题(其实gcc3.2到3.4也一定程度上存在这样的问题) 当在高版本机器上使用低版本的机器就会导致这样的错误, 这个问题比较常见在32位的环境上, 另外就在32位环境不小心使用了64位的库或者反过来64位环境使用了32位的库.
- C/C++相互依赖和链接 gcc和g++编译结果的混用需要保证能够extern "C" 两边都可以使用的接口,在我们的64位环境中gcc链接g++的库还需要加上 -lstdc++,具体见前文对于混合编译的说明
- 运行期报错 这个问题基本上是由于程序使用了dlopen方式载入.so, 但.so没有把所有需要的库都链接上,具体参加上文中对于静态库和动态库混合使用的说明
原文地址:http://blog.chinaunix.net/space.php?uid=8305736&do=blog&id=2033014
我后来检查GC2的Makefile时发现它里面定义的库连接的位置还是在开发者机器上的路径,没办法我重新修改了路径。编译往下走了,可是走着走着又停住了。还是不行。不过出错的信息不同了。主要是关于qwt库中的问题。这可把我难住了。甚至把库文件拷贝在/usr/lib 把头文件放入/usr/include也无效。(*注:在安装好库以后,或者复制进以上文件夹后记得ldconfig,免得给自己带来麻烦,如果库不在系统默认路径下时要把绝对路径写入/etc/ld.so.conf后再ldconfig)
执行了上述操作无效后我开始考虑是否是32位操作系统和64位操作系统的问题。但事实上qwt库是在64位机器上自己编译的,并且其它调用这个库的文件都有很好的被编译,出现问题的只是某几个函数。那么会不会是qwt版本的问题呢?我是按照软件开发者的要求使用的5.2.1版本的啊。我决定从重新开始编译库开始。
qwt库的编译过程是:
qmake
make
make install
其实这个过程我不知执行了多少遍了。可是这次执行时我鬼使神差的在执行了qmake后打开了qwt中自动生成的Makefile文件。在开头的几行中我竟然看到这样的提示 。oh myGod!为什么会是2.2.8呢?我突然想到我的系统上QT3和QT4的版本是同时存在的,GC2的软件作者要求使用QT4来编译,而qwt的库竟然是用qmake 3.3.8生成的。难道问题在这里?
我决定尝试更换下默认版本来试试。
sudo update-alternative --config qmake
默认的果然是qmake-qt3,好的,选择qmake-qt4。
重新编译qwt库,并install。
启动QT Creator 编译GC2。
很顺利,只报了个错误,signals cannot be virtual。
找到报错的位置,原来是个类里面声明时的问题,去到了声明前的virtual。重新编译。
终于内牛满面的看到了熟悉的界面。
总结了一下教训。
1.undefined reference to 这种错误的来源千奇百怪,并不一定完全是库和头文件没有安装的原因,可能安装了也有问题,至于问题是如何来的,比如我这里就是因为编译环境的差异导致的问题。
2.这个软件没有配置configure文件,没有对编译环境提前检查和设定,这给直接编译带来了不小的困难,包括Makefile中路径的设定,一般很难想到还要在这种地方做修改。
3.系统环境越复杂,出现各种莫名其妙的问题的可能性就越大。比如我在ldconfig时遇到了这样的提示libqwt.so.5 不是一个符号连接,可是在我生成的文件里它就是个符号引用,后来在/usr/lib 下发现以前复制进去过同名的库文件,并且不是符号连接的,因为优先级的原因,ld要先检查/usr/lib 下的文件,当然我后制定的路径里的文件就出现了问题。删掉那些文件后问题就消失了。
4.仔细分析报错的原因,如果我一开始就能想到问什么其它文件中使用到qwt库没有出现这个问题,而只有那个文件出现问题的话,可能也就不会走这么多弯路了。虽然一开始也有考虑过,但是没有深入的去想,只是人云亦云的认为是没有安装好库和连接指定的问题。转移了目标,最后绕了一圈还是回到了起点。
以后遇到的问题可能还会更多,很高兴这次没有中途放弃最后解决了它,感谢海风和唐sir的鼓励和帮助。O(∩_∩)O哈哈~收工!
阅读(1905) | 评论(0) | 转发(0) |